From 1c82d8c9360dc6e0591a00b3a0133b6af9a535e3 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 10 May 2020 11:10:30 +0200 Subject: [PATCH] svg print space areas --- src/ifcconvert/IfcConvert.cpp | 6 +++++- src/serializers/SvgSerializer.cpp | 23 +++++++++++++++++------ src/serializers/SvgSerializer.h | 3 ++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 17b818a452..0d9d0d8ae3 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -357,7 +357,8 @@ int main(int argc, char** argv) { "Use a negative value to use the system's default precision (should be 6 typically). " "Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used, " " and any other value means that 6 or 7 decimals are used.") - ("print-space-names", "Prints IfcSpace LongName and Name in the geometry output. Applicable for SVG output"); + ("print-space-names", "Prints IfcSpace LongName and Name in the geometry output. Applicable for SVG output") + ("print-space-areas", "Prints calculated IfcSpace areas in square meters. Applicable for SVG output"); po::options_description cmdline_options; cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(ifc_options).add(serializer_options); @@ -689,6 +690,9 @@ int main(int argc, char** argv) { if (vmap.count("print-space-names") != 0) { static_cast(serializer.get())->setPrintSpaceNames(true); } + if (vmap.count("print-space-areas") != 0) { + static_cast(serializer.get())->setPrintSpaceAreas(true); + } if (bounding_width.is_initialized() && bounding_height.is_initialized()) { static_cast(serializer.get())->setBoundingRectangle(bounding_width.get(), bounding_height.get()); } diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 19c0bc21ba..511eb53150 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -383,7 +383,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) for (int i = 1; i <= wires->Length(); ++i) { const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i)); - if (wire.Closed() && print_space_names_ && o->type() == "IfcSpace") { + if (wire.Closed() && (print_space_names_ || print_space_areas_) && o->type() == "IfcSpace") { // we explicitly specify the surface here, to later on // simplify the projection from {x,y,z} to {u, v} because // we know we can simply discard z. @@ -448,8 +448,11 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) } if (center_point) { - std::vector labels = { o->name() }; - if (o->type() == "IfcSpace") { + std::vector labels; + if (print_space_names_) { + labels.push_back(o->name()); + } + if (print_space_names_ && o->type() == "IfcSpace") { auto attr = o->product()->get("LongName"); if (!attr->isNull()) { std::string long_name = *attr; @@ -458,6 +461,14 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) } } } + if (print_space_areas_) { + GProp_GProps prop; + BRepGProp::SurfaceProperties(largest_closed_wire_face, prop); + const double area = prop.Mass(); + std::stringstream ss; + ss << std::setprecision(2) << std::fixed << std::showpoint << area; + labels.push_back(ss.str() + "m²"); + } path_object& po = p; util::string_buffer path; @@ -468,9 +479,9 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) path.add("\" y=\""); ycoords.push_back(path.add(center_point->Y())); path.add("\">"); - for (auto it = labels.begin(); it != labels.end(); ++it) { - const auto& l = *it; - double dy = labels.begin() == it + for (auto lit = labels.begin(); lit != labels.end(); ++lit) { + const auto& l = *lit; + double dy = labels.begin() == lit ? 0.35 - (labels.size() - 1.) / 2. : 1.0; // <- dy is relative to the previous text element, so // always 1 for successive spans. diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index ee3b675599..770da52479 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -38,7 +38,7 @@ protected: std::ofstream svg_file; double xmin, ymin, xmax, ymax, width, height; boost::optional section_height; - bool rescale, print_space_names_; + bool rescale, print_space_names_, print_space_areas_; std::multimap paths; std::vector< boost::shared_ptr > xcoords; std::vector< boost::shared_ptr > ycoords; @@ -74,6 +74,7 @@ public: void setBoundingRectangle(double width, double height); void setSectionHeight(double h, IfcUtil::IfcBaseEntity* storey = 0) { section_height = h; storey_ = storey; } void setPrintSpaceNames(bool b) { print_space_names_ = b; } + void setPrintSpaceAreas(bool b) { print_space_areas_ = b; } std::string nameElement(const IfcGeom::Element* elem); std::string nameElement(const IfcUtil::IfcBaseEntity* elem); };