PlanarSrf using Rhinocommon

rhino
curve
rhinocommon
bug

(Ibrahim Mahmoud) #1

I’m trying to do the equivalent of PlanarSrf using RhinoCommon, and I’ve come across an issue.

So far I’m using Brep.CreatePatch() to do it, and it works - EXCEPT if the closed curve in question self intersects (like an inward loop).

The Patch result looks fine in Wireframe, but when I go to any other view I get a weird polygon of some sort that doesn’t fit the border I see in the Wireframe view.

If I extract the border from this failed Patch, and use PlanarSrf, the desired result appears.

How can I duplicate that result using Rhinocommon?


(Menno Deij - van Rijswijk) #2

What happens in Rhino is that the curve is processed using Boolean operations. You can mimic that using the following code

protected Result RunCommand(RhinoDoc doc, RunMode mode)
{
    ObjRef cRef;
    Result res = RhinoGet.GetOneObject("crv", false, ObjectType.Curve, out cRef);
    if (res != Result.Success)
        return res;

    Curve crv = cRef.Curve();
    if (!crv.IsClosed)
    {
        RhinoApp.WriteLine("Curve is not closed");
        return Result.Success;
    }

    var x = Intersection.CurveSelf(crv, doc.ModelAbsoluteTolerance);
    if (x == null || x.Count == 0)
    {
        Brep[] noIntersect = Brep.CreatePlanarBreps(crv);
        foreach (var p in noIntersect)
            doc.Objects.AddBrep(p);
        return Result.Success;
    }
    // the self-intersection parameters are stored in ParameterA and ParameterB
    // this is where to split the curve.
    Curve[] split = crv.Split(new[] {x[0].ParameterA, x[0].ParameterB});

    // the split will probably not be exactly on the curve start or end, so 
    // look for one closed curve and join the rest.
    if (split.Length != 2)
    {
        Curve closed = split.FirstOrDefault(t => t.IsClosed);
        if (null == closed)
        {
            RhinoApp.WriteLine("No closed curve found after split at self-intersection.");
            return Result.Success;
        }
        Curve[] other = Curve.JoinCurves(split.Except(new[] {closed}));
        if (null == other || other.Length != 1 || !other[0].IsClosed)
        {
            RhinoApp.WriteLine("Unable to join other parts into one closed curve.");
            return Result.Success;
        }
        split[0] = closed;
        split[1] = other[0];
    }

    Brep[] planar = Brep.CreatePlanarBreps(new[] {split[0], split[1]});
    if (null != planar)
    {
        foreach (Brep p in planar)
            doc.Objects.Add(p);
    }
            
    return Result.Success;
}