예제 #1
0
        /// <summary>
        /// available after call to UpdateSection()
        /// </summary>
        public DMesh3 GetSectionMesh(double simplifyTol = 0.01)
        {
            DMesh3 mesh = new DMesh3();

            if (localCurves.Loops == null)
            {
                return(mesh);
            }

            List <GeneralPolygon2d> solids = GetSolids();

            foreach (GeneralPolygon2d poly in solids)
            {
                poly.Simplify(simplifyTol, simplifyTol / 10, true);
                TriangulatedPolygonGenerator gen = new TriangulatedPolygonGenerator()
                {
                    Polygon = poly
                };
                DMesh3 polyMesh = gen.Generate().MakeDMesh();
                MeshTransforms.PerVertexTransform(polyMesh, (uv) => {
                    return(frameL.FromPlaneUV((Vector2f)uv.xy, 2));
                });
                MeshEditor.Append(mesh, polyMesh);
            }

            if (OutputSpace != CoordSpace.ObjectCoords)
            {
                MeshTransforms.PerVertexTransform(mesh, (v) => {
                    return(SceneTransforms.TransformTo((Vector3f)v, SO, CoordSpace.ObjectCoords, OutputSpace));
                });
            }

            return(mesh);
        }
예제 #2
0
        /// <summary>
        /// Generates a row of cylinders tessellated w/ different chord lengths
        ///   eg 10x1cm : CalibrationModelGenerator.MakePrintStepSizeTest(10.0f, 10.0f, 0.1, 1.0, 10);
        /// </summary>
        public static DMesh3 MakePrintStepSizeTest(double cylDiam, double cylHeight, double lowStep, double highStep, int nSteps)
        {
            double spacing = 2.0f;
            float  r       = (float)cylDiam * 0.5f;
            double cx      = 0.5 * (nSteps * cylDiam + (nSteps - 1) * spacing);

            DMesh3 accumMesh = new DMesh3();

            double cur_x = -cx + cylDiam / 2;

            for (int k = 0; k < nSteps; ++k)
            {
                double t         = (double)k / (double)(nSteps - 1);
                double chord_len = (1.0 - t) * lowStep + (t) * highStep;
                int    slices    = (int)((MathUtil.TwoPI * r) / chord_len);

                CappedCylinderGenerator cylgen = new CappedCylinderGenerator()
                {
                    BaseRadius       = r,
                    TopRadius        = r,
                    Height           = (float)cylHeight,
                    Slices           = slices,
                    NoSharedVertices = false
                };
                DMesh3 cylMesh = cylgen.Generate().MakeDMesh();
                MeshTransforms.Translate(cylMesh, -cylMesh.CachedBounds.Min.y * Vector3d.AxisY);
                MeshTransforms.Translate(cylMesh, cur_x * Vector3d.AxisX);
                cur_x += cylDiam + spacing;
                MeshEditor.Append(accumMesh, cylMesh);
            }

            MeshTransforms.ConvertYUpToZUp(accumMesh);

            return(accumMesh);
        }
예제 #3
0
            public override fMesh MakeGeometry(AxisGizmoFlags widget)
            {
                switch (widget)
                {
                case AxisGizmoFlags.AxisTranslateY:
                    if (MyAxisTranslateY == null)
                    {
                        Radial3DArrowGenerator arrowGen = new Radial3DArrowGenerator()
                        {
                            HeadLength = 2.0f, TipRadius = 0.1f, StickLength = 1.5f, Clockwise = true
                        };
                        DMesh3 mesh = arrowGen.Generate().MakeDMesh();
                        MeshNormals.QuickCompute(mesh);
                        MeshTransforms.Translate(mesh, 0.5 * Vector3d.AxisY);
                        DMesh3 flip = new DMesh3(mesh);
                        MeshTransforms.Rotate(flip, Vector3d.Zero, Quaterniond.AxisAngleD(Vector3d.AxisX, 180));
                        MeshEditor.Append(mesh, flip);
                        MyAxisTranslateY = new fMesh(mesh);
                    }
                    return(MyAxisTranslateY);

                default:
                    return(null);
                }
            }
