[vtkusers] triangulating a cylinder

Obada Mahdi omahdi at gmx.de
Wed Dec 6 22:47:25 EST 2006


Hi,

just some additional hints:

On 12/6/06, debbie larson <debbielarson_9 at hotmail.com> wrote:
> I would like to build a vtkPolyData (triangular) representation of a
> cylinder. The points that define the cylinder sit on a number N of
> perpendicular circles (they are equally spaced).

There is a polydata source, vtkCylinderSource, that will generate a
polygonal representation of a cylinder (including normals and texture
coordinates), given its radius, height and resolution (number of
facets), have a look at

http://www.vtk.org/doc/nightly/html/classvtkCylinderSource.html

It uses quads instead of triangles for the facets, but you could use
vtkTriangleFilter to triangulate its output.  There is also
vtkTubeFilter

http://www.vtk.org/doc/nightly/html/classvtkTubeFilter.html

which you could try if you need the polygonal representation of your
cylinder to consist of several "rings".  According to the
documentation, it produces triangle strips, which can also be split
using vtkTriangleFilter (if separate triangles are required).

> I dont know how to specify the vtkCellArray for the triangles so that they
> match the points.

I am not sure whether that is your question, but the correlation
between a cell array and corresponding points is provided implicitly
by grouping them in a data set like vtkPolyData.  Cell definitions in
a cell array only contain point IDs (i.e., simple integers), there is
no explicit link to a particuar set of points.  The "rules" for how to
interpret these IDs and correlate them to actual coordinates are just
part of the concept of e.g. vtkPolyData.

> Here it is how I compute the points in the cylinder
>
> -------------------------------------------------------
>
> float pts[number_of_points*N][3];
> for (int k=0;k<N;k++)
>         {
>           for (int j=0;j<number_of_points;j++)
>             {
>
> pts[k*number_of_points+j][0]=radius*cos(2*M_PI*j/number_of_points);
> pts[k*number_of_points+j][1]=radius*sin(2*M_PI*j/number_of_points);
>               pts[k*number_of_points+j][2]=k*distance_between_circles;
>              }
>          }
> vtkFloatArray* coords=vtkFloatArray::New();
>   coords->SetNumberOfComponents(3);
>   coords->SetNumberOfTuples(number_of_points*N);
>
>   for (int i=0;i<number_of_points*N;i++)
>     {
>       coords->SetTuple(i,innerpts[i]);
>     }
>   vtkPoints points=vtkPoints::New();
>   points->SetData(coords);
>   ---------------------------------------------------------------------
> I would like to do something like
>
> vtkCellArray* tri=vtkCellArray::New();
>
> and assign the points above to tri. How to do it?

To insert triangles one at a time, ring for ring, one could probably
do something like
----
  for ( int k = 0; k < N-1; k++ ) {  // only run up to N-2
    // Point IDs of first points in current ring and next ring.
    const int curOffset = k*number_of_points;
    const int nextOffset = curOffset + number_of_points;

    // Triangulate a single quad like this:
    // ...[j]---[j+1]...  ring k+1 (indices start at nextOffset)
    //      |\  |
    //      | \ |
    //      |  \|
    // ...[j]---[j+1]...  ring k (indices start at curOffset)
    for ( int j = 0; j < number_of_points-1; j++ ) {
      vtkIdType tri1[3] = { curOffset+j, curOffset+j+1, nextOffset+j };
      vtkIdType tri2[3] = { nextOffset+j, curOffset+j+1, curOffset+j+1 };

      tri->InsertNextCell(3, tri1);
      tri->InsertNextCell(3, tri2);
    }
  }

  // Use `points' and `tri' to populate a vtkPolyData
  vtkPolyData* cylinderPolys = vtkPolyData::New();
  cylinderPolys->SetPoints(points);
  cylinderPolys->SetPolys(tri);
----

Note that this already makes assumptions about the layout of the `pts'
array.  I am not sure whether the code above is correct, but it shows
the general idea :-) Creating triangle strips would be even simpler.

You might also want to have a look at the implementations of
vtkCylinderSource and vtkTubeFilter at
Graphics/vtkCylinderSource.cxx
Graphics/vtkTubeFilter.cxx
to see how it is done there.


HTH,

Obada



More information about the vtkusers mailing list