Example #1
0
        public static ComponentProblem Add(ref ComponentProblems problems, BrepEdge edge, BrepTrim trim, string problem, ComponentProblemTypes type, object data = null)
        {
            var componentReal = new ComponentIndex(ComponentIndexType.BrepEdge, edge.EdgeIndex);
            var componentGUI  = new ComponentIndex(ComponentIndexType.BrepEdge, trim.TrimIndex);

            return(Add(ref problems, componentReal, componentGUI, problem, type, data));
        }
Example #2
0
        public static IEnumerable <DB.BRepBuilderEdgeGeometry> ToHost(BrepEdge edge)
        {
            var edgeCurve = edge.EdgeCurve.Trim(edge.Domain);

            if (edge.ProxyCurveIsReversed)
            {
                edgeCurve.Reverse();
            }

            switch (edgeCurve)
            {
            case LineCurve line:
                yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(line)));

                yield break;

            case ArcCurve arc:
                yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(arc)));

                yield break;

            case NurbsCurve nurbs:
                yield return(DB.BRepBuilderEdgeGeometry.Create(ToHost(nurbs)));

                yield break;

            default:
                Debug.Fail($"{edgeCurve} is not supported as a Solid Edge");
                yield break;
            }
        }
Example #3
0
        private Face ByBrepFace(BrepFace ghBrepFace)
        {
            Rhino.Geometry.Surface ghSurface = ghBrepFace.UnderlyingSurface();

            Face untrimmedFace = BySurface(ghSurface);

            BrepLoop     ghOuterLoop = ghBrepFace.OuterLoop;
            Wire         outerWire   = null;
            BrepLoopList ghLoops     = ghBrepFace.Loops;
            List <Wire>  innerWires  = new List <Wire>();

            foreach (BrepLoop ghLoop in ghLoops)
            {
                BrepTrimList ghTrims       = ghLoop.Trims;
                List <Edge>  trimmingEdges = new List <Edge>();
                foreach (BrepTrim ghTrim in ghTrims)
                {
                    BrepEdge ghEdge = ghTrim.Edge;
                    if (ghEdge == null)
                    {
                        continue;
                        //throw new Exception("An invalid Rhino edge is encountered.");
                    }

                    Topology topology = ByCurve(ghEdge.DuplicateCurve());

                    // Edge or Wire?
                    Edge trimmingEdge = topology as Edge;
                    if (trimmingEdge != null)
                    {
                        trimmingEdges.Add(trimmingEdge);
                    }

                    Wire partialTrimmingWire = topology as Wire;
                    if (partialTrimmingWire != null)
                    {
                        List <Edge> partialTrimmingEdges = partialTrimmingWire.Edges;
                        trimmingEdges.AddRange(partialTrimmingEdges);
                    }
                }
                Wire          trimmingWire     = Wire.ByEdges(trimmingEdges);
                List <Vertex> trimmingVertices = trimmingWire.Vertices;

                if (ghLoop == ghOuterLoop)
                {
                    outerWire = trimmingWire;
                }
                else
                {
                    innerWires.Add(trimmingWire);
                }
            }

            Face outerTrimmedFace = Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true);
            Face finalFace        = outerTrimmedFace.AddInternalBoundaries(innerWires);

            return(finalFace);
        }
Example #4
0
        public static BrepVertex _GetEndVertex(this BrepEdge edge)
        {
            return(edge.EndVertex);

            var trim  = edge._FindTrim();
            var point = trim.Face.PointAt(trim.PointAtEnd.X, trim.PointAtEnd.Y);

            return(trim.Brep.Vertices[point._GetVertexIndex(trim.Brep.Vertices, 1, true)]);
        }
Example #5
0
        public static Edge ToTopologic(this BrepEdge brepEdge)
        {
            if (brepEdge == null)
            {
                return(null);
            }

            global::Rhino.Geometry.NurbsCurve nurbsCurve = brepEdge.ToNurbsCurve();
            return(ToTopologic(nurbsCurve));
        }
 // check the location of edges, maxdistance to rd == 0 -> on that class road
 public static bool offsetValue(List <Line> a, BrepEdge edge)
 {
     foreach (Line rd in a)
     {
         if (rd.DistanceTo(edge.PointAtStart, true) < inter_tol && rd.DistanceTo(edge.PointAtEnd, true) < inter_tol)
         {
             // on this road
             return(true);
         }
     }
     // none
     return(false);
 }
Example #7
0
        private Topologic.Topology ByCurve(Curve ghCurve)
        {
            LineCurve ghLine = ghCurve as LineCurve;

            if (ghLine != null)
            {
                return(ByLine(ghLine.Line));
            }

            Rhino.Geometry.NurbsCurve ghNurbsCurve = ghCurve as Rhino.Geometry.NurbsCurve;
            if (ghNurbsCurve != null)
            {
                return(ByNurbsCurve(ghNurbsCurve));
            }

            ArcCurve ghArcCurve = ghCurve as ArcCurve;

            if (ghArcCurve != null)
            {
                return(ByArcCurve(ghArcCurve));
            }

            BrepEdge ghBrepEdge = ghCurve as BrepEdge;

            if (ghBrepEdge != null)
            {
                return(ByBrepEdge(ghBrepEdge));
            }

            //BrepTrim ghBrepTrim = ghCurve as BrepTrim;
            //if (ghBrepTrim != null)
            //{
            //    return ByBrepTrim(ghBrepTrim);
            //}

            PolylineCurve ghPolylineCurve = ghCurve as PolylineCurve;

            if (ghPolylineCurve != null)
            {
                return(ByPolylineCurve(ghPolylineCurve));
            }

            PolyCurve ghPolyCurve = ghCurve as PolyCurve;

            if (ghPolyCurve != null)
            {
                return(ByPolyCurve(ghPolyCurve));
            }

            throw new Exception("This type of curve is not yet supported.");
        }
Example #8
0
        public static Topology ToTopologic(this Curve curve)
        {
            if (curve == null)
            {
                return(null);
            }

            LineCurve lineCurve = curve as LineCurve;

            if (lineCurve != null)
            {
                return(lineCurve.Line.ToTopologic());
            }

            Rhino.Geometry.NurbsCurve nurbsCurve = curve as Rhino.Geometry.NurbsCurve;
            if (nurbsCurve != null)
            {
                return(nurbsCurve.ToTopologic());
            }

            ArcCurve arcCurve = curve as ArcCurve;

            if (arcCurve != null)
            {
                return(arcCurve.ToTopologic());
            }

            BrepEdge brepEdge = curve as BrepEdge;

            if (brepEdge != null)
            {
                return(brepEdge.ToTopologic());
            }

            PolylineCurve ghPolylineCurve = curve as PolylineCurve;

            if (ghPolylineCurve != null)
            {
                return(ghPolylineCurve.ToTopologic());
            }

            PolyCurve ghPolyCurve = curve as PolyCurve;

            if (ghPolyCurve != null)
            {
                return(ghPolyCurve.ToTopologic());
            }

            return(null);
        }
Example #9
0
        /// <summary>
        /// Create frames that are aligned with a Brep. The input curve does not
        /// necessarily have to lie on the Brep.
        /// </summary>
        /// <param name="curve">Input centreline of the glulam.</param>
        /// <param name="brep">Brep to align the glulam orientation to.</param>
        /// <param name="num_samples">Number of orientation frames to use for alignment.</param>
        /// <returns>New Glulam oriented to the brep.</returns>
        public static Plane[] FramesNormalToSurface(Curve curve, Brep brep, int num_samples = 20)
        {
            num_samples = Math.Max(num_samples, 2);
            double[]       t = curve.DivideByCount(num_samples - 1, true);
            Plane[]        planes = new Plane[num_samples];
            Vector3d       xaxis, yaxis, zaxis;
            Point3d        pt;
            ComponentIndex ci;

            for (int i = 0; i < t.Length; ++i)
            {
                brep.ClosestPoint(curve.PointAt(t[i]), out pt, out ci, out double u, out double v, 0, out yaxis);

                // From: https://discourse.mcneel.com/t/brep-closestpoint-normal-is-not-normal/15147/8
                // If the closest point is found on an edge, average the face normals
                if (ci.ComponentIndexType == ComponentIndexType.BrepEdge)
                {
                    BrepEdge edge  = brep.Edges[ci.Index];
                    int[]    faces = edge.AdjacentFaces();
                    yaxis = Vector3d.Zero;
                    for (int j = 0; j < faces.Length; ++j)
                    {
                        BrepFace bf = edge.Brep.Faces[j];
                        if (bf.ClosestPoint(pt, out u, out v))
                        {
                            Vector3d faceNormal = bf.NormalAt(u, v);
                            yaxis += faceNormal;
                        }
                    }
                    yaxis.Unitize();
                }

                zaxis     = curve.TangentAt(t[i]);
                xaxis     = Vector3d.CrossProduct(zaxis, yaxis);
                planes[i] = new Plane(pt, xaxis, yaxis);
            }

            return(planes);
        }
Example #10
0
 private Topologic.Edge ByBrepEdge(BrepEdge ghBrepEdge)
 {
     Rhino.Geometry.NurbsCurve ghNurbsCurve = ghBrepEdge.ToNurbsCurve();
     return(ByNurbsCurve(ghNurbsCurve));
 }
Example #11
0
        //internal static Brep ToRawBrep(/*const*/ Brep brep, double scaleFactor)
        //{
        //    brep = brep.DuplicateShallow() as Brep;
        //    return EncodeRaw(ref brep, scaleFactor) ? brep : default;
        //}

        //internal static bool EncodeRaw(ref Brep brep, double scaleFactor)
        //{
        //    if (scaleFactor != 1.0 && !brep.Scale(scaleFactor))
        //        return default;

        //    var bbox = brep.GetBoundingBox(false);
        //    if (!bbox.IsValid || bbox.Diagonal.Length < Revit.ShortCurveTolerance)
        //        return default;

        //    return SplitFaces(ref brep);
        //}

        //static bool SplitFaces(ref Brep brep)
        //{
        //    Brep brepToSplit = null;
        //    while (!ReferenceEquals(brepToSplit, brep))
        //    {
        //        brepToSplit = brep;

        //        foreach (var face in brepToSplit.Faces)
        //        {
        //            var splitters = new List<Curve>();

        //            var trimsBBox = BoundingBox.Empty;
        //            foreach (var trim in face.OuterLoop.Trims)
        //                trimsBBox.Union(trim.GetBoundingBox(true));

        //            var domainUV = new Interval[]
        //            {
        //    new Interval(trimsBBox.Min.X, trimsBBox.Max.X),
        //    new Interval(trimsBBox.Min.Y, trimsBBox.Max.Y),
        //            };

        //            // Compute splitters
        //            var splittedUV = new bool[2] { false, false };
        //            for (int d = 0; d < 2; d++)
        //            {
        //                var domain = domainUV[d];
        //                var t = domain.Min;

        //                while (face.GetNextDiscontinuity(d, Continuity.Gsmooth_continuous, t, domain.Max, out t))
        //                {
        //                    splitters.AddRange(face.TrimAwareIsoCurve(1 - d, t));
        //                    splittedUV[d] = true;
        //                }
        //            }

        //            var closedUV = new bool[2] { face.IsClosed(0), face.IsClosed(1) };
        //            if (!splittedUV[0] && closedUV[0])
        //            {
        //                splitters.AddRange(face.TrimAwareIsoCurve(1, face.Domain(0).Mid));
        //                splittedUV[0] = true;
        //            }
        //            if (!splittedUV[1] && closedUV[1])
        //            {
        //                splitters.AddRange(face.TrimAwareIsoCurve(0, face.Domain(1).Mid));
        //                splittedUV[1] = true;
        //            }

        //            if (splitters.Count > 0)
        //            {
        //                var surfaceIndex = face.SurfaceIndex;
        //                var splitted = face.Split(splitters, Revit.ShortCurveTolerance);
        //                if (splitted is null)
        //                {
        //                    Debug.Fail("BrepFace.Split", "Failed to split a closed face.");
        //                    return false;
        //                }

        //                if (brepToSplit.Faces.Count == splitted.Faces.Count)
        //                {
        //                    // Split was ok but for tolerance reasons no new faces were created.
        //                    // Too near from the limits.
        //                }
        //                else
        //                {

        //                    foreach (var f in splitted.Faces)
        //                    {
        //                        if (f.SurfaceIndex != surfaceIndex)
        //                            continue;

        //                        if (splittedUV[0] && splittedUV[1])
        //                            f.ShrinkFace(BrepFace.ShrinkDisableSide.ShrinkAllSides);
        //                        else if (splittedUV[0])
        //                            f.ShrinkFace(BrepFace.ShrinkDisableSide.DoNotShrinkSouthSide | BrepFace.ShrinkDisableSide.DoNotShrinkNorthSide);
        //                        else if (splittedUV[1])
        //                            f.ShrinkFace(BrepFace.ShrinkDisableSide.DoNotShrinkEastSide | BrepFace.ShrinkDisableSide.DoNotShrinkWestSide);
        //                    }

        //                    // Start again until no face is splitted
        //                    brep = splitted;
        //                    break;
        //                }
        //            }
        //        }
        //    }

        //    return brep is object;
        //}
        #endregion

        #region Transfer
        /// <summary>
        /// Replaces <see cref="Raw.RawEncoder.ToHost(Brep)"/> to catch Revit Exceptions
        /// </summary>
        /// <param name="brep"></param>
        /// <returns></returns>
        public static NXOpen.Body ToSolid(/*const*/ Brep brep)
        {
            try
            {
                BodyStyle brepType;
                switch (brep.SolidOrientation)
                {
                case BrepSolidOrientation.Inward: brepType = BodyStyle.Sheet; break;

                case BrepSolidOrientation.Outward: brepType = BodyStyle.Solid; break;
                }

                List <NXOpen.Body> faceBodies = new List <NXOpen.Body>();
                foreach (var face in brep.Faces)
                {
                    using (var nurbSurface = face.ToNurbsSurface())
                    {
                        List <(List <NXOpen.Curve> edgeCurves, List <int> directions)> boundaryEdgeCurves = new List <(List <NXOpen.Curve>, List <int>)>();
                        for (int i = 0; i < face.Loops.Count; i++)
                        {
                            List <NXOpen.Curve> currentEdgeCurves = new List <NXOpen.Curve>();

                            List <int> currentDirections = new List <int>();

                            var trims = face.Loops[i].Trims;
                            for (int j = 0; j < trims.Count; j++)
                            {
                                if (trims[j].TrimType != BrepTrimType.Boundary && trims[j].TrimType != BrepTrimType.Mated)
                                {
                                    continue;
                                }

                                BrepEdge edge = trims[j].Edge;

                                if (edge is null)
                                {
                                    continue;
                                }

                                var currentEdgeCurve = edge.Trim(edge.Domain).ToCurve();

                                currentEdgeCurves.Add(currentEdgeCurve);
                                currentDirections.Add(edge.ProxyCurveIsReversed ? -1 : 1);
                            }

                            boundaryEdgeCurves.Add((currentEdgeCurves, currentDirections));
                        }

                        if (nurbSurface.IsPlanar())
                        {
                            // 使用有界平面创建
                            var boundaryCurves   = boundaryEdgeCurves.SelectMany(obj => obj.edgeCurves).ToArray();
                            var boundedPlaneBody = _theSession.Parts.Work.Features.CreateBoundedPlane(boundaryCurves).GetBodies()[0];
                            boundedPlaneBody.RemoveParameter();
                            faceBodies.Add(boundedPlaneBody);
                            //boundaryCurves.Delete();

                            //NXOpen.UF.StringList bplaneBoundaries = new NXOpen.UF.StringList()
                            //{
                            //    num = boundaryEdgeCurves.Count,
                            //    id = boundaryEdgeCurves.SelectMany(obj => obj.edgeCurveTags).ToArray(),
                            //    dir = boundaryEdgeCurves.SelectMany(obj => obj.directions).ToArray(),
                            //    _string = boundaryEdgeCurves.Select(obj => obj.edgeCurveTags.Count).ToArray()
                            //};

                            //double[] tolerrances = new double[bplaneBoundaries.dir.Length];
                            //for (int i = 0; i < tolerrances.Length; i++)
                            //    tolerrances[i] = DistanceTolerance;
                            //theUfSession.Modl.CreateBplane(ref bplaneBoundaries, tolerrances, out NXOpen.Tag body);

                            //bplaneBoundaries.id.Select(obj => obj.GetTaggedObject() as NXOpen.NXObject).ToArray().Delete();
                        }
                        else
                        {
                            var faceBody = RawEncoder.ToHost(nurbSurface);

                            #region 找到一个位于面上的点
                            Point3d point3dOnFace     = new Point3d();
                            bool    findInteriorPoint = false;
                            if (face.IsPointOnFace(face.Domain(0).Mid, face.Domain(1).Mid) == PointFaceRelation.Interior)
                            {
                                face.Evaluate(face.Domain(0).Mid, face.Domain(1).Mid, 0, out point3dOnFace, out _);
                                findInteriorPoint = true;
                            }
                            else
                            {
                                var firstEdge = face.Loops.ElementAt(0).Trims.ElementAt(0).Edge;

                                Point3d ptOnFirstEdge = firstEdge.PointAt(firstEdge.Domain.Mid);

                                face.ClosestPoint(ptOnFirstEdge, out double u, out double v);

                                double offsetValue = 0.02;

                                u += offsetValue;
                                v += offsetValue;
                                if (face.IsPointOnFace(u, v) == PointFaceRelation.Interior)
                                {
                                    face.Evaluate(u, v, 0, out point3dOnFace, out _);
                                    findInteriorPoint = true;
                                }
                                else
                                {
                                    u -= 2 * offsetValue;
                                    v -= 2 * offsetValue;
                                    if (face.IsPointOnFace(u, v) == PointFaceRelation.Interior)
                                    {
                                        face.Evaluate(u, v, 0, out point3dOnFace, out _);
                                        findInteriorPoint = true;
                                    }
                                }
                            }

                            if (!findInteriorPoint)
                            {
                                findInteriorPoint.ToString().ListingWindowWriteLine();
                                var copiedFaceBody = faceBody.CopyAndPaste()[0] as NXOpen.Body;
                                copiedFaceBody.SetColor(216);
                            }
                            #endregion

                            for (int i = 0; i < boundaryEdgeCurves.Count; i++)
                            {
                                NXOpen.UF.UFModl.TrimObject[] trimBoundaryObjects = new NXOpen.UF.UFModl.TrimObject[boundaryEdgeCurves[i].edgeCurves.Count];

                                for (int j = 0; j < trimBoundaryObjects.Length; j++)
                                {
                                    trimBoundaryObjects[j] = new NXOpen.UF.UFModl.TrimObject {
                                        object_tag = boundaryEdgeCurves[i].edgeCurves[j].Tag, curve_project_method = boundaryEdgeCurves[i].directions[j]
                                    };
                                }

                                _theUfSession.Modl.TrimSheet(faceBody.Tag, trimBoundaryObjects.Length, trimBoundaryObjects, null, 1, 1, point3dOnFace.ToXYZ().ToArray(), 0.01, out int numGapPoints, out double[] gapPoints);
                            }

                            faceBodies.Add(faceBody);
                        }
#if !DEBUG
                        boundaryEdgeCurves.SelectMany(obj => obj.edgeCurves).ToArray().Delete();
#endif
                    }
                }

                NXOpen.Body resultBody = null;
                if (faceBodies.Count > 1)
                {
                    var sewFeature = WorkPart.Features.CreateSew(faceBodies.ToArray());
                    resultBody = sewFeature.GetBodies()[0];
#if !DEBUG
                    resultBody.RemoveParameter();
#endif
                }
                else
                {
                    resultBody = faceBodies[0];
                }

                var brepArea = brep.GetArea();
                var bodyArea = resultBody.GetArea();
                resultBody.SetUserAttribute("Area", -1, bodyArea, NXOpen.Update.Option.Now);
                var error = Math.Abs(brepArea - bodyArea) / brepArea;
                resultBody.SetUserAttribute("Error", -1, error, NXOpen.Update.Option.Now);
                if (error > 0.001)
                {
                    resultBody.SetColor(186);
                }
            }
            catch (NXOpen.NXException e)
            {
                Logger.Error(e.ToString());
            }

            return(null);
        }
Example #12
0
    static void MakeTwistedCubeTrimmingLoop(ref Brep brep, ref BrepFace face, // Indices of corner vertices listed in SW, SE, NW, NE order
                                            int eSi,                          // index of edge on south side of surface
                                            int eS_dir,                       // orientation of edge with respect to surface trim
                                            int eEi,                          // index of edge on south side of surface
                                            int eE_dir,                       // orientation of edge with respect to surface trim
                                            int eNi,                          // index of edge on south side of surface
                                            int eN_dir,                       // orientation of edge with respect to surface trim
                                            int eWi,                          // index of edge on south side of surface
                                            int eW_dir                        // orientation of edge with respect to surface trim
                                            )
    {
        Surface srf  = brep.Surfaces[face.SurfaceIndex];
        var     loop = brep.Loops.Add(BrepLoopType.Outer, face);

        // Create trimming curves running counter clockwise around the surface's domain.
        // Start at the south side
        // side: 0=south, 1=east, 2=north, 3=west
        for (int side = 0; side < 4; side++)
        {
            Curve trimming_curve = TwistedCubeTrimmingCurve(srf, side);
            int   curve_index    = brep.Curves2D.Add(trimming_curve);

            int       ei      = 0;
            bool      reverse = false;
            IsoStatus iso     = IsoStatus.None;
            switch (side)
            {
            case 0: // south
                ei      = eSi;
                reverse = (eS_dir == -1);
                iso     = IsoStatus.South;
                break;

            case 1: // east
                ei      = eEi;
                reverse = (eE_dir == -1);
                iso     = IsoStatus.East;
                break;

            case 2: // north
                ei      = eNi;
                reverse = (eN_dir == -1);
                iso     = IsoStatus.North;
                break;

            case 3: // west
                ei      = eWi;
                reverse = (eW_dir == -1);
                iso     = IsoStatus.West;
                break;
            }

            BrepEdge edge = brep.Edges[ei];
            BrepTrim trim = brep.Trims.Add(edge, reverse, loop, curve_index);
            trim.IsoStatus = iso;
            trim.TrimType  = BrepTrimType.Mated; // This b-rep is closed, so all trims have mates.
            trim.SetTolerances(0, 0);            // This simple example is exact - for models with
            // non-exact data, set tolerance as explained in
            // definition of BrepTrim.
        }
    }
        public Brep BrepToSpeckle(Solid solid)
        {
#if REVIT2021
            // TODO: Incomplete implementation!!

            var brep = new Brep();
            brep.units = ModelUnits;

            if (solid is null || solid.Faces.IsEmpty)
            {
                return(null);
            }

            var faceIndex    = 0;
            var edgeIndex    = 0;
            var curve2dIndex = 0;
            var curve3dIndex = 0;
            var loopIndex    = 0;
            var trimIndex    = 0;
            var surfaceIndex = 0;

            var speckleFaces       = new Dictionary <Face, BrepFace>();
            var speckleEdges       = new Dictionary <Edge, BrepEdge>();
            var speckleEdgeIndexes = new Dictionary <Edge, int>();
            var speckle3dCurves    = new ICurve[solid.Edges.Size];
            var speckle2dCurves    = new List <ICurve>();
            var speckleLoops       = new List <BrepLoop>();
            var speckleTrims       = new List <BrepTrim>();

            foreach (var face in solid.Faces.Cast <Face>())
            {
                var surface     = FaceToSpeckle(face, out bool orientation, 0.0);
                var iterator    = face.EdgeLoops.ForwardIterator();
                var loopIndices = new List <int>();

                while (iterator.MoveNext())
                {
                    var loop            = iterator.Current as EdgeArray;
                    var loopTrimIndices = new List <int>();
                    // Loop through the edges in the loop.
                    var loopIterator = loop.ForwardIterator();
                    while (loopIterator.MoveNext())
                    {
                        // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge.
                        var edge  = loopIterator.Current as Edge;
                        var faceA = edge.GetFace(0);

                        // Determine what face side are we currently on.
                        var edgeSide = face == faceA ? 0 : 1;

                        // Get curve, create trim and save index
                        var trim       = edge.GetCurveUV(edgeSide);
                        var sTrim      = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1);
                        var sTrimIndex = trimIndex;
                        loopTrimIndices.Add(sTrimIndex);

                        // Add curve and trim, increase index counters.
                        speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane()));
                        speckleTrims.Add(sTrim);
                        curve2dIndex++;
                        trimIndex++;

                        // Check if we have visited this edge before.
                        if (!speckleEdges.ContainsKey(edge))
                        {
                            // First time we visit this edge, add 3d curve and create new BrepEdge.
                            var edgeCurve = edge.AsCurve();
                            speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve);
                            var sCurveIndex = curve3dIndex;
                            curve3dIndex++;

                            // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition.
                            var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null);
                            speckleEdges.Add(edge, sEdge);
                            speckleEdgeIndexes.Add(edge, edgeIndex);
                            edgeIndex++;
                        }
                        else
                        {
                            // Already visited this edge, skip curve 3d
                            var sEdge      = speckleEdges[edge];
                            var sEdgeIndex = speckleEdgeIndexes[edge];
                            sTrim.EdgeIndex = sEdgeIndex;

                            // Update trim indices with new item.
                            // TODO: Make this better.
                            var trimIndices = sEdge.TrimIndices.ToList();
                            trimIndices.Append(sTrimIndex);
                            sEdge.TrimIndices = trimIndices.ToArray();
                        }
                    }

                    var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer);
                    speckleLoops.Add(speckleLoop);
                    var sLoopIndex = loopIndex;
                    loopIndex++;
                    loopIndices.Add(sLoopIndex);
                }

                speckleFaces.Add(face,
                                 new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation));
                faceIndex++;
                brep.Surfaces.Add(surface);
                surfaceIndex++;
            }

            var mesh = new Mesh();
            (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> {
                solid
            });
            mesh.units = ModelUnits;
            // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit.
            // TODO: Set tolerances and flags in rhino when provenance is revit.
            brep.Faces        = speckleFaces.Values.ToList();
            brep.Curve2D      = speckle2dCurves;
            brep.Curve3D      = speckle3dCurves.ToList();
            brep.Trims        = speckleTrims;
            brep.Edges        = speckleEdges.Values.ToList();
            brep.Loops        = speckleLoops;
            brep.displayValue = mesh;
            return(brep);
#else
            throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021.");
#endif
        }
        public List <BRepBuilderEdgeGeometry> BrepEdgeToNative(BrepEdge edge)
        {
            // TODO: Trim curve with domain. Unsure if this is necessary as all our curves are converted to NURBS on Rhino output.

            var  nativeCurveArray = CurveToNative(edge.Curve);
            bool isTrimmed        = edge.Curve.domain != null && edge.Domain != null &&
                                    (edge.Curve.domain.start != edge.Domain.start ||
                                     edge.Curve.domain.end != edge.Domain.end);

            if (nativeCurveArray.Size == 1)
            {
                var nativeCurve = nativeCurveArray.get_Item(0);

                if (edge.ProxyCurveIsReversed)
                {
                    nativeCurve = nativeCurve.CreateReversed();
                }

                if (nativeCurve == null)
                {
                    return(new List <BRepBuilderEdgeGeometry>());
                }
                if (isTrimmed)
                {
                    nativeCurve.MakeBound(edge.Domain.start ?? 0, edge.Domain.end ?? 1);
                }
                if (!nativeCurve.IsBound)
                {
                    nativeCurve.MakeBound(0, nativeCurve.Period);
                }

                var endPoint   = nativeCurve.GetEndPoint(0);
                var source     = nativeCurve.GetEndPoint(1);
                var distanceTo = endPoint.DistanceTo(source);
                var closed     = distanceTo < 1E-6;
                if (closed)
                {
                    // Revit does not like single curve loop edges, so we split them in two.
                    var start = nativeCurve.GetEndParameter(0);
                    var end   = nativeCurve.GetEndParameter(1);
                    var mid   = (end - start) / 2;

                    var a = nativeCurve.Clone();
                    a.MakeBound(start, mid);

                    var b = nativeCurve.Clone();
                    b.MakeBound(mid, end);

                    var halfEdgeA = BRepBuilderEdgeGeometry.Create(a);
                    var halfEdgeB = BRepBuilderEdgeGeometry.Create(b);
                    return(new List <BRepBuilderEdgeGeometry> {
                        halfEdgeA, halfEdgeB
                    });
                }

                // TODO: Remove short segments if smaller than 'Revit.ShortCurveTolerance'.
                var fullEdge = BRepBuilderEdgeGeometry.Create(nativeCurve);
                return(new List <BRepBuilderEdgeGeometry> {
                    fullEdge
                });
            }

            var iterator = edge.ProxyCurveIsReversed
        ? nativeCurveArray.ReverseIterator()
        : nativeCurveArray.ForwardIterator();

            var result = new List <BRepBuilderEdgeGeometry>();

            while (iterator.MoveNext())
            {
                var crv = iterator.Current as DB.Curve;
                if (edge.ProxyCurveIsReversed)
                {
                    crv = crv.CreateReversed();
                }
                result.Add(BRepBuilderEdgeGeometry.Create(crv));
            }

            return(result);
        }
Example #15
0
 public static BrepTrim _FindTrim(this BrepEdge edge)
 {
     return(edge.Brep.Trims.First(o => o.Edge == edge));
 }
Example #16
0
        public static global::Topologic.Face ToTopologic(this BrepFace brepFace)
        {
            global::Rhino.Geometry.Surface ghSurface = brepFace?.UnderlyingSurface();
            if (ghSurface == null)
            {
                return(null);
            }

            global::Topologic.Face untrimmedFace = ghSurface.ToTopologic();

            BrepLoop     ghOuterLoop = brepFace.OuterLoop;
            Wire         outerWire   = null;
            BrepLoopList ghLoops     = brepFace.Loops;
            List <Wire>  innerWires  = new List <Wire>();

            foreach (BrepLoop ghLoop in ghLoops)
            {
                BrepTrimList ghTrims       = ghLoop.Trims;
                List <Edge>  trimmingEdges = new List <Edge>();
                foreach (BrepTrim ghTrim in ghTrims)
                {
                    BrepEdge ghEdge = ghTrim.Edge;
                    if (ghEdge == null)
                    {
                        continue;
                        //throw new Exception("An invalid Rhino edge is encountered.");
                    }

                    Topology topology = ghEdge.DuplicateCurve().ToTopologic();
                    if (topology == null)
                    {
                        continue;
                    }

                    // Edge or Wire?
                    Edge trimmingEdge = topology as Edge;
                    if (trimmingEdge != null)
                    {
                        trimmingEdges.Add(trimmingEdge);
                    }

                    Wire partialTrimmingWire = topology as Wire;
                    if (partialTrimmingWire != null)
                    {
                        IList <Edge> partialTrimmingEdges = partialTrimmingWire.Edges;
                        trimmingEdges.AddRange(partialTrimmingEdges);
                    }
                }

                Wire trimmingWire = Wire.ByEdges(trimmingEdges);
                if (ghLoop == ghOuterLoop)
                {
                    outerWire = trimmingWire;
                }
                else
                {
                    innerWires.Add(trimmingWire);
                }
            }

            global::Topologic.Face outerTrimmedFace = global::Topologic.Utilities.FaceUtility.TrimByWire(untrimmedFace, outerWire, true);
            global::Topologic.Face finalFace        = outerTrimmedFace.AddInternalBoundaries(innerWires);

            return(finalFace);
        }