Beispiel #1
0
        /// <summary>
        /// Geometry - vertex to edges connectivity
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        public static Line[][] VE_Ln(this Mesh mesh)
        {
            Line[][] veSorted_Ln = new Line[mesh.TopologyVertices.Count][];
            int[][]  veSorted    = mesh.VE();

            for (int i = 0; i < mesh.TopologyVertices.Count; i++)
            {
                veSorted_Ln[i] = new Line[veSorted[i].Length];

                for (int j = 0; j < veSorted[i].Length; j++)
                {
                    Rhino.IndexPair pair = mesh.TopologyEdges.GetTopologyVertices(veSorted[i][j]);
                    int             a    = -1;
                    int             b    = -1;
                    if (pair.I == i)
                    {
                        a = pair.I;
                        b = pair.J;
                    }
                    else
                    {
                        b = pair.I;
                        a = pair.J;
                    }
                    veSorted_Ln[i][j] = new Line(mesh.TopologyVertices[a], mesh.TopologyVertices[b]);
                }
            }

            return(veSorted_Ln);
        }
Beispiel #2
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh mesh = new Mesh();

            DA.GetData(0, ref mesh);
            int iteration = DA.Iteration;

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

            Line[]      lines      = mesh.GetAllNGonEdgesLines(e);
            bool[]      n          = mesh.NakedNGonEdges(e);
            List <Line> linesNaked = new List <Line>();

            List <Vector3d> vecs = new List <Vector3d>();
            int             j    = 0;

            foreach (int i in e)
            {
                Line l = mesh.TopologyEdges.EdgeLine(i);
                //l.Transform(Transform.Rotation())
                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
                    );

                vecs.Add(vec);

                if (n[j])
                {
                    linesNaked.Add(l);
                }
                j++;
            }

            this.PreparePreview(mesh, DA.Iteration, null, false, null, lines.ToList());

            DA.SetDataTree(0, new DataTree <Line>(lines, new GH_Path(iteration)));
            DA.SetDataTree(1, new DataTree <int>(e, new GH_Path(iteration)));
            DA.SetDataTree(2, new DataTree <bool>(n, new GH_Path(iteration)));
            DA.SetDataTree(3, new DataTree <Vector3d>(vecs, new GH_Path(iteration)));

            Line[] ae = new Line[mesh.TopologyEdges.Count];
            for (int i = 0; i < mesh.TopologyEdges.Count; i++)
            {
                ae[i] = mesh.TopologyEdges.EdgeLine(i);
            }

            DA.SetDataTree(4, new DataTree <Line>(linesNaked, new GH_Path(iteration)));
            DA.SetDataTree(5, new DataTree <Line>(ae, new GH_Path(iteration)));
        }
