shamantou blog site

shamantou@gmail.com

导航

vtkPolyData相关的一些资料
vtk中点的描绘和操作在vtkPoints类中完成,调用SetPointInsertPoint可以设置点的vtkIdType(类似id的值)和三维坐标,2个函数的功能相同,区别在于InsertPoint先要完成点的范围检查和内存分配工作,所以速度较慢。注:这2个函数的实质是调用SetTupleInsertTuple在数组的第i个位置赋值。适用于bit\char\data\double\float等所有array。以vtkFloatArray为例函数void vtkFloatArray::SetTuple( const vtkIdType    i, const float *   tuple ) [virtual] 的第一个参数是位置内容,第二个参数是数据指针。
实际操作的时候只需要考虑vtkPoints的指针就可以了,只是在点操作的时候才需要调用上述函数。
 
vtkCellArray中设置cell单元,调用InsertNextCell函数逐步添加新的cell,例如函数vtkCellArray::InsertNextCell ( vtkIdType    npts,   vtkIdType *    pts ) [inline] 的第一个参数值标是cell中点的个数,第二个参数指向那些点的坐标数据。(说明:vtkIdType *    pts 存储的是所包括点在points中的顺序信息,其个数当然应该和前面的npts一致。)
这里,2点可以连成一条线,三点可以得到一个面。也就是说:vtk中关于点、线、面的那些信息都是存放在cellarray中,应用时也是直接对cellarray指针进行处理,数据的写入和读取在vtkCellArray类完成。
 
接下来的工作是定义一个vtkPolyData,得到包括顶点、线、多边形、三角形带在内的几何结构,即三维实体。这里通过函数SetPoints设置点信息,SetPolys设置单元排列(cell array)定义多边形,cell array设置单元排列(cell array)定义线,SetStrips设置单元排列(cell array)定义三角形带stripSetVerts设置顶点,诸如此类....
 
 
然后定义vtkPolyDataMapper,通过SetInput输入vtkPolyData信息,再定义vtkActor,调用SetMapper导入vtkPolyDataMapper,接下来vtkRenderer,调用AddActor,然后 vtkRenderWindow调用Render,再加上其他辅助的函数,就可以完整的完成输出了。
 
以下是在vtk中绘制四面体的函数代码:
 
 int i;
 static float x[4][3]={{0,0,0}, {1,0,0}, {0,1,0},{0,0,1}};
 static vtkIdType pts[4][3]={{0,1,2},{0,1,3},{0,2,3},{1,2,3}};
 //这里说明了每个pts[i]由哪几个点构成,如第一个由{0,0,0}, {1,0,0}, {0,1,0}组成。
 
 vtkPolyData *tetrahedron = vtkPolyData::New();
 vtkPoints *points = vtkPoints::New();
 vtkCellArray *polys = vtkCellArray::New();
 
 
 for (i=0; i<4; i++) points->InsertPoint(i,x[i]);//输入各点
 for (i=0; i<4; i++) polys->InsertNextCell(3,pts[i]);//输入各cell信息
 
 
 
 tetrahedron->SetPoints(points);
 points->Delete();
 tetrahedron->SetPolys(polys);
 polys->Delete();
//导入信息到vtkPolyData
 
 
 vtkPolyDataMapper *tetrahedronMapper = vtkPolyDataMapper::New();
      tetrahedronMapper->SetInput(tetrahedron);
      tetrahedronMapper->SetScalarRange(0,7);
          
 vtkActor *tetrahedronActor = vtkActor::New();
      tetrahedronActor->SetMapper(tetrahedronMapper);
 
 
 vtkCamera *camera = vtkCamera::New();
      camera->SetPosition(1,1,1);
      camera->SetFocalPoint(0,0,0);
 
 vtkRenderer *renderer = vtkRenderer::New();
 vtkRenderWindow *renWin = vtkRenderWindow::New();
    renWin->AddRenderer(renderer);
 
 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);
 
      renderer->AddActor(tetrahedronActor);
      renderer->SetActiveCamera(camera);
      renderer->ResetCamera();
      renderer->SetBackground(0,0,0);
 
      renWin->SetSize(300,300);
 
 
 renWin->Render();
 iren->Start();
 
 tetrahedron->Delete();
 tetrahedronMapper->Delete();
 tetrahedronActor->Delete();
 camera->Delete();
 renderer->Delete();
 renWin->Delete();
 iren->Delete();
 
 
 
 
vtk是通过YYSTYPE结构来存放vrml相关信息的,YYSTYPE的定义如下:
 
typedef union {
 char                    *string;
 float           sffloat;
 vtkPoints       *vec3f;
 vtkIdTypeArray     *mfint32;
 int             sfint;
} YYSTYPE;
 
vtk中导入vrml的主要工作是在yyparse中完成的,我们关心的是yylval,它是定义的YYSTYPE类型指针。下段代码就是通过该指针,设置了各标量位置的颜色。yylval的一些细节目前还没有搞清楚....
 
    {
    vtkCellArray *cells;
    int index, j;
    vtkIdType *pts=0;
    vtkIdType npts;
    vtkPolyData *pd = (vtkPolyData *)this->CurrentMapper->GetInput();
    if (pd->GetNumberOfPolys() > 0)
      cells = pd->GetPolys();
    else
      cells = pd->GetLines();
    cells->InitTraversal();
    index = 0;j = 0;
    cells->GetNextCell(npts, pts);
    for (int i=0;i <= yylval.mfint32->GetMaxId();i++)
      {
      if (yylval.mfint32->GetValue(index) == -1)
        {
        cells->GetNextCell(npts, pts);
        // Pass by the -1
        index++;
        j = 0;
        }
      else
        {
        // Redirect color into scalar position
        this->CurrentScalars->SetComponent(pts[j++], 0,
                                           yylval.mfint32->GetValue(index++));
        }
      }
    }
 
