VTK  9.2.20230328
vtkVolumeMask.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkVolumeMask.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #ifndef vtkVolumeMask_h
17 #define vtkVolumeMask_h
18 
19 #include <vtkDataArray.h>
20 #include <vtkImageData.h>
21 #include <vtkOpenGLRenderWindow.h>
22 #include <vtkRenderWindow.h>
23 #include <vtkRenderer.h>
24 #include <vtkTextureObject.h>
25 
26 #include <map> // STL required
27 
28 //----------------------------------------------------------------------------
29 VTK_ABI_NAMESPACE_BEGIN
31 {
32 public:
33  //--------------------------------------------------------------------------
35  {
36  this->Texture = nullptr;
37  this->Loaded = false;
38  this->LoadedExtent[0] = VTK_INT_MAX;
39  this->LoadedExtent[1] = VTK_INT_MIN;
40  this->LoadedExtent[2] = VTK_INT_MAX;
41  this->LoadedExtent[3] = VTK_INT_MIN;
42  this->LoadedExtent[4] = VTK_INT_MAX;
43  this->LoadedExtent[5] = VTK_INT_MIN;
44  }
45 
46  //--------------------------------------------------------------------------
48  {
49  if (this->Texture)
50  {
51  this->Texture->Delete();
52  this->Texture = nullptr;
53  }
54  }
55 
56  //--------------------------------------------------------------------------
57  vtkTimeStamp GetBuildTime() { return this->BuildTime; }
58 
59  //--------------------------------------------------------------------------
60  void Activate() { this->Texture->Activate(); }
61 
62  //--------------------------------------------------------------------------
63  void Deactivate() { this->Texture->Deactivate(); }
64 
65  //--------------------------------------------------------------------------
66  void Update(vtkRenderer* ren, vtkImageData* input, int cellFlag, int textureExtent[6],
67  int scalarMode, int arrayAccessMode, int arrayId, const char* arrayName,
68  vtkIdType maxMemoryInBytes)
69  {
70  bool needUpdate = false;
71  bool modified = false;
72 
73  if (!this->Texture)
74  {
76  needUpdate = true;
77  }
78 
80  auto ostate = renWin->GetState();
81  this->Texture->SetContext(renWin);
82 
83  if (!this->Texture->GetHandle())
84  {
85  needUpdate = true;
86  }
87 
88  int obsolete = needUpdate || !this->Loaded || input->GetMTime() > this->BuildTime;
89  if (!obsolete)
90  {
91  obsolete = cellFlag != this->LoadedCellFlag;
92  int i = 0;
93  while (!obsolete && i < 6)
94  {
95  obsolete = obsolete || this->LoadedExtent[i] > textureExtent[i];
96  ++i;
97  obsolete = obsolete || this->LoadedExtent[i] < textureExtent[i];
98  ++i;
99  }
100  }
101 
102  if (obsolete)
103  {
104  this->Loaded = false;
105  int dim[3];
106  input->GetDimensions(dim);
107 
109  input, scalarMode, arrayAccessMode, arrayId, arrayName, this->LoadedCellFlag);
110 
111  // DON'T USE GetScalarType() or GetNumberOfScalarComponents() on
112  // ImageData as it deals only with point data...
113  int scalarType = scalars->GetDataType();
114  if (scalarType != VTK_UNSIGNED_CHAR)
115  {
116  cout << "Mask should be VTK_UNSIGNED_CHAR." << endl;
117  }
118  if (scalars->GetNumberOfComponents() != 1)
119  {
120  cout << "Mask should be a one-component scalar field." << endl;
121  }
122 
123  GLint internalFormat = GL_R8;
124  GLenum format = GL_RED;
125  GLenum type = GL_UNSIGNED_BYTE;
126 
127  // Enough memory?
128  int textureSize[3];
129  int i = 0;
130  while (i < 3)
131  {
132  textureSize[i] = textureExtent[2 * i + 1] - textureExtent[2 * i] + 1;
133  ++i;
134  }
135 
136  GLint width;
137  glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &width);
138  this->Loaded = textureSize[0] <= width && textureSize[1] <= width && textureSize[2] <= width;
139  if (this->Loaded)
140  {
141  // so far, so good but some cards don't report allocation error
142  this->Loaded = textureSize[0] * textureSize[1] * textureSize[2] *
143  vtkAbstractArray::GetDataTypeSize(scalarType) * scalars->GetNumberOfComponents() <=
144  maxMemoryInBytes;
145  if (this->Loaded)
146  {
147  ostate->vtkglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
148 
149  if (!(textureExtent[1] - textureExtent[0] + cellFlag == dim[0]))
150  {
151  ostate->vtkglPixelStorei(GL_UNPACK_ROW_LENGTH, dim[0] - cellFlag);
152  }
153  if (!(textureExtent[3] - textureExtent[2] + cellFlag == dim[1]))
154  {
155  ostate->vtkglPixelStorei(GL_UNPACK_IMAGE_HEIGHT, dim[1] - cellFlag);
156  }
157  void* dataPtr = scalars->GetVoidPointer(
158  ((textureExtent[4] * (dim[1] - cellFlag) + textureExtent[2]) * (dim[0] - cellFlag) +
159  textureExtent[0]) *
160  scalars->GetNumberOfComponents());
161 
162  this->Texture->SetDataType(type);
163  this->Texture->SetFormat(format);
164  this->Texture->SetInternalFormat(internalFormat);
165  this->Texture->Create3DFromRaw(
166  textureSize[0], textureSize[1], textureSize[2], 1, scalarType, dataPtr);
172  this->Texture->SetBorderColor(0.0f, 0.0f, 0.0f, 0.0f);
173 
174  // Restore the default values.
175  ostate->vtkglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
176  ostate->vtkglPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
177 
178  this->LoadedCellFlag = cellFlag;
179  i = 0;
180  while (i < 6)
181  {
182  this->LoadedExtent[i] = textureExtent[i];
183  ++i;
184  }
185 
186  double spacing[3];
187  double origin[3];
188  input->GetSpacing(spacing);
189  input->GetOrigin(origin);
190  int swapBounds[3];
191  swapBounds[0] = (spacing[0] < 0);
192  swapBounds[1] = (spacing[1] < 0);
193  swapBounds[2] = (spacing[2] < 0);
194 
195  if (!this->LoadedCellFlag) // loaded extents represent points
196  {
197  // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
198  // in general, x=o+i*spacing.
199  // if spacing is positive min extent match the min of the
200  // bounding box
201  // and the max extent match the max of the bounding box
202  // if spacing is negative min extent match the max of the
203  // bounding box
204  // and the max extent match the min of the bounding box
205 
206  // if spacing is negative, we may have to rethink the equation
207  // between real point and texture coordinate...
208  this->LoadedBounds[0] =
209  origin[0] + static_cast<double>(this->LoadedExtent[0 + swapBounds[0]]) * spacing[0];
210  this->LoadedBounds[2] =
211  origin[1] + static_cast<double>(this->LoadedExtent[2 + swapBounds[1]]) * spacing[1];
212  this->LoadedBounds[4] =
213  origin[2] + static_cast<double>(this->LoadedExtent[4 + swapBounds[2]]) * spacing[2];
214  this->LoadedBounds[1] =
215  origin[0] + static_cast<double>(this->LoadedExtent[1 - swapBounds[0]]) * spacing[0];
216  this->LoadedBounds[3] =
217  origin[1] + static_cast<double>(this->LoadedExtent[3 - swapBounds[1]]) * spacing[1];
218  this->LoadedBounds[5] =
219  origin[2] + static_cast<double>(this->LoadedExtent[5 - swapBounds[2]]) * spacing[2];
220  }
221  else // loaded extents represent cells
222  {
223  int wholeTextureExtent[6];
224  input->GetExtent(wholeTextureExtent);
225  i = 1;
226  while (i < 6)
227  {
228  wholeTextureExtent[i]--;
229  i += 2;
230  }
231 
232  i = 0;
233  while (i < 3)
234  {
235  if (this->LoadedExtent[2 * i] == wholeTextureExtent[2 * i])
236  {
237  this->LoadedBounds[2 * i + swapBounds[i]] = origin[i];
238  }
239  else
240  {
241  this->LoadedBounds[2 * i + swapBounds[i]] =
242  origin[i] + (static_cast<double>(this->LoadedExtent[2 * i]) + 0.5) * spacing[i];
243  }
244 
245  if (this->LoadedExtent[2 * i + 1] == wholeTextureExtent[2 * i + 1])
246  {
247  this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
248  (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 1.0) * spacing[i];
249  }
250  else
251  {
252  this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
253  (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 0.5) * spacing[i];
254  }
255  ++i;
256  }
257  }
258  modified = true;
259  }
260  }
261  }
262 
263  if (modified)
264  {
265  this->BuildTime.Modified();
266  }
267  }
268 
269  //--------------------------------------------------------------------------
270  double* GetLoadedBounds() { return this->LoadedBounds; }
271 
272  //--------------------------------------------------------------------------
274 
275  //--------------------------------------------------------------------------
276  int GetLoadedCellFlag() { return this->LoadedCellFlag; }
277 
278  //--------------------------------------------------------------------------
279  bool IsLoaded() { return this->Loaded; }
280 
281  // Get the texture unit
282  //--------------------------------------------------------------------------
283  int GetTextureUnit(void)
284  {
285  if (!this->Texture)
286  {
287  return -1;
288  }
289  return this->Texture->GetTextureUnit();
290  }
291 
292  //--------------------------------------------------------------------------
294  {
295  if (this->Texture)
296  {
297  this->Texture->ReleaseGraphicsResources(window);
298  this->Texture->Delete();
299  this->Texture = nullptr;
300  }
301  }
302 
303 protected:
306 
307  double LoadedBounds[6];
309 
311  bool Loaded;
312 };
313 
314 //----------------------------------------------------------------------------
316 {
317 public:
318  std::map<vtkImageData*, vtkVolumeMask*> Map;
319  vtkMapMaskTextureId() = default;
320 
321 private:
322  vtkMapMaskTextureId(const vtkMapMaskTextureId& other) = delete;
323  vtkMapMaskTextureId& operator=(const vtkMapMaskTextureId& other) = delete;
324 };
325 
326 VTK_ABI_NAMESPACE_END
327 #endif // vtkVolumeMask_h
328 // VTK-HeaderTest-Exclude: vtkVolumeMask.h
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
virtual int GetDataTypeSize() const =0
Return the size of the underlying data type.
virtual int GetDataType() const =0
Return the underlying data type.
virtual void * GetVoidPointer(vtkIdType valueIdx)=0
Return a void pointer.
static vtkDataArray * GetScalars(vtkDataSet *input, int scalarMode, int arrayAccessMode, int arrayId, const char *arrayName, int &cellFlag)
Internal helper function for getting the active scalars.
abstract superclass for arrays of numeric data
Definition: vtkDataArray.h:166
vtkMTimeType GetMTime() override
Datasets are composite objects and need to check each part for MTime THIS METHOD IS THREAD SAFE.
topologically and geometrically regular array of data
Definition: vtkImageData.h:164
virtual double * GetOrigin()
Set/Get the origin of the dataset.
virtual int * GetDimensions()
Get dimensions of this structured points dataset.
virtual int * GetExtent()
Set/Get the extent.
virtual double * GetSpacing()
Set the spacing (width,height,length) of the cubical cells that compose the data set.
std::map< vtkImageData *, vtkVolumeMask * > Map
vtkMapMaskTextureId()=default
virtual void Delete()
Delete a VTK object.
OpenGL rendering window.
virtual vtkOpenGLState * GetState()
static vtkOpenGLRenderWindow * SafeDownCast(vtkObjectBase *o)
abstract specification for renderers
Definition: vtkRenderer.h:183
vtkRenderWindow * GetRenderWindow()
Specify the rendering window in which to draw.
Definition: vtkRenderer.h:577
abstracts an OpenGL texture object.
void SetContext(vtkOpenGLRenderWindow *)
Get/Set the context.
virtual void SetWrapT(int)
Wrap mode for the first texture coordinate "t" Valid values are:
void SetInternalFormat(unsigned int glInternalFormat)
Get/Set internal format (OpenGL internal format) that should be used.
virtual void Activate()
Activate and Bind the texture.
virtual void SetMagnificationFilter(int)
Magnification filter mode.
virtual unsigned int GetHandle()
Returns the OpenGL handle.
int GetTextureUnit()
Return the texture unit used for this texture.
static vtkTextureObject * New()
virtual void SetBorderColor(float, float, float, float)
Border Color (RGBA).
virtual void ReleaseGraphicsResources(vtkWindow *win)
Deactivate and UnBind the texture.
void SetDataType(unsigned int glType)
Get the data type for the texture as GLenum type.
void Deactivate()
Deactivate and UnBind the texture.
virtual void SetWrapR(int)
Wrap mode for the first texture coordinate "r" Valid values are:
void SetFormat(unsigned int glFormat)
Get/Set format (OpenGL internal format) that should be used.
bool Create3DFromRaw(unsigned int width, unsigned int height, unsigned int depth, int numComps, int dataType, void *data)
Create a 3D texture from client memory numComps must be in [1-4].
virtual void SetMinificationFilter(int)
Minification filter mode.
virtual void SetWrapS(int)
Wrap mode for the first texture coordinate "s" Valid values are:
record modification and/or execution time
Definition: vtkTimeStamp.h:56
void Modified()
Set this objects time to the current time.
double LoadedBounds[6]
void Update(vtkRenderer *ren, vtkImageData *input, int cellFlag, int textureExtent[6], int scalarMode, int arrayAccessMode, int arrayId, const char *arrayName, vtkIdType maxMemoryInBytes)
Definition: vtkVolumeMask.h:66
vtkTimeStamp BuildTime
void Deactivate()
Definition: vtkVolumeMask.h:63
vtkTextureObject * Texture
vtkIdType LoadedExtent[6]
vtkTimeStamp GetBuildTime()
Definition: vtkVolumeMask.h:57
void ReleaseGraphicsResources(vtkWindow *window)
int GetTextureUnit(void)
int GetLoadedCellFlag()
vtkIdType * GetLoadedExtent()
double * GetLoadedBounds()
window superclass for vtkRenderWindow
Definition: vtkWindow.h:40
@ type
Definition: vtkX3D.h:528
@ spacing
Definition: vtkX3D.h:493
#define GL_UNSIGNED_BYTE
int vtkIdType
Definition: vtkType.h:327
#define VTK_INT_MIN
Definition: vtkType.h:155
#define VTK_UNSIGNED_CHAR
Definition: vtkType.h:47
#define VTK_INT_MAX
Definition: vtkType.h:156