Performance Drop When Unrolling Offset Brep Faces

Hello everyone,

I’m currently facing some performance issues and would appreciate your insights. (Apologies in advance for not including a file.)

The issue arises when I offset a Brep face and then unroll it. I ran a small test comparing the performance of unrolling with and without the offset step. The results were quite different:

  • With offset: ~960 ms
  • Without offset: ~170 ms

The Brep faces themselves are relatively simple, mostly partial cylindrical surfaces (blue/green in the model).

So what is basically happening

var offset = Brep.CreateFromOffsetFace(face.Face3D, offsetDistance,
    Tollerances.AbsoluteTolerance, false, false);

//When i dont offset the unroller is way faster 
//Also when i set the offset distance to 0, still same problem
var unroller = new Rhino.Geometry.Unroller(offset);
unroller.AbsoluteTolerance = Tollerances.AbsoluteTolerance;
var edgeIdList = new List<Guid>();
var edgeList3d = new List<Curve>();
var normalAtEdge = new List<Vector3d>();
var results = unroller.PerformUnroll(out var curves2D, out _, out _);

Has anyone experienced similar behavior or knows why the offset step causes such a significant slowdown? Any suggestions on how to improve the performance would be greatly appreciated.

Thanks in advance!

offset-unroll.gh (33.1 KB)

I think it’s due control points and isocurves

2 Likes

offsetPerformance.gh (12.9 KB)

did a fast less extensive test then @martinsiegrist.

my guess:
it makes a huge difference if the surfaces are trimmed / untrimmed …
i internalized a shrunk and default / filletEdge Geometry in above .gh.

also tolerances might cause issues.

@felix.brunold
provide some geometry
what tolerance are you using ?

try to
_shrinkTrimmedSrfToEdge
before you run the test.
use Stopwatch inside your code to figure out wether it is Brep.CreateFromOffsetFace or unroller.PerformUnroll.

in rhinocommon
https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.collections.brepfacelist/shrinkfaces

kind regards - tom

2 Likes

Thanks a lot @martinsiegrist and @Tom_P for your input!

Based on your suggestions, I did some further testing and found that ShrinkFaces() made a significant difference in performance… that definitely helped!

Regarding tolerances: I was previously using the document’s absolute tolerance. However, I noticed that setting the tolerance to 0 shaved off a few more milliseconds. I still need to test whether this holds up well in edge cases, but it looks promising so far. Thanks guys

offsetPerformance_fb.gh (164.6 KB)

Looks already way better:

(Before)

(After)

(Remark)
I removed

unroller.AbsoluteTolerance = Tollerances.AbsoluteTolerance 

And went with the default settings. That made also quite a difference. So from 1sec to 87ms looks good to me.

Dear @felix.brunold

another approach:
my guess - rhino does not have a special method to offset cylindrical surfaces.
But offsetting a cylindrical surface can be done by scale2d.

below approach is 3-5% faster for the shrunk surfaces
and 30% faster for un-shrunk surfaces

you may also consider parallel.for to do the offset. Rhino is not very suitable for Multi-Threading check this forum.

        BrepFace face = brep.Faces[index];
        Brep offset = null;
        if (brep.Surfaces[face.SurfaceIndex].TryGetCylinder(out Cylinder cylinder))
        {
            offset = face.ToBrep();
            double k = (cylinder.Radius + offsetD) / cylinder.Radius;
            // 2d scale instead of offset
            Transform xForm = Transform.Scale(cylinder.BasePlane,k,k,1.0);
            offset.Transform(xForm);
        } else
        {
            offset = Brep.CreateFromOffsetFace(face, offsetD,tolerance, false,false);
        };

updated version - same name sorry:
offsetPerformance.gh (19.0 KB)

if this helps - you owe me a coffee or beer in Zürich - looks like we both are based here.

good luck with your promising plug-in

cheers - tom

1 Like

Well @Tom_P

Looks like I owe you with pleasure a coffee or a beer!
Amazing thanks!