Visualization of STL


I want to visualize a STL geometry along with other OCC shapes.

Currently, I archive this by loading the STL via RWStl::ReadFile and then attaching it as a triangulation to a TopoDS_Shape using the UpdateFace method.

This generally works. But my STL geometry usually contains sharp edges and since the rendering algorithm uses averaged point normals, these edges look very ugly (see attachment).

I guess, I could solve this by splitting the triangulation at the sharp edges. But I find this rather cumbersome to implement. Is there already some elegant solution to this problem available?

I'm very thankful for any hint.

Regards, Hannes

Kirill Gavrilov's picture

STL format is quite bad in this respect - it defines the sequence of triangles by duplicating each triangle node coordinates, with no grouping, indexation, naming, per-node normals and so on.
Loading such triangulation with preserved data duplication works quite bad - such mesh would be too heavy for visualization and useless for any operation.
Therefore, RWStl merges nodes while reading the file, but this merge is done geometrically - without determining sharp edges or something like that.

This makes sense in one context (where you need to work with sewed geometry) but can have side effects in another context (e.g. visualization).
Visualization by default reconstructs smooth normals by averaging normals to triangles sharing common nodes - this produces visual artifacts on sharp edges.

There are several possible approaches:

  • Display STL mesh without smooth shading (flat per-triangle normals).
    This can be achieved, for example, using appropriate Shading Model (Graphic3d_TOSM_FACET) in OCCT 3D Viewer.
  • Merge nodes on another criteria with detection of sharp edges during mesh import.
    Note that RWStl design allows overriding this routine.
    This would solves visual artifacts but may cause issues with other algorithms, in case if they rely on predefined sharing,
  • Use (another) Data Model separating nodal attributes.
    So that triangulation will have the same compact array of unique 3D vertices,
    but other vertex attributes like Normals will be stored separately.
    Some 3D applications follow this approach to mix flexibility and preserve geometrical identity;
    it should be noted, though, that graphics hardware does not natively support such kind of input data,
    so that to display it on the screen application still has to define a data structure like Poly_Triangulation.
  • Go further and implement an algorithm splitting STL mesh into regions ("smooth groups"),
    so that they can be defined as a set of Poly_Triangulation sharing common edges defined as Poly_PolygonOnTriangulation.

Open CASCADE CAD Assistant, for example, implements the second approach by merging nodes considering angle between facets.