protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> mesh = new List <Mesh>(); if (DA.GetDataList(0, mesh)) { List <int>[] mc = MeshUtilSimple.MeshCollisions(mesh); DA.SetDataTree(0, GrasshopperUtil.ArrayOfListsToTree(mc)); //Next check overlapping faces only if ngons exists List <Polyline[]>[] mcPlines = new List <Polyline[]> [mc.Length]; for (int i = 0; i < mc.Length; i++) { mcPlines[i] = new List <Polyline[]>(); for (int j = 0; j < mc[i].Count; j++) { //Do it with ngons MeshUtil.GetOverlap(mesh[i], mesh[mc[i][j]], 0.1); } } }//if }
public Polyline[][] FaceOutlines(Mesh M, Plane[] facePlanes, Plane[] linePlanes, int[][] fe_, int[][] fe, double offset, double thickness, Line[] cutLines, Dictionary <int, int> e, Surface rs) { Mesh projectionMesh = Mesh.CreateFromBrep(rs.ToBrep())[0]; Polyline[][] outlines = new Polyline[facePlanes.Length][]; Polyline[][] outlinesCopy = new Polyline[facePlanes.Length][]; //Draw perpendicular joint Tuple <int, int>[][] efe = M.GetEF_LocalID(M.GetAllNGonEdges(M.GetNGonsTopoBoundaries())); if (offset > 0) { for (int i = 0; i < facePlanes.Length; i++) { //Base Planes Plane basePlane0 = new Plane(facePlanes[i].MovePlanebyAxis(offset * 0.5 + thickness * 0.5)); Plane basePlane1 = new Plane(facePlanes[i].MovePlanebyAxis(offset * 0.5 + -thickness * 0.5)); Plane basePlane2 = new Plane(facePlanes[i].MovePlanebyAxis(offset * -0.5 + thickness * 0.5)); Plane basePlane3 = new Plane(facePlanes[i].MovePlanebyAxis(offset * -0.5 + -thickness * 0.5)); //Side Planes List <Plane> sidePlanes = new List <Plane>(); for (int j = 0; j < fe_[i].Length; j++) { sidePlanes.Add(linePlanes[fe_[i][MathUtil.Wrap(j - 1, fe_[i].Length)]]); } //Intersect base plane with side planes Polyline outline0 = PolylineUtil.PolylineFromPlanes(basePlane0, sidePlanes); Polyline outline1 = PolylineUtil.PolylineFromPlanes(basePlane1, sidePlanes); Polyline outline2 = PolylineUtil.PolylineFromPlanes(basePlane2, sidePlanes); Polyline outline3 = PolylineUtil.PolylineFromPlanes(basePlane3, sidePlanes); outlines[i] = new Polyline[] { outline0, outline1, outline2, outline3 }; } return(outlines); } else { List <Plane>[] sidePlanes = new List <Plane> [facePlanes.Length]; for (int i = 0; i < facePlanes.Length; i++) { //Base Planes Plane basePlane0 = new Plane(facePlanes[i].MovePlanebyAxis(thickness * 0.5)); Plane basePlane1 = new Plane(facePlanes[i].MovePlanebyAxis(-thickness * 0.5)); //Side Planes sidePlanes[i] = new List <Plane>(); for (int j = 0; j < fe_[i].Length; j++) { sidePlanes[i].Add(linePlanes[fe_[i][j]]); } //Intersect base plane with side planes Polyline outline0 = PolylineUtil.PolylineFromPlanes(basePlane0, sidePlanes[i]); Polyline outline1 = PolylineUtil.PolylineFromPlanes(basePlane1, sidePlanes[i]); Polyline outline0Copy = new Polyline(outline0); Polyline outline1Copy = new Polyline(outline1); outlines[i] = new Polyline[] { outline0, outline1 }; outlinesCopy[i] = new Polyline[] { new Polyline(outline0), new Polyline(outline1) }; }//for i for (int i = 0; i < facePlanes.Length; i++) { //Loop segments and check intersection for (int j = 0; j < outlines[i][0].Count - 1; j++) { //Get current segment Line segment0 = outlines[i][0].SegmentAt(j); // current line Line segment1 = outlines[i][1].SegmentAt(j); // current line //Get connected face of that segment int flattenID = e[fe[i][j]]; Tuple <int, int>[] edgeFacesAndEdge = efe[flattenID]; if (edgeFacesAndEdge.Length == 2) { int neiFID = (edgeFacesAndEdge[0].Item1 == i) ? 1 : 0; int neiF = edgeFacesAndEdge[neiFID].Item1; int nextNei = edgeFacesAndEdge[neiFID].Item2; Plane planeA = sidePlanes[neiF][MathUtil.Wrap(nextNei + 2, fe[neiF].Length)]; Plane planeB = sidePlanes[neiF][MathUtil.Wrap(nextNei + 0, fe[neiF].Length)]; Plane planeC = sidePlanes[neiF][MathUtil.Wrap(nextNei + 1, fe[neiF].Length)]; Plane planeD = sidePlanes[neiF][MathUtil.Wrap(nextNei + 3, fe[neiF].Length)]; //Rhino.RhinoApp.WriteLine(fe[neiF].Length.ToString() + " " + sidePlanes[neiF].Count.ToString() + " " + MathUtil.Wrap(nextNei - 1, fe[neiF].Length).ToString()); int nn = MathUtil.Wrap(nextNei - 1, fe[neiF].Length); //nextNei = fe[neiF][MathUtil.Wrap(nextNei - 1, fe[neiF].Length)]; //for(int k = 0; k < fe[neiF].Length; k++) { //int nextNei = k; //Rhino.RhinoApp.wr if (i == 11 && j == 3) { Rectangle3d rec = new Rectangle3d(planeA, 10, 10); //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(rec); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(outlinesCopy[i][0]); rec = new Rectangle3d(planeB, 10, 10); //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(rec); //rec = new Rectangle3d(planeC, 10, 10); //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(rec); } //Rhino.RhinoApp.WriteLine("ww"); bool flag = Rhino.Geometry.Intersect.Intersection.LinePlane(segment0, planeB, out double t); if (t > 0 && t < 1) { Point3d neiP0 = NGonsCore.PlaneUtil.LinePlane(segment0, planeB); outlinesCopy[i][0].Insert((int)Math.Ceiling(outlinesCopy[i][0].ClosestParameter(neiP0)), neiP0); Point3d neiP1 = NGonsCore.PlaneUtil.LinePlane(segment1, planeB); outlinesCopy[i][1].Insert((int)Math.Ceiling(outlinesCopy[i][1].ClosestParameter(neiP1)), neiP1); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(neiP0); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(neiP1); } //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(neiP); // } } } //if (i == 11) { //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(outlinesCopy[i][0]); //} } for (int i = 0; i < facePlanes.Length; i++) { outlinesCopy[i][0].RemoveAt(0); outlinesCopy[i][1].RemoveAt(0); for (int j = 0; j < outlinesCopy[i][0].Count; j++) { Line line = new Line(outlinesCopy[i][0][j], outlinesCopy[i][1][j]); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(line); Point3d pt = MeshUtilSimple.MeshRay(projectionMesh, line); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(pt); outlinesCopy[i][0][j] = pt; } outlinesCopy[i][0].Close(); outlinesCopy[i][1].Close(); } //Edge vectors Vector3d[] ev = new Vector3d[efe.Length]; } return(outlinesCopy); }
public static Mesh Dual(this Mesh mesh, int type = 0, Surface surface = null, List <Point3d> pts = null) { Mesh x = mesh.DuplicateMesh(); bool hasOnlyTriangleQuadNgons = true; for (int i = 0; i < x.Ngons.Count; i++) { if (x.Ngons[i].BoundaryVertexCount > 4) { hasOnlyTriangleQuadNgons = false; break; } } if (hasOnlyTriangleQuadNgons) { x.Ngons.Clear(); } int Type = Math.Abs(type); Mesh dual = new Mesh(); if (surface != null) { Surface s = surface; s.SetDomain(0, new Interval(0, 1)); s.SetDomain(1, new Interval(0, 1)); } if (x.Ngons.Count == 0) { //Get face center int count = 0; foreach (MeshFace mf in x.Faces) { Point3d barycenter = Point3d.Origin; if (pts != null) { if (pts.Count == x.Faces.Count) { Type = 2; } } switch (Type) { case (2): barycenter = pts[count]; break; case (1): if (mf.IsQuad) { barycenter = new Polyline(new Point3d[] { x.Vertices[mf.A], x.Vertices[mf.B], x.Vertices[mf.C], x.Vertices[mf.D], x.Vertices[mf.A] }).CenterPoint(); } else { barycenter = new Polyline(new Point3d[] { x.Vertices[mf.A], x.Vertices[mf.B], x.Vertices[mf.C], x.Vertices[mf.A] }).CenterPoint(); } break; default: barycenter += (x.Vertices[mf.A]); barycenter += (x.Vertices[mf.B]); barycenter += (x.Vertices[mf.C]); if (mf.IsQuad) { barycenter += (x.Vertices[mf.D]); barycenter /= 4; } else { barycenter /= 3; } break; } dual.Vertices.Add(barycenter); count++; } //Apply dual List <Polyline> polylines = new List <Polyline>(); bool[] nakedv = x.GetNakedEdgePointStatus(); Point3d[] midPoints = MeshUtilSimple.EdgeMidPoints(x); dual.Vertices.AddVertices(midPoints); //int[] edges = x.TopologyVertices.ConnectedEdges(vID); //foreach (int edgeID in edges) { // int[] edgeFaces = x.TopologyEdges.GetConnectedFaces(edgeID); // if (edgeFaces.Length == 1) { // nakedFaces.Add(edgeFaces[0]); // nakedEdges.Add(edgeID); // nakedEdgesP.Add(midPoints[edgeID]); // // nakedEdgesPDistToLastP.Add(lastPoint.DistanceToSquared(midPoints[edgeID])); // } //} for (int i = 0; i < x.Vertices.Count; i++) { if (nakedv[i] && type < 0) { continue; } int vID = x.TopologyVertices.TopologyVertexIndex(i); int[] vf = x.TopologyVertices.ConnectedFaces(vID); int[] sortedFaces = SortFacesConnectedToTopologyVertex(x, vf); //You can select vertices from dual mesh //Or if you calculate barycenter here, then you will have duplicate points if (vf.Length > 0) //2 { Polyline polyline = new Polyline(); List <int> id = new List <int>(); for (int j = 0; j < sortedFaces.Length; j++) { polyline.Add(dual.Vertices[sortedFaces[j]]); id.Add(sortedFaces[j]); } if (nakedv[i]) { Point3d lastPoint = polyline.Last(); List <int> nakedEdges = new List <int>(); List <Point3d> nakedEdgesP = new List <Point3d>(); List <double> nakedEdgesPDistToLastP = new List <double>(); List <int> nakedFaces = new List <int>(); int[] edges = x.TopologyVertices.ConnectedEdges(vID); int numberOfNakedV = 0; foreach (int edgeID in edges) { int[] edgeFaces = x.TopologyEdges.GetConnectedFaces(edgeID); if (edgeFaces.Length == 1) { numberOfNakedV++; nakedFaces.Add(edgeFaces[0]); nakedEdges.Add(edgeID); nakedEdgesP.Add(midPoints[edgeID]); // nakedEdgesPDistToLastP.Add(lastPoint.DistanceToSquared(midPoints[edgeID])); } } if (nakedFaces.Count == 2) { if (id.Last() == nakedFaces[0]) { polyline.Add(nakedEdgesP[0]); if (vf.Length <= 10) { polyline.Add(x.Vertices[vID]); } polyline.Add(nakedEdgesP[1]); //id.Add(nakedFaces[0]); //id.Add(nakedFaces[1]); } else { polyline.Add(nakedEdgesP[1]); if (vf.Length <= 10) { polyline.Add(x.Vertices[vID]); } polyline.Add(nakedEdgesP[0]); //id.Add(nakedFaces[1]); //id.Add(nakedFaces[0]); } } } polyline.Add(polyline[0]); polylines.Add(polyline); //MeshFace[] faces = polyline.TriangulateClosedPolyline(); //if (faces != null) { // int f = dual.Faces.Count;//current dual faces // int[] faceId = new int[faces.Length];//triangulate polyline faces // for (int j = 0; j < faces.Length; j++) { // //id - face id // dual.Faces.AddFace(id[faces[j].A], id[faces[j].B], id[faces[j].C]); // faceId[j] = f++; // } // dual.Ngons.AddNgon(MeshNgon.Create(id, faceId)); //} } } dual = MeshCreate.MeshFromPolylines(polylines, 0); } else { if (pts != null) { if (pts.Count == x.Ngons.Count) { Type = 2; } } int[][] tv = x.GetNGonsTopoBoundaries(); HashSet <int> allV = x.GetAllNGonsVertices(); List <Polyline> polylines = new List <Polyline>(); int[][] vf = x.GetNGonsConnectedToNGonVertices(allV); int[][] vf_ = new int[vf.Length][]; List <int>[] ff = x.GetNgonFaceAdjacencyOrdered(); bool[] naked = x.GetNakedNGonPointStatus(allV); for (int i = 0; i < vf.Length; i++) { if (naked[i]) { continue; } vf_[i] = new int[vf[i].Length]; HashSet <int> tempHash = new HashSet <int>(); Polyline outline = new Polyline(); for (int j = 0; j < vf[i].Length; j++) { if (j == 0) { vf_[i][j] = vf[i][0]; tempHash.Add(vf[i][0]); switch (Type) { case (2): outline.Add(pts[vf[i][0]]); break; case (1): outline.Add(x.GetNgonCenter(vf[i][0])); break; default: outline.Add(x.Ngons.GetNgonCenter(vf[i][0])); break; } } else { List <int> ffLocal = ff[vf_[i][j - 1]]; List <int> neiF = ffLocal.Intersect(vf[i]).ToList(); foreach (int nf in neiF) { if (tempHash.Add(nf)) { vf_[i][j] = nf; switch (Type) { case (2): outline.Add(pts[nf]); break; case (1): outline.Add(x.GetNgonCenter(nf)); break; default: outline.Add(x.Ngons.GetNgonCenter(nf)); break; } break; } //if } } //if } //for j outline.Close(); polylines.Add(outline); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(outline); }//for i dual = MeshCreate.MeshFromPolylines(polylines, 0.01); }//if ngon dual.Clean(); //var bfs = NGonsCore.Graphs.UndirectedGraphBfsRhino.MeshBFS(dual, "0"); //dual = NGonsCore.MeshCreate.MeshFromPolylines(dual.UnifyWinding(bfs.Item2[0].ToArray()), 0.01); return(dual); }