0

I'm trying to get to the end on a code that will help me scripting the generation of customized stl files.

The general needs I have are to :

  • be in python and if possible without other back-end software
  • minimize the dependencies
  • produce lightweight models

and specifically to :

  • generate a 3D mesh for regular shapes
  • generate a 3D mesh from text based on different fonts
  • wrap the text mesh around a cylinder
  • perform boolean operations

So far, I cannot find the right library to perform those operations.

I found the library sdf which is really awesome but generate large models.

Trimesh is great. I managed to generate the meshes of the structure, export to HTML and STL but cannot perform boolean operations without back-end.

I looked a bit into Pymesh but the librairy seems not beeing developped anymore and has a large number of dependencies.

I'm now trying with looked quickly into PyVista but currently can't get into issues with non manifold models.

here is the code that I want manifold

import numpy as np
import pyvista as pv
RES = 20

vertices = np.array([
        [20.5, -17.5, 0.0],
        [24.39711432, -8.75, 0.0],
        [24.39711432, 8.75, 0.0],
        [20.5, 17.5, 0.0],
        [19.20096189, 8.75, 0.0],
        [19.20096189, -8.75, 0.0],
        [20.5, -17.5, 0.0]])
profile = pv.MultipleLines(vertices)
profile.plot(color='tan')
extruded = profile.extrude_rotate(resolution=RES**2, rotation_axis=(0, 1, 0))#, capping=False)
print(extruded.is_all_triangles)
print(extruded.is_manifold)
print(extruded.extract_geometry().n_open_edges)
extruded.plot_normals()

# Check if all triangles :
extruded = extruded.fill_holes(4*RES)
print(extruded.is_all_triangles)
print(extruded.is_manifold)
print(extruded.extract_geometry().n_open_edges)
extruded.plot_normals()

extruded.plot(color='tan')

Step 2 is add text around it.

1 Answers1

0

I don't fully understand what you want to end up with (especially about the text part), but your cylinder is almost manifold and can be made manifold.

There are a few issues:

  1. Your fill_holes call adds a "bottom" to your cylinder. This will mess up manifoldness, because the edge of this "bottom" belongs to three faces each (one inside wall, one outside wall, and one "bottom" face). I recommend forgetting about the bottom as long as you need a manifold mesh, and only adding that bottom at the very end if you need it.
  2. Your MultipleLines call creates 7 points, so the polygonal cross-section is not actually closed. You could either create the polyline with a different approach, or just call .clean() on your profile to make it closed.
  3. You also need to remove capping from the extrusion, because that could lead to two internal faces inside the cylinder, again messing with manifoldness.
  4. If you fix the above, you end up with an extruded cylinder that has 12 open edges still: two times 6. This indicates that VTK fails to identify the two ends of the rotational extrusion as identical, and calling .clean() doesn't help either. It turns out that we have to bump up the default tolerance value to fix this. A choice of tolerance=1e-10 works nicely for your example, but you could go much higher to be on the safe side if your model's parameters can vary.

Here's the fixed snippet:

import numpy as np
import pyvista as pv

RES = 20

vertices = np.array([
        [20.5, -17.5, 0.0],
        [24.39711432, -8.75, 0.0],
        [24.39711432, 8.75, 0.0],
        [20.5, 17.5, 0.0],
        [19.20096189, 8.75, 0.0],
        [19.20096189, -8.75, 0.0],
        [20.5, -17.5, 0.0]])
profile = pv.MultipleLines(vertices).clean()
extruded = profile.extrude_rotate(resolution=RES**2, rotation_axis=(0, 1, 0), capping=False)
cleaned = extruded.clean(tolerance=1e-10)
print(cleaned.is_manifold)  # True

All that being said, boolean operations with VTK ca be finnicky. You might find that the end result still doesn't fit your use case. But you'll only know once you try.