Beispiel #3
0
        //Get ngon planes
        public static Plane[][] EPlanes(Mesh mesh, HashSet <int> allE, Dictionary <int, int> allEDict, Plane[] planesO, Plane[] planesOffset, int[][] eNgons, double jointWidth, double rotation, Line[] innerLines, int[][] ngonEdges, int[][] jointTypes, int[][] vertexNGons, int[] allV, double maxLength)
        {
            Line[]    eLine = mesh.GetAllNGonEdgesLines(allE);//Plane origin points will be on those lines
            Plane[][] mp;



            //EDGE PLANES
            Plane[] edgePlanes = new Plane[allEDict.Count];

            //Loop through all bisector edge faces and check if that edge belongs to one of edge faces
            //Dictionary<int, Plane> bisectors = GetBisectors(allE, planesO, eNgons);
            Dictionary <int, Plane> bisectors = GetCustomAveragePlanes(allE, planesO, eNgons, allV, mesh, ngonEdges, allEDict);



            for (int i = 0; i < allEDict.Count; i++)
            {
                Plane planeForXAxisRotation = (jointTypes[i][0] == 3) ? planesO[eNgons[i][0]] : planesO[eNgons[i][1]]; // Check which edges are connected with bisectors
                edgePlanes[i] = PlaneUtil.PlaneFromLinePlane(innerLines[i], planeForXAxisRotation);                    //Take edge vector and rotate it by male plane and in this way get edgePlane


                foreach (KeyValuePair <int, Plane> pair in bisectors)
                {
                    //Test if edge is connected to bisector edge
                    //Get connected ngons of bisector edge

                    //Insertion direction:
                    //1. Bisector plane 2Dof insertion freedom
                    //To insert all edges correctly - insertion direction is limited to 1 Dof
                    //2. It is a bisector of mesh faces connected to edge vertices, excluding faces connected to edges
                    int[] bisectorNgons = eNgons[pair.Key];

                    bool flag1 = eNgons[i].Contains(bisectorNgons[0]);
                    bool flag2 = eNgons[i].Contains(bisectorNgons[1]);

                    if (flag1 || flag2)
                    {
                        Plane modifiedBisectorPlane = new Plane(edgePlanes[i].Origin, pair.Value.XAxis, pair.Value.YAxis); //Move bisector plane to the middle of edge

                        Rhino.IndexPair ip  = mesh.TopologyEdges.GetTopologyVertices(allE.ElementAt(i));
                        Rhino.IndexPair bip = mesh.TopologyEdges.GetTopologyVertices(allE.ElementAt(pair.Key));

                        //If edge is connected to bisector edge
                        if ((ip.I == bip.I || ip.I == bip.J || ip.J == bip.I || ip.J == bip.J) && (i != pair.Key))
                        {
                            edgePlanes[i] = PlaneUtil.AlignPlane(edgePlanes[i], modifiedBisectorPlane);
                            //edgePlanes[i] = modifiedBisectorPlane;
                        }

                        else
                        {
                            planeForXAxisRotation = (jointTypes[i][0] == 3) ? planesO[eNgons[i][1]] : planesO[eNgons[i][0]]; // Check which edges are connected with bisectors
                            edgePlanes[i]         = PlaneUtil.PlaneFromLinePlane(innerLines[i], planeForXAxisRotation);      //Take edge vector and rotate it by male plane and in this way get edgePlane
                            //Get vertex ngons
                            int[] CurrentEdgeVertexNgons_I = vertexNGons[Array.IndexOf(allV, ip.I)];
                            int[] CurrentEdgeVertexNgons_J = vertexNGons[Array.IndexOf(allV, ip.J)];
                            //Boolean difference between two

                            int faceI = CurrentEdgeVertexNgons_I.Except(CurrentEdgeVertexNgons_J).First();
                            // int faceJ = CurrentEdgeVertexNgons_J.Except(CurrentEdgeVertexNgons_I).First();
                            Plane bi     = planesO[faceI];
                            Plane mPlane = new Plane(edgePlanes[i].Origin, bi.XAxis, bi.YAxis);

                            //edgePlanes[i].Rotate(Math.PI*0.5, edgePlanes[i].ZAxis);
                            //edgePlanes[i] = new Plane(edgePlanes[i].Origin, edgePlanes[i].YAxis, edgePlanes[i].XAxis);
                            edgePlanes[i] = PlaneUtil.AlignPlane(edgePlanes[i], mPlane);
                            //edgePlanes[i].Rotate(Math.PI * 0.5, edgePlanes[i].ZAxis);
                            //edgePlanes[i].Rotate(Math.PI * 0.5, edgePlanes[i].ZAxis);
                        }
                        break;
                    }
                }
            }



            //OFFSET PLANES
            mp = new Plane[allEDict.Count][];


            HashSet <int> edges = new HashSet <int>();

            int[] e1 = ngonEdges[6];
            int[] e2 = ngonEdges[7];
            for (int i = 0; i < e1.Length; i++)
            {
                edges.Add(allEDict[e1[i]]);
            }
            for (int i = 0; i < e2.Length; i++)
            {
                edges.Add(allEDict[e2[i]]);
            }
            Rhino.RhinoApp.ClearCommandHistoryWindow();
            foreach (var edge in edges)
            {
                GrasshopperUtil.Debug(edge);
            }



            for (int i = 0; i < allEDict.Count; i++)
            {
                mp[i] = new Plane[0];
                if (jointTypes[i][0] != -1 && jointTypes[i][1] != -1)
                {
                    //Direction
                    Vector3d vec = Vector3d.Subtract((Vector3d)innerLines[i].From, (Vector3d)innerLines[i].To);
                    vec.Unitize();
                    vec *= jointWidth;
                    //Distance
                    double dist = innerLines[i].Length - jointWidth; //Draw at least one joint
                    int    n    = (int)(innerLines[i].Length * 0.5 / jointWidth) - 1;



                    if (innerLines[i].Length > maxLength)
                    {
                        vec.Unitize();
                        double jointWidth2 = innerLines[i].Length / 10;
                        vec *= jointWidth2;

                        dist = innerLines[i].Length - jointWidth2; //Draw at least one joint
                        n    = (int)((innerLines[i].Length * 0.5 / jointWidth2) - 1);
                    }


                    n = (n <= 0) ? 0 : n;



                    //Planes
                    //Define center planes
                    mp[i] = new Plane[n * 2 + 2];
                    if (dist > 0)
                    {
                        mp[i][n] = new Plane(edgePlanes[i]);
                        mp[i][n].Translate(vec * 0.5);
                        mp[i][n + 1] = new Plane(edgePlanes[i]);
                        mp[i][n + 1].Translate(-vec * 0.5);
                    }
                    //Define rest of the planes
                    for (int j = 1; j < n + 1; j++)
                    {
                        int t = n - j;
                        mp[i][t] = new Plane(edgePlanes[i]);
                        mp[i][t].Translate((j * vec) + (vec * 0.5));
                        mp[i][j + n + 1] = new Plane(edgePlanes[i]);
                        mp[i][j + n + 1].Translate((j * -vec) - (vec * 0.5));
                    }

                    if (dist < 0)
                    {
                        mp[i] = new Plane[0];
                    }


                    //if (edges.Contains(i))
                    // mp[i] = new Plane[0];
                }
            }

            //ROTATE PLANES
            RotatePlaneArray(mp, rotation);

            //OUTPUT
            return(mp);
        }
