public static TetgenMesh Tetrahedralize(TetgenMesh mesh, TetgenBehaviour Behaviour) { return(Tetrahedralize(mesh.Vertices, mesh.FaceIndices, mesh.FaceSizes, Behaviour)); }
public static TetgenMesh Tetrahedralize(double[] vertList, int[] faceIndexList, int[] faceSizesList, TetgenBehaviour beh) { TetgenMesh finalResult = null; unsafe { InteropMesh a = new InteropMesh(); InteropMesh *result = null; fixed(double *aVerts = &vertList[0]) { fixed(int *aFaces = &faceIndexList[0]) { fixed(int *aFSizes = &faceSizesList[0]) { a.numVertices = vertList.Length / 3; a.numFaceIndices = faceIndexList.Length; a.vertices = aVerts; a.faceIndices = aFaces; a.faceSizes = aFSizes; a.numFaces = faceSizesList.Length; System.Console.WriteLine(string.Format("Num verts: {0}", a.numVertices)); System.Console.WriteLine(string.Format("Num face indices: {0}", a.numFaceIndices)); System.Console.WriteLine(string.Format("Num faces: {0}", a.numFaces)); TetgenBehaviourUnsafe bu = new TetgenBehaviourUnsafe(); bu.plc = beh.plc; bu.quality = beh.quality; bu.optlevel = beh.optlevel; bu.optmaxdihedral = beh.optmaxdihedral; bu.optminslidihed = beh.optminslidihed; bu.optminsmtdihed = beh.optminsmtdihed; bu.coarsen = beh.coarsen; bu.maxvolume = beh.maxvolume; bu.minratio = beh.minratio; bu.mindihedral = beh.mindihedral; bu.insertaddpoints = beh.insertaddpoints; bu.refine = beh.refine; bu.supsteiner_level = beh.supsteiner_level; //try //{ result = performTetgen(&a, &bu); //} //catch (SEHException ex) //{ // System.Console.WriteLine(ex.Message); // System.Console.WriteLine(ex.StackTrace); // System.Console.ReadLine(); //ArgumentException e = new ArgumentException("Tetgen has thrown an error. Possible reason is corrupt or self-intersecting meshes", ex); //throw e; //} } } } if (result == null) { System.Console.WriteLine("Result is null."); return(null); } if (result->numVertices == 0) { freeMesh(result); return(null); } finalResult = new TetgenMesh(); finalResult.Vertices = new double[result->numVertices * 3]; finalResult.FaceIndices = new int[result->numFaceIndices]; finalResult.FaceSizes = new int[result->numFaces]; finalResult.TetraIndices = new int[result->numTetra * 4]; finalResult.EdgeIndices = new int[result->numEdges * 2]; if (result->numVertices > 0) { Parallel.For(0, finalResult.Vertices.Length, i => { finalResult.Vertices[i] = result->vertices[i]; }); } if (result->numFaceIndices > 0) { Parallel.For(0, finalResult.FaceIndices.Length, i => { finalResult.FaceIndices[i] = result->faceIndices[i]; }); } if (result->numFaces > 0) { Parallel.For(0, finalResult.FaceSizes.Length, i => { finalResult.FaceSizes[i] = result->faceSizes[i]; }); } if (result->numTetra > 0) { Parallel.For(0, finalResult.TetraIndices.Length, i => { finalResult.TetraIndices[i] = result->tetra[i]; }); } if (result->numEdges > 0) { Parallel.For(0, finalResult.EdgeIndices.Length, i => { finalResult.EdgeIndices[i] = result->edges[i]; }); } //freeMesh(result); } // end-unsafe return(finalResult); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> meshes = new List <Mesh>(); if (!DA.GetDataList("Mesh", meshes)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified."); return; } int flags = 1; DA.GetData("Flags", ref flags); double minratio = 2.0; DA.GetData("MinRatio", ref minratio); if (minratio <= 1.0) { minratio = 1.1; } TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour(); b.quality = 1; b.plc = 1; b.minratio = minratio; b.coarsen = 1; DataTree <int> indices = new DataTree <int>(); DataTree <GH_Mesh> meshes_out = new DataTree <GH_Mesh>(); DataTree <GH_Point> points_out = new DataTree <GH_Point>(); int N, index = 0; GH_Path path; for (int i = 0; i < meshes.Count; ++i) { TetgenMesh tin = TetgenRC.ExtensionMethods.ToTetgenMesh(meshes[i]); TetgenSharp.TetgenMesh tm = TetgenSharp.TetRhino.Tetrahedralize(tin, b); //path = new GH_Path(i); switch (flags) { case (0): meshes_out.AddRange(TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x)), new GH_Path(i, 0)); break; case (1): meshes_out.Add(new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)), new GH_Path(i, 0)); break; case (2): N = tm.TetraIndices.Length / 4; for (int j = 0; j < N; ++j) { path = new GH_Path(i, j); index = j * 4; indices.Add(tm.TetraIndices[index], path); indices.Add(tm.TetraIndices[index + 1], path); indices.Add(tm.TetraIndices[index + 2], path); indices.Add(tm.TetraIndices[index + 3], path); } points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0)); break; case (3): N = tm.EdgeIndices.Length / 2; for (int j = 0; j < N; ++j) { path = new GH_Path(i, j); index = j * 2; indices.Add(tm.EdgeIndices[index], path); indices.Add(tm.EdgeIndices[index + 1], path); } points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0)); break; default: break; } } DA.SetDataTree(MeshOutIndex, meshes_out); DA.SetDataTree(IndicesOutIndex, indices); DA.SetDataTree(PointsOutIndex, points_out); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> meshes = new List <Mesh>(); if (!DA.GetDataList("Mesh", meshes)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified."); return; } int flags = 1; DA.GetData("Flags", ref flags); double minratio = 2.0; DA.GetData("MinRatio", ref minratio); if (minratio <= 1.0) { minratio = 1.1; } double maxvolume = 2.0; DA.GetData("MaxVolume", ref maxvolume); int steiner = 0; DA.GetData("Steiner", ref steiner); int coarsen = 0; DA.GetData("Coarsen", ref coarsen); DataTree <int> indices = new DataTree <int>(); DataTree <GH_Mesh> meshes_out = new DataTree <GH_Mesh>(); DataTree <GH_Point> points_out = new DataTree <GH_Point>(); var face_indices = new DataTree <int>(); var verts_indices = new DataTree <int>(); int N, index = 0; GH_Path path; for (int i = 0; i < meshes.Count; ++i) { if (maxvolume > 0) { var vmp = VolumeMassProperties.Compute(meshes[i]); maxvolume = Math.Max(maxvolume, vmp.Volume / 100000); // Safety so as not to end up with too many elements... } TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour(); b.quality = 1; b.plc = 1; b.minratio = minratio; b.coarsen = coarsen; b.maxvolume = maxvolume; b.supsteiner_level = steiner; TetgenMesh tin = TetgenRC.ExtensionMethods.ToTetgenMesh(meshes[i]); TetgenSharp.TetgenMesh tm = TetgenSharp.TetRhino.Tetrahedralize(tin, b); //path = new GH_Path(i); if (tm == null) { this.Message = "Failed."; return; } switch (flags) { case (0): meshes_out.AddRange(TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x)), new GH_Path(i, 0)); break; case (1): meshes_out.Add(new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)), new GH_Path(i, 0)); break; case (2): N = tm.TetraIndices.Length / 4; for (int j = 0; j < N; ++j) { path = new GH_Path(i, j); index = j * 4; indices.Add(tm.TetraIndices[index], path); indices.Add(tm.TetraIndices[index + 1], path); indices.Add(tm.TetraIndices[index + 2], path); indices.Add(tm.TetraIndices[index + 3], path); } N = tm.FaceSizes.Length; int fi = 0; for (int j = 0; j < N; ++j) { var fpath = new GH_Path(i, j); for (int k = 0; k < tm.FaceSizes[j]; ++k) { face_indices.Add(tm.FaceIndices[fi], fpath); fi++; } } points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0)); break; case (3): N = tm.EdgeIndices.Length / 2; for (int j = 0; j < N; ++j) { path = new GH_Path(i, j); index = j * 2; indices.Add(tm.EdgeIndices[index], path); indices.Add(tm.EdgeIndices[index + 1], path); } points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0)); break; default: break; } } DA.SetDataTree(MeshOutIndex, meshes_out); DA.SetDataTree(IndicesOutIndex, indices); DA.SetDataTree(PointsOutIndex, points_out); DA.SetDataTree(FacesOutIndex, face_indices); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = new Mesh(); if (!DA.GetData("Mesh", ref mesh)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified."); return; } int flags = 1; DA.GetData("Flags", ref flags); double minratio = 2.0; DA.GetData("MinRatio", ref minratio); if (minratio <= 1.0) { minratio = 1.1; } TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour(); b.quality = 1; b.plc = 1; b.minratio = minratio; b.coarsen = 1; TetgenMesh tin = TetgenRC.ExtensionMethods.ToTetgenMesh(mesh); TetgenSharp.TetgenMesh tm = TetgenSharp.TetRhino.Tetrahedralize(tin, b); DataTree <int> indices; int N, index = 0; GH_Path path; switch (flags) { case (0): DA.SetDataList("Mesh", TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x))); break; case (1): DA.SetDataList("Mesh", new GH_Mesh[] { new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)) }); break; case (2): indices = new DataTree <int>(); N = tm.TetraIndices.Length / 4; DA.SetData("Length", N); //Ajout BH for (int i = 0; i < N; ++i) { path = new GH_Path(i); index = i * 4; indices.Add(tm.TetraIndices[index], path); indices.Add(tm.TetraIndices[index + 1], path); indices.Add(tm.TetraIndices[index + 2], path); indices.Add(tm.TetraIndices[index + 3], path); } DA.SetDataTree(1, indices); DA.SetDataList("Points", TetgenRC.ExtensionMethods.ToPointList(tm)); break; case (3): indices = new DataTree <int>(); N = tm.EdgeIndices.Length / 2; for (int i = 0; i < N; ++i) { path = new GH_Path(i); index = i * 2; indices.Add(tm.EdgeIndices[index], path); indices.Add(tm.EdgeIndices[index + 1], path); } DA.SetDataTree(1, indices); DA.SetDataList("Points", TetgenRC.ExtensionMethods.ToPointList(tm)); break; default: break; } }