Beispiel #1
1
        public HalfEdge GetEdge(Vertex a, Vertex b, Face f, HalfEdge abNext)
        {
            List<HalfEdge> appropriateEdges;
            if (edges.ContainsKey(b))
            {
                appropriateEdges = edges[b];
            }
            else
            {
                appropriateEdges = new List<HalfEdge>();
                edges[b] = appropriateEdges;
            }

            var query = appropriateEdges.Where(x => x.Twin.End == a);
            switch (query.Count())
            {
                case 0:
                    {
                        HalfEdge edge = new HalfEdge(this, null, true);
                        HalfEdge twin = edge.Twin;
                        edge.End = b;
                        twin.End = a;
                        edge.Face = f;
                        edge.Next = abNext;
                        return edge;
                    }
                case 1:
                    {
                        var edge = query.First();

                        if (abNext != null && edge.Next != abNext && edge.Next != null)
                            throw new ArgumentException("Edge already attached to edge " + edge.Next);

                        if (f != null && edge.Face != f && edge.Face != null)
                            throw new ArgumentException("Edge already attached to face " + edge.Face);

                        edge.Face = f ?? edge.Face;
                        edge.Next = abNext ?? edge.Next;
                        return edge;
                    }
                default:
                    throw new MeshMalformedException("More than one edge already exists between " + a + " and " + b);
            }
        }
Beispiel #2
0
        private IEnumerable<ProceduralFace> Split(Face f)
        {
            HashSet<HalfEdge> edges = new HashSet<HalfEdge>();
            foreach (var edge in f.Edges)
            {
                var dir = (edge.End.Position - edge.Twin.End.Position);
                if (Math.Abs(dir.X) > 0.1f || Math.Abs(dir.Z) > 0.1f)
                    edges.Add(edge);
            }

            if (edges.Count != 2)
                throw new InvalidOperationException("Not 2 edges");

            int splits = 2;
            foreach (var edge in edges)
            {
                var dir = edge.End.Position - edge.Twin.End.Position;
                var step = dir / (float)splits;
                var start = edge.Twin.End.Position;

                for (int i = 1; i < splits; i++)
                    edge.Split(Mesh.GetVertex(start + step * i));
            }

            Vertex[] vertices = f.Vertices.ToArray();

            f.Delete();

            for (int i = 0; i < vertices.Length / 2 - 1; i++)
            {
                yield return (ProceduralFace)Mesh.GetFace(vertices[i], vertices[i + 1], vertices[vertices.Length - 2 - i], vertices[vertices.Length - 1 - i]);
            }

            //return new List<ProceduralFace>();
        }
Beispiel #3
0
        private IEnumerable<ProceduralFace> Split(Face f)
        {
            Vertex[] v = f.Vertices.ToArray();

            f.Delete();

            Vector3 up = -new Plane(v[0].Position, v[1].Position, v[2].Position).Normal;

            Vertex a = Mesh.GetVertex(v[0].Position * 0.5f + v[1].Position * 0.5f + up * 2);
            Vertex b = Mesh.GetVertex(v[2].Position * 0.5f + v[3].Position * 0.5f + up * 2);

            yield return (ProceduralFace)Mesh.GetFace(v[1], v[2], b, a);
            yield return (ProceduralFace)Mesh.GetFace(v[3], v[0], a, b);
            yield return (ProceduralFace)Mesh.GetFace(v[0], v[1], a);
            yield return (ProceduralFace)Mesh.GetFace(v[2], v[3], b);
        }
Beispiel #4
0
 public void Deleted(Face f)
 {
     changes.Push(new DeleteFace(f));
 }
Beispiel #5
0
 public void Added(Face f)
 {
     changes.Push(new AddFace(f));
 }
Beispiel #6
0
 public DeleteFace(Face f)
 {
     Border = f.Vertices.Select(a => a.Position).ToArray();
 }
Beispiel #7
0
 public AddFace(Face f)
 {
     Border = f.Vertices.ToArray();
 }
Beispiel #8
0
 public void SplitMidpointEnd(Face f, Vertex mid)
 {
     throw new NotImplementedException();
 }
Beispiel #9
0
        public Face GetFace(IEnumerable<Vertex> vertices)
        {
            //throw new NotImplementedException("Check if this face already exists");
            //throw new NotImplementedException("Check if this face would conflict with an already existing face");

            List<HalfEdge> edges = new List<HalfEdge>();
            Face f = new Face();

            Vertex first = null;
            Vertex previous = null;
            foreach (var v in vertices)
            {
                if (first == null)
                    first = v;
                else
                    edges.Add(GetEdge(previous, v, f, null));

                previous = v;
            }

            edges.Add(GetEdge(previous, first, f, null));

            for (int i = 0; i < edges.Count; i++)
            {
                var next = edges[(i + 1) % edges.Count];

                if (edges[i].Next != null && edges[i].Next != next)
                    throw new InvalidOperationException("Cannot link edges, conflicting link already exists");

                edges[i].Next = edges[(i + 1) % edges.Count];
            }

            foreach (var vertex in vertices)
            {
                var set = faces.GetOrAdd(vertex, a => new ConcurrentDictionary<Face, bool>());
                set.AddOrUpdate(f, true, (a, b) => { throw new InvalidOperationException(); });
            }

            return f;
        }
Beispiel #10
0
 public HalfEdge GetEdge(Vertex a, Vertex b, Face abf, HalfEdge abNext, Face baf, HalfEdge baNext)
 {
     throw new NotImplementedException();
 }