public MoveVertexAction(Render render, Controller ctrl, VertexSelection sel) : base(render, ctrl) { vertex = sel.vertex; origin = vertex.position; edges = new List <TempEdge>(); face_rends = new List <FaceRenderer>(); foreach (var face in render.model.faces) { int i = face.vertices.IndexOf(vertex); if (i >= 0) { edges.Add(new TempEdge { sel = new EdgeSelection { face = face, num = face.VertexNum(i - 1) }, far_vertex = face.GetVertex(i - 1), direction = origin - face.GetVertex(i - 1).position }); edges.Add(new TempEdge { sel = new EdgeSelection { face = face, num = i }, far_vertex = face.GetVertex(i + 1), direction = origin - face.GetVertex(i + 1).position }); face_rends.Add(render.GetFaceRenderer(face)); } } }
public static Selection FindClosest(Vector3 point, Model model, bool color_in_face = false) { Selection result = VertexSelection.FindClosestVertex(point, model); if (result == null) { result = EdgeSelection.FindClosestEdge(point, model); } if (result == null) { result = FaceSelection.FindClosestFace(point, model, color_in_face); } return(result); }
public override void Drag() { Vector3 pos = render.world.InverseTransformPoint(ctrl.position); EdgeSelection closest_edge; var subspace = SnapPosition(pos, out closest_edge); var ptsubspace = new PointedSubspace(subspace, origin); Vector3 otherpos = render.world.InverseTransformPoint(other_ctrl.position); Selection othersel = Selection.FindClosest(otherpos, render.model, color_in_face: true); Vector3? dummyedge_from = null; string other_ctrl_hint = null; if (othersel != null) { AddSelection(othersel, GUIDE_COLOR); if (!othersel.ContainsVertex(vertex)) { PointedSubspace otherptsubspace = othersel.GetPointedSubspace(); if (othersel is VertexSelection) { Vertex v = ((VertexSelection)othersel).vertex; var foot = v.position; otherptsubspace = new PointedSubspace(subspace.NormalSubspace(), foot); if (closest_edge != null && closest_edge.ContainsVertex(v)) { float distance = Vector3.Distance(v.position, pos); int cm_distance = Mathf.RoundToInt(distance * 100 / 5) * 5; other_ctrl_hint = "clamped at " + cm_distance + " cm"; var point0 = v.position + cm_distance * 0.01f * (origin - v.position).normalized; ptsubspace = new PointedSubspace(new Subspace0(), point0); otherptsubspace = PointedSubspace.Void(); } else if (subspace is Subspace0) { float distance = Vector3.Distance(v.position, origin); int mm_distance = Mathf.RoundToInt(distance * 1000); other_ctrl_hint = (mm_distance / 10.0).ToString() + " cm"; } } else if (othersel is EdgeSelection) { Vertex v1, v2; ((EdgeSelection)othersel).GetVertices(out v1, out v2); Vector3 foot1 = v1.position; Vector3 foot2 = v2.position; Subspace orthogonal_plane = new Subspace2(foot2 - foot1); var ptsub1 = new PointedSubspace(orthogonal_plane, foot1); var ptsub2 = new PointedSubspace(orthogonal_plane, foot2); var dist0 = otherptsubspace.Distance(pos); var dist1 = ptsub1.Distance(pos); var dist2 = ptsub2.Distance(pos); if (dist1 <= dist0 && dist1 <= dist2) { otherptsubspace = ptsub1; othersel = new VertexSelection { vertex = v1 }; } else if (dist2 <= dist0 && dist2 <= dist1) { otherptsubspace = ptsub2; othersel = new VertexSelection { vertex = v2 }; } } if (otherptsubspace.Distance(pos) < Selection.DISTANCE_VERTEX_MIN) { ptsubspace = ptsubspace.IntersectedWith(otherptsubspace); dummyedge_from = othersel.Center(); } } } pos = ptsubspace.Snap(pos); vertex.position = pos; foreach (var face_rend in face_rends) { face_rend.ComputeMesh(); } if (dummyedge_from.HasValue) { AddSelection(EdgeSelection.DummyEdgeSelection(dummyedge_from.Value, pos), GUIDE_COLOR); } AddSelection(new VertexSelection { vertex = vertex }, subspace is Subspace0 ? Darker(COLOR) : COLOR); SelectionFinished(); if (other_ctrl.CurrentHoverTracker() == null) { ControllerMode.Get(other_ctrl).UpdatePointer(render, EMode.Guide); other_ctrl.SetControllerHints(trigger: other_ctrl_hint); } }