3ds提取点线面信息的方法:
 
在我们读3ds文件的时候,先是由this->FileFD = fopen (this->FileName, "rb")打开文件,然后程序调用Read3DSRead3DS再调用parse_3ds_file解析文件....
 
vtk3DSImporter类包括有
 vtk3DSOmniLight *OmniList;
 vtk3DSSpotLight *SpotLightList;
 vtk3DSCamera    *CameraList;
  vtk3DSMesh      *MeshList;
 vtk3DSMaterial *MaterialList;
 vtk3DSMatProp   *MatPropList;
 
vtk3DSMesh指针就可以得到我们希望得到的那些关于点、线、面的信息,因此可以按照
文件->vtk3DSImporter指针->vtk3DSMesh指针(包含相关信息)
->aMapper,aStripper,aNormalfaceaCellArray,aPoints,aPolyData
的顺序得到相关数据。
 
下面是导入actorrenderer的函数,从中可以清晰的看到vtk中数据是如何处理的
 
步骤:从MeshList提取mesh>mesh创建actor->添加actorrenderer
注释:1mesh结构包含有aMapper,aStripper,aNormalface                              aCellArray,aPoints,aPolyData等等,这些就是我们希望得到的那些信息。
      2GeneratePolyData:从meshvtkPolyData
          mesh结构提取faceaCellArray,aPoints,aPolyData保存所需要的信息到
      vtk3DSFace *face;
      vtkCellArray *triangles;
        vtkPoints *vertices;
      vtkPolyData *polyData;
        最后通过调用SetPolys SetPoints函数,返回包括有完整信息的vtkPolyData指针。
      polyData->SetPolys (triangles);
      polyData->SetPoints (vertices);
     3、下面是ImportActors函数和GeneratePolyData 函数的代码。
 
 
void vtk3DSImporter::ImportActors (vtkRenderer *renderer)
{
 vtk3DSMatProp *material;
 vtk3DSMesh *mesh;
 vtkStripper *polyStripper;
 vtkPolyDataNormals *polyNormals;
 vtkPolyDataMapper *polyMapper;
 vtkPolyData *polyData;
 vtkActor *actor;
 
 // walk the list of meshes, creating actors
 for (mesh = this->MeshList; mesh != (vtk3DSMesh *) NULL;
       mesh = (vtk3DSMesh *) mesh->next)
    {
    if (mesh->faces == 0)
      {
      vtkWarningMacro (<< "part " << mesh->name << " has zero faces... skipping\n");
      continue;
      }
 
    polyData = this->GeneratePolyData (mesh);
    mesh->aMapper = polyMapper = vtkPolyDataMapper::New ();
    mesh->aStripper = polyStripper = vtkStripper::New ();
 
    // if ComputeNormals is on, insert a vtkPolyDataNormals filter
    if (this->ComputeNormals)
      {
      mesh->aNormals = polyNormals = vtkPolyDataNormals::New ();
      polyNormals->SetInput (polyData);
      polyStripper->SetInput (polyNormals->GetOutput ());
      }
    else
      {
      polyStripper->SetInput (polyData);
      }
   
    polyMapper->SetInput (polyStripper->GetOutput ());
    vtkDebugMacro (<< "Importing Actor: " << mesh->name);
    mesh->anActor = actor = vtkActor::New ();
    actor->SetMapper (polyMapper);
    material = (vtk3DSMatProp *)VTK_LIST_FIND(this->MatPropList, mesh->mtl[0]->name);
    actor->SetProperty (material->aProperty);
    renderer->AddActor (actor);
 }
}
 
vtkPolyData *vtk3DSImporter::GeneratePolyData (vtk3DSMesh *mesh)
{
 int i;
 vtk3DSFace *face;
 vtkCellArray *triangles;
 vtkPoints *vertices;
 vtkPolyData *polyData;
 
 face = mesh->face;
 mesh->aCellArray = triangles = vtkCellArray::New ();
 triangles->Allocate(mesh->faces * 3);
 for (i = 0; i < mesh->faces; i++, face++)
    {
    triangles->InsertNextCell (3);
    triangles->InsertCellPoint (face->a);
    triangles->InsertCellPoint (face->b);
    triangles->InsertCellPoint (face->c);
    }
 
 mesh->aPoints = vertices = vtkPoints::New ();
 vertices->Allocate(mesh->vertices);
 for (i = 0; i < mesh->vertices; i++)
    {
    vertices->InsertPoint (i, (float *) mesh->vertex[i]);
    }
 mesh->aPolyData = polyData = vtkPolyData::New ();
 polyData->SetPolys (triangles);
 polyData->SetPoints (vertices);
 
 return polyData;
}
 
 
<< 电力相关企业雪后的交大 >>

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最近发表

Powered By Z-Blog 1.8 Arwen Build 81206 Copyright 2006-2009 | ooplab.org | shamantou@gmail.com | 沪ICP备08011244号 | Some Rights Reserved.