DMesh3 GenerateRemesh(DMesh3 mesh) { DMesh3 remeshed = new DMesh3(mesh); DMeshAABBTree3 project = new DMeshAABBTree3(mesh); project.Build(); MeshProjectionTarget Target = new MeshProjectionTarget(project.Mesh, project); double minlen, maxlen, avglen; MeshQueries.EdgeLengthStats(mesh, out minlen, out maxlen, out avglen); double edge_len = (TargetEdgeLength == 0) ? Loop.AverageEdgeLength : avglen; Remesher r = new Remesher(remeshed); r.SetTargetEdgeLength(edge_len); r.SetProjectionTarget(Target); MeshConstraintUtil.FixAllBoundaryEdges(r); for (int k = 0; k < 20; ++k) { r.BasicRemeshPass(); } return(remeshed); }
void remove_old_vertices(int[] MapV, DMesh3 mesh) { HashSet <int> keepV = new HashSet <int>(); for (int k = 0; k < MapV.Length; ++k) { if (MapV[k] != DMesh3.InvalidID) { keepV.Add(MapV[k]); } } Remesher r = new Remesher(mesh); //r.EnableCollapses = false; //r.EnableSplits = false; //r.EnableFlips = false; r.SmoothSpeedT = 1.0; //r.EnableSmoothing = false; r.PreventNormalFlips = true; r.SetTargetEdgeLength(1.0); //r.EnableSmoothing = false; MeshConstraints c = new MeshConstraints(); foreach (int vid in keepV) { c.SetOrUpdateVertexConstraint(vid, VertexConstraint.Pinned); } r.SetExternalConstraints(c); double minE, maxE, avgE; MeshQueries.EdgeLengthStats(mesh, out minE, out maxE, out avgE); r.SetTargetEdgeLength(avgE * .3); for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } //int iter = 0; //while (iter++ < 10) { // r.SetTargetEdgeLength(iter * 1.0); // for (int k = 0; k < 10; ++k) // r.BasicRemeshPass(); //} }
public bool Compute() { PlanarMesh = BuildPlanarMesh(false); InflatedMesh = ComputeInflation(PlanarMesh); DMesh3 remeshed = GenerateRemesh(InflatedMesh); Flatten(remeshed); ResultMesh = ComputeInflation(remeshed); MeshBoundaryLoops loops = new MeshBoundaryLoops(ResultMesh); DMesh3 otherSide = new DMesh3(ResultMesh); foreach (int vid in otherSide.VertexIndices()) { Vector3d v = otherSide.GetVertex(vid); v.z = -v.z; otherSide.SetVertex(vid, v); } otherSide.ReverseOrientation(); MeshEditor editor = new MeshEditor(ResultMesh); int[] mapVArray; editor.AppendMesh(otherSide, out mapVArray); IndexMap mapV = new IndexMap(mapVArray); foreach (EdgeLoop loop in loops) { int[] otherLoop = (int[])loop.Vertices.Clone(); IndexUtil.Apply(otherLoop, mapV); editor.StitchLoop(loop.Vertices, otherLoop); } Remesher remesh = new Remesher(ResultMesh); remesh.SetTargetEdgeLength(TargetEdgeLength); remesh.SmoothSpeedT = 0.25f; for (int k = 0; k < 10; ++k) { remesh.BasicRemeshPass(); } ResultMesh = new DMesh3(ResultMesh, true); LaplacianMeshSmoother smoother = new LaplacianMeshSmoother(ResultMesh); foreach (int vid in ResultMesh.VertexIndices()) { smoother.SetConstraint(vid, ResultMesh.GetVertex(vid), 0.5f, false); } smoother.SolveAndUpdateMesh(); return(true); }
DMesh3 BuildPlanarMesh(bool bPreservePolygon) { DMesh3 planarMesh = new DMesh3(); Vector2d center = CurveUtils2.CentroidVtx(Loop.Vertices); int center_id = planarMesh.AppendVertex(new Vector3d(center.x, center.y, 0)); int prev_id = -1; int first_id = -1; foreach (Vector2d v in Loop.Vertices) { int next_id = planarMesh.AppendVertex(new Vector3d(v.x, v.y, Thickness)); if (prev_id > 0) { planarMesh.AppendTriangle(center_id, prev_id, next_id); prev_id = next_id; } else { first_id = next_id; prev_id = next_id; } } planarMesh.AppendTriangle(center_id, prev_id, first_id); if (ReverseOrientation) { planarMesh.ReverseOrientation(); } Debug.Assert(planarMesh.CheckValidity()); double edge_len = (TargetEdgeLength == 0) ? Loop.AverageEdgeLength : TargetEdgeLength; Remesher r = new Remesher(planarMesh); r.SetTargetEdgeLength(edge_len); r.SmoothSpeedT = 1.0f; if (bPreservePolygon) { MeshConstraintUtil.FixAllBoundaryEdges(r); } else { MeshConstraintUtil.PreserveBoundaryLoops(r); } for (int k = 0; k < 20; ++k) { r.BasicRemeshPass(); } return(planarMesh); }
protected void generate(float fDiameter, float fHeight, float fWallThickness, float fBaseThickness) { base.reset_holes(); CappedCylinderGenerator outer_cylgen = new CappedCylinderGenerator() { BaseRadius = fDiameter / 2, TopRadius = fDiameter / 2, Height = fHeight + 10, Slices = 60, Clockwise = true }; DMesh3 outer_mesh = outer_cylgen.Generate().MakeDMesh(); float fInnerDiam = fDiameter - 2 * fWallThickness; CappedCylinderGenerator inner_cylgen = new CappedCylinderGenerator() { BaseRadius = fInnerDiam / 2, TopRadius = fInnerDiam / 2, Height = fHeight + 10, Slices = 60, Clockwise = false }; DMesh3 inner_mesh = inner_cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(inner_mesh, fBaseThickness * Vector3d.AxisY); DMesh3[] meshes = new DMesh3[2] { outer_mesh, inner_mesh }; foreach (DMesh3 mesh in meshes) { Remesher r = new Remesher(mesh); r.SetTargetEdgeLength(TargetEdgeLength); r.SmoothSpeedT = 0.5f; r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllGroupBoundaryEdges(r.Constraints, mesh, true); r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh)); for (int k = 0; k < 10; ++k) { r.BasicRemeshPass(); } } Vector3d vCutPos = new Vector3d(0, fHeight, 0); Vector3d vCutNormal = Vector3d.AxisY; foreach (DMesh3 mesh in meshes) { MeshPlaneCut cut = new MeshPlaneCut(mesh, new Vector3d(0, fHeight, 0), Vector3d.AxisY); cut.Cut(); } base.set_output_meshes(inner_mesh, outer_mesh); }
public static DMesh3 Remesh(DMesh3 mesh, double edgeLenght, int iteration) { Remesher r = new Remesher(mesh); r.PreventNormalFlips = true; r.SetTargetEdgeLength(edgeLenght); for (int k = 0; k < iteration; ++k) { r.BasicRemeshPass(); } return(new g3.DMesh3(r.Mesh, true)); }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; double targetL = 0; int numI = 0; bool fixB = false; bool projBack = false; DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref targetL); DA.GetData(2, ref numI); DA.GetData(3, ref fixB); DA.GetData(4, ref projBack); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); Remesher r = new Remesher(dMsh_copy); r.PreventNormalFlips = true; r.SetTargetEdgeLength(targetL); r.SmoothSpeedT = 0.5; if (fixB) { MeshConstraintUtil.FixAllBoundaryEdges(r); } if (projBack) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dMsh_goo.Value)); } for (int k = 0; k < numI; ++k) { r.BasicRemeshPass(); } bool isValid = dMsh_copy.CheckValidity(); if (!isValid) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during remeshing. Please check..."); } DA.SetData(0, dMsh_copy); }
/// <summary> /// uses marching cubes to help smooth the mesh after using the remesher /// experimental /// </summary> /// <param name="edgeLength"></param> /// <param name="smoothSpeed"></param> /// <param name="iterations"></param> /// <param name="cells"></param> public void Smooth(double edgeLength, double smoothSpeed, double iterations, double cells) { //Use the Remesher class to do a basic remeshing DMesh3 mesh = new DMesh3(_mesh); Remesher r = new Remesher(mesh); r.PreventNormalFlips = true; r.SetTargetEdgeLength(edgeLength); r.SmoothSpeedT = smoothSpeed; r.SetProjectionTarget(MeshProjectionTarget.Auto(mesh)); for (int k = 0; k < iterations; k++) { r.BasicRemeshPass(); } //marching cubes int num_cells = (int)cells; if (cells > 0) { double cell_size = mesh.CachedBounds.MaxDim / num_cells; MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(mesh, cell_size); sdf.Compute(); var iso = new DenseGridTrilinearImplicit(sdf.Grid, sdf.GridOrigin, sdf.CellSize); MarchingCubes c = new MarchingCubes(); c.Implicit = iso; c.Bounds = mesh.CachedBounds; c.CubeSize = c.Bounds.MaxDim / cells; c.Bounds.Expand(3 * c.CubeSize); c.Generate(); _smoothMesh = c.Mesh; } else { _smoothMesh = mesh; } _displayMesh = DMeshToMeshGeometry(_smoothMesh); _moldMesh = null; }
/// <summary> /// Class for normalising and refining a given mesh. /// </summary> /// <param name="mesh">The mesh that needs to be refined.</param> /// <param name="file">The file containing the shape to refine.</param> /// <exception cref="ArgumentNullException">If the given file is /// <see langword="null"/>.</exception> /// <exception cref="ArgumentException">If the given file does not exist. /// </exception> public void RefineMesh(Shapes.IMesh mesh, FileInfo file) { if (mesh == null) { throw new ArgumentNullException(nameof(mesh)); } if (file == null) { throw new ArgumentNullException(nameof(file)); } if (!file.Exists) { throw new ArgumentException(Resources.EX_FileNotFound, file.FullName); } DMesh3 meshDMesh3 = mesh as GeometryMesh; Remesher remesher = new Remesher(meshDMesh3) { PreventNormalFlips = true }; int i = 0; while (meshDMesh3.VertexCount < Settings.RefineVertexNumber && i < Settings.MaxRefineIterations) { remesher.SetTargetEdgeLength(0.0001F); remesher.BasicRemeshPass(); i++; } Reducer reducer = new Reducer(meshDMesh3); reducer.ReduceToVertexCount(Settings.RefineVertexNumber); Settings.FileManager.Write(file.FullName, GeometryMesh.ToGeometryMesh(meshDMesh3)); }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; double targetL = 0; bool fixB = false; bool projBack = false; bool run = false; bool reset = false; int maxIter = 0; DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref targetL); DA.GetData(3, ref fixB); DA.GetData(4, ref projBack); DA.GetData(2, ref maxIter); DA.GetData(5, ref run); DA.GetData(6, ref reset); if (passes >= maxIter) { run = false; } if (r is null || reset) { dMsh_copy = new DMesh3(dMsh_goo.Value); r = new Remesher(dMsh_copy); r.PreventNormalFlips = true; r.SetTargetEdgeLength(targetL); r.SmoothSpeedT = 0.5; passes = 0; if (fixB) { MeshConstraintUtil.FixAllBoundaryEdges(r); } if (projBack) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dMsh_goo.Value)); } } if (run && !reset) { r.BasicRemeshPass(); passes++; Update(); } bool isValid = dMsh_copy.CheckValidity(); if (!isValid) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during remeshing. Please check..."); } this.Message = "Pass: " + passes.ToString(); DA.SetData(0, dMsh_copy); }
public static void performance_grinder() { LocalProfiler p = new LocalProfiler(); DateTime start = DateTime.Now; //p.Start("Meshgen"); //for (int k = 0; k < 100; ++k) { // Sphere3Generator_NormalizedCube tmpgen = new Sphere3Generator_NormalizedCube(); // tmpgen.EdgeVertices = 100; // tmpgen.Generate(); // DMesh3 tmp = tmpgen.MakeDMesh(); //} //p.StopAndAccumulate("Meshgen"); //System.Console.WriteLine("done meshgen"); Sphere3Generator_NormalizedCube meshgen = new Sphere3Generator_NormalizedCube() { EdgeVertices = 100 }; meshgen.Generate(); DMesh3 sphereMesh = meshgen.MakeDMesh(); //p.Start("Spatial"); //for (int k = 0; k < 100; ++k) { // DMeshAABBTree3 tmpspatial = new DMeshAABBTree3(sphereMesh); // tmpspatial.Build(); //} //p.StopAndAccumulate("Spatial"); //System.Console.WriteLine("done spatial"); meshgen.EdgeVertices = 5; meshgen.Generate(); sphereMesh = meshgen.MakeDMesh(); double remesh_len = (2.0 / 5.0) * 0.025; // takes ~220s //double remesh_len = (2.0 / 5.0) * 0.05; long max_mem = 0; Remesher remesher = new Remesher(sphereMesh); for (int k = 0; k < 10; ++k) { System.Console.WriteLine("{0}", k); p.Start("Remesh"); remesher.SetTargetEdgeLength(remesh_len); remesher.SmoothSpeedT = 0.5f; for (int j = 0; j < 20; ++j) { remesher.BasicRemeshPass(); foreach (int vid in sphereMesh.VertexIndices()) { Vector3d v = sphereMesh.GetVertex(vid); v.Normalize(); sphereMesh.SetVertex(vid, v); } } p.StopAndAccumulate("Remesh"); //System.Console.WriteLine(sphereMesh.MeshInfoString()); System.Console.WriteLine(" {0}", k); p.Start("Reduce"); remesher.SetTargetEdgeLength(remesh_len * 10); for (int j = 0; j < 20; ++j) { remesher.BasicRemeshPass(); foreach (int vid in sphereMesh.VertexIndices()) { Vector3d v = sphereMesh.GetVertex(vid); v.Normalize(); sphereMesh.SetVertex(vid, v); } } p.StopAndAccumulate("Reduce"); } DateTime end = DateTime.Now; System.Console.WriteLine("done remesh"); System.Console.WriteLine("Time {0} MaxMem {1}", (end - start).TotalSeconds, max_mem / (1024 * 1024)); System.Console.WriteLine(p.AllAccumulatedTimes("Accumulated: ")); }
protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; List <Point3d> points = new List <Point3d>(); double targetL = 0; int numI = 0; int fixB = 0; bool projBack = false; double smooth = 0; DA.GetData(0, ref dMsh_goo); DA.GetDataList(2, points); DA.GetData(1, ref targetL); DA.GetData(6, ref numI); DA.GetData(3, ref fixB); DA.GetData(5, ref projBack); DA.GetData(7, ref smooth); List <EdgeConstraint_goo> edgeC = new List <EdgeConstraint_goo>(); DA.GetDataList(4, edgeC); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); Remesher r = new Remesher(dMsh_copy); r.PreventNormalFlips = true; r.SetTargetEdgeLength(targetL); r.SmoothSpeedT = smooth; if (fixB == 2) { MeshConstraintUtil.FixAllBoundaryEdges(r); } else if (fixB == 1) { MeshConstraintUtil.PreserveBoundaryLoops(r); } else { r.SetExternalConstraints(new MeshConstraints()); } if (edgeC.Count > 0) { for (int i = 0; i < edgeC.Count; i++) { var tempEC = edgeC[i]; IProjectionTarget target = new DCurveProjectionTarget(tempEC.crv); for (int j = 0; j < tempEC.edges.Length; j++) { tempEC.constraint.Target = target; r.Constraints.SetOrUpdateEdgeConstraint(tempEC.edges[j], tempEC.constraint); } for (int j = 0; j < tempEC.vertices.Length; j++) { if (tempEC.PinVerts) { r.Constraints.SetOrUpdateVertexConstraint(tempEC.vertices[j], VertexConstraint.Pinned); } else { r.Constraints.SetOrUpdateVertexConstraint(tempEC.vertices[j], new VertexConstraint(target)); } } } } if (points.Count > 0) { DMeshAABBTree3 mshAABB = new DMeshAABBTree3(dMsh_copy, true); var v3pts = points.Select(pt => pt.ToVec3d()); foreach (var p in v3pts) { int id = mshAABB.FindNearestVertex(p, 0.1); if (id != -1) { r.Constraints.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned); } } } if (projBack) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dMsh_goo.Value)); } for (int k = 0; k < numI; ++k) { r.BasicRemeshPass(); } bool isValid = dMsh_copy.CheckValidity(); if (!isValid) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during remeshing. Please check..."); } DA.SetData(0, dMsh_copy); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh m = DA.Fetch <Mesh>("Mesh"); bool fixEdges = DA.Fetch <bool>("FixEdges"); double l = DA.Fetch <double>("EdgeLength"); int iterations = DA.Fetch <int>("Iterations"); List <Point3d> fixPt = DA.FetchList <Point3d>("FixPt"); bool project = DA.Fetch <bool>("Project"); bool loops = DA.Fetch <bool>("Loops"); Mesh mesh = m.DuplicateMesh(); mesh.Faces.ConvertQuadsToTriangles(); double len = (l == 0) ? mesh.GetBoundingBox(false).Diagonal.Length * 0.1 : l; //r.PreventNormalFlips = true; List <int> ids = new List <int>(); Point3d[] pts = mesh.Vertices.ToPoint3dArray(); foreach (Point3d p in fixPt) { ids.Add(NGonsCore.PointUtil.ClosestPoint(p, pts)); } DMesh3 dmesh = mesh.ToDMesh3(); Remesher r = new Remesher(dmesh); r.Precompute(); r.SetTargetEdgeLength(len); r.SmoothSpeedT = 0.5; if (project) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dmesh)); } r.EnableFlips = r.EnableSplits = r.EnableCollapses = true; r.EnableSmoothing = true; MeshConstraints cons = new MeshConstraints(); if (ids.Count > 0) { foreach (int id in ids) { //cons.SetOrUpdateVertexConstraint(id, new VertexConstraint(true, 1)); cons.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned); } } r.SetExternalConstraints(cons); r.Precompute(); if (fixEdges) { //r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllBoundaryEdges(r); MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(cons, dmesh, 0); //MeshConstraintUtil.FixAllBoundaryEdges_AllowCollapse(cons, dmesh, 0); } if (loops) { MeshConstraintUtil.PreserveBoundaryLoops(r); //project to edge //MeshConstraintUtil.PreserveBoundaryLoops(cons,dmesh);//project to edge } r.SetExternalConstraints(cons); for (int k = 0; k < iterations; ++k) { r.BasicRemeshPass(); } //output if (ids.Count > 0 && !fixEdges) { this.Message = "Vertices"; } else if (ids.Count == 0 && fixEdges) { this.Message = "Edges"; } else if (ids.Count > 0 && fixEdges) { this.Message = "Vertices + Edges"; } else { this.Message = ""; } dmesh = new DMesh3(dmesh, true); Mesh rmesh = dmesh.ToRhinoMesh(); if (loops) { Mesh mesh_ = rmesh.DuplicateMesh(); Rhino.IndexPair[] closestEdges = new Rhino.IndexPair[fixPt.Count]; int counter = 0; foreach (Point3d p in fixPt) { double[] d = new double[rmesh.TopologyEdges.Count]; int[] eid = new int[rmesh.TopologyEdges.Count]; for (int i = 0; i < rmesh.TopologyEdges.Count; i++) { if (rmesh.TopologyEdges.GetConnectedFaces(i).Length == 1) { Line line = rmesh.TopologyEdges.EdgeLine(i); line.ClosestPoint(p, true); d[i] = line.ClosestPoint(p, true).DistanceToSquared(p); //line.From.DistanceToSquared(p) + line.To.DistanceToSquared(p); } else { d[i] = 99999; } eid[i] = i; } Array.Sort(d, eid); closestEdges[counter++] = rmesh.TopologyEdges.GetTopologyVertices(eid[0]); } for (int i = 0; i < fixPt.Count; i++) { mesh_.Vertices.Add(fixPt[i]); mesh_.Faces.AddFace(rmesh.Vertices.Count + i, closestEdges[i].I, closestEdges[i].J); } rmesh = mesh_; } rmesh.UnifyNormals(); rmesh.RebuildNormals(); // rmesh.UnifyNormals(); DA.SetData(0, rmesh); }