stavbodik
(סתיו בודיק)
January 23, 2024, 4:30pm
1
Can anyone explain me what’s the difference between transforming actor when using this two different approach ?
The first one is using the vtkTransformPolyDataFilter on the 3D object PolyData.
The second one is calling to SetUserMatrix on the vtkActor.
The problem is that I am getting wrong bounding box when calling GetBounds on the vtkActor when using the SetUserMatrix function.
In this image you can see 2 different vtkActor’s , both of them transformed to the correct location(same transformation matrix), but the GetBounds using the SetUserMatrix are wrong .
Why the function called UserMatrix ?
Thanks !
jaswantp
(Jaswant Panchumarti (Kitware))
January 23, 2024, 4:38pm
2
This method modifies the underlying coordinates of the vtkPoints
before rendering. When you call actor->GetBounds(), it returns the bounds of these transformed coordinates.
This method applies transformation matrix in the GPU during rendering. The coordinates of vtkPoints
are not transformed.
1 Like
stavbodik
(סתיו בודיק)
January 23, 2024, 4:57pm
3
Thanks for the explanation, so from this we can’t understand why GetBounds returns a different result, sounds like a bug ?
Note : the wrong bounds are not the bounds before transform the object from 0,0,0 (green circle in the image ) the wrong bounds are actually transformed and rotate but in wrong scale .
jaswantp
(Jaswant Panchumarti (Kitware))
January 23, 2024, 4:59pm
4
Does sound like a bug. But I’m unsure if it actually is. Maybe a new method called GetDataBounds()
is needed?
1 Like
stavbodik
(סתיו בודיק)
January 23, 2024, 5:00pm
6
I just edited my answer :
“Note : the wrong bounds are not the bounds before transform the object from 0,0,0 (green circle in the image ) the wrong bounds are actually translated and rotated but with wrong scale .”
stavbodik
(סתיו בודיק)
January 23, 2024, 6:46pm
7
Trying to workaround, getting the bbox after setusermatrix without get bounds, by using the transformation matrix multiply by points(min,max) got from getbounds after reading the ply file ,before setting user matrix.
nothing works
stavbodik
(סתיו בודיק)
January 24, 2024, 11:49am
8
Why matrix × point is not working ?
@jaswantp
jaswantp
(Jaswant Panchumarti (Kitware))
January 24, 2024, 3:15pm
9
It is not clear to me what you’re trying to achieve. GetBounds
always returns the bounding box of the actual geometry. Not the transformed actor’s bounds.
stavbodik
(סתיו בודיק)
January 24, 2024, 3:18pm
10
@jaswantp
Take the min,max (2 3D points) of the object before applying transformation.
Apply the transformation on all poly data (3D Object)
Apply the transformation on this 2 points and draw bounding box using this 2 transformed points.
You can see that the bounding box after transforming the two points is wrong.
jaswantp
(Jaswant Panchumarti (Kitware))
January 24, 2024, 3:28pm
11
The UserMatrix
is applied in model-space. This may be different from the world-space in which vtkTransformPolyDataFilter operates. Can you try using actor->GetMatrix()
to transform the original min and max?
stavbodik
(סתיו בודיק)
January 24, 2024, 3:51pm
12
For now I am trying to do the same only in world space with the filter, not using UserMatrix.
Look I also tried this approach , same results, wrong coordinates after calculating rotation for 2 circle blue points :
vtkMatrix4x4* transformMatrix = loadWorkVolumeTransform(transformFilePath);
vtkNew<vtkConeSource> vtkConeSource;
vtkConeSource->SetRadius(0.6);
vtkConeSource->SetCenter(0, 0, 0);
vtkConeSource->Update();
double originalBounds[6] = { 0 };
vtkConeSource->GetOutput()->GetBounds(originalBounds);
vtkNew<vtkTransform> transform3D;
transform3D->SetMatrix(transformMatrix);
transform3D->Update();
vtkNew <vtkTransformPolyDataFilter> transformFilter3D;
transformFilter3D->SetInputData(vtkConeSource->GetOutput());
transformFilter3D->SetTransform(transform3D);
transformFilter3D->Update();
appender_result->AddInputConnection(transformFilter3D->GetOutputPort());
appender_result->Update();
double originalMin[3] = { originalBounds[0],originalBounds[2],originalBounds[4]};
double originalMax[3] = { originalBounds[1],originalBounds[3],originalBounds[5]};
double center[3] = { originalMin[0]+(originalMax[0] - originalMin[0]) / 2,originalMin[1]+(originalMax[1] - originalMin[1])/2,originalMin[2]+(originalMax[2] - originalMin[2])/2 };
vtkSmartPointer<vtkPoints> boundsPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkPolyData> boundsPolydata = vtkSmartPointer<vtkPolyData>::New();
boundsPoints->InsertNextPoint(originalMin);
boundsPoints->InsertNextPoint(originalMax);
boundsPolydata->SetPoints(boundsPoints);
vtkNew<vtkTransform> transform;
transform->SetMatrix(transformMatrix);
transform->Update();
vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
transformFilter->SetInputData(boundsPolydata);
transformFilter->SetTransform(transform);
transformFilter->Update();
double transformedMin[3];
transformFilter->GetOutput()->GetPoint(0, transformedMin);
double transformedMax[3];
transformFilter->GetOutput()->GetPoint(1, transformedMax);
drawCircle1(transformedMin, color_blue);
drawCircle1(transformedMax, color_blue);
vtkSmartPointer<vtkPolyDataMapper> polyDataMapper_result = vtkSmartPointer<vtkPolyDataMapper>::New();
vtkSmartPointer<vtkActor> actor_result = vtkSmartPointer<vtkActor>::New();
actor_result->SetMapper(polyDataMapper_result);
polyDataMapper_result->SetInputData(appender_result->GetOutput());
drawBoundingBox(actor_result->GetBounds());
vtkRendered->AddActor(actor_result);
stavbodik
(סתיו בודיק)
January 24, 2024, 4:49pm
14
Same result @jaswantp
vtkMatrix4x4* transformMatrix = loadWorkVolumeTransform(transformFilePath);
vtkNew<vtkConeSource> vtkConeSource;
vtkConeSource->SetRadius(0.6);
vtkConeSource->SetCenter(0, 0, 0);
vtkConeSource->Update();
double originalBounds[6] = { 0 };
vtkConeSource->GetOutput()->GetBounds(originalBounds);
vtkNew<vtkTransform> transform3D;
transform3D->SetMatrix(transformMatrix);
transform3D->Update();
vtkNew <vtkTransformPolyDataFilter> transformFilter3D;
transformFilter3D->SetInputData(vtkConeSource->GetOutput());
transformFilter3D->SetTransform(transform3D);
transformFilter3D->Update();
appender_result->AddInputConnection(transformFilter3D->GetOutputPort());
appender_result->Update();
double originalMin[3] = { originalBounds[0],originalBounds[2],originalBounds[4]};
double originalMax[3] = { originalBounds[1],originalBounds[3],originalBounds[5]};
double center[3] = { originalMin[0]+(originalMax[0] - originalMin[0]) / 2,originalMin[1]+(originalMax[1] - originalMin[1])/2,originalMin[2]+(originalMax[2] - originalMin[2])/2 };
double* transformedMin = transform3D->TransformDoublePoint(originalMin);
double transformedMinNew[3] = { 0 };
std::memcpy(transformedMinNew, transformedMin, sizeof(double) * 3);
double* transformedMax = transform3D->TransformDoublePoint(originalMax);
drawCircle1(transformedMinNew, color_blue);
drawCircle1(transformedMax, color_blue);
vtkSmartPointer<vtkPolyDataMapper> polyDataMapper_result = vtkSmartPointer<vtkPolyDataMapper>::New();
vtkSmartPointer<vtkActor> actor_result = vtkSmartPointer<vtkActor>::New();
actor_result->SetMapper(polyDataMapper_result);
polyDataMapper_result->SetInputData(appender_result->GetOutput());
drawBoundingBox(actor_result->GetBounds());
vtkRendered->AddActor(actor_result);
stavbodik
(סתיו בודיק)
January 24, 2024, 5:07pm
15
@jaswantp GOT IT! the orintation of the boundingbox is NOT THE SAME after rotation, I need to figure out how to calculate it correctly .
Here is image before and after rotation 30 DEG around the Z axis !
stavbodik
(סתיו בודיק)
January 24, 2024, 5:26pm
16
I guess, I have to rotate all the corners and to find new min,max of the bbox (: