예제 #1
0
 private static int CompareDinosByLength2(IndexPair x, IndexPair y)
 {
     if(Pmin(x) > Pmin(y))return 1;
     if (Pmin(x) < Pmin(y)) return -1;
     if(Pmin(x) == Pmin(y)){
       if(Pmax(x) > Pmax(y))return 1;
       if (Pmax(x) < Pmax(y)) return -1;
       return 0;
     }
     else return 0;
 }
예제 #2
0
        public static void GrowHull(ref Mesh Msh, Point3d Pt)
        {
            double Tol       = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 0.1;//RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
            double AngleTest = (Math.PI * 0.5) - ((0.1 / 360) * (Math.PI * 2.0));

            MeshPoint CP = Msh.ClosestMeshPoint(Pt, 0);

            if (CP.Point.DistanceTo(Pt) < Tol)
            {
                int[] EdgeIndices = Msh.TopologyEdges.GetEdgesForFace(CP.FaceIndex);
                Msh.Faces.RemoveAt(CP.FaceIndex);
                Msh.Vertices.Add(Pt);
                List <MeshFace> AddFaces = new List <MeshFace>();

                for (int EdgeIdx = 0; EdgeIdx < EdgeIndices.Length; EdgeIdx++)
                {
                    Rhino.IndexPair VertexPair = Msh.TopologyEdges.GetTopologyVertices(EdgeIndices[EdgeIdx]);
                    AddFaces.Add(new MeshFace(Msh.TopologyVertices.MeshVertexIndices(VertexPair.I)[0], Msh.TopologyVertices.MeshVertexIndices(VertexPair.J)[0], Msh.Vertices.Count - 1));
                }
                Msh.Faces.AddFaces(AddFaces);
                return;
            }
            else if (Msh.IsPointInside(Pt, Tol, true))
            {
                return;
            }
            else
            {
                Msh.FaceNormals.ComputeFaceNormals();
                List <int> DeleteFaces = new List <int>();
                for (int FaceIdx = 0; FaceIdx < Msh.Faces.Count; FaceIdx++)
                {
                    Vector3d VecTest   = new Vector3d(Msh.Faces.GetFaceCenter(FaceIdx) - Pt);
                    Plane    PlaneTest = new Plane(Msh.Faces.GetFaceCenter(FaceIdx), Msh.FaceNormals[FaceIdx]);
                    if (Vector3d.VectorAngle(PlaneTest.ZAxis, VecTest) > AngleTest || Math.Abs(PlaneTest.DistanceTo(Pt)) < Tol)
                    {
                        DeleteFaces.Add(FaceIdx);
                    }
                }
                Msh.Faces.DeleteFaces(DeleteFaces);
                Msh.Vertices.Add(Pt);
                List <MeshFace> AddFaces = new List <MeshFace>();
                for (int EdgeIdx = 0; EdgeIdx < Msh.TopologyEdges.Count; EdgeIdx++)
                {
                    if (!Msh.TopologyEdges.IsSwappableEdge(EdgeIdx))
                    {
                        IndexPair VertexPair = Msh.TopologyEdges.GetTopologyVertices(EdgeIdx);
                        AddFaces.Add(new MeshFace(Msh.TopologyVertices.MeshVertexIndices(VertexPair.I)[0], Msh.TopologyVertices.MeshVertexIndices(VertexPair.J)[0], Msh.Vertices.Count - 1));
                    }
                }
                Msh.Faces.AddFaces(AddFaces);
                return;
            }
        }
