• vtkMapper


    本文只是整理了该网页的内容: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;
        }
    }
  • 相关阅读:
    11-27:项目进度
    11-23:项目进度
    Scrum团队成立,阅读《构建之法》第6~7章,并参考以下链接,发布读后感、提出问题、并简要说明你对Scrum的理解
    团队项目:二次开发
    实验二 作业调度
    欣赏并且评价同学的复利计算博客
    对于我们的复利计算程序的升级
    用汉堡包的方式评价一下自己的合作伙伴
    结对项目:复利计算
    软件工程构建之法第四章读后感
  • 原文地址:https://www.cnblogs.com/phoenixdsg/p/6128583.html
Copyright © 2020-2023  润新知