OffsetCrvOnSrf inconsistent even on simple geometry

Offset by 84 fails, but by 55 works…
OffsetCrvOnSrfby84.3dm (24.2 KB)

Hello - as far as I can see an offset of 84 falls completely off the surface.

-Pascal

I see. But that’s not how it works if at least 1 nanometer of an offset curve falls onto surface. It magically appears to fill surface border to border. Which is another thing that doesn’t make sense. Albeit it’s a good thing in my case.

Any idea how to alleviate it?

Correct - the curve is extended - but I would not count on the extended part of curve to always be an offset. The result is always explodable into offsets and extensions.

In this case, since your curve is a line, and the surface planar, the solution is to set a CPlane to the surface, offset the line and extend it. Or, make a Cylinder at 84 radius, using the line endpoints as guides, tall enough to intersect the surface.

-Pascal

Yeah, that’s very clunky. Nothing that can’t be scripted, but I was hoping for some improvement in OffsetCrvonSrf from R4 to R6.

I think the command isn’t “smart” enough as if it “thinks” the offset curve falls over the opposite edge of the surface while in this case it’s simply off to the side.

Just dawned on me - another solution would be to offset in 2 or 3 steps… Probably less screwery would be involved to get to the result too. And it’d work for non-planar surfaces. Thanks for insight!

Here’s a thing that may help if the inputs are simple like your example

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc


def test():
    rad = 1
    if sc.sticky.has_key('CYL_BREP_RADIUS'):
        rad = sc.sticky['CYL_BREP_RADIUS']
        
    crvId = rs.GetObject("Select the line", filter=4, preselect=True)
    if not crvId:return
    
    srfId = rs.GetObject("Select the surface", filter=8)
    if not srfId: return
    
    rad = rs.GetReal("Radius", rad)
    if not rad: return
    sc.sticky['CYL_BREP_RADIUS'] = rad

    crv= sc.doc.Objects.Find(crvId).Geometry
    length = crv.GetLength()
    plane = Rhino.Geometry.Plane(crv.PointAtStart, crv.PointAtEnd- crv.PointAtStart)
    circle = Rhino.Geometry.Circle(plane, rad)
    line = Rhino.Geometry.Line(crv.PointAtStart, crv.PointAtEnd)
    
    brep = sc.doc.Objects.Find(srfId).Geometry.Faces[0].DuplicateFace(False)
    
    cyl = Rhino.Geometry.Cylinder(circle, length)
    
    bb = Rhino.Geometry.BoundingBox()
    bb.Union(brep.GetBoundingBox(False))
    bb.Union(cyl.ToBrep(False, False).GetBoundingBox(False))
    line.ExtendThroughBox(bb)
    
    plane.Origin= line.From
    circle = Rhino.Geometry.Circle(plane, rad)
    cyl = Rhino.Geometry.Cylinder(circle, line.Length)
    
    x = Rhino.Geometry.Intersect.Intersection.BrepSurface(brep, cyl.ToNurbsSurface(), .001)
    if x[0]:
        ids = [sc.doc.Objects.AddCurve(item)for item in x[1]]
        if ids: rs.SelectObjects(ids)
            
    sc.doc.Views.Redraw

test()

-Pascal

1 Like