VTK
/Users/kitware/Dashboards/MyTests/VTK_BLD_Release_docs/Utilities/Doxygen/dox/Rendering/VolumeOpenGL2/vtkVolumeMask.h
Go to the documentation of this file.
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