[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