/// <summary> /// Finds the adjacencies between triangles and subsegments. /// </summary> private static void SetSegments(TriangleNetMesh triangleNetMesh, Polygon polygon, List <Otri>[] vertexarray) { Otri checktri = default(Otri); Otri nexttri; // Triangle TVertex checkdest; Otri checkneighbor = default(Otri); Osub subseg = default(Osub); Otri prevlink; // Triangle TVertex tmp; TVertex sorg, sdest; bool notfound; //bool segmentmarkers = false; int boundmarker; int aroundvertex; int i; int hullsize = 0; // Prepare to count the boundary edges. if (triangleNetMesh.behavior.Poly) { // Link the segments to their neighboring triangles. boundmarker = 0; i = 0; foreach (var item in triangleNetMesh.subsegs.Values) { subseg.seg = item; sorg = polygon.Segments[i].GetVertex(0); sdest = polygon.Segments[i].GetVertex(1); boundmarker = polygon.Segments[i].Label; if ((sorg.id < 0 || sorg.id >= triangleNetMesh.invertices) || (sdest.id < 0 || sdest.id >= triangleNetMesh.invertices)) { Log.Instance.Error("Segment has an invalid vertex index.", "MeshReader.Reconstruct()"); throw new Exception("Segment has an invalid vertex index."); } // set the subsegment's vertices. subseg.orient = 0; subseg.SetOrg(sorg); subseg.SetDest(sdest); subseg.SetSegOrg(sorg); subseg.SetSegDest(sdest); subseg.seg.boundary = boundmarker; // Try linking the subsegment to triangles that share these vertices. for (subseg.orient = 0; subseg.orient < 2; subseg.orient++) { // Take the number for the destination of subsegloop. aroundvertex = subseg.orient == 1 ? sorg.id : sdest.id; int index = vertexarray[aroundvertex].Count - 1; // Look for triangles having this vertex. prevlink = vertexarray[aroundvertex][index]; nexttri = vertexarray[aroundvertex][index]; checktri = nexttri; tmp = subseg.Org(); notfound = true; // Look for triangles having this edge. Note that I'm only // comparing each triangle's destination with the subsegment; // each triangle's apex is handled through a different vertex. // Because each triangle appears on three vertices' lists, each // occurrence of a triangle on a list can (and does) represent // an edge. In this way, most edges are represented twice, and // every triangle-subsegment bond is represented once. while (notfound && (checktri.tri.id != TriangleNetMesh.DUMMY)) { checkdest = checktri.Dest(); if (tmp == checkdest) { // We have a match. Remove this triangle from the list. //prevlink = vertexarray[aroundvertex][index]; vertexarray[aroundvertex].Remove(prevlink); // Bond the subsegment to the triangle. checktri.SegBond(ref subseg); // Check if this is a boundary edge. checktri.Sym(ref checkneighbor); if (checkneighbor.tri.id == TriangleNetMesh.DUMMY) { // The next line doesn't insert a subsegment (because there's // already one there), but it sets the boundary markers of // the existing subsegment and its vertices. triangleNetMesh.InsertSubseg(ref checktri, 1); hullsize++; } notfound = false; } index--; // Find the next triangle in the stack. prevlink = vertexarray[aroundvertex][index]; nexttri = vertexarray[aroundvertex][index]; checktri = nexttri; } } i++; } } // Mark the remaining edges as not being attached to any subsegment. // Also, count the (yet uncounted) boundary edges. for (i = 0; i < triangleNetMesh.vertices.Count; i++) { // Search the stack of triangles adjacent to a vertex. int index = vertexarray[i].Count - 1; nexttri = vertexarray[i][index]; checktri = nexttri; while (checktri.tri.id != TriangleNetMesh.DUMMY) { // Find the next triangle in the stack before this // information gets overwritten. index--; nexttri = vertexarray[i][index]; // No adjacent subsegment. (This overwrites the stack info.) checktri.SegDissolve(triangleNetMesh.dummysub); checktri.Sym(ref checkneighbor); if (checkneighbor.tri.id == TriangleNetMesh.DUMMY) { triangleNetMesh.InsertSubseg(ref checktri, 1); hullsize++; } checktri = nexttri; } } triangleNetMesh.hullsize = hullsize; }