Thursday, January 24, 2019

OpenLSTO plus InverseCSG

I was recently excited to learn about the OpenLSTO and InverseCSG projects, and that got me thinking: can we automate topology optimization interpretation for a 3D part with open source tools?

Topology optimization results are usually a discrete set of density voxels (as from ToPy) or a triangulated mesh (as from OpenLSTO). There is an interpretation step often required to take this result and turn it into something that you can fabricate or incorporate into further design activities. In the case of OpenLSTO you are getting what your manufacturing chain needs (an stl file) if you are 3D printing.

Interpreting the results of a topology optimization can be a time consuming manual process for a designer. While the steps to interpret a 2D topology optimization result can already be automated with a complete open source tool-chain, 3D is harder. I demonstrated in this post how the 2D bitmap output of ToPy can be traced to generate dxf files that you can import and manipulate in a CAD program. On the other hand, here’s an example I did that demonstrates the more manual process for a 3D part.

There is a fairly accessible literature on the interpretation of topology optimization results to get manufacturable designs. This was written about a decade ago, but I think it’s still a mostly accurate representation of the state of the practice: “The current industry standard for processing TO [topology optimization] results is to have a human designer manually create a parametric CAD model that approximates the [topology optimization output]. This is a tedious and time consuming process which is highly dependent on the individual designer’s interpretation of the TO results.” [1] For example, see this tutorial on how to use Altair’s set of tools to accomplish this task. There are some efforts to partially automate the interpretation of the topology optimization results which seem to be based primarily on curve fitting cross-sections.

Figure 1: Topology Optimization Interpretation Process [1]

Hsu et al. [2] demonstrated a method of interpretation that relied on approximating 2D cross-sections of the 3D topology optimization result and fitting those with NURBS.

Figure 2: Cross-section-based NURBS model of topology optimization result

They note a significant drawback with this sort of an approach, “the direction of selected representative cross-section will affect the efficiency in reconstructing the three-dimensional CAD model.” In a similar vein, Bruno et al. [3] propose a
method that automatically generates spline-based 2D CAD models that can be meshed and then analyzed to ensure that the interpreted design still meets design requirements since there is usually a degradation in the optimized metric (compliance, max stress) caused by the interpretation step. Some drawbacks noted by Larsen et al. [1] is that these spline fitting approaches miss opportunities to fit lower order models with fewer parameters than NURBS (like
CSG primitives), and there is no feature operation tree at the end of the interpretation process which would be useful to designers for further design steps. They lay out a nine step method to interpret topology optimization results
  1. Generate an IGES file containing the faceted surfaces of the TO results
  2. Import the design space part and overlay with the faceted surfaces
  3. Identify feature surfaces among the faceted surfaces of the IGES file
  4. Identify design space surfaces that the feature intersects
  5. Signify feature orientation geometry
  6. Specify the number of cross sections to use
  7. Sample the model at each cross section location
  8. Compare samples to polar maps of defined shape templates
  9. Utilize CAD API to cut geometry away from design space part

This process requires a significant amount of interactive user input. I think it would be great if a tool like InverseCSG could automate this work-flow or something like it.

The OpenLSTO project ships with an example 3D cantilever. It is interesting to try InverseCSG on this part. The stl file is up on github.

I ran this shape (converted to off) through the InverseCSG process. The resulting CSG part is pretty rough (unusable), but interesting.

There are plenty of parameters I probably need to tweak in the ransac.conf file or the arguments in the InverseCSG call for accuracy and surface or volume sampling to get a better result. If you’ve got ideas in that direction please share them in the comments.

One of the aspects of InverseCSG that I like is that it ships with a 50 part benchmark dataset.

Figure 3: InverseCSG benchmark dataset

None of thse really looks like the sort of shape you get from a topology optimization code though. I think a really cool expansion to the InverseCSG benchmark dataset would be some outputs from a tool like OpenLSTO or ToPy perhaps inspired by classic topology optimization cases that are often used in the literature like the Michell cantilever, the Messerschmidt–Bölkow–Blohm beam.

Drop a commnent and let me know if you have luck trying this work-flow on any of your parts, or if you see any improvements out there you like that tackle the topology optimization interpretation step in a useful way.

Thanks for reading!


Larsen, S., Jensen, C.G., “Converting Topology Optimization Results into Parametric CAD Models,” Computer-Aided Design and Applications, Vol. 6, No. 3, Taylor & Francis, 2009.

Hsu, M.H., Hsu, Y.L., “Interpreting three-dimensional structural topology optimization results,” Journal of Computers and Structures, Vol. 83, No. 4-5, 2005.

Bruno, H.B.S., Barros, G., Martha, L., Menezes, I., “Interpretation of Density-Based Topology Optimization Results by Means of a Topological Data Structure,” VI International Symposium on Solid Mechanics - MecSol 2017, 26-28 April, 2017.


  1. Hi,

    Could you please explain how you got the csg from your input please ?


  2. Hi,

    Could you please explain the choice of the parameters ?

    target_sample_num: 50000
    cluster_epsilon: 0.1
    epsilon: 0.1
    min_points: 500
    normal_threshold: 0.8
    probability: 0.5
    max_iter: 100
    max_diam: 0.1
    gc_max_iter: 10
    base: 5.0
    smooth_cost: 10.0
    label_cost: 10.0

    1. I used the defaults; playing with these may help improve on the result shown in this post...