예제 #3
0
        /// <summary>
        /// Instace constructor based on a list of curves (i.e. a lattice).
        /// </summary>
        public ExoMesh(List<Curve> struts)
        {
            m_hulls = new List<ExoHull>();
            m_sleeves = new List<ExoSleeve>();
            m_plates = new List<ExoPlate>();
            m_mesh = new Mesh();

            double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

            // First, we convert the struts to a list of unique nodes and node pairs
            // We use the following lists to extract valid data from the input list
            var nodeList = new Point3dList();               // List of unique nodes
            var nodePairList = new List<IndexPair>();       // List of struts, as node index pairs
            struts = FrameTools.CleanNetwork(struts, tol, out nodeList, out nodePairList);

            // Set hull locations
            foreach (Point3d node in nodeList)
            {
                m_hulls.Add(new ExoHull(node));
            }
               

            // Create sleeves, plates and relational indices
            for (int i = 0; i < struts.Count; i++)
            {
                m_sleeves.Add(new ExoSleeve(struts[i], nodePairList[i]));
                // Construct plates
                m_plates.Add(new ExoPlate(nodePairList[i].I, struts[i].TangentAtStart));
                m_plates.Add(new ExoPlate(nodePairList[i].J, -struts[i].TangentAtEnd));
                // Set sleeve relational parameters
                IndexPair platePair = new IndexPair(m_plates.Count - 2, m_plates.Count - 1);
                m_sleeves[i].PlatePair = platePair;
                // Set hull relational parameters
                m_hulls[nodePairList[i].I].SleeveIndices.Add(i);
                m_hulls[nodePairList[i].J].SleeveIndices.Add(i);
                m_hulls[nodePairList[i].I].PlateIndices.Add(platePair.I);
                m_hulls[nodePairList[i].J].PlateIndices.Add(platePair.J);
            }
        }
예제 #4
0
        /// <summary>
        /// Formats the line input into the UnitCell object. It converts the list of lines into
        /// a list of unique nodes and unique node pairs, ignoring duplicates.
        /// </summary>
        private void ExtractTopology(List<Line> lines)
        {
            double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

            CellTools.FixIntersections(ref lines);

            // Iterate through list of lines
            foreach (Line line in lines)
            {
                // Get line, and it's endpoints
                Point3d[] pts = new Point3d[] { line.From, line.To };
                List<int> nodeIndices = new List<int>();
                
                // Loop over end points, being sure to not create the same node twice
                foreach (Point3d pt in pts)
                {
                    int closestIndex = this.Nodes.ClosestIndex(pt);  // find closest node to current pt
                    // If node already exists
                    if (this.Nodes.Count != 0 && this.Nodes[closestIndex].EpsilonEquals(pt, tol))
                    {
                        nodeIndices.Add(closestIndex);
                    }
                    // If it doesn't exist, add it
                    else
                    {
                        this.Nodes.Add(pt);
                        nodeIndices.Add(this.Nodes.Count - 1);
                    }
                }

                IndexPair nodePair = new IndexPair(nodeIndices[0], nodeIndices[1]);
                // If not duplicate strut, save it
                if (this.NodePairs.Count == 0 || !NodePairs.Contains(nodePair))
                {
                    this.NodePairs.Add(nodePair);
                }
                
            }
        }
예제 #5
0
 static int Pmin(IndexPair pair)
 {
     if(pair.I > pair.J)return pair.J;
     else return pair.I;
 }
