Building Breps


#1

Dear community,

I am trying to build up geometries in Rhino. That means I try to create full patches with trimming information. I coded the following script, in the end all data seems to be correct but the Brep is still unvalid. When I check every entry it is valid. But in the end I am not able to create an entire patch with trimming information

Is there somebody who could maybe help me? Thanks!

I took the whole code with also the hashtables where I get the data from.

        var thisBrep = new Brep();

        var breps = RhinoVisualizerPlugIn.Instance.geometry["breps"];

        foreach (var brep in (IEnumerable)breps)
        {
            var facesArray = (brep as Hashtable)["faces"];

            foreach (var faceElement in (IEnumerable)facesArray)
            {
                var one_face = (Hashtable)faceElement;
                var surface = (Hashtable)one_face["surface"];
                var degrees = surface["degrees"];
                var degreeList = (from object u in (IEnumerable)degrees select Convert.ToInt32(u)).ToList();
                List<List<double>> knot_vectors = new List<List<double>>();
                foreach (var knot in (IEnumerable)surface["knot_vectors"])
                {
                    var knots = (from object u in (IEnumerable)knot select Convert.ToDouble(u)).ToList();
                    knot_vectors.Add(knots);
                }
                Dictionary<int, List<double>> control_points = new Dictionary<int, List<double>>();
                List<int> ids = new List<int>();
                foreach (var cp in (IEnumerable)surface["control_points"])
                {
                    var one_cp = cp as ArrayList;
                    int id = Convert.ToInt32(one_cp[0]);
                    var locations = (from object u in (IEnumerable)one_cp[1] select Convert.ToDouble(u)).ToList();
                    control_points.Add(id, locations);
                    ids.Add(id);
                }
                int degree_u = degreeList[0];
                int degree_v = degreeList[0];
                int control_points_u = knot_vectors[0].Count - degreeList[0] + 1;
                int control_points_v = knot_vectors[1].Count - degreeList[1] + 1;
                var nurbSurface = NurbsSurface.Create(3, true, degree_u + 1,
                    degree_v + 1, control_points_u, control_points_v);

                if (nurbSurface != null)
                {
                    for (int u = 0; u < nurbSurface.KnotsU.Count; u++)
                    {
                        nurbSurface.KnotsU[u] = knot_vectors[0][u];
                    }
                    for (int v = 0; v < nurbSurface.KnotsV.Count; v++)
                    {
                        nurbSurface.KnotsV[v] = knot_vectors[1][v];
                    }
                    for (int u = 0; u < nurbSurface.Points.CountU; u++)
                    {
                        for (int v = 0; v < nurbSurface.Points.CountV; v++)
                        {
                            var ControlPointID = u * nurbSurface.Points.CountV + v;//(knot_vectors[1].Count - degreeList[1] + 1) + v;
                            nurbSurface.Points.SetControlPoint(u, v,
                                new ControlPoint(control_points[ids[ControlPointID]][0], control_points[ids[ControlPointID]][1],
                                    control_points[ids[ControlPointID]][2], control_points[ids[ControlPointID]][3]));
                        }
                    }

                    int surfaceIndex = thisBrep.AddSurface(nurbSurface);
                    BrepFace face = thisBrep.Faces.Add(surfaceIndex);

                    foreach (var boundary_loop in (IEnumerable)one_face["boundary_loops"])
                    {
                        var one_boundary_loop = (Hashtable)boundary_loop;
                        if (Convert.ToString(one_boundary_loop["loop_type"]) == "inner")
                        {
                            BrepLoop rhinoLoop = thisBrep.Loops.Add(BrepLoopType.Inner, face);
                        }
                        else
                        {
                            BrepLoop rhinoLoop = thisBrep.Loops.Add(BrepLoopType.Outer, face);

                            foreach (var trimming_curve in (IEnumerable)one_boundary_loop["trimming_curves"])
                            {
                                var one_trimming_curve = (Hashtable)trimming_curve;
                                Hashtable one_parameter_curve = one_trimming_curve["parameter_curve"] as Hashtable;
                                int degree = Convert.ToInt32(one_parameter_curve["degree"]);

                                var parameter_knot_vector = (from object u in (IEnumerable)one_parameter_curve["knot_vector"] select Convert.ToDouble(u)).ToList();

                                List<List<double>> parameter_control_points = new List<List<double>>();
                                foreach (var cp in (IEnumerable)one_parameter_curve["control_points"])
                                {
                                    var one_cp = (from object u in (IEnumerable)cp select Convert.ToDouble(u)).ToList();
                                    parameter_control_points.Add(one_cp);
                                }

                                NurbsCurve nurbCurve = new NurbsCurve(2, true, degree + 1,
                                    parameter_control_points.Count);
                                for (int i = 0; i < nurbCurve.Knots.Count; i++)
                                {
                                    nurbCurve.Knots[i] = parameter_knot_vector[i];
                                }
                                for (int i = 0; i < parameter_control_points.Count; i++)
                                {
                                    nurbCurve.Points.SetPoint(i, parameter_control_points[i][0], parameter_control_points[i][1],
                                        parameter_control_points[i][2], parameter_control_points[i][3]);
                                }

                                int curve2DIndex = thisBrep.Curves2D.Add(nurbCurve);
                                Curve curve3D = nurbSurface.Pushup(thisBrep.Curves2D[curve2DIndex], 0.001);

                                int curve3DIndex = thisBrep.Curves3D.Add(curve3D);

                                BrepVertex firstVertex = thisBrep.Vertices.Add(curve3D.PointAtStart, 0.001);
                                BrepVertex lastVertex = thisBrep.Vertices.Add(curve3D.PointAtEnd, 0.001);


                                BrepEdge edge = thisBrep.Edges.Add(firstVertex, lastVertex, curve3DIndex, 0.001);
                                BrepTrim trim = thisBrep.Trims.Add(edge, false, rhinoLoop, curve2DIndex);

                                trim.TrimType = BrepTrimType.Boundary;
                                trim.SetTolerances(0.001, 0.001);
                                thisBrep.SetTrimIsoFlags();
                            }
                        }
                    }
                }
            }

        }
        doc.Objects.AddBrep(thisBrep);

