// 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()); }
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 } }
void apply_semanticRequirements(Polyhedron& exteriorPolyhe) { std::map<std::string,std::vector<bool>> semanticNormals; semanticNormals["Roof"] = std::vector<bool>(3,true); semanticNormals["Roof"][2] = false; // down semanticNormals["Ground"] = std::vector<bool>(3,false); semanticNormals["Ground"][2] = true; semanticNormals["Ceiling"] = std::vector<bool>(3,false); semanticNormals["Ceiling"][2] = true; semanticNormals["Floor"] = std::vector<bool>(3,false); semanticNormals["Floor"][0] = true; semanticNormals["Wall"] = std::vector<bool>(3,true); semanticNormals["Window"] = std::vector<bool>(3,true); semanticNormals["Door"] = std::vector<bool>(3,true); semanticNormals["Closure"] = std::vector<bool>(3,true); semanticNormals[TO_DIST_SEMANTIC] = std::vector<bool>(3,true); //semanticNormals["Anything"] = std::vector<bool>(3,true); std::map<std::string,int> semanticEnum; semanticEnum["Roof"] = 1; semanticEnum["Window"] = 2; semanticEnum["Door"] = 3; semanticEnum["Wall"] = 4; semanticEnum["Ground"] = 5; semanticEnum["Ceiling"] = 6; semanticEnum["Floor"] = 7; semanticEnum["Closure"] = 8; semanticEnum["Anything"] = 9; //semanticEnum["Install"] = 10; Vector_3 ortVec; Polyhedron::Facet_iterator exfIt; // Iterate over exterior faces for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) { int minSem = 99; for (std::vector<std::string>::iterator svIt=exfIt->equidistSems.begin();svIt!=exfIt->equidistSems.end();++svIt) { // Add equidist semantics std::map<std::string,int>::iterator seIt = semanticEnum.find(*svIt); if (seIt!=semanticEnum.end()) { // ...... if (seIt->second<minSem) { minSem = seIt->second; exfIt->semanticBLA = *svIt; } }else { // This seems wrong... exfIt->semanticBLA = *svIt; break; } } pointVector facetPoints = comp_facetPoints(exfIt); CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec); // Calculate normal vector, ortVec set to zero in newell if (!normalizeVector(ortVec)) continue; std::map<std::string,std::vector<bool>>::iterator snIt = semanticNormals.find(exfIt->semanticBLA); if (snIt!=semanticNormals.end()) { if (!snIt->second[0] && ortVec.z() > HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_UP_SEMANTIC; else if (!snIt->second[1] && ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC; else if (!snIt->second[2] && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC; } else { if (ortVec.z() > HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_UP_SEMANTIC; else if (ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC; else if (ortVec.z() <= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC; } } // Set semantics of facets created due to closing (too far from original geometry) for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) { if (exfIt->semanticBLA==TO_DIST_SEMANTIC) { std::set<Polyhedron::Facet_handle> fhSet; connectedSemFacets(exfIt,TO_DIST_SEMANTIC,false,fhSet); bool canBeUp = indirectlyTouchingFindSem(DEFAULT_UP_SEMANTIC,fhSet); bool canBeDown = indirectlyTouchingFindSem(DEFAULT_DOWN_SEMANTIC,fhSet); assignCeilVloor(fhSet,canBeUp,canBeDown); } } }