void ModelEdge_Click()
        {
            MeshEdge e = Model.Edges[OpObject.Index];

            if (IsSplitting)
            {
                MeshVertex v = Model.SplitEdgeAt(e, OpObject.Position);
                if (PreviousSplittedVertex != null)
                {
                    Model.AddEdge(PreviousSplittedVertex, v, true);
                }
                PreviousSplittedVertex = v;

                Model.UpdateAll();
                return;
            }

            e.Selected    = true;
            e.V1.Selected = true;
            e.V2.Selected = true;
            Model.UpdateAll();

            Console.WriteLine(e.V1.Position + "-->" + e.V2.Position);
            Console.WriteLine((e.F1 == null ? -1 : e.F1.Index) + ", " +
                              (e.F2 == null ? -1 : e.F2.Index));
        }
示例#2
0
 public MeshEdge Eqv(MeshEdge e)
 {
     if (e == null)
     {
         return(null);
     }
     return(edges[e.Index]);
 }
示例#3
0
        ////////////////////////////////////////////////////////////////////////

        public MeshVertex SplitEdgeAt(MeshEdge e, Vector3 pos)
        {
            if (Edges[e.Index] != e)
            {
                return(null);
            }

            MeshVertex new_v = this.AddVertex(pos);

            // save the vertex sequences of adjacency facets
            List <MeshVertex> f1v = new List <MeshVertex>();
            List <MeshVertex> f2v = new List <MeshVertex>();

            if (e.F1 != null)
            {
                for (int i = 0; i < e.F1.Vertices.Count; i++)
                {
                    var vs = e.F1.Vertices;
                    f1v.Add(vs[i]);
                    MeshEdge cur_e = vs[i].EdgeConnecting(vs[(i + 1) % vs.Count]);
                    if (cur_e == e)
                    {
                        f1v.Add(new_v);
                    }
                }
            }

            if (e.F2 != null)
            {
                for (int i = 0; i < e.F2.Vertices.Count; i++)
                {
                    var vs = e.F2.Vertices;
                    f2v.Add(vs[i]);
                    MeshEdge cur_e = vs[i].EdgeConnecting(vs[(i + 1) % vs.Count]);
                    if (cur_e == e)
                    {
                        f2v.Add(new_v);
                    }
                }
            }

            // reconstruct facet
            this.RemoveEdge(e);
            if (f1v.Count > 0)
            {
                this.AddFacet(f1v.ToArray());
            }
            if (f2v.Count > 0)
            {
                this.AddFacet(f2v.ToArray());
            }

            return(new_v);
        }
示例#4
0
        public MeshGraph Clone()
        {
            MeshGraph mg = new MeshGraph();

            mg.triangles = this.triangles;

            foreach (MeshVertex v in vertices)
            {
                MeshVertex new_v = new MeshVertex(v.Position);
                new_v.SetGraphInfo(mg, mg.vertices.Count);
                mg.vertices.Add(new_v);
            }

            foreach (MeshEdge e in edges)
            {
                MeshEdge new_e = new MeshEdge(mg.Eqv(e.V1), mg.Eqv(e.V2));
                new_e.SetGraphInfo(mg, mg.edges.Count);
                mg.edges.Add(new_e);
            }

            foreach (MeshFacet f in facets)
            {
                MeshFacet new_f = new MeshFacet();
                foreach (MeshVertex v in f.vertices)
                {
                    new_f.vertices.Add(mg.Eqv(v));
                }
                new_f.SetGraphInfo(mg, mg.facets.Count);
                mg.facets.Add(new_f);
            }

            // Maintain adjacency cache
            foreach (MeshEdge e in mg.edges)
            {
                MeshEdge old_e = this.Eqv(e);
                e.f1 = mg.Eqv(old_e.f1);
                e.f2 = mg.Eqv(old_e.f2);
            }

            foreach (MeshVertex v in mg.vertices)
            {
                MeshVertex old_v = this.Eqv(v);
                foreach (var entry in old_v.adjacency)
                {
                    v.adjacency.Add(mg.Eqv(entry.Key), mg.Eqv(entry.Value));
                }
            }

            return(mg);
        }
示例#5
0
        public void RemoveEdge(MeshEdge e)
        {
            int i = e.Index;

            if (edges[i] != e)
            {
                return;
            }

            if (i != edges.Count - 1)
            {
                edges[i] = edges.Last();
                edges[i].SetGraphInfo(this, i);
            }

            edges.RemoveAt(edges.Count - 1);
            e.Selected = false;
            e.ClearAdjacency();
            e.p1.adjacency.Remove(e.p2);
            e.p2.adjacency.Remove(e.p1);
        }
        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);
                }
            }
        }
示例#7
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));
        }
示例#8
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);
        }
示例#9
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);
        }