RhinoCommon BrepFace accurate BoundingBox Issue

Hi,
if I split any brep and join it back togethor, I will get the correct bounding box of each face in the Rhino GUI by selecting the indivual face and using the BoundingBox command. In RhinoCommon this is not the case. For each face I get the bounding box of the original untrimmed surface. I only get accurate face bounding boxes, if I first shrink all faces of the brep. Is this behaviour in RhinoCommon intended or an issue? Usually, I do not check, if all surfaces are shrunk in my model.

See the simple cpython script below that demonstrates this issue:

import Rhino
import scriptcontext as sc
import rhinoscriptsyntax as rs

def main():

    shrink_faces = True
    #shrink_faces = False

    # Create a rectangle
    split_plane_origin = Rhino.Geometry.Point3d(0, 0, 0)
    split_plane_normal = Rhino.Geometry.Vector3d(0, 1, 0)
    split_plane = Rhino.Geometry.Plane(split_plane_origin, split_plane_normal)

    brep_rectangle = Rhino.Geometry.PlaneSurface(split_plane, Rhino.Geometry.Interval(0, 10), Rhino.Geometry.Interval(0, 100)).ToBrep()
    #sc.doc.Objects.AddBrep(brep_rectangle)

    # Create a split plane at the specified location
    split_plane_origin = Rhino.Geometry.Point3d(50, 0, 5)
    split_plane_normal = Rhino.Geometry.Vector3d(1, 0, 0)
    split_plane = Rhino.Geometry.Plane(split_plane_origin, split_plane_normal)

    split_brep = Rhino.Geometry.PlaneSurface(split_plane, Rhino.Geometry.Interval(-10, 10), Rhino.Geometry.Interval(-10, 10)).ToBrep()
    #sc.doc.Objects.AddBrep(split_surface)

    new_breps = brep_rectangle.Split(split_brep, sc.doc.ModelAbsoluteTolerance)
    
    new_brep = Rhino.Geometry.Brep.JoinBreps(new_breps, sc.doc.ModelAbsoluteTolerance)[0]

    sc.doc.Objects.AddBrep(new_brep)

    if shrink_faces:
        new_brep.Faces.ShrinkFaces()

    for i, face in enumerate(new_brep.Faces):
        print(f'face = {i}, bbox = {face.GetBoundingBox(True)}')

    return


if __name__ == "__main__":
    main()

Using shrink_surfaces=False will print the following:

face = 0, bbox = 0,0,0 - 100,0,10
face = 1, bbox = 0,0,0 - 100,0,10

Using shrink_surfaces=True will print the correct bounding box as follows:

face = 0, bbox = 49.999999999999986,0,0 - 100,0,10
face = 1, bbox = 0,0,0 - 50,0,10

Hi @daniel.kowollik

The GetBoundingBox method of a face is indeed confusing / misleading. As it will get the boundingbox of the underlying surface.

To get the boundingbox of the trimmed face you can first construct a single face brep from the face and get the boundingbox if the brep:

https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.brepface/duplicateface

Does that help?

Thank you for your response. I am using the bounding box method to be faster with search algorithms. Your idea generates more overhead and more memory usage. The workaround with ShrinkFaces generates also overhead, but reduces memory usage, therefore I prefer my workaround for now.
Is there anyone from McNeel, who has an opinion on this topic?

Hi @daniel.kowollik,

To compute the bounding box of a Brep face, use BrepFace.DuplicateFace to create a single-faced Brep. Then compute the bounding box from the resulting Brep.

– Dale

Hi @dale,
thank you for your answer. Both workarounds seem to generate the same result. Does that mean BrepFace.GetBoundingBox is no bug?

Correct. BrepFace is a proxy for its underling surface and does not implement (override) Surface.GetBoundingBox.

– Dale