VTK  9.5.20251211
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//----------------------------------------------------------------------------
18VTK_ABI_NAMESPACE_BEGIN
20{
21public:
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 //--------------------------------------------------------------------------
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] *
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 void* dataPtr = scalars->GetVoidPointer(
147 ((textureExtent[4] * (dim[1] - cellFlag) + textureExtent[2]) * (dim[0] - cellFlag) +
148 textureExtent[0]) *
149 scalars->GetNumberOfComponents());
150
151 this->Texture->SetDataType(type);
152 this->Texture->SetFormat(format);
153 this->Texture->SetInternalFormat(internalFormat);
154 this->Texture->Create3DFromRaw(
155 textureSize[0], textureSize[1], textureSize[2], 1, scalarType, dataPtr);
156 this->Texture->SetWrapS(vtkTextureObject::ClampToEdge);
157 this->Texture->SetWrapT(vtkTextureObject::ClampToEdge);
158 this->Texture->SetWrapR(vtkTextureObject::ClampToEdge);
159 this->Texture->SetMagnificationFilter(vtkTextureObject::Nearest);
160 this->Texture->SetMinificationFilter(vtkTextureObject::Nearest);
161 this->Texture->SetBorderColor(0.0f, 0.0f, 0.0f, 0.0f);
162
163 // Restore the default values.
164 ostate->vtkglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
165 ostate->vtkglPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
166
167 this->LoadedCellFlag = cellFlag;
168 i = 0;
169 while (i < 6)
170 {
171 this->LoadedExtent[i] = textureExtent[i];
172 ++i;
173 }
174
175 double spacing[3];
176 double origin[3];
177 input->GetSpacing(spacing);
178 input->GetOrigin(origin);
179 int swapBounds[3];
180 swapBounds[0] = (spacing[0] < 0);
181 swapBounds[1] = (spacing[1] < 0);
182 swapBounds[2] = (spacing[2] < 0);
183
184 if (!this->LoadedCellFlag) // loaded extents represent points
185 {
186 // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
187 // in general, x=o+i*spacing.
188 // if spacing is positive min extent match the min of the
189 // bounding box
190 // and the max extent match the max of the bounding box
191 // if spacing is negative min extent match the max of the
192 // bounding box
193 // and the max extent match the min of the bounding box
194
195 // if spacing is negative, we may have to rethink the equation
196 // between real point and texture coordinate...
197 this->LoadedBounds[0] =
198 origin[0] + static_cast<double>(this->LoadedExtent[0 + swapBounds[0]]) * spacing[0];
199 this->LoadedBounds[2] =
200 origin[1] + static_cast<double>(this->LoadedExtent[2 + swapBounds[1]]) * spacing[1];
201 this->LoadedBounds[4] =
202 origin[2] + static_cast<double>(this->LoadedExtent[4 + swapBounds[2]]) * spacing[2];
203 this->LoadedBounds[1] =
204 origin[0] + static_cast<double>(this->LoadedExtent[1 - swapBounds[0]]) * spacing[0];
205 this->LoadedBounds[3] =
206 origin[1] + static_cast<double>(this->LoadedExtent[3 - swapBounds[1]]) * spacing[1];
207 this->LoadedBounds[5] =
208 origin[2] + static_cast<double>(this->LoadedExtent[5 - swapBounds[2]]) * spacing[2];
209 }
210 else // loaded extents represent cells
211 {
212 int wholeTextureExtent[6];
213 input->GetExtent(wholeTextureExtent);
214 i = 1;
215 while (i < 6)
216 {
217 wholeTextureExtent[i]--;
218 i += 2;
219 }
220
221 i = 0;
222 while (i < 3)
223 {
224 if (this->LoadedExtent[2 * i] == wholeTextureExtent[2 * i])
225 {
226 this->LoadedBounds[2 * i + swapBounds[i]] = origin[i];
227 }
228 else
229 {
230 this->LoadedBounds[2 * i + swapBounds[i]] =
231 origin[i] + (static_cast<double>(this->LoadedExtent[2 * i]) + 0.5) * spacing[i];
232 }
233
234 if (this->LoadedExtent[2 * i + 1] == wholeTextureExtent[2 * i + 1])
235 {
236 this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
237 (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 1.0) * spacing[i];
238 }
239 else
240 {
241 this->LoadedBounds[2 * i + 1 - swapBounds[i]] = origin[i] +
242 (static_cast<double>(this->LoadedExtent[2 * i + 1]) + 0.5) * spacing[i];
243 }
244 ++i;
245 }
246 }
247 modified = true;
248 }
249 }
250 }
251
252 if (modified)
253 {
254 this->BuildTime.Modified();
255 }
256 }
257
258 //--------------------------------------------------------------------------
259 double* GetLoadedBounds() { return this->LoadedBounds; }
260
261 //--------------------------------------------------------------------------
263
264 //--------------------------------------------------------------------------
265 int GetLoadedCellFlag() { return this->LoadedCellFlag; }
266
267 //--------------------------------------------------------------------------
268 bool IsLoaded() { return this->Loaded; }
269
270 // Get the texture unit
271 //--------------------------------------------------------------------------
273 {
274 if (!this->Texture)
275 {
276 return -1;
277 }
278 return this->Texture->GetTextureUnit();
279 }
280
281 //--------------------------------------------------------------------------
283 {
284 if (this->Texture)
285 {
286 this->Texture->ReleaseGraphicsResources(window);
287 this->Texture->Delete();
288 this->Texture = nullptr;
289 }
290 }
291
292protected:
295
296 double LoadedBounds[6];
298
300 bool Loaded;
301};
302
303//----------------------------------------------------------------------------
305{
306public:
307 std::map<vtkImageData*, vtkVolumeMask*> Map;
309
310private:
311 vtkMapMaskTextureId(const vtkMapMaskTextureId& other) = delete;
312 vtkMapMaskTextureId& operator=(const vtkMapMaskTextureId& other) = delete;
313};
314
315VTK_ABI_NAMESPACE_END
316#endif // vtkVolumeMask_h
317// VTK-HeaderTest-Exclude: vtkVolumeMask.h
int GetNumberOfComponents() const
Set/Get the dimension (n) of the components.
virtual int GetDataType() const
Return the underlying data type.
virtual int GetDataTypeSize() const =0
Return the size of 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.
int * GetDimensions()
Get dimensions of this structured points dataset.
virtual int * GetExtent()
Set/Get the extent.
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
virtual double * GetOrigin()
Set/Get the origin of the dataset.
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
OpenGL rendering window.
static vtkOpenGLRenderWindow * SafeDownCast(vtkObjectBase *o)
virtual vtkOpenGLState * GetState()
abstract specification for renderers
vtkRenderWindow * GetRenderWindow()
Specify the rendering window in which to draw.
abstracts an OpenGL texture object.
static vtkTextureObject * New()
record modification and/or execution 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)
vtkTimeStamp BuildTime
vtkTextureObject * Texture
vtkIdType LoadedExtent[6]
vtkTimeStamp GetBuildTime()
vtkIdType * GetLoadedExtent()
void ReleaseGraphicsResources(vtkWindow *window)
double * GetLoadedBounds()
int GetLoadedCellFlag()
window superclass for vtkRenderWindow
Definition vtkWindow.h:48
#define vtkDataArray
#define GL_UNSIGNED_BYTE
int vtkIdType
Definition vtkType.h:367
#define VTK_INT_MIN
Definition vtkType.h:195
#define VTK_UNSIGNED_CHAR
Definition vtkType.h:36
#define VTK_INT_MAX
Definition vtkType.h:196