Compute.rhino3d.appserver partially empty output when using THREE.JS STL loader

Hello, I am currently trying to use VUE: upload STL -> THREEJS Loader -> rhino3dm -> compute.rhino3d.appserver -> compute.rhino3dm -> THREEJS Loader

My problem is, many rhino3dm meshes lead to empty outputs from the compute.rhino3d.appserver, even though the inputs work when imported in Rhino and used with the same grasshopper document in the GUI.
What could be the problem?

It works with the moon , with the simple cube, but does not with the large cube with many triangles. The TREE.JS example file seen in the lower mid doesn’t work either.

2020-11-16 14_35_22-Window

How can I find out what’s the reason for this behaviour?
There is the MeshFace.IsValid method, but I don’t know if it would help in my case. How can I determine if the rhino3dm mesh is valid or broken?

Has someone here encountered similar errors? I think using THREE.JS to load the STLs is part of the problem, as I haven’t found similar errors about on the forum.

data.zip (115.5 KB)

Attachments in the zip:

  • STL files
  • rhino3dm meshes of malfunctioning large cube and the working smaller cube as JSON

@martinborst1 I was able to import all of the STLs you posted into Rhino and push meshes back with the following definition on the AppServer: importSTL.gh (5.4 KB)

The definition has the following c# script:

private void RunScript(string path, ref object A)
{
    if( null == path ) return;

    var doc = RhinoDoc.CreateHeadless(null);
    doc.Import(path);

    var mesh = new Rhino.Geometry.Mesh();

    Rhino.DocObjects.RhinoObject[] meshObjects = doc.Objects.FindByObjectType(Rhino.DocObjects.ObjectType.Mesh);

    foreach(Rhino.DocObjects.RhinoObject mo in meshObjects)
      mesh.Append(mo.Geometry as Rhino.Geometry.Mesh);

    A = mesh;
  }

This zip contains an html and js file which calls this def and shows the resulting meshes with Three.js: importStl.zip (2.5 KB)

Let me know if this helps to resolve any of the issues you are having.

1 Like

We also now have better error logging for Grasshopper definitions in Compute. Update to the latest build to try it out.

1 Like

Hello Luis,
thanks for your help, I appreciate it.

What I am trying to do is a simple mock up of a geometry configuratior where users can upload their own initial geometry. This geometry get’s processed by grasshopper and then returned to the UI. Proving the file path to rhino therefore is no option for me, as the user and the compute server are not necessarily on the same computer / don’t have access to the same files.
I need a way to provide the geometry directly within the user interface, but current approach doesn’t work right now.

@will Thank you, I will try it out with the new version.

How are your users importing their geometry?

I am using the https://bootstrap-vue.org/docs/components/form-file vue component, which is basically just a pretty vue version of the < input type=“file” > html element (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)

I read the file using a FileReader and provide the result to the appropriate THREE loader. The loader returns a THREE mesh, which I convert to a rhino mesh via “createFromThreejsJSON”.
This rhino mesh is the one that I provide to the compute.rhino3d.appserver.

The error logging is indeed better / more verbose.

[13:40:51 ERR] An exception occured while processing request
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei Rhino.FileIO.DracoCompression.Compress(Mesh mesh, DracoCompressionOptions options)
bei Script_Instance.RunScript(Mesh mesh, Object& base64Draco) in c:\Users\borstm\AppData\Local\Temp\ma4sg4hw.0.cs:Zeile 62.
bei Script_Instance.InvokeRunScript(IGH_Component owner, Object rhinoDocument, Int32 iteration, List`1 inputs, IGH_DataAccess DA) in c:\Users\borstm\AppData\Local\Temp\ma4sg4hw.0.cs:Zeile 106.
bei ScriptComponents.Component_AbstractScript.SolveInstance(IGH_DataAccess access)
[13:40:51 DBG] Warning in grasshopper component: “Pipe” (270c8142-31cf-46d2-b965-b1d316acc58b): Input parameter Curve failed to collect data
[13:40:51 DBG] Warning in grasshopper component: “Mesh Join” (515e42f8-f9ad-4e59-8e11-0ba88af6d974): Input parameter Meshes failed to collect data
[13:40:51 DBG] Warning in grasshopper component: “Mesh” (eeef1023-fbb6-41d9-8cfe-6cc16c5fdf90): Floating parameter Mesh failed to collect data
127.0.0.1 - [2020-11-17T13:40:51.9126915+01:00] “POST /grasshopper HTTP/1.1” 200 -

I am currently experimenting with my grasshopper document and found out that something that worked before fails then if you edit the document where you don’t think it would make a difference

What is weird is that this definition leads to results with the “large_cube.stl”,

When a scale component is inserted, it doesn’t work anymore. I only tried it out with the scale component. I don’t know if the scale component is actually the problem here; all I know is that the definition breaks when added as depicted.

[14:10:14 ERR] An exception occured while processing request
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
   bei Rhino.FileIO.DracoCompression.Compress(Mesh mesh, DracoCompressionOptions options)
   bei Script_Instance.RunScript(Mesh mesh, Object& base64Draco) in c:\Users\borstm\AppData\Local\Temp\ma4sg4hw.0.cs:Zeile 62.
   bei Script_Instance.InvokeRunScript(IGH_Component owner, Object rhinoDocument, Int32 iteration, List`1 inputs, IGH_DataAccess DA) in c:\Users\borstm\AppData\Local\Temp\ma4sg4hw.0.cs:Zeile 106.
   bei ScriptComponents.Component_AbstractScript.SolveInstance(IGH_DataAccess access)

How I tested this behaviour: send request from the GUI, edit the gh file, restart the compute.rhino3d.appserver (so that it uses the new gh definition and doesn’t reuse the result from the prior request), send the same request from the GUI

Both cases work in the GUI

Another thing that I noticed is that if there is no error, the result also changes / is not same as in the GUI when editing the gh definition in minor ways.
2020-11-17 14_17_10-Window
In black: source geometry, white resulting geometry
This of course could also be an issue with my front end, but I am not sure about it.

Still, I would focus on doing the conversion directly in Rhino.

This is an iteration of the previous def that I posted: importFileData.gh (5.4 KB)

It reads the input file as bytes and encodes it as a base64 string. In gh, we decode that data, save the file to disk, import it into a headless doc, and spit out the meshes:

private void RunScript(string data, string ext, ref object A)
  {

    if( null == data || null == ext ) return;

    var decodedData = Convert.FromBase64String(data);

    var tmpPath = Path.GetTempFileName();
    tmpPath = Path.ChangeExtension(tmpPath, ext);

    File.WriteAllBytes(tmpPath, decodedData);

    if(File.Exists(tmpPath))
    {
      var doc = Rhino.RhinoDoc.CreateHeadless(null);
      doc.Import(tmpPath);

      var mesh = new Rhino.Geometry.Mesh();

      Rhino.DocObjects.RhinoObject[] meshObjects = doc.Objects.FindByObjectType(Rhino.DocObjects.ObjectType.Mesh);

      foreach(Rhino.DocObjects.RhinoObject mo in meshObjects)
        mesh.Append(mo.Geometry as Rhino.Geometry.Mesh);

      A = mesh;
    }
  }

Here is the html and js:
importFile.zip (4.0 KB)

IMPORTANT NOTE: I had to modify the AppServer request limit because I believe the default with expressjs is 100kb and one of your stls was 183kb. You should change the lines in app.js of the AppServer project:

// app.use(express.json())
// app.use(express.urlencoded({ extended: false }))
app.use(express.json({limit: '50mb'}))
app.use(express.urlencoded({limit: '50mb', extended: true, parameterLimit:50000}))

2 Likes