Segfault when fetching results of boolean filter

Hi there, I’m creating a web app using ParaView and Trame for heart valve surgery planning. One of the features of this app is to perform various calculations based on where a cylinder representing a replacement valve is positioned on an STL file of a patient’s left ventricle. In order to perform these calculations, I need to perform a boolean intersection between the STL and the cylinder, which I can currently do in the Paraview GUI using the BooleanOperations filter by adding it as a plugin using the XML file in this post.

I am now trying to write a Python script to run the BooleanOperations filter to find the intersection of the STL and cylinder, then extract a subset of the points from this based on their x and y coordinates. While it seems like the script loads the plugin and does the boolean operation correctly, when I try to use servermanager.Fetch to get the results, my app crashes with a segmentation fault, no other information about why it crashed is given. Since I have used servermanager.Fetch for another calculation in the app with no issues, the only reason I can think of for the segfault happening is due to using a plugin to expose the BooleanOperations filter.

The relevant code is below. Any help on how to fix this is greatly appreciated!

def join_LV_implant(lv_stl, implant, BOOLEAN_FILTER_PATH):
    # triangulate implant to use with boolean filter
    triangled_implant = simple.Triangulate(Input=implant)

    # do boolean operation of lv and triangulated implant
    simple.LoadPlugin(BOOLEAN_FILTER_PATH, remote=False, ns=globals())
    lv_implant_boolean = BooleanOperation(FirstSurface=lv_stl, SecondSurface=triangled_implant)
    lv_implant_boolean.Operation = 'Intersection'

    return lv_implant_boolean

def get_MV_dp(state, lv_implant_boolean):
    ...

    # find mv_med_top using lv_implant_boolean
    lv_implant_boolean.Operation = 'Intersection'

    # clip data to narrow down the points
    bool_clip1 = simple.Clip(Input=lv_implant_boolean)
    bool_clip1.ClipType.Origin = [0.0, 0.0, -5.0]
    bool_clip1.ClipType.Normal = [0.0, 1.0, 0.0]

    bool_clip2 = simple.Clip(Input=bool_clip1)
    bool_clip2.ClipType.Origin = [0.0, 0.0, -5.0]
    bool_clip2.ClipType.Normal = [0.0, 0.0, -1.0]
    boolean_data = servermanager.Fetch(bool_clip2) # crashes here
    intersection_points = boolean_data.GetPoints()

Can you try to update the pipeline before the call to Fetch ? So we can have more insight on the origin of the crash.

You can do that with an UpdatePipeline(proxy=boolean_clip2). Or even around each Clip operation.

After further testing, I think it might be an issue with the BooleanOperation filter itself. I tried running UpdatePipeline after each Clip operation, as well as right after using the BooleanOperation filter in the first function, and the app still segfaults at this point with no information.

One possible reason could be that the plugin isn’t loading properly, but I don’t see any error messages about it. Is there a way to gather more error information?

If you have no error with the BooleanOperation creation, then I the plugin is correctly loaded. (otherwise you should have some NameError: name 'BooleanOperation' is not defined).
For full log, you can use

import vtk
vtk.vtkLogger.SetStderrVerbosity(vtk.vtkLogger.VERBOSITY_TRACE)

Concerning the boolean operation itself, you may want to look at this plugin:
https://gitlab.kitware.com/vtk/meshing/vespa

If you can use it, it has a more robust and efficient implementation.

As I mentioned in that post, I would definitely steer you away from using the vtkBooleanOperationPolyDataFilter as of now. It has not proven robust enough for arbitrary operations - computational geometry is hard to get right!

Note the dual licensing of CGAL - commercial and GPLv3.

1 Like

Thank you both for your help! After playing around with the app and Paraview a bit more, I think I found what the issue was. When I originally tested the BooleanOperations filter in Paraview, I only used one cylinder, but in the actual app, the valve is composed of two cylinders grouped together using Group Datasets to represent different parts of the valve. As such, the app crashed when trying to do the booelan operation between these two cylinders and the STL. I’ve managed to get around this by creating a separate cylinder to represent the whole valve, and the BooleanOperations filter runs without any issues with this.

For my current purposes, it seems like using the BooleanOperations filter is ideal, but if I run into more issues in the future I will definitely look into using the Vespa plugin instead.

2 Likes