I can’t find any solution to my problem - Automated exploding blocks with preserved texture mapping of the output geometry. In my example, geometry inside the block definition is using box mapping.
Approaches I tried:
With the use of Grasshopper components from plugins: Heteroptera, Human, Elefront.
I can receive internal geometry this way but without attributes. I can reassign materials but not the mapping of course.
ExplodeBlock command in Rhino - manual approach gives me good results but it is manual. I could try to run Rhino command from Grasshopper with the use of "Rhino Command " component from LunchBox plugin but such an approach is far from how should it be. I would need to select geometry in the Rhino window etc.
My last hope - Python.
I used rs.ExplodeBlockInstance method Rhino - RhinoScriptSyntax
Unfortunately, it changes the mapping (rotates it to match world cplane and maybe does something more to it).
All of the approaches I took are visible on the screenshot and in the file that I attached.
import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc
def coerceinstanceobject(id, raise_if_missing):
rhobj = rs.coercerhinoobject(id, True, raise_if_missing)
if isinstance(rhobj, Rhino.DocObjects.InstanceObject): return rhobj
if raise_if_missing: raise ValueError("unable to find InstanceObject")
def test_explodeinstance():
iref_id = rs.GetObject("Select block instance to explode", rs.filter.instance);
if not iref_id: return
iref = coerceinstanceobject(iref_id, True)
if not iref: return
xf = iref.InstanceXform
yes = xf.IsValid and not xf.IsZero and not xf.IsIdentity
guids = sc.doc.Objects.AddExplodedInstancePieces(iref, False, True)
if guids:
if yes:
for id in guids:
rhobj = sc.doc.Objects.FindId(id)
atts = rhobj.Attributes.Duplicate()
atts.Transform(xf)
sc.doc.Objects.ModifyAttributes(id, atts, True)
sc.doc.Objects.Delete(iref_id, True)
sc.doc.Views.Redraw()
test_explodeinstance()
I converted it into this to use it inside Grasshopper.
import rhinoscriptsyntax as rs
if toggle:
Guidy =
Guidy.append(x)
guids = Guidy
for guid in guids:
rs.Command(" _Explode " + " SelID " + str(guid) + " Enter ")
else:
print “off”
Using this method, is there a straightforward way to receive guids of all exploded geometries? If I explode 3 blocks and use Last Created Objects, it selects only one set of geometry.