////////////////////////////////////////////////////////////////////////
        /// 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();
        }
示例#3
0
        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);
        }
示例#5
0
        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
        }
示例#6
0
        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]);
                }
            }
        }
示例#8
0
        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);
        }
示例#9
0
        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();
        }
示例#10
0
        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);
                }
            }
        }
示例#12
0
        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();
        }
示例#13
0
        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));
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
 public MeshEdge(MeshVertex v1, MeshVertex v2)
 {
     p1 = v1;
     p2 = v2;
 }