Offset with an Angled (Elevated) Object

Using RhinoScript (Python).

I have a polyline in Rhino where the starting point is at Z=0 and the end point is at Z=20. If I offset manually to the inside in Rhino and use the InCPlane=No then it looks great:

If I offset manually to the inside in Rhino and use the InCPlane=Yes then it is not clean at all:

If I run rs.OffsetCurve to programmatically offset the curve it comes out just like the “non-clean” version. How to I get rs.OffsetCurve to give me the other version? There is no “InCPlane” option. I imagine the Offset command in Rhino with the InCPlane=No option does not use the current CPlane so maybe it uses the object’s CPlane. Am I right? Maybe I need to pass the normal to rs.OffsetCurve, but there’s not a CPlane for the object when I select it with rs.GetObject.

Any help would be appreciated.

Offset Issue.3dm (30.2 KB) (260 Bytes)

Hi @Mike24,

the rs.OffsetCurve method has an optional input normal which you could use to feed in the normal of the curve’s plane. To get this plane, you would do this:

plane = rs.CurvePlane(crv_id, -1)
normal = plane.ZAxis

However, i would recommend to use some RhinoCommon where you can offset in a plane without having to declare a point for the offset direction. The direction is relative to the curve’s plane, so i entered 10 as the distance. To offset on the other side, you would use a negative number:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def TestOffset():
    crv_id = rs.GetObject("", rs.filter.curve)
    if not crv_id: return
    curve = rs.coercecurve(crv_id, -1, True)
    tolerance = scriptcontext.doc.ModelAbsoluteTolerance
    is_planar, plane = curve.TryGetPlane(tolerance)
    if not is_planar: return
    style = Rhino.Geometry.CurveOffsetCornerStyle.Sharp
    rc = curve.Offset(plane, 10, tolerance, style)
    if not rc: return
    for crv in rc: scriptcontext.doc.Objects.AddCurve(crv)


Just a side observation: a planar object offset outside of its own plane becomes non-planar so, strictly, this is a clean representation of that non planar object.

(Provided you have selected Corner=Sharp: if you select Corner=None then I wouldn’t expect the corner ends to be joined but they are. I think this is wrong, @pascal, albeit trivial.)

Hi Jeremy - this guy should not be here, correct?


Hi Pascal,

I don’t think so, when Corner=None.


@clement - Thanks. The whole thing was exactly that…the curve’s normal was not passed regardless if the corner was set to None or Sharp.