public Mesh Mesh3DMinimalBox(Mesh mesh) { List <Point3d> x = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; for (int i = 0; i < vs.Count; i++) { x.Add(new Point3d(vs[i])); } Mesh mesh2 = ch.ConvexHull(x); mesh2.Faces.ConvertQuadsToTriangles(); double t = double.MaxValue; Transform xform = new Transform(); for (int i = 0; i < mesh2.Faces.Count - 1; i++) { Point3d p1 = new Point3d(mesh2.Vertices[mesh2.Faces[i].A]); Point3d p2 = new Point3d(mesh2.Vertices[mesh2.Faces[i].B]); Point3d p3 = new Point3d(mesh2.Vertices[mesh2.Faces[i].C]); Plane p = new Plane(p1, p2, p3); Mesh mesh3 = new Mesh(); mesh3.Append(mesh); mesh3.Transform(Transform.PlaneToPlane(p, Plane.WorldXY)); Rhino.Geometry.BoundingBox box = mesh3.GetBoundingBox(true); double area = (box.Max.X - box.Min.X) * (box.Max.Y - box.Min.Y) * (box.Max.Z - box.Min.Z); if (area < t) { t = area; xform = Transform.PlaneToPlane(p, Plane.WorldXY); } } mesh.Transform(xform); return(mesh); }
private void addRhinoMeshVertices(Rhino.Geometry.Collections.MeshTopologyVertexList meshVertexList, Rhino.Geometry.Collections.MeshVertexNormalList meshVertexNormalList) { for (int i = 0; i < meshVertexList.Count; i++) { addVertex(UsefulFunctions.convertPointToVector(meshVertexList[i])); } }
public Mesh Mesh2DMinimalBox(Mesh mesh) { List <Point3d> x = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; for (int i = 0; i < vs.Count; i++) { x.Add(new Point3d(vs[i])); } Grasshopper.Kernel.Geometry.Node2List list = new Grasshopper.Kernel.Geometry.Node2List(x); Polyline pl = Grasshopper.Kernel.Geometry.ConvexHull.Solver.ComputeHull(list); double t = double.MaxValue; Transform xform = new Transform(); for (int i = 0; i < pl.Count - 1; i++) { Vector3d Xaxis = pl[i + 1] - pl[i]; Vector3d Yaxis = Vector3d.CrossProduct(Xaxis, Vector3d.ZAxis); Plane p = new Plane(pl[i], Xaxis, Yaxis); Polyline pl2 = new Polyline(pl); pl2.Transform(Transform.PlaneToPlane(p, Plane.WorldXY)); Rhino.Geometry.BoundingBox box = pl2.BoundingBox; double area = (box.Max.X - box.Min.X) * (box.Max.Y - box.Min.Y); if (area < t) { t = area; xform = Transform.PlaneToPlane(p, Plane.WorldXY); } } mesh.Transform(xform); return(mesh); }
public Gauss(Mesh input_mesh) { mesh = input_mesh; mesh.Compact(); mesh.UnifyNormals(); el = mesh.TopologyEdges; vs = mesh.TopologyVertices; ps = new List<VertexProperties>(); for (int i = 0; i < vs.Count; i++) { ps.Add(new VertexProperties (mesh.Normals[vs.MeshVertexIndices(i)[0]])); // outputs2.Add(new Vector3d()); } }
public List <Point3d> GetRandomVertex(Mesh mesh, int count) { Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; List <Point3d> output = new List <Point3d>(); if (count < 7) { return(output); } BoundingBox box = mesh.GetBoundingBox(true); double distance = box.Max.DistanceTo(box.Min); distance /= Math.Sqrt(count * 2); int stepCount = 0; while (output.Count < count && stepCount < count * 100) { bool sign = true; Point3d pt2 = new Point3d(vs[rnd.Next(0, vs.Count)]); for (int i = 0; i < output.Count; i++) { Point3d pt = output[i]; if (pt.DistanceTo(pt2) < distance) { sign = false; break; } } if (sign) { output.Add(pt2); stepCount = 0; } else { stepCount++; } } return(output); }
protected override void SolveInstance(IGH_DataAccess DA) { low = -(double)(min) * Math.Pow(10, exp1); up = (double)(max) * Math.Pow(10, exp1); //Input bool d1 = true; double distance = 2; method = 2; //curvatureType = 3; Interval interval = new Interval(0, 0); if (!DA.GetData(0, ref this.mesh)) { return; } ///List<Color> colors = new List<Color>() { Color.FromArgb(255, 0, 0), Color.FromArgb(255, 255, 0), Color.FromArgb(255, 255, 255) }; List <Color> colors = new List <Color>(); int ct = 0; if (DA.GetData(1, ref ct)) { curvatureType = ct; } // DA.GetData(2, ref d1); DA.GetData(2, ref distance); DA.GetData(3, ref method); // DA.GetData(5, ref animate); DA.GetData(4, ref interval); if (DA.GetDataList(5, colors) && colors.Count == 3) { A = colors[0]; B = colors[1]; C = colors[2]; } bool run = true; DA.GetData(6, ref run); //NGonsCore.MeshUtil.Clean(mesh); //Calculation #region topvertex = mesh.TopologyVertices; //Values from Mesh_Curvature_Utilities struct if (run) { mainK = NGonsCore.MeshUtilSimple.Mesh_Cuvature_Utilities_Debugging.MainK(d1, !d1, (int)distance, aMeshEdgeLength * distance, method, curvatureType, mesh, topvertex); Kmed = mainK.y; KT = mainK.x; kmmin = Enumerable.Min(Kmed); kmmax = Enumerable.Max(Kmed); v1 = kmmin + 0.1 * (kmmax - kmmin); v2 = kmmin + 0.9 * (kmmax - kmmin); vertexCol = Enumerable.Repeat(Color.Black, mesh.Vertices.Count).ToList(); double[] KmedSort = new double[Kmed.Count]; Kmed.CopyTo(KmedSort); KmedSort.ToList().Sort(); low = KmedSort[(int)(KmedSort.Length / 3)]; up = KmedSort[(int)(2 * (KmedSort.Length / 3))]; v1 = low; v2 = up; v1 = kmmin; v2 = kmmax; } else if (interval.Min != interval.Max) { v1 = interval.Min; v2 = interval.Max; } //if (display) colorMesh3Colors(); //else colorMeshGradient(); colorMeshGradient(); #endregion //Output baseMessage(); DA.SetData(0, mesh); DA.SetDataList(1, Kmed); }
/// <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) { double anchorThreshold = 0.01; double pointDuplicateThreshold = 0.01; bool isSheetMesh = false; GH_Structure <IGH_Goo> springTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Vector> velTree = new GH_Structure <GH_Vector>(); GH_Structure <GH_Number> massTree = new GH_Structure <GH_Number>(); GH_Structure <GH_Number> lengthTree = new GH_Structure <GH_Number>(); GH_Structure <GH_Number> stiffnessTree = new GH_Structure <GH_Number>(); List <double> sheetStiffeningList = new List <double>(); GH_Structure <IGH_Goo> anchorTree = new GH_Structure <IGH_Goo>(); List <bool> selfCollisionList = new List <bool>(); List <int> groupIndexList = new List <int>(); List <SpringSystem> springSystems = new List <SpringSystem>(); DA.GetDataTree(0, out springTree); DA.GetDataTree(1, out velTree); DA.GetDataTree(2, out massTree); DA.GetDataTree(3, out lengthTree); DA.GetDataTree(4, out stiffnessTree); DA.GetDataList(5, sheetStiffeningList); DA.GetDataList(6, selfCollisionList); DA.GetDataTree(7, out anchorTree); DA.GetDataList(8, groupIndexList); #region simplify trees and if(branch.Count == 1) make sure everything sits in path {0} if (!springTree.IsEmpty) { springTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!velTree.IsEmpty) { velTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!massTree.IsEmpty) { massTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!lengthTree.IsEmpty) { lengthTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!stiffnessTree.IsEmpty) { stiffnessTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (!anchorTree.IsEmpty) { anchorTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps); } if (springTree.Branches.Count != groupIndexList.Count || springTree.Branches.Count != selfCollisionList.Count) { throw new Exception("Line tree doesn't fit either groupIndices count or selfCollision count!"); } if (springTree.Branches.Count == 1) { GH_Structure <IGH_Goo> lT = new GH_Structure <IGH_Goo>(); lT.AppendRange(springTree.Branches[0], new GH_Path(0)); springTree = lT; } if (velTree.Branches.Count == 1) { GH_Structure <GH_Vector> vT = new GH_Structure <GH_Vector>(); vT.AppendRange(velTree.Branches[0], new GH_Path(0)); velTree = vT; } if (massTree.Branches.Count == 1) { GH_Structure <GH_Number> mT = new GH_Structure <GH_Number>(); mT.AppendRange(massTree.Branches[0], new GH_Path(0)); massTree = mT; } if (lengthTree.Branches.Count == 1) { GH_Structure <GH_Number> leT = new GH_Structure <GH_Number>(); leT.AppendRange(lengthTree.Branches[0], new GH_Path(0)); lengthTree = leT; } if (stiffnessTree.Branches.Count == 1) { GH_Structure <GH_Number> sT = new GH_Structure <GH_Number>(); sT.AppendRange(stiffnessTree.Branches[0], new GH_Path(0)); stiffnessTree = sT; } if (anchorTree.Branches.Count == 1) { GH_Structure <IGH_Goo> aT = new GH_Structure <IGH_Goo>(); aT.AppendRange(anchorTree.Branches[0], new GH_Path(0)); anchorTree = aT; } #endregion for (int branchIndex = 0; branchIndex < springTree.Branches.Count; branchIndex++) { List <float> positions = new List <float>(); List <float> velocities = new List <float>(); List <float> invMasses = new List <float>(); List <int> springPairIndices = new List <int>(); List <float> targetLengths = new List <float>(); List <float> stiffnesses = new List <float>(); List <int> anchorIndices = new List <int>(); List <float> initialLengths = new List <float>(); //just for info GH_Path path = new GH_Path(branchIndex); List <Line> lines = new List <Line>(); Curve c; Line l; Mesh mesh = new Mesh(); foreach (IGH_Goo springObject in springTree.get_Branch(path)) { if (springObject.CastTo <Mesh>(out mesh)) { break; } else if (springObject.CastTo <Curve>(out c)) { if (c.IsPolyline()) { Polyline pl; c.TryGetPolyline(out pl); for (int i = 0; i < pl.SegmentCount; i++) { lines.Add(pl.SegmentAt(i)); } AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Polyline in branch " + branchIndex + " was split into its segments!"); } else { lines.Add(new Line(c.PointAtStart, c.PointAtEnd)); } } else if (springObject.CastTo <Line>(out l)) { lines.Add(l); } } #region isMesh if (mesh != null && mesh.IsValid) { mesh.Vertices.CombineIdentical(true, true); mesh.Weld(Math.PI); mesh.UnifyNormals(); Rhino.Geometry.Collections.MeshTopologyVertexList mv = mesh.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList me = mesh.TopologyEdges; //Add everything related to particles for (int i = 0; i < mv.Count; i++) { //add position positions.Add(mv[i].X); positions.Add(mv[i].Y); positions.Add(mv[i].Z); //add velocity Vector3d vel = new Vector3d(0.0, 0.0, 0.0); if (velTree.PathExists(path)) { if (velTree.get_Branch(path).Count > i) { vel = velTree.get_DataItem(path, i).Value; } else { vel = velTree.get_DataItem(path, 0).Value; } } velocities.Add((float)vel.X); velocities.Add((float)vel.Y); velocities.Add((float)vel.Z); //add inverse mass float invMass = 1.0f; if (massTree.PathExists(path)) { if (massTree.get_Branch(path).Count > i) { invMass = 1.0f / (float)massTree.get_DataItem(path, i).Value; } else { invMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value; } } invMasses.Add(invMass); } //Add everything related to spring lines for (int i = 0; i < me.Count; i++) { springPairIndices.Add(me.GetTopologyVertices(i).I); springPairIndices.Add(me.GetTopologyVertices(i).J); //add length float length = (float)me.EdgeLine(i).Length; initialLengths.Add(length); if (lengthTree.PathExists(path)) { float temp = 0.0f; if (lengthTree.get_Branch(path).Count > i) { temp = (float)lengthTree.get_DataItem(path, i).Value; } else { temp = (float)lengthTree.get_DataItem(path, 0).Value; } if (temp < 0.0) { length *= -temp; } else { length = temp; } } targetLengths.Add(length); //add stiffness float stiffness = 1.0f; if (stiffnessTree.PathExists(path)) { if (stiffnessTree.get_Branch(path).Count > i) { stiffness = (float)stiffnessTree.get_DataItem(path, i).Value; } else { stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value; } } stiffnesses.Add(stiffness); List <Line> f = new List <Line>(); if (sheetStiffeningList.Count > branchIndex && sheetStiffeningList[branchIndex] > 0.0) { isSheetMesh = true; int[] adjFaceInd = me.GetConnectedFaces(i); if (adjFaceInd.Length == 2) { f.Add(me.EdgeLine(i)); MeshFace faceA = mesh.Faces[adjFaceInd[0]]; MeshFace faceB = mesh.Faces[adjFaceInd[1]]; if (faceA.IsTriangle && faceB.IsTriangle) { List <int> allInds = new List <int> { faceA.A, faceA.B, faceA.C, faceB.A, faceB.B, faceB.C }; int[] uniques = new int[6] { 0, 0, 0, 0, 0, 0 }; for (int h = 0; h < 6; h++) { for (int g = 0; g < 6; g++) { if (allInds[h] == allInds[g]) { uniques[h]++; } } } for (int h = 0; h < 6; h++) { if (uniques[h] == 1) { springPairIndices.Add(mv.TopologyVertexIndex(allInds[h])); stiffnesses.Add((float)(stiffness * sheetStiffeningList[branchIndex])); } } float le = (float)mv[springPairIndices[springPairIndices.Count - 2]].DistanceTo(mv[springPairIndices[springPairIndices.Count - 1]]); targetLengths.Add(le); initialLengths.Add(le); f.Add(new Line(mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 1])], mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 2])])); } } } } } #endregion #region isLines else if (lines.Count != 0) { List <Line> cleanLineList = new List <Line>(); double ptDuplThrSquared = pointDuplicateThreshold * pointDuplicateThreshold; #region clean up line list List <Line> lHist = new List <Line>(); for (int j = 0; j < lines.Count; j++) { //Clean list from duplicate lines Line lCand = lines[j]; Point3d ptCandA = lCand.From; Point3d ptCandB = lCand.To; bool lineExistsAlready = false; foreach (Line lh in lHist) { Line tempL = new Line(lCand.From, lCand.To); if ((Util.SquareDistance(tempL.From, lh.From) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.To) < ptDuplThrSquared) || (Util.SquareDistance(tempL.From, lh.To) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.From) < ptDuplThrSquared)) { lineExistsAlready = true; } } //Clean list from too short lines if (!(Util.SquareDistance(ptCandA, ptCandB) < ptDuplThrSquared || lineExistsAlready)) { lHist.Add(lCand); cleanLineList.Add(lCand); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Spring nr. " + j + " in branch " + branchIndex + " is either invalid (too short) or appeared for the second time. It is ignored."); } } #endregion //get velocity and mass for this branch (no mass / velo per particle allowed) List <float> branchDefaultVelocity = new List <float>() { 0.0f, 0.0f, 0.0f }; if (velTree.PathExists(path)) { branchDefaultVelocity = new List <float> { (float)velTree.get_DataItem(path, 0).Value.X, (float)velTree.get_DataItem(path, 0).Value.Y, (float)velTree.get_DataItem(path, 0).Value.Z } } ; float branchDefaultInvMass = 1.0f; if (massTree.PathExists(path)) { branchDefaultInvMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value; } //find unique line start indices List <int> springStartIndices = new List <int>(); int advance = 0; for (int item = 0; item < cleanLineList.Count; item++) { Point3d ptCand = cleanLineList[item].From; int alreadyExistsAs = -1; for (int k = 0; k < positions.Count / 3; k++) { //simple squared distance if (Util.SquareDistance(new Point3d(positions[k * 3], positions[k * 3 + 1], positions[k * 3 + 2]), ptCand) < ptDuplThrSquared) { alreadyExistsAs = k; springStartIndices.Add(alreadyExistsAs); break; } } if (alreadyExistsAs == -1) { positions.Add((float)ptCand.X); positions.Add((float)ptCand.Y); positions.Add((float)ptCand.Z); velocities.AddRange(branchDefaultVelocity); invMasses.Add(branchDefaultInvMass); springStartIndices.Add(advance); advance++; } } //find unique line end indices List <int> springEndIndices = new List <int>(); for (int item = 0; item < cleanLineList.Count; item++) { Point3d ptCand = cleanLineList[item].To; int alreadyExistsAs = -1; for (int k = 0; k < positions.Count / 3; k++) { if (Util.SquareDistance(new Point3d(positions[3 * k], positions[3 * k + 1], positions[3 * k + 2]), ptCand) < ptDuplThrSquared) { alreadyExistsAs = k; springEndIndices.Add(alreadyExistsAs); break; } } if (alreadyExistsAs == -1) { positions.Add((float)ptCand.X); positions.Add((float)ptCand.Y); positions.Add((float)ptCand.Z); velocities.AddRange(branchDefaultVelocity); invMasses.Add(branchDefaultInvMass); springEndIndices.Add(advance); advance++; } } //weave spring start indices and spring end indices together for (int w = 0; w < springStartIndices.Count; w++) { springPairIndices.Add(springStartIndices[w]); springPairIndices.Add(springEndIndices[w]); } //Add everything spring line related... for (int i = 0; i < cleanLineList.Count; i++) { //add length float length = (float)cleanLineList[i].Length; initialLengths.Add(length); if (lengthTree.PathExists(path)) { float temp = 0.0f; if (lengthTree.get_Branch(path).Count > i) { temp = (float)lengthTree.get_DataItem(path, i).Value; } else { temp = (float)lengthTree.get_DataItem(path, 0).Value; } if (temp < 0.0) { length *= -temp; } else { length = temp; } } targetLengths.Add(length); //add stiffness float stiffness = 1.0f; if (stiffnessTree.PathExists(path)) { if (stiffnessTree.get_Branch(path).Count > i) { stiffness = (float)stiffnessTree.get_DataItem(path, i).Value; } else { stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value; } } stiffnesses.Add(stiffness); } } #endregion else { throw new Exception("No valid spring input found in branch " + branchIndex); } //Add anchors if (anchorTree.PathExists(path)) { foreach (IGH_Goo anchorObj in anchorTree.get_Branch(path)) { string ass = ""; int ai = 0; Point3d ap = new Point3d(0.0, 0.0, 0.0); if (anchorObj.CastTo <string>(out ass)) { anchorIndices.Add(int.Parse(ass)); } else if (anchorObj.CastTo <int>(out ai)) { anchorIndices.Add(ai); } else if (anchorObj.CastTo <Point3d>(out ap)) { for (int i = 0; i < positions.Count / 3; i++) { if ((anchorThreshold * anchorThreshold) > Math.Pow((positions[3 * i] - ap.X), 2) + Math.Pow((positions[3 * i + 1] - ap.Y), 2) + Math.Pow((positions[3 * i + 2] - ap.Z), 2)) { anchorIndices.Add(i); } } } } } SpringSystem ss = new SpringSystem(positions.ToArray(), velocities.ToArray(), invMasses.ToArray(), springPairIndices.ToArray(), targetLengths.ToArray(), stiffnesses.ToArray(), selfCollisionList[branchIndex], anchorIndices.ToArray(), groupIndexList[branchIndex]); ss.Mesh = mesh; ss.IsSheetMesh = isSheetMesh; ss.InitialLengths = initialLengths.ToArray(); springSystems.Add(ss); } DA.SetDataList(0, springSystems); }
public string FirstEdge(Mesh mesh, out List <int> firstLoop1) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; firstLoop1 = new List <int>(); int firstPoint = -1; for (int i = 0; i < vs.Count; i++) { if (vs.ConnectedTopologyVertices(i).Length == 2) { firstPoint = i; break; } } if (firstPoint == -1) { return("can not find a 2 degree Vertex,Please check the mesh boundary"); } int SecondPoint = vs.ConnectedTopologyVertices(firstPoint)[0]; int ThirdPoint = vs.ConnectedTopologyVertices(firstPoint)[1]; int firstPoint1 = firstPoint; firstLoop1.Add(firstPoint); if (vs.ConnectedTopologyVertices(ThirdPoint).Length == 2) { firstLoop1.Add(ThirdPoint); } else if (vs.ConnectedTopologyVertices(SecondPoint).Length == 2) { firstLoop1.Add(SecondPoint); } else { firstLoop1.Add(SecondPoint); for (int i = 0; i < vs.Count; i++) { bool stop = false; int[] index = vs.ConnectedTopologyVertices(SecondPoint); for (int j = 0; j < index.Length; j++) { if (index[j] != firstPoint1) { if (vs.ConnectedTopologyVertices(index[j]).Length == 3) { firstPoint1 = SecondPoint; SecondPoint = index[j]; firstLoop1.Add(SecondPoint); break; }//if if (vs.ConnectedTopologyVertices(index[j]).Length == 2) { firstPoint1 = SecondPoint; SecondPoint = index[j]; firstLoop1.Add(SecondPoint); stop = true; break; }//if } } if (stop) { break; } } } return("Done"); }
public string Mesh2Mesh(Mesh mesh, out Mesh s, double uscale, double vscale) { 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++) { //Print("j:" + j.ToString() + " k:" + k.ToString() + " energy: " + energy[index[k]].ToString());//////// energy[index[k]]++; } } //Print("///"); for (int j = 0; j < firstLoop1.Count; j++) { int[] index = vs.ConnectedTopologyVertices(firstLoop1[j]); for (int k = 0; k < index.Length; k++) { // Print("j:" + j.ToString() + " k:" + k.ToString() + " energy: " + energy[index[k]].ToString());//////// 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); } } List <Point3d> output1 = new List <Point3d>(); for (int i = 0; i < indexPt.Count; i++) { output1.Add(vs[indexPt[i]]); } // s = NurbsSurface.CreateFromPoints(output1, Column, firstLoop1.Count, 3, 3); s = mc.MeshFromPoints(output1, firstLoop1.Count, Column, uscale, vscale); return(str); }
public string Mesh2Topo(ref Mesh mesh, out Mesh mesh2, double length, double width, double mX, double mY, double maxX, double maxY) { // //construct a single bitmap but the edge is not fit well.The Vt has not been tested yet. // 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]; for (int i = 0; i < Column; i++) { for (int j = 0; j < firstLoop1.Count; j++) { output1.Add(vs[indexPt[iCount]]); int indexV = vs.MeshVertexIndices(indexPt[iCount])[0]; cl[iCount] = mesh.VertexColors[indexV]; iCount++; Point3d pt = new Point3d(length / MX * i, width / MY * (double)j, 0); output2.Add(pt); } } mesh2 = mc.MeshFromPoints(output2, firstLoop1.Count, Column); mesh = mc.MeshFromPoints(output1, firstLoop1.Count, Column); mesh2.Transform(Transform.Translation(mX, mY, 0)); mesh.VertexColors.Clear(); mesh.VertexColors.AppendColors(cl); mesh2.VertexColors.Clear(); mesh2.VertexColors.AppendColors(cl); iCount = 0; //Print(mesh.TextureCoordinates.Count.ToString());//unit=100 for (double i = 0; i < Column; i++) { for (double j = 0; j < firstLoop1.Count; j++) { //not tested mesh.TextureCoordinates.Add(new Point2f((Single)((i * length / MX + mX) / maxX), (Single)(j * width / MY + mY) / maxY)); mesh2.TextureCoordinates.Add(new Point2f((Single)((i * length / MX + mX) / maxX), (Single)(j * width / MY + mY) / maxY)); iCount++; } } return(str); }
/// 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); }
public Mesh Unfold(Mesh mesh) { List <face> Faces = new List <face>(); List <edge> Edges = new List <edge>(); mesh.Faces.ConvertQuadsToTriangles(); mesh.UnifyNormals(); mesh.Compact(); Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; mesh.FaceNormals.ComputeFaceNormals(); //Print(mesh.FaceNormals.Count.ToString()); // Print(mesh.Vertices.Count.ToString()); for (int i = 0; i < mesh.Faces.Count; i++) { face f1 = new face( new Point3d(mesh.Vertices[mesh.Faces[i].A]), new Point3d(mesh.Vertices[mesh.Faces[i].B]), new Point3d(mesh.Vertices[mesh.Faces[i].C]), mesh.FaceNormals[i] ); Faces.Add(f1); } for (int i = 0; i < el.Count; i++) { int[] faceid = el.GetConnectedFaces(i); edge e1 = new edge(vs[el.GetTopologyVertices(i).I], vs[el.GetTopologyVertices(i).J]); if (faceid.Length == 1) { e1.Faces = new face[1]; e1.Faces[0] = Faces[faceid[0]]; } else if (faceid.Length > 1) { e1.Faces = new face[2]; e1.Faces[0] = Faces[faceid[0]]; e1.Faces[1] = Faces[faceid[1]]; } e1.ID = i; Edges.Add(e1); } for (int i = 0; i < mesh.Faces.Count; i++) { int[] edgeid = el.GetEdgesForFace(i); face f1 = Faces[i]; f1.edges[0] = Edges[edgeid[0]]; f1.edges[1] = Edges[edgeid[1]]; f1.edges[2] = Edges[edgeid[2]]; f1.ID = i; } /* List< Mesh> output2 = new List< Mesh>(); * for (int i = 0; i < Faces.Count; i++) * { * output2.Add(Faces[i].DrawFace()); * } * B = output2; */ face f = Faces[0]; f.AddTransform(Transform.PlaneToPlane(new Plane(f.Center(), -f.Normal), Plane.WorldXY)); FaceLoop(f); //Print(f.Pts[0].X.ToString() + "/" + f.Pts[0].Y.ToString() + "/" + f.Pts[0].Z.ToString()); Mesh output = new Mesh(); for (int i = 0; i < Faces.Count; i++) { output.Append(Faces[i].DrawFace()); } return(output); }
public Mesh Catmull_Clark(Mesh x) { Mesh mesh = new Mesh(); List <Point3d> pv = new List <Point3d>(); List <Point3d> pe = new List <Point3d>(); List <Point3d> pf = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList el = x.TopologyEdges; for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); Point3d pf1 = new Point3d(); for (int j = 0; j < index.Length; j++) { pf1 += vs[index[j]]; } pf1 /= index.Length; pf.Add(pf1); } for (int i = 0; i < el.Count; i++) { IndexPair pair = el.GetTopologyVertices(i); Point3d pe1 = vs[pair.I] + vs[pair.J]; int[] index = el.GetConnectedFaces(i); if (index.Length == 2) { pe1 += pf[index[0]] + pf[index[1]]; pe1 /= 4.0; } else { pe1 = pe1 / 2.0; } pe.Add(pe1); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedEdges(i); int[] index2 = vs.ConnectedFaces(i); Point3d V = vs[i]; if (index.Length == index2.Length) { Point3d R = new Point3d(), Q = new Point3d(); for (int j = 0; j < index.Length; j++) { IndexPair pair = el.GetTopologyVertices(index[j]); Point3d pe1 = (vs[pair.I] + vs[pair.J]) * 0.5f; R += pe1; } R /= index.Length; for (int j = 0; j < index2.Length; j++) { Q += pf[index2[j]]; } Q /= index2.Length; int n = vs.ConnectedTopologyVertices(i).Length; V = Q + (R * 2) + V * (n - 3); V /= n; } else { Point3d R = new Point3d(); for (int j = 0; j < index.Length; j++) { if (el.GetConnectedFaces(index[j]).Length == 1) { IndexPair pair = el.GetTopologyVertices(index[j]); R += vs[pair.I] + vs[pair.J]; } } V = R * 0.125f + V * 0.5; } pv.Add(V); } mesh.Vertices.AddVertices(pv); mesh.Vertices.AddVertices(pe); mesh.Vertices.AddVertices(pf); for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); if (x.Faces[i].IsQuad) { int pc = pv.Count + pe.Count + i; int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p4 = index[3]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p34 = el.GetEdgeIndex(p3, p4) + pv.Count; int p41 = el.GetEdgeIndex(p4, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, pc, p41); mesh.Faces.AddFace(p12, p2, p23, pc); mesh.Faces.AddFace(pc, p23, p3, p34); mesh.Faces.AddFace(p41, pc, p34, p4); } else if (x.Faces[i].IsTriangle) { int pc = pv.Count + pe.Count + i; int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p31 = el.GetEdgeIndex(p3, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, pc, p31); mesh.Faces.AddFace(p12, p2, p23, pc); mesh.Faces.AddFace(pc, p23, p3, p31); } } mesh.UnifyNormals(); return(mesh); }
public Mesh Loop(Mesh x) { Mesh mesh = new Mesh(); x.Faces.ConvertQuadsToTriangles(); List <Point3d> pv = new List <Point3d>(); List <Point3d> pe = new List <Point3d>(); Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices; Rhino.Geometry.Collections.MeshTopologyEdgeList el = x.TopologyEdges; for (int i = 0; i < el.Count; i++) { IndexPair pair = el.GetTopologyVertices(i); Point3d pe1 = (vs[pair.I] + vs[pair.J]); int[] index = el.GetConnectedFaces(i); if (index.Length == 2) { int[] index1 = vs.IndicesFromFace(index[0]); int[] index2 = vs.IndicesFromFace(index[1]); pe1 += vs[index1[0]] + vs[index1[1]] + vs[index1[2]]; pe1 += vs[index2[0]] + vs[index2[1]] + vs[index2[2]]; pe1 /= 8.0; } else { pe1 = pe1 / 2.0; } pe.Add(pe1); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedEdges(i); int[] index2 = vs.ConnectedFaces(i); Point3d V = vs[i]; if (index.Length == index2.Length) { Point3d R = new Point3d(); double n = (double)index.Length; double u = Math.Pow(0.375 + 0.25 * Math.Cos(Math.PI * 2.0 / n), 2); u = (0.625 - u) / n; for (int j = 0; j < index.Length; j++) { IndexPair pair = el.GetTopologyVertices(index[j]); R += (vs[pair.I] + vs[pair.J] - V); } V = V * (1 - n * u) + R * u; } else { Point3d R = new Point3d(); for (int j = 0; j < index.Length; j++) { if (el.GetConnectedFaces(index[j]).Length == 1) { IndexPair pair = el.GetTopologyVertices(index[j]); R += vs[pair.I] + vs[pair.J]; } } V = R * 0.125f + V * 0.5; } pv.Add(V); } mesh.Vertices.AddVertices(pv); mesh.Vertices.AddVertices(pe); for (int i = 0; i < x.Faces.Count; i++) { int[] index = vs.IndicesFromFace(i); int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p12 = el.GetEdgeIndex(p1, p2) + pv.Count; int p23 = el.GetEdgeIndex(p2, p3) + pv.Count; int p31 = el.GetEdgeIndex(p3, p1) + pv.Count; mesh.Faces.AddFace(p1, p12, p31); mesh.Faces.AddFace(p31, p12, p23); mesh.Faces.AddFace(p3, p31, p23); mesh.Faces.AddFace(p2, p23, p12); } mesh.UnifyNormals(); return(mesh); }
private List <MeshSimplify_Point> preDivide(Mesh mesh) { Rhino.Geometry.Collections.MeshTopologyEdgeList el = mesh.TopologyEdges; Rhino.Geometry.Collections.MeshTopologyVertexList vs = mesh.TopologyVertices; List <MeshSimplify_Point> PointList = new List <MeshSimplify_Point>(); for (int i = 0; i < vs.Count; i++) { MeshSimplify_Point pt = new MeshSimplify_Point(vs[i]); if (vs.MeshVertexIndices(i).Length > 0) { pt.N = mesh.Normals[vs.MeshVertexIndices(i)[0]]; } else { pt.computeNormal(mesh); } PointList.Add(pt); } for (int i = 0; i < vs.Count; i++) { int[] index = vs.ConnectedTopologyVertices(i); for (int j = 0; j < index.Length; j++) { PointList[i].refpoints.Add(PointList[index[j]]); } PointList[i].Sort(); } ///////////////////////////////////////////////////// for (int i = 0; i < vs.Count; i++) { PointList[i].order = 0; } for (int i = 0; i < el.Count; i++) { if (el.GetConnectedFaces(i).Length == 1) { PointList[el.GetTopologyVertices(i).I].order = 5; PointList[el.GetTopologyVertices(i).J].order = 5; } } for (int i = 0; i < vs.Count; i++) { if (PointList[i].order == 5) { if (PointList[i].refpoints.Count != 3) { PointList[i].order = 4; } } else { if (PointList[i].refpoints.Count != 4) { PointList[i].order = 4; } } } ////////////////////////////////////////////////////////// for (int k = 0; k < PointList.Count; k++) { bool sign = true; for (int i = 0; i < PointList.Count; i++) { if (PointList[i].order == 4) { sign = false; PointList[i].order++; if (PointList[i].refpoints.Count == 4) { if (PointList[i].refpoints[0].order == 5 && PointList[i].refpoints[2].order != 5) { PointList[i].refpoints[2].order = 1; } if (PointList[i].refpoints[1].order == 5 && PointList[i].refpoints[3].order != 5) { PointList[i].refpoints[3].order = 1; } if (PointList[i].refpoints[2].order == 5 && PointList[i].refpoints[0].order != 5) { PointList[i].refpoints[0].order = 1; } if (PointList[i].refpoints[3].order == 5 && PointList[i].refpoints[1].order != 5) { PointList[i].refpoints[1].order = 1; } } else { for (int j = 0; j < PointList[i].refpoints.Count; j++) { PointList[i].refpoints[j].order++; } } } } for (int i = 0; i < PointList.Count; i++) { if (PointList[i].order > 0 && PointList[i].order < 4) { PointList[i].order = 4; } } if (sign) { break; } } return(PointList); }