예제 #6
0
        /// 2Nurbs 
        /// 
        public string Mesh2Topo(ref Mesh mesh, out Mesh mesh2, int edge, out IndexPair data)
        {
            Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges;
            Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices;
            string str = "";
            List<int> firstLoop1;
            str += FirstEdge(mesh, out firstLoop1);
            double column = (double)vs.Count / (double)firstLoop1.Count;
            int Column = (int)column;
            if (column - Column != 0) str += "Points Count error,Please confirm the topo to be quad style";
            int[] energy = new int[vs.Count];
            List<int> indexPt = new List<int>();
            indexPt.AddRange(firstLoop1);
            for (int i = 0; i < firstLoop1.Count; i++) { energy[firstLoop1[i]] = 1; }
            for (int i = 0; i < Column - 1; i++)
            {
                bool sign = true;
                for (int j = 0; j < firstLoop1.Count; j++)
                {
                    int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]);
                    for (int k = 0; k < index.Length; k++)
                    {
                        energy[index[k]]++;
                    }
                }
                for (int j = 0; j < firstLoop1.Count; j++)
                {
                    int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]);
                    for (int k = 0; k < index.Length; k++)
                    {
                        if (energy[index[k]] == 1)
                        {
                            firstLoop1[j] = index[k]; sign = false; break;
                        }
                    }
                }
                if (sign) { str += " Loop false,Not quad topo Or To the end"; }
                else { indexPt.AddRange(firstLoop1); }
            }
            ///
            ///*******
            double MX = (double)Column - 1;
            double MY = (double)firstLoop1.Count - 1;
            List<Point3d> output1 = new List<Point3d>();
            List<Point3d> output2 = new List<Point3d>();
            int iCount = 0;
            Color[] cl = new Color[mesh.Vertices.Count];
            //edge
            List<int> pl1 = new List<int>();
            List<int> pl2 = new List<int>();
            List<int> pl3 = new List<int>();
            List<int> pl4 = new List<int>();
            int edge1 = 0, edge2 = 0, edge3 = 0, edge4 = 0;
            //////////
            for (int i = 0; i < Column; i++)
            {
                for (int j = 0; j < firstLoop1.Count; j++)
                {
                    if (i == 0) pl1.Add(iCount);
                    if (i == column - 1) pl3.Add(iCount);
                    if (j == 0) pl2.Add(iCount);
                    if (j == firstLoop1.Count - 1) pl4.Add(iCount);
                    if (i == 0 && j == 0) edge1 = iCount;
                    if (i == 0 && j == firstLoop1.Count - 1) edge2 = iCount;
                    if (i == column - 1 && j == firstLoop1.Count - 1) edge3 = iCount;
                    if (i == column - 1 && j == 0) edge4 = iCount;
                    output1.Add(vs[indexPt[iCount]]);
                    int indexV = vs.MeshVertexIndices(indexPt[iCount])[0];
                    cl[iCount] = mesh.VertexColors[indexV];
                    iCount++;
                    Point3d pt = new Point3d(edge * i, edge * j, 0);
                    output2.Add(pt);
                }
            }
            mesh2 = mc.MeshFromPoints(output2, firstLoop1.Count, Column);
            mesh = mc.MeshFromPoints(output1, firstLoop1.Count, Column);
            mesh.VertexColors.Clear();
            mesh.VertexColors.AppendColors(cl);
            mesh2.VertexColors.Clear();
            mesh2.VertexColors.AppendColors(cl);
            ///edge
            List<Point3d> pts;

            /////////////////////////////////////////////////////////
            Color[] cl1 = new Color[pl1.Count * 2]; pts = new List<Point3d>();
            for (int i = 0; i < pl1.Count; i++)
            {
                pts.Add(new Point3d(mesh2.Vertices[pl1[i]]));
                pts.Add((Point3d)mesh2.Vertices[pl1[i]] + new Vector3d(-edge, 0, 0));
                cl1[i * 2] = mesh2.VertexColors[pl1[i]]; cl1[i * 2 + 1] = mesh2.VertexColors[pl1[i]];
            }
            Mesh mesh3 = mc.MeshFromPoints(pts, 2, pl1.Count);
            mesh3.VertexColors.AppendColors(cl1);
            mesh2.Append(mesh3);
            /////////////////////////////////////////////////////////
            Color[] cl2 = new Color[pl2.Count * 2]; pts = new List<Point3d>();
            for (int i = 0; i < pl2.Count; i++)
            {
                pts.Add(new Point3d(mesh2.Vertices[pl2[i]]));
                pts.Add((Point3d)mesh2.Vertices[pl2[i]] + new Vector3d(0, -edge, 0));
                cl2[i * 2] = mesh2.VertexColors[pl2[i]]; cl2[i * 2 + 1] = mesh2.VertexColors[pl2[i]];
            }
            mesh3 = mc.MeshFromPoints(pts, 2, pl2.Count);
            mesh3.VertexColors.AppendColors(cl2);
            mesh2.Append(mesh3);
            /////////////////////////////////////////////////////////
            Color[] cl3 = new Color[pl3.Count * 2]; pts = new List<Point3d>();
            for (int i = 0; i < pl3.Count; i++)
            {
                pts.Add(new Point3d(mesh2.Vertices[pl3[i]]));
                pts.Add((Point3d)mesh2.Vertices[pl3[i]] + new Vector3d(edge, 0, 0));
                cl3[i * 2] = mesh2.VertexColors[pl3[i]]; cl3[i * 2 + 1] = mesh2.VertexColors[pl3[i]];
            }
            mesh3 = mc.MeshFromPoints(pts, 2, pl3.Count);
            mesh3.VertexColors.AppendColors(cl3);
            mesh2.Append(mesh3);
            /////////////////////////////////////////////////////////
            Color[] cl4 = new Color[pl4.Count * 2]; pts = new List<Point3d>();
            for (int i = 0; i < pl4.Count; i++)
            {
                pts.Add(new Point3d(mesh2.Vertices[pl4[i]]));
                pts.Add((Point3d)mesh2.Vertices[pl4[i]] + new Vector3d(0, edge, 0));
                cl4[i * 2] = mesh2.VertexColors[pl4[i]]; cl4[i * 2 + 1] = mesh2.VertexColors[pl4[i]];
            }
            mesh3 = mc.MeshFromPoints(pts, 2, pl4.Count);
            mesh3.VertexColors.AppendColors(cl4);
            mesh2.Append(mesh3);
            /////////////////////////////////////////////////////////

            Point3d ept = (Point3d)mesh2.Vertices[edge1];
            mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(-edge, 0, 0), ept + new Vector3d(-edge, -edge, 0), ept + new Vector3d(0, -edge, 0));
            mesh3.VertexColors.Add(mesh2.VertexColors[edge1]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge1]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge1]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge1]);
            mesh2.Append(mesh3);
            ept = (Point3d)mesh2.Vertices[edge2];
            mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(-edge, 0, 0), ept + new Vector3d(-edge, edge, 0), ept + new Vector3d(0, edge, 0));
            mesh3.VertexColors.Add(mesh2.VertexColors[edge2]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge2]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge2]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge2]);
            mesh2.Append(mesh3);
            ept = (Point3d)mesh2.Vertices[edge3];
            mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(edge, 0, 0), ept + new Vector3d(edge, edge, 0), ept + new Vector3d(0, edge, 0));
            mesh3.VertexColors.Add(mesh2.VertexColors[edge3]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge3]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge3]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge3]);
            mesh2.Append(mesh3);
            ept = (Point3d)mesh2.Vertices[edge4];
            mesh3 = mc.MeshFromPoints(ept, ept + new Vector3d(edge, 0, 0), ept + new Vector3d(edge, -edge, 0), ept + new Vector3d(0, -edge, 0));
            mesh3.VertexColors.Add(mesh2.VertexColors[edge4]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge4]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge4]);
            mesh3.VertexColors.Add(mesh2.VertexColors[edge4]);
            mesh2.Append(mesh3);

            //////////////////////////////////////////////////////
            for (double i = 1; i <= Column; i++)
            {
                for (double j = 1; j <= firstLoop1.Count; j++)
                {
                    mesh.TextureCoordinates.Add(i / (Column + 1), j / (firstLoop1.Count + 1));
                }
            }
            data = new IndexPair((Column + 1) * edge, (firstLoop1.Count + 1) * edge);
            return str;
        }