(Menno Deij - van Rijswijk) #2

Without the actual geometry you’re trying to add (can you post it?), it’s difficult to see what’s wrong. The way to tackle this, I think, is to use this:

string err;
if (!thisBrep.IsValidWithLog(out err))
  RhinoApp.WriteLine("BREP not valid: "+err);
else
  doc.Objects.AddBrep(thisBrep);

The error will usually give detailed information why the BRep is not valid. Then you can try to fix the code.


#3

Hi,

thanks a lot for that hint. With it I was able to solve some of the problems.

But I cannot find out the following:
BREP not valid: ON_Brep.m_L[0] loop has trim vertex mismatch:
m_T[loop.m_ti[0]=0].m_vi[1] = 1 != m_T[loop.m_ti[1]=1].m_vi[0]=2.

Is there any repair function for the vertices?

Or does there exist a tutorial to read and display own defined breps?

Thanks!

Anyays I attached the geometry that I am trying to read in.

geometry.txt (5.2 KB)
.


#4

Alright I think I found the function:

thisBrep.SetVertices();

But after this function call all tolerances dissapear. The error then looks as follows:

BREP not valid: brep.m_V[0] vertex is not valid.
vertex.m_tolerace = -1.23432e+308 (should be >= 0.0)

Is this a bug in the SetVertices() call? The Vertices by themself are on the right position.

Thanks


(Dale Fugier) #5

Hi @Tobi,

Here are a couple of examples of building Breps from scratch:

https://github.com/mcneel/rhino-developer-samples/blob/6/rhinocommon/cs/SampleCsCommands/SampleCsFaceWithHole.cs
https://github.com/mcneel/rhino-developer-samples/blob/6/rhinocommon/cs/SampleCsCommands/SampleCsTrimmedPlane.cs

Also, if you get your Brep “almost” build, try calling Brep.Repair and see if Rhino is smart enough to fill in the rest of the missing information.

– Dale