public LRTriangleMesh ResolveTriangles(int[] vertexMapping)
        {
            this.vertexMapping = vertexMapping;
            lrCornerResolver   = new LRCornerResolver(ref lrTriangleMesh, ref ctTriangleMesh, ref tMarked, ref vertexMapping);

            //Loop through all vertices
            for (int i = 0; i < vertexMapping.Length; i++)
            {
                int[]   faces = ctTriangleMesh.VF(i);
                int[][] facesSharingRingEdge = LRUtils.GetFacesSharingRingEdge(faces, tMarked);

                if (vMarked[i]) //If vertex is marked then its not isolated and therefore has a ring edge (is start vertex of a ring edge)
                {
                    if (facesSharingRingEdge[0] != null && !tProcessed[facesSharingRingEdge[0][0]])
                    {
                        //Resolve "left" triangle
                        int c  = ctTriangleMesh.GetSpecificCorner(facesSharingRingEdge[0][0], i);                          //Get the corner of the vertex, which is incident with the marked triangle of the ring edge, where the vertex is the start vertex
                        int pc = ctTriangleMesh.P(c);                                                                      //Get the next corner around the triangle, which is the one facing the ring edge

                        lrTriangleMesh.LR[(2 * vertexMapping[ctTriangleMesh.V(c)])] = vertexMapping[ctTriangleMesh.V(pc)]; //Store the mapped vertex index (laced ring vertex index) in the LR table at the correct pos.
                    }

                    if (facesSharingRingEdge[0] != null && !tProcessed[facesSharingRingEdge[0][1]])
                    {
                        //Resolve "right" triangle
                        int c  = ctTriangleMesh.GetSpecificCorner(facesSharingRingEdge[0][1], i);                              //Get the corner of the vertex, which is incident with the marked triangle of the ring edge, where the vertex is the start vertex
                        int nc = ctTriangleMesh.N(c);                                                                          //Get the previous corner around the triangle, which is the one facing the ring edge

                        lrTriangleMesh.LR[(2 * vertexMapping[ctTriangleMesh.V(c)]) + 1] = vertexMapping[ctTriangleMesh.V(nc)]; //Store the mapped vertex index (laced ring vertex index) in the LR table at the correct pos.
                    }

                    T0LookUp(i, faces); //Look up if vertex is part of a T0 and handle accordingly
                }
                else //Isolated vertex
                {
                    CheckAndResolveIsolatedVertex(i); //Create entry for isolated vertex
                    T0LookUp(i, faces);               //Look up if it is part of a T0 and handle accordingly
                }
            }

            //Store results in lr object
            lrTriangleMesh.T  = t.ToArray();
            lrTriangleMesh.O  = lrCornerResolver.O.ToArray();
            lrTriangleMesh.TS = ts.ToArray();
            lrTriangleMesh.OS = lrCornerResolver.OS.ToArray();
            lrTriangleMesh.C  = lrCornerResolver.IsolatedCorners.ToArray();

            return(lrTriangleMesh);
        }