예제 #7
0
        /// <summary>
        /// Removes duplicate/invalid/tiny curves and outputs the cleaned list, a list of unique nodes and a list of node pairs.
        /// </summary>
        public static List<Curve> CleanNetwork(List<Curve> inputStruts, double tol, out Point3dList nodes, out List<IndexPair> nodePairs)
        {
            nodes = new Point3dList();
            nodePairs = new List<IndexPair>();

            var struts = new List<Curve>();

            // Loop over list of struts
            for (int i = 0; i < inputStruts.Count; i++)
            {
                Curve strut = inputStruts[i];
                // Unitize domain
                strut.Domain = new Interval(0, 1);
                // Minimum strut length (if user defined very small tolerance, use 100*rhinotolerance)
                double minLength = Math.Max(tol, 100*RhinoDoc.ActiveDoc.ModelAbsoluteTolerance);
                // If strut is invalid, ignore it
                if (strut == null || !strut.IsValid || strut.IsShort(minLength))
                {
                    continue;
                }

                Point3d[] pts = new Point3d[2] { strut.PointAtStart, strut.PointAtEnd };
                List<int> nodeIndices = new List<int>();
                // Loop over end points of strut
                // Check if node is already in nodes list, if so, we find its index instead of creating a new node
                for (int j = 0; j < 2; j++)
                {
                    Point3d pt = pts[j];
                    // Find closest node to current pt
                    int closestIndex = nodes.ClosestIndex(pt); 

                    // If node already exists (within tolerance), set the index
                    if (nodes.Count != 0 && pt.EpsilonEquals(nodes[closestIndex], tol))
                    {
                        nodeIndices.Add(closestIndex);
                    }
                    // If node doesn't exist
                    else
                    {
                        // Update lookup list
                        nodes.Add(pt);
                        nodeIndices.Add(nodes.Count - 1);
                    }
                }

                // We must ignore duplicate struts
                bool isDuplicate = false;
                IndexPair nodePair = new IndexPair(nodeIndices[0], nodeIndices[1]);

                int dupIndex = nodePairs.IndexOf(nodePair);
                // dupIndex equals -1 if nodePair not found, i.e. if it doesn't equal -1, a match was found
                if (nodePairs.Count != 0 && dupIndex != -1)
                {
                    // Check the curve midpoint to make sure it's a duplicate
                    Curve testStrut = struts[dupIndex];
                    Point3d ptA = strut.PointAt(0.5);
                    Point3d ptB = testStrut.PointAt(0.5);
                    if (ptA.EpsilonEquals(ptB, tol)) isDuplicate = true;
                }

                // So we only create the strut if it doesn't exist yet (check nodePairLookup list)
                if (!isDuplicate)
                {
                    // Update the lookup list
                    nodePairs.Add(nodePair);
                    strut.Domain = new Interval(0, 1);
                    struts.Add(strut);
                }
            }

            return struts;
        }
