VTK  9.7.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 <iostream> // STL required
15 #include <map> // STL required
16 
17 //----------------------------------------------------------------------------
18 VTK_ABI_NAMESPACE_BEGIN
20 {
21 public:
22  //--------------------------------------------------------------------------
24  {
25  this->Texture = nullptr;
26  this->Loaded = false;
27  this->LoadedExtent[0] = VTK_INT_MAX;
28  this->LoadedExtent[1] = VTK_INT_MIN;
29  this->LoadedExtent[2] = VTK_INT_MAX;
30  this->LoadedExtent[3] = VTK_INT_MIN;
31  this->LoadedExtent[4] = VTK_INT_MAX;
32  this->LoadedExtent[5] = VTK_INT_MIN;
33  }
34 
35  //--------------------------------------------------------------------------
37  {
38  if (this->Texture)
39  {
40  this->Texture->Delete();
41  this->Texture = nullptr;
42  }
43  }
44 
45  //--------------------------------------------------------------------------
46  vtkTimeStamp GetBuildTime() { return this->BuildTime; }
47 
48  //--------------------------------------------------------------------------
49  void Activate() { this->Texture->Activate(); }
50 
51  //--------------------------------------------------------------------------
52  void Deactivate() { this->Texture->Deactivate(); }
53 
54  //--------------------------------------------------------------------------
55  void Update(vtkRenderer* ren, vtkImageData* input, int cellFlag, int textureExtent[6],
56  int scalarMode, int arrayAccessMode, int arrayId, const char* arrayName,
57  vtkIdType maxMemoryInBytes)
58  {
59  bool needUpdate = false;
60  bool modified = false;
61 
62  if (!this->Texture)
63  {
65  needUpdate = true;
66  }
67 
69  auto ostate = renWin->GetState();
70  this->Texture->SetContext(renWin);
71 
72  if (!this->Texture->GetHandle())
73  {
74  needUpdate = true;
75  }
76 
77  int obsolete = needUpdate || !this->Loaded || input->GetMTime() > this->BuildTime;
78  if (!obsolete)
79  {
80  obsolete = cellFlag != this->LoadedCellFlag;
81  int i = 0;
82  while (!obsolete && i < 6)
83  {
84  obsolete = obsolete || this->LoadedExtent[i] > textureExtent[i];
85  ++i;
86  obsolete = obsolete || this->LoadedExtent[i] < textureExtent[i];
87  ++i;
88  }
89  }
90 
91  if (obsolete)
92  {
93  this->Loaded = false;
94  int dim[3];
95  input->GetDimensions(dim);
96 
98  input, scalarMode, arrayAccessMode, arrayId, arrayName, this->LoadedCellFlag);
99 
100  // DON'T USE GetScalarType() or GetNumberOfScalarComponents() on
101  // ImageData as it deals only with point data...
102  int scalarType = scalars->GetDataType();
103  if (scalarType != VTK_UNSIGNED_CHAR)
104  {
105  std::cout << "Mask should be VTK_UNSIGNED_CHAR." << std::endl;
106  }
107  if (scalars->GetNumberOfComponents() != 1)
108  {
109  std::cout << "Mask should be a one-component scalar field." << std::endl;
110  }
111 
112  GLint internalFormat = GL_R8;
113  GLenum format = GL_RED;
114  GLenum type = GL_UNSIGNED_BYTE;
115 
116  // Enough memory?
117  int textureSize[3];
118  int i = 0;
119  while (i < 3)
120  {
121  textureSize[i] = textureExtent[2 * i + 1] - textureExtent[2 * i] + 1;
122  ++i;
123  }
124 
125  GLint width;
126  glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &width);
127  this->Loaded = textureSize[0] <= width && textureSize[1] <= width && textureSize[2] <= width;
128  if (this->Loaded)
129  {
130  // so far, so good but some cards don't report allocation error
131  this->Loaded = textureSize[0] * textureSize[1] * textureSize[2] *
132  vtkAbstractArray::GetDataTypeSize(scalarType) * scalars->GetNumberOfComponents() <=
133  maxMemoryInBytes;
134  if (this->Loaded)
135  {
136  ostate->vtkglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
137 
138  if (!(textureExtent[1] - textureExtent[0] + cellFlag == dim[0]))
139  {
140  ostate->vtkglPixelStorei(GL_UNPACK_ROW_LENGTH, dim[0] - cellFlag);
141  }
142  if (!(textureExtent[3] - textureExtent[2] + cellFlag == dim[1]))
143  {
144  ostate->vtkglPixelStorei(GL_UNPACK_IMAGE_HEIGHT, dim[1] - cellFlag);
145  }
146  auto scalarsAOS = scalars->ToAOSDataArray();
147  void* dataPtr = scalarsAOS->GetVoidPointer( // NOLINT(bugprone-unsafe-functions)
148  ((textureExtent[4] * (dim[1] - cellFlag) + textureExtent[2]) * (dim[0] - cellFlag) +
149  textureExtent[0]) *
150  scalars->GetNumberOfComponents());
151 
152  this->Texture->SetDataType(type);
153  this->Texture->SetFormat(format);
154  this->Texture->SetInternalFormat(internalFormat);
155  this->Texture->Create3DFromRaw(
156  textureSize[0], textureSize[1], textureSize[2], 1, scalarType, dataPtr);
162  this->Texture->SetBorderColor(0.0f, 0.0f, 0.0f, 0.0f);
163 
164  // Restore the default values.
165  ostate->vtkglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
166  ostate->vtkglPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
167 
168  this->LoadedCellFlag = cellFlag;
169  i = 0;
170  while (i < 6)
171  {
172  this->LoadedExtent[i] = textureExtent[i];
173  ++i;
174  }
175 
176  double spacing[3];
177  double origin[3];
178  input->GetSpacing(spacing);
179  input->GetOrigin(origin);
180  int swapBounds[3];
181  swapBounds[0] = (spacing[0] < 0);
182  swapBounds[1] = (spacing[1] < 0);
183  swapBounds[2] = (spacing[2] < 0);
184 
185  if (!this->LoadedCellFlag) // loaded extents represent points
186  {
187  // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
188  // in general, x=o+i*spacing.
189  // if spacing is positive min extent match the min of the
190  // bounding box
191  // and the max extent match the max of the bounding box
192  // if spacing is negative min extent match the max of the
193  // bounding box
194  // and the max extent match the min of the bounding box
195 
196  // if spacing is negative, we may have to rethink the equation
197  // between real point and texture coordinate...
198  this->LoadedBounds[0] =
199  origin[0] + static_cast<double>(this->LoadedExtent[0 + swapBounds[0]]) * spacing[0];
200  this->LoadedBounds[2] =
201  origin[1] + static_cast<double>(this->LoadedExtent[2 + swapBounds[1]]) * spacing[1];
202  this->LoadedBounds[4] =
203  origin[2] + static_cast<double>(this->LoadedExtent[4 + swapBounds[2]]) * spacing[2];
204  this->LoadedBounds[1] =
205  origin[0] + static_cast<double>(this->LoadedExtent[1 - swapBounds[0]]) * spacing[0];
206  this->LoadedBounds[3] =
207  origin[1] + static_cast<double>(this->LoadedExtent[3 - swapBounds[1]]) * spacing[1];
208  this->LoadedBounds[5] =
209  origin[2] + static_cast<double>(this->LoadedExtent[5 - swapBounds[2]]) * spacing[2];
210  }
211  else // loaded extents represent cells
212  {
213  int wholeTextureExtent[6];
214  input->GetExtent(wholeTextureExtent);
215  i = 1;
216  while (i < 6)
217  {
218  wholeTextureExtent[i]--;
219  i += 2;
220  }
221 
222  i = 0;
223  while (i < 3)
224  {
225  if (this->LoadedExtent[2 * i] == wholeTextureExtent[2 * i])
226  {
227  this->LoadedBounds[2 * i + swapBounds[i]] = origin[i];
228  }
229  else
230  {
231  this->LoadedBounds[2 * i + swapBounds[i]] =
232  origin[i] + (static_cast<double>(this->LoadedExtent[2 * i]) + 0.5) * spacing[i];
233  }
234 
235  if (this->LoadedExtent[2 * i + 1] == wholeTextureExtent[2 * i + 1])
236  {
237  this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
238  (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 1.0) * spacing[i];
239  }
240  else
241  {
242  this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
243  (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 0.5) * spacing[i];
244  }
245  ++i;
246  }
247  }
248  modified = true;
249  }
250  }
251  }
252 
253  if (modified)
254  {
255  this->BuildTime.Modified();
256  }
257  }
258 
259  //--------------------------------------------------------------------------
260  double* GetLoadedBounds() { return this->LoadedBounds; }
261 
262  //--------------------------------------------------------------------------
264 
265  //--------------------------------------------------------------------------
266  int GetLoadedCellFlag() { return this->LoadedCellFlag; }
267 
268  //--------------------------------------------------------------------------
269  bool IsLoaded() { return this->Loaded; }
270 
271  // Get the texture unit
272  //--------------------------------------------------------------------------
274  {
275  if (!this->Texture)
276  {
277  return -1;
278  }
279  return this->Texture->GetTextureUnit();
280  }
281 
282  //--------------------------------------------------------------------------
284  {
285  if (this->Texture)
286  {
287  this->Texture->ReleaseGraphicsResources(window);
288  this->Texture->Delete();
289  this->Texture = nullptr;
290  }
291  }
292 
293 protected:
296 
297  double LoadedBounds[6];
299 
301  bool Loaded;
302 };
303 
304 //----------------------------------------------------------------------------
306 {
307 public:
308  std::map<vtkImageData*, vtkVolumeMask*> Map;
309  vtkMapMaskTextureId() = default;
310 
311 private:
312  vtkMapMaskTextureId(const vtkMapMaskTextureId& other) = delete;
313  vtkMapMaskTextureId& operator=(const vtkMapMaskTextureId& other) = delete;
314 };
315 
316 VTK_ABI_NAMESPACE_END
317 #endif // vtkVolumeMask_h
318 // 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:46
vtkSmartPointer< vtkDataArray > ToAOSDataArray()
If the array is not already in AOS format, return a new array that is with the same data...
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:192
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.
void Modified()
Set this objects time to the current time.
abstract specification for renderers
Definition: vtkRenderer.h:63
#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:363
vtkTextureObject * Texture
vtkTimeStamp BuildTime
void ReleaseGraphicsResources(vtkWindow *window)
int GetTextureUnit()
vtkMapMaskTextureId()=default
void Deactivate()
Definition: vtkVolumeMask.h:52
int * GetDimensions()
Get dimensions of this structured points dataset.
window superclass for vtkRenderWindow
Definition: vtkWindow.h:41
virtual int GetDataTypeSize() const =0
Return the size of the underlying data type.
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:45
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 the format (GLenum) and internal format (GLenum) in use.
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:55
abstracts an OpenGL texture object.
int GetLoadedCellFlag()
#define VTK_UNSIGNED_CHAR
Definition: vtkType.h:36
void Deactivate()
Deactivate and UnBind the texture.
static vtkTextureObject * New()
virtual int GetDataType() const
Return the underlying data type.
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:471
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:191
double LoadedBounds[6]
virtual void Delete()
Delete a VTK object.
void SetContext(vtkOpenGLRenderWindow *)
Get/Set the context.
virtual void SetMagnificationFilter(int)
Magnification filter mode.