void CityGMLWriter::writeGeometrySLD(PolVector& pVec,int LoD,bool is_buildInstall) { for (PolVector::iterator pvIt=pVec.begin();pvIt!=pVec.end();++pvIt) { // Writing solid if (is_buildInstall) gml_ofstream << indent++ << "<bldg:lod"<<LoD<<"Geometry>"<<std::endl; else gml_ofstream << indent++ << "<bldg:lod"<<LoD<<"Solid>"<<std::endl; gml_ofstream << indent++ << "<gml:Solid>"<<std::endl; gml_ofstream << indent++ << "<gml:exterior>"<<std::endl; gml_ofstream << indent++ << "<gml:CompositeSurface>"<<std::endl; for (Polyhedron::Facet_iterator fIt=pvIt->facets_begin();fIt!=pvIt->facets_end();++fIt) writeSurfaceMember(fIt); gml_ofstream << --indent << "</gml:CompositeSurface>"<<std::endl; gml_ofstream << --indent << "</gml:exterior>"<<std::endl; gml_ofstream << --indent << "</gml:Solid>"<<std::endl; if (is_buildInstall) gml_ofstream << --indent << "</bldg:lod"<<LoD<<"Geometry>"<<std::endl; else gml_ofstream << --indent << "</bldg:lod"<<LoD<<"Solid>"<<std::endl; } }
void CityGMLWriter::writeGeometry(PolVector& pVec,int kindOSolid,int LoD) { bool is_build = kindOSolid==0; bool is_buildInstall = kindOSolid==1; bool is_buildPart = kindOSolid==2; bool is_room = kindOSolid==3; bool is_interior = is_room; unsigned int partCount = 0; for (PolVector::iterator pvIt=pVec.begin();pvIt!=pVec.end();++pvIt,++partCount) { // create sfs sfsVec semFacetSetsVector; sfsVec openSFSVector; std::map<int,std::vector<int>> openingMap; groupSemanticFacets(*pvIt,semFacetSetsVector,openSFSVector,openingMap); // Write header if (!is_build) writeGeometryHeader(kindOSolid,partCount); // Should start loop over all LoD's here but mehh sfsVec::iterator sfsVecIt=semFacetSetsVector.begin(); if (temp2FinalSem(sfsVecIt->first)!="BuildingInstallation") { // GMLid's of the current solid GMLidMap solidIDs; int surfCount = 0; // Current surface index for (;sfsVecIt!=semFacetSetsVector.end();++sfsVecIt,++surfCount) { std::string finalSem = temp2FinalSem(sfsVecIt->first); gml_ofstream << indent++ << "<bldg:boundedBy>"<<std::endl; gml_ofstream << indent++ << "<bldg:"+finalSem+">"<<std::endl; gml_ofstream << indent << "<gml:name>"<<sfsVecIt->first<<" "<<partCount<<surfCount<<"</gml:name>"<<std::endl; gml_ofstream << indent++ << "<bldg:lod"<<LoD<<"MultiSurface>"<<std::endl; // lod3Geometry for bi? No only solids gml_ofstream << indent++ << "<gml:MultiSurface>"<<std::endl; // Prepare gmlId string std::stringstream idStrtss; if (is_build) { idStrtss << filename_0ext<<"_S"<<surfCount; } else if (is_buildInstall) { idStrtss << filename_0ext<<"_BuildingInstallation_"<<partCount<<"_S"<<surfCount; } else if (is_buildPart) { idStrtss << filename_0ext<<"_BuildingPart_"<<partCount<<"_S"<<surfCount; } else if (is_room) { idStrtss << filename_0ext<<"_Room_"<<partCount<<"_S"<<surfCount; } std::string gmlStrt = idStrtss.str(); int memIdx = 0; for (std::set<Polyhedron::Facet_handle>::iterator setIt=sfsVecIt->second.begin();setIt!=sfsVecIt->second.end();++setIt,++memIdx) { // Start new member // Create gmlID std::stringstream gmlIDss; gmlIDss << gmlStrt<<"_m"<<memIdx; std::string gmlID = gmlIDss.str(); // Store gmlID's solidIDs[finalSem].push_back(gmlID); // current solid gmlID's gmlIDs[finalSem].push_back(gmlID); // all gmlID's // Write Surface member to file writeSurfaceMember(*setIt,gmlID,is_interior); } // Close non-opening part of surface gml_ofstream << --indent << "</gml:MultiSurface>"<<std::endl; gml_ofstream << --indent << "</bldg:lod"<<LoD<<"MultiSurface>"<<std::endl; // lod3Geometry // Process openings for current surface writeSurfaceOpening(gmlStrt, solidIDs, openSFSVector, openingMap, surfCount,LoD,is_interior); // Close current surface gml_ofstream << --indent << "</bldg:"+finalSem+">"<<std::endl; gml_ofstream << --indent << "</bldg:boundedBy>"<<std::endl; } // Writing solid with XLinks gml_ofstream << indent++ << "<bldg:lod"<<LoD<<"Solid>"<<std::endl; gml_ofstream << indent++ << "<gml:Solid>"<<std::endl; gml_ofstream << indent++ << "<gml:exterior>"<<std::endl; gml_ofstream << indent++ << "<gml:CompositeSurface>"<<std::endl; for (idIt = solidIDs.begin(); idIt != solidIDs.end(); ++idIt) { gml_ofstream << indent << "<!-- "<<idIt->first<<" -->"<<std::endl; // Comment polyType for (int v = 0; v != idIt->second.size(); ++v) { if (is_interior) { gml_ofstream << indent++ << "<gml:surfaceMember>"<<std::endl; gml_ofstream << indent++ << "<gml:OrientableSurface orientation=\"-\">"<<std::endl; gml_ofstream << indent << "<gml:baseSurface xlink:href=\"#"<<idIt->second[v]<<"\"/>"<<std::endl; gml_ofstream << --indent << "</gml:OrientableSurface>"<<std::endl; gml_ofstream << --indent << "</gml:surfaceMember>"<<std::endl; } else gml_ofstream << indent << "<gml:surfaceMember xlink:href=\"#"<<idIt->second[v]<<"\"/>"<<std::endl; } } gml_ofstream << --indent << "</gml:CompositeSurface>"<<std::endl; gml_ofstream << --indent << "</gml:exterior>"<<std::endl; gml_ofstream << --indent << "</gml:Solid>"<<std::endl; gml_ofstream << --indent << "</bldg:lod"<<LoD<<"Solid>"<<std::endl; } else writeGeometrySLD(pVec,LoD,is_buildInstall); // Write no_SEM_BI solid // Close buildingInstall or BuildingPart if (!is_build) writeGeometryFooter(kindOSolid); } }
void set_semantic_AABB_C2V(Polyhedron& exteriorPolyhe,PolVector& polyVec) { if (exteriorPolyhe.is_pure_triangle()) { std::transform( exteriorPolyhe.facets_begin(), exteriorPolyhe.facets_end(),exteriorPolyhe.planes_begin(),Plane_equation()); std::vector<std::string> semList; std::vector<std::shared_ptr<AAbbTree>> treeList; // Build Trees. One for each semantic for(PolVector::iterator pvIt = polyVec.begin();pvIt!=polyVec.end();++pvIt) {// Get AABB trees of all semantics if (pvIt->is_pure_triangle()) { std::string semP = pvIt->facets_begin()->semanticBLA; std::vector<std::string>::iterator strIt = std::find(semList.begin(), semList.end(),semP); if (strIt==semList.end()) { // If new sematic semList.push_back(semP); // Add sem std::shared_ptr<AAbbTree> tree = std::make_shared<AAbbTree>(pvIt->facets_begin(),pvIt->facets_end()); // Create tree tree->accelerate_distance_queries(); // accelerate treeList.push_back(tree); // Add tree } else // If not new treeList[strIt-semList.begin()]->insert(pvIt->facets_begin(),pvIt->facets_end()); // Append to tree } else std::cerr << "ERROR: Not pure triangle (set_semantic_AABB2C2V)" << std::endl; } // For each facet calculate the least distance to each tree std::string semListStr = boost::algorithm::join((semList), " "); int percCount = 1; Polyhedron::Facet_iterator exfIt; // Iterate over exterior faces for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt,++percCount) { std::cout << "\r"<<semListStr<<". ("<<100*percCount/exteriorPolyhe.size_of_facets()<<"%)"; Vector_3 orthVec = exfIt->plane().orthogonal_vector(); normalizeVector(orthVec); //if (!normalizeVector(ortVec)) continue; std::vector<distSemFace> dsfList(semList.size()); Point_3 centerPoint = comp_facetCentroid(exfIt); // Compute centroid std::vector<Kernel::FT> leastSemDistances; for (int intIt=0;intIt<(int)treeList.size();++intIt) { // Loop over all trees AAbbTree::Point_and_primitive_id pp = treeList[intIt]->closest_point_and_primitive(centerPoint); dsfList[intIt].dist = CGAL::squared_distance(centerPoint,pp.first); // Store distance semantic and facet for each tree dsfList[intIt].sem = semList[intIt]; dsfList[intIt].fh = pp.second; } std::sort(dsfList.begin(),dsfList.end(),by_dist()); exfIt->leastSqDistance = dsfList[0].dist; // least sqrt distance if (exfIt->isMinkFacet = dsfList[0].dist > SEMANTIC_DISTANCE_THRESHOLD) { exfIt->semanticBLA = TO_DIST_SEMANTIC; // Default semantic if too distant continue; } else exfIt->semanticBLA = dsfList[0].sem; // Semantics of closest Vector_3 faceNormal; Kernel::FT faceSqArea; double minAngle = 10; Kernel::FT maxArea= 0; for (std::vector<distSemFace>::iterator slIt = dsfList.begin();slIt != dsfList.end();++slIt)// HANDLE ANYTHING AS LESS IMPORTANT if (slIt->dist < dsfList[0].dist+OVERLAP_DIST_THRESHOLD) { // Check if Equidistant pointVector facetPoints = comp_facetPoints(exfIt); CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),faceNormal); // Calculate normal vector, ortVec set to zero in newell double angle = comp_angle(orthVec,faceNormal); if (angle!=-1 && angle < minAngle+OVERLAP_ANGLE_THRESHOLD) { if (minAngle >= angle+OVERLAP_ANGLE_THRESHOLD) exfIt->equidistSems.clear(); if (angle < minAngle) minAngle = angle; faceSqArea = comp_facetSquaredArea(facetPoints); if (faceSqArea>maxArea-OVERLAP_AREA_THRESHOLD) { if (maxArea<=faceSqArea-OVERLAP_AREA_THRESHOLD) exfIt->equidistSems.clear(); if (faceSqArea>maxArea) maxArea = faceSqArea; exfIt->equidistSems.push_back(slIt->sem); // Add equidist semantics } } } } std::cout << "\r"<<semListStr<<". (100%)" << std::endl; }else std::cerr << "ERROR: Not pure triangle (set_semantic_AABB2C2V)" << std::endl; }