예제 #8
0
 private static int CompareDinosByLength(IndexPair x, IndexPair y)
 {
     if (x.J > y.J) return 1;
     if (x.J == y.J) return 0;
     if (x.J < y.J) return -1;
     else return 0;
 }
예제 #9
0
 /// <summary>
 /// Instance constuctor based on the underlying curve and hull pair for this sleeve.
 /// </summary>
 public ExoSleeve(Curve curve, IndexPair hullPair)
 {
     m_curve = curve;
     m_hullPair = hullPair;
     m_platePair = new IndexPair();
     m_startRadius = 0.0;
     m_endRadius = 0.0;
 }
예제 #10
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 public ExoSleeve()
 {
     m_curve = null;
     m_hullPair = new IndexPair();
     m_platePair = new IndexPair();
     m_startRadius = 0.0;
     m_endRadius = 0.0;
 }
예제 #11
0
        public static DataTree <Polyline> ReciprocalFrame(this Mesh mesh, double angle = 10, double dist = 0.25, double width = 0.1)
        {
            DataTree <Polyline> polylines = new DataTree <Polyline>();


            try {
                var    display   = new List <Line>();
                double thickness = width;

                int[][]       tv    = mesh.GetNGonsTopoBoundaries();
                HashSet <int> tvAll = mesh.GetAllNGonsTopoVertices();
                HashSet <int> e     = mesh.GetAllNGonEdges(tv);

                Line[] lines  = mesh.GetAllNGonEdgesLines(e);
                Line[] lines1 = mesh.GetAllNGonEdgesLines(e);

                bool[] nakedV = mesh.GetNakedEdgePointStatus();


                int[][] fe = mesh.GetNGonFacesEdges(tv);

                Plane[] planes = new Plane[lines.Length];

                Vector3d[] vecs = new Vector3d[mesh.TopologyEdges.Count];

                int j = 0;
                foreach (int i in e)
                {
                    Line            l   = mesh.TopologyEdges.EdgeLine(i);
                    Rhino.IndexPair ip  = mesh.TopologyEdges.GetTopologyVertices(i);
                    int             v0  = mesh.TopologyVertices.MeshVertexIndices(ip.I)[0];
                    int             v1  = mesh.TopologyVertices.MeshVertexIndices(ip.J)[0];
                    Vector3d        vec = new Vector3d(
                        (mesh.Normals[v0].X + mesh.Normals[v1].X) * 0.5,
                        (mesh.Normals[v0].Y + mesh.Normals[v1].Y) * 0.5,
                        (mesh.Normals[v0].Z + mesh.Normals[v1].Z) * 0.5
                        );
                    vec.Unitize();
                    vecs[j] = vec;


                    if (mesh.TopologyEdges.GetConnectedFaces(i).Length == 2)
                    {
                        l.Transform(Transform.Rotation(Rhino.RhinoMath.ToRadians(angle), vec, l.PointAt(0.5)));
                    }



                    Vector3d cross = Vector3d.CrossProduct(l.Direction, vec);
                    planes[j] = new Plane(l.PointAt(0.5), cross);
                    cross.Unitize();
                    l.Transform(Transform.Translation(cross * thickness));

                    lines[j] = l;
                    l.Transform(Transform.Translation(-cross * 2 * thickness));
                    lines1[j++] = l;
                }

                //ngon vertex edges
                int[][] connectedE = mesh.GetConnectedNGonEdgesToNGonTopologyVertices(tvAll, e);
                int[]   allEArray  = e.ToArray();
                int[]   allvArray  = tvAll.ToArray();

                Line[] linesCopy   = new Line[lines.Length];
                Line[] linesCopy1  = new Line[lines.Length];
                Line[] linesCopyM  = new Line[lines.Length];
                Line[] linesCopyM1 = new Line[lines.Length];
                // Line[] linesCopyMoved = new Line[lines.Length];

                for (int i = 0; i < lines.Length; i++)
                {
                    linesCopy[i]   = new Line(lines[i].From, lines[i].To);
                    linesCopy1[i]  = new Line(lines1[i].From, lines1[i].To);
                    linesCopyM[i]  = new Line(lines[i].From + vecs[i] * dist, lines[i].To + vecs[i] * dist);
                    linesCopyM1[i] = new Line(lines1[i].From + vecs[i] * dist, lines1[i].To + vecs[i] * dist);
                }

                for (int i = 0; i < connectedE.Length; i++)
                {
                    //Defines planes
                    int     total            = connectedE[i].Length;
                    Plane[] projectionPlanes = new Plane[total];

                    int start = total - 1;
                    for (j = start; j < start + total; j++)
                    {
                        int currentEdge = connectedE[i][j % total];
                        int localID     = Array.IndexOf(allEArray, currentEdge);
                        projectionPlanes[j - start] = planes[localID];
                    }


                    //Intersect lines

                    for (j = 0; j < connectedE[i].Length; j++)
                    {
                        int currentEdge = connectedE[i][j];
                        if (mesh.TopologyEdges.GetConnectedFaces(currentEdge).Length == 1)
                        {
                            continue;
                        }

                        int       localID       = Array.IndexOf(allEArray, currentEdge);
                        Line      currentLine   = linesCopy[localID];
                        Line      currentLine1  = linesCopy1[localID];
                        Line      currentLineM  = linesCopyM[localID];
                        Line      currentLineM1 = linesCopyM1[localID];
                        IndexPair pair          = mesh.TopologyEdges.GetTopologyVertices(currentEdge);

                        double lineT, lineT1;
                        Plane  currentPlane = new Plane(projectionPlanes[j]);



                        double flag = 1;

                        //Check length
                        Plane tempPlane = new Plane(currentPlane);
                        Line  temp2     = new Line(currentLine.From, currentLine.To);
                        tempPlane.Origin += tempPlane.ZAxis * (thickness);
                        Line   temp = new Line(currentLine.From, currentLine.To);
                        double tt;
                        Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt);
                        if (allvArray[i] == pair.I)
                        {
                            temp.From = temp2.PointAt(tt);
                        }
                        else
                        {
                            temp.To = temp2.PointAt(tt);
                        }

                        double lineLen0 = temp.Length;

                        tempPlane         = new Plane(currentPlane);
                        temp2             = new Line(currentLine.From, currentLine.To);
                        tempPlane.Origin += tempPlane.ZAxis * (-thickness);
                        temp              = new Line(currentLine.From, currentLine.To);
                        Rhino.Geometry.Intersect.Intersection.LinePlane(temp2, tempPlane, out tt);
                        if (allvArray[i] == pair.I)
                        {
                            temp.From = temp2.PointAt(tt);
                        }
                        else
                        {
                            temp.To = temp2.PointAt(tt);
                        }

                        double lineLen1 = temp.Length;
                        //End Check Length

                        if (lineLen1 < lineLen0)
                        {
                            flag = -1;
                        }



                        currentPlane.Origin += currentPlane.ZAxis * (flag * thickness);

                        Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine, currentPlane, out lineT);
                        Rhino.Geometry.Intersect.Intersection.LinePlane(currentLine1, currentPlane, out lineT1);
                        Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM, currentPlane, out lineT);
                        Rhino.Geometry.Intersect.Intersection.LinePlane(currentLineM1, currentPlane, out lineT1);


                        if (allvArray[i] == pair.I)
                        {
                            currentLine.From   = currentLine.PointAt(lineT);
                            currentLine1.From  = currentLine1.PointAt(lineT1);
                            currentLineM.From  = currentLineM.PointAt(lineT);
                            currentLineM1.From = currentLineM1.PointAt(lineT1);
                        }
                        else
                        {
                            currentLine.To   = currentLine.PointAt(lineT);
                            currentLine1.To  = currentLine1.PointAt(lineT1);
                            currentLineM.To  = currentLineM.PointAt(lineT);
                            currentLineM1.To = currentLineM1.PointAt(lineT1);
                        }

                        linesCopy[localID]   = currentLine;
                        linesCopy1[localID]  = currentLine1;
                        linesCopyM[localID]  = currentLineM;
                        linesCopyM1[localID] = currentLineM1;
                    }
                }



                for (int i = 0; i < linesCopy.Length; i++)
                {
                    if (mesh.TopologyEdges.GetConnectedFaces(allEArray[i]).Length == 1)
                    {
                        continue;
                    }

                    polylines.AddRange(new Polyline[] {
                        new Polyline(new Point3d[] { linesCopy[i].From, linesCopy[i].To, linesCopy1[i].To, linesCopy1[i].From, linesCopy[i].From }),
                        new Polyline(new Point3d[] { linesCopyM[i].From, linesCopyM[i].To, linesCopyM1[i].To, linesCopyM1[i].From, linesCopyM[i].From })
                    }, new GH_Path(i));
                }



                //A = linesCopy;
                //B = linesCopy1;
                //C = linesCopyM;
                //D = linesCopyM1;
                //E = polylines;
            } catch (Exception e) {
                Rhino.RhinoApp.WriteLine(e.ToString());
            }

            return(polylines);
        }
예제 #12
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh           m          = DA.Fetch <Mesh>("Mesh");
            bool           fixEdges   = DA.Fetch <bool>("FixEdges");
            double         l          = DA.Fetch <double>("EdgeLength");
            int            iterations = DA.Fetch <int>("Iterations");
            List <Point3d> fixPt      = DA.FetchList <Point3d>("FixPt");
            bool           project    = DA.Fetch <bool>("Project");
            bool           loops      = DA.Fetch <bool>("Loops");

            Mesh mesh = m.DuplicateMesh();

            mesh.Faces.ConvertQuadsToTriangles();

            double len = (l == 0) ? mesh.GetBoundingBox(false).Diagonal.Length * 0.1 : l;



            //r.PreventNormalFlips = true;

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

            Point3d[] pts = mesh.Vertices.ToPoint3dArray();
            foreach (Point3d p in fixPt)
            {
                ids.Add(NGonsCore.PointUtil.ClosestPoint(p, pts));
            }



            DMesh3   dmesh = mesh.ToDMesh3();
            Remesher r     = new Remesher(dmesh);

            r.Precompute();
            r.SetTargetEdgeLength(len);
            r.SmoothSpeedT = 0.5;
            if (project)
            {
                r.SetProjectionTarget(MeshProjectionTarget.Auto(dmesh));
            }

            r.EnableFlips     = r.EnableSplits = r.EnableCollapses = true;
            r.EnableSmoothing = true;


            MeshConstraints cons = new MeshConstraints();


            if (ids.Count > 0)
            {
                foreach (int id in ids)
                {
                    //cons.SetOrUpdateVertexConstraint(id, new VertexConstraint(true, 1));
                    cons.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned);
                }
            }
            r.SetExternalConstraints(cons);

            r.Precompute();

            if (fixEdges)
            {
                //r.SetExternalConstraints(new MeshConstraints());
                MeshConstraintUtil.FixAllBoundaryEdges(r);
                MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(cons, dmesh, 0);
                //MeshConstraintUtil.FixAllBoundaryEdges_AllowCollapse(cons, dmesh, 0);
            }

            if (loops)
            {
                MeshConstraintUtil.PreserveBoundaryLoops(r); //project to edge
                                                             //MeshConstraintUtil.PreserveBoundaryLoops(cons,dmesh);//project to edge
            }
            r.SetExternalConstraints(cons);


            for (int k = 0; k < iterations; ++k)
            {
                r.BasicRemeshPass();
            }



            //output
            if (ids.Count > 0 && !fixEdges)
            {
                this.Message = "Vertices";
            }
            else if (ids.Count == 0 && fixEdges)
            {
                this.Message = "Edges";
            }
            else if (ids.Count > 0 && fixEdges)
            {
                this.Message = "Vertices + Edges";
            }
            else
            {
                this.Message = "";
            }



            dmesh = new DMesh3(dmesh, true);
            Mesh rmesh = dmesh.ToRhinoMesh();

            if (loops)
            {
                Mesh mesh_ = rmesh.DuplicateMesh();
                Rhino.IndexPair[] closestEdges = new Rhino.IndexPair[fixPt.Count];

                int counter = 0;
                foreach (Point3d p in fixPt)
                {
                    double[] d   = new double[rmesh.TopologyEdges.Count];
                    int[]    eid = new int[rmesh.TopologyEdges.Count];

                    for (int i = 0; i < rmesh.TopologyEdges.Count; i++)
                    {
                        if (rmesh.TopologyEdges.GetConnectedFaces(i).Length == 1)
                        {
                            Line line = rmesh.TopologyEdges.EdgeLine(i);
                            line.ClosestPoint(p, true);
                            d[i] = line.ClosestPoint(p, true).DistanceToSquared(p); //line.From.DistanceToSquared(p) + line.To.DistanceToSquared(p);
                        }
                        else
                        {
                            d[i] = 99999;
                        }
                        eid[i] = i;
                    }



                    Array.Sort(d, eid);

                    closestEdges[counter++] = rmesh.TopologyEdges.GetTopologyVertices(eid[0]);
                }

                for (int i = 0; i < fixPt.Count; i++)
                {
                    mesh_.Vertices.Add(fixPt[i]);
                    mesh_.Faces.AddFace(rmesh.Vertices.Count + i, closestEdges[i].I, closestEdges[i].J);
                }
                rmesh = mesh_;
            }
            rmesh.UnifyNormals();
            rmesh.RebuildNormals();
            // rmesh.UnifyNormals();



            DA.SetData(0, rmesh);
        }