protected virtual DMesh3 compute_sharp_edge_flow() { DMesh3 sourceMesh = MeshSource.GetDMeshUnsafe(); ISpatial inputSpatial = MeshSource.GetSpatial(); DMesh3 targetMesh = TargetSource.GetDMeshUnsafe(); ISpatial targetSpatial = TargetSource.GetSpatial(); DMesh3 meshIn = new DMesh3(sourceMesh); if (is_invalidated()) { return(null); } RemesherPro remesher = new RemesherPro(meshIn); remesher.SetTargetEdgeLength(TargetEdgeLength); remesher.PreventNormalFlips = this.PreventNormalFlips; remesher.EnableFlips = this.EnableFlips; remesher.EnableSplits = this.EnableSplits; remesher.EnableCollapses = this.EnableCollapses; remesher.EnableSmoothing = this.EnableSmoothing; remesher.SmoothSpeedT = this.SmoothingSpeed; TransformedMeshProjectionTarget target = new TransformedMeshProjectionTarget(targetMesh, targetSpatial) { SourceToTargetXForm = source_to_target, TargetToSourceXForm = target_to_source }; remesher.SetProjectionTarget(target); if (sourceMesh.CachedIsClosed == false) { if (remesher.Constraints == null) { remesher.SetExternalConstraints(new MeshConstraints()); } if (BoundaryMode == BoundaryModes.FreeBoundaries) { MeshConstraintUtil.PreserveBoundaryLoops(remesher.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.FixedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges(remesher.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.ConstrainedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(remesher.Constraints, meshIn, 0); } } if (is_invalidated()) { return(null); } remesher.Progress = new ProgressCancel(is_invalidated); remesher.SharpEdgeReprojectionRemesh(RemeshRounds, ProjectionRounds); if (is_invalidated()) { return(null); } return(meshIn); }
protected virtual DMesh3 compute_standard() { DMesh3 sourceMesh = MeshSource.GetDMeshUnsafe(); ISpatial sourceSpatial = MeshSource.GetSpatial(); DMesh3 meshIn = new DMesh3(sourceMesh); RemesherPro remesh = new RemesherPro(meshIn); //Remesher remesh = new Remesher(meshIn); remesh.SetTargetEdgeLength(TargetEdgeLength); remesh.PreventNormalFlips = this.PreventNormalFlips; remesh.EnableFlips = this.EnableFlips; remesh.EnableSplits = this.EnableSplits; remesh.EnableCollapses = this.EnableCollapses; remesh.EnableSmoothing = this.EnableSmoothing; remesh.SmoothSpeedT = this.SmoothingSpeed; if (ReprojectToInput) { MeshProjectionTarget target = new MeshProjectionTarget(sourceMesh, sourceSpatial); remesh.SetProjectionTarget(target); } // if we are preserving creases, this will also automatically constrain boundary // edges boundary loops/spans. if (preserve_creases) { if (remesh.Constraints == null) { remesh.SetExternalConstraints(new MeshConstraints()); } MeshTopology topo = new MeshTopology(meshIn); topo.CreaseAngle = this.CreaseAngle; topo.AddRemeshConstraints(remesh.Constraints); // replace boundary edge constraints if we want other behaviors if (BoundaryMode == BoundaryModes.FixedBoundaries) { MeshConstraintUtil.FixEdges(remesh.Constraints, meshIn, topo.BoundaryEdges); } } else if (sourceMesh.CachedIsClosed == false) { if (remesh.Constraints == null) { remesh.SetExternalConstraints(new MeshConstraints()); } if (BoundaryMode == BoundaryModes.FreeBoundaries) { MeshConstraintUtil.PreserveBoundaryLoops(remesh.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.FixedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges(remesh.Constraints, meshIn); } else if (BoundaryMode == BoundaryModes.ConstrainedBoundaries) { MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(remesh.Constraints, meshIn, 0); } } remesh.Progress = new ProgressCancel(is_invalidated); remesh.FastestRemesh(RemeshRounds, true); //for (int k = 0; k < RemeshRounds; ++k) // remesh.BasicRemeshPass(); // free boundary remesh can leave sliver triangles around the border. clean that up. if (sourceMesh.CachedIsClosed == false && BoundaryMode == BoundaryModes.FreeBoundaries) { MeshEditor.RemoveFinTriangles(meshIn, (mesh, tid) => { Index3i tv = mesh.GetTriangle(tid); return(MathUtil.AspectRatio(mesh.GetVertex(tv.a), mesh.GetVertex(tv.b), mesh.GetVertex(tv.c)) > 2); }); } if (is_invalidated()) { return(null); } return(meshIn); }
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); }