[vtkusers] Stretch/deform surface
superzz
jxdw_zlf at yahoo.com.cn
Tue Mar 23 22:20:21 EDT 2010
Hello Miguel
I SetNumberOfTransforms to 2, but it still does not work.
My code is
#include "vtkCellArray.h"
#include "vtkAppendPolyData.h"
#include "vtkXMLPolyDataReader.h"
#include "vtkSphereWidget.h"
#include "vtkCommand.h"
#include "vtkConeSource.h"
#include "vtkGlyph3D.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderer.h"
#include "vtkSphereSource.h"
#include "vtkTransform.h"
#include "vtkCallbackCommand.h"
#include "vtkRegressionTestImage.h"
#include "vtkDebugLeaks.h"
#include "vtkPlanes.h"
#include "vtkClipPolyData.h"
#include "vtkLODActor.h"
#include "vtkRegressionTestImage.h"
#include "vtkDebugLeaks.h"
#include "vtkProperty.h"
#include "vtkSphere.h"
#include "vtkDebugLeaks.h"
#include "vtkSelectEnclosedPoints.h"
#include "vtkFloatArray.h"
#include "vtkThinPlateSplineTransform.h"
#include "vtkWeightedTransformFilter.h"
#include "vtkPointData.h"
int main( int argc, char *argv[] )
{
double mousePos[] = {0,0,1};
double mousePosNew[] = {1,1,1};
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
// renderer->AddActor(maceActor);
renderer->SetBackground(0,0,0);
renWin->SetSize(300,300);
vtkSphereSource *sphereSource = vtkSphereSource::New();
sphereSource ->SetRadius(1);
sphereSource->SetPhiResolution(40);
sphereSource->SetThetaResolution(40);
sphereSource->Update();
vtkPolyData *modelPoly = sphereSource->GetOutput();
// draw a sphere to get some points of the surface
vtkSphereSource* sphere = vtkSphereSource::New();
sphere->SetCenter(mousePos[0],mousePos[1], mousePos[2]);
sphere->SetRadius(0.3);
// 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(2);
weightedTransform->SetTransform(thinPlate, 0);
weightedTransform->SetWeightArray( "weights" );
weightedTransform->Update();
vtkPointSet *outputPointSet = weightedTransform->GetOutput();
vtkPoints *pvtkPoints = vtkPoints::New();
pvtkPoints->SetNumberOfPoints(numPts);
for(int i = 0 ; i < outputPointSet->GetNumberOfPoints();++i){
pvtkPoints->InsertPoint(i, outputPointSet->GetPoint(i));
}
vtkCellArray *pvtkCellArray = vtkCellArray::New();
pvtkCellArray->InsertNextCell(numPts);
for (int pi = 0; pi < outputPointSet->GetNumberOfPoints(); pi++)
{
pvtkCellArray->InsertCellPoint(pi);
}
vtkPolyData *pvtkPolyData = vtkPolyData::New();
pvtkPolyData->SetPoints(pvtkPoints);
pvtkPolyData->SetPolys(pvtkCellArray);
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInput(pvtkPolyData);
vtkActor *actor = vtkActor::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetRepresentationToPoints();
renderer ->AddActor(actor);
iren->Initialize();
renWin->Render();
renderer->ResetCamera();
iren->Start();
// Clean up
sphere->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
return 0;
}
Thanks!
superZZ
Miguel Angel Rodriguez Florido wrote:
>
> Hi Marius,
>
> I'm not sure but perhaps you need to define another transform (an
> identity) to combina with your thinPlate.
>
> Later, SetNumberOfTransforms to 2 and use the weights to weight the
> contribution of each one. In same cases, you won't transform the points
> (basically the identity is 1 and the thinPlate 0), and in other cases
> you will transform the points with the thinPlate.
>
> Hth.
>
> Marius Erdt wrote:
>> 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
>>>
>>
>>
>> _______________________________________________
>> 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
>
>
> --
> Miguel Angel Rodriguez Florido
> Center for Technology in Medicine-ULPGC-Gran Canaria-CanaryIslands,Spain
> Emails:marf@{ctm.ulpgc.es,bwh.harvard.edu}-http://www.ctm.ulpgc.es/~marf
> Tfnos:+34 928 451253, +34 928 452956 - Fax:+34 928 451243
>
>
>
>
>
>
> _______________________________________________
> 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
>
>
http://old.nabble.com/file/p28009887/DeformTest.cxx DeformTest.cxx
--
View this message in context: http://old.nabble.com/Stretch-deform-surface-tp18013244p28009887.html
Sent from the VTK - Users mailing list archive at Nabble.com.
More information about the vtkusers
mailing list