createGeometry failed: Wrong topology of boundary mesh for parametrization
I have an STL file that I would like to remesh but it fails when I tried to create the geometry (createGeometry) and I get an error like this:
Error: Wrong topology of boundary mesh for parametrization
The STL file represents the surface of a body and that surface is built manually so it may easily contain non-manifold surfaces. What I want is to be able to find out the surface and fix the model. As mentioned here (#1126 (comment 12170)), I know I can just ignore the error and run the code regardless. However, Gmsh could not generate any tetrahedral meshes, which may be caused by the failure in creating the geometry. The GUI shows there are triangles missing (see the screenshot) on the surface possibly caused by the failure in creating geometry.
Here is the Python script used:
#!/usr/bin/env python3
import gmsh
import numpy as np
gmsh.initialize()
gmsh.model.add('test_merge')
# Merge the stl file
gmsh.merge('ovoid_body.stl')
angle = 10 * np.pi / 180.
curve_angle = 180 * np.pi / 180.
gmsh.model.mesh.classifySurfaces(
angle=angle,
boundary=True,
forReparametrization=True,
curveAngle=curve_angle
)
gmsh.option.setNumber("General.AbortOnError", 0)
# Reparameterize
gmsh.model.mesh.createGeometry()
# Generate the 3D mesh
gmsh.model.mesh.generate(3)
# Launch the GUI to see the results:
gmsh.fltk.run()
And here is the STL file: ovoid_body.stl
I then tried another way of doing things. I tried to add all the nodes and triangles as discrete entities and then create the geometry. I got a slightly different error:
Error: Wrong topology of triangulation for parametrization: one edge is incident to 4 triangles
Here is the code that I used to add the discrete entities:
#!/usr/bin/env python
import gmsh
import numpy as np
gmsh.initialize()
gmsh.model.add('ovoid_body')
gmsh.logger.start()
nodes = np.loadtxt('ovoid_body.node', skiprows=1)
cells = np.loadtxt('ovoid_body.ele', skiprows=1, dtype=np.int32)
coords = nodes[:, 1:]
cell_nodes = cells[:, 1:]
ncells, _ = cell_nodes.shape
# Add a 2D discrete entity to the model (the surface of the ore body)
gmsh.model.addDiscreteEntity(2, 1)
gmsh.model.mesh.addNodes(2, 1, nodes[:, 0], coords.flatten())
gmsh.model.mesh.addElementsByType(1, 2, cell_nodes[:, 0], cell_nodes.flatten())
# Reclassify the nodes on the curves and the points (since we put them all on
# the surface before with `addNodes' for simplicity)
gmsh.model.mesh.reclassifyNodes()
surf = gmsh.model.getEntities(2)
sloop = gmsh.model.geo.addSurfaceLoop([e[1] for e in surf])
gmsh.model.geo.addVolume([sloop], 1)
gmsh.option.setNumber("General.AbortOnError", 0)
# Create a geometry for the discrete curves and surfaces, so that we can remesh
# them later on:
gmsh.model.mesh.createGeometry()
gmsh.model.mesh.generate(3)
# Launch the GUI to see the results:
gmsh.fltk.run()
Here are the node and ele files: ovoid_body.ele ovoid_body.node
The screenshot shows what the GUI gives me:
Is there a way to find out which triangle is causing the problem so that I can fix them? Is there anything in the Gmsh API that can be used to preprocess the mesh to deal with the non-manifold issue?
Thanks very much.