#1153 --svg-without-storeys and correct positioning and scale based on annotation block

This commit is contained in:
Thomas Krijnen
2021-04-18 15:03:28 +02:00
parent 776c68e2b0
commit bb6312e174
3 changed files with 53 additions and 6 deletions
+2
View File
@@ -396,6 +396,7 @@ int main(int argc, char** argv) {
"Approximate every curve as polygonal in SVG output")
("svg-project",
"Always enable hidden line rendering instead of only on elevations")
("svg-without-storeys", "Don't emit drawings for building storeys")
("door-arcs", "Draw door openings arcs for IfcDoor elements")
("section-height", po::value<double>(&section_height),
"Specifies the cut section height for SVG 2D geometry.")
@@ -1012,6 +1013,7 @@ int main(int argc, char** argv) {
static_cast<SvgSerializer*>(serializer.get())->setUseHlrPoly(vmap.count("svg-poly") > 0);
static_cast<SvgSerializer*>(serializer.get())->setPolygonal(vmap.count("svg-write-poly") > 0);
static_cast<SvgSerializer*>(serializer.get())->setAlwaysProject(vmap.count("svg-project") > 0);
static_cast<SvgSerializer*>(serializer.get())->setWithoutStoreys(vmap.count("svg-without-storeys") > 0);
if (relative_center_x && relative_center_y) {
static_cast<SvgSerializer*>(serializer.get())->setDrawingCenter(*relative_center_x, *relative_center_y);
}
+42 -4
View File
@@ -603,14 +603,37 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* brep_obj) {
}
}
if (!emit_building_storeys_ && scale && size) {
scale_ = scale;
size_ = std::make_pair(
// The header writes values in mm
size->first * 1000 * *scale_,
size->second * 1000 * *scale_
);
}
if (pln) {
// Move pln to have projection of origin at plane center.
// This is necessary to have Poly and BRep HLR at the same position
// (Poly) is wrong otherwise.
Extrema_ExtPElS ext;
ext.Perform(gp::Origin(), *pln, 1.e-5);
auto P0 = pln->Location();
pln->SetLocation(ext.Point(1).Value());
if (!emit_building_storeys_ && scale && size) {
auto P1 = pln->Location();
gp_Vec v(P1.XYZ() - P0.XYZ());
gp_Trsf pi;
pi.SetTransformation(pln->Position());
pi.Invert();
v.Transform(pi);
offset_2d_ = std::make_pair(
(-size->first / 2. - v.X()) * 1000 * *scale_,
(-size->second / 2. + v.Y()) * 1000 * *scale_
);
}
if (!deferred_section_data_) {
deferred_section_data_.emplace();
}
@@ -639,7 +662,9 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* brep_obj) {
element_buffer_.push_back(data);
}
write(data);
if (emit_building_storeys_) {
write(data);
}
}
namespace {
@@ -1408,16 +1433,22 @@ std::array<std::array<double, 3>, 3> SvgSerializer::resize() {
if (size_) {
// Scale the resulting image to a bounding rectangle specified by command line arguments
// or specified by IfcAnnotation[ObjectType=DRAWING]
const double dx = xmax - xmin;
const double dy = ymax - ymin;
double sc, cx, cy;
if (scale_) {
if (offset_2d_ && scale_) {
// offset_2d is the offset in plane u,v coordinates as we want to keep the
// plane coordinates used for HLR close to the model origin.
sc = (*scale_) * 1000;
cx = offset_2d_->first;
cy = offset_2d_->second;
} else if (scale_) {
sc = (*scale_) * 1000;
cx = (xmax + xmin) / 2. * sc - size_->first * center_x_.get_value_or(0.5);
cy = (ymax + ymin) / 2. * sc - size_->second * center_y_.get_value_or(0.5);
}
else {
} else {
if (calculated_scale_) {
sc = *calculated_scale_;
}
@@ -1708,6 +1739,8 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
}
void SvgSerializer::finalize() {
doWriteHeader();
for (auto& p : drawing_metadata) {
addTextAnnotations(p.first);
}
@@ -1900,6 +1933,11 @@ void SvgSerializer::finalize() {
}
void SvgSerializer::writeHeader() {
// This doesn't do anything anymore because there is now the option that an
// IfcAnnotation[ObjectType=DRAWING] defines the SVG viewBox and dimensions
}
void SvgSerializer::doWriteHeader() {
svg_file << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
if (use_namespace_) {
svg_file << " xmlns:ifc=\"http://www.ifcopenshell.org/ns\"";
+9 -2
View File
@@ -136,9 +136,9 @@ protected:
double xmin, ymin, xmax, ymax;
boost::optional<std::vector<section_data>> section_data_;
boost::optional<std::vector<section_data>> deferred_section_data_;
boost::optional<double> scale_, calculated_scale_, center_x_, center_y_, scale_backup_;
boost::optional<double> scale_, calculated_scale_, center_x_, center_y_;
boost::optional<double> storey_height_line_length_;
boost::optional<std::pair<double, double>> size_, size_backup_;
boost::optional<std::pair<double, double>> size_, offset_2d_;
boost::optional<std::string> space_name_transform_;
bool with_section_heights_from_storey_, print_space_names_, print_space_areas_;
@@ -146,6 +146,7 @@ protected:
bool draw_door_arcs_, is_floor_plan_;
bool auto_section_, auto_elevation_;
bool use_namespace_, use_hlr_poly_, always_project_, polygonal_;
bool emit_building_storeys_;
IfcParse::IfcFile* file;
IfcUtil::IfcBaseEntity* storey_;
@@ -189,6 +190,7 @@ public:
, use_hlr_poly_(false)
, always_project_(false)
, polygonal_(false)
, emit_building_storeys_(true)
, file(0)
, storey_(0)
, xcoords_begin(0)
@@ -201,6 +203,7 @@ public:
void addSizeComponent(const boost::shared_ptr<util::string_buffer::float_item>& fi) { radii.push_back(fi); }
void growBoundingBox(double x, double y) { if (x < xmin) xmin = x; if (x > xmax) xmax = x; if (y < ymin) ymin = y; if (y > ymax) ymax = y; }
void writeHeader();
void doWriteHeader();
bool ready();
void write(const IfcGeom::TriangulationElement<real_t>* /*o*/) {}
void write(const IfcGeom::BRepElement<real_t>* o);
@@ -258,6 +261,10 @@ public:
always_project_ = b;
}
void setWithoutStoreys(bool b) {
emit_building_storeys_ = !b;
}
void setScale(double s) { scale_ = s; }
void setDrawingCenter(double x, double y) {
center_x_ = x; center_y_ = y;