Beispiel #1
0
        // public void ReIndex() //clear away all the dead elements to save space
        // //maybe it is better to just create a fresh one rather than trying to shuffle the existing
        // {
        // }
        public P_mesh Dual()
        {
            // can later add options for other ways of defining face centres (barycenter/circumcenter etc)
            // won't work yet with naked boundaries

            P_mesh P = this;
            P_mesh D = new P_mesh();

            //for every primal face, add the barycenter to the dual's vertex list
            //dual vertex outgoing HE is primal face's start HE
            //for every vertex of the primal, add a face to the dual
            //dual face's startHE is primal vertex's outgoing's pair

            for (int i = 0; i < P.Faces.Count; i++)
            {
                    D.Vertices.Add(new P_vertex(P.FaceCentroid(i)));
                    List<int> FaceHalfedges = P.FaceHEs(i);
                    for (int j = 0; j < FaceHalfedges.Count; j++)
                    {
                        if (P.HalfEdges[P.PairHalfEdge(FaceHalfedges[j])].AdjacentFace != -1)
                        {
                         // D.Vertices[i].OutgoingHalfEdge = FaceHalfedges[j];
                            D.Vertices[D.Vertices.Count-1].OutgoingHalfEdge = P.PairHalfEdge(FaceHalfedges[j]);
                            break;
                        }
                    }
            }

            for (int i = 0; i < P.Vertices.Count; i++)
            {
                if (P.VertexNakedEdgeCount(i) == 0)
                {
                    D.Faces.Add(new P_face());
                 // D.Faces[i].FirstHalfEdge = P.PairHalfEdge(P.Vertices[i].OutgoingHalfEdge);
                    D.Faces[D.Faces.Count-1].FirstHalfEdge = P.Vertices[i].OutgoingHalfEdge;
                }
            }

            // dual halfedge start V is primal AdjacentFace
            // dual halfedge AdjacentFace is primal end V
            // dual nextHE is primal's pair's prev
            // dual prevHE is primal's next's pair

            // halfedge pairs stay the same

            int newIndex = 0;

            for (int i = 0; i < P.HalfEdges.Count; i++)
            {
                if ((P.HalfEdges[i].AdjacentFace != -1) & (P.HalfEdges[P.PairHalfEdge(i)].AdjacentFace != -1))
                {
                    P_halfedge DualHE = new P_halfedge();
                    P_halfedge PrimalHE = P.HalfEdges[i];
                    //DualHE.StartVertex = PrimalHE.AdjacentFace;
                    DualHE.StartVertex = P.HalfEdges[P.PairHalfEdge(i)].AdjacentFace;

                    if (P.VertexNakedEdgeCount(PrimalHE.StartVertex) == 0)
                    {
                        //DualHE.AdjacentFace = P.HalfEdges[P.PairHalfEdge(i)].StartVertex;
                        DualHE.AdjacentFace = PrimalHE.StartVertex;
                    }
                    else { DualHE.AdjacentFace = -1; }

                    //This will currently fail with open meshes...
                    //one option could be to build the dual with all halfedges, but mark some as dead
                    //if they connect to vertex -1
                    //mark the 'external' faces all as -1 (the ones that are dual to boundary verts)
                    //then go through and if any next or prevs are dead hes then replace them with the next one around
                    //this needs to be done repeatedly until no further change

                    //DualHE.NextHalfEdge = P.HalfEdges[P.PairHalfEdge(i)].PrevHalfEdge;
                    DualHE.NextHalfEdge = P.PairHalfEdge(PrimalHE.PrevHalfEdge);

                    //DualHE.PrevHalfEdge = P.PairHalfEdge(PrimalHE.NextHalfEdge);
                    DualHE.PrevHalfEdge = P.HalfEdges[P.PairHalfEdge(i)].NextHalfEdge;

                    DualHE.Index = newIndex;

                    D.HalfEdges.Add(DualHE);
                    newIndex += 1;
                }
            }
            return D;
        }
Beispiel #2
0
        //Create a Plankton Mesh from a Rhino Mesh
        public P_mesh(Mesh M)
        {
            M.Vertices.CombineIdentical(true, true);
            M.Vertices.CullUnused();
            M.UnifyNormals();
            M.Weld(Math.PI);

            this.Faces = new List<P_face>();
            this.HalfEdges = new List<P_halfedge>();
            this.Vertices = new List<P_vertex>();

            for (int i = 0; i < M.Vertices.Count; i++)
            {
                Vertices.Add(new P_vertex(M.TopologyVertices[i]));
            }

            for (int i = 0; i < M.Faces.Count; i++)
            {Faces.Add(new P_face()); }

            for (int i = 0; i < M.TopologyEdges.Count; i++)
            {
                P_halfedge HalfA = new P_halfedge();

                HalfA.StartVertex = M.TopologyEdges.GetTopologyVertices(i).I;

                if (Vertices[HalfA.StartVertex].OutgoingHalfEdge == -1)
                { Vertices[HalfA.StartVertex].OutgoingHalfEdge = HalfEdges.Count; }

                P_halfedge HalfB = new P_halfedge();

                HalfB.StartVertex = M.TopologyEdges.GetTopologyVertices(i).J;

                if (Vertices[HalfB.StartVertex].OutgoingHalfEdge == -1)
                { Vertices[HalfB.StartVertex].OutgoingHalfEdge = HalfEdges.Count + 1; }

                bool[] Match;
                int[] ConnectedFaces = M.TopologyEdges.GetConnectedFaces(i, out Match);

                //Note for Steve Baer : This Match bool doesn't seem to work on triangulated meshes - it often returns true
                //for both faces, even for a properly oriented manifold mesh, which can't be right
                //So - making our own check for matching:
                //(I suspect the problem is related to C being the same as D for triangles, so best to
                //deal with them separately just to make sure)
                //loop through the vertices of the face until finding the one which is the same as the start of the edge
                //iff the next vertex around the face is the end of the edge then it matches.

                Match[0] = false;
                if (Match.Length > 1)
                {Match[1] = true;}

                int VertA = M.TopologyVertices.TopologyVertexIndex(M.Faces[ConnectedFaces[0]].A);
                int VertB = M.TopologyVertices.TopologyVertexIndex(M.Faces[ConnectedFaces[0]].B);
                int VertC = M.TopologyVertices.TopologyVertexIndex(M.Faces[ConnectedFaces[0]].C);
                int VertD = M.TopologyVertices.TopologyVertexIndex(M.Faces[ConnectedFaces[0]].D);

                if ((VertA == M.TopologyEdges.GetTopologyVertices(i).I)
                    && (VertB == M.TopologyEdges.GetTopologyVertices(i).J))
                { Match[0] = true;
                }
                if ((VertB == M.TopologyEdges.GetTopologyVertices(i).I)
                    && (VertC == M.TopologyEdges.GetTopologyVertices(i).J))
                {
                    Match[0] = true;
                }
                if ((VertC == M.TopologyEdges.GetTopologyVertices(i).I)
                    && (VertD == M.TopologyEdges.GetTopologyVertices(i).J))
                {
                    Match[0] = true;
                }
                if ((VertD == M.TopologyEdges.GetTopologyVertices(i).I)
                   && (VertA == M.TopologyEdges.GetTopologyVertices(i).J))
                {
                    Match[0] = true;
                }
                //I don't think these next 2 should ever be needed, but just in case:
                if ((VertC == M.TopologyEdges.GetTopologyVertices(i).I)
                   && (VertA == M.TopologyEdges.GetTopologyVertices(i).J))
                {
                    Match[0] = true;
                }
                if ((VertB == M.TopologyEdges.GetTopologyVertices(i).I)
                    && (VertD == M.TopologyEdges.GetTopologyVertices(i).J))
                {
                    Match[0] = true;
                }

                if (Match[0] == true)
                {
                    HalfA.AdjacentFace = ConnectedFaces[0];
                    if (Faces[HalfA.AdjacentFace].FirstHalfEdge == -1)
                    { Faces[HalfA.AdjacentFace].FirstHalfEdge = HalfEdges.Count; }
                    if (ConnectedFaces.Length > 1)
                    {
                        HalfB.AdjacentFace = ConnectedFaces[1];
                        if (Faces[HalfB.AdjacentFace].FirstHalfEdge == -1)
                        { Faces[HalfB.AdjacentFace].FirstHalfEdge = HalfEdges.Count + 1; }
                    }
                    else
                    {
                        HalfB.AdjacentFace = -1;
                    }
                }
                else
                {
                    HalfB.AdjacentFace = ConnectedFaces[0];

                    if (Faces[HalfB.AdjacentFace].FirstHalfEdge == -1)
                    { Faces[HalfB.AdjacentFace].FirstHalfEdge = HalfEdges.Count + 1; }

                    if (ConnectedFaces.Length > 1)
                    {
                        HalfA.AdjacentFace = ConnectedFaces[1];

                        if (Faces[HalfA.AdjacentFace].FirstHalfEdge == -1)
                        { Faces[HalfA.AdjacentFace].FirstHalfEdge = HalfEdges.Count; }
                    }
                    else
                    {
                        HalfA.AdjacentFace = -1;
                    }
                }
                HalfEdges.Add(HalfA);
                HalfEdges[2 * i].Index = 2 * i; //
                HalfEdges.Add(HalfB);
                HalfEdges[2 * i + 1].Index = 2 * i + 1; //
            }

            for (int i = 0; i < (HalfEdges.Count); i += 2)
            {
                int[] EndNeighbours = M.TopologyVertices.ConnectedTopologyVertices(HalfEdges[i + 1].StartVertex, true);
                for (int j = 0; j < EndNeighbours.Length; j++)
                {
                    if(EndNeighbours[j]==HalfEdges[i].StartVertex)
                    {
                        int EndOfNextHalfEdge = EndNeighbours[(j - 1 + EndNeighbours.Length) % EndNeighbours.Length];
                        int StartOfPrevOfPairHalfEdge = EndNeighbours[(j + 1) % EndNeighbours.Length];

                        int NextEdge = M.TopologyEdges.GetEdgeIndex(HalfEdges[i + 1].StartVertex,EndOfNextHalfEdge);
                        int PrevPairEdge = M.TopologyEdges.GetEdgeIndex(HalfEdges[i + 1].StartVertex,StartOfPrevOfPairHalfEdge);

                        if (M.TopologyEdges.GetTopologyVertices(NextEdge).I == HalfEdges[i + 1].StartVertex)
                        { HalfEdges[i].NextHalfEdge = NextEdge * 2; }
                        else
                        { HalfEdges[i].NextHalfEdge = NextEdge * 2 + 1; }

                        if (M.TopologyEdges.GetTopologyVertices(PrevPairEdge).J == HalfEdges[i + 1].StartVertex)
                        { HalfEdges[i + 1].PrevHalfEdge = PrevPairEdge * 2; }
                        else
                        { HalfEdges[i + 1].PrevHalfEdge = PrevPairEdge * 2+1; }
                        break;
                    }
                }

                int[] StartNeighbours = M.TopologyVertices.ConnectedTopologyVertices(HalfEdges[i].StartVertex, true);
                for (int j = 0; j < StartNeighbours.Length; j++)
                {
                    if (StartNeighbours[j] == HalfEdges[i+1].StartVertex)
                    {
                        int EndOfNextOfPairHalfEdge = StartNeighbours[(j - 1 + StartNeighbours.Length) % StartNeighbours.Length];
                        int StartOfPrevHalfEdge = StartNeighbours[(j + 1) % StartNeighbours.Length];

                        int NextPairEdge = M.TopologyEdges.GetEdgeIndex(HalfEdges[i].StartVertex, EndOfNextOfPairHalfEdge);
                        int PrevEdge = M.TopologyEdges.GetEdgeIndex(HalfEdges[i].StartVertex, StartOfPrevHalfEdge);

                        if (M.TopologyEdges.GetTopologyVertices(NextPairEdge).I == HalfEdges[i].StartVertex)
                        { HalfEdges[i + 1].NextHalfEdge = NextPairEdge * 2; }
                        else
                        { HalfEdges[i + 1].NextHalfEdge = NextPairEdge * 2 + 1; }

                        if (M.TopologyEdges.GetTopologyVertices(PrevEdge).J == HalfEdges[i].StartVertex)
                        { HalfEdges[i].PrevHalfEdge = PrevEdge * 2; }
                        else
                        { HalfEdges[i].PrevHalfEdge = PrevEdge * 2 + 1; }
                        break;
                    }
                }
            }
        }