Gmsh in Grasshopper

Thanks for pointing out the license issue with GMSH – I’ll be more careful about that in the future.

Do you think it’s better not to share these code here, considering the license clash with Rhino? Am I violating Rhino community guidelines?

By the way, I’ve been working on a plugin inspired by MapsModelsImporter to import Google Earth geometry into Rhino. But now I’m thinking it might have a similar problem. Any advice or thoughts on this?


The main focus of the video is to showcase the Billboard component from the Javid plugin

2 Likes

Sorry, my point was that if one was to make an implementation and not distribute/publish it, that might not violate the license. But I may very well be wrong :thinking:

I believe you are correct. But then I am not really a laywer either :slight_smile:

1 Like

would it mean that it can live in the forum as a thread, but not be distributed as a plugin through PackageManager?

Posting code on a forum is still a form of distribution.

1 Like

Thanks for the explanation.
Right triremesh is for more constant length.

I used pip3.exe install numpy and the numpy library files didn’t exist in a right folder to be imported in Grasshopper, so that I copied them manually and pasted to the correct path.
Surprisingly it works.
If there is other possible approach to install packages, I would be happy to know.

I am also not a lawyer, but the license seems to be concerned with modification and distribution rather than use. If you go into the license itself:
https://gmsh.info/LICENSE.txt


And “work based on” is defined in section 2:
image
I am also not a lawyer (worth saying twice), but it seems like the original post is just using the program so is ok as it isn’t modifying or distributing. Only a sample use was distributed, not the program itself.

On the technical side, I was able to get the original script to work by following Mahdiyar’s Jan 2024 solution of installing gmsh and numpy with pip3.exe install.

Everything seems to be working, but I wasn’t able to get the fields to work. Has anyone been able to? Even changing some of the min/max and threshold distances didn’t yield a change in the mesh.

Hi @Mahdiyar, @eirannejad

I’ve been working on translating Gmsh code into C# using Gmsh.Net, but I’m running into some issues when trying to integrate Gmsh.Net.dll in the Rhino Script Editor. It seems the problem might also be related to the gmsh.dll, which is part of the library dependencies.

I downloaded the required DLL files from the following GitHub repository:
https://github.com/noy1993/Gmsh.Net/tree/master/dll/windows.

Do you have any experience or suggestions regarding how to properly use Gmsh.Net.dll in a C# workflow? Any advice on resolving this issue would be greatly appreciated!


Code:

using Rhino;
using Rhino.Geometry;
using System.Collections.Generic;
using System.Linq;
using GmshNet; // If using Gmsh.Net

void RunScript(List<Point3d> outer, List<List<Point3d>> inners, double lengthMin, double lengthMax, 
               bool quad, List<Mesh> nodes, ref object A)
{
    // 1. Initialize Gmsh
    Gmsh.Initialize();
    Gmsh.Clear();

    // 2. Set mesh properties
    Gmsh.Option.SetNumber("Mesh.CharacteristicLengthMin", lengthMin);
    Gmsh.Option.SetNumber("Mesh.CharacteristicLengthMax", lengthMax);

    // 3. Geometry definition
    int CreateLoop(List<Point3d> pts)
    {
        List<int> pointTags = pts.Select(
            p => Gmsh.Model.Geo.AddPoint(p.X, p.Y, p.Z, lengthMin)).ToList();
        pointTags.Add(pointTags[0]);

        List<int> lineTags = new List<int>();
        for (int i = 0; i < pointTags.Count - 1; i++)
        {
            lineTags.Add(Gmsh.Model.Geo.AddLine(pointTags[i], pointTags[i + 1]));
        }

        return Gmsh.Model.Geo.AddCurveLoop(lineTags.ToArray());
    }

    var outerLoop = CreateLoop(outer);

    List<int> loops = new List<int> { outerLoop };
    foreach (var inner in inners)
    {
        loops.Add(CreateLoop(inner));
    }

    int planeSurface = Gmsh.Model.Geo.AddPlaneSurface(loops.ToArray());

    // 4. Configure meshing field (if target nodes are provided)
    if (nodes != null && nodes.Count > 0)
    {
        var pointTags = nodes.Select(node => Gmsh.Model.Geo.AddPoint(node.Vertices[0].X, 
                                                                     node.Vertices[0].Y, 
                                                                     node.Vertices[0].Z)).ToList();

        int field = Gmsh.Model.Mesh.Field.Add("Distance");
        Gmsh.Model.Mesh.Field.SetNumbers(field, "PointsList", pointTags);

        int thresholdField = Gmsh.Model.Mesh.Field.Add("Threshold");
        Gmsh.Model.Mesh.Field.SetNumber(thresholdField, "IField", field);
        Gmsh.Model.Mesh.Field.SetNumber(thresholdField, "LcMin", lengthMin / 50);
        Gmsh.Model.Mesh.Field.SetNumber(thresholdField, "LcMax", lengthMax * 2);
        Gmsh.Model.Mesh.Field.SetNumber(thresholdField, "DistMin", lengthMin * 2);
        Gmsh.Model.Mesh.Field.SetNumber(thresholdField, "DistMax", lengthMin * 10 + lengthMax * 10);

        Gmsh.Model.Mesh.Field.SetAsBackgroundMesh(thresholdField);
    }

    // 5. Enable quadrangular meshing if specified
    if (quad)
    {
        Gmsh.Model.Mesh.Recombine(2, planeSurface);
    }

    Gmsh.Model.Geo.Synchronize();

    // 6. Generate the mesh
    Gmsh.Model.Mesh.Generate(2);

    // 7. Extract mesh nodes and connectivity
    var nodesArray = Gmsh.Model.Mesh.GetNodes();
    var coords = nodesArray.Item2;

    var elements = Gmsh.Model.Mesh.GetElements();
    var elementNodes = elements.Item3[0];

    // Convert data to a Rhino.Geometry.Mesh
    Mesh mesh = new Mesh();
    for (int i = 0; i < coords.Length; i += 3)
    {
        mesh.Vertices.Add(coords[i], coords[i + 1], coords[i + 2]);
    }

    int faceSize = quad ? 4 : 3;
    for (int i = 0; i < elementNodes.Length; i += faceSize)
    {
        if (quad)
        {
            mesh.Faces.AddFace((int)elementNodes[i] - 1, (int)elementNodes[i + 1] - 1,
                               (int)elementNodes[i + 2] - 1, (int)elementNodes[i + 3] - 1);
        }
        else
        {
            mesh.Faces.AddFace((int)elementNodes[i] - 1, (int)elementNodes[i + 1] - 1,
                               (int)elementNodes[i + 2] - 1);
        }
    }
    mesh.RebuildNormals();
    mesh.Compact();

    // 8. Output the mesh to Grasshopper
    A = mesh;

    // Finalize Gmsh
    Gmsh.Finalize();
}

@eirannejad !!!Grasshopper script editor is busy gmsh.dll and can’t load it !!

  • What happens if you put the #r line on the first line of the script outside of the #region?
  • Would it be possible to test with a simpler dll path that does not include special characters like #?

Also please DM me the report in RhinoCodeLogs command. You should be able to run that command on Rhino prompt

I test (## R on the first line of the script outside ‘area’) and the crash of rhino