I’ve noticed when using rhino3dm.File3dmObject.Geometry.GetBoundingBox() the box returned ignores surface trimming, and encompasses control points for curves.
I fear I’m asking a dumb question, but how can I work around this and get bounding boxes that don’t include control points / untrimmed portions of objects?
This functionality isn’t available in stand alone rhinod3m. If you have a render mesh attached to your Brep, you can use the mesh’s bounding box to get a tighter bbox.
import compute_rhino3d.Util
import compute_rhino3d.Mesh
from rhino3dm import File3dm, MeshType
# compute_rhino3d.Util.url = 'http://192.168.1.218:8080/'
f = File3dm.Read('trim.3dm')
brep = f.Objects[0].Geometry # get trimmed surface
# option 1. - bounding box from trimmed surface (ignores trim)
a = brep.GetBoundingBox()
# option 2. - bounding box from render mesh (might not be present)
mesh = brep.Faces[0].GetMesh(MeshType.Any)
b = mesh.GetBoundingBox()
# option 3. - use compute to mesh surface, then get bounding box (if you don't have a render mesh)
c = compute_rhino3d.Mesh.CreateFromBrep(brep)[0].GetBoundingBox()
n = File3dm()
n.Objects.AddBrep(brep)
n.Objects.AddBrep(a.ToBrep())
n.Objects.AddBrep(b.ToBrep())
n.Objects.AddBrep(c.ToBrep())
n.Write('box.3dm', 7)
print('Saved to box.3dm')
I just updated compute to properly handle computing an accurate bounding box for all geometry types. There was some code in compute.rhino3d that was not properly deserializing to the GeometryBase class from JSON.
I apologise for being dense @stevebaer but are you able to provide a 2 or 3 line example?
I cannot get it to work for me. compute_rhino3d.GeometryBase is abstract, and compute_rhino3d.Brep (for example) doesn’t implement GetBoundingBox( … ).
(rhino3dm.Brep does but that’s the untrimmed version)
import compute_rhino3d.GeometryBase
from rhino3dm import BoundingBox
# [...] get `brep` from somewhere
# Brep derives from GeometryBase, so it can be passed to GetBoundingBox()
data = compute_rhino3d.GeometryBase.GetBoundingBox(brep, True)
# GetBoundingBox() returns a dict that isn't automatically deserialised, but
# we can easily construct a BoundingBox from the data if we need it
bbox = BoundingBox(data['Min']['X'], data['Min']['Y'], data['Min']['Z'], data['Max']['X'], data['Max']['Y'], data['Max']['Z'])
print(bbox)
@stevebaer, do we need a DecodeToBoundingBox and/or a DecodeToBox in Utils?
Thanks Will, much appreciated, that is what I was doing, I get this result: (my server is up and operating fine, I have v0.12.1 of the compute python library)
@fergus.hudson, the “instances of abstract classes cannot be created” bug has already been fixed (see #129). Have you tried updating your server? If you used the bootstrap script to set up your server then there’s a handy update script that you can download and run.