Automatically bake .ghx files to .ply

Hello friends,

I have many thousands of .ghx files and I need to convert them into .ply files. The manual workflow would be to open Grasshopper, bake the component to Rhino and then saveAs file.ply.

However, as I have thousands of files and will have thousands more in the future, a manual approach is not feasible.
What would be the best was to automate this?

Thanks a lot.

Probably easiest to create a C# script (or VB or Python) inside Grasshopper. You give this script a folder or list of filenames, it loads them all, runs them all, bakes them all, then unloads the ghx files, selects the geometry and runs the Export command.

Is there a good rule for which parameters in the ghx files contain the meshes you wish to bake?

This is not great in terms of automation, but it may get you started: processor.gh (2.8 KB)

As per usual there is some juggling involved trying to do things from within a solution (which is where the RunScript() method runs). So I have to create a form with a button which allows the process to run starting from a UI event instead.

  private void RunScript()
  {
    var form = new System.Windows.Forms.Form();
    form.ShowInTaskbar = false;
    form.Text = "PLY Process";
    form.MinimizeBox = false;
    form.MaximizeBox = false;
    form.Size = new System.Drawing.Size(200, 200);

    var button = new System.Windows.Forms.Button();
    button.Dock = System.Windows.Forms.DockStyle.Fill;
    button.Text = "Run!";
    button.Click += ButtonClick;

    form.Controls.Add(button);
    form.Show(Grasshopper.Instances.DocumentEditor);
  }

  // <Custom additional code> 
  private void ButtonClick(object sender, EventArgs e)
  {
    System.Windows.Forms.OpenFileDialog dlg = new System.Windows.Forms.OpenFileDialog();
    dlg.Filter = "Grasshopper Files|*.gh;*.ghx";
    dlg.Multiselect = true;

    if (dlg.ShowDialog(Grasshopper.Instances.DocumentEditor) != System.Windows.Forms.DialogResult.OK)
      return;

    var names = dlg.FileNames;
    foreach (var name in names)
      LoadAndBakeAndExportFile(name);
  }

  private void LoadAndBakeAndExportFile(string ghxFile)
  {
    var editor = Grasshopper.Instances.DocumentEditor;
    if (!editor.ScriptAccess_OpenDocument(ghxFile))
      return;

    var doc = Grasshopper.Instances.ActiveCanvas.Document;
    doc.NewSolution(false);

    var ids = BakeFile(doc);

    Rhino.RhinoDoc.ActiveDoc.Objects.UnselectAll();
    Rhino.RhinoDoc.ActiveDoc.Objects.Select(ids);

    string folder = System.IO.Path.GetDirectoryName(ghxFile);
    string filename = System.IO.Path.GetFileNameWithoutExtension(ghxFile);
    string filepath = folder + System.IO.Path.DirectorySeparatorChar + filename + ".ply";

    string command = string.Format("-_Export \"{0}\" _Enter _Enter _Enter", filepath);
    Rhino.RhinoApp.RunScript(command, false);

    Rhino.RhinoDoc.ActiveDoc.Objects.Delete(ids, true);
    editor.ScriptAccess_CloseDocument();
  }
  private HashSet<Guid> BakeFile(GH_Document doc)
  {
    var ids = new HashSet<Guid>();
    foreach (var obj in doc.Objects)
    {
      if (obj.NickName != "Export")
        continue;

      var param = obj as Grasshopper.Kernel.Parameters.Param_Mesh;
      if (param == null)
        continue;

      foreach (IGH_Goo goo in param.VolatileData.AllData(true))
      {
        var mesh = goo as GH_Mesh;
        if (mesh == null)       continue;
        if (mesh.Value == null) continue;

        ids.Add(RhinoDocument.Objects.AddMesh(mesh.Value));
      }
    }
    return ids;
  }
1 Like

Thank you so much. That is very helpful!

Hi David,

I have one more small question. I want to only bake the object that is farthest to the right on the grasshopper canvas.
But I’m not sure how to select that component. Do you have any ideas?

You need to iterate over all the IGH_DocumentObjects in the document, get their attributes, get the attribute Bounds and filter for the Right property.

Thanks!

Hi David, you helped me a lot already, but I have another question.

I’m writing the whole script in Python and I’m able to load the file and identify the most right component, but I still haven’t figured out how to bake it.

Basically, I don know how to translate these two lines into Python:

var param = obj as Grasshopper.Kernel.Parameters.Param_Mesh;

ids.Add(RhinoDocument.Objects.AddMesh(mesh.Value));

Could you give me another hint?

Sorry, no hablo Python.