# SetUserMatrix vs using vtkTransformPolyDataFilter

**URL:** https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131
**Category:** Support
**Created:** [January 23, 2024, 4:30pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131 "2024-01-23T16:30:51Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 23, 2024, 4:30pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/1 "2024-01-23T16:30:51Z")

</div>

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.

 ![image](https://discourse.vtk.org/uploads/default/original/2X/0/0dba82f857422f739bd1687bc9a88e66eb52d982.png)

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 !

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [January 23, 2024, 4:38pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/2 "2024-01-23T16:38:01Z")

</div>

> [@stavbodik](#):
>
> The first one is using the vtkTransformPolyDataFilter on the 3D object PolyData.

This method modifies the underlying coordinates of the `vtkPoints` before rendering. When you call actor-\>GetBounds(), it returns the bounds of these transformed coordinates.

> [@stavbodik](#):
>
> The second one is calling to SetUserMatrix on the vtkActor.

This method applies transformation matrix in the GPU during rendering. The coordinates of `vtkPoints` are not transformed.

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 23, 2024, 4:57pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/3 "2024-01-23T16:57:37Z")

</div>

> [@jaswantp](#):
>
> This method applies transformation matrix in the GPU during rendering. The coordinates of `vtkPoints` are not transformed.

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 .

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [January 23, 2024, 4:59pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/4 "2024-01-23T16:59:14Z")

</div>

Does sound like a bug. But I’m unsure if it actually is. Maybe a new method called `GetDataBounds()` is needed?

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [January 23, 2024, 4:59pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/5 "2024-01-23T16:59:24Z")

</div>

@cory.quammen

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 23, 2024, 5:00pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/6 "2024-01-23T17:00:16Z")

</div>

> [@stavbodik](#):
>
> 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 .

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 .”

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 23, 2024, 6:46pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/7 "2024-01-23T18:46:42Z")

</div>

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

 ![image](https://discourse.vtk.org/uploads/default/original/2X/b/b93974367ce45407034f5b91ce38f18782c41a49.png)

 ![image](https://discourse.vtk.org/uploads/default/original/2X/1/1d7b10ee50e6d248697f1bfee376bf8524db6612.png)

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 11:49am UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/8 "2024-01-24T11:49:35Z")

</div>

Why matrix × point is not working ?

@jaswantp

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [January 24, 2024, 3:15pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/9 "2024-01-24T15:15:41Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 3:18pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/10 "2024-01-24T15:18:50Z")

</div>

> [@jaswantp](#):
>
> Not the transformed actor’s bounds.

@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.

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [January 24, 2024, 3:28pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/11 "2024-01-24T15:28:40Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 3:51pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/12 "2024-01-24T15:51:23Z")

</div>

> [@jaswantp](#):
>
> This may be different from the world-space in which vtkTransformPolyDataFilter operates.

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);

```

 ![image](https://discourse.vtk.org/uploads/default/original/2X/b/b507d7f95f1b266ef994a2b6b818da409da7c7be.png)

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 4:49pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/14 "2024-01-24T16:49:41Z")

</div>

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);

```

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 5:07pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/15 "2024-01-24T17:07:24Z")

</div>

@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 !

 ![image](https://discourse.vtk.org/uploads/default/original/2X/f/f7d25717cf83a79ca6a1d6d826861975ef7b274a.png)

---

<div class="post-metadata">

### Author: ![stavbodik](https://discourse.vtk.org/user_avatar/discourse.vtk.org/stavbodik/32/7081_2.png) [@stavbodik](https://discourse.vtk.org/u/stavbodik)
#### Post date: [January 24, 2024, 5:26pm UTC](https://discourse.vtk.org/t/setusermatrix-vs-using-vtktransformpolydatafilter/13131/16 "2024-01-24T17:26:13Z")

</div>

I guess, I have to rotate all the corners and to find new min,max of the bbox (:
