Beispiel #1
0
        static int AddSurface(Brep brep, Surface surface, Curve[] loops, out List <BrepBoundary>[] shells)
        {
            // Extract base surface
            if (surface is object)
            {
                double trimTolerance = Revit.VertexTolerance * 0.1;
                int    si            = brep.AddSurface(surface);

                if (surface is PlaneSurface)
                {
                    var nurbs = surface.ToNurbsSurface();
                    nurbs.KnotsU.InsertKnot(surface.Domain(0).Mid);
                    nurbs.KnotsV.InsertKnot(surface.Domain(1).Mid);
                    surface = nurbs;
                }

                // Classify Loops
                var nesting   = new int[loops.Length];
                var edgeLoops = new BrepBoundary[loops.Length];
                {
                    var trims = new Curve[loops.Length];

                    int index = 0;
                    foreach (var loop in loops)
                    {
                        if (loop is PolyCurve polycurve)
                        {
                            var trim = new PolyCurve();
                            for (int s = 0; s < polycurve.SegmentCount; s++)
                            {
                                var segment     = polycurve.SegmentCurve(s);
                                var trimSegment = surface.Pullback(segment, trimTolerance);
                                trim.AppendSegment(trimSegment);
                            }

                            trims[index++] = trim;
                        }
                        else
                        {
                            trims[index++] = surface.Pullback(loop, trimTolerance);
                        }
                    }

                    for (int i = 0; i < edgeLoops.Length; ++i)
                    {
                        for (int j = i + 1; j < edgeLoops.Length; ++j)
                        {
                            var containment = Curve.PlanarClosedCurveRelationship(trims[i], trims[j], Plane.WorldXY, Revit.VertexTolerance * Revit.ModelUnits);
                            if (containment == RegionContainment.MutualIntersection)
                            {
                                edgeLoops[i].type = BrepLoopType.Outer;
                                edgeLoops[j].type = BrepLoopType.Outer;
                            }
                            else if (containment == RegionContainment.AInsideB)
                            {
                                nesting[i]++;
                            }
                            else if (containment == RegionContainment.BInsideA)
                            {
                                nesting[j]++;
                            }
                        }
                    }

                    // Fix orientation if necessary
                    index = 0;
                    foreach (var loop in loops)
                    {
                        // Ignore intersecting loops
                        if (edgeLoops[index].type == BrepLoopType.Unknown)
                        {
                            if (nesting[index] % 2 != 0)
                            {
                                edgeLoops[index].type = BrepLoopType.Inner;
                            }
                            else
                            {
                                edgeLoops[index].type = BrepLoopType.Outer;
                            }
                        }

                        switch (trims[index].ClosedCurveOrientation())
                        {
                        case CurveOrientation.Undefined:
                            break;

                        case CurveOrientation.CounterClockwise:
                            if (edgeLoops[index].type == BrepLoopType.Inner)
                            {
                                loops[index].Reverse();
                            }
                            break;

                        case CurveOrientation.Clockwise:
                            if (edgeLoops[index].type == BrepLoopType.Outer)
                            {
                                loops[index].Reverse();
                            }
                            break;
                        }

                        ++index;
                    }
                }

                // Create Brep Edges and compute trims
                {
                    int index = 0;
                    foreach (var edgeLoop in loops)
                    {
                        // Ignore unclasified loops
                        if (edgeLoops[index].type == BrepLoopType.Unknown)
                        {
                            continue;
                        }

                        var kinks = new List <double>();
                        {
                            var domain = edgeLoop.Domain;
                            var t      = domain.Min;
                            while (edgeLoop.GetNextDiscontinuity(Continuity.C1_locus_continuous, t, domain.Max, out t))
                            {
                                kinks.Add(t);
                            }
                        }

                        var edges = kinks.Count > 0 ? edgeLoop.Split(kinks) : new Curve[] { edgeLoop };

                        edgeLoops[index].edges       = new List <BrepEdge>();
                        edgeLoops[index].trims       = new PolyCurve();
                        edgeLoops[index].orientation = new List <int>();

                        foreach (var edge in edges)
                        {
                            var brepEdge = default(BrepEdge);
                            brepEdge = brep.Edges.Add(brep.AddEdgeCurve(edge));

                            edgeLoops[index].edges.Add(brepEdge);
                            var segment = edge;

                            edgeLoops[index].orientation.Add(segment.TangentAt(segment.Domain.Mid).IsParallelTo(brepEdge.TangentAt(brepEdge.Domain.Mid)));

                            var trim = surface.Pullback(segment, trimTolerance);
                            edgeLoops[index].trims.Append(trim);
                        }

                        edgeLoops[index].trims.MakeClosed(Revit.VertexTolerance);

                        ++index;
                    }
                }

                // Sort edgeLoops in nesting orther, shallow loops first
                Array.Sort(nesting, edgeLoops);

                var outerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Outer);
                var innerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Inner);

                // Group Edge loops in shells with the outer loop as the first one
                shells = outerLoops.
                         Select(x => new List <BrepBoundary>()
                {
                    x
                }).
                         ToArray();

                if (shells.Length == 1)
                {
                    shells[0].AddRange(innerLoops);
                }
                else
                {
                    // Iterate in reverse order to found deeper loops before others
                    foreach (var innerLoop in innerLoops.Reverse())
                    {
                        foreach (var shell in shells.Reverse())
                        {
                            var containment = Curve.PlanarClosedCurveRelationship(innerLoop.trims, shell[0].trims, Plane.WorldXY, Revit.VertexTolerance);
                            if (containment == RegionContainment.AInsideB)
                            {
                                shell.Add(innerLoop);
                                break;
                            }
                        }
                    }
                }

                return(si);
            }

            shells = default;
            return(-1);
        }
        static int AddSurface(Brep brep, DB.Face face, out List <BrepBoundary>[] shells, Dictionary <DB.Edge, BrepEdge> brepEdges = null)
        {
            // Extract base surface
            if (ToRhinoSurface(face, out var parametricOrientation) is Surface surface)
            {
                if (!parametricOrientation)
                {
                    surface.Transpose(true);
                }

                int si = brep.AddSurface(surface);

                if (surface is PlaneSurface planar)
                {
                    var nurbs = planar.ToNurbsSurface();
                    nurbs.KnotsU.InsertKnot(surface.Domain(0).Mid);
                    nurbs.KnotsV.InsertKnot(surface.Domain(1).Mid);
                    surface = nurbs;
                }
                else if (surface is SumSurface sum)
                {
                    surface = sum.ToNurbsSurface();
                }

                // Extract and classify Edge Loops
                var edgeLoops = new List <BrepBoundary>(face.EdgeLoops.Size);
                foreach (var edgeLoop in face.EdgeLoops.Cast <DB.EdgeArray>())
                {
                    if (edgeLoop.IsEmpty)
                    {
                        continue;
                    }

                    var edges = edgeLoop.Cast <DB.Edge>();
                    if (!face.MatchesSurfaceOrientation())
                    {
                        edges = edges.Reverse();
                    }

                    var loop = new BrepBoundary()
                    {
                        type        = BrepLoopType.Unknown,
                        orientation = new List <int>(edgeLoop.Size),
                        edges       = new List <BrepEdge>(edgeLoop.Size),
                        trims       = new PolyCurve()
                    };

                    var trims = new List <Curve>(edgeLoop.Size);
                    foreach (var edge in edges)
                    {
                        var brepEdge = default(BrepEdge);
                        if (brepEdges?.TryGetValue(edge, out brepEdge) != true)
                        {
                            var curve = edge.AsCurve();
                            if (curve is null)
                            {
                                continue;
                            }

                            brepEdge = brep.Edges.Add(brep.AddEdgeCurve(ToRhino(curve)));
                            brepEdges?.Add(edge, brepEdge);
                        }

                        var segment = ToRhino(edge.AsCurveFollowingFace(face));
                        if (!face.MatchesSurfaceOrientation())
                        {
                            segment.Reverse();
                        }

                        if (surface.Pullback(segment, 1e-5) is Curve trim)
                        {
                            trims.Add(trim);
                            loop.edges.Add(brepEdge);

                            loop.orientation.Add(segment.TangentAt(segment.Domain.Mid).IsParallelTo(brepEdge.TangentAt(brepEdge.Domain.Mid)));
                        }
                    }

                    // Add singular edges
                    for (int ti = 0, ei = 0; ti < trims.Count; ++ti, ++ei)
                    {
                        int tA = ti;
                        int tB = (ti + 1) % trims.Count;

                        loop.trims.AppendSegment(trims[tA]);

                        int eA = ei;
                        int eB = (ei + 1) % loop.edges.Count;

                        var start = loop.orientation[eA] > 0 ? (loop.edges[eA]).PointAtEnd   : (loop.edges[eA]).PointAtStart;
                        var end   = loop.orientation[eB] > 0 ? (loop.edges[eB]).PointAtStart : (loop.edges[eB]).PointAtEnd;

                        if (start.EpsilonEquals(end, Revit.VertexTolerance))
                        {
                            var startTrim = new Point2d(trims[tA].PointAtEnd);
                            var endTrim   = new Point2d(trims[tB].PointAtStart);
                            var midTrim   = (endTrim + startTrim) * 0.5;

                            if (surface.IsAtSingularity(midTrim.X, midTrim.Y, false))
                            {
                                loop.orientation.Insert(eA + 1, 0);
                                loop.edges.Insert(eA + 1, default);
                                loop.trims.AppendSegment(new LineCurve(startTrim, endTrim));

                                ei++;
                            }
                        }
                        else // Missing edge
                        {
                            Debug.WriteLine("Missing edge detected");
                        }
                    }

                    loop.trims.MakeClosed(Revit.VertexTolerance);

                    switch (loop.trims.ClosedCurveOrientation())
                    {
                    case CurveOrientation.Undefined: loop.type = BrepLoopType.Unknown; break;

                    case CurveOrientation.CounterClockwise: loop.type = BrepLoopType.Outer; break;

                    case CurveOrientation.Clockwise: loop.type = BrepLoopType.Inner; break;
                    }

                    edgeLoops.Add(loop);
                }

                var outerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Outer);
                var innerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Inner);

                // Group Edge loops in shells with the outer loop as the first one
                shells = outerLoops.
                         Select(x => new List <BrepBoundary>()
                {
                    x
                }).
                         ToArray();

                if (shells.Length == 1)
                {
                    shells[0].AddRange(innerLoops);
                }
                else
                {
                    foreach (var edgeLoop in innerLoops)
                    {
                        foreach (var shell in shells)
                        {
                            var containment = Curve.PlanarClosedCurveRelationship(edgeLoop.trims, shell[0].trims, Plane.WorldXY, Revit.VertexTolerance);
                            if (containment == RegionContainment.AInsideB)
                            {
                                shell.Add(edgeLoop);
                                break;
                            }
                        }
                    }
                }

                return(si);
            }

            shells = default;
            return(-1);
        }