예제 #4
0
        public override void Apply()
        {
            if (current_result_is_partial)
            {
                PreviewSO.EditAndUpdateMesh((mesh) => {
                    mesh.ReverseOrientation();
                    MeshEditor.Append(mesh, combineMesh);
                }, GeometryEditTypes.ArbitraryEdit);
            }

            base.Apply();
        }
예제 #5
0
        public DMesh3 GetCombinedMesh(int nLayerStep = 1)
        {
            DMesh3 fullMesh = new DMesh3();

            double[]        z      = LayerMeshes.Keys.ToArray();
            List <DMesh3>[] layers = LayerMeshes.Values.ToArray();
            Array.Sort(z, layers);
            nLayerStep = MathUtil.Clamp(nLayerStep, 1, 999999);
            for (int li = 0; li < layers.Length; li += nLayerStep)
            {
                var meshlist = layers[li];
                foreach (var mesh in meshlist)
                {
                    MeshEditor.Append(fullMesh, mesh);
                }
            }
            return(fullMesh);
        }
예제 #6
0
        public override void Apply()
        {
            if (current_result_is_partial)
            {
                PreviewSO.EditAndUpdateMesh((mesh) => {
                    if (ShellDirection == ShellDirections.Outer)
                    {
                        combineMesh.ReverseOrientation();
                    }
                    else if (ShellDirection == ShellDirections.Inner)
                    {
                        mesh.ReverseOrientation();
                    }
                    MeshEditor.Append(mesh, combineMesh);
                }, GeometryEditTypes.ArbitraryEdit);
            }

            base.Apply();
        }
예제 #7
0
        public DMesh3 MakeElementsMesh(Polygon2d spanProfile, Polygon2d loopProfile)
        {
            var result = new DMesh3();

            validate_topology();

            foreach (EdgeSpan span in Spans)
            {
                DCurve3 curve   = span.ToCurve(Mesh);
                var     tubegen = new TubeGenerator(curve, spanProfile);
                MeshEditor.Append(result, tubegen.Generate().MakeDMesh());
            }

            foreach (EdgeLoop loop in Loops)
            {
                DCurve3 curve   = loop.ToCurve(Mesh);
                var     tubegen = new TubeGenerator(curve, loopProfile);
                MeshEditor.Append(result, tubegen.Generate().MakeDMesh());
            }

            return(result);
        }
예제 #8
0
        public DMesh3 Make3DTubes(Interval1i layer_range, double merge_tol, double tube_radius)
        {
            Polygon2d tube_profile = Polygon2d.MakeCircle(tube_radius, 8);
            Frame3f   frame        = Frame3f.Identity;

            DMesh3 full_mesh = new DMesh3();

            foreach (int layer_i in layer_range)
            {
                PlanarSlice slice = Slices[layer_i];
                frame.Origin = new Vector3f(0, 0, slice.Z);
                foreach (GeneralPolygon2d gpoly in slice.Solids)
                {
                    List <Polygon2d> polys = new List <Polygon2d>()
                    {
                        gpoly.Outer
                    }; polys.AddRange(gpoly.Holes);
                    foreach (Polygon2d poly in polys)
                    {
                        Polygon2d simpPoly = new Polygon2d(poly);
                        simpPoly.Simplify(merge_tol, 0.01, true);
                        if (simpPoly.VertexCount < 3)
                        {
                            Util.gBreakToDebugger();
                        }
                        TubeGenerator tubegen = new TubeGenerator(simpPoly, frame, tube_profile)
                        {
                            NoSharedVertices = true
                        };
                        DMesh3 tubeMesh = tubegen.Generate().MakeDMesh();
                        MeshEditor.Append(full_mesh, tubeMesh);
                    }
                }
            }

            return(full_mesh);
        }
        public static void test_sort_mesh_components()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_nested_spheres.obj");

            MeshConnectedComponents components = new MeshConnectedComponents(mesh);

            components.FindConnectedT();
            DSubmesh3Set componentMeshes = new DSubmesh3Set(mesh, components);

            LocalProfiler p = new LocalProfiler();

            p.Start("sort");

            MeshSpatialSort sorter = new MeshSpatialSort();

            foreach (DSubmesh3 submesh in componentMeshes)
            {
                sorter.AddMesh(submesh.SubMesh, submesh);
            }
            sorter.Sort();

            p.Stop("sort");
            System.Console.WriteLine(p.AllTimes());

            DMesh3 resultMesh = new DMesh3();

            foreach (var solid in sorter.Solids)
            {
                if (solid.Outer.InsideOf.Count == 0)
                {
                    MeshEditor.Append(resultMesh, solid.Outer.Mesh);
                }
            }

            TestUtil.WriteTestOutputMesh(resultMesh, "mesh_components.obj");
        }
