internal static void test_MeshAutoRepair() { Console.Write("test_MeshAutoRepair..."); // b1 will has edges that are overlapping, but disconnected, it's the result of a merge // I guess autorepair should weld it back DMesh3 b1 = TestUtil.LoadTestInputMesh("NeedHealing.obj"); // b2 is the same mesh, but we weld it var b2 = new DMesh3(b1, true); MergeCoincidentEdges merg = new MergeCoincidentEdges(b2); merg.Apply(); MeshAutoRepair autoRepair = new MeshAutoRepair(b1); autoRepair.Apply(); var allOk = b1.VertexCount == b2.VertexCount && b1.EdgeCount == b2.EdgeCount && b1.TriangleCount == b2.TriangleCount; if (!allOk) { var outF = TestUtil.WriteTestOutputMesh(b1, "MeshOps_MeshAutoRepair.obj"); Console.WriteLine($"Error, shape written to: {outF}"); } else { Console.WriteLine("Ok"); } }
public static void test_repair_1() { string filename = "swat.obj"; //string filename = "chainsaw.obj"; DMesh3 mesh = TestUtil.LoadTestInputMesh(filename); MeshAutoRepair repair = new MeshAutoRepair(mesh); repair.Apply(); TestUtil.WriteTestOutputMesh(mesh, filename.Replace(".obj", ".repaired.obj")); }
public static void Main(string[] args) { CommandArgumentSet arguments = new CommandArgumentSet(); //arguments.Register("-tcount", int.MaxValue); //arguments.Register("-percent", 50.0f); //arguments.Register("-v", false); arguments.Register("-output", ""); if (arguments.Parse(args) == false) { return; } if (arguments.Filenames.Count != 1) { print_usage(); return; } string inputFilename = arguments.Filenames[0]; if (!File.Exists(inputFilename)) { System.Console.WriteLine("File {0} does not exist", inputFilename); return; } string outputFilename = Path.GetFileNameWithoutExtension(inputFilename); string format = Path.GetExtension(inputFilename); outputFilename = outputFilename + ".repaired" + format; if (arguments.Saw("-output")) { outputFilename = arguments.Strings["-output"]; } //int triCount = int.MaxValue; //if (arguments.Saw("-tcount")) // triCount = arguments.Integers["-tcount"]; //float percent = 50.0f; //if (arguments.Saw("-percent")) // percent = arguments.Floats["-percent"]; bool verbose = true; //if (arguments.Saw("-v")) // verbose = arguments.Flags["-v"]; List <DMesh3> meshes; try { DMesh3Builder builder = new DMesh3Builder(); IOReadResult result = StandardMeshReader.ReadFile(inputFilename, ReadOptions.Defaults, builder); if (result.code != IOCode.Ok) { System.Console.WriteLine("Error reading {0} : {1}", inputFilename, result.message); return; } meshes = builder.Meshes; } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } if (meshes.Count == 0) { System.Console.WriteLine("file did not contain any valid meshes"); return; } DMesh3 mesh = meshes[0]; for (int k = 1; k < meshes.Count; ++k) { MeshEditor.Append(mesh, meshes[k]); } if (mesh.TriangleCount == 0) { System.Console.WriteLine("mesh does not contain any triangles"); return; } if (verbose) { System.Console.WriteLine("initial mesh contains {0} triangles", mesh.TriangleCount); } if (verbose) { System.Console.WriteLine("Repairing...", mesh.TriangleCount); } MeshAutoRepair repair = new MeshAutoRepair(mesh); repair.RemoveMode = MeshAutoRepair.RemoveModes.None; bool bOK = repair.Apply(); if (verbose) { if (bOK == false) { System.Console.WriteLine("repair failed!"); } else { System.Console.WriteLine("done! repaired mesh contains {0} triangles", mesh.TriangleCount); } } try { IOWriteResult wresult = StandardMeshWriter.WriteMesh(outputFilename, mesh, WriteOptions.Defaults); if (wresult.code != IOCode.Ok) { System.Console.WriteLine("Error writing {0} : {1}", inputFilename, wresult.message); return; } } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } return; }
public static void test_autorepair_thingi10k() { //const string THINGIROOT = "E:\\Thingi10K\\"; string WRITEPATH = "E:\\Thingi10K\\repair_fails\\"; //string[] files = File.ReadAllLines("E:\\Thingi10K\\current\\thingi10k_open.txt"); string[] files = File.ReadAllLines("C:\\git\\gsGeometryTests\\test_output\\thingi10k_autorepair_failures.txt"); //string[] files = new string[] { // "E:\\Thingi10K\\raw_meshes\\37011.stl" //}; SafeListBuilder <string> failures = new SafeListBuilder <string>(); int count = 0; int MAX_NUM_FILES = 10000; gParallel.ForEach(files, (filename) => { if (count > MAX_NUM_FILES) { return; } int i = count; Interlocked.Increment(ref count); if (i % 10 == 0) { System.Console.WriteLine("{0} / {1}", i, files.Length); } long start_ticks = DateTime.Now.Ticks; DMesh3Builder builder = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = builder }; IOReadResult result = reader.Read(filename, ReadOptions.Defaults); if (result.code != IOCode.Ok) { System.Console.WriteLine("{0} FAILED TO READ!", filename); failures.SafeAdd(filename); return; } DMesh3 mesh = builder.Meshes[0]; for (int k = 1; k < builder.Meshes.Count; ++k) { MeshEditor.Append(mesh, builder.Meshes[k]); } DMesh3 before = new DMesh3(mesh); try { MeshAutoRepair repair = new MeshAutoRepair(mesh); repair.Apply(); } catch (Exception e) { System.Console.WriteLine("EXCEPTION {0} : {1}", filename, e.Message); failures.SafeAdd(filename); return; } if (mesh.IsClosed() == false) { failures.SafeAdd(filename); Util.WriteDebugMesh(before, WRITEPATH + Path.GetFileNameWithoutExtension(filename) + ".obj"); Util.WriteDebugMesh(mesh, WRITEPATH + Path.GetFileNameWithoutExtension(filename) + ".failed.obj"); return; } else { if (mesh.CheckValidity(false, FailMode.ReturnOnly) == false) { System.Console.WriteLine("INVALID {0}", filename); failures.SafeAdd(filename); Util.WriteDebugMesh(before, WRITEPATH + Path.GetFileNameWithoutExtension(filename) + ".obj"); Util.WriteDebugMesh(mesh, WRITEPATH + Path.GetFileNameWithoutExtension(filename) + ".invalid.obj"); return; } } }); //foreach (string failure in failures.Result) { // System.Console.WriteLine("FAIL: {0}", failure); //} System.Console.WriteLine("repaired {0} of {1}", files.Length - failures.Result.Count, files.Length); TestUtil.WriteTestOutputStrings(make_strings(failures), "thingi10k_autorepair_failures_new.txt"); }