Gmsh in Grasshopper

For an exciting personal project, I’ve been exploring remeshing techniques using Grasshopper. Typically, I rely on @DanielPiker 's Remesh by Color - a fantastic component that’s been essential to my workflow (see an example here). However, for this project, I decided to look beyond the usual and integrate Gmsh, a popular finite element mesh generator, into Grasshopper. Surprisingly, incorporating Gmsh was a smooth process, thanks to the new Python script which now supports Python 3. Here’s my code. It’s quite basic and there’s room for improvement. The key part is converting a Gmsh mesh into a Rhino mesh.

#r: gmsh

import gmsh
import Rhino.Geometry as rg
import numpy as np

gmsh.initialize()

gmsh.clear()
gmsh.option.setNumber("Mesh.CharacteristicLengthMin", length.Min)
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", length.Max)


def create_loop(pts):
    p_tags = [gmsh.model.geo.add_point(p.X, p.Y, 0.0, p.Z+0.01) for p in pts]
    p_tags.append(p_tags[0])
    l_tags = [gmsh.model.geo.add_line(pt1, pt2) for pt1, pt2 in zip(p_tags, p_tags[1:])]
    return gmsh.model.geo.add_curve_loop(l_tags)


loops = [create_loop(outer)]
loops.extend(create_loop(inner) for inner in inners.Branches)
plane_surface = gmsh.model.geo.add_plane_surface(loops)

if nodes != None:
    p_tags = [gmsh.model.geo.add_point(n.X, n.Y, n.Z) for n in nodes]
    field = gmsh.model.mesh.field.add("Distance")
    gmsh.model.mesh.field.setNumbers(field, "PointsList", p_tags)
    threshold_field = gmsh.model.mesh.field.add("Threshold")
    gmsh.model.mesh.field.setNumber(threshold_field, "IField", field)
    gmsh.model.mesh.field.setNumber(threshold_field, "LcMin", length.Min / 50)
    gmsh.model.mesh.field.setNumber(threshold_field, "LcMax", length.Max * 2)
    gmsh.model.mesh.field.setNumber(threshold_field, "DistMin", length.Min * 2)
    gmsh.model.mesh.field.setNumber(
        threshold_field, "DistMax", length.Min * 10 + length.Max * 10
    )
    gmsh.model.mesh.field.setAsBackgroundMesh(threshold_field)
    
if quad:
    gmsh.model.geo.mesh.setRecombine(2, 1)
gmsh.model.geo.synchronize()
gmsh.model.mesh.generate(2)  # 2 for 2D mesh


coords = np.array(gmsh.model.mesh.getNodes()[1]).reshape(-1, 3)
faces = np.array((gmsh.model.mesh.getElements()[2][1]) - 1).reshape(
    -1, 4 if quad else 3
)
gmsh.finalize()

mesh = rg.Mesh()
for point in coords:
    mesh.Vertices.Add(*point)
for face in faces:
    mesh.Faces.AddFace(*[int(v) for v in face])
mesh.RebuildNormals()
mesh.Compact()
a = mesh

Gmsh.gh (14.5 KB)

P.S. I’m aware of the Iguana plugin, which also utilizes GMSH. However, for this project, I wanted more direct control over the remeshing process, which led me to take this approach.

26 Likes

So cool! Adding it to my tests :smiley:

3 Likes

hi cool @Mahdiyar
@eirannejad
i get this error to call gmsh.py
i install by this pip install --upgrade gmsh

I Test this methods to call gmsh but error come
#r:C:\Users\es\AppData\Local\Programs\Python\Python310\Lib\site-packages\gmsh.py
#r: gmsh```


I also installed gmsh with pip and I get this error:

Warning: could not find Gmsh shared library gmsh-4.12.dll with ctypes.util.find_library() or in the following locations: ['C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\default-CQsG1puP\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\default-CQsG1puP\\lib\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\default-CQsG1puP\\Lib\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\lib\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\site-envs\\Lib\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\lib\\gmsh-4.12.dll', 'C:\\Users\\martinsiegrist\\.rhinocode\\py39-rh8\\Lib\\gmsh-4.12.dll']

same here :slight_smile:

I’m using the copypasted code you posted starting with #r: gmsh
line 3 is the import gmsh

fix error by:@mahdiyar solotion install this in CMD:

C:\Users\%UserName%\.rhinocode\py39-rh8\Scripts\pip3.exe install gmsh


C:\Users\%UserName%\.rhinocode\py39-rh8\Scripts\pip3.exe install numpy

thanks for @mahdiyar

1 Like

At present, to install Gmsh, one needs to manually use pip. However, thanks to @eirannejad the upcoming 8.4 release candidate will simplify this.

# venv: site-packages
# r: gmsh

This approach is particularly useful when packages cannot be installed in separate virtual environments. For instance, Gmsh has DLLs that are not copied during package installation, and pip does not flag this as an issue.

In the meantime, you can use the following commands in the command prompt to install Gmsh and numpy:

C:\Users\%UserName%\.rhinocode\py39-rh8\Scripts\pip3.exe install gmsh
C:\Users\%UserName%\.rhinocode\py39-rh8\Scripts\pip3.exe install numpy
4 Likes

Here’s another example of using Gmsh in Grasshopper. The dress’s mesh is also made in Rhino and Grasshopper, using Kangaroo. You can see how it’s done here.

11 Likes

interesting, how did you pass the mesh rhino component to gmsh.model?

btw, in case you hadn’t noticed yet: gmsh license (GPL) is incompatible with Rhino (closed source).

1 Like

As ignorant in this matter, what does that mean and/or what did you meant with that? :sweat_smile:
It means that gmsh cannot be integrated in rhino?
What about keeping it as an external installed library in the system but accessing it through compiled plugins for Rhino? Would that be ok?

2 Likes

Correct

No, since the plugins would have to somehow link to it, and runs in the Rhino process.

1 Like

Thank you for the quick answer.

Plugins are compiled and work “under the hood”… nobody can see how…

What about how Mahdiyar did? Throug a not-yet-compiled script.
The code calling for that library is “open”, plain readable… still no? :thinking:

Still no, it is against GPL terms.

1 Like

Thank you for the clarification.


That’s sad. :neutral_face:

Doesn’t the “…you plan to distribute” part from their licensing give some “wiggle room” for personal use?

3 Likes

… lol?

The code is published…

1 Like

What’s make gmsh better than the triremesh component?
Thanks

The TriRemesh component is indeed excellent. However, what I demonstrated is more aligned with what the Remesh By Color component can achieve. TriRemesh tends to create meshes with edges of similar lengths, although @DanielPiker has mentioned plans to introduce support for variable mesh sizing.

There are other interesting remeshing tools, such as the one in the @Petras_Vestartas NGon plugin, which implements Remeshing from Geometry3Sharp.

I should mention that GMSH is a three-dimensional finite element mesh generator, and the content I shared in the video only scratches the surface of its capabilities.
image

You can see what Gmsh is really good at here.

2 Likes