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); }
public static IMesh ExtrudeTwoDimensionalElementsEdges(IMesh mesh, IEnumerable <int> eKeys, double length) { IMesh dM = mesh.CleanCopy(); ITopologicVertex v, vv; IVector3D n; IElement e, nE; int next_vKey = mesh.FindNextVertexKey(); int next_eKey = mesh.FindNextElementKey(); foreach (int eK in eKeys) { e = mesh.GetElementWithKey(eK); if (e.TopologicDimension == 2) { List <int> vertices = new List <int>(); foreach (int vK in e.Vertices) { v = mesh.GetVertexWithKey(vK); n = mesh.Topology.ComputeVertexNormal(vK); vv = new ITopologicVertex(v.Position + n, next_vKey); dM.AddVertex(next_vKey, vv); vertices.Add(next_vKey); next_vKey++; } int[] hf; List <int> temp; int next_i, prev_i; for (int i = 1; i <= e.HalfFacetsCount; i++) { e.GetHalfFacet(i, out hf); temp = new List <int>(hf); next_i = i; if (i == e.HalfFacetsCount) { next_i = 0; } prev_i = i - 1; temp.Add(vertices[next_i]); temp.Add(vertices[prev_i]); nE = new ISurfaceElement(temp.ToArray()); dM.AddElement(nE); } } } dM.BuildTopology(true); return(dM); }
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 IMesh BuildMesh() { IMesh mesh = new IMesh(); Boolean flag = BuildDataBase(); if (flag) { mesh = new IMesh(); mesh.AddRangeVertices(vertices.ToList()); foreach (int[] f in faces) { mesh.AddElement(new ISurfaceElement(f[0], f[1], f[2], f[3])); } mesh.BuildTopology(); } return(mesh); }
public static IMesh DualMesh(IMesh mesh) { IMesh nM = new IMesh(); // Face center points foreach (IElement e in mesh.Elements) { nM.AddVertex(e.Key, new ITopologicVertex(ISubdividor.ComputeAveragePosition(e.Vertices, mesh))); } int[] data1, data2; PointCloud cloud = new PointCloud(); List <int> global = new List <int>(); int vertexKey = nM.FindNextVertexKey(); foreach (ITopologicVertex v in mesh.Vertices) { data1 = mesh.Topology.GetVertexIncidentElementsSorted(v.Key); if (!mesh.Topology.IsNakedVertex(v.Key)) { nM.AddElement(new ISurfaceElement(data1)); } else { List <int> local = new List <int>(); data2 = mesh.Topology.GetVertexAdjacentVerticesSorted(v.Key); bool flag = false; foreach (int vv in data2) { if (mesh.Topology.IsNakedEdge(vv, v.Key)) { Point3d p = ISubdividor.ComputeAveragePoint(new[] { vv, v.Key }, mesh); int idx = cloud.ClosestPoint(p); if (idx == -1) { flag = true; } else { if (p.DistanceTo(cloud[idx].Location) > 0.01) { flag = true; } else { flag = false; } } if (flag) { cloud.Add(p); nM.AddVertex(vertexKey, new ITopologicVertex(p)); global.Add(vertexKey); local.Add(vertexKey); vertexKey++; } else { local.Add(global[idx]); } } } nM.AddVertex(vertexKey, new ITopologicVertex(v)); local.Insert(1, vertexKey); local.AddRange(data1.Reverse()); vertexKey++; nM.AddElement(new ISurfaceElement(local.ToArray())); } } nM.BuildTopology(true); return(nM); }
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 static IMesh Loop(IMesh mesh) { IMesh triMesh = IModifier.Triangulate2DElements(mesh); IMesh sMesh = new IMesh(); //Old vertices foreach (int vK in triMesh.VerticesKeys) { sMesh.AddVertex(vK, new ITopologicVertex(ComputeLoopVertexPosition(triMesh, vK))); } // Subidvision int key = triMesh.FindNextVertexKey(); int[] hf; IElement element_sibling; int elementID_sibling, halfFacetID_sibling; Boolean visited; Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>(); // Vertices foreach (int elementID in triMesh.ElementsKeys) { IElement e = triMesh.GetElementWithKey(elementID); 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); sMesh.AddVertex(key, new ITopologicVertex(ComputeAveragePosition(hf, triMesh))); 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 = triMesh.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++; } } } } } triMesh.CleanElementsVisits(); //Faces int prev; foreach (int elementID in triMesh.ElementsKeys) { IElement e = triMesh.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; } sMesh.AddElement(new ISurfaceElement(new[] { eV[prev], e.Vertices[i], eV[i] })); } sMesh.AddElement(new ISurfaceElement(new[] { eV[0], eV[1], eV[2] })); } } // Edge Vertex foreach (int eK in eVertex.Keys) { IElement e = triMesh.GetElementWithKey(eK); for (int i = 1; i <= e.HalfFacetsCount; i++) { e.GetHalfFacet(i, out hf); int vK = eVertex[eK][i - 1]; sMesh.SetVertexPosition(vK, ComputeLoopEdgeVertexPosition(hf, triMesh)); } } //Build Mesh sMesh.BuildTopology(); return(sMesh); }
public static HashSet <int> TryParseToIguanaElement(int elementType, long[] nodes, int nodes_per_element, int number_of_elements, ref HashSet <int> parsedNodes, ref IMesh mesh) { if (IsElementImplemented(elementType)) { for (int j = 0; j < number_of_elements; j++) { int[] eD = new int[nodes_per_element]; IElement e = null; for (int k = 0; k < nodes_per_element; k++) { eD[k] = (int)nodes[j * nodes_per_element + k]; parsedNodes.Add(eD[k]); } switch (elementType) { //1st-order Triangle Face case 2: e = new ISurfaceElement(eD); break; //1st-order Quadrangle Face case 3: e = new ISurfaceElement(eD); break; //2nd-order 6-node triangle case 9: e = new ISurfaceElement.HighOrder.ITriangle6(eD); break; //2nd-order 9-node quadrangle case 10: e = new ISurfaceElement.HighOrder.IQuadrangle9(eD); break; //2nd-order 8-node quadrangle case 16: e = new ISurfaceElement.HighOrder.IQuadrangle8(eD); break; //3rd-order 9-node incomplete triangle case 20: e = new ISurfaceElement.HighOrder.ITriangle9(eD); break; //4th-order 12-node incomplete triangle case 22: e = new ISurfaceElement.HighOrder.ITriangle12(eD); break; //5th-order 15-node incomplete triangle case 24: e = new ISurfaceElement.HighOrder.ITriangle15(eD); break; //2nd-order 10-node tetrahedron case 11: e = new ITetrahedronElement.HighOrder.ITetrahedron10(eD); break; //1s-order 4-node tetrahedron element case 4: e = new ITetrahedronElement(eD); break; //2n-order 13-node pyramid case 19: e = new IPyramidElement.HighOrder.IPyramid13(eD); break; //1st-order 5-node pyramid element case 7: e = new IPyramidElement(eD); break; //1st-order 6-node prism element case 6: e = new IPrismElement(eD); break; //2nd-order 15-node prism case 18: e = new IPrismElement.HighOrder.IPrism15(eD); break; //1st-order 8-node hexahedron element case 5: e = new IHexahedronElement(eD); break; //2nd-order 20-node hexahedron case 17: e = new IHexahedronElement.HighOrder.IHexahedron20(eD); break; } if (e != null) { mesh.AddElement(e); } } } return(parsedNodes); }