vtkPlane.ComputeBestFittingPlane()

Hello, I need to fit a vtkPlane to a PolyData, but I do not understand how to use the method ComputeBestFittingPlane().

The vtkPlane.ComputeBestFittingPlane() documentation says “Given a set of points calculate the best-fitting origin and normal for the plane. The origin will be the centroid of the points. The normal is determined by using the covariance matrix of the points relative to the centroid. Returns true if successful. If not successful the origin will still contain the centroid and the normal will point into z-direction.”

I implemented it as:

my_plane = Plane()
my_plane.ComputeBestFittingPlane(my_polydata.GetOutput().GetPoints())

But this rises the error “TypeError: ComputeBestFittingPlane() takes exactly 3 arguments (1 given)”.

Actually the documentation says:

ComputeBestFittingPlane()

static bool vtkPlane::ComputeBestFittingPlane ( vtkPoints * pts,
double * origin,
double * normal
)

But according to my understanding origin and normal should be the output of this method, not an input…

Could you help me please? Thanks!

You’ll need to pass in references for origin and normal. See this part of the VTK documentation on how to do that: Python Wrappers - VTK documentation

Hello and thanks for the really quick answer!

What I understand from your answer is that the origin and normal should be dummy objects that will be filled with actual values after the ComputeBestFittingPlane method runs.

I created the reference objects and now I get an enigmatic crash that does not rise any specific error in the PyCharm debugger.

from vtk import (...) reference


my_plane = Plane()
my_origin = reference(0.)
my_normal = reference(0.)
my_plane.ComputeBestFittingPlane(my_polydata.GetOutput().GetPoints(), my_plane, my_normal)

>>> Process finished with exit code -1073741819 (0xC0000005)

Both the origin and normal should be double, so it seems OK. I also tried with [0., 0., 0.], thinking that they should be vectors actually, but this does not work.

Any ideas? Thanks!

Try a tuple? my_normal = reference((0, 0, 0))

Both (0., 0., 0.) and (0, 0, 0) result in:

TypeError: ComputeBestFittingPlane argument %Id: %V

Maybe the problem is with giving the input points as my_polydata.GetOutput().GetPoints()?

It should be OK…

I also tried using my_plane.GetOrigin() and my_plane.GetNormal(), and reference(my_plane.GetOrigin()) and reference(my_plane.GetNormal()).

Getorigin() and GetNormal() actually output a tuple, e.g. (0.0, 0.0, 1.0), but in the end ComputeBestFittingPlane always results in the error TypeError: ComputeBestFittingPlane argument %Id: %V.

if my_polydata is a polydata, there’s no need for .GetOutput()

Hello, Thanks! I tried also this, getting always the same error.

As input I tried:

my_polydata - a vtkAppendPolydata()

the output from the latter my_polydata.GetOutput()

the points my_polydata.GetOutput().GetPoints().

Origin and normal are tuples with reference.

new_xs_plane_origin = reference((0., 0., 0.))
new_xs_plane_normal = reference((1., 0., 0.))

The debugger says they are vtkmodules.vtkCommonCore.tuple_reference((0.0, 0.0, 1.0)).

And this always fails:

outcome = new_xs_plane.ComputeBestFittingPlane(append_points, new_xs_plane_origin, new_xs_plane_normal)

TypeError: ComputeBestFittingPlane argument %Id: %V

ComputeBestFittingPlane is a static method from vtkPlane. I believe it should be called like this:

outcome = vtkPlane.ComputeBestFittingPlane(append_points, new_xs_plane_origin, new_xs_plane_normal)