pointVector get_facetPoints(Polyhedron::Halfedge_handle& heH) { Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = heH->facet_begin(); // same as just heH? pointVector facetPnts; do facetPnts.push_back(itHDS->vertex()->point()); while (++itHDS != heH->facet_begin()); return facetPnts; }
// Search whether a facet is touching a certain semantic directly or indirectly through the facets in the list bool indirectlyTouchingFindSem(std::string findSem,std::set<Polyhedron::Facet_handle>& fhSet) { for (std::set<Polyhedron::Facet_handle>::iterator sfIt=fhSet.begin();sfIt!=fhSet.end();++sfIt) { Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = (*sfIt)->facet_begin(); do if (itHDS->opposite()->facet()->semanticBLA == findSem) return true; while (++itHDS != (*sfIt)->facet_begin()); } return false; }
// Depricated // Creates a list of coplanar facets with equal semantics // Returns the combined area (Assumes area has been set) double coplanarSem(Polyhedron::Facet_handle fh, std::set<Polyhedron::Facet_handle>& fhSet) { fhSet.insert(fh); // Add to list double summedArea = fh->area; // Get area, assumes precalculated Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = fh->facet_begin(); do { if (is_coplanar(itHDS,true)) { // Check coplanearity and equal semantics if (fhSet.find(itHDS->opposite()->facet())==fhSet.end()) // If new to list summedArea += coplanarSem(itHDS->opposite()->facet(),fhSet); // Recursive search and sum } } while (++itHDS != fh->facet_begin()); return summedArea; }
// Creates a List of all connected facets based on sem void connectedSemFacets(Polyhedron::Facet_handle fh, std::string sem,bool allExceptThisSem, std::set<Polyhedron::Facet_handle>& fhSet, bool checkCoPlanar) { if (sem=="-1") sem = fh->semanticBLA; // Set semantic to input facet sem fhSet.insert(fh); // Add to list Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = fh->facet_begin(); // Loop over the edges do { if ((itHDS->opposite()->facet()->semanticBLA==sem ^ allExceptThisSem) && (!checkCoPlanar || is_NewelCoplanar(itHDS))){ // If part of sem(s) we're looking for (and coplanar if needed) if (fhSet.find(itHDS->opposite()->facet())==fhSet.end()) // If not yet in set connectedSemFacets(itHDS->opposite()->facet(),sem,allExceptThisSem,fhSet,checkCoPlanar);// Recursive search } } while (++itHDS != fh->facet_begin()); }
// Remove small triangles with different semantics void remove_singularSemantics(Polyhedron& exteriorPolyhe) { double SMALL_TRIANGLE_LIMIT = 0.1; Polyhedron::Facet_iterator exfIt; // Iterate over exterior faces while (true) { bool newSemFound = false; for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) { if (exfIt->area < SMALL_TRIANGLE_LIMIT) { std::map<std::string,double> semCountList; std::map<std::string,double>::iterator semCount; Polyhedron::Facet::Halfedge_around_facet_circulator itHDS = exfIt->facet_begin(); double maxArea = 0; std::string newSem; do { if (is_coplanar(itHDS,false)) { std::string otherSem = itHDS->opposite()->facet()->semanticBLA; // Compute sum of area if (is_coplanar(itHDS->opposite()->next(),true) || is_coplanar(itHDS->opposite()->prev(),true)) { semCount = semCountList.find(otherSem); if (semCount == semCountList.end()) semCountList[otherSem] = 1; // Might not be needed else ++(semCountList[otherSem]); } } } while (++itHDS != exfIt->facet_begin()); for (semCount = semCountList.begin();semCount!=semCountList.end();++semCount) { if (semCount->second > maxArea) { maxArea = semCount->second; newSem = semCount->first; } else if (semCount->second == maxArea && ((exfIt->semanticBLA=="Anything"&&semCount->first!="Anything")||semCount->first==exfIt->semanticBLA)) newSem = semCount->first; } if (maxArea > 0 && newSem!=exfIt->semanticBLA) { exfIt->semanticBLA = newSem; newSemFound = true; break; // Dafuq? is this correct? } } } if (!newSemFound) break; // Really? } }
void groupSemanticFacets(Polyhedron& polyhe,sfsVec& semFacetSetsVector,sfsVec& openSFSVector,std::map<int,std::vector<int>>& openingMap){ bool skip; // Group non-openings for (Polyhedron::Facet_iterator fIt=polyhe.facets_begin();fIt!=polyhe.facets_end();++fIt) { if (fIt->semanticBLA == "Window" || fIt->semanticBLA == "Door") continue; // Skip openings skip = false; // Check of facet has already been processed for (unsigned int i=0;i<semFacetSetsVector.size();++i) { if (semFacetSetsVector[i].first == fIt->semanticBLA // Check sem of set && (semFacetSetsVector[i].second.find(fIt)!=semFacetSetsVector[i].second.end())) { // if in set -> skip skip = true; break; } } if (skip) continue; std::set<Polyhedron::Facet_handle> fhSet; connectedSemFacets(fIt,fIt->semanticBLA,false,fhSet,false); // Get list of all (in)directly connected facets semFacetSetsVector.push_back(sfsPair(fIt->semanticBLA,fhSet)); // Store connected facet list } // Group and match openings for (Polyhedron::Facet_iterator fIt=polyhe.facets_begin();fIt!=polyhe.facets_end();++fIt) { if (!(fIt->semanticBLA == "Window" || fIt->semanticBLA == "Door")) continue; // Skip non-openings skip = false; // Check of facet has already been processed for (unsigned int i=0;i<openSFSVector.size();++i) { if (openSFSVector[i].first == fIt->semanticBLA // Check sem of set && (openSFSVector[i].second.find(fIt)!=openSFSVector[i].second.end())) { // if in set -> skip skip = true; break; } } if (skip) continue; // Store opening facets std::set<Polyhedron::Facet_handle> fhSet; connectedSemFacets(fIt,fIt->semanticBLA,false,fhSet,false); openSFSVector.push_back(sfsPair(fIt->semanticBLA,fhSet)); // Match/Find Surface containing the opening bool found = false; bool setRoof = false; Polyhedron::Facet_handle otherFace; otherFace->semanticBLA; Polyhedron::Facet::Halfedge_around_facet_circulator itHDS; for (std::set<Polyhedron::Facet_handle>::iterator setIt=fhSet.begin();setIt!=fhSet.end();++setIt) { itHDS = (*setIt)->facet_begin(); // Loop over the edges do { if (itHDS->opposite()->facet()->semanticBLA=="Wall" || itHDS->opposite()->facet()->semanticBLA=="WallSurface") { otherFace = itHDS->opposite()->facet(); // Prefer wall surfaces found = true; break; } else if (itHDS->opposite()->facet()->semanticBLA=="Roof" || itHDS->opposite()->facet()->semanticBLA=="RoofSurface") { otherFace = itHDS->opposite()->facet(); // Prefer wall surfaces setRoof = true; } else if (!setRoof // Roof is better than other (except wall) && itHDS->opposite()->facet()->semanticBLA!="Window" && itHDS->opposite()->facet()->semanticBLA!="Door" && itHDS->opposite()->facet()->semanticBLA!="Install" && itHDS->opposite()->facet()->semanticBLA!="BuildingInstallation") otherFace = itHDS->opposite()->facet(); } while (++itHDS != (*setIt)->facet_begin()); if (found) break; // Break when wall or roof found } int openingContainer = 0; // Index of container surface for (unsigned int i=0;i<semFacetSetsVector.size();++i) { if (semFacetSetsVector[i].first == otherFace->semanticBLA // Check sem of set && (semFacetSetsVector[i].second.find(otherFace)!=semFacetSetsVector[i].second.end())) { // if in set -> skip openingContainer = i; break; } } openingMap[openingContainer].push_back(openSFSVector.size()-1); // Add opening reference to container vector } }