0031431: Visualization, PrsMgr_PresentableObject - simplify HLR computing interface
[occt.git] / src / Graphic3d / Graphic3d_MarkerImage.cxx
CommitLineData
a577aaab 1// Created on: 2013-06-25
2// Created by: Dmitry BOBYLEV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
a577aaab 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
a577aaab 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
a577aaab 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
a577aaab 15
16#include <Graphic3d_MarkerImage.hxx>
17
18#include <Image_PixMap.hxx>
19#include <Standard_Atomic.hxx>
20#include <TColStd_HArray1OfByte.hxx>
21
92efcf78 22IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MarkerImage,Standard_Transient)
23
a577aaab 24namespace
25{
26 static volatile Standard_Integer THE_MARKER_IMAGE_COUNTER = 0;
a3f6f591 27}
a577aaab 28
a577aaab 29
30// =======================================================================
31// function : Graphic3d_MarkerImage
32// purpose :
33// =======================================================================
34Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(Image_PixMap)& theImage)
c04c30b3 35: myImage (theImage),
a577aaab 36 myMargin (1),
37 myWidth ((Standard_Integer )theImage->Width()),
38 myHeight ((Standard_Integer )theImage->Height())
39{
40 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
41 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
42
43 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
44 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
45}
46
47// =======================================================================
48// function : Graphic3d_MarkerImage
49// purpose :
50// =======================================================================
51Graphic3d_MarkerImage::Graphic3d_MarkerImage (const Handle(TColStd_HArray1OfByte)& theBitMap,
52 const Standard_Integer& theWidth,
53 const Standard_Integer& theHeight)
54: myBitMap (theBitMap),
a577aaab 55 myMargin (1),
56 myWidth (theWidth),
57 myHeight (theHeight)
58{
59 myImageId = TCollection_AsciiString ("Graphic3d_MarkerImage_")
60 + TCollection_AsciiString (Standard_Atomic_Increment (&THE_MARKER_IMAGE_COUNTER));
61
62 myImageAlphaId = TCollection_AsciiString ("Graphic3d_MarkerImageAlpha_")
63 + TCollection_AsciiString (THE_MARKER_IMAGE_COUNTER);
64}
65
66// =======================================================================
67// function : GetBitMapArray
68// purpose :
69// =======================================================================
70Handle(TColStd_HArray1OfByte) Graphic3d_MarkerImage::GetBitMapArray (const Standard_Real& theAlphaValue) const
71{
72 if (!myBitMap.IsNull())
73 {
74 return myBitMap;
75 }
76
77 Handle(TColStd_HArray1OfByte) aBitMap;
78 if (myImage.IsNull())
79 {
80 return aBitMap;
81 }
82
83 const Standard_Integer aNumOfBytesInRow = (Standard_Integer )(myImage->Width() / 8) + (myImage->Width() % 8 ? 1 : 0);
84 const Standard_Integer aNumOfBytes = (Standard_Integer )(aNumOfBytesInRow * myImage->Height());
85 const Standard_Integer aHeight = (Standard_Integer )myImage->Height();
86 const Standard_Integer aWidth = (Standard_Integer )myImage->Width();
87 aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
88 aBitMap->Init (0);
89 for (Standard_Integer aRow = 0; aRow < aHeight; aRow++)
90 {
91 for (Standard_Integer aColumn = 0; aColumn < aWidth; aColumn++)
92 {
e958a649 93 const Quantity_ColorRGBA aColor = myImage->PixelColor (aColumn, aRow);
a577aaab 94 Standard_Boolean aBitOn = Standard_False;
e958a649 95 if (myImage->Format() == Image_Format_Gray)
a577aaab 96 {
e958a649 97 aBitOn = aColor.GetRGB().Red() > theAlphaValue;
a577aaab 98 }
e958a649 99 else //if (myImage->Format() == Image_Format_Alpha)
a577aaab 100 {
e958a649 101 aBitOn = aColor.Alpha() > theAlphaValue;
a577aaab 102 }
103
008aef40 104 Standard_Integer anIndex = aNumOfBytesInRow * aRow + aColumn / 8;
105 aBitMap->SetValue (anIndex, (Standard_Byte)(aBitMap->Value (anIndex) +
106 (aBitOn ? (0x80 >> (aColumn % 8)) : 0)));
a577aaab 107 }
108 }
109
110 return aBitMap;
111}
112
113// =======================================================================
114// function : GetImage
115// purpose :
116// =======================================================================
117const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImage()
118{
119 if (!myImage.IsNull())
120 {
121 return myImage;
122 }
123
124 if (myBitMap.IsNull())
125 {
126 return myImage;
127 }
128
129 // Converting a byte array to bitmap image. Row and column offsets are used
130 // to store bitmap in a square image, so the image will not be stretched
131 // when rendering with point sprites.
132 const Standard_Integer aNumOfBytesInRow = myWidth / 8 + (myWidth % 8 ? 1 : 0);
133 const Standard_Integer aSize = Max (myWidth, myHeight);
134 const Standard_Integer aRowOffset = (aSize - myHeight) / 2 + myMargin;
135 const Standard_Integer aColumnOffset = (aSize - myWidth ) / 2 + myMargin;
136 const Standard_Integer aLowerIndex = myBitMap->Lower();
137
138 myImage = new Image_PixMap();
dc858f4c 139 myImage->InitZero (Image_Format_Alpha, aSize + myMargin * 2, aSize + myMargin * 2);
a577aaab 140 for (Standard_Integer aRowIter = 0; aRowIter < myHeight; aRowIter++)
141 {
142 Standard_Byte* anImageRow = myImage->ChangeRow (aRowIter + aRowOffset);
143 for (Standard_Integer aColumnIter = 0; aColumnIter < myWidth; aColumnIter++)
144 {
dde68833 145 Standard_Boolean aBitOn = (myBitMap->Value (aLowerIndex + aNumOfBytesInRow * aRowIter + aColumnIter / 8) & (0x80 >> (aColumnIter % 8))) != 0;
a577aaab 146 anImageRow[aColumnIter + aColumnOffset] = aBitOn ? 255 : 0;
147 }
148 }
149
150 return myImage;
151}
152
153// =======================================================================
154// function : GetImageAlpha
155// purpose :
156// =======================================================================
157const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImageAlpha()
158{
159 if (!myImageAlpha.IsNull())
160 {
161 return myImageAlpha;
162 }
163
164 if (!myImage.IsNull())
165 {
dc858f4c 166 if (myImage->Format() == Image_Format_Gray
167 || myImage->Format() == Image_Format_Alpha)
a577aaab 168 {
169 myImageAlpha = myImage;
170 }
171 else
172 {
173 myImageAlpha = new Image_PixMap();
dc858f4c 174 myImageAlpha->InitZero (Image_Format_Alpha, myImage->Width(), myImage->Height());
a577aaab 175 myImageAlpha->SetTopDown (Standard_False);
498ce76b 176 for (Standard_Size aRowIter = 0; aRowIter < myImage->Height(); aRowIter++)
a577aaab 177 {
178 Standard_Byte* anImageRow = myImageAlpha->ChangeRow (aRowIter);
498ce76b 179 for (Standard_Size aColumnIter = 0; aColumnIter < myImage->Width(); aColumnIter++)
a577aaab 180 {
e958a649 181 const Quantity_ColorRGBA aColor = myImage->PixelColor ((Standard_Integer)aColumnIter, (Standard_Integer)aRowIter);
182 anImageRow[aColumnIter] = Standard_Byte (255.0 * aColor.Alpha());
a577aaab 183 }
184 }
185 }
186 }
187
188 return myImageAlpha;
189}
190
191// =======================================================================
192// function : GetImageId
193// purpose :
194// =======================================================================
195const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageId() const
196{
197 return myImageId;
198}
199
200// =======================================================================
201// function : GetImageAlphaId
202// purpose :
203// =======================================================================
204const TCollection_AsciiString& Graphic3d_MarkerImage::GetImageAlphaId() const
205{
206 return myImageAlphaId;
207}
208
209// =======================================================================
210// function : GetTextureSize
211// purpose :
212// =======================================================================
213void Graphic3d_MarkerImage::GetTextureSize (Standard_Integer& theWidth,
214 Standard_Integer& theHeight) const
215{
216 theWidth = myWidth;
217 theHeight = myHeight;
218}