diff --git a/mesh_ops/MeshLoopSmooth.cs b/mesh_ops/MeshLoopSmooth.cs new file mode 100644 index 00000000..fafa3e43 --- /dev/null +++ b/mesh_ops/MeshLoopSmooth.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; + +namespace g3 +{ + public class MeshLoopSmooth + { + public DMesh3 Mesh; + public EdgeLoop Loop; + + public double Alpha = 0.25f; + public int Rounds = 10; + + // reproject smoothed position to new location + public Func ProjectF; + + + Vector3d[] SmoothedPostions; + + public MeshLoopSmooth(DMesh3 mesh, EdgeLoop loop) + { + Mesh = mesh; + Loop = loop; + + SmoothedPostions = new Vector3d[Loop.Vertices.Length]; + + ProjectF = null; + } + + + public virtual ValidationStatus Validate() + { + ValidationStatus loopStatus = MeshValidation.IsEdgeLoop(Mesh, Loop); + return loopStatus; + } + + + public virtual bool Smooth() + { + int NV = Loop.Vertices.Length; + + double a = MathUtil.Clamp(Alpha, 0, 1); + double num_rounds = MathUtil.Clamp(Rounds, 0, 10000); + + for (int round = 0; round < num_rounds; ++round) { + + // compute + for (int i = 0; i < NV; ++i) { + int vid = Loop.Vertices[(i + 1) % NV]; + Vector3d prev = Mesh.GetVertex(Loop.Vertices[i]); + Vector3d cur = Mesh.GetVertex(vid); + Vector3d next = Mesh.GetVertex(Loop.Vertices[(i + 2) % NV]); + + Vector3d centroid = (prev + next) * 0.5; + SmoothedPostions[i] = (1 - Alpha) * cur + (Alpha) * centroid; + } + + // bake + for (int i = 0; i < NV; ++i) { + int vid = Loop.Vertices[(i + 1) % NV]; + Mesh.SetVertex(vid, SmoothedPostions[i]); + } + } + + return true; + } + + } +} diff --git a/queries/MeshValidation.cs b/queries/MeshValidation.cs index 4d4fc1de..9c71b0d7 100644 --- a/queries/MeshValidation.cs +++ b/queries/MeshValidation.cs @@ -8,6 +8,8 @@ public enum ValidationStatus { Ok, + NotAVertex, + NotBoundaryVertex, NotBoundaryEdge, @@ -19,6 +21,26 @@ public enum ValidationStatus public static class MeshValidation { + public static ValidationStatus IsEdgeLoop(DMesh3 mesh, EdgeLoop loop) + { + int N = loop.Vertices.Length; + for ( int i = 0; i < N; ++i ) { + if ( ! mesh.IsVertex(loop.Vertices[i]) ) + return ValidationStatus.NotAVertex; + } + for (int i = 0; i < N; ++i) { + int a = loop.Vertices[i]; + int b = loop.Vertices[(i + 1) % N]; + + int eid = mesh.FindEdge(a, b); + if (eid == DMesh3.InvalidID) + return ValidationStatus.VerticesNotConnectedByEdge; + } + return ValidationStatus.Ok; + } + + + public static ValidationStatus IsBoundaryLoop(DMesh3 mesh, EdgeLoop loop) { int N = loop.Vertices.Length;