예제 #10
0
        public static void test_tube_generator()
        {
            Polygon2d  circle_path = Polygon2d.MakeCircle(50, 64);
            PolyLine2d arc_path    = new PolyLine2d(circle_path.Vertices.Take(circle_path.VertexCount / 2));
            Polygon2d  irreg_path  = new Polygon2d();

            for (int k = 0; k < circle_path.VertexCount; ++k)
            {
                irreg_path.AppendVertex(circle_path[k]);
                k += k / 2;
            }
            PolyLine2d irreg_arc_path = new PolyLine2d(irreg_path.Vertices.Take(circle_path.VertexCount - 1));

            Polygon2d square_profile = Polygon2d.MakeCircle(7, 32);

            square_profile.Translate(4 * Vector2d.One);
            //square_profile[0] = 20 * square_profile[0].Normalized;

            bool no_shared = true;

            WriteGeneratedMesh(
                new TubeGenerator(circle_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_loop_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(irreg_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_irregloop_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(arc_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_arc_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(irreg_arc_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_irregarc_standarduv.obj");



            // append tube border around each hole of input mesh
            DMesh3            inMesh   = TestUtil.LoadTestInputMesh("n_holed_bunny.obj");
            Polygon2d         bdrycirc = Polygon2d.MakeCircle(0.25, 6);
            MeshBoundaryLoops loops    = new MeshBoundaryLoops(inMesh);

            foreach (EdgeLoop loop in loops)
            {
                DCurve3       curve = loop.ToCurve().ResampleSharpTurns();
                TubeGenerator gen   = new TubeGenerator(curve, bdrycirc)
                {
                    NoSharedVertices = false
                };
                MeshEditor.Append(inMesh, gen.Generate().MakeDMesh());
            }
            TestUtil.WriteTestOutputMesh(inMesh, "boundary_tubes.obj");
        }
예제 #11
0
        public virtual void Update()
        {
            base.begin_update();
            int start_timestamp = this.CurrentInputTimestamp;

            if (MeshSource == null)
            {
                throw new Exception("SeparateSolidsOp: must set valid MeshSource to compute!");
            }

            ResultMeshes = null;

            try {
                DMesh3 meshIn = new DMesh3(MeshSource.GetDMeshUnsafe());

                MeshConnectedComponents comp = new MeshConnectedComponents(meshIn);
                comp.FindConnectedT();
                DSubmesh3Set subMeshes = new DSubmesh3Set(meshIn, comp);

                List <DMesh3> curMeshes = new List <DMesh3>();
                foreach (var submesh in subMeshes)
                {
                    curMeshes.Add(submesh.SubMesh);
                }

                if (group_nested_shells)
                {
                    MeshSpatialSort sort = new MeshSpatialSort();
                    foreach (var mesh in curMeshes)
                    {
                        sort.AddMesh(mesh, mesh);
                    }
                    sort.Sort();

                    curMeshes.Clear();
                    foreach (var solid in sort.Solids)
                    {
                        DMesh3 outer = solid.Outer.Mesh;
                        if (orient_nested_shells && is_outward_oriented(outer) == false)
                        {
                            outer.ReverseOrientation();
                        }

                        foreach (var hole in solid.Cavities)
                        {
                            if (orient_nested_shells && hole.Mesh.CachedIsClosed && is_outward_oriented(hole.Mesh) == true)
                            {
                                hole.Mesh.ReverseOrientation();
                            }
                            MeshEditor.Append(outer, hole.Mesh);
                        }

                        curMeshes.Add(outer);
                    }
                }

                ResultMeshes = curMeshes;

                base.complete_update();
            } catch (Exception) {
                ResultMeshes = new List <DMesh3>();
                base.complete_update();
                throw;
            }
        }
예제 #12
0
        protected virtual void compute_shell_extrude()
        {
            DMesh3 mesh = new DMesh3(MeshSource.GetDMeshUnsafe());

            MeshNormals.QuickCompute(mesh);

            if (shell_direction == ShellDirections.Symmetric)
            {
                double thickness = shell_thickness * 0.5;

                DMesh3          outerMesh    = new DMesh3(mesh);
                MeshExtrudeMesh outerExtrude = new MeshExtrudeMesh(outerMesh);
                outerExtrude.ExtrudedPositionF = (v, n, vid) => {
                    return(v + thickness * (Vector3d)n);
                };
                if (outerExtrude.Extrude() == false)
                {
                    throw new Exception("MeshShellOp.compute_shell_extrude: outer Extrude() returned false!");
                }
                MeshEditor.RemoveTriangles(outerMesh, outerExtrude.InitialTriangles);

                MeshExtrudeMesh innerExtrude = new MeshExtrudeMesh(mesh);
                innerExtrude.IsPositiveOffset  = false;
                innerExtrude.ExtrudedPositionF = (v, n, vid) => {
                    return(v - thickness * (Vector3d)n);
                };
                if (innerExtrude.Extrude() == false)
                {
                    throw new Exception("MeshShellOp.compute_shell_extrude: inner Extrude() returned false!");
                }
                MeshEditor.RemoveTriangles(mesh, innerExtrude.InitialTriangles);

                MeshEditor.Append(mesh, outerMesh);

                if (cached_is_closed == false)
                {
                    // cheating!
                    MergeCoincidentEdges merge = new MergeCoincidentEdges(mesh);
                    merge.Apply();
                }
            }
            else
            {
                double thickness = (shell_direction == ShellDirections.Outer) ?
                                   shell_thickness : -shell_thickness;

                MeshExtrudeMesh extrude = new MeshExtrudeMesh(mesh);
                extrude.IsPositiveOffset = (shell_direction == ShellDirections.Outer);

                extrude.ExtrudedPositionF = (v, n, vid) => {
                    return(v + thickness * (Vector3d)n);
                };

                if (extrude.Extrude() == false)
                {
                    throw new Exception("MeshShellOp.compute_shell_extrude: Extrude() returned false!");
                }

                if (shell_surface_only && cached_is_closed)
                {
                    MeshEditor.RemoveTriangles(mesh, extrude.InitialTriangles);
                    if (shell_direction == ShellDirections.Inner)
                    {
                        mesh.ReverseOrientation();
                    }
                    if (shell_direction == ShellDirections.Inner || shell_direction == ShellDirections.Outer)
                    {
                        mesh.AttachMetadata("is_partial", new object());
                    }
                }
            }

            if (is_invalidated())
            {
                return;
            }

            ResultMesh = mesh;
        }
예제 #13
0
        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");
        }
예제 #14
0
        protected virtual DMesh3 compute_wrap()
        {
            DMesh3 meshIn = MeshSource.GetDMeshUnsafe();

            double unsigned_offset = Math.Abs(distance);

            if (cached_sdf == null ||
                unsigned_offset > cached_sdf_max_offset ||
                grid_cell_size != cached_sdf.CellSize)
            {
                DMeshAABBTree3 use_spatial = input_spatial;
                CachingMeshSDF sdf         = new CachingMeshSDF(meshIn, grid_cell_size, use_spatial);
                sdf.MaxOffsetDistance = 2 * (float)unsigned_offset;

                sdf.CancelF = is_invalidated;
                sdf.Initialize();
                if (is_invalidated())
                {
                    return(null);
                }

                cached_sdf            = sdf;
                cached_sdf_max_offset = unsigned_offset;
                cached_sdf_bounds     = meshIn.CachedBounds;
            }

            var grid_iso = new CachingMeshSDFImplicit(cached_sdf);
            // currently MCPro-Continuation does not work w/ non-zero
            //   isovalues, so we have to shift our target offset externally
            var iso = new ImplicitOffset3d()
            {
                A = grid_iso, Offset = distance
            };

            MarchingCubesPro c = new MarchingCubesPro();

            c.Implicit = iso;
            c.Bounds   = cached_sdf_bounds;
            c.CubeSize = mesh_cell_size;
            c.Bounds.Expand(distance + 3 * c.CubeSize);

            c.CancelF = is_invalidated;
            c.GenerateContinuation(offset_seeds(meshIn, distance));
            if (is_invalidated())
            {
                return(null);
            }

            Reducer r = new Reducer(c.Mesh);

            r.FastCollapsePass(c.CubeSize * 0.5, 3, true);
            if (is_invalidated())
            {
                return(null);
            }

            if (min_component_volume > 0)
            {
                MeshEditor.RemoveSmallComponents(c.Mesh, min_component_volume, min_component_volume);
            }
            if (is_invalidated())
            {
                return(null);
            }

            DMesh3 offsetMesh = c.Mesh;

            MeshConnectedComponents comp = new MeshConnectedComponents(offsetMesh);

            comp.FindConnectedT();
            if (is_invalidated())
            {
                return(null);
            }
            DSubmesh3Set subMeshes = new DSubmesh3Set(offsetMesh, comp);

            if (is_invalidated())
            {
                return(null);
            }

            MeshSpatialSort sort = new MeshSpatialSort();

            foreach (var subMesh in subMeshes)
            {
                sort.AddMesh(subMesh.SubMesh, subMesh);
            }
            sort.Sort();
            if (is_invalidated())
            {
                return(null);
            }

            DMesh3 outerMesh = new DMesh3();

            foreach (var solid in sort.Solids)
            {
                DMesh3 outer = solid.Outer.Mesh;
                //if (is_outward_oriented(outer) == false)
                //    outer.ReverseOrientation();
                MeshEditor.Append(outerMesh, outer);
            }
            if (is_invalidated())
            {
                return(null);
            }

            return(compute_inset(outerMesh));
        }
예제 #15
0
        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 + ".reduced" + 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 = false;

            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);
            }

            Reducer r = new Reducer(mesh);

            if (triCount < int.MaxValue)
            {
                if (verbose)
                {
                    System.Console.Write("reducing to {0} triangles...", triCount);
                }
                r.ReduceToTriangleCount(triCount);
            }
            else
            {
                int nT = (int)((float)mesh.TriangleCount * percent / 100.0f);
                nT = MathUtil.Clamp(nT, 1, mesh.TriangleCount);
                if (verbose)
                {
                    System.Console.Write("reducing to {0} triangles...", nT);
                }
                r.ReduceToTriangleCount(nT);
            }

            if (verbose)
            {
                System.Console.WriteLine("done!");
            }

            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;
        }
예제 #16
0
        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;
        }
