diff --git a/src/ifcconvert/SvgSerializer.cpp b/src/ifcconvert/SvgSerializer.cpp index 43677966e5..a517ac42c1 100644 --- a/src/ifcconvert/SvgSerializer.cpp +++ b/src/ifcconvert/SvgSerializer.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -209,7 +210,8 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) } } - if (!storey) return; + // With a global section height, building storeys are not a requirement. + if (!storey && !section_height) return; path_object& p = start_path(storey, nameElement(o)); @@ -343,8 +345,52 @@ std::string SvgSerializer::nameElement(const IfcGeom::Element* elem) } std::string SvgSerializer::nameElement(const IfcSchema::IfcProduct* elem) { + if (elem == 0) { return ""; } std::ostringstream oss; const std::string type = elem->is(IfcSchema::Type::IfcBuildingStorey) ? "storey" : "product"; oss << "id=\"product-" << IfcParse::IfcGlobalId(elem->GlobalId()).formatted() << "\""; return oss.str(); } + +void SvgSerializer::setFile(IfcParse::IfcFile* f) { + file = f; + IfcSchema::IfcBuildingStorey::list::ptr storeys = f->entitiesByType(); + if (!storeys || storeys->size() == 0) { + + IfcGeom::Kernel kernel; + + IfcSchema::IfcProject::list::ptr projects = f->entitiesByType(); + if (projects->size() == 1) { + IfcSchema::IfcProject* project = *projects->begin(); + std::pair length_unit = kernel.initializeUnits(project->UnitsInContext()); + } else { + Logger::Error("No single project encountered, output might be invalid or missing"); + return; + } + + std::vector to_derive_from; + to_derive_from.push_back(IfcSchema::Type::IfcBuilding); + to_derive_from.push_back(IfcSchema::Type::IfcSite); + std::vector::const_iterator it; + for (it = to_derive_from.begin(); it != to_derive_from.end(); ++it) { + IfcEntityList::ptr untyped = f->entitiesByType(*it); + if (untyped) { + IfcSchema::IfcProduct::list::ptr insts = untyped->as(); + IfcSchema::IfcProduct::list::it jt; + for (jt = insts->begin(); jt != insts->end(); ++jt) { + IfcSchema::IfcProduct* product = *jt; + if (product->hasObjectPlacement()) { + gp_Trsf trsf; + if (kernel.convert(product->ObjectPlacement(), trsf)) { + setSectionHeight(trsf.TranslationPart().Z() + 1.); + Logger::Warning("No building storeys encountered, used for reference:", product->entity); + return; + } + } + } + } + } + } + + Logger::Error("No building storeys encountered, output might be invalid or missing"); +} \ No newline at end of file diff --git a/src/ifcconvert/SvgSerializer.h b/src/ifcconvert/SvgSerializer.h index 542541f9d0..21de0107f7 100644 --- a/src/ifcconvert/SvgSerializer.h +++ b/src/ifcconvert/SvgSerializer.h @@ -66,7 +66,7 @@ public: bool isTesselated() const { return false; } void finalize(); void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {} - void setFile(IfcParse::IfcFile* f) { file = f; } + void setFile(IfcParse::IfcFile* f); void setBoundingRectangle(double width, double height); void setSectionHeight(double h) { section_height = h; } std::string nameElement(const IfcGeom::Element* elem);