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); }
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; } }