public static IMesh Triangulate2DElements(IMesh mesh) { IMesh triangulated = new IMesh(); foreach (ITopologicVertex v in mesh.Vertices) { triangulated.AddVertex(v.Key, new ITopologicVertex(v)); } ISurfaceElement face; int key = mesh.FindNextVertexKey(); foreach (IElement e in mesh.Elements) { if (e.TopologicDimension == 2) { if (e.VerticesCount == 3) { face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[2]); triangulated.AddElement(face); } else if (e.VerticesCount == 4) { face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[3]); triangulated.AddElement(face); face = new ISurfaceElement(e.Vertices[3], e.Vertices[1], e.Vertices[2]); triangulated.AddElement(face); } else { IPoint3D pos = ISubdividor.ComputeAveragePosition(e.Vertices, mesh); ITopologicVertex v = new ITopologicVertex(pos.X, pos.Y, pos.Z, key); triangulated.AddVertex(key, v); for (int i = 1; i <= e.HalfFacetsCount; i++) { int[] hf; e.GetHalfFacet(i, out hf); face = new ISurfaceElement(hf[0], hf[1], key); triangulated.AddElement(face); } key++; } } } triangulated.BuildTopology(); return(triangulated); }
/// <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) { ITopologicVertex vertex = new ITopologicVertex(); DA.GetData(0, ref vertex); Point3d position = new Point3d(vertex.X, vertex.Y, vertex.Z); Point3d uvw = new Point3d(vertex.U, vertex.V, vertex.W); DA.SetData(0, vertex.Key); DA.SetData(1, position); DA.SetData(2, uvw); DA.SetData(3, vertex.GetElementID()); DA.SetData(4, vertex.GetHalfFacetID()); }
/// <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) { Point3d pt = new Point3d(); double u = 0, v = 0, w = 0; int key = -1; DA.GetData(0, ref pt); DA.GetData(1, ref key); DA.GetData(2, ref u); DA.GetData(2, ref v); DA.GetData(2, ref w); ITopologicVertex vertex = new ITopologicVertex(pt.X, pt.Y, pt.Z, u, v, w, key); DA.SetData(0, vertex); }
public static IMesh ExtrudeTwoDimensionalElements(IMesh mesh, IEnumerable <int> eKeys, double length) { IMesh dM = mesh.CleanCopy(); ITopologicVertex v, vv; IVector3D n, pos; IElement e, nE; int next_vKey = mesh.FindNextVertexKey(); foreach (int eK in eKeys) { e = mesh.GetElementWithKey(eK); if (e.TopologicDimension == 2) { dM.DeleteElement(eK, false); nE = null; mesh.Topology.ComputeTwoDimensionalElementNormal(eK, out n, out pos); n *= length; List <int> vertices = new List <int>(e.Vertices); foreach (int vK in e.Vertices) { v = mesh.GetVertexWithKey(vK); vv = new ITopologicVertex(v.Position + n, next_vKey); dM.AddVertex(next_vKey, vv); vertices.Add(next_vKey); next_vKey++; } if (vertices.Count == 8) { nE = new IHexahedronElement(vertices.ToArray()); } else if (vertices.Count == 6) { nE = new IPrismElement(vertices.ToArray()); } if (nE != null) { dM.AddElement(nE); } } } dM.BuildTopology(true); return(dM); }
public bool BuildDataBase() { if (vertices != null) { Boolean flag = false; if (rhinoMesh.TextureCoordinates.Count == rhinoMesh.Vertices.Count) { flag = true; } Point2f uvw = new Point2f(0, 0); for (int i = 0; i < rhinoMesh.Vertices.Count; i++) { if (flag) { uvw = rhinoMesh.TextureCoordinates[i]; } ITopologicVertex v = new ITopologicVertex(rhinoMesh.Vertices[i]); v.Key = i + 1; v.TextureCoordinates = new double[] { uvw.X, uvw.Y, 0 }; vertices.Add(v); } foreach (MeshFace f in rhinoMesh.Faces) { ISurfaceElement iF = new ISurfaceElement(vertices[f.A].Key, vertices[f.B].Key, vertices[f.C].Key); if (f.IsQuad) { iF = new ISurfaceElement(vertices[f.A].Key, vertices[f.B].Key, vertices[f.C].Key, vertices[f.D].Key); } iF.Key = keyElement; faces.Add(iF); keyElement++; } return(true); } else { return(false); } }
/// <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) { IMesh mesh = new IMesh(); Vector3d vec = new Vector3d(); int vKey = 0; DA.GetData(0, ref mesh); DA.GetData(1, ref vKey); DA.GetData(2, ref vec); IMesh dM = mesh.DeepCopy(); ITopologicVertex v = dM.GetVertexWithKey(vKey); dM.SetVertexPosition(vKey, v.Position + new IVector3D(vec.X, vec.Y, vec.Z)); DA.SetData(0, dM); }
internal static IPoint3D ComputeLoopVertexPosition(IMesh m, int vKey) { ITopologicVertex v = m.GetVertexWithKey(vKey); int[] vN = m.Topology.GetVertexAdjacentVertices(vKey); IPoint3D pos = v.Position; IVector3D vec = new IVector3D(); if (!m.Topology.IsNakedVertex(vKey)) { int n = vN.Length; double coef = (3.0 / 16.0) * n; if (n > 3) { coef = (3.0 / (8.0 * n)) * n; } vec = pos * (1 - coef); vec += (ComputeAveragePosition(vN, m) * coef); } else { int count = 0; foreach (int nKey in vN) { if (m.Topology.IsNakedEdge(nKey, vKey)) { vec += ComputeAveragePosition(ComputeAveragePosition(new[] { vKey, nKey }, m), v.Position); count++; } } vec /= count; } return(new IPoint3D(vec.X, vec.Y, vec.Z)); }
public IMesh ApplyModifier(IMesh mesh) { if (mesh != null) { this.init(mesh); IMesh nMesh = new IMesh(); for (int iter = 0; iter < MaxInterations; iter++) { for (int i = 0; i < count; i++) { //Laplacian calculation double dxA = 0.0; double dxB = 0.0; int vK = mesh.VerticesKeys[i]; int[] vStart = mesh.Topology.GetVertexAdjacentVertices(vK); for (int j = 0; j < vStart.Length; j++) { int idx = vStart[j]; dxA += coef[i][j] * (A[idx] - A[i]) / vStart.Length; dxB += coef[i][j] * (B[idx] - B[i]) / vStart.Length; } //Reaction-diffusion equation double AB2 = A[i] * B[i] * B[i]; nextA[i] = A[i] + (DiffusionRateA * dxA - AB2 + FeedFactor * (1 - A[i])) * TimeStep; nextB[i] = B[i] + (DiffusionRateB * dxB + AB2 - (KillFactor + FeedFactor) * B[i]) * TimeStep; } for (int i = 0; i < count; i++) { A[i] = Math.Min(Math.Max(nextA[i], 0.0), 1.0); B[i] = Math.Min(Math.Max(nextB[i], 0.0), 1.0); } } for (int i = 0; i < count; i++) { int vK = mesh.VerticesKeys[i]; ITopologicVertex vertex = mesh.GetVertexWithKey(vK); double param = (A[i] - B[i]); IVector3D n = mesh.Topology.ComputeVertexNormal(vK); n *= (A[i] - B[i]); vertex.Position += n; nMesh.AddVertex(vK, vertex); } nMesh.AddRangeElements(mesh.Elements); nMesh.BuildTopology(); return(nMesh); } else { return(null); } }
public static IMesh CatmullClark(IMesh mesh) { IMesh sMesh = new IMesh(); //Old vertices foreach (int vK in mesh.VerticesKeys) { sMesh.AddVertex(vK, new ITopologicVertex(ComputesCatmullClarkVertexPosition(mesh, vK))); } // Subidvision int key = mesh.FindNextVertexKey(); int[] hf; IElement element_sibling; int elementID_sibling, halfFacetID_sibling; Boolean visited; Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>(); Dictionary <int, int> fVertex = new Dictionary <int, int>(); IPoint3D pos; int count = mesh.ElementsKeys.Count; // Vertices foreach (int elementID in mesh.ElementsKeys) { IElement e = mesh.GetElementWithKey(elementID); //Add face vertex pos = ComputeAveragePosition(e.Vertices, mesh); sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key)); fVertex.Add(elementID, key); key++; if (!e.Visited) { if (e.TopologicDimension == 2) { if (!eVertex.ContainsKey(elementID)) { eVertex.Add(elementID, new int[e.HalfFacetsCount]); } for (int halfFacetID = 1; halfFacetID <= e.HalfFacetsCount; halfFacetID++) { e.GetHalfFacet(halfFacetID, out hf); visited = e.IsHalfFacetVisited(halfFacetID); if (!visited) { e.RegisterHalfFacetVisit(halfFacetID); e.GetHalfFacet(halfFacetID, out hf); pos = ComputeAveragePosition(hf, mesh); sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key)); eVertex[elementID][halfFacetID - 1] = key; if (!e.IsNakedSiblingHalfFacet(halfFacetID)) { while (!visited) { e.RegisterHalfFacetVisit(halfFacetID); //Collect information of siblings elementID_sibling = e.GetSiblingElementID(halfFacetID); halfFacetID_sibling = e.GetSiblingHalfFacetID(halfFacetID); element_sibling = mesh.GetElementWithKey(elementID_sibling); visited = element_sibling.IsHalfFacetVisited(halfFacetID_sibling); halfFacetID = halfFacetID_sibling; e = element_sibling; if (!eVertex.ContainsKey(elementID_sibling)) { eVertex.Add(elementID_sibling, new int[e.HalfFacetsCount]); } eVertex[elementID_sibling][halfFacetID - 1] = key; } } key++; } } } } } mesh.CleanElementsVisits(); //Faces int prev; int[] data; foreach (int elementID in mesh.ElementsKeys) { IElement e = mesh.GetElementWithKey(elementID); if (e.TopologicDimension == 2) { int[] eV = eVertex[elementID]; for (int i = 0; i < e.Vertices.Length; i++) { prev = i - 1; if (prev < 0) { prev = e.Vertices.Length - 1; } data = new int[] { e.Vertices[i], eV[prev], fVertex[elementID], eV[i] }; ISurfaceElement face = new ISurfaceElement(data); sMesh.AddElement(face); } } } // Edge Vertex foreach (int eK in eVertex.Keys) { IElement e = mesh.GetElementWithKey(eK); for (int i = 1; i <= e.HalfFacetsCount; i++) { int[] hf1; e.GetHalfFacet(i, out hf1); ITopologicVertex v1 = sMesh.GetVertexWithKey(eVertex[eK][i - 1]); v1.Position = ComputeCatmullClarkEdgeVertexPosition(hf1, mesh); sMesh.SetVertex(v1.Key, v1); } } //Build Mesh sMesh.BuildTopology(); return(sMesh); }
public Boolean BuildDataBase() { if (U == 0 || V == 0) { return(false); } else { vertices = new ITopologicVertex[((U + 1) * V) * 2]; int keyNode = 1; // outer vertices //Plane old = new Plane(); for (int i = 0; i <= U; i++) { double z = (i * height) / U; if (path != null) { Point3d origin = path.PointAt(i); int idx = i + 1; if (i == U) { idx = i - 1; } Point3d next = path.PointAt(idx); Vector3d vec = next - origin; if (i == U) { vec.Reverse(); } Plane pl = new Plane(origin, vec); /*if (i == 0) old = pl; * else * { * pl.Transform(Transform.PlaneToPlane(pl, old)); * old = pl; * }*/ for (int j = 0; j < V; j++) { double x = outerRadius * Math.Cos(((2 * Math.PI) / V) * j); double y = outerRadius * Math.Sin(((2 * Math.PI) / V) * j); Point3d pt = pl.PointAt(x, y); vertices[j + (i * V)] = new ITopologicVertex(pt.X, pt.Y, pt.Z, keyNode); keyNode++; } } else { for (int j = 0; j < V; j++) { vertices[j + (i * V)].X = outerRadius * Math.Cos(((2 * Math.PI) / V) * j); vertices[j + (i * V)].Y = outerRadius * Math.Sin(((2 * Math.PI) / V) * j); vertices[j + (i * V)].Z = z; } } } // inner vertices for (int i = U; i >= 0; i--) { double z = (i * height) / U; if (path != null) { Point3d origin = path.PointAt(i); int idx = i - 1; if (i == 0) { idx = i + 1; } Point3d next = path.PointAt(idx); Vector3d vec = origin - next; if (i == 0) { vec.Reverse(); } Plane pl = new Plane(origin, vec); for (int j = 0; j < V; j++) { double x = shiftX + (innerRadius * Math.Cos(((2 * Math.PI) / V) * j)); double y = shiftY + (innerRadius * Math.Sin(((2 * Math.PI) / V) * j)); Point3d pt = pl.PointAt(x, y); vertices[j + (i * V) + ((U + 1) * V)] = new ITopologicVertex(pt.X, pt.Y, pt.Z, keyNode); keyNode++; } } else { for (int j = 0; j < V; j++) { vertices[(j + (i * V) + ((U + 1) * V))].X = shiftX + (innerRadius * Math.Cos(((2 * Math.PI) / V) * j)); vertices[(j + (i * V) + ((U + 1) * V))].Y = shiftY + (innerRadius * Math.Sin(((2 * Math.PI) / V) * j)); vertices[(j + (i * V) + ((U + 1) * V))].Z = z; } } } faces = new int[(U * V * 2) + (V * 2)][]; for (int j = 0; j < V; j++) { // outer faces for (int i = 0; i < U; i++) { faces[j + (i * V)] = new int[4]; faces[j + (i * V)][0] = vertices[((j + 1) % V) + (i * V)].Key; faces[j + (i * V)][1] = vertices[((j + 1) % V) + V + (i * V)].Key; faces[j + (i * V)][2] = vertices[j + (i * V) + V].Key; faces[j + (i * V)][3] = vertices[j + (i * V)].Key; } // top faces if (j != (V - 1)) { faces[j + (U * V)] = new int[4]; faces[j + (U * V)][0] = vertices[j + (U * V) + V].Key; faces[j + (U * V)][1] = vertices[j + 1 + (U * V) + V].Key; faces[j + (U * V)][2] = vertices[j + 1].Key; faces[j + (U * V)][3] = vertices[j].Key; } else { faces[j + (U * V)] = new int[4]; faces[j + (U * V)][0] = vertices[j + (U * V) + V].Key; faces[j + (U * V)][1] = vertices[(U * V) + V].Key; faces[j + (U * V)][2] = vertices[0].Key; faces[j + (U * V)][3] = vertices[j].Key; } // inner faces for (int i = 0; i < U; i++) { faces[(j + (i * V)) + (U * V) + V] = new int[4]; faces[(j + (i * V)) + (U * V) + V][0] = vertices[(j + (i * V)) + (U * V) + V].Key; faces[(j + (i * V)) + (U * V) + V][1] = vertices[(j + (i * V) + V) + (U * V) + V].Key; faces[(j + (i * V)) + (U * V) + V][2] = vertices[(((j + 1) % V) + V + (i * V)) + (U * V) + V].Key; faces[(j + (i * V)) + (U * V) + V][3] = vertices[(((j + 1) % V) + (i * V)) + (U * V) + V].Key; } // bottom faces if (j != (V - 1)) { faces[j + (2 * (U * V)) + V] = new int[4]; faces[j + (2 * (U * V)) + V][0] = vertices[j + (U * V)].Key; faces[j + (2 * (U * V)) + V][1] = vertices[j + 1 + (U * V)].Key; faces[j + (2 * (U * V)) + V][2] = vertices[j + 1 + (U * V) + V + (U * V)].Key; faces[j + (2 * (U * V)) + V][3] = vertices[j + (U * V) + V + (U * V)].Key; } else { faces[j + (2 * (U * V)) + V] = new int[4]; faces[j + (2 * (U * V)) + V][0] = vertices[j + (U * V)].Key; faces[j + (2 * (U * V)) + V][1] = vertices[(V * U)].Key; faces[j + (2 * (U * V)) + V][2] = vertices[vertices.Length - 1 - j].Key; faces[j + (2 * (U * V)) + V][3] = vertices[vertices.Length - 1].Key; } } return(true); } }