[vtkusers] Stretch/deform surface

Marius Erdt marius.erdt at gmx.de
Fri Jun 20 11:17:51 EDT 2008


Right now, I run the following code:

       // draw a sphere to get some points of the surface
          vtkSphereSource* sphere = vtkSphereSource::New();
          sphere->SetCenter(mousePos[0],mousePos[1], mousePos[2]);
          sphere->SetRadius(20.0);

       // label the surface points that are inside the sphere
          vtkSelectEnclosedPoints* enclosedSelector = 
vtkSelectEnclosedPoints::New();
          enclosedSelector->SetInput(modelPoly);
          enclosedSelector->SetSurface(sphere->GetOutput());
          enclosedSelector->Update();

          vtkPoints* modelPoints = modelPoly->GetPoints();
          long numPts = modelPoints->GetNumberOfPoints();
          long ptId;

          vtkFloatArray* farray = vtkFloatArray::New();
          farray->SetNumberOfComponents(1);
          farray->SetNumberOfTuples(numPts);

       // iterate over all points of the surface and label all points 
that are inside the sphere in a seperate float array

          for (ptId = 0 ; ptId < numPts; ptId++){
              if (enclosedSelector->IsInside(ptId) == 1){
                  farray->SetComponent(ptId,0,1.0);
              }
              else {
                farray->SetComponent(ptId,0,1.0);
              }
          }

        // attach the label array to the surface
          vtkFieldData* fieldData = vtkFieldData::New();
          farray->SetName("weights");
          modelPoly->GetPointData()->AddArray(farray);

          vtkThinPlateSplineTransform* thinPlate = 
vtkThinPlateSplineTransform::New();

       // add old and new mouse position to the thin plate spline transform
          vtkPoints *points = vtkPoints::New();
          vtkPoints *pointsNew = vtkPoints::New();
          points->SetNumberOfPoints(1);
          pointsNew->SetNumberOfPoints(1);
          points->SetPoint(0, mousePos[0], mousePos[1], mousePos[2]);
          pointsNew->SetPoint(0, mousePosNew[0], mousePosNew[1], 
mousePosNew[2]);

          thinPlate->SetSourceLandmarks(points);
          thinPlate->SetTargetLandmarks(pointsNew);
          thinPlate->SetSigma(0.1);
          thinPlate->SetBasisToR();

       // run the weighted transform filter with the surface as input 
and the label array as weights
          vtkWeightedTransformFilter* weightedTransform = 
vtkWeightedTransformFilter::New();
            weightedTransform->SetInput(modelPoly);
            weightedTransform->SetNumberOfTransforms(1);
            weightedTransform->SetTransform(thinPlate, 0);
            weightedTransform->SetWeightArray( "weights" );
            weightedTransform->Update();


Perhaps I missed some important fact in the procedure, because the 
result is a global transformation of the whole model.



Miguel Ángel Rodríguez Florido wrote:
>     Perhaps in my case it was easier, but what I did was just the same 
> that
> you comment. The only difference was that I applied the combinations of
> transforms to different regions of the surface (rotations and 
> displacement)
>
>     For me this was enough.
>
>     I guess that in your case is more complex. I don't know if 
> somebody in
> this list has developed a BSpline for VTK.
>
>     Please, let me know if I can help you or let the vtkusers' list 
> know if
> you find a solution.
>
>     Hth.
>
>
> Marius Erdt escribió:
>> Thanks for your suggestion Miguel.
>>
>> I've tried to use the vtkWeightedTransformFilter. The input is the 
>> surface and a thinPlateSpline transform. In addition I've created a 
>> label array that weights the transform for every point, i.e. 1 for 
>> every point I want to transform and 0 for every point that should not 
>> be transformed. However, the result was, that the whole surface was 
>> distorted, so I think the weights have to be set in another way. What 
>> I do know is that setting of all weights to 1 results in a global 
>> transformation as one would expect. But setting some of the weights 
>> to 0 does not seem to work..
>>
>>
>> Miguel Ángel Rodríguez Florido wrote:
>>>     If you know the points (or regions) or you can choose them, you 
>>> could try vtkWeightedTransformFilter
>>>
>>> http://www.vtk.org/doc/release/5.0/html/a02205.html
>>>
>>>     I hope to help.
>>>     Best
>>>
>>> Karthik Krishnan escribió:
>>>> Marius Erdt wrote:
>>>>> Hi,
>>>>>
>>>>> I'd like to manually deform a polyData surface, i.e. I set two 
>>>>> mouse positions and I want a part of the surface to be stretched 
>>>>> in the direction given by the vector between the points (just like 
>>>>> what is possible in CAD programs).
>>>>>
>>>>> I've tried to use the vtkThinPlateSplineTransform on the surface, 
>>>>> but this has a very global effect on the model. That means, the 
>>>>> whole surface is translated in the given direction, instead of 
>>>>> just a small neighborhood.
>>>> The Kernel splines, one of which is the Thin plate spline (Thin 
>>>> Plate, Thin Plate R2LogR) have infinite support. You can change the 
>>>> decay, but it will still have a non-zero deformation at an infinite 
>>>> distance from the center.
>>>>
>>>> You might want to consider BSpline transforms for your purpose. 
>>>> They are local in support and you can define the locality (number 
>>>> of nodes).
>>>>
>>>> VTK does not have a BSpline implementation, but ITK does. You can 
>>>> use the method
>>>>
>>>>  itk::BSplineTransform< double, 3, 3 >::TransformPoint(..)
>>>>
>>>> and iterate over each point in your polydata.
>>>>
>>>>
>>>> -- 
>>>> Karthik Krishnan
>>>> R & D Engineer,
>>>> Kitware Inc,
>>>> Ph: +1 518 3713971 x119
>>>> Fax: +1 518 3714573
>>>>
>>>> _______________________________________________
>>>> This is the private VTK discussion list.
>>>> Please keep messages on-topic. Check the FAQ at: 
>>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.vtk.org/mailman/listinfo/vtkusers
>>>
>>
>>
>> _______________________________________________
>> This is the private VTK discussion list.
>> Please keep messages on-topic. Check the FAQ at: 
>> http://www.vtk.org/Wiki/VTK_FAQ
>> Follow this link to subscribe/unsubscribe:
>> http://www.vtk.org/mailman/listinfo/vtkusers
>





More information about the vtkusers mailing list