mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +00:00
SVG --draw-storey-heights=left option
This commit is contained in:
@@ -355,6 +355,9 @@ int main(int argc, char** argv) {
|
|||||||
double section_height;
|
double section_height;
|
||||||
std::string svg_scale, svg_center;
|
std::string svg_scale, svg_center;
|
||||||
std::string section_ref, elevation_ref;
|
std::string section_ref, elevation_ref;
|
||||||
|
// "none", "full" or "left"
|
||||||
|
std::string storey_height_display;
|
||||||
|
SvgSerializer::storey_height_display_types svg_storey_height_display = SvgSerializer::SH_NONE;
|
||||||
|
|
||||||
po::options_description serializer_options("Serialization options");
|
po::options_description serializer_options("Serialization options");
|
||||||
serializer_options.add_options()
|
serializer_options.add_options()
|
||||||
@@ -381,6 +384,7 @@ int main(int argc, char** argv) {
|
|||||||
("auto-elevation",
|
("auto-elevation",
|
||||||
"Creates SVG elevation drawings automatically based on model extents")
|
"Creates SVG elevation drawings automatically based on model extents")
|
||||||
("draw-storey-heights",
|
("draw-storey-heights",
|
||||||
|
po::value<std::string>(&storey_height_display)->default_value("none")->implicit_value("full"),
|
||||||
"Draws a horizontal line at the height of building storeys in vertical drawings")
|
"Draws a horizontal line at the height of building storeys in vertical drawings")
|
||||||
("svg-xmlns",
|
("svg-xmlns",
|
||||||
"Stores name and guid in a separate namespace as opposed to data-name, data-guid")
|
"Stores name and guid in a separate namespace as opposed to data-name, data-guid")
|
||||||
@@ -508,6 +512,22 @@ int main(int argc, char** argv) {
|
|||||||
print_usage();
|
print_usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vmap.count("draw-storey-heights")) {
|
||||||
|
boost::to_lower(storey_height_display);
|
||||||
|
|
||||||
|
if (storey_height_display == "none") {
|
||||||
|
svg_storey_height_display = SvgSerializer::SH_NONE;
|
||||||
|
} else if (storey_height_display == "full") {
|
||||||
|
svg_storey_height_display = SvgSerializer::SH_FULL;
|
||||||
|
} else if (storey_height_display == "left") {
|
||||||
|
svg_storey_height_display = SvgSerializer::SH_LEFT;
|
||||||
|
} else {
|
||||||
|
cerr_ << "[Error] --draw-storey-heights should be none|full|left" << std::endl;
|
||||||
|
print_usage();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (vmap.count("log-format") == 1) {
|
if (vmap.count("log-format") == 1) {
|
||||||
boost::to_lower(log_format);
|
boost::to_lower(log_format);
|
||||||
@@ -952,7 +972,7 @@ int main(int argc, char** argv) {
|
|||||||
static_cast<SvgSerializer*>(serializer.get())->setPrintSpaceAreas(true);
|
static_cast<SvgSerializer*>(serializer.get())->setPrintSpaceAreas(true);
|
||||||
}
|
}
|
||||||
if (vmap.count("draw-storey-heights") != 0) {
|
if (vmap.count("draw-storey-heights") != 0) {
|
||||||
static_cast<SvgSerializer*>(serializer.get())->setDrawStoreyHeights(true);
|
static_cast<SvgSerializer*>(serializer.get())->setDrawStoreyHeights(svg_storey_height_display);
|
||||||
}
|
}
|
||||||
if (bounding_width.is_initialized() && bounding_height.is_initialized()) {
|
if (bounding_width.is_initialized() && bounding_height.is_initialized()) {
|
||||||
static_cast<SvgSerializer*>(serializer.get())->setBoundingRectangle(bounding_width.get(), bounding_height.get());
|
static_cast<SvgSerializer*>(serializer.get())->setBoundingRectangle(bounding_width.get(), bounding_height.get());
|
||||||
|
|||||||
@@ -1022,7 +1022,12 @@ void SvgSerializer::write(const geometry_data& data) {
|
|||||||
gp_Pnt prev;
|
gp_Pnt prev;
|
||||||
|
|
||||||
for (int i = 1; i <= wires->Length(); ++i) {
|
for (int i = 1; i <= wires->Length(); ++i) {
|
||||||
const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i));
|
|
||||||
|
// @nb not const, because in case of storey annotations we might
|
||||||
|
// generate a new wire with fixed length
|
||||||
|
|
||||||
|
TopoDS_Wire wire = TopoDS::Wire(wires->Value(i));
|
||||||
|
|
||||||
if (wire.Closed() && (print_space_names_ || print_space_areas_) && data.product->declaration().is("IfcSpace")) {
|
if (wire.Closed() && (print_space_names_ || print_space_areas_) && data.product->declaration().is("IfcSpace")) {
|
||||||
// we explicitly specify the surface here, to later on
|
// we explicitly specify the surface here, to later on
|
||||||
// simplify the projection from {x,y,z} to {u, v} because
|
// simplify the projection from {x,y,z} to {u, v} because
|
||||||
@@ -1040,9 +1045,8 @@ void SvgSerializer::write(const geometry_data& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
write(*po, wire);
|
|
||||||
|
if (data.product->declaration().is("IfcBuildingStorey") && storey_height_display_ != SH_NONE && wires->Length() == 1 && IfcGeom::Kernel::count(wire, TopAbs_EDGE) == 1) {
|
||||||
if (data.product->declaration().is("IfcBuildingStorey") && draw_storey_heights_ && wires->Length() == 1 && IfcGeom::Kernel::count(wire, TopAbs_EDGE) == 1) {
|
|
||||||
|
|
||||||
std::string elev_str;
|
std::string elev_str;
|
||||||
|
|
||||||
@@ -1077,12 +1081,31 @@ void SvgSerializer::write(const geometry_data& data) {
|
|||||||
std::swap(p0, p1);
|
std::swap(p0, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo these settings are getting out of hand, how can we
|
||||||
|
// streamline this?
|
||||||
|
std::string anchor;
|
||||||
|
gp_Pnt* anchor_pt;
|
||||||
|
if (storey_height_display_ == SH_FULL) {
|
||||||
|
anchor = "end";
|
||||||
|
anchor_pt = &p1;
|
||||||
|
} else {
|
||||||
|
anchor = "start";
|
||||||
|
anchor_pt = &p0;
|
||||||
|
|
||||||
|
auto d = (p1.XYZ() - p0.XYZ());
|
||||||
|
d.Normalize();
|
||||||
|
d *= 3;
|
||||||
|
gp_Pnt p1x(p0.XYZ() + d);
|
||||||
|
|
||||||
|
wire = BRepBuilderAPI_MakePolygon(p0, p1x).Wire();
|
||||||
|
}
|
||||||
|
|
||||||
// dominant-baseline="central" is not well supported in IE.
|
// dominant-baseline="central" is not well supported in IE.
|
||||||
// so we add a 0.35 offset to the dy of the tspans
|
// so we add a 0.35 offset to the dy of the tspans
|
||||||
path.add(" <text text-anchor=\"end\" x=\"");
|
path.add(" <text text-anchor=\"" + anchor + "\" x=\"");
|
||||||
xcoords.push_back(path.add(p1.X()));
|
xcoords.push_back(path.add(anchor_pt->X()));
|
||||||
path.add("\" y=\"");
|
path.add("\" y=\"");
|
||||||
ycoords.push_back(path.add(p1.Y()));
|
ycoords.push_back(path.add(anchor_pt->Y()));
|
||||||
path.add("\">");
|
path.add("\">");
|
||||||
for (auto lit = labels.begin(); lit != labels.end(); ++lit) {
|
for (auto lit = labels.begin(); lit != labels.end(); ++lit) {
|
||||||
const auto& l = *lit;
|
const auto& l = *lit;
|
||||||
@@ -1091,7 +1114,7 @@ void SvgSerializer::write(const geometry_data& data) {
|
|||||||
: 1.0; // <- dy is relative to the previous text element, so
|
: 1.0; // <- dy is relative to the previous text element, so
|
||||||
// always 1 for successive spans.
|
// always 1 for successive spans.
|
||||||
path.add("<tspan x=\"");
|
path.add("<tspan x=\"");
|
||||||
xcoords.push_back(path.add(p1.X()));
|
xcoords.push_back(path.add(anchor_pt->X()));
|
||||||
path.add("\" dy=\"");
|
path.add("\" dy=\"");
|
||||||
path.add(boost::lexical_cast<std::string>(dy));
|
path.add(boost::lexical_cast<std::string>(dy));
|
||||||
path.add("em\">");
|
path.add("em\">");
|
||||||
@@ -1101,6 +1124,8 @@ void SvgSerializer::write(const geometry_data& data) {
|
|||||||
path.add("</text>");
|
path.add("</text>");
|
||||||
po->second.push_back(path);
|
po->second.push_back(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write(*po, wire);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,7 +1522,7 @@ void SvgSerializer::finalize() {
|
|||||||
draw_hlr(ax, { nullptr, drawing_name });
|
draw_hlr(ax, { nullptr, drawing_name });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_storey_heights_ && pln && std::abs(pln->Position().Direction().Z()) < 1.e-5) {
|
if (storey_height_display_ != SH_NONE && pln && std::abs(pln->Position().Direction().Z()) < 1.e-5) {
|
||||||
auto storeys = this->file->instances_by_type("IfcBuildingStorey");
|
auto storeys = this->file->instances_by_type("IfcBuildingStorey");
|
||||||
if (storeys) {
|
if (storeys) {
|
||||||
const double lu = file->getUnit("LENGTHUNIT").second;
|
const double lu = file->getUnit("LENGTHUNIT").second;
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ class SvgSerializer : public GeometrySerializer {
|
|||||||
public:
|
public:
|
||||||
typedef std::pair<std::string, std::vector<util::string_buffer> > path_object;
|
typedef std::pair<std::string, std::vector<util::string_buffer> > path_object;
|
||||||
typedef std::vector< boost::shared_ptr<util::string_buffer::float_item> > float_item_list;
|
typedef std::vector< boost::shared_ptr<util::string_buffer::float_item> > float_item_list;
|
||||||
|
enum storey_height_display_types {
|
||||||
|
SH_NONE, SH_FULL, SH_LEFT
|
||||||
|
};
|
||||||
protected:
|
protected:
|
||||||
std::ofstream svg_file;
|
std::ofstream svg_file;
|
||||||
double xmin, ymin, xmax, ymax, width, height;
|
double xmin, ymin, xmax, ymax, width, height;
|
||||||
@@ -133,7 +136,7 @@ protected:
|
|||||||
boost::optional<double> scale_, calculated_scale_, center_x_, center_y_;
|
boost::optional<double> scale_, calculated_scale_, center_x_, center_y_;
|
||||||
|
|
||||||
bool with_section_heights_from_storey_, rescale, print_space_names_, print_space_areas_;
|
bool with_section_heights_from_storey_, rescale, print_space_names_, print_space_areas_;
|
||||||
bool draw_storey_heights_;
|
storey_height_display_types storey_height_display_;
|
||||||
bool draw_door_arcs_, is_floor_plan_;
|
bool draw_door_arcs_, is_floor_plan_;
|
||||||
bool auto_section_, auto_elevation_;
|
bool auto_section_, auto_elevation_;
|
||||||
bool use_namespace_, use_hlr_poly_, always_project_;
|
bool use_namespace_, use_hlr_poly_, always_project_;
|
||||||
@@ -208,7 +211,7 @@ public:
|
|||||||
void setSectionHeightsFromStoreys(double offset=1.);
|
void setSectionHeightsFromStoreys(double offset=1.);
|
||||||
void setPrintSpaceNames(bool b) { print_space_names_ = b; }
|
void setPrintSpaceNames(bool b) { print_space_names_ = b; }
|
||||||
void setPrintSpaceAreas(bool b) { print_space_areas_ = b; }
|
void setPrintSpaceAreas(bool b) { print_space_areas_ = b; }
|
||||||
void setDrawStoreyHeights(bool b) { draw_storey_heights_ = b; }
|
void setDrawStoreyHeights(storey_height_display_types sh) { storey_height_display_ = sh; }
|
||||||
void setDrawDoorArcs(bool b) { draw_door_arcs_ = b; }
|
void setDrawDoorArcs(bool b) { draw_door_arcs_ = b; }
|
||||||
|
|
||||||
std::array<std::array<double, 3>, 3> resize();
|
std::array<std::array<double, 3>, 3> resize();
|
||||||
|
|||||||
Reference in New Issue
Block a user