void TriangleClipperBase::processFaces() { for (UINT32 i = 0; i < (UINT32)mesh.faces.size(); i++) { ClipFace& face = mesh.faces[i]; if (face.visible) { // The edge is culled. If the edge is exactly on the clip // plane, it is possible that a visible triangle shares it. // The edge will be re-added during the face loop. for (UINT32 j = 0; j < (UINT32)face.edges.size(); j++) { ClipEdge& edge = mesh.edges[face.edges[j]]; ClipVert& v0 = mesh.verts[edge.verts[0]]; ClipVert& v1 = mesh.verts[edge.verts[1]]; v0.occurs = 0; v1.occurs = 0; } } UINT32 start, end; if (getOpenPolyline(mesh.faces[i], start, end)) { // Polyline is open, close it UINT32 closeEdgeIdx = (UINT32)mesh.edges.size(); mesh.edges.push_back(ClipEdge()); ClipEdge& closeEdge = mesh.edges.back(); closeEdge.verts[0] = start; closeEdge.verts[1] = end; closeEdge.faces.push_back(i); face.edges.push_back(closeEdgeIdx); } } }
bool ClipMesh::processFaces( const Plane& clippingPlane ) { // the mesh straddles the plane. a new convex polygon face will be // generated. add it now and insert edges when they are visited. const size_t fNew = _faces.size(); _faces.push_back(CFace()); CFace& faceNew = _faces[fNew]; faceNew.normal = -clippingPlane.normal; // process the faces for( unsigned int currFace = 0; currFace < fNew; ++currFace ) { CFace& face = _faces[currFace]; if( !face.visible ) { continue; } // determine if the face is on the negative side, the positive side, // or split by the clipping plane. the occurs members are set to zero // to help find the end points of the polyline that results from clipping // a face. //assert(face.edges.size() >= 2 ); // unexpected condition if( face.edges.size() < 2 ) { return false; } std::set<int>::const_iterator iter = face.edges.begin(); const std::set<int>::const_iterator end = face.edges.end(); while( iter != end ) { const int e = *iter++; CEdge& edge = _edges[e]; //assert(edge.visible); // unexpected condition if( !edge.visible ) { return false; } _vertices[edge.vertex[0]].occurs = 0; _vertices[edge.vertex[1]].occurs = 0; } int vStart; int vFinal; if( getOpenPolyline(face, vStart, vFinal) ) { // polyline is open, close it up const size_t eNew = _edges.size(); _edges.push_back(CEdge()); CEdge& edgeNew = _edges[eNew]; edgeNew.vertex[0] = vStart; edgeNew.vertex[1] = vFinal; edgeNew.faces[0] = currFace; edgeNew.faces[1] = fNew; // add new edge to polygons face.edges.insert(eNew); faceNew.edges.insert(eNew); } } // process 'faceNew' to make sure it is a simple polygon (theoretically // convex, but numerically may be slightly not convex). floating-point // round-off errors can cause the new face from the last loop to be // needle-like with a collapse of two edges into a single edge. this // block guarantees the invariant face is always a simple polygon. if( !postProcess(fNew, faceNew) ) { return false; } if( faceNew.edges.size() < 3 ) { // face is completely degenerate, remote it from mesh _faces.pop_back(); } return true; }