예제 #1
0
// Writes facet with gmlID to file
void CityGMLWriter::writeSurfaceMember(Polyhedron::Facet_handle fh, std::string gmlID, bool is_interior) {
	gml_ofstream << indent++ << "<gml:surfaceMember>"<<std::endl;
	if (gmlID=="") {
		std::stringstream gmlIDss;
		gmlIDss << filename_0ext<<"_Solid_"<<SLDgmlID;			
		gmlID = gmlIDss.str();
		gmlIDs["BuildingInstallation"].push_back(gmlID);
		++SLDgmlID;
	}

	gml_ofstream << indent++ << "<gml:Polygon gml:id=\""<< gmlID <<"\">"<<std::endl;
    gml_ofstream << indent++ << "<gml:exterior>"<<std::endl;
    gml_ofstream << indent++ << "<gml:LinearRing>"<<std::endl;
    gml_ofstream << indent++ << "<gml:posList>"<<std::endl;
	// Get posList
		pointVector pointV = comp_facetPoints(fh);					// Reverse List if interior so facets should face inward
		if (is_interior) std::reverse(pointV.begin(),pointV.end());

		std::string posList; std::stringstream ss;							// Putting coordinates in a String
		
		for (pointVector::iterator pvIt=pointV.begin();pvIt!=pointV.end();++pvIt) {
			ss.str(std::string());ss.clear();ss.precision(OUTPUT_DECIMALS); ss << indent << *pvIt << ""<<std::endl;
			posList += ss.str();
		}		// Duplicate first coords at the end
		ss.str(std::string());ss.clear();ss.precision(OUTPUT_DECIMALS); ss <<indent << CGAL::to_double(pointV.begin()->x()) <<" "<< CGAL::to_double(pointV.begin()->y()) <<" "<< CGAL::to_double(pointV.begin()->z()) << ""<<std::endl;
		posList += ss.str();
	// Got posList
	gml_ofstream << posList;
	gml_ofstream << --indent << "</gml:posList>"<<std::endl;
	gml_ofstream << --indent << "</gml:LinearRing>"<<std::endl;
	gml_ofstream << --indent << "</gml:exterior>"<<std::endl;
	gml_ofstream << --indent << "</gml:Polygon>"<<std::endl;
	gml_ofstream << --indent << "</gml:surfaceMember>"<<std::endl;
}
예제 #2
0
// Assign either ceiling, floor or the default semantic based on input booleans and normal vector
void assignCeilVloor(std::set<Polyhedron::Facet_handle>& fhSet, bool canBeUp, bool canBeDown) {
	pointVector facetPoints;
	Vector_3 ortVec;
	for (std::set<Polyhedron::Facet_handle>::iterator sfIt=fhSet.begin();sfIt!=fhSet.end();++sfIt) {
		if (!canBeUp && !canBeDown) {
			(*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC; continue;
		}

		facetPoints = comp_facetPoints(*sfIt);
		CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec);
		if (!normalizeVector(ortVec)) continue;
		if (canBeDown && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE )	(*sfIt)->semanticBLA = DEFAULT_DOWN_SEMANTIC;
		else if (canBeUp && ortVec.z() >= HORIZONTAL_ANGLE_RANGE )	(*sfIt)->semanticBLA = DEFAULT_UP_SEMANTIC;
		else														(*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC;
	}
}
예제 #3
0
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;
}
예제 #4
0
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);
		}
	}
}