Transform GUID in GH?

I am currently looking for a quick way to transform Rhino geometry from Grasshopper without referencing and baking.

OpenNest’s Transform GUID is basically what I need, but unfortunately they did not expose the delete orignal boolean, so you always keep the original.

Does anyone know a quick way of transforming GUID and deleting the original Geometry?

My pseudo code attempt in Python (ps: I don’t really know Python):

"""Provides a scripting component.
    Inputs:
        x: List of GUIDs
        y: List of Transforms
        z: Bool delete original
        u: Trigger transform
    Output:
        a: The a output variable"""

__author__ = "seltz"
__version__ = "2022.03.09"

import rhinoscriptsyntax as rs
import Rhino as rc
import scriptcontext as sc
import System.Guid

sc.doc = rc.RhinoDoc.ActiveDoc

if u:
    for i in x:
        rhobj = x(i)
        xform = y(i)
        delete = z
        sc.doc.Objects.Transform(rhobj, xform, delete)
        sc.doc.Views.Redraw()

This post also seems relevant: Curious: Faster to Transform then delete rather than Transform with delete true

Here is what I want to do:

Set any number of “floor objects”, set any number of geometries placed above the floor, transform the objects so they sit directly on the floor objects:

ground_object.3dm (183.5 KB)
ground_object.gh (27.7 KB)

Thanks!

You can replace a Rhino document object, that might help. Here’s a rhinoscriptsyntax example (that uses RhinoDoc.Objects.Replace behind the scenes):

Thanks, I have updated my code above slightly with some inputs from that post you linked.

So it’s not possible to use the Transform method and set the delete boolean to true?

As I said I am not good in Python in Grasshopper. I was hoping you could spot what is wrong with my python code.

Current error:

image

Thank you.

Ah yes, sorry I missed the details, no it looks like it is:

https://developer.rhino3d.com/api/RhinoCommon/html/Overload_Rhino_DocObjects_Tables_ObjectTable_Transform.htm

You could also implement rhinoscriptsyntax.MoveObject instead, might be the simplest I’d imagine.

Edit: Here’s a super fast example of using rhinoscriptsyntax.MoveObjects (note: plural):

220309_MoveObjects_GHPython_00.3dm (270.8 KB)
220309_MoveObjects_GHPython_00.gh (3.5 KB)

Edit II: Nevermind, this causes an expiration error. Will have a look when I get some time.

1 Like

it should be x[i] , not x(i), etc
And for i in range(len(x))

1 Like

Ah yes, I get the same with the fixes to my script from @gankeyu :smiley:

Hm, any ideas what the problem is?

ps: if you simply tick “Do not show this message again”, it does work until the next time you restart Rhino though.

Thank you. I can’t believe I was that close already. Maybe I DO need to learn some python for GH :thinking:

If you get GUID from referenced geometry, the geometry parameter will be expired if any transforms are made. If so, you probably put a Data Dam between geometry and GUID (iirc)

Bests,
Keyu Gan

1 Like

I’m pretty sure we’re getting caught in a feedback loop, where the added/manipulated Rhino object geometry parameter will retrigger the GHPython component during computation. You can internalise the guid list to avoid this:

Edit: You could also use rs.SelectedObjects(), like in my first post above, to input the geometry, which also negates the expiration error:


220310_MoveObjects_GHPython_00.3dm (272.6 KB)
220310_MoveObjects_GHPython_00.gh (2.2 KB)

If the Python component is the terminal component, you can put the transform code in AfterSolveInstance (with SDK mode enabled) Otherwise you need to revise the logic flow.

Unfortunately then the data dam expires:

That sounds good. Can you show how to implement it? I can’t see any Python examples, only VB and C#!?

Interestingly, if I make it into a Grasshopper Player command it works with no error messages (they are probably just hidden).

That’s kind of what I wanted anyways. Now if only there was a better boolean input for Grasshopper Player. Why can’t we set a default for a boolean, so you only have to press Enter like you do for Rhino commands?? Or just add a component that is only a confirmation.

I tried with just having the the u input set to always true, so you don’t have to have a stupid boolean just to ask “do you really want to do the thing you started the command for”, but then it transforms twice.

ground_object_player.gh (25.7 KB)

Hi all!
I tried with c#, and I’ve seen one of the problem is when you are using multiple IDs , committing a change on the first object would already retrigger the c# while it is still working on the second…
A solution: load your IDs and transformations as tree, so the c# is executed only once for each button press.

c# transform referenced geo
c# transform referenced geo.gh (7.8 KB)

Please provide same-structure and same-length trees on “id” and “T” parameters. (maybe use longest list before?)
Also, this is ignored by undo function, so beware!

Code probably can be tweaked in many ways.

 private void RunScript(DataTree<Guid> id, DataTree<Transform> T, bool go)
  {
    if(go){
      if(!ex){
        ex = true;
        ID = id;
        t = T;
        GrasshopperDocument.ScheduleSolution(5, SolutionCallback);
      }
    }else{ex = false;}
  }

  // <Custom additional code> 
  private bool ex;
  private Grasshopper.DataTree<Guid> ID;
  private Grasshopper.DataTree<Rhino.Geometry.Transform> t;

  private void SolutionCallback(GH_Document doc){
    for(int i = 0;i < ID.AllData().Count;i++){
      Rhino.DocObjects.RhinoObject obj = this.RhinoDocument.Objects.FindId(ID.AllData()[i]);
      obj.Geometry.Transform(t.AllData()[i]);
      obj.CommitChanges();
    }
  }

Hi Armin -

You could do something like this:
image

-wim

1 Like