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