예제 #17
0
        public static void test_write_solids()
        {
            //string FORMAT = ".obj";
            string FORMAT    = ".g3mesh";
            string WRITEPATH = "E:\\Thingi10K\\closed\\";

            string[] files = File.ReadAllLines("E:\\Thingi10K\\current\\thingi10k_closed.txt");
            SafeListBuilder <string> failures = new SafeListBuilder <string>();

            if (!Directory.Exists(WRITEPATH))
            {
                Directory.CreateDirectory(WRITEPATH);
            }

            int k = 0;

            gParallel.ForEach(files, (filename) => {
                int i = k;
                Interlocked.Increment(ref k);
                if (i % 500 == 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!", filename);
                    failures.SafeAdd(filename);
                    return;
                }

                DMesh3 combineMesh = new DMesh3();
                if (builder.Meshes.Count == 1)
                {
                    combineMesh = builder.Meshes[0];
                }
                else
                {
                    foreach (DMesh3 mesh in builder.Meshes)
                    {
                        MeshEditor.Append(combineMesh, mesh);
                    }
                }


                if (combineMesh.IsClosed() == false)
                {
                    MergeCoincidentEdges closeCracks = new MergeCoincidentEdges(combineMesh);
                    closeCracks.Apply();
                }

                if (combineMesh.IsClosed() == false)
                {
                    System.Console.WriteLine("NOT CLOSED: {0}", filename);
                    return;
                }

                string outPath = Path.Combine(WRITEPATH, Path.GetFileNameWithoutExtension(filename) + FORMAT);
                StandardMeshWriter.WriteMesh(outPath, combineMesh, WriteOptions.Defaults);
            });
        }