[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