Example #2
0
        private void RingExpander()
        {
            int s = ctTriangleMesh.IncidentCorner[new Random().Next(ctTriangleMesh.IncidentCorner.Length)];

            int c = s; // start at the seed corner s
            vMarked[ctTriangleMesh.V(ctTriangleMesh.N(c))] = vMarked[ctTriangleMesh.V(ctTriangleMesh.P(c))] = true; // mark vertices as visited
            do
            {
                if (!vMarked[ctTriangleMesh.V(c)])
                {
                    vMarked[ctTriangleMesh.V(c)] = tMarked[c / 3] = true; // invade c.T
                }
                else if (!tMarked[c / 3])
                {
                    c = ctTriangleMesh.Opposite[c]; // go back one triangle
                }

                c = ctTriangleMesh.Opposite[ctTriangleMesh.N(c)]; // advance to next ring edge on the right
            }
            while (c != ctTriangleMesh.Opposite[s]); // until back at the beginning
        }
        /// <summary>
        /// Resolves the corners which need to be explicitly stored in the O, OS and C-Structures for the given ct-corner c1.
        /// This is only necessary if the corner and respectivly the vertex is part of a T0
        /// </summary>
        /// <param name="c">The corner from the corner table structure to process</param>
        /// <param name="co">The opposite corner from the corner table structure</param>
        public void ResolveCorners(int c, int co)
        {
            //Used if theres a expensive triangle, with two adjacent T0-triangles
            if (ctOppCornerOsCornerMap.ContainsKey(c))
            {
                if (oCornerOffset % 8 == 3 || oCornerOffset % 8 == 7) //it's necessary to skip those entries
                {
                    oCornerOffset++;
                }

                OS[ctOppCornerOsCornerMap[c].Item2] = 8 * lrTriangleMesh.MR + oCornerOffset; //Add opposite corner of ET
                oCornerOffset++;

                O.Add(ctOppCornerOsCornerMap[c].Item1);
                return;
            }

            //Check if adjacent triangle is T2 triangle
            if (IsRingEdge(co, ctTriangleMesh.N(co)) && IsRingEdge(co, ctTriangleMesh.P(co)))
            {
                int sc;
                int sc1;

                if (tMarked[co / 3])
                {
                    sc  = co;                                             //Corner of start vertex from the adjacent triangle
                    sc1 = ctTriangleMesh.P(co);                           //Since it's a T2, there is a second ring edge and thus a second start vertex

                    if (oCornerOffset % 8 == 3 || oCornerOffset % 8 == 7) //it's necessary to skip those entries
                    {
                        oCornerOffset++;
                    }

                    OS.Add(8 * lrTriangleMesh.MR + oCornerOffset); //Add opposite corner of et

                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[ctTriangleMesh.N(sc)], -1);
                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[sc1], -1);

                    OS.Add(8 * lrTriangleMesh.MR + oCornerOffset); //Same entry twice, because one vertex is part of both ring edges
                    ResolveIsolatedVertexCorner(vertexMapping[ctTriangleMesh.V(c)], 8 * lrTriangleMesh.MR + oCornerOffset);
                    oCornerOffset++;

                    //Create opposite entry
                    O.Add(vertexMapping[ctTriangleMesh.V(co)] * 8);
                }
                else
                {
                    sc  = co;                   //Corner of start vertex from the adjacent triangle
                    sc1 = ctTriangleMesh.N(co); //Since it's a T2, there is a second ring edge and thus a second start vertex

                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[sc1], -1);

                    if (oCornerOffset % 8 == 3 || oCornerOffset % 8 == 7) //it's necessary to skip those entries
                    {
                        oCornerOffset++;
                    }

                    OS.Add(8 * lrTriangleMesh.MR + oCornerOffset); //Add opposite corner of et
                    OS.Add(8 * lrTriangleMesh.MR + oCornerOffset); //Same entry twice, because one vertex is part of both ring edges
                    ResolveIsolatedVertexCorner(vertexMapping[ctTriangleMesh.V(c)], 8 * lrTriangleMesh.MR + oCornerOffset);
                    oCornerOffset++;

                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[ctTriangleMesh.P(sc)], -1);

                    //Create opposite entry
                    O.Add(vertexMapping[ctTriangleMesh.V(co)] * 8 + 6);
                }
            }
            //Check if adjacent triangle has oc and oc.n as a ring edge
            else if (IsRingEdge(co, ctTriangleMesh.N(co)))
            {
                int sc;
                int lrC;
                int lrC1;

                if (tMarked[co / 3])
                {
                    sc   = co;                                          //Corner of start vertex from the adjacent triangle
                    lrC  = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 2; //calc. laced ring corner
                    lrC1 = vertexMapping[ctTriangleMesh.V(sc)] * 8;     //calc. laced ring corner of the other ring vertex

                    AddOsEntry(c);
                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[ctTriangleMesh.N(sc)], lrC);
                }
                else
                {
                    sc   = ctTriangleMesh.N(co);                        //Corner of start vertex from the adjacent triangle
                    lrC  = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 6; //calc. laced ring corner
                    lrC1 = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 4; //calc. laced ring corner of the other ring vertex

                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[sc], lrC);
                    AddOsEntry(c);
                }

                O.Add(lrC1);
            }
            //Check if adjacent triangle has oc and oc.p as a ring edge
            else if (IsRingEdge(co, ctTriangleMesh.P(co)))
            {
                int sc;
                int lrC;
                int lrC1;

                if (tMarked[co / 3])
                {
                    sc   = ctTriangleMesh.P(co);                        //Corner of start vertex from the adjacent triangle
                    lrC  = vertexMapping[ctTriangleMesh.V(sc)] * 8;     //calc. laced ring corner
                    lrC1 = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 2; //calc. laced ring corner of the other ring vertex

                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[sc], lrC);
                    AddOsEntry(c);
                }
                else
                {
                    sc   = co;                                          //Corner of start vertex from the adjacent triangle
                    lrC  = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 4; //calc. laced ring corner
                    lrC1 = vertexMapping[ctTriangleMesh.V(sc)] * 8 + 6; //calc. laced ring corner of the other ring vertex

                    AddOsEntry(c);
                    ResolveOtherETOpposite(ctTriangleMesh.Opposite[ctTriangleMesh.P(sc)], lrC);
                }

                O.Add(lrC1);
            }
            //The adjacent triangle is a T0
            else
            {
                if (oCornerOffset % 8 == 3 || oCornerOffset % 8 == 7) //it's necessary to skip those entries
                {
                    oCornerOffset++;
                }

                ResolveT0AdjacentCorners(c, co);
                ResolveIsolatedVertexCorner(vertexMapping[ctTriangleMesh.V(c)], 8 * lrTriangleMesh.MR + oCornerOffset);
                oCornerOffset++;

                return;
            }
        }
        private int GetNextRingVertex(int startVertex, int[][] facesSharingRingEdge)
        {
            int c = ctTriangleMesh.GetSpecificCorner(facesSharingRingEdge[0][0], startVertex);

            return(ctTriangleMesh.V(ctTriangleMesh.N(c)));
        }