In RhinoCommon is there an easy way to get the bounding box of an InstanceDefinition whose content I can’t know beforehand ?
my guess - you have to iterate over all objects of the definition and union the boundingboxes
Thanks Tom, I was thinking about a more “out-of-the-box” way but I will make my own recursive function.
I was digging in the API and did not find anything suitable.
maybe i arm wrong.
@dale should know better.
Hi @dale !
I’m making a small plugin to make quick pave settings on jewelry models.
I made a nice custom conduit which for each instanceObject
with a certain flag in userDictionary
will draw a circle and a text label with the size of the stone over the instance :
Since the instance definition is available to the user, they could put anything inside or transform the content however they want (which is good I think), therefore I need to know the top Z position in the definition to know where to draw the text label. So far I just check the bbox of the first geometry, which is not ideal :
def getDefinitionZLimit() :
definition = getDef()
firstObject = definition.GetObjects()[0]
if isinstance( firstObject, Rhino.DocObjects.BrepObject ) :
brepGeom = firstObject.BrepGeometry
bbox = brepGeom.GetBoundingBox( False )
return bbox.Max.Z
return 0
I’m quite new to RhinoCommon API so I’m struggling a bit.
It seems GeometryBase.GetBoundingBox is the only function to get a bounding box of anything ?
Does this do what you want?
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def BlockDefinitionBoundingBox():
blk_names=rs.BlockNames()
if not blk_names: return
blk_name=rs.ListBox(blk_names)
if not blk_name: return
blk_def=sc.doc.InstanceDefinitions.Find(blk_name)
rhobjs=blk_def.GetObjects()
#create 'empty' bounding box
bbox=Rhino.Geometry.BoundingBox()
for rhobj in rhobjs:
#get each object's geometry and bounding box
obj_bb=rhobj.Geometry.GetBoundingBox(True)
#union with current bb (bbox)
bbox.Union(obj_bb)
sc.doc.Objects.AddBox(Rhino.Geometry.Box(bbox))
sc.doc.Views.Redraw()
BlockDefinitionBoundingBox()
Note this gets the bounding box of the original block DEFINITION, not of any of its INSTANCES that might be in the document… There actually don’t need to be any instances in the file, just the definition. If you want an instance bounding box, that’s a different story.
Here is a quickie scriptlet that gets an instance geometry bounding box:
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def GetBlockInstanceBB():
msg="Select block instance for bounding box"
blk_inst=rs.GetObject(msg,4096,preselect=True)
if not blk_inst: return
geo=rs.coercegeometry(blk_inst) #InstanceReferenceGeometry
bbox=geo.GetBoundingBox(True)
if bbox.IsValid:
sc.doc.Objects.AddBox(Rhino.Geometry.Box(bbox))
sc.doc.Views.Redraw()
GetBlockInstanceBB()
Hi Mitch, thank you for taking the time to answer.
My goal is indeed to get the bounding box of an object definition that may contain an object instance (of a definition that may itself contain an instance, etc… ).
I didn’t know the class InstanceReferenceGeometry
, so I didn’t realize I could just use GetBoundingBox
on an instance. I thought I had to write a recursive function that calls itself again everytime it encounters an instance object, while computing a local transformation matrix for the geometry contained within that instance, etc…
Much simpler like that, there is an out-of-the-box solution after all, thanks again !