Beispiel #3
0
        static int AddSurface(Brep brep, DB.Face face, out List <BrepBoundary>[] shells, Dictionary <DB.Edge, BrepEdge> brepEdges = null)
        {
            // Extract base surface
            if (ToRhinoSurface(face, out var parametricOrientation) is Surface surface)
            {
                if (!parametricOrientation)
                {
                    surface.Transpose(true);
                }

                int si = brep.AddSurface(surface);

                if (surface is PlaneSurface planar)
                {
                    var nurbs = planar.ToNurbsSurface();
                    nurbs.KnotsU.InsertKnot(surface.Domain(0).Mid);
                    nurbs.KnotsV.InsertKnot(surface.Domain(1).Mid);
                    surface = nurbs;
                }
                else if (surface is SumSurface sum)
                {
                    surface = sum.ToNurbsSurface();
                }

                // Extract and classify Edge Loops
                var edgeLoops = new List <BrepBoundary>(face.EdgeLoops.Size);
                foreach (var edgeLoop in face.EdgeLoops.Cast <DB.EdgeArray>())
                {
                    if (edgeLoop.IsEmpty)
                    {
                        continue;
                    }

                    var edges = edgeLoop.Cast <DB.Edge>();
                    if (!face.MatchesSurfaceOrientation())
                    {
                        edges = edges.Reverse();
                    }

                    var loop = new BrepBoundary()
                    {
                        type        = BrepLoopType.Unknown,
                        edges       = new List <BrepEdge>(edgeLoop.Size),
                        trims       = new PolyCurve(),
                        orientation = new List <int>(edgeLoop.Size)
                    };

                    foreach (var edge in edges)
                    {
                        var brepEdge = default(BrepEdge);
                        if (brepEdges?.TryGetValue(edge, out brepEdge) != true)
                        {
                            var curve = edge.AsCurve();
                            if (curve is null)
                            {
                                continue;
                            }

                            brepEdge = brep.Edges.Add(brep.AddEdgeCurve(ToRhino(curve)));
                            brepEdges?.Add(edge, brepEdge);
                        }

                        loop.edges.Add(brepEdge);
                        var segment = ToRhino(edge.AsCurveFollowingFace(face));

                        if (!face.MatchesSurfaceOrientation())
                        {
                            segment.Reverse();
                        }

                        loop.orientation.Add(segment.TangentAt(segment.Domain.Mid).IsParallelTo(brepEdge.TangentAt(brepEdge.Domain.Mid)));

                        var trim = surface.Pullback(segment, Revit.VertexTolerance);
                        loop.trims.Append(trim);
                    }

                    loop.trims.MakeClosed(Revit.VertexTolerance);

                    switch (loop.trims.ClosedCurveOrientation())
                    {
                    case CurveOrientation.Undefined: loop.type = BrepLoopType.Unknown; break;

                    case CurveOrientation.CounterClockwise: loop.type = BrepLoopType.Outer; break;

                    case CurveOrientation.Clockwise: loop.type = BrepLoopType.Inner; break;
                    }

                    edgeLoops.Add(loop);
                }

                var outerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Outer);
                var innerLoops = edgeLoops.Where(x => x.type == BrepLoopType.Inner);

                // Group Edge loops in shells with the outer loop as the first one
                shells = outerLoops.
                         Select(x => new List <BrepBoundary>()
                {
                    x
                }).
                         ToArray();

                if (shells.Length == 1)
                {
                    shells[0].AddRange(innerLoops);
                }
                else
                {
                    foreach (var edgeLoop in innerLoops)
                    {
                        foreach (var shell in shells)
                        {
                            var containment = Curve.PlanarClosedCurveRelationship(edgeLoop.trims, shell[0].trims, Plane.WorldXY, Revit.VertexTolerance);
                            if (containment == RegionContainment.AInsideB)
                            {
                                shell.Add(edgeLoop);
                                break;
                            }
                        }
                    }
                }

                return(si);
            }

            shells = default;
            return(-1);
        }
