protected override void SolveInstance(IGH_DataAccess DA) { DMesh3_goo dMsh_goo = null; double w = 1; DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref w); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value, true); LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(dMsh_copy); foreach (int vid in dMsh_copy.VertexIndices()) { if (deformer.IsConstrained(vid) == false) { deformer.SetConstraint(vid, dMsh_copy.GetVertex(vid), w); } } bool success = deformer.SolveAndUpdateMesh(); bool isValid = dMsh_copy.CheckValidity(); if (!success) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Laplacian deform seems to have failed. Please check..."); } if (!isValid) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh seems to have been corrupted during smoothing. Please check..."); } DA.SetData(0, dMsh_copy); }
// [RMS] this only tests some basic cases... public static void test_Laplacian_deformer() { // compact version DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true); Debug.Assert(mesh.IsCompact); AxisAlignedBox3d bounds = mesh.GetBounds(); TestUtil.WriteTestOutputMesh(mesh, "laplacian_deformer_before.obj"); List <IMesh> result_meshes = new List <IMesh>(); LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh); int ti = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2)); int v_pin = mesh.GetTriangle(ti).a; List <int> constraints = new List <int>() { v_pin }; double consPin = 10; double consBottom = 10; foreach (int vid in constraints) { result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(vid), (vid == 0) ? 0.2f : 0.1f, Colorf.Red)); } foreach (int vid in mesh.VertexIndices()) { Vector3d v = mesh.GetVertex(vid); bool bottom = (v.y - bounds.Min.y) < 0.01f; if (constraints.Contains(vid)) { deformer.SetConstraint(vid, v + Vector3f.AxisY, consPin, false); } if (bottom) { deformer.SetConstraint(vid, v, consBottom, false); } } deformer.SolveAndUpdateMesh(); result_meshes.Add(mesh); TestUtil.WriteTestOutputMeshes(result_meshes, "laplacian_deformer_after.obj"); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { DMesh3 mesh = new DMesh3(MakeRemeshedCappedCylinder(1.0), true); AxisAlignedBox3d bounds = mesh.GetBounds(); List <IMesh> result_meshes = new List <IMesh>(); LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh); // constrain bottom points foreach (int vid in mesh.VertexIndices()) { g3.Vector3d v = mesh.GetVertex(vid); bool bottom = (v.y - bounds.Min.y) < 0.01f; if (bottom) { deformer.SetConstraint(vid, v, 10); } } // constrain one other vtx int ti = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new g3.Vector3d(2, 5, 2)); int v_pin = mesh.GetTriangle(ti).a; g3.Vector3d cons_pos = mesh.GetVertex(v_pin); cons_pos += new g3.Vector3d(0.5, 0.5, 0.5); deformer.SetConstraint(v_pin, cons_pos, 10); deformer.Initialize(); g3.Vector3d[] resultV = new g3.Vector3d[mesh.MaxVertexID]; deformer.Solve(resultV); foreach (int vid in mesh.VertexIndices()) { mesh.SetVertex(vid, resultV[vid]); } var rhinoMesh = GopherUtil.ConvertToRhinoMesh(mesh); doc.Objects.AddMesh(rhinoMesh); return(Result.Success); }
// [RMS] this only tests some basic cases... public static void test_LaplacianDeformation() { // compact version DMesh3 mesh = new DMesh3(TestUtil.MakeRemeshedCappedCylinder(1.0), true); Debug.Assert(mesh.IsCompact); AxisAlignedBox3d bounds = mesh.GetBounds(); List <IMesh> result_meshes = new List <IMesh>(); LaplacianMeshDeformer deformer = new LaplacianMeshDeformer(mesh); // constrain bottom points foreach (int vid in mesh.VertexIndices()) { Vector3d v = mesh.GetVertex(vid); bool bottom = (v.y - bounds.Min.y) < 0.01f; if (bottom) { deformer.SetConstraint(vid, v, 10); } } // constrain one other vtx int ti = MeshQueries.FindNearestTriangle_LinearSearch(mesh, new Vector3d(2, 5, 2)); int v_pin = mesh.GetTriangle(ti).a; Vector3d cons_pos = mesh.GetVertex(v_pin); cons_pos += new Vector3d(0.5, 0.5, 0.5); deformer.SetConstraint(v_pin, cons_pos, 10); result_meshes.Add(TestUtil.MakeMarker(mesh.GetVertex(v_pin), 0.2f, Colorf.Red)); deformer.Initialize(); Vector3d[] resultV = new Vector3d[mesh.MaxVertexID]; deformer.Solve(resultV); foreach (int vid in mesh.VertexIndices()) { mesh.SetVertex(vid, resultV[vid]); } result_meshes.Add(mesh); TestUtil.WriteDebugMeshes(result_meshes, "___LAPLACIAN_result.obj"); }
public override void MoveTo(MoveArgs args) { if (BlockMove) { if (args.translate != Vector3.zero) { transform.Translate(args.translate, Space.World); transform.parent.SendMessage("Translate", args); } } else { if (args.translate != Vector3.zero) { MeshFilter mf = GetComponent <MeshFilter>(); Mesh mesh = mf.sharedMesh; Vector3 localTranslate = transform.InverseTransformVector(args.translate); Vector3d target = mesh.vertices[selectedVertex] + localTranslate; if (AppState.instance.editScale > 2) { if (n != AppState.instance.editScale) { n = AppState.instance.editScale; // // first we need to find the n-ring of vertices // // first get 1-ring nRing = new List <int>(); List <Int32> inside = new List <int>(); nRing.Add(selectedVertex); for (int i = 0; i < n; i++) { int[] working = nRing.ToArray(); nRing.Clear(); foreach (int v in working) { if (!inside.Contains(v)) { foreach (int vring in dmesh.VtxVerticesItr(v)) { if (!inside.Contains(vring)) { nRing.Add(vring); } } } inside.Add(v); } } } // // create the deformer // set the constraint that the selected vertex is moved to position // set the contraint that the n-ring remains stationary // LaplacianMeshDeformer deform = new LaplacianMeshDeformer(dmesh); deform.SetConstraint(selectedVertex, target, 1, false); foreach (int v in nRing) { deform.SetConstraint(v, dmesh.GetVertex(v), 10, false); } deform.SolveAndUpdateMesh(); newDmesh = deform.Mesh; } else { dmesh.SetVertex(selectedVertex, target); } // // reset the Unity meh // if (sphere != null) { sphere.transform.localPosition = (Vector3)dmesh.GetVertex(selectedVertex); } List <Vector3> vtxs = new List <Vector3>(); foreach (int v in newDmesh.VertexIndices()) { vtxs.Add((Vector3)newDmesh.GetVertex(v)); } mesh.vertices = vtxs.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); } } }