mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
#1153 --svg-without-storeys and correct positioning and scale based on annotation block
This commit is contained in:
@@ -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>(§ion_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);
|
||||
}
|
||||
|
||||
@@ -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\"";
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user