//////////////////////////////////////////////////////////////////////// /// Semantic Events void ModelVertex_Click() { if (IsSplitting) { if (PreviousSplittedVertex != null) { Model.AddEdge(PreviousSplittedVertex, Model.Vertices[OpObject.Index], true); } PreviousSplittedVertex = Model.Vertices[OpObject.Index]; Model.UpdateAll(); return; } Model.Vertices[OpObject.Index].Selected = true; Model.UpdateAll(); }
private void glc_MouseUp(Object sender, MouseEventArgs e) { // Was to drag but didn't, treated as clicked if (!DragInfo.WasDragging) { // This behavious is usually cancelling actions if (DragInfo.State == DragState.RightButton) { IsSplitting = false; PreviousSplittedVertex = null; } else if (DragInfo.State == DragState.LeftButton) { OpObject = ObjectMapFuzzy(e.X, e.Y, 3, (int)ObjectType.ModelVertex); TryKeepSelection(); if (OpObject.Type == ObjectType.ModelVertex) { ModelVertex_Click(); } else if (OpObject.Type == ObjectType.ModelEdge) { ModelEdge_Click(); } else if (OpObject.Type == ObjectType.ModelFacet) { ModelFacet_Click(); } } } else if (DragInfo.State == DragState.None) { TryKeepSelection(); } if (DragInfo.State == DragState.BoxSelect) { BoxSelect_Finished(); this.BoxSelectingType = ObjectType.None; } DragInfo.Reset(); }
public void RemoveVertex(MeshVertex v) { int i = v.Index; if (vertices[i] != v) { return; } if (i != vertices.Count - 1) { vertices[i] = vertices.Last(); vertices[i].SetGraphInfo(this, i); } vertices.RemoveAt(vertices.Count - 1); v.Selected = false; v.ClearAdjacency(); }
public override void AddMeshGraphUpon( ref MeshGraph mg, bool selected = true) { MeshVertex[,] vs = new MeshVertex[VSubdivision - 1, USubdivision]; for (int v = 1; v < VSubdivision; v++) { for (int u = 0; u < USubdivision; u++) { double a = Math.PI * 2 * u / USubdivision; double b = -Math.PI * v / VSubdivision + Math.PI / 2; vs[v - 1, u] = mg.AddVertex( (float)(Radius * Math.Cos(a) * Math.Cos(b)), (float)(Radius * Math.Sin(b)), -(float)(Radius * Math.Sin(a) * Math.Cos(b))); } } for (int v = 0; v < VSubdivision - 2; v++) { for (int u = 0; u < USubdivision; u++) { mg.AddFacet(vs[v, u], vs[v + 1, u], vs[v + 1, (u + 1) % USubdivision], vs[v, (u + 1) % USubdivision]); } } MeshVertex top = mg.AddVertex(0, Radius, 0), btm = mg.AddVertex(0, -Radius, 0); for (int u = 0; u < USubdivision; u++) { mg.AddFacet(top, vs[0, u], vs[0, (u + 1) % USubdivision]); mg.AddFacet(vs[VSubdivision - 2, (u + 1) % USubdivision], vs[VSubdivision - 2, u], btm); } foreach (MeshVertex v in vs) { SelectAdjacency(v); } SelectAdjacency(top); SelectAdjacency(btm); }
public RotationTransformerRenderer() : base(ObjectType.RotationTransformer) { MeshVertex[] vs = new MeshVertex[32]; for (int i = 0; i < 32; i++) { double a = 2.0 * Math.PI * i / 32.0; vs[i] = axis.AddVertex(1.5f * (float)Math.Cos(a), 0, 1.5f * (float)Math.Sin(a)); if (i > 0) { axis.AddEdge(vs[i - 1], vs[i]); } } axis.AddEdge(vs[31], vs[0]); axis.EdgeData.UpdateData(); axisTfs = new Matrix4[3]; axisTfs[0] = Matrix4.CreateRotationZ((float)Math.PI / 2); // x axisTfs[1] = Matrix4.Identity; // y axisTfs[2] = Matrix4.CreateRotationX((float)Math.PI / 2); // z }
public GridRenderer() { SetSource(vertex_shader_source, "", fragment_shader_source); grid = new MeshGraph(); for (int i = -50; i < 50; i++) { MeshVertex v1 = grid.AddVertex(i, 0, -50); MeshVertex v2 = grid.AddVertex(i, 0, 50); grid.AddEdge(v1, v2); } for (int i = -50; i < 50; i++) { MeshVertex v1 = grid.AddVertex(-50, 0, i); MeshVertex v2 = grid.AddVertex(50, 0, i); grid.AddEdge(v1, v2); } grid.EdgeData.UpdateData(); }
public override void AddMeshGraphUpon( ref MeshGraph mg, bool selected = true) { MeshVertex[,] vs = new MeshVertex[USubdivision + 1, VSubdivision + 1]; for (int i = 0; i <= VSubdivision; i++) { for (int j = 0; j <= USubdivision; j++) { vs[i, j] = mg.AddVertex(Size * j / USubdivision - Size / 2, 0, -Size * i / VSubdivision - Size / 2); } } for (int i = 0; i < VSubdivision; i++) { for (int j = 0; j < USubdivision; j++) { mg.AddFacet(vs[i, j], vs[i, j + 1], vs[i + 1, j + 1], vs[i + 1, j]); } } }
public ScalingTransformerRenderer() : base(ObjectType.ScalingTransformer) { new BoxMeshFactory(0.1f, 0.1f, 0.1f) .AddMeshGraphUpon(ref axis, false); foreach (MeshVertex v in axis.Vertices) { v.Position = v.Position + new Vector3(0, 0, 3); } MeshVertex vorg = axis.AddVertex(0, 0, 0); MeshVertex vhead = axis.AddVertex(0, 0, 3); axis.AddEdge(vorg, vhead); axis.EdgeData.UpdateData(); axis.FacetData.UpdateData(); axisTfs = new Matrix4[3]; axisTfs[0] = Matrix4.CreateRotationY((float)Math.PI / 2); axisTfs[1] = Matrix4.CreateRotationX(-(float)Math.PI / 2); axisTfs[2] = Matrix4.Identity; Scaling = new Vector3(1, 1, 1); }
public void f_Selection_Select_Neighbours() { Stack <MeshVertex> vstack = new Stack <MeshVertex>(ParentWindow.Model.SelectedVertices); ParentWindow.Model.DeselectAll(); while (vstack.Count > 0) { MeshVertex v = vstack.Pop(); if (v.Selected) { continue; } v.Selected = true; foreach (MeshEdge e in v.Edges) { e.Selected = true; if (e.F1 != null) { e.F1.Selected = true; } if (e.F2 != null) { e.F2.Selected = true; } } foreach (MeshVertex adj in v.AdjacencyVertices) { vstack.Push(adj); } } ParentWindow.Model.UpdateAll(); }
public override void AddMeshGraphUpon( ref MeshGraph mg, bool selected = true) { MeshVertex[] topf = new MeshVertex[Subdivision]; MeshVertex[] btmf = new MeshVertex[Subdivision]; for (int i = 0; i < Subdivision; i++) { double a = Math.PI * 2 * i / Subdivision; topf[i] = mg.AddVertex(Radius * (float)Math.Cos(a), Height / 2, -Radius * (float)Math.Sin(a)); btmf[i] = mg.AddVertex(Radius * (float)Math.Cos(a), -Height / 2, -Radius * (float)Math.Sin(a)); } mg.AddFacet(topf); mg.AddFacet(btmf.Reverse().ToArray()); for (int i = 0; i < Subdivision; i++) { mg.AddFacet(topf[i], btmf[i], btmf[(i + 1) % Subdivision], topf[(i + 1) % Subdivision]); } }
public void CreateTriangle() { MeshVertex v1 = new MeshVertex(1, 0, 1); MeshVertex v2 = new MeshVertex(2, 1, 0); MeshVertex v3 = new MeshVertex(1, 3, 1); MeshGraph mg = new MeshGraph(); mg.AddVertex(v1); mg.AddVertex(v2); mg.AddVertex(v3); MeshEdge e1 = mg.AddEdge(v1, v2); MeshEdge e2 = mg.AddEdge(v3, v2); MeshFacet f = mg.AddFacet(v1, v2, v3); CollectionAssert.Contains(mg.Vertices, v1); CollectionAssert.Contains(mg.Vertices, v2); CollectionAssert.Contains(mg.Vertices, v3); Assert.AreEqual(v1.EdgeConnecting(v2), v2.EdgeConnecting(v1), "", e1); Assert.AreEqual(v3.EdgeConnecting(v2), v2.EdgeConnecting(v3), "", e2); CollectionAssert.Contains(mg.Edges, v1.EdgeConnecting(v2)); CollectionAssert.Contains(mg.Edges, v2.EdgeConnecting(v3)); CollectionAssert.Contains(mg.Edges, v3.EdgeConnecting(v1)); CollectionAssert.Contains(e1.AdjacencyFacets, f); CollectionAssert.Contains(e1.Endpoints, v1); CollectionAssert.Contains(f.Vertices, v1); CollectionAssert.Contains(f.Vertices, v2); CollectionAssert.Contains(f.Vertices, v3); CollectionAssert.Contains(f.Edges, v1.EdgeConnecting(v2)); CollectionAssert.Contains(f.Edges, v2.EdgeConnecting(v3)); CollectionAssert.Contains(f.Edges, v3.EdgeConnecting(v1)); { // Remove the facet MeshGraph rm = mg.Clone(); MeshFacet rmf = rm.Eqv(f); rm.RemoveFacet(rmf); CollectionAssert.DoesNotContain(rm.Facets, rmf); CollectionAssert.DoesNotContain( rm.Eqv(e1).AdjacencyFacets, rmf); CollectionAssert.DoesNotContain( rm.Eqv(e2).AdjacencyFacets, rmf); } { // Remove an edge MeshGraph rm = mg.Clone(); MeshEdge rme = rm.Eqv(e1); MeshFacet rmf = rm.Eqv(f); rm.RemoveEdge(rme); CollectionAssert.DoesNotContain(rm.Edges, rme); CollectionAssert.DoesNotContain(rm.Facets, rmf); CollectionAssert.DoesNotContain( rme.AdjacencyFacets, rmf); CollectionAssert.DoesNotContain( rm.Eqv(e2).AdjacencyFacets, rmf); } { // Remove an vertex MeshGraph rm = mg.Clone(); MeshVertex rmv = rm.Eqv(v2); MeshEdge rme1 = rm.Eqv(v2.EdgeConnecting(rm.Eqv(v1))); MeshEdge rme2 = rm.Eqv(v2.EdgeConnecting(rm.Eqv(v3))); MeshFacet rmf = rm.Eqv(f); rm.RemoveVertex(rmv); CollectionAssert.DoesNotContain(rm.Vertices, rmv); CollectionAssert.DoesNotContain(rm.Edges, rme1); CollectionAssert.DoesNotContain(rm.Edges, rme2); CollectionAssert.DoesNotContain(rm.Facets, rmf); Assert.AreEqual(rmv.Edges.Count, 0); foreach (var v in rm.Vertices) { Assert.AreEqual(v.Edges.Count, 1); } } }
public void f_Edit_Join() { // find outer edges and duplicated(inner) edges Dictionary <MeshEdge, bool> edtable = new Dictionary <MeshEdge, bool>(); HashSet <MeshEdge> dup_edges = new HashSet <MeshEdge>(); foreach (MeshFacet f in ParentWindow.Model.SelectedFacets) { foreach (MeshEdge e in f.Edges) { if (dup_edges.Contains(e)) { continue; } else if (edtable.ContainsKey(e)) { edtable.Remove(e); dup_edges.Add(e); continue; } edtable.Add(e, e.F1 == f ? true : false); } } List <MeshVertex> vs = new List <MeshVertex>(); vs.Add(edtable.First().Value ? edtable.First().Key.V1 : edtable.First().Key.V2); MeshVertex cur_v = edtable.First().Value ? edtable.First().Key.V2 : edtable.First().Key.V1; while (cur_v != vs[0]) { vs.Add(cur_v); foreach (MeshEdge e in cur_v.Edges) { if (edtable.ContainsKey(e)) { if (edtable[e] && e.V1 == cur_v) { cur_v = e.V2; break; } if (!edtable[e] && e.V2 == cur_v) { cur_v = e.V1; break; } } } if (cur_v == vs.Last()) { throw new Exception("Unknown Error"); } } List <MeshFacet> oldfacets = new List <MeshFacet>(ParentWindow.Model.SelectedFacets); foreach (MeshFacet f in oldfacets) { ParentWindow.Model.RemoveFacet(f); } foreach (MeshEdge e in dup_edges) { ParentWindow.Model.RemoveEdge(e); } ParentWindow.Model.AddFacet(vs.ToArray()); ParentWindow.Model.UpdateAll(); }
public MeshFacet AddTriangle(Vector3 posdir, params MeshVertex[] vs) { // There should always be one edge that has connected with // another facet to create a correct facet, otherwise the // algorithm will create the facet corresponding to posdir bool has_connected_edge = false; // After sorting, vs[0] -> vs[1] -> vs[2] is a positive order for (int i = 0; i < 2; i++) { for (int j = i + 1; j < 2; j++) { MeshEdge e = vs[i].EdgeConnecting(vs[j]); if (e == null) { continue; } if (e.F1 != null) { has_connected_edge = true; MeshVertex[] sorted_vs = new MeshVertex[3]; sorted_vs[0] = e.V2; sorted_vs[1] = e.V1; sorted_vs[2] = vs[3 - i - j]; vs = sorted_vs; break; } if (e.F2 != null) { has_connected_edge = true; MeshVertex[] sorted_vs = new MeshVertex[3]; sorted_vs[0] = e.V1; sorted_vs[1] = e.V2; sorted_vs[2] = vs[3 - i - j]; vs = sorted_vs; break; } } } if (!has_connected_edge) { Vector3 normal = Vector3.Cross( vs[1].Position - vs[0].Position, vs[2].Position - vs[1].Position); if (Vector3.Dot(posdir, normal) < 0) { MeshVertex[] sorted_vs = new MeshVertex[3]; sorted_vs[0] = vs[2]; sorted_vs[1] = vs[1]; sorted_vs[2] = vs[0]; vs = sorted_vs; } } return(this.AddFacet(vs)); }
public MeshFacet AddFacet(params MeshVertex[] vs) { if (vs.Length < 3) { throw new Exception("Vertex count less than 3."); } for (int vi = 0; vi < vs.Length; vi++) { if (vs[vi] == vs[(vi + 1) % vs.Length]) { throw new Exception("Ill-formed vertex sequence"); } } MeshFacet f = new MeshFacet(vs); string failure = ""; for (int vi = 0; vi < vs.Length; vi++) { MeshVertex p1 = vs[vi]; MeshVertex p2 = vs[(vi + 1) % vs.Length]; MeshEdge e = AddEdge(p1, p2); if (e.V1 == p1 && e.V2 == p2) { if (e.f1 != null) { failure = "Positive facet has been occupied"; break; } e.f1 = f; } else if (e.V1 == p2 && e.V2 == p1) { if (e.f2 != null) { failure = "Negative facet has been occupied"; break; } e.f2 = f; } else { throw new Exception("Unexpected edge"); } } // rollback if (failure.Length > 0) { foreach (MeshEdge e in f.Edges) { if (e == null) { continue; } if (e.f1 == f) { e.f1 = null; } if (e.f2 == f) { e.f2 = null; } } throw new Exception(failure); } int i = facets.Count; facets.Add(f); f.SetGraphInfo(this, i); triangles += f.TrianglesCount; return(f); }
public MeshEdge AddEdge(MeshVertex p1, MeshVertex p2, bool check_facet = false) { MeshEdge e = p1.EdgeConnecting(p2); if (e != null) { return(e); } if (p1 == p2) { return(null); } e = new MeshEdge(p1, p2); p1.adjacency.Add(p2, e); p2.adjacency.Add(p1, e); int i = edges.Count; edges.Add(e); e.SetGraphInfo(this, i); if (check_facet) { // check the intersection MeshFacet common_facet = null; HashSet <MeshFacet> p1f = new HashSet <MeshFacet>( p1.AdjacencyFacets); foreach (MeshFacet f in p2.AdjacencyFacets) { if (p1f.Contains(f)) { common_facet = f; break; } } if (common_facet != null) { List <MeshVertex> f1 = new List <MeshVertex>(); List <MeshVertex> f2 = new List <MeshVertex>(); List <MeshVertex> current = f1; foreach (MeshVertex v in common_facet.Vertices) { // if current vertex matches p1 or p2, add this vertex // to both vertex list and switch current to the other one current.Add(v); if (v == p1) { current = current == f1 ? f2 : f1; current.Add(p1); } else if (v == p2) { current = current == f1 ? f2 : f1; current.Add(p2); } } this.RemoveFacet(common_facet); this.AddFacet(f1.ToArray()); this.AddFacet(f2.ToArray()); } } return(e); }
public MeshEdge(MeshVertex v1, MeshVertex v2) { p1 = v1; p2 = v2; }