Beispiel #4
0
        private static void AddNXFace(NXOpen.Face face, Brep brep)
        {
            Surface surface = face.ToRhinoSurface();

            if (surface == null)
            {
                return;
            }

            int surfIndex = brep.AddSurface(surface);

            BrepFace brepFace = brep.Faces.Add(surfIndex);

            // Console.WriteLine("***************************************************");

            try
            {
                var loopList = face.GetLoops().ToList();

                if (loopList.Count == 0)
                {
                    return;
                }

                if (loopList[0].Type != NXOpen.Extensions.Topology.LoopType.Outer && loopList[0].Type != NXOpen.Extensions.Topology.LoopType.LikelyOuter)
                {
                    var outerLoop = loopList.FirstOrDefault(obj => obj.Type == NXOpen.Extensions.Topology.LoopType.Outer || obj.Type == NXOpen.Extensions.Topology.LoopType.LikelyOuter);

                    if (outerLoop != null)
                    {
                        loopList.Remove(outerLoop);

                        loopList.Insert(0, outerLoop);
                    }
                }

                var faceSense = face.GetSense();

                // Console.WriteLine("Face Sense:" + faceSense);

                var outerLoopSense = loopList[0].FirstFin.Sense;

                // Console.WriteLine("Outer loop:" + outerLoopSense);

                for (int i = 0; i < loopList.Count; i++)
                {
                    // Console.WriteLine("********Loop*******");

                    var currentNxLoop = loopList[i];

                    if (currentNxLoop.Fins.Length == 0)
                    {
                        continue;
                    }

                    BrepLoopType brepLoopType;
                    switch (currentNxLoop.Type)
                    {
                    case NXOpen.Extensions.Topology.LoopType.LikelyOuter:
                    case NXOpen.Extensions.Topology.LoopType.Outer:
                        brepLoopType = BrepLoopType.Outer;
                        break;

                    case NXOpen.Extensions.Topology.LoopType.LikelyInner:
                    case NXOpen.Extensions.Topology.LoopType.Inner:
                    case NXOpen.Extensions.Topology.LoopType.InnerSingular:
                        brepLoopType = BrepLoopType.Inner;
                        break;

                    case NXOpen.Extensions.Topology.LoopType.Winding:
                        if (i == 0)
                        {
                            brepLoopType = BrepLoopType.Outer;
                        }
                        else
                        {
                            brepLoopType = BrepLoopType.Inner;
                        }
                        break;

                    case NXOpen.Extensions.Topology.LoopType.Unknown:
                    default:
                        brepLoopType = BrepLoopType.Unknown;
                        break;
                    }

                    var brepLoop = brep.Loops.Add(brepLoopType, brepFace);

                    var currentFin = currentNxLoop.FirstFin;

                    var trims = new PolyCurve();

                    Dictionary <BrepEdge, int> brepEdges = new Dictionary <BrepEdge, int>();

                    int finCount = 0;

                    do
                    {
                        finCount++;

                        var curve3d = currentFin.Edge.ToRhinoCurve();

                        if (currentFin.StartVertex != null && curve3d.PointAtStart.DistanceTo(currentFin.StartVertex.Position.ToRhino()) > Globals.DistanceTolerance)
                        {
                            curve3d.Reverse();
                        }

                        var brepEdgeCurve = brep.AddEdgeCurve(curve3d);

                        var brepEdge = brep.Edges.Add(brepEdgeCurve);

                        //Console.WriteLine("Start of Fin" + currentFin.StartVertex.Position);
                        //Console.WriteLine("Start of Edge" + curve3d.PointAtStart);
                        //Console.WriteLine("End of Fin" + currentFin.EndVertex.Position);
                        //Console.WriteLine("End of Edge" + curve3d.PointAtEnd);

                        brepEdges.Add(brepEdge, curve3d.TangentAt(curve3d.Domain.Mid).IsParallelTo(brepEdge.TangentAt(brepEdge.Domain.Mid)));

                        var curve2d = surface.Pullback(curve3d, Globals.DistanceTolerance);

                        trims.Append(curve2d);

                        currentFin = currentFin.Next;
                    } while (currentFin != currentNxLoop.FirstFin);

                    trims.MakeClosed(Globals.DistanceTolerance);

                    for (int j = 0; j < brepEdges.Count; j++)
                    {
                        if (trims.SegmentCurve(j) is Curve)
                        {
                            var curve = trims.SegmentCurve(j) as Curve;
                            var ti    = brep.AddTrimCurve(curve);

                            if (brepEdges.ElementAt(j).Value == 0)
                            {
                                continue;
                            }

                            var brepTrim = brep.Trims.Add(brepEdges.ElementAt(j).Key, brepEdges.ElementAt(j).Value < 0, brepLoop, ti);

                            brepTrim.TrimType = BrepTrimType.Boundary;
                        }
                    }

                    // brepLoop.Trims.MatchEnds();

                    // brep.Trims.MatchEnds(brepLoop.Trims[0], brepLoop.Trims.Last());

                    // brep.Repair(Globals.DistanceTolerance);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("无法添加 NX 面:" + ex);
            }

            brep.Trims.MatchEnds();

            brep.Repair(Globals.DistanceTolerance);
        }