VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: vtkVolumeMask.h 00005 00006 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00007 All rights reserved. 00008 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 00016 #ifndef vtkVolumeMask_h_ 00017 #define vtkVolumeMask_h_ 00018 00019 #include <vtkDataArray.h> 00020 #include <vtkImageData.h> 00021 #include <vtkOpenGLRenderWindow.h> 00022 #include <vtkRenderer.h> 00023 #include <vtkRenderWindow.h> 00024 #include <vtkTextureObject.h> 00025 00026 #include <map> // STL required 00027 00028 //---------------------------------------------------------------------------- 00029 class vtkVolumeMask 00030 { 00031 public: 00032 //-------------------------------------------------------------------------- 00033 vtkVolumeMask() 00034 { 00035 this->Texture = NULL; 00036 this->Loaded = false; 00037 this->LoadedExtent[0] = VTK_INT_MAX; 00038 this->LoadedExtent[1] = VTK_INT_MIN; 00039 this->LoadedExtent[2] = VTK_INT_MAX; 00040 this->LoadedExtent[3] = VTK_INT_MIN; 00041 this->LoadedExtent[4] = VTK_INT_MAX; 00042 this->LoadedExtent[5] = VTK_INT_MIN; 00043 } 00044 00045 //-------------------------------------------------------------------------- 00046 ~vtkVolumeMask() 00047 { 00048 if (this->Texture) 00049 { 00050 this->Texture->Delete(); 00051 this->Texture = 0; 00052 } 00053 } 00054 00055 //-------------------------------------------------------------------------- 00056 vtkTimeStamp GetBuildTime() 00057 { 00058 return this->BuildTime; 00059 } 00060 00061 //-------------------------------------------------------------------------- 00062 void Bind() 00063 { 00064 this->Texture->Activate(); 00065 } 00066 00067 //-------------------------------------------------------------------------- 00068 void Update(vtkRenderer* ren, 00069 vtkImageData *input, 00070 int cellFlag, 00071 int textureExtent[6], 00072 int scalarMode, 00073 int arrayAccessMode, 00074 int arrayId, 00075 const char* arrayName, 00076 vtkIdType maxMemoryInBytes) 00077 { 00078 bool needUpdate = false; 00079 bool modified = false; 00080 00081 if (!this->Texture) 00082 { 00083 this->Texture = vtkTextureObject::New(); 00084 needUpdate = true; 00085 } 00086 00087 this->Texture->SetContext(vtkOpenGLRenderWindow::SafeDownCast( 00088 ren->GetRenderWindow())); 00089 00090 if (!this->Texture->GetHandle()) 00091 { 00092 needUpdate = true; 00093 } 00094 00095 int obsolete = needUpdate || !this->Loaded || 00096 input->GetMTime()>this->BuildTime; 00097 if(!obsolete) 00098 { 00099 obsolete = cellFlag != this->LoadedCellFlag; 00100 int i = 0; 00101 while(!obsolete && i<6) 00102 { 00103 obsolete = obsolete || this->LoadedExtent[i]>textureExtent[i]; 00104 ++i; 00105 obsolete = obsolete || this->LoadedExtent[i]<textureExtent[i]; 00106 ++i; 00107 } 00108 } 00109 00110 if(obsolete) 00111 { 00112 this->Loaded = false; 00113 int dim[3]; 00114 input->GetDimensions(dim); 00115 00116 vtkDataArray *scalars = 00117 vtkAbstractMapper::GetScalars(input,scalarMode,arrayAccessMode, 00118 arrayId,arrayName, 00119 this->LoadedCellFlag); 00120 00121 // DONT USE GetScalarType() or GetNumberOfScalarComponents() on 00122 // ImageData as it deals only with point data... 00123 int scalarType = scalars->GetDataType(); 00124 if(scalarType != VTK_UNSIGNED_CHAR) 00125 { 00126 cout <<"Mask should be VTK_UNSIGNED_CHAR." << endl; 00127 } 00128 if(scalars->GetNumberOfComponents()!=1) 00129 { 00130 cout << "Mask should be a one-component scalar field." << endl; 00131 } 00132 00133 GLint internalFormat = GL_ALPHA8; 00134 GLenum format = GL_ALPHA; 00135 GLenum type = GL_UNSIGNED_BYTE; 00136 00137 // Enough memory? 00138 int textureSize[3]; 00139 int i = 0; 00140 while(i < 3) 00141 { 00142 textureSize[i] = textureExtent[2*i+1] - textureExtent[2*i] + 1; 00143 ++i; 00144 } 00145 00146 GLint width; 00147 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &width); 00148 this->Loaded = textureSize[0] <= width && textureSize[1] <= width && 00149 textureSize[2] <= width; 00150 if(this->Loaded) 00151 { 00152 // so far, so good but some cards don't report allocation error 00153 this->Loaded = textureSize[0] * textureSize[1]* 00154 textureSize[2] * 00155 vtkAbstractArray::GetDataTypeSize(scalarType) * 00156 scalars->GetNumberOfComponents() <= 00157 maxMemoryInBytes; 00158 if(this->Loaded) 00159 { 00160 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 00161 00162 if(!(textureExtent[1]-textureExtent[0]+cellFlag==dim[0])) 00163 { 00164 glPixelStorei(GL_UNPACK_ROW_LENGTH,dim[0]-cellFlag); 00165 } 00166 if(!(textureExtent[3]-textureExtent[2]+cellFlag==dim[1])) 00167 { 00168 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT_EXT, 00169 dim[1]-cellFlag); 00170 } 00171 void* dataPtr = scalars->GetVoidPointer( 00172 ((textureExtent[4]*(dim[1]-cellFlag)+textureExtent[2]) * 00173 (dim[0]-cellFlag)+textureExtent[0]) * 00174 scalars->GetNumberOfComponents()); 00175 00176 this->Texture->SetDataType(type); 00177 this->Texture->SetFormat(format); 00178 this->Texture->SetInternalFormat(internalFormat); 00179 this->Texture->Create3DFromRaw( 00180 textureSize[0], textureSize[1], textureSize[2], 00181 1, scalarType, dataPtr); 00182 this->Texture->Activate(); 00183 this->Texture->SetWrapS(vtkTextureObject::ClampToEdge); 00184 this->Texture->SetWrapT(vtkTextureObject::ClampToEdge); 00185 this->Texture->SetWrapR(vtkTextureObject::ClampToEdge); 00186 this->Texture->SetMagnificationFilter(vtkTextureObject::Nearest); 00187 this->Texture->SetMinificationFilter(vtkTextureObject::Nearest); 00188 this->Texture->SetBorderColor(0.0f, 0.0f, 0.0f, 0.0f); 00189 00190 // Restore the default values. 00191 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 00192 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT_EXT, 0); 00193 00194 this->LoadedCellFlag = cellFlag; 00195 i = 0; 00196 while(i < 6) 00197 { 00198 this->LoadedExtent[i] = textureExtent[i]; 00199 ++i; 00200 } 00201 00202 double spacing[3]; 00203 double origin[3]; 00204 input->GetSpacing(spacing); 00205 input->GetOrigin(origin); 00206 int swapBounds[3]; 00207 swapBounds[0] = (spacing[0] < 0); 00208 swapBounds[1] = (spacing[1] < 0); 00209 swapBounds[2] = (spacing[2] < 0); 00210 00211 if(!this->LoadedCellFlag) // loaded extents represent points 00212 { 00213 // slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2]; 00214 // in general, x=o+i*spacing. 00215 // if spacing is positive min extent match the min of the 00216 // bounding box 00217 // and the max extent match the max of the bounding box 00218 // if spacing is negative min extent match the max of the 00219 // bounding box 00220 // and the max extent match the min of the bounding box 00221 00222 // if spacing is negative, we may have to rethink the equation 00223 // between real point and texture coordinate... 00224 this->LoadedBounds[0]=origin[0]+ 00225 static_cast<double>(this->LoadedExtent[0+swapBounds[0]])*spacing[0]; 00226 this->LoadedBounds[2]=origin[1]+ 00227 static_cast<double>(this->LoadedExtent[2+swapBounds[1]])*spacing[1]; 00228 this->LoadedBounds[4]=origin[2]+ 00229 static_cast<double>(this->LoadedExtent[4+swapBounds[2]])*spacing[2]; 00230 this->LoadedBounds[1]=origin[0]+ 00231 static_cast<double>(this->LoadedExtent[1-swapBounds[0]])*spacing[0]; 00232 this->LoadedBounds[3]=origin[1]+ 00233 static_cast<double>(this->LoadedExtent[3-swapBounds[1]])*spacing[1]; 00234 this->LoadedBounds[5]=origin[2]+ 00235 static_cast<double>(this->LoadedExtent[5-swapBounds[2]])*spacing[2]; 00236 00237 } 00238 else // loaded extents represent cells 00239 { 00240 int wholeTextureExtent[6]; 00241 input->GetExtent(wholeTextureExtent); 00242 i=1; 00243 while(i<6) 00244 { 00245 wholeTextureExtent[i]--; 00246 i+=2; 00247 } 00248 00249 i=0; 00250 while(i<3) 00251 { 00252 if(this->LoadedExtent[2*i]==wholeTextureExtent[2*i]) 00253 { 00254 this->LoadedBounds[2*i+swapBounds[i]]=origin[i]; 00255 } 00256 else 00257 { 00258 this->LoadedBounds[2*i+swapBounds[i]]=origin[i]+ 00259 (static_cast<double>(this->LoadedExtent[2*i])+0.5)*spacing[i]; 00260 } 00261 00262 if(this->LoadedExtent[2*i+1]==wholeTextureExtent[2*i+1]) 00263 { 00264 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+ 00265 (static_cast<double>(this->LoadedExtent[2*i+1])+1.0)*spacing[i]; 00266 } 00267 else 00268 { 00269 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+ 00270 (static_cast<double>(this->LoadedExtent[2*i+1])+0.5)*spacing[i]; 00271 } 00272 ++i; 00273 } 00274 } 00275 modified = true; 00276 } 00277 } 00278 } 00279 00280 if(modified) 00281 { 00282 this->BuildTime.Modified(); 00283 } 00284 } 00285 00286 //-------------------------------------------------------------------------- 00287 double* GetLoadedBounds() 00288 { 00289 return this->LoadedBounds; 00290 } 00291 00292 //-------------------------------------------------------------------------- 00293 vtkIdType* GetLoadedExtent() 00294 { 00295 return this->LoadedExtent; 00296 } 00297 00298 //-------------------------------------------------------------------------- 00299 int GetLoadedCellFlag() 00300 { 00301 return this->LoadedCellFlag; 00302 } 00303 00304 //-------------------------------------------------------------------------- 00305 bool IsLoaded() 00306 { 00307 return this->Loaded; 00308 } 00309 00310 // Get the texture unit 00311 //-------------------------------------------------------------------------- 00312 int GetTextureUnit(void) 00313 { 00314 if (!this->Texture) 00315 { 00316 return -1; 00317 } 00318 return this->Texture->GetTextureUnit(); 00319 } 00320 00321 //-------------------------------------------------------------------------- 00322 void ReleaseGraphicsResources(vtkWindow *window) 00323 { 00324 if (this->Texture) 00325 { 00326 this->Texture->ReleaseGraphicsResources(window); 00327 this->Texture->Delete(); 00328 this->Texture = 0; 00329 } 00330 } 00331 00332 00333 protected: 00334 vtkTextureObject* Texture; 00335 vtkTimeStamp BuildTime; 00336 00337 double LoadedBounds[6]; 00338 vtkIdType LoadedExtent[6]; 00339 00340 int LoadedCellFlag; 00341 bool Loaded; 00342 }; 00343 00344 //---------------------------------------------------------------------------- 00345 class vtkMapMaskTextureId 00346 { 00347 public: 00348 std::map<vtkImageData *,vtkVolumeMask*> Map; 00349 vtkMapMaskTextureId() 00350 { 00351 } 00352 private: 00353 vtkMapMaskTextureId(const vtkMapMaskTextureId &other); 00354 vtkMapMaskTextureId &operator=(const vtkMapMaskTextureId &other); 00355 }; 00356 00357 #endif // vtkVolumeMask_h_ 00358 // VTK-HeaderTest-Exclude: vtkVolumeMask.h