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 void Load(IMesh mesh, string filePath) { var dxfLoad = DxfDocument.Load(filePath); var vertices = new List <IVertex>(); var faces = new List <IFace>(); var verticesIndexMap = new Dictionary <IVertex, int>(); int currentVertexIndex = 0; foreach (var face3D in dxfLoad.Faces3d) { var v1 = face3D.FirstVertex; var v2 = face3D.SecondVertex; var v3 = face3D.ThirdVertex; var v4 = face3D.FourthVertex; currentVertexIndex = CreateTriangleFace(v1, v2, v3, verticesIndexMap, currentVertexIndex, vertices, faces); currentVertexIndex = CreateTriangleFace(v3, v4, v1, verticesIndexMap, currentVertexIndex, vertices, faces); } foreach (var vertex in vertices) { mesh.AddVertex(vertex); } foreach (var face in faces) { mesh.AddFace(face); } }
public void Load(IMesh mesh, string filePath) { var dxfLoad = DxfDocument.Load(filePath); var vertices = new List<IVertex>(); var faces = new List<IFace>(); var verticesIndexMap = new Dictionary<IVertex, int>(); int currentVertexIndex = 0; foreach (var face3D in dxfLoad.Faces3d) { var v1 = face3D.FirstVertex; var v2 = face3D.SecondVertex; var v3 = face3D.ThirdVertex; var v4 = face3D.FourthVertex; currentVertexIndex = CreateTriangleFace(v1, v2, v3, verticesIndexMap, currentVertexIndex, vertices, faces); currentVertexIndex = CreateTriangleFace(v3, v4, v1, verticesIndexMap, currentVertexIndex, vertices, faces); } foreach (var vertex in vertices) { mesh.AddVertex(vertex); } foreach (var face in faces) { mesh.AddFace(face); } }
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 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 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); } }
private void Load(TextReader textReader, IMesh mesh) { var vertices = new List<IVertex>(); var faces = new List<IFace>(); var verticesIndexMap = new Dictionary<IVertex, int>(); int currentVertexIndex = 0; var positions = new List<Vector3>(); var normals = new List<Vector3>(); var texCoords = new List<Vector3>(); string line; while ((line = textReader.ReadLine()) != null) { line = line.Trim(_splitCharacters); line = line.Replace(" ", " "); var parameters = line.Split(_splitCharacters); switch (parameters[0]) { case "p": // Point break; case "v": // Vertex var x = float.Parse(parameters[1], CultureInfo.InvariantCulture); var y = float.Parse(parameters[2], CultureInfo.InvariantCulture); var z = float.Parse(parameters[3], CultureInfo.InvariantCulture); positions.Add(new Vector3(x, y, z)); break; case "vt": // TexCoord var u = float.Parse(parameters[1], CultureInfo.InvariantCulture); var v = float.Parse(parameters[2], CultureInfo.InvariantCulture); texCoords.Add(new Vector3(u, v, 0)); break; case "vn": // Normal var nx = float.Parse(parameters[1], CultureInfo.InvariantCulture); var ny = float.Parse(parameters[2], CultureInfo.InvariantCulture); var nz = float.Parse(parameters[3], CultureInfo.InvariantCulture); normals.Add(new Vector3(nx, ny, nz).Normalized()); break; case "f": var faceVertexIndices = new List<int>(); for (int i = 0; i < parameters.Length - 1; i++) { //The definition of what is a vertex in an OBJ file only exists appears when the vertex of each face is being defined //We only want to add distinctive vertices to our list of vertices, so we test here if we already have a vertex with the same //parameters, in which case we will use the existing vertex, if not we will add the new vertex to our list and increase the vertex //index counter var candidateVertex = GetVertex(parameters[i + 1], positions, normals, texCoords); if (!verticesIndexMap.ContainsKey(candidateVertex)) { verticesIndexMap.Add(candidateVertex, currentVertexIndex); vertices.Add(candidateVertex); currentVertexIndex++; } var index = verticesIndexMap[candidateVertex]; faceVertexIndices.Add(index); } var face = _faceFactory.CreateFace(faceVertexIndices); faces.Add(face); break; } } foreach (var vertex in vertices) { mesh.AddVertex(vertex); } foreach (var face in faces) { mesh.AddFace(face); } }
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); }
private void Load(TextReader textReader, IMesh mesh) { var vertices = new List <IVertex>(); var faces = new List <IFace>(); var verticesIndexMap = new Dictionary <IVertex, int>(); int currentVertexIndex = 0; var positions = new List <Vector3>(); var normals = new List <Vector3>(); var texCoords = new List <Vector3>(); string line; while ((line = textReader.ReadLine()) != null) { line = line.Trim(_splitCharacters); line = line.Replace(" ", " "); var parameters = line.Split(_splitCharacters); switch (parameters[0]) { case "p": // Point break; case "v": // Vertex var x = float.Parse(parameters[1], CultureInfo.InvariantCulture); var y = float.Parse(parameters[2], CultureInfo.InvariantCulture); var z = float.Parse(parameters[3], CultureInfo.InvariantCulture); positions.Add(new Vector3(x, y, z)); break; case "vt": // TexCoord var u = float.Parse(parameters[1], CultureInfo.InvariantCulture); var v = float.Parse(parameters[2], CultureInfo.InvariantCulture); texCoords.Add(new Vector3(u, v, 0)); break; case "vn": // Normal var nx = float.Parse(parameters[1], CultureInfo.InvariantCulture); var ny = float.Parse(parameters[2], CultureInfo.InvariantCulture); var nz = float.Parse(parameters[3], CultureInfo.InvariantCulture); normals.Add(new Vector3(nx, ny, nz).Normalized()); break; case "f": var faceVertexIndices = new List <int>(); for (int i = 0; i < parameters.Length - 1; i++) { //The definition of what is a vertex in an OBJ file only exists appears when the vertex of each face is being defined //We only want to add distinctive vertices to our list of vertices, so we test here if we already have a vertex with the same //parameters, in which case we will use the existing vertex, if not we will add the new vertex to our list and increase the vertex //index counter var candidateVertex = GetVertex(parameters[i + 1], positions, normals, texCoords); if (!verticesIndexMap.ContainsKey(candidateVertex)) { verticesIndexMap.Add(candidateVertex, currentVertexIndex); vertices.Add(candidateVertex); currentVertexIndex++; } var index = verticesIndexMap[candidateVertex]; faceVertexIndices.Add(index); } var face = _faceFactory.CreateFace(faceVertexIndices); faces.Add(face); break; } } foreach (var vertex in vertices) { mesh.AddVertex(vertex); } foreach (var face in faces) { mesh.AddFace(face); } }