Intersect polydata with an implicit function

Hi all,
There is vtkIntersectionPolyDataFilter to get the intersection of two polydata but I didn’t find a filter that could that with a polydata and an implicit function.
Of course, one can convert an implicit function to a polydata and use vtkIntersectionPolyDataFilter but it seems an unoptimized way to do it.
Thanks for your help.
Ludovic

You can sample the implicit function with the polydata (probably using probe filter) then use threshold filter to cut the polydata. The advantage of this approach is that threshold filter always works, while vtkIntersectionPolyDataFilter randomly fails even for completely valid inputs.

Thanks Andras.
I have a bit of difficulty to understand how these filters work.
So far here is what I got:

polyData = LoadMesh(objPath)

source = vtk.vtkSphereSource()
source.SetCenter(center)
source.SetRadius(radius)
source.SetPhiResolution(100)
source.SetThetaResolution(100)

probeFilter = vtk.vtkProbeFilter()
probeFilter.SetInputConnection( source.GetOutputPort())
probeFilter.SetSourceConnection(scanMesh.GetOutputPort())

array = probeFilter.GetValidPoints()
tupleCount = array.GetNumberOfTuples()
print("tupleCount " + str(tupleCount))
componentCount = array.GetNumberOfComponents()
print("componentCount " + str(componentCount))

The tuple count is 0 and the component count is 1.

I’m not sure I am doing this right…

The problem with the above code snippet that you try to use two polydata as input of probe filter. One of them should be the implicit function instead.

So I guess I have to convert a implicit function to a dataset.
I tried to do that with a sample function like this:

boxR = vtk.vtkCubeSource()
boxR.SetBounds(-10,10,-10,10,-10,10)

radius = 4
center = 10,0,0

sphere = vtk.vtkSphere()
sphere.SetCenter(center)
sphere.SetRadius(radius)

sample = vtk.vtkSampleFunction()
sample.SetSampleDimensions(50,50,50)
sample.SetImplicitFunction(sphere)

probeFilter = vtk.vtkProbeFilter()
probeFilter.SetInputConnection(sample.GetOutputPort())
probeFilter.SetSourceConnection(boxR.GetOutputPort())

But I still get what looks like an empty array.

@lmainguy as you have discovered, vtkProbeFilter cannot be used with implicit functions. And using vtkSampleFunction to convert an implicit function into a data set for use with vtkProbeFilter is horridly inefficient. Don’t use vtkProbeFilter for this.

The best approach is to use vtkClipPolyData, using SetClipFunction() to apply the implicit function.

The second-best approach is to use vtkSampleImplicitFunctionFilter, using SetImplicitFunction() to sample the function, followed by vtkClipPolyData.

2 Likes

Hi David,
Thanks for your help!
Ok the next step is to get the boundary edges of the clipped polydata.
I guess vtkFeatureEdges is the correct tool to achieve that?

Yes indeed. But if all you need are the edges, then use vtkCutter instead of vtkClipPolyData. The cutter will give you the just the edges.

Ohhh so there is a class that does what I want. Nice!
I was actually in the process to do that in Python, glad to know the solution already exists in C++.

Thanks David!

Glad to help. One final note: if you are visualizing edges (or lines of any sort), you might find vtkTubeFilter useful. It turns all lines into tubes of a specified radius so that they are thicker and therefore easier to see. And it’s very fast.