Beispiel #4
0
        public static Dictionary <int, Plane> GetCustomAveragePlanes(HashSet <int> allE, Plane[] planesO, int[][] eNgons, int[] allV, Mesh mesh, int[][] ngonEdges, Dictionary <int, int> allEDict)
        {
            Dictionary <int, Plane> bisectors = new Dictionary <int, Plane>();


            double minAngle = Math.PI / 18 * 3;
            double maxAngle = Math.PI / 18 * 15;

            for (int i = 0; i < allE.Count; i++)
            {
                int[]  ngons = eNgons[i];
                double angle = Vector3d.VectorAngle(planesO[ngons[0]].ZAxis, planesO[ngons[1]].ZAxis);
                if (angle < minAngle || angle > maxAngle)
                {
                    //Get connected edges to current edges
                    int[] edgesA    = ngonEdges[ngons[0]];
                    int[] ngonPairA = new int[0];
                    int[] edgesB    = ngonEdges[ngons[1]];
                    int[] ngonPairB = new int[0];


                    Rhino.IndexPair ip = mesh.TopologyEdges.GetTopologyVertices(allE.ElementAt(i));

                    for (int j = 0; j < edgesA.Length; j++)
                    {
                        Rhino.IndexPair tempIp = mesh.TopologyEdges.GetTopologyVertices(edgesA[j]);
                        if (ip.I != tempIp.I && ip.J != tempIp.J && ip.J != tempIp.I && ip.I != tempIp.J)
                        {
                            ngonPairA = eNgons[allEDict[edgesA[j]]];
                            //GrasshopperUtil.Debug(ngonPairA[0]);
                            //GrasshopperUtil.Debug(ngonPairA[1]);
                            break;
                        }
                    }

                    for (int j = 0; j < edgesB.Length; j++)
                    {
                        Rhino.IndexPair tempIp = mesh.TopologyEdges.GetTopologyVertices(edgesB[j]);
                        if (ip.I != tempIp.I && ip.J != tempIp.J && ip.J != tempIp.I && ip.I != tempIp.J)
                        {
                            ngonPairB = eNgons[allEDict[edgesB[j]]];
                            //GrasshopperUtil.Debug(ngonPairB[0]);
                            //GrasshopperUtil.Debug(ngonPairB[1]);
                            break;
                        }
                    }


                    int faceA = ngonPairB.Except(ngons).First();
                    int faceB = ngonPairA.Except(ngons).First();

                    Plane ptemp = planesO[faceA];
                    ptemp.Flip();

                    Plane bisector = PlaneUtil.AveragePlane(new Plane[] { ptemp, planesO[faceB] });;
                    bisectors.Add(i, bisector);
                }
            }

            return(bisectors);
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Rhino.Geometry.Mesh M = null;
            if (!DA.GetData(0, ref M))
            {
                return;
            }

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

            if (!DA.GetDataList(1, L))
            {
                return;
            }

            List <double> offset = new List <double>();

            if (!DA.GetDataList(2, offset))
            {
                return;
            }

            // Check that the mesh is valid, weld all edges, recalculate vertex normals
            if (!M.IsValid)
            {
                return;
            }

            /*M.Weld(Math.PI); // Not compatible with Rhino 4!
             * M.Compact();
             * M.UnifyNormals();
             * M.Flip(true, true, true);*/
            M.Normals.ComputeNormals();
            //M.Normals.UnitizeNormals();

            int n = M.TopologyVertices.Count;
            int m = M.TopologyEdges.Count;

            List <Point3f[]> layers = new List <Point3f[]>();
            List <string>    bars   = new List <string>();

            // Add dummy zero offset
            offset.Insert(0, 0);

            // for each layer, add two center line "layers"
            // (note: the first layer of nodes will be "on" the surface of the mesh, otherwise remove "- 0.5 * offset[1]"!)
            for (int i = 1; i < offset.Count; i++)
            {
                Point3f[] l0 = new Point3f[n];
                Point3f[] l1 = new Point3f[n];
                for (int j = 0; j < n; j++)
                {
                    int vertex = M.TopologyVertices.MeshVertexIndices(j)[0];
                    l0[j] = M.TopologyVertices[j] + (float)(2 * offset[i - 1] + 0.5 * offset[i] - 0.5 * offset[1]) * M.Normals[vertex];
                    l1[j] = M.TopologyVertices[j] + (float)(2 * offset[i - 1] + 1.5 * offset[i] - 0.5 * offset[1]) * M.Normals[vertex];
                }
                layers.Add(l0);
                layers.Add(l1);
            }

            // Remove dummy zero offset
            offset.RemoveAt(0);

            // Bars - for each, list by 'line' and by start/end node indices (and calculate gamma angle)
            List <Line> lines = new List <Line>();

            double[] gamma = new double[m];
            for (int i = 0; i < m; i++)
            {
                Rhino.IndexPair se = M.TopologyEdges.GetTopologyVertices(i);

                // ------------------------------------------------------------------------------
                // GAMMA
                Vector3d[] normals = new Vector3d[] {
                    M.Normals[M.TopologyVertices.MeshVertexIndices(se.I)[0]],
                    M.Normals[M.TopologyVertices.MeshVertexIndices(se.J)[0]]
                };
                Vector3d avg      = normals[0] + normals[1];
                Plane    vertical = new Plane(M.TopologyVertices[se.I], M.TopologyVertices[se.J],
                                              M.TopologyVertices[se.J] + Vector3f.ZAxis);
                Plane bar = new Plane(M.TopologyVertices[se.I], M.TopologyVertices[se.J],
                                      new Point3d(M.TopologyVertices[se.J]) + avg);
                gamma[i]  = (180 * (Vector3d.VectorAngle(vertical.Normal, bar.Normal))) / Math.PI;
                gamma[i] *= Vector3d.CrossProduct(vertical.Normal, bar.Normal).IsParallelTo(M.TopologyVertices[se.J] - M.TopologyVertices[se.I]);
                // ------------------------------------------------------------------------------

                if (L[i] == 0)
                { // WARP, add to layers 0, 2, 4, ...
                    for (int j = 0; j < offset.Count; j++)
                    {
                        lines.Add(new Line(layers[2 * j][se.I], layers[2 * j][se.J]));
                        bars.Add(string.Format("{0,6} {1,6}", (2 * j) * n + se.I + 1, (2 * j) * n + se.J + 1));
                    }
                }
                else
                { // WEFT, add to layers 1, 3, 5, ...
                    for (int j = 0; j < offset.Count; j++)
                    {
                        lines.Add(new Line(layers[2 * j + 1][se.I], layers[2 * j + 1][se.J]));
                        bars.Add(string.Format("{0,6} {1,6}", (2 * j + 1) * n + se.I + 1, (2 * j + 1) * n + se.J + 1));
                    }
                }
            }
            // Links
            for (int i = 0; i < M.TopologyVertices.Count; i++)
            {
                for (int j = 0; j < layers.Count - 1; j++)
                {
                    lines.Add(new Line(layers[j][i], layers[j + 1][i]));
                    bars.Add(string.Format("{0,6} {1,6}", (j) * n + i + 1, (j + 1) * n + i + 1));
                }
            }

            // Nodes - list all by coordinates
            List <Point3f> nodes = new List <Point3f>();

            for (int i = 0; i < layers.Count; i++)
            {
                nodes.AddRange(layers[i]);
            }

            DA.SetDataList(0, nodes);
            DA.SetDataList(1, bars);
            DA.SetDataList(2, gamma);
            DA.SetDataList(3, lines);
        }