Adding objects to the doc modifies them

Hi,

I’m writing a C# rhino plugin where I edit some geometries and then add them to the RhinoDoc by manually calling Rhino.RhinoDoc.ActiveDoc.Objects.Add, but then if I look at the added geometry in the doc I see that the number of faces, edges and vertices has changed.
Why is my geometry modified ? Is there a way to prevent this ?
If this is a quality check, how can I perform the same operations on my geometries beforehand to be iso ?

Also I’m not sure if this is related but when I try to call CreateFilletEdges on the added brep in the doc sometimes it fails to join the created fillets and the brep making 2 separate objects. Why is that and is there a way to know beforehand if this behaviour will happen (some kind of sanity check), so that I can avoid wasting time baking objects incompatible with filleting ?

Thanks for your answers :slight_smile:

Can you send the code we can run and models if applicable?

Hi Gijs,

Here is the Data that you can use :
FailingData.zip (957.2 KB)
BakeDifferentThanGeometry : contains the data to run the following test where baked data is different than the starting geometry
FailingFillets : contains a brep example where fillet operation fails for some reason.

Here is the code for my baking test :

public void RegressionTestForMcNeel()
{
    string file = [ADD_PATH_TO_FILE_HERE] + "\\BakeDifferentThanGeometry.3dm";
    Rhino.RhinoDoc.Open(file, out bool _);
    // load support curve and slices
    RhinoObject[] objs = Rhino.RhinoDoc.ActiveDoc.Objects.FindByLayer("support");
    NurbsCurve support = objs != null && objs.Length == 1 ? (NurbsCurve)objs[0].Geometry : null;
    objs = Rhino.RhinoDoc.ActiveDoc.Objects.FindByLayer("slices");
    var objList = objs.ToList();
    objList.Sort((a, b) => a.Name.CompareTo(b.Name));
    var slices = new List<NurbsCurve>();
    foreach(var obj in objList)
    {
        slices.Add(obj != null ? (NurbsCurve)obj.Geometry : null);
    }
    // then compute sweep
    Brep[] res = Brep.CreateFromSweep(support, slices, true, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance);
    Assert.That(res.Length != 0);
    var swept = res[0];
    // bake it to compare
    Guid addedId = Rhino.RhinoDoc.ActiveDoc.Objects.Add(swept);
    Brep baked = (Brep)Rhino.RhinoDoc.ActiveDoc.Objects.FindId(addedId).Geometry;
    Assert.That(AreBrepsIdentical(baked, swept, RhinoUtils.getTolerance()));
}

// utility functions for testing geometry equality

public static bool AreBrepsIdentical(Brep brep1, Brep brep2, double tolerance)
{
    if (brep1.Faces.Count != brep2.Faces.Count ||
        brep1.Edges.Count != brep2.Edges.Count ||
        brep1.Vertices.Count != brep2.Vertices.Count)
        return false;

    // Compare surfaces
    for (int i = 0; i < brep1.Faces.Count; i++)
    {
        Surface srf1 = brep1.Faces[i].UnderlyingSurface();
        Surface srf2 = brep2.Faces[i].UnderlyingSurface();
        if (!AreSurfacesIdentical(srf1, srf2, tolerance))
            return false;
    }

    // Compare edges
    for (int i = 0; i < brep1.Edges.Count; i++)
    {
        NurbsCurve curve1 = brep1.Edges[i].ToNurbsCurve();
        NurbsCurve curve2 = brep2.Edges[i].ToNurbsCurve();
        if (!AreCurvesIdentical(curve1, curve2, tolerance))
            return false;
    }

    return true;
}

public static bool AreSurfacesIdentical(Surface srf1, Surface srf2, double tolerance)
{
    if (srf1.Domain(0) != srf2.Domain(0) || srf1.Domain(1) != srf2.Domain(1))
        return false;

    for (double u = 0.0; u <= 1.0; u += 0.25)
    {
        for (double v = 0.0; v <= 1.0; v += 0.25)
        {
            Point3d p1 = srf1.PointAt(srf1.Domain(0).ParameterAt(u), srf1.Domain(1).ParameterAt(v));
            Point3d p2 = srf2.PointAt(srf2.Domain(0).ParameterAt(u), srf2.Domain(1).ParameterAt(v));

            if (!p1.EpsilonEquals(p2, tolerance))
                return false;
        }
    }

    return true;
}

public static bool AreCurvesIdentical(Curve curve1, Curve curve2, double tolerance)
{
    if (!curve1.Domain.Equals(curve2.Domain))
        return false;

    for (double t = 0.0; t <= 1.0; t += 0.2)
    {
        Point3d p1 = curve1.PointAt(curve1.Domain.ParameterAt(t));
        Point3d p2 = curve2.PointAt(curve2.Domain.ParameterAt(t));

        if (!p1.EpsilonEquals(p2, tolerance))
            return false;
    }

    return true;
}

Here if you need something more :slight_smile:
Thanks

my guess - without testing your code / example:

Adding Objects to the doc removes kinks for example.
you can youse the following overload:

public Guid AddBrep(
    Brep brep,
    ObjectAttributes attributes,
    HistoryRecord history,
    bool reference,
    bool splitKinkySurfaces
)

try

splitKinkySurfaces = false;

https://developer.rhino3d.com/api/rhinocommon/rhino.docobjects.tables.objecttable/addbrep#(brep,objectattributes,historyrecord,bool,bool)

see this topic

2 Likes

Works like a charm, thank you very much ^^

Now that I have no more baking problem I still have to find a way to know beforehand if my brep is valid for fillet operation success… I’ll create a separate post about his maybe