Export stl files with C# component in GH


(Davidand103) #1

Hi,

I would like to export my GH generated geometry as stl files without baking the geometry, i.e. I don’t want to leave grasshopper. Preferably do I want to do it in C# since I then can include it in my own components I’m developing at the moment.

I’ve done some reasearch but I can’t find what I’m really looking for, so I need some help here and I would be thankful for any help!

Regards, David.


#2

I used to do something like this, but if there is a direct way to call rhino common export methods I would also be quite interested… Maybe there are also smarter ways to react to the errors by raising exceptions or so…

    protected void ExportSat(List<Brep> breps, string path)
    {
        List<Guid> guidList = new List<Guid>();
        Rhino.DocObjects.Tables.ObjectTable ot = Rhino.RhinoDoc.ActiveDoc.Objects;
        for (int i = 0; i < breps.Count; i++)
        {
            if (breps[i] == null || !breps[i].IsValid)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No object to bake, or brep not valid, aborted.");
                return;
            }
            System.Guid guid = ot.AddBrep(breps[i]);
            guidList.Add(guid);
        }
        int nSelected = ot.Select(guidList);
        if (nSelected != guidList.Count)
        {
            this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Not all objects could be selected, aborted.");
            return;
        }

        string cmd = "-_Export " + path + ".sat" + " _Enter";
        Rhino.RhinoApp.RunScript(cmd, false);

        ot.Delete(guidList, true);
    }

Grasshopper becomes uncontrollable when I use export stl component
(Giulio Piacentino) #3

The method @dsonntag mentions will work nicely for all supported file extensions.
Otherwise, if you want to export meshes to OBJ in Rhino 6, you can use:
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_FileIO_FileObj_Write.htm

See this thread for an example:

Finally, writing a simple version of an STL file is not terribly complicated. I wrote Turtle a while ago, and it contains an example:

also the second link above contains a definition that already does that. Check it out!


(Davidand103) #5

Thanks @dsonntag and @piac for your replies.

I’m quite new to C# so please bear with me here when I have some follow up questions.

I tried to implement the code snippet you send @dsonntag and first of all the AddRuntimeMessage didn’t work, so I replaced it with a Print() line instead. What do I need to modify to make that line work and also If I make this work would this give me an error message directly on the GH component instead of printing the error in the out as my line does?

Have I understod it correctly when I say that this is a function/method that I should write under //costum additional code ? And to execute the function I obviously have to call it in my main code as ExportSat(x, y);, but this alone does not export the file though does it?

Lastly, if I want to export the brep in an other format can I then simply replace .sat with .stl, .dwg, .dxf, etc.?

I managed to figure this out on my own. By replacing the suffix I export the brep’s in a different format and I had written the path incorrectly so I didn’t see the export, i.e. it is enough to call ExportSat(x,y); to export the files. However, the first question remains.

Regards, David.


#6

The method is taken from a compiled component developed in Visual Studio. If you want to use it in a C#-script component, you need to adjust the lines you mentioned, for example by either printing the Error message as you proposed, or by replacing “this” with “Component”, so:

Component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, 
   "No object to bake, or brep not valid, aborted.");

If this the apropiate way to handle errors depends on your case. In the code snippet, if you try to export/bake invalid or null objects it will create a red Error balloon on the component and stop working (because in my case I assume that generally something is not working properly, and I want to see this immediately). But obviously you could also just skip invalid/null items and handle only items you know how to deal with, e.g. by removing the error message or replace it with a warning, and replace the return; with continue;.


(Davidand103) #7

Yeah I understood that when I moved the code to Visual Studio because then the Print() line didn’t work instead.

And I see what you are saying there with handeling the errors, there are many ways obviously and I will adapt it to what suits me the best.

One last qustion though - I realized that it doesn’t work when I try to export to a path that has a " " in the string e.g. C:\Users\admin\Desktop\Test folder. Is there some way of resolving this since I will not ALWAYS have control of the incoming path.


#8

Yeah, this is a bug, I remember I had that but never fixed it :grimacing:

I think this should work:

string cmd = "-_Export " + "\"" + path + ".stl" + "\"" + " _Enter";

(Davidand103) #9

It sure did, thank you!


(Davidand103) #10

Another bug I’ve found in the code is that when I wrap the code in an boolean statement ( if(button)…) grasshopper freezes when I execute the code, meaning I cant insert new components, pan the view, connect wires, etc., but I can press the button again and when I do so grasshopper again works fine. During the whole time Rhino is working as normal though. I find it very strange and I’ve been trying to find out what the problem is but I can’t figure it out.

This is how I’ve adapted the code:

protected void ExportStl(Brep geom, string path)
        {
            List<Guid> guidList = new List<Guid>();
            Rhino.DocObjects.Tables.ObjectTable ot = Rhino.RhinoDoc.ActiveDoc.Objects;
            
            System.Guid guid = ot.AddBrep(geom);
            guidList.Add(guid);
            
            int nSelected = ot.Select(guidList);
                        
            string cmd = "-_Export " + "\"" + path + ".stl" + "\"" + " _Enter" + " _Enter";
            Rhino.RhinoApp.RunScript(cmd, false);           

            ot.Delete(guidList, true);
        }

I’ve excluded some if statements now to make it a bit lighter, they are anyways only there to catch errors and are not the source of the problem.


#11

I guess this is related to this:


(Davidand103) #12

It definitely is, thanks for a quick reply.

I solved by either holding down the button longer before releasing it or by replacing it with a boolean toggle.


#13

Yeah, I do use this script only in components which are triggered by a toggle. As mentioned in the other post this is not per se a bug of the script but rather of the combination button + executing a command in rhino using RhinoApp.RunScript(). Guess you’ll have to ask the Rhino guys why this is…