mesh flaw occurs when using vtkBooleanOperation

Hi, I am using vtk to reconstruct blood vessel surface from vessel skeleton (center line along the vessel)

I constructed two tube type of vessel and going to glue them using vtkBooleanOperation.
The vessel is made by vtkTubeFilter

However, there occurs some mesh flaw in the joint area

I cannot understand whole algorithm of vtkBooleanOperation, and I need some help
I cannot find what is wrong

What I want to construct is like following

However, what I got is (when using SetOperationToUnion)

Refer, when using SetOperationToIntersection

main code :

merger = ObjectManager.Merger()
merger.SetInput(tubeFilter1, tubeFilter2)
unionActor = merger.Merge()
unionActor.GetProperty().SetOpacity(0.9)

Merger class code :

def __init__(self):
    self.m_filter = vtk.vtkBooleanOperationPolyDataFilter()
    self.m_normal = vtk.vtkPolyDataNormals()
    self.m_mapper = vtk.vtkPolyDataMapper()
    self.m_triFilter1 = vtk.vtkTriangleFilter()
    self.m_triFilter2 = vtk.vtkTriangleFilter()
    self.m_actor = vtk.vtkActor()

def SetInput(self, object1, object2):
    self.m_triFilter1.SetInputConnection(object1.GetOutputPort())
    self.m_triFilter2.SetInputConnection(object2.GetOutputPort())
    self.m_filter.SetInputConnection(0, self.m_triFilter1.GetOutputPort())
    self.m_filter.SetInputConnection(1, self.m_triFilter2.GetOutputPort())

def Merge(self):
    self.m_filter.SetOperationToUnion()
    self.m_filter.Update()

    self.m_normal.SetInputData(self.m_filter.GetOutput())
    self.m_normal.ComputePointNormalsOn()
    self.m_normal.Update()

    self.m_mapper.SetInputConnection(self.m_normal.GetOutputPort())
    self.m_actor.SetMapper(self.m_mapper)
    self.m_actor.GetProperty().SetRepresentationToWireframe()

    return self.m_actor

Boolean mesh implementations are really hard to implement correctly and they often fail (even in very expensive commercial software). Unfortunately, VTK’s implementation is quite fragile and it often generates incorrect meshes for complex inputs (and sometimes even for quite simple inputs, too). You may try to slightly move around the meshes until there are no errors in the output mesh.

If you need a definitive solution that always produces correct results then one option is to convert the mesh to binary labelmap, perform Boolean operations on the labelmap, then convert the labelmap back to surface mesh. Disadvantage of this approach that original model points are not preserved and you may need a lot of memory if you need preserve mesh geometry very accurately. If you want to give it a try without implementing anything, then you can perform these steps in 3D Slicer’s Segment Editor module (load models, import them to segmentation, use Logical operators effect, export resulting segment to model).

If you use Python, then another option is to use Boolean mesh operations of Blender, which is reported to be quite robust and very fast. You can import Blender Python package and process VTK meshes as described here.

Thanks for replying

My program needs computation time within 1sec (without visual rendering, only needs surface model like stl format)
Now, I consider blender or using construct mesh manually…
anyway, thanks again

blender works properly
I used boolean operation in blender and I got following

thanks again @lassoan

There is an alternative boolean operations implementation (Apache License, Version 2.0) by @Ron84 that may be more robust. It could be a good project for someone to compare the performance and accuracy of both, with the aim of potentially integrating this implementation into VTK proper.

3 Likes

Do you know how to remove both the inputs of port 0 and 1 in a vtkBooleanOperationPolyDataFIlter. I tried using RemoveAllInputs() but it only removed the data in port 0.

Looks promising, thanks for sharing. Next time we need Boolean mesh operations, we’ll give it a try.

alternative boolean operations implementation works well too

But, I cannot compare the performance at now, it needs more consideration
Anyway, thanks too

:grinning:

Hello, Ron,
Nice to meet you

I followed your instruction which is described in github and installed vtk 8.2 with vtkbool.
I found vtkbool.dll and lib, but there is no python package for vtkbool
I checked again that my vtk is installed with python wrapped

I completed the work with C++ but I wonder why vtkbool python package is not installed.
Can you give me some help?

Following is CMake configuration what I have done


Hello @hyunseoki .

The wrapper currently does not work with VTK8 :frowning:.

But next time I will fix it.

Thanks replying @Ron84

Oh… I hope it will be soon.

Then, is it compatible with vtk 7.x ?

Yes it works fine with VTK6 and VTK7.

@hyunseoki vtkbool now works with VTK8. Try it out! If CMake cannot detect VTK’s Python version, set py_ver manually. E.g. with set(py_ver "3.7").

Best regards
Ronald

@Ron84 I could take a shot at making this a Remote Module. That way you could still use your version with VTK. Ii it’s OK with you I could start soon. I will fork your repo and add what I need to make it a remote module. Eventually, you could take my changes and offer this option.

Bill

1 Like

Oh yeah, sounds nice. Make the changes and then create a pull request. :grinning: