本文只是整理了该网页的内容:http://www.cnblogs.com/lizhengjin/archive/2009/08/16/1547340.html
vtkMapper是一个抽象类,指定了几何数据和图元的接口,子类化vtkMapper,利用颜色查找表把数据映射成图元;封装了opengl的核心函数glBegin(GL_Vertex)glEnd()等生成图元的函数。
有几个重要的机制影响Actror的行为,ScalarVisibility控制标量数据如点属性,单元属性是否启用.
标量模式(ScalarMode)ivar 被用来决定是使用点的scalar数据还是拓扑结构(cell data)的scalar为模型对象(object)添加彩色。默认情况下,是使用点的scalar,当然,如果point和cell都没有scalar,也就不会有添加颜色这个动作了。反之,你也可以明确指出是使用点(point)的scalar或cell的scalar。最后,通过查找颜色表的方式将颜色映射(mapping)到模型对象上,颜色模式是由ColorMode flag决定。
该类的另一个特点是,是否使用“直接渲染模式(immediate mode rendering)”,在直接渲染模式关闭的情况下,则使用“显示链表渲染模式(display list rendering)”。如果使用显示链表模式渲染,就需要构建一个数据结构,通过渲染库(renering library)可以快速完成数据结构构建,并渲染。显示链表渲染模式的一个弱点是,需要另外开辟内存,这会影响运行性能。
// Another important feature of the mapper is the ability to shift the
// z-buffer to resolve coincident topology. For example, if you'd like to
// draw a mesh with some edges a different color, and the edges lie on the
// mesh, this feature can be useful to get nice looking lines. (See the
// ResolveCoincidentTopology-related methods.)
//另一个特性是利用z-buffer去解决深度容差,比如,如果你想画一个网格,这个网格带有边界,并且边界线的
艳色和网格的艳色不一样,这个时候打开深度偏移就可以得到很好的效果
映射器的另一个重要特征是,它能够沿着z-buffer深度方向,逐像素解析同一个拓扑结构。比如,如果你想绘制一个网格,网格上有不同颜色的边线(edges),映射器的这个特征可以使得不同颜色之间有一个渐变的过程,这样我们就会得到非常好看的线段(参见ResolveConincidentTopology方法)。
// .SECTION See Also // vtkDataSetMapper vtkPolyDataMapper #ifndef __vtkMapper_h #define __vtkMapper_h #include "vtkAbstractMapper3D.h" #include "vtkScalarsToColors.h" // For VTK_COLOR_MODE_DEFAULT and _MAP_SCALARS #define VTK_RESOLVE_OFF 0 #define VTK_RESOLVE_POLYGON_OFFSET 1 #define VTK_RESOLVE_SHIFT_ZBUFFER 2 #define VTK_GET_ARRAY_BY_ID 0 #define VTK_GET_ARRAY_BY_NAME 1 #define VTK_MATERIALMODE_DEFAULT 0 #define VTK_MATERIALMODE_AMBIENT 1 #define VTK_MATERIALMODE_DIFFUSE 2 #define VTK_MATERIALMODE_AMBIENT_AND_DIFFUSE 3 class vtkWindow; class vtkRenderer; class vtkActor; class vtkDataSet; class vtkFloatArray; class vtkImageData; class VTK_RENDERING_EXPORT vtkMapper : public vtkAbstractMapper3D { public: vtkTypeRevisionMacro(vtkMapper,vtkAbstractMapper3D); void PrintSelf(ostream& os, vtkIndent indent); // Description: // Make a shallow copy of this mapper. void ShallowCopy(vtkAbstractMapper *m); // Description: // Overload standard modified time function. If lookup table is modified, // then this object is modified as well. unsigned long GetMTime(); // Description: // Method initiates the mapping process. Generally sent by the actor // as each frame is rendered. virtual void Render(vtkRenderer *ren, vtkActor *a) = 0;//执行渲染的代码,由子类实现 // Description: // Release any graphics resources that are being consumed by this mapper. // The parameter window could be used to determine which graphic // resources to release. virtual void ReleaseGraphicsResources(vtkWindow *) {}; // Description: // Specify a lookup table for the mapper to use. void SetLookupTable(vtkScalarsToColors *lut);设置艳色查找表,给actor着色 vtkScalarsToColors *GetLookupTable(); // Description: // Create default lookup table. Generally used to create one when none // is available with the scalar data. virtual void CreateDefaultLookupTable(); // Description: // Turn on/off flag to control whether scalar data is used to color objects. vtkSetMacro(ScalarVisibility,int); vtkGetMacro(ScalarVisibility,int); vtkBooleanMacro(ScalarVisibility,int); // Description: // Turn on/off flag to control whether the mapper's data is static. Static data // means that the mapper does not propagate updates down the pipeline, greatly // decreasing the time it takes to update many mappers. This should only be // used if the data never changes. //如果mapper里面的数据集不发生变化的时候,可以极大的增加速度 vtkSetMacro(Static,int); vtkGetMacro(Static,int); vtkBooleanMacro(Static,int); // Description: // Control how the scalar data is mapped to colors. By default // (ColorModeToDefault), unsigned char scalars are treated as colors, and // NOT mapped through the lookup table, while everything else is. Setting // ColorModeToMapScalars means that all scalar data will be mapped through // the lookup table. (Note that for multi-component scalars, the // particular component to use for mapping can be specified using the // SelectColorArray() method.) //所有的艳色模式都要通过艳色查找表实现 vtkSetMacro(ColorMode,int); vtkGetMacro(ColorMode,int); void SetColorModeToDefault() {this->SetColorMode(VTK_COLOR_MODE_DEFAULT);}; void SetColorModeToMapScalars() {this->SetColorMode(VTK_COLOR_MODE_MAP_SCALARS);}; // Description: // Return the method of coloring scalar data. const char *GetColorModeAsString(); // Description: // By default, vertex color is used to map colors to a surface. // Colors are interpolated after being mapped. // This option avoids color interpolation by using a one dimensional // texture map for the colors. //映射艳色后插值 vtkSetMacro(InterpolateScalarsBeforeMapping,int); vtkGetMacro(InterpolateScalarsBeforeMapping,int); vtkBooleanMacro(InterpolateScalarsBeforeMapping,int); // Description: // Control whether the mapper sets the lookuptable range based on its // own ScalarRange, or whether it will use the LookupTable ScalarRange // regardless of it's own setting. By default the Mapper is allowed to set // the LookupTable range, but users who are sharing LookupTables between // mappers/actors will probably wish to force the mapper to use the // LookupTable unchanged. vtkSetMacro(UseLookupTableScalarRange,int); vtkGetMacro(UseLookupTableScalarRange,int); vtkBooleanMacro(UseLookupTableScalarRange,int); // Description: // Specify range in terms of scalar minimum and maximum (smin,smax). These // values are used to map scalars into lookup table. Has no effect when // UseLookupTableScalarRange is true. vtkSetVector2Macro(ScalarRange,double); vtkGetVectorMacro(ScalarRange,double,2); // Description: // Turn on/off flag to control whether data is rendered using // immediate mode or note. Immediate mode rendering // tends to be slower but it can handle larger datasets. // The default value is immediate mode off. If you are // having problems rendering a large dataset you might // want to consider using immediate more rendering. //控制是否渲染大的数据集 vtkSetMacro(ImmediateModeRendering,int); vtkGetMacro(ImmediateModeRendering,int); vtkBooleanMacro(ImmediateModeRendering,int); // Description: // Turn on/off flag to control whether data is rendered using // immediate mode or note. Immediate mode rendering // tends to be slower but it can handle larger datasets. // The default value is immediate mode off. If you are // having problems rendering a large dataset you might // want to consider using immediate more rendering. static void SetGlobalImmediateModeRendering(int val); static void GlobalImmediateModeRenderingOn() {vtkMapper::SetGlobalImmediateModeRendering(1);}; static void GlobalImmediateModeRenderingOff() {vtkMapper::SetGlobalImmediateModeRendering(0);}; static int GetGlobalImmediateModeRendering(); // Description: // Control how the filter works with scalar point data and cell attribute // data. By default (ScalarModeToDefault), the filter will use point data, // and if no point data is available, then cell data is used. Alternatively // you can explicitly set the filter to use point data // (ScalarModeToUsePointData) or cell data (ScalarModeToUseCellData). // You can also choose to get the scalars from an array in point field // data (ScalarModeToUsePointFieldData) or cell field data // (ScalarModeToUseCellFieldData). If scalars are coming from a field // data array, you must call SelectColorArray before you call // GetColors. // When ScalarMode is set to use Field Data (ScalarModeToFieldData), you // must call SelectColorArray to choose the field data array to be used to // color cells. In this mode, if the poly data has triangle strips, // the field data is treated as the celldata for each mini-cell formed by // a triangle in the strip rather than the entire strip. vtkSetMacro(ScalarMode,int); vtkGetMacro(ScalarMode,int); void SetScalarModeToDefault() { this->SetScalarMode(VTK_SCALAR_MODE_DEFAULT);}; void SetScalarModeToUsePointData() { this->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_DATA);}; void SetScalarModeToUseCellData() { this->SetScalarMode(VTK_SCALAR_MODE_USE_CELL_DATA);}; void SetScalarModeToUsePointFieldData() { this->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);}; void SetScalarModeToUseCellFieldData() { this->SetScalarMode(VTK_SCALAR_MODE_USE_CELL_FIELD_DATA);}; void SetScalarModeToUseFieldData() { this->SetScalarMode(VTK_SCALAR_MODE_USE_FIELD_DATA); } // Description: // When ScalarMode is set to UsePointFieldData or UseCellFieldData, // you can specify which array to use for coloring using these methods. // The lookup table will decide how to convert vectors to colors. //用点哉属性或者单元哉属性 void SelectColorArray(int arrayNum); void SelectColorArray(const char* arrayName); // Description: // Legacy: // These methods used to be used to specify the array component. // It is better to do this in the lookup table. void ColorByArrayComponent(int arrayNum, int component); void ColorByArrayComponent(const char* arrayName, int component); // Description: // Get the array name or number and component to color by. char* GetArrayName() { return this->ArrayName; } int GetArrayId() { return this->ArrayId; } int GetArrayAccessMode() { return this->ArrayAccessMode; } int GetArrayComponent() { return this->ArrayComponent; } // Description: // Return the method for obtaining scalar data. const char *GetScalarModeAsString(); // Description: // Set/Get a global flag that controls whether coincident topology (e.g., a // line on top of a polygon) is shifted to avoid z-buffer resolution (and // hence rendering problems). If not off, there are two methods to choose // from. PolygonOffset uses graphics systems calls to shift polygons, but // does not distinguish vertices and lines from one another. ShiftZBuffer // remaps the z-buffer to distinguish vertices, lines, and polygons, but // does not always produce acceptable results. If you use the ShiftZBuffer // approach, you may also want to set the ResolveCoincidentTopologyZShift // value. (Note: not all mappers/graphics systems implement this // functionality.) static void SetResolveCoincidentTopology(int val); static int GetResolveCoincidentTopology(); static void SetResolveCoincidentTopologyToDefault(); static void SetResolveCoincidentTopologyToOff() {SetResolveCoincidentTopology(VTK_RESOLVE_OFF);} static void SetResolveCoincidentTopologyToPolygonOffset() {SetResolveCoincidentTopology(VTK_RESOLVE_POLYGON_OFFSET);} static void SetResolveCoincidentTopologyToShiftZBuffer() {SetResolveCoincidentTopology(VTK_RESOLVE_SHIFT_ZBUFFER);} // Description: // Used to set the polygon offset scale factor and units. // Used when ResolveCoincidentTopology is set to PolygonOffset. // These are global variables. static void SetResolveCoincidentTopologyPolygonOffsetParameters( double factor, double units); static void GetResolveCoincidentTopologyPolygonOffsetParameters( double& factor, double& units); // Description: // Used when ResolveCoincidentTopology is set to PolygonOffset. The polygon // offset can be applied either to the solid polygonal faces or the // lines/vertices. When set (default), the offset is applied to the faces // otherwise it is applied to lines and vertices. // This is a global variable. static void SetResolveCoincidentTopologyPolygonOffsetFaces(int faces); static int GetResolveCoincidentTopologyPolygonOffsetFaces(); // Description: // Used to set the z-shift if ResolveCoincidentTopology is set to // ShiftZBuffer. This is a global variable. static void SetResolveCoincidentTopologyZShift(double val); static double GetResolveCoincidentTopologyZShift(); // Description: // Return bounding box (array of six doubles) of data expressed as // (xmin,xmax, ymin,ymax, zmin,zmax). virtual double *GetBounds(); virtual void GetBounds(double bounds[6]) {this->vtkAbstractMapper3D::GetBounds(bounds);}; // Description: // This instance variable is used by vtkLODActor to determine which // mapper to use. It is an estimate of the time necessary to render. // Setting the render time does not modify the mapper. //vtkLoadActor在不同的时刻需要不同的vtkMapper void SetRenderTime(double time) {this->RenderTime = time;} vtkGetMacro(RenderTime, double); //BTX // Description: // Get the input as a vtkDataSet. This method is overridden in // the specialized mapper classes to return more specific data types. vtkDataSet *GetInput(); //ETX // Description: // Get the input to this mapper as a vtkDataSet, instead of as a // more specialized data type that the subclass may return from // GetInput(). This method is provided for use in the wrapper languages, // C++ programmers should use GetInput() instead. vtkDataSet *GetInputAsDataSet() {return this->GetInput();} // Description: // Map the scalars (if there are any scalars and ScalarVisibility is on) // through the lookup table, returning an unsigned char RGBA array. This is // typically done as part of the rendering process. The alpha parameter // allows the blending of the scalars with an additional alpha (typically // which comes from a vtkActor, etc.) vtkUnsignedCharArray *MapScalars(double alpha); // Description: // Set/Get the light-model color mode. vtkSetMacro(ScalarMaterialMode,int); vtkGetMacro(ScalarMaterialMode,int); void SetScalarMaterialModeToDefault() {this->SetScalarMaterialMode(VTK_MATERIALMODE_DEFAULT);}; void SetScalarMaterialModeToAmbient() {this->SetScalarMaterialMode(VTK_MATERIALMODE_AMBIENT);}; void SetScalarMaterialModeToDiffuse() {this->SetScalarMaterialMode(VTK_MATERIALMODE_DIFFUSE);}; void SetScalarMaterialModeToAmbientAndDiffuse() {this->SetScalarMaterialMode(VTK_MATERIALMODE_AMBIENT_AND_DIFFUSE);}; // Description: // Return the light-model color mode. const char *GetScalarMaterialModeAsString(); protected: vtkMapper(); ~vtkMapper(); vtkUnsignedCharArray *Colors; // Use texture coordinates for coloring. int InterpolateScalarsBeforeMapping; // Coordinate for each point. vtkFloatArray *ColorCoordinates; // 1D ColorMap used for the texture image. vtkImageData* ColorTextureMap; void MapScalarsToTexture(vtkDataArray* scalars, double alpha); vtkScalarsToColors *LookupTable; int ScalarVisibility; vtkTimeStamp BuildTime; double ScalarRange[2]; int UseLookupTableScalarRange; int ImmediateModeRendering; int ColorMode; int ScalarMode; int ScalarMaterialMode; double RenderTime; // for coloring by a component of a field data array int ArrayId; char ArrayName[256]; int ArrayComponent; int ArrayAccessMode; int Static; private: vtkMapper(const vtkMapper&); // Not implemented. void operator=(const vtkMapper&); // Not implemented. }; #endif //提供了艳色查找表,深度偏移等 #include "vtkMapper.h" #include "vtkDataSet.h" #include "vtkExecutive.h" #include "vtkLookupTable.h" #include "vtkFloatArray.h" #include "vtkImageData.h" #include "vtkPointData.h" #include "vtkMath.h" vtkCxxRevisionMacro(vtkMapper, "$Revision: 1.122 $"); // Initialize static member that controls global immediate mode rendering static int vtkMapperGlobalImmediateModeRendering = 0; // Initialize static member that controls global coincidence resolution static int vtkMapperGlobalResolveCoincidentTopology = VTK_RESOLVE_OFF; static double vtkMapperGlobalResolveCoincidentTopologyZShift = 0.01; static double vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor = 1.0; static double vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits = 1.0; static int vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces = 1; //偏移相关的参数 // Construct with initial range (0,1). vtkMapper::vtkMapper() { this->Colors = 0; this->Static = 0; this->LookupTable = 0; this->ScalarVisibility = 1; this->ScalarRange[0] = 0.0; this->ScalarRange[1] = 1.0; this->UseLookupTableScalarRange = 0; this->ImmediateModeRendering = 0; this->ColorMode = VTK_COLOR_MODE_DEFAULT; this->ScalarMode = VTK_SCALAR_MODE_DEFAULT; this->ScalarMaterialMode = VTK_MATERIALMODE_DEFAULT; vtkMath::UninitializeBounds(this->Bounds); this->Center[0] = this->Center[1] = this->Center[2] = 0.0; this->RenderTime = 0.0; strcpy(this->ArrayName, ""); this->ArrayId = -1; this->ArrayComponent = 0; this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID; this->InterpolateScalarsBeforeMapping = 0; this->ColorCoordinates = 0; this->ColorTextureMap = 0; } vtkMapper::~vtkMapper() { if (this->LookupTable) { this->LookupTable->UnRegister(this); } if ( this->Colors != 0 ) { this->Colors->UnRegister(this); } if ( this->ColorCoordinates != 0 ) { this->ColorCoordinates->UnRegister(this); } if ( this->ColorTextureMap != 0 ) { this->ColorTextureMap->UnRegister(this); } } // Get the bounds for the input of this mapper as // (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax). double *vtkMapper::GetBounds() { static double bounds[] = {-1.0,1.0, -1.0,1.0, -1.0,1.0}; vtkDataSet *input = this->GetInput(); if ( ! input ) { return bounds; } else { if (!this->Static) { this->Update(); } input->GetBounds(this->Bounds); return this->Bounds; } } vtkDataSet *vtkMapper::GetInput() { if (this->GetNumberOfInputConnections(0) < 1) { return 0; } return vtkDataSet::SafeDownCast( this->GetExecutive()->GetInputData(0, 0)); } void vtkMapper::SetGlobalImmediateModeRendering(int val) { if (val == vtkMapperGlobalImmediateModeRendering) { return; } vtkMapperGlobalImmediateModeRendering = val; } int vtkMapper::GetGlobalImmediateModeRendering() { return vtkMapperGlobalImmediateModeRendering; } void vtkMapper::SetResolveCoincidentTopology(int val) { if (val == vtkMapperGlobalResolveCoincidentTopology) { return; } vtkMapperGlobalResolveCoincidentTopology = val; } int vtkMapper::GetResolveCoincidentTopology() { return vtkMapperGlobalResolveCoincidentTopology; } void vtkMapper::SetResolveCoincidentTopologyToDefault() { vtkMapperGlobalResolveCoincidentTopology = VTK_RESOLVE_OFF; } void vtkMapper::SetResolveCoincidentTopologyZShift(double val) { if (val == vtkMapperGlobalResolveCoincidentTopologyZShift) { return; } vtkMapperGlobalResolveCoincidentTopologyZShift = val; } double vtkMapper::GetResolveCoincidentTopologyZShift() { return vtkMapperGlobalResolveCoincidentTopologyZShift; } void vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters( double factor, double units) { if (factor == vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor && units == vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits ) { return; } vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor = factor; vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits = units; } void vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters( double& factor, double& units) { factor = vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor; units = vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits; } void vtkMapper::SetResolveCoincidentTopologyPolygonOffsetFaces(int faces) { vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces = faces; } int vtkMapper::GetResolveCoincidentTopologyPolygonOffsetFaces() { return vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces; } // Overload standard modified time function. If lookup table is modified, // then this object is modified as well. unsigned long vtkMapper::GetMTime() { //unsigned long mTime=this->MTime.GetMTime(); unsigned long mTime=vtkAbstractMapper::GetMTime(); unsigned long lutMTime; if ( this->LookupTable != NULL ) { lutMTime = this->LookupTable->GetMTime(); mTime = ( lutMTime > mTime ? lutMTime : mTime ); } return mTime; } void vtkMapper::ShallowCopy(vtkAbstractMapper *mapper) { vtkMapper *m = vtkMapper::SafeDownCast(mapper); if ( m != NULL ) { this->SetLookupTable(m->GetLookupTable()); this->SetScalarVisibility(m->GetScalarVisibility()); this->SetScalarRange(m->GetScalarRange()); this->SetColorMode(m->GetColorMode()); this->SetScalarMode(m->GetScalarMode()); this->SetScalarMaterialMode(m->GetScalarMaterialMode()); this->SetImmediateModeRendering(m->GetImmediateModeRendering()); this->SetUseLookupTableScalarRange(m->GetUseLookupTableScalarRange()); if ( m->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID ) { this->ColorByArrayComponent(m->GetArrayId(),m->GetArrayComponent()); } else { this->ColorByArrayComponent(m->GetArrayName(),m->GetArrayComponent()); } } // Now do superclass this->vtkAbstractMapper3D::ShallowCopy(mapper); } // a side effect of this is that this->Colors is also set // to the return value vtkUnsignedCharArray *vtkMapper::MapScalars(double alpha) { int cellFlag = 0; vtkDataArray *scalars = vtkAbstractMapper:: GetScalars(this->GetInput(), this->ScalarMode, this->ArrayAccessMode, this->ArrayId, this->ArrayName, cellFlag); // This is for a legacy feature: selection of the array component to color by // from the mapper. It is now in the lookuptable. When this feature // is removed, we can remove this condition. if (scalars == 0 || scalars->GetNumberOfComponents() <= this->ArrayComponent) { this->ArrayComponent = 0; } if ( !this->ScalarVisibility || scalars==0 || this->GetInput()==0) { // No scalar colors. if ( this->ColorCoordinates ) { this->ColorCoordinates->UnRegister(this); this->ColorCoordinates = 0; } if ( this->ColorTextureMap ) { this->ColorTextureMap->UnRegister(this); this->ColorTextureMap = 0; } if ( this->Colors ) { this->Colors->UnRegister(this); this->Colors = 0; } return 0; } // Get the lookup table. if ( scalars->GetLookupTable() ) { this->SetLookupTable(scalars->GetLookupTable()); } else { // make sure we have a lookup table//make sure we have a lookup table if ( this->LookupTable == 0 ) { this->CreateDefaultLookupTable(); } this->LookupTable->Build(); } if ( !this->UseLookupTableScalarRange ) { this->LookupTable->SetRange(this->ScalarRange); } // Decide betweeen texture color or vertex color. // Cell data always uses vertext color. // Only point data can use both texture and vertext coloring. if (this->InterpolateScalarsBeforeMapping && ! cellFlag) { // Only use texture color if we are mapping scalars. // Directly coloring with RGB unsigned chars should not use texture. if ( this->ColorMode != VTK_COLOR_MODE_DEFAULT || (vtkUnsignedCharArray::SafeDownCast(scalars)) == 0 ) { // Texture color option. this->MapScalarsToTexture(scalars, alpha); return 0; } } // Vertex colors are being used. // Get rid of texure Color arrays. Only texture or vertex coloring // can be active at one time. The existence of the array is the // signal to use that technique. if ( this->ColorCoordinates ) { this->ColorCoordinates->UnRegister(this); this->ColorCoordinates = 0; } if ( this->ColorTextureMap ) { this->ColorTextureMap->UnRegister(this); this->ColorTextureMap = 0; } // Lets try to resuse the old colors.//Lets try to resuse the old colors; if (this->Colors) { if (this->LookupTable && this->LookupTable->GetAlpha() == alpha) { if (this->GetMTime() < this->Colors->GetMTime() && this->GetInput()->GetMTime() < this->Colors->GetMTime() && this->LookupTable->GetMTime() < this->Colors->GetMTime()) { return this->Colors; } } } // Get rid of old colors if ( this->Colors ) { this->Colors->UnRegister(this); this->Colors = 0; } // map scalars this->LookupTable->SetAlpha(alpha); this->Colors = this->LookupTable-> MapScalars(scalars, this->ColorMode, this->ArrayComponent); // Consistent register and unregisters this->Colors->Register(this); this->Colors->Delete(); return this->Colors; } void vtkMapper::SelectColorArray(int arrayNum)//SelectColorArray(int arrayNum) { this->ColorByArrayComponent(arrayNum, -1); } void vtkMapper::SelectColorArray(const char* arrayName) { this->ColorByArrayComponent(arrayName, -1); } void vtkMapper::ColorByArrayComponent(int arrayNum, int component) { if (this->ArrayId == arrayNum && component == this->ArrayComponent && this->ArrayAccessMode == VTK_GET_ARRAY_BY_ID) { return; } this->Modified(); this->ArrayId = arrayNum; this->ArrayComponent = component; this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID; } void vtkMapper::ColorByArrayComponent(const char* arrayName, int component) { if (!arrayName || ( strcmp(this->ArrayName, arrayName) == 0 && component == this->ArrayComponent && this->ArrayAccessMode == VTK_GET_ARRAY_BY_NAME )) { return; } this->Modified(); strcpy(this->ArrayName, arrayName); this->ArrayComponent = component; this->ArrayAccessMode = VTK_GET_ARRAY_BY_NAME; } // Specify a lookup table for the mapper to use. void vtkMapper::SetLookupTable(vtkScalarsToColors *lut) { if ( this->LookupTable != lut ) { if ( this->LookupTable) { this->LookupTable->UnRegister(this); } this->LookupTable = lut; if (lut) { lut->Register(this); } this->Modified(); } } vtkScalarsToColors *vtkMapper::GetLookupTable() { if ( this->LookupTable == 0 ) { this->CreateDefaultLookupTable(); } return this->LookupTable; } void vtkMapper::CreateDefaultLookupTable() { if ( this->LookupTable) { this->LookupTable->UnRegister(this); } this->LookupTable = vtkLookupTable::New(); // Consistent Register/UnRegisters. this->LookupTable->Register(this); this->LookupTable->Delete(); } // Return the method of coloring scalar data. const char *vtkMapper::GetColorModeAsString(void) { if ( this->ColorMode == VTK_COLOR_MODE_MAP_SCALARS ) { return "MapScalars"; } else { return "Default"; } } // Return the method for obtaining scalar data. const char *vtkMapper::GetScalarModeAsString(void) { if ( this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ) { return "UseCellData"; } else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_POINT_DATA ) { return "UsePointData"; } else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_POINT_FIELD_DATA ) { return "UsePointFieldData"; } else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ) { return "UseCellFieldData"; } else { return "Default"; } } const char *vtkMapper::GetScalarMaterialModeAsString(void) { if ( this->ScalarMaterialMode == VTK_MATERIALMODE_AMBIENT ) { return "Ambient"; } else if ( this->ScalarMaterialMode == VTK_MATERIALMODE_DIFFUSE ) { return "Diffuse"; } else if ( this->ScalarMaterialMode == VTK_MATERIALMODE_AMBIENT_AND_DIFFUSE ) { return "Ambient and Diffuse"; } else { return "Default"; } } template<class T> void vtkMapperCreateColorTextureCoordinates(T* input, float* output, vtkIdType num, int numComps, int component, double* range) { double tmp, sum; double k = 1.0 / (range[1]-range[0]); vtkIdType i; int j; if (component < 0 || component >= numComps) { for (i = 0; i < num; ++i) { sum = 0; for (j = 0; j < numComps; ++j) { tmp = static_cast<double>(*input); sum += (tmp * tmp); ++input; } output[i] = k * (sqrt(sum) - range[0]); if (output[i] > 1.0) { output[i] = 1.0; } if (output[i] < 0.0) { output[i] = 0.0; } } } else { input += component; for (i = 0; i < num; ++i) { output[i] = k * (static_cast<double>(*input) - range[0]); if (output[i] > 1.0) { output[i] = 1.0; } if (output[i] < 0.0) { output[i] = 0.0; } input = input + numComps; } } } #define ColorTextureMapSize 256 // a side effect of this is that this->ColorCoordinates and // this->ColorTexture are set. void vtkMapper::MapScalarsToTexture(vtkDataArray* scalars, double alpha) { double* range = this->LookupTable->GetRange(); // Get rid of vertex color array. Only texture or vertex coloring // can be active at one time. The existence of the array is the // signal to use that technique. if ( this->Colors ) { this->Colors->UnRegister(this); this->Colors = 0; } // If the lookup table has changed, the recreate the color texture map. // Set a new lookup table changes this->MTime. if (this->ColorTextureMap == 0 || this->GetMTime() > this->ColorTextureMap->GetMTime() || this->LookupTable->GetMTime() > this->ColorTextureMap->GetMTime() || this->LookupTable->GetAlpha() != alpha) { this->LookupTable->SetAlpha(alpha); if ( this->ColorTextureMap ) { this->ColorTextureMap->UnRegister(this); this->ColorTextureMap = 0; } // Get the texture map from the lookup table. // Create a dummy ramp of scalars. // In the future, we could extend vtkScalarsToColors. double k = (range[1]-range[0]) / (ColorTextureMapSize-1); vtkFloatArray* tmp = vtkFloatArray::New(); tmp->SetNumberOfTuples(ColorTextureMapSize); float* ptr = tmp->GetPointer(0); for (int i = 0; i < ColorTextureMapSize; ++i) { *ptr = range[0] + i * k; ++ptr; } this->ColorTextureMap = vtkImageData::New(); this->ColorTextureMap->SetExtent(0,ColorTextureMapSize-1, 0,0, 0,0); this->ColorTextureMap->SetNumberOfScalarComponents(4); this->ColorTextureMap->SetScalarTypeToUnsignedChar(); this->ColorTextureMap->GetPointData()->SetScalars( this->LookupTable->MapScalars(tmp, this->ColorMode, 0)); // Do we need to delete the scalars? this->ColorTextureMap->GetPointData()->GetScalars()->Delete(); // Consistent register and unregisters this->ColorTextureMap->Register(this); this->ColorTextureMap->Delete(); tmp->Delete(); } // Create new coordinates if necessary. // Need to compare lookup table incase the range has changed. if (this->ColorCoordinates == 0 || this->GetMTime() > this->ColorCoordinates->GetMTime() || this->GetInput()->GetMTime() > this->ColorCoordinates->GetMTime() || this->LookupTable->GetMTime() > this->ColorCoordinates->GetMTime()) { // Get rid of old colors if ( this->ColorCoordinates ) { this->ColorCoordinates->UnRegister(this); this->ColorCoordinates = 0; } // Now create the color texture coordinates. int numComps = scalars->GetNumberOfComponents(); void* input = scalars->GetVoidPointer(0); vtkIdType num = scalars->GetNumberOfTuples(); this->ColorCoordinates = vtkFloatArray::New(); this->ColorCoordinates->SetNumberOfTuples(num); float* output = this->ColorCoordinates->GetPointer(0); int scalarComponent; // Although I like the feature of applying magnitude to single component // scalars, it is not how the old MapScalars for vertex coloring works. if (this->LookupTable->GetVectorMode() == vtkScalarsToColors::MAGNITUDE && scalars->GetNumberOfComponents() > 1) { scalarComponent = -1; } else { scalarComponent = this->LookupTable->GetVectorComponent(); } switch (scalars->GetDataType()) { vtkTemplateMacro( vtkMapperCreateColorTextureCoordinates(static_cast<VTK_TT*>(input), output, num, numComps, scalarComponent, range) ); case VTK_BIT: vtkErrorMacro("Cannot color by bit array."); break; default: vtkErrorMacro(<< "Unknown input ScalarType"); return; } } } void vtkMapper::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); if ( this->LookupTable ) { os << indent << "Lookup Table: "; this->LookupTable->PrintSelf(os,indent.GetNextIndent()); } else { os << indent << "Lookup Table: (none) "; } os << indent << "Immediate Mode Rendering: " << (this->ImmediateModeRendering ? "On " : "Off "); os << indent << "Global Immediate Mode Rendering: " << (vtkMapperGlobalImmediateModeRendering ? "On " : "Off "); os << indent << "Scalar Visibility: " << (this->ScalarVisibility ? "On " : "Off "); os << indent << "Static: " << (this->Static ? "On " : "Off "); double *range = this->GetScalarRange(); os << indent << "Scalar Range: (" << range[0] << ", " << range[1] << ") "; os << indent << "UseLookupTableScalarRange: " << this->UseLookupTableScalarRange << " "; os << indent << "Color Mode: " << this->GetColorModeAsString() << endl; os << indent << "InterpolateScalarsBeforeMapping: " << (this->InterpolateScalarsBeforeMapping ? "On " : "Off "); os << indent << "Scalar Mode: " << this->GetScalarModeAsString() << endl; os << indent << "LM Color Mode: " << this->GetScalarMaterialModeAsString() << endl; os << indent << "RenderTime: " << this->RenderTime << endl; os << indent << "Resolve Coincident Topology: "; if ( vtkMapperGlobalResolveCoincidentTopology == VTK_RESOLVE_OFF ) { os << "Off" << endl; } else if ( vtkMapperGlobalResolveCoincidentTopology == VTK_RESOLVE_POLYGON_OFFSET ) { os << "Polygon Offset" << endl; } else { os << "Shift Z-Buffer" << endl; } }