IGL_INLINE void igl::copyleft::cgal::outer_facet( const Eigen::PlainObjectBase<DerivedV> & V, const Eigen::PlainObjectBase<DerivedF> & F, const Eigen::PlainObjectBase<DerivedN> & N, const Eigen::PlainObjectBase<DerivedI> & I, IndexType & f, bool & flipped) { // Algorithm: // Find an outer edge. // Find the incident facet with the largest absolute X normal component. // If there is a tie, keep the one with positive X component. // If there is still a tie, pick the face with the larger signed index // (flipped face has negative index). typedef typename DerivedV::Scalar Scalar; typedef typename DerivedV::Index Index; const size_t INVALID = std::numeric_limits<size_t>::max(); Index v1,v2; Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces; outer_edge(V, F, I, v1, v2, incident_faces); assert(incident_faces.size() > 0); auto generic_fabs = [&](const Scalar& val) -> const Scalar { if (val >= 0) return val; else return -val; }; Scalar max_nx = 0; size_t outer_fid = INVALID; const size_t num_incident_faces = incident_faces.size(); for (size_t i=0; i<num_incident_faces; i++) { const auto& fid = incident_faces(i); const Scalar nx = N(fid, 0); if (outer_fid == INVALID) { max_nx = nx; outer_fid = fid; } else { if (generic_fabs(nx) > generic_fabs(max_nx)) { max_nx = nx; outer_fid = fid; } else if (nx == -max_nx && nx > 0) { max_nx = nx; outer_fid = fid; } else if (nx == max_nx) { if ((max_nx >= 0 && outer_fid < fid) || (max_nx < 0 && outer_fid > fid)) { max_nx = nx; outer_fid = fid; } } } } assert(outer_fid != INVALID); f = outer_fid; flipped = max_nx < 0; }
void Foam::CV2D::calcDual ( point2DField& dualPoints, faceList& dualFaces, wordList& patchNames, labelList& patchSizes, EdgeMap<label>& mapEdgesRegion, EdgeMap<label>& indirectPatchEdge ) const { // Dual points stored in triangle order. dualPoints.setSize(number_of_faces()); label dualVerti = 0; for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { if ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) { fit->faceIndex() = dualVerti; dualPoints[dualVerti++] = toPoint2D(circumcenter(fit)); } else { fit->faceIndex() = -1; } } dualPoints.setSize(dualVerti); extractPatches(patchNames, patchSizes, mapEdgesRegion, indirectPatchEdge); forAll(patchNames, patchi) { Info<< "Patch " << patchNames[patchi] << " has size " << patchSizes[patchi] << endl; } // Create dual faces // ~~~~~~~~~~~~~~~~~ dualFaces.setSize(number_of_vertices()); label dualFacei = 0; labelList faceVerts(maxNvert); for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->internalOrBoundaryPoint()) { Face_circulator fcStart = incident_faces(vit); Face_circulator fc = fcStart; label verti = 0; do { if (!is_infinite(fc)) { if (fc->faceIndex() < 0) { FatalErrorInFunction << "Dual face uses vertex defined by a triangle" " defined by an external point" << exit(FatalError); } // Look up the index of the triangle faceVerts[verti++] = fc->faceIndex(); } } while (++fc != fcStart); if (faceVerts.size() > 2) { dualFaces[dualFacei++] = face(labelList::subList(faceVerts, verti)); } else { Info<< "From triangle point:" << vit->index() << " coord:" << toPoint2D(vit->point()) << " generated illegal dualFace:" << faceVerts << endl; } } } dualFaces.setSize(dualFacei); }
void Foam::CV2D::writeFaces(const fileName& fName, bool internalOnly) const { Info<< "Writing dual faces to " << fName << nl << endl; OFstream str(fName); label dualVerti = 0; for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { if ( !internalOnly || ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) ) { fit->faceIndex() = dualVerti++; meshTools::writeOBJ(str, toPoint3D(circumcenter(fit))); } else { fit->faceIndex() = -1; } } for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (!internalOnly || vit->internalOrBoundaryPoint()) { Face_circulator fcStart = incident_faces(vit); Face_circulator fc = fcStart; str<< 'f'; do { if (!is_infinite(fc)) { if (fc->faceIndex() < 0) { FatalErrorInFunction << "Dual face uses vertex defined by a triangle" " defined by an external point" << exit(FatalError); } str<< ' ' << fc->faceIndex() + 1; } } while (++fc != fcStart); str<< nl; } } }