Exemplo n.º 1
0
    public static Rhino.Commands.Result AddTwistedCube(Rhino.RhinoDoc doc)
    {
        Point3d[] points = new Point3d[8];
        points[0] = new Point3d(0.0, 0.0, 0.0);   // point A = geometry for vertex 0
        points[1] = new Point3d(10.0, 0.0, 0.0);  // point B = geometry for vertex 1
        points[2] = new Point3d(10.0, 8.0, -1.0); // point C = geometry for vertex 2
        points[3] = new Point3d(0.0, 6.0, 0.0);   // point D = geometry for vertex 3
        points[4] = new Point3d(1.0, 2.0, 11.0);  // point E = geometry for vertex 4
        points[5] = new Point3d(10.0, 0.0, 12.0); // point F = geometry for vertex 5
        points[6] = new Point3d(10.0, 7.0, 13.0); // point G = geometry for vertex 6
        points[7] = new Point3d(0.0, 6.0, 12.0);  // point H = geometry for vertex 7

        Brep brep = new Brep();

        // Create eight vertices located at the eight points
        for (int vi = 0; vi < 8; vi++)
        {
            brep.Vertices.Add(points[vi], 0.0);
        }

        // Create 3d curve geometry - the orientations are arbitrarily chosen
        // so that the end vertices are in alphabetical order.
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[B])); // line AB
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[C])); // line BC
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[D])); // line CD
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[D])); // line AD
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[F])); // line EF
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[F], points[G])); // line FG
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[G], points[H])); // line GH
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[H])); // line EH
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[E])); // line AE
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[F])); // line BF
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[G])); // line CG
        brep.Curves3D.Add(TwistedCubeEdgeCurve(points[D], points[H])); // line DH

        // Create the 12 edges that connect the corners of the cube.
        MakeTwistedCubeEdges(ref brep);

        // Create 3d surface geometry - the orientations are arbitrarily chosen so
        // that some normals point into the cube and others point out of the cube.
        brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[C], points[D])); // ABCD
        brep.AddSurface(TwistedCubeSideSurface(points[B], points[C], points[G], points[F])); // BCGF
        brep.AddSurface(TwistedCubeSideSurface(points[C], points[D], points[H], points[G])); // CDHG
        brep.AddSurface(TwistedCubeSideSurface(points[A], points[D], points[H], points[E])); // ADHE
        brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[F], points[E])); // ABFE
        brep.AddSurface(TwistedCubeSideSurface(points[E], points[F], points[G], points[H])); // EFGH

        // Create the CRhinoBrepFaces
        MakeTwistedCubeFaces(ref brep);

        if (brep.IsValid)
        {
            doc.Objects.AddBrep(brep);
            doc.Views.Redraw();
            return(Rhino.Commands.Result.Success);
        }
        return(Rhino.Commands.Result.Failure);
    }
  public static Rhino.Commands.Result AddTwistedCube(Rhino.RhinoDoc doc)
  {
    Point3d[] points = new Point3d[8];
    points[0] = new Point3d(0.0, 0.0, 0.0);   // point A = geometry for vertex 0
    points[1] = new Point3d(10.0, 0.0, 0.0);  // point B = geometry for vertex 1
    points[2] = new Point3d(10.0, 8.0, -1.0); // point C = geometry for vertex 2
    points[3] = new Point3d(0.0, 6.0, 0.0);   // point D = geometry for vertex 3
    points[4] = new Point3d(1.0, 2.0, 11.0);  // point E = geometry for vertex 4
    points[5] = new Point3d(10.0, 0.0, 12.0); // point F = geometry for vertex 5
    points[6] = new Point3d(10.0, 7.0, 13.0); // point G = geometry for vertex 6
    points[7] = new Point3d(0.0, 6.0, 12.0);  // point H = geometry for vertex 7

    Brep brep = new Brep();

    // Create eight vertices located at the eight points
    for (int vi = 0; vi < 8; vi++)
      brep.Vertices.Add(points[vi], 0.0);

    // Create 3d curve geometry - the orientations are arbitrarily chosen
    // so that the end vertices are in alphabetical order.
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[B])); // line AB
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[C])); // line BC
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[D])); // line CD
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[D])); // line AD
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[F])); // line EF
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[F], points[G])); // line FG
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[G], points[H])); // line GH
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[H])); // line EH
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[E])); // line AE
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[F])); // line BF
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[G])); // line CG
    brep.Curves3D.Add(TwistedCubeEdgeCurve(points[D], points[H])); // line DH

    // Create the 12 edges that connect the corners of the cube.
    MakeTwistedCubeEdges(ref brep);

    // Create 3d surface geometry - the orientations are arbitrarily chosen so
    // that some normals point into the cube and others point out of the cube.
    brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[C], points[D])); // ABCD
    brep.AddSurface(TwistedCubeSideSurface(points[B], points[C], points[G], points[F])); // BCGF
    brep.AddSurface(TwistedCubeSideSurface(points[C], points[D], points[H], points[G])); // CDHG
    brep.AddSurface(TwistedCubeSideSurface(points[A], points[D], points[H], points[E])); // ADHE
    brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[F], points[E])); // ABFE
    brep.AddSurface(TwistedCubeSideSurface(points[E], points[F], points[G], points[H])); // EFGH

    // Create the CRhinoBrepFaces
    MakeTwistedCubeFaces(ref brep);

    if (brep.IsValid)
    {
      doc.Objects.AddBrep(brep);
      doc.Views.Redraw();
      return Rhino.Commands.Result.Success;
    }
    return Rhino.Commands.Result.Failure;
  }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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);
        }
        /// <summary>
        /// This example demonstrates how to construct a ON_Brep
        /// with the topology shown below.
        ///
        ///  E-------C--------D
        ///  |       /\       |
        ///  |      /  \      |
        ///  |     /    \     |
        ///  |    e2      e1  |
        ///  |   /        \   |
        ///  |  /          \  |
        ///  | /            \ |
        ///  A-----e0-------->B
        ///
        ///  Things need to be defined in a valid brep:
        ///   1- Vertices
        ///   2- 3D Curves (geometry)
        ///   3- Edges (topology - reference curve geometry)
        ///   4- Surface (geometry)
        ///   5- Faces (topology - reference surface geometry)
        ///   6- Loops (2D parameter space of faces)
        ///   4- Trims and 2D curves (2D parameter space of edges)
        /// </summary>
        /// <returns>A Brep if successful, null otherwise</returns>
        public static Brep MakeTrimmedPlane()
        {
            // Define the vertices
            var points = new Point3d[5];

            points[A] = new Point3d(0.0, 0.0, 0.0);   // point A = geometry for vertex 0 (and surface SW corner)
            points[B] = new Point3d(10.0, 0.0, 0.0);  // point B = geometry for vertex 1 (and surface SE corner)
            points[C] = new Point3d(5.0, 10.0, 0.0);  // point C = geometry for vertex 2
            points[D] = new Point3d(10.0, 10.0, 0.0); // point D (surface NE corner)
            points[E] = new Point3d(0.0, 10.0, 0.0);  // point E (surface NW corner)

            // Create the Brep
            var brep = new Brep();

            // Create three vertices located at the three points
            for (var vi = 0; vi < 3; vi++)
            {
                // This simple example is exact - for models with
                // non-exact data, set tolerance as explained in
                // definition of BrepVertex.
                brep.Vertices.Add(points[vi], 0.0);
            }

            // Create 3d curve geometry - the orientations are arbitrarily chosen
            // so that the end vertices are in alphabetical order.
            brep.Curves3D.Add(CreateLinearCurve(points[A], points[B])); // line AB
            brep.Curves3D.Add(CreateLinearCurve(points[B], points[C])); // line BC
            brep.Curves3D.Add(CreateLinearCurve(points[A], points[C])); // line CD

            // Create edge topology for each curve in the brep
            CreateEdges(brep);

            // Create 3d surface geometry - the orientations are arbitrarily chosen so
            // that some normals point into the cube and others point out of the cube.
            brep.AddSurface(CreatePlanarSurface(points[A], points[B], points[D], points[E])); // ABDE

            // Create face topology and 2d parameter space loops and trims
            CreateFaces(brep);

#if DEBUG
            string tlog;
            var    rc = brep.IsValidTopology(out tlog);
            if (!rc)
            {
                RhinoApp.WriteLine(tlog);
                return(null);
            }

            string glog;
            rc = brep.IsValidGeometry(out glog);
            if (!rc)
            {
                RhinoApp.WriteLine(glog);
                return(null);
            }
#endif

            // Validate the results
            if (!brep.IsValid)
            {
                RhinoApp.Write("Trimmed Brep face is not valid.");
                return(null);
            }

            return(brep);
        }
        /// <summary>
        /// This example demonstrates how to construct a ON_Brep
        /// with the topology shown below.
        ///
        ///  D---------e2-----C
        ///  |                |
        ///  |  G----e6---H   |
        ///  |  |         |   |
        ///  e3 e5        e7  |
        ///  |  |         |   |
        ///  |  F----e4---E   |
        ///  |                |
        ///  A-------e0-------B
        ///
        ///  Things need to be defined in a valid brep:
        ///   1- Vertices
        ///   2- 3D Curves (geometry)
        ///   3- Edges (topology - reference curve geometry)
        ///   4- Surface (geometry)
        ///   5- Faces (topology - reference surface geometry)
        ///   6- Loops (2D parameter space of faces)
        ///   4- Trims and 2D curves (2D parameter space of edges)
        /// </summary>
        /// <returns>A Brep if successful, null otherwise</returns>
        public static Brep MakeBrepFace()
        {
            // Define the vertices
            var points = new Point3d[8];

            points[A] = new Point3d(0.0, 0.0, 0.0);   // point A = geometry for vertex 0
            points[B] = new Point3d(10.0, 0.0, 0.0);  // point B = geometry for vertex 1
            points[C] = new Point3d(10.0, 10.0, 0.0); // point C = geometry for vertex 2
            points[D] = new Point3d(0.0, 10.0, 0.0);  // point D = geometry for vertex 3

            points[E] = new Point3d(8.0, 2.0, 0.0);   // point E = geometry for vertex 4
            points[F] = new Point3d(2.0, 2.0, 0.0);   // point F = geometry for vertex 5
            points[G] = new Point3d(2.0, 8.0, 0.0);   // point G = geometry for vertex 6
            points[H] = new Point3d(8.0, 8.0, 0.0);   // point H = geometry for vertex 7

            // Create the Brep
            var brep = new Brep();

            // Create four vertices of the outer edges
            for (var vi = 0; vi < 8; vi++)
            {
                // This simple example is exact - for models with
                // non-exact data, set tolerance as explained in
                // definition of BrepVertex.
                brep.Vertices.Add(points[vi], 0.0);
            }

            // Create 3d curve geometry of the outer boundary
            // The orientations are arbitrarily chosen
            // so that the end vertices are in alphabetical order.
            brep.Curves3D.Add(CreateLinearCurve(points[A], points[B])); // line AB
            brep.Curves3D.Add(CreateLinearCurve(points[B], points[C])); // line BC
            brep.Curves3D.Add(CreateLinearCurve(points[C], points[D])); // line CD
            brep.Curves3D.Add(CreateLinearCurve(points[A], points[D])); // line AD

            // Create 3d curve geometry of the hole
            brep.Curves3D.Add(CreateLinearCurve(points[E], points[F])); // line EF
            brep.Curves3D.Add(CreateLinearCurve(points[F], points[G])); // line GH
            brep.Curves3D.Add(CreateLinearCurve(points[G], points[H])); // line HI
            brep.Curves3D.Add(CreateLinearCurve(points[E], points[H])); // line EI

            // Create edge topology for each curve in the brep.
            CreateEdges(brep);

            // Create 3d surface geometry - the orientations are arbitrarily chosen so
            // that some normals point into the cube and others point out of the cube.
            brep.AddSurface(CreateNurbsSurface(points[A], points[B], points[C], points[D])); // ABCD

            // Create face topology and 2d parameter space loops and trims.
            CreateFace(brep, ABCD);

#if DEBUG
            string tlog;
            var    rc = brep.IsValidTopology(out tlog);
            if (!rc)
            {
                RhinoApp.WriteLine(tlog);
                return(null);
            }

            string glog;
            rc = brep.IsValidGeometry(out glog);
            if (!rc)
            {
                RhinoApp.WriteLine(glog);
                return(null);
            }
#endif

            // Validate the results
            if (!brep.IsValid)
            {
                RhinoApp.Write("Brep face is not valid.");
                return(null);
            }

            return(brep);
        }
        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);
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
0
        public override bool TryLoad(JObject data, Model model, RhinoDoc document)
        {
            if (!data.HasType("Brep"))
            {
                return(false);
            }

            var attributes = GetAttributes(document, data);

            var curves2d = new Dictionary <string, NurbsCurve>();
            var surfaces = new Dictionary <string, NurbsSurface>();

            foreach (var faceKey in data["faces"].AsList <string>())
            {
                var faceData = model[faceKey];

                var loops = new List <List <Curve> >();

                foreach (var loopKey in faceData["loops"].AsList <string>())
                {
                    var loop = new List <Curve>();

                    foreach (var trimKey in model[loopKey]["trims"].AsList <string>())
                    {
                        var curveKey = model[trimKey]["geometry"].As <string>();

                        if (!curves2d.TryGetValue(curveKey, out NurbsCurve curve))
                        {
                            curve = GetNurbsCurve2D(model[curveKey]);
                            curves2d.Add(curveKey, curve);
                        }

                        loop.Add(curve);
                    }

                    loops.Add(loop);
                }

                var surfaceKey = faceData["geometry"].As <string>();

                if (!surfaces.TryGetValue(surfaceKey, out NurbsSurface surface))
                {
                    surface = GetNurbsSurface3D(model[surfaceKey]);
                    surfaces.Add(surfaceKey, surface);
                }

                var planarSurface = new PlaneSurface(Plane.WorldXY, surface.Domain(0), surface.Domain(1));

                var planarBrep = new Brep();

                var planarSurfaceIndex = planarBrep.AddSurface(planarSurface);

                var face = planarBrep.Faces.Add(planarSurfaceIndex);

                planarBrep.Loops.AddPlanarFaceLoop(face.FaceIndex, BrepLoopType.Outer, loops[0]);

                for (int i = 1; i < loops.Count; i++)
                {
                    planarBrep.Loops.AddPlanarFaceLoop(0, BrepLoopType.Inner, loops[i]);
                }

                var brep = Brep.CopyTrimCurves(face, surface, document.ModelAbsoluteTolerance);

                brep.SetTrimIsoFlags();

                brep.Faces[0].RebuildEdges(document.ModelAbsoluteTolerance, true, true);

                if (faceData.ContainsKey("key"))
                {
                    attributes.Name = faceData["key"].As <string>();
                }

                document.Objects.Add(brep, attributes);
            }

            return(true);
        }
        /// <summary>
        /// This example demonstrates how to construct a Brep
        /// with the topology shown below.
        ///
        ///            H-------e6-------G
        ///           /                /|
        ///          / |              / |
        ///         /  e7            /  e5
        ///        /   |            /   |
        ///       /                e10  |
        ///      /     |          /     |
        ///     e11    E- - e4- -/- - - F
        ///    /                /      /
        ///   /      /         /      /
        ///  D---------e2-----C      e9
        ///  |     /          |     /
        ///  |    e8          |    /
        ///  e3  /            e1  /
        ///  |                |  /
        ///  | /              | /
        ///  |                |/
        ///  A-------e0-------B
        ///
        /// </summary>
        /// <returns>A Brep if successful, null otherwise</returns>
        public static Brep MakeTwistedCube()
        {
            // Define the vertices of the twisted cube
            var points = new Point3d[8];

            points[A] = new Point3d(0.0, 0.0, 0.0);   // point A = geometry for vertex 0
            points[B] = new Point3d(10.0, 0.0, 0.0);  // point B = geometry for vertex 1
            points[C] = new Point3d(10.0, 8.0, -1.0); // point C = geometry for vertex 2
            points[D] = new Point3d(0.0, 6.0, 0.0);   // point D = geometry for vertex 3
            points[E] = new Point3d(1.0, 2.0, 11.0);  // point E = geometry for vertex 4
            points[F] = new Point3d(10.0, 0.0, 12.0); // point F = geometry for vertex 5
            points[G] = new Point3d(10.0, 7.0, 13.0); // point G = geometry for vertex 6
            points[H] = new Point3d(0.0, 6.0, 12.0);  // point H = geometry for vertex 7

            // Create the Brep
            var brep = new Brep();

            // Create eight Brep vertices located at the eight points
            for (var vi = 0; vi < points.Length; vi++)
            {
                // This simple example is exact - for models with
                // non-exact data, set tolerance as explained in
                // definition of BrepVertex.
                brep.Vertices.Add(points[vi], 0.0);
            }

            // Create 3d curve geometry - the orientations are arbitrarily chosen
            // so that the end vertices are in alphabetical order.
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[B])); // line AB
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[C])); // line BC
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[D])); // line CD
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[D])); // line AD
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[F])); // line EF
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[F], points[G])); // line FG
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[G], points[H])); // line GH
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[H])); // line EH
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[E])); // line AE
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[F])); // line BF
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[G])); // line CG
            brep.Curves3D.Add(TwistedCubeEdgeCurve(points[D], points[H])); // line DH

            // Create the 12 edges that connect the corners of the cube
            MakeTwistedCubeEdges(brep);

            // Create 3d surface geometry - the orientations are arbitrarily chosen so
            // that some normals point into the cube and others point out of the cube.
            brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[C], points[D])); // ABCD
            brep.AddSurface(TwistedCubeSideSurface(points[B], points[C], points[G], points[F])); // BCGF
            brep.AddSurface(TwistedCubeSideSurface(points[C], points[D], points[H], points[G])); // CDHG
            brep.AddSurface(TwistedCubeSideSurface(points[A], points[D], points[H], points[E])); // ADHE
            brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[F], points[E])); // ABFE
            brep.AddSurface(TwistedCubeSideSurface(points[E], points[F], points[G], points[H])); // EFGH

            // Create the Brep faces
            MakeTwistedCubeFaces(brep);

#if DEBUG
            for (var fi = 0; fi < brep.Faces.Count; fi++)
            {
                TraverseBrepFace(brep, fi);
            }

            string tlog;
            var    rc = brep.IsValidTopology(out tlog);
            if (!rc)
            {
                RhinoApp.WriteLine(tlog);
                return(null);
            }

            string glog;
            rc = brep.IsValidGeometry(out glog);
            if (!rc)
            {
                RhinoApp.WriteLine(glog);
                return(null);
            }
#endif

            // Validate the results
            if (!brep.IsValid)
            {
                RhinoApp.Write("Twisted cube Brep is not valid.");
                return(null);
            }

            return(brep);
        }