/// <summary> /// Removes ghost triangles. /// </summary> /// <param name="startghost"></param> /// <returns>Number of vertices on the hull.</returns> int RemoveGhosts(ref Otri startghost) { Otri searchedge = default(Otri); Otri dissolveedge = default(Otri); Otri deadtriangle = default(Otri); Vertex markorg; int hullsize; bool noPoly = !_TriangleNetMesh.behavior.Poly; // Find an edge on the convex hull to start point location from. startghost.Lprev(ref searchedge); searchedge.Sym(); _TriangleNetMesh.dummytri.neighbors[0] = searchedge; // Remove the bounding box and count the convex hull edges. startghost.Copy(ref dissolveedge); hullsize = 0; do { hullsize++; dissolveedge.Lnext(ref deadtriangle); dissolveedge.Lprev(); dissolveedge.Sym(); // If no PSLG is involved, set the boundary markers of all the vertices // on the convex hull. If a PSLG is used, this step is done later. if (noPoly) { // Watch out for the case where all the input vertices are collinear. if (dissolveedge.tri.id != TriangleNetMesh.DUMMY) { markorg = dissolveedge.Org(); if (markorg.label == 0) { markorg.label = 1; } } } // Remove a bounding triangle from a convex hull triangle. dissolveedge.Dissolve(_TriangleNetMesh.dummytri); // Find the next bounding triangle. deadtriangle.Sym(ref dissolveedge); // Delete the bounding triangle. _TriangleNetMesh.TriangleDealloc(deadtriangle.tri); } while (!dissolveedge.Equals(startghost)); return(hullsize); }
/// <summary> /// Remove the "infinite" bounding triangle, setting boundary markers as appropriate. /// </summary> /// <returns>Returns the number of edges on the convex hull of the triangulation.</returns> /// <remarks> /// The triangular bounding box has three boundary triangles (one for each /// side of the bounding box), and a bunch of triangles fanning out from /// the three bounding box vertices (one triangle for each edge of the /// convex hull of the inner mesh). This routine removes these triangles. /// </remarks> int RemoveBox() { Otri deadtriangle = default(Otri); Otri searchedge = default(Otri); Otri checkedge = default(Otri); Otri nextedge = default(Otri), finaledge = default(Otri), dissolveedge = default(Otri); Vertex markorg; int hullsize; bool noPoly = !_TriangleNetMesh.behavior.Poly; // Find a boundary triangle. nextedge.tri = _TriangleNetMesh.dummytri; nextedge.orient = 0; nextedge.Sym(); // Mark a place to stop. nextedge.Lprev(ref finaledge); nextedge.Lnext(); nextedge.Sym(); // Find a triangle (on the boundary of the vertex set) that isn't // a bounding box triangle. nextedge.Lprev(ref searchedge); searchedge.Sym(); // Check whether nextedge is another boundary triangle // adjacent to the first one. nextedge.Lnext(ref checkedge); checkedge.Sym(); if (checkedge.tri.id == TriangleNetMesh.DUMMY) { // Go on to the next triangle. There are only three boundary // triangles, and this next triangle cannot be the third one, // so it's safe to stop here. searchedge.Lprev(); searchedge.Sym(); } // Find a new boundary edge to search from, as the current search // edge lies on a bounding box triangle and will be deleted. _TriangleNetMesh.dummytri.neighbors[0] = searchedge; hullsize = -2; while (!nextedge.Equals(finaledge)) { hullsize++; nextedge.Lprev(ref dissolveedge); dissolveedge.Sym(); // If not using a PSLG, the vertices should be marked now. // (If using a PSLG, markhull() will do the job.) if (noPoly) { // Be careful! One must check for the case where all the input // vertices are collinear, and thus all the triangles are part of // the bounding box. Otherwise, the setvertexmark() call below // will cause a bad pointer reference. if (dissolveedge.tri.id != TriangleNetMesh.DUMMY) { markorg = dissolveedge.Org(); if (markorg.label == 0) { markorg.label = 1; } } } // Disconnect the bounding box triangle from the mesh triangle. dissolveedge.Dissolve(_TriangleNetMesh.dummytri); nextedge.Lnext(ref deadtriangle); deadtriangle.Sym(ref nextedge); // Get rid of the bounding box triangle. _TriangleNetMesh.TriangleDealloc(deadtriangle.tri); // Do we need to turn the corner? if (nextedge.tri.id == TriangleNetMesh.DUMMY) { // Turn the corner. dissolveedge.Copy(ref nextedge); } } _TriangleNetMesh.TriangleDealloc(finaledge.tri); return(hullsize); }