[vtkusers] Filling vtkPoints and vtkCellArray fast

Matt pspmatt at gmail.com
Mon Jan 18 17:45:28 EST 2010


Ok! So, I have managed to use my underlying C arrays without much overhead.
Here, is the code:

  float *vtkPts = (float * ) argv[0];
  int *vtkCells = (int * ) argv[1];
  int PtsArraySize = * (int *)  argv[2];
  int CellArraySize = * (int *)  argv[3];
  int nCells = * (int *) argv[4];

  // Here comes the vtk stuff

    vtkSmartPointer <vtkFloatArray> pts_fltarr =
vtkSmartPointer<vtkFloatArray>::New();
    pts_fltarr->SetNumberOfComponents(3); // X,Y,Z
    pts_fltarr->SetArray(vtkPts, PtsArraySize, 1);

    vtkSmartPointer <vtkPoints> Points = vtkSmartPointer<vtkPoints>::New();
    Points->SetData(pts_fltarr);


    vtkSmartPointer <vtkIdTypeArray> Conn =
vtkSmartPointer<vtkIdTypeArray>::New();
    Conn->SetArray(vtkCells, CellArraySize,1);

    vtkSmartPointer <vtkCellArray> Polys =
vtkSmartPointer<vtkCellArray>::New();
    Polys->SetCells(nCells,Conn);

    vtkSmartPointer <vtkPolyData> Tracts = vtkSmartPointer
<vtkPolyData>::New();

    Tracts->SetPoints(Points);
    Tracts->SetLines(Polys);
    Tracts->Update();

    vtkSmartPointer <vtkTubeFilter> Tubes =
vtkSmartPointer<vtkTubeFilter>::New();
    Tubes->SetInput(Tracts);
    Tubes->SetRadius(.2);
    Tubes->SetNumberOfSides(6);
    Tubes->Update();

------------------------------

Now, I want to pass back two new arrays to IDL that contains the point data
and the triangle strip (connectivity).
Again, if I could just access the arrays directly life would be much
simpler.  However, it appears going in reverse might be harder than what I
have already setup.

This will give me the size needed for the arrays:

    // pts
    int NumPoints = Tubes->GetOutput()->GetNumberOfPoints();

    // cells/strips/num of elemens in array
    int NumConn = Tubes->GetOutput()->GetStrips()->GetSize();

The plan would be to allocate an array of ints (vtkIdType) to hold the
strips and an array of floats to hold the point data.  Both, 1D.

Strips (connectivity):
-------------------------------

Tubes->GetOutput()->GetStrips()->GetData() // Will give me a vtkIdTypeArray
- but I really want is an array of vtkIdType.
  -- At this point, I'd like to use a getArray function like the setArray
function - but, it doesn't exist.
  -- So, do I need to loop through the whole vtkIdTypeArray and copy it into
an array of vtkIdType??
 -- or can I avoid this with some trick that I can't figure out?

Points:
----------
Tubes->GetOutput()->GetPoints() // will give me a vtkPoints object with all
of my points

-- Again, at this point, I'd like to be able to extract the float array in
the same way I set it, i.e setdata()
-- I don't see a good option to do this.
-- Do, I need to go point-by-point filling a new float array?


Let me know if you can think of a way I can accomplish this?  I can write my
own code to it.  But, wonder if there is a way to do this and my lack of
experience with vtk is not allowing me to see it.

Thanks again,

Matt




On Fri, Jan 15, 2010 at 4:38 PM, Matt <pspmatt at gmail.com> wrote:

> Yup, I figured that out as soon as I sent the email.
>
> Thanks for all the help!
>
> Matt
>
>
> On Fri, Jan 15, 2010 at 3:33 PM, David Gobbi <david.gobbi at gmail.com>wrote:
>
>> Hi Matt,
>>
>> If your vtk is built with VTK_USE_64BIT_IDS=OFF, then vtkIdType is
>> just a typedef for "int" and vtkIdType will be interchangeable with
>> int.  If vtkIdType is a 64-bit int (or if you want your code to work
>> when vtkIdType is 64-bit) then yes, you will have to copy your int
>> data into the vtkIdTypeArray.
>>
>>   David
>>
>>
>> On Fri, Jan 15, 2010 at 2:03 PM, Matt <pspmatt at gmail.com> wrote:
>> > Thanks so much! That was really helpful.
>> > I am able to access my C array directly for vtkPoints.  That is awesome.
>> > You explanation and advice really helped my understanding.
>> >
>> > I am now trying to figure out this vtkCellArray which I understand takes
>> a
>> > vtkIdTypeArray which contains vtkIdType.
>> > Again, I would like to be able to access my c array directly (if
>> possible).
>> > Or, use the least overhead possible.
>> > My c array is of type int and takes the form:  N, p1, p2, p3, N, p2,
>> p3,
>> > p4, p5, N, .... The number of points per cell varies.
>> > I guess I can't access this c array directly because it is not the right
>> > type.  Seems a shame.  The data seems to be represented exactly as the
>> > vtkCellArray is organized or at least in my limited understanding it
>> does.
>> >
>> > So, what's the best plan of action?  Fill an array of vtkIdType with the
>> > contents of my int c array. And, then pass that into a vtkIdTypeArray,
>> which
>> > I then pass onto the vtkCellArray.
>> >
>> > Any advice, code snippets would be much appreciated.  I am a bit stuck.
>> >
>> > Matt
>> >
>> >
>> >
>> > On Fri, Jan 15, 2010 at 11:03 AM, David Gobbi <david.gobbi at gmail.com>
>> wrote:
>> >>
>> >> The vtkPoints() class has a SetData() method as you have already seen,
>> >> and the vtkCellArray class has a method called SetCells(int ncells,
>> >> vtkIdTypeArray *cells) that takes a vtkDataArray that contains the
>> >> connectivity array.
>> >>
>> >> For vtkPoints::SetData(), the vtkDataArray must be either a
>> >> vtkFloatArray or a vtkDoubleArray.  For vtkCellArray::SetCells(), only
>> >> a vtkIdTypeArray containing "vtkIdType" values is allowed... vtkIdType
>> >> is a typedef for either "int" or "long long" depending on whether
>> >> VTK_USE_64BIT_IDS was set by cmake.
>> >>
>> >> You can efficiently set up a vtkDataArray by using the SetTuple()
>> >> method, since it is an inline method.  In fact, so is the
>> >> vtkPoints::SetPoint() method.
>> >>
>> >> If you have a huge data set and don't want to copy your data, you can
>> >> have VTK use your C arrays directly.  The VTK arrays have a method
>> >> called "SetArray()" that can be used like this:
>> >>
>> >> vtkFloatArray *array = vtkFloatArray::New();
>> >> array->SetNumberOfComponents(3);
>> >> array->SetArray(c_array, number_of_points*3, 1);
>> >>
>> >> The "1" on the end tells VTK not call "delete []" or "free()" on
>> >> c_array when the vtkDataArray is freed.  You don't have to call
>> >> SetNumberOfTuples() because VTK will automatically set the size of the
>> >> array from the size of the c_array you give it.
>> >>
>> >> Note that VTK always uses vtkIdType for its cells, you can't choose
>> >> whether to use 32-bit or 64-bit ids at run time.
>> >>
>> >>   David
>> >>
>> >>
>> >> On Fri, Jan 15, 2010 at 9:21 AM, Matt <pspmatt at gmail.com> wrote:
>> >> > Hello,
>> >> >
>> >> > I have recently started using VTK.  First, let me say thanks! It is
>> >> > amazing.
>> >> > I am working on an application in ITTVIS IDL that will communicate
>> with
>> >> > a
>> >> > DLL (C++) that contains VTK code.
>> >> > I have the DLL and the communication working fine and am able to pass
>> >> > data
>> >> > between the programs.
>> >> > I want to make a bunch of polygons and pass them through the generate
>> >> > tube
>> >> > filter before passing it back to IDL.
>> >> >
>> >> > I am passing two arrays from IDL:
>> >> >
>> >> > 1) Array of points in floats. 1D.    Form:    X0 Y0 Z0 X1 Y1 Z1 X2 Y2
>> Z2
>> >> >
>> >> > 2) Array of connectivity in int. 1D    Form:        N P0 P1 P2 N P1
>> P3 N
>> >> > P2
>> >> > P3
>> >> >
>> >> >
>> >> > ** I think the data is in the form that it is represented in memory
>> in
>> >> > VTK.
>> >> > (As in pg. 126 4th edition, OO approach to 3D graphics)
>> >> >
>> >> > The usual approach would be to create a vtkPolyData array (for the
>> >> > polygons), vtkPoints, and a vtkCellArray for connectivity).
>> >> > And, then to fill them using vtkPoints->InsertPoint,
>> >> > vtkCellArray->InsertNextCell, and then vtkPolyData->setPoints.
>> >> >
>> >> > However, I need this to be very effcient as I may be calling these
>> >> > routines
>> >> > repeatedly.  Given, that the data is almost in the form that VTK
>> >> > expects.
>> >> > I want to be able to stuff the data in whole vs point by point, cell
>> by
>> >> > cell.
>> >> >
>> >> > I can't seem to find a good explanation on how I would go about doing
>> >> > this.
>> >> >
>> >> > There seems to be a ->setData method in vtkPoints class but it takes
>> a
>> >> > vtkDataArray and I currently just have a plain old array of floats.
>> >> > I think the same goes for setCells in the vtkCellArray class.
>> >> >
>> >> > Could someone give me a quick example of the few lines of code it
>> would
>> >> > take
>> >> > to impelement this.  Or,, point me to a resource that shows an
>> example
>> >> > of
>> >> > this
>> >> >
>> >> > Thanks
>> >> >
>> >> > Matt
>> >> >
>> >> > _______________________________________________
>> >> > Powered by www.kitware.com
>> >> >
>> >> > Visit other Kitware open-source projects at
>> >> > http://www.kitware.com/opensource/opensource.html
>> >> >
>> >> > Please keep messages on-topic and check the VTK FAQ at:
>> >> > http://www.vtk.org/Wiki/VTK_FAQ
>> >> >
>> >> > Follow this link to subscribe/unsubscribe:
>> >> > http://www.vtk.org/mailman/listinfo/vtkusers
>> >> >
>> >> >
>> >
>> >
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100118/74b227d3/attachment.htm>


More information about the vtkusers mailing list