From 979f37d7c6df170596ebf182ccc01b0b5fd2f71e Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sat, 2 Jan 2021 12:34:10 +0100 Subject: [PATCH] --svg-poly option and correct HLR view direction --- src/ifcconvert/IfcConvert.cpp | 3 ++ src/serializers/SvgSerializer.cpp | 77 ++++++++++++++++++++----------- src/serializers/SvgSerializer.h | 12 ++++- 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 63926249d1..45e5520dce 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -376,6 +376,8 @@ int main(int argc, char** argv) { "Creates SVG elevation drawings automatically based on model extents") ("svg-xmlns", "Stores name and guid in a separate namespace as opposed to data-name, data-guid") + ("svg-poly", + "Uses the polygonal algorithm for hidden line rendering") ("door-arcs", "Draw door openings arcs for IfcDoor elements") ("section-height", po::value(§ion_height), "Specifies the cut section height for SVG 2D geometry.") @@ -959,6 +961,7 @@ int main(int argc, char** argv) { static_cast(serializer.get())->setAutoElevation(true); } static_cast(serializer.get())->setUseNamespace(vmap.count("svg-xmlns") > 0); + static_cast(serializer.get())->setUseHlrPoly(vmap.count("svg-poly") > 0); if (relative_center_x && relative_center_y) { static_cast(serializer.get())->setDrawingCenter(*relative_center_x, *relative_center_y); } diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 998d68c577..ad3f89cd57 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -68,6 +68,8 @@ #include +#include + #include "../ifcparse/IfcGlobalId.h" #include "SvgSerializer.h" @@ -566,7 +568,7 @@ void SvgSerializer::write(const geometry_data& data) { auto& compound_to_use = is_floor_plan_ ? compound : compound_unmirrored; - if (use_hlr && hlr) { + if (use_hlr && (hlr_poly || hlr_brep)) { // Check if any of the bounding box points is on the correct side of the plane Bnd_Box bb; @@ -593,13 +595,19 @@ void SvgSerializer::write(const geometry_data& data) { } else { state = d < 0. ? -1 : 1; } - if (state == 1) { + if (state == -1) { any = true; } } if (any) { - hlr->Add(compound_to_use); + if (hlr_brep) { + hlr_brep->Add(compound_to_use); + } + if (hlr_poly) { + BRepMesh_IncrementalMesh(compound_to_use, 0.10); + hlr_poly->Load(compound_to_use); + } } } @@ -988,30 +996,30 @@ void SvgSerializer::finalize() { if (auto_elevation_) { { gp_Pln pln(gp_Ax3( - gp_Pnt((xmin + xmax) / 2., -(ymin - 1.e-1), 0.), - gp_Dir(0, -1, 0), - gp_Dir(-1, 0, 0))); + gp_Pnt(0., -(ymin - 10.), 0.), + gp_Dir(0, 1, 0), + gp_Dir(1, 0, 0))); deferred_section_data_->push_back(vertical_section{ pln , "Elevation South", true }); } { gp_Pln pln(gp_Ax3( - gp_Pnt(xmax + 1.e-1, (ymin + ymax) / -2., 0.), - gp_Dir(-1, 0, 0), - gp_Dir(0, -1, 0))); + gp_Pnt(xmax + 10., 0., 0.), + gp_Dir(1, 0, 0), + gp_Dir(0, 1, 0))); deferred_section_data_->push_back(vertical_section{ pln , "Elevation East", true }); } { gp_Pln pln(gp_Ax3( - gp_Pnt((xmin + xmax) / 2., -(ymax + 1.e-1), 0.), - gp_Dir(0, 1, 0), - gp_Dir(1, 0, 0))); + gp_Pnt(0., -(ymax + 10.), 0.), + gp_Dir(0, -1, 0), + gp_Dir(-1, 0, 0))); deferred_section_data_->push_back(vertical_section{ pln , "Elevation North", true }); } { gp_Pln pln(gp_Ax3( - gp_Pnt(xmin - 1.e-1, (ymin + ymax) / -2., 0.), - gp_Dir(1, 0, 0), - gp_Dir(0, 1, 0))); + gp_Pnt(xmin - 10., 0., 0.), + gp_Dir(-1, 0, 0), + gp_Dir(0, -1, 0))); deferred_section_data_->push_back(vertical_section{ pln , "Elevation West", true }); } } @@ -1033,7 +1041,11 @@ void SvgSerializer::finalize() { } if (use_hlr) { - hlr = new HLRBRep_Algo; + if (use_hlr_poly_) { + hlr_poly = new HLRBRep_PolyAlgo; + } else { + hlr_brep = new HLRBRep_Algo; + } } section_data_ = std::vector{ sd }; @@ -1043,18 +1055,30 @@ void SvgSerializer::finalize() { if (use_hlr) { const auto& section = boost::get(sd); - gp_Ax2 transform = section.plane.Position().Ax2(); - HLRAlgo_Projector projector(transform); - hlr->Projector(projector); - hlr->Update(); - hlr->Hide(); + gp_Trsf trsf; + trsf.SetTransformation(section.plane.Position()); + HLRAlgo_Projector projector(trsf, false, 1.); + + TopoDS_Shape hlr_compound_unmirrored; + + if (use_hlr_poly_) { + hlr_poly->Projector(projector); - HLRBRep_HLRToShape hlr_shapes(hlr); - auto hlr_compound_unmirrored = hlr_shapes.VCompound(); + hlr_poly->Update(); + HLRBRep_PolyHLRToShape hlr_shapes; + hlr_shapes.Update(hlr_poly); + hlr_compound_unmirrored = hlr_shapes.VCompound(); + } else { + hlr_brep->Projector(projector); + + hlr_brep->Update(); + hlr_brep->Hide(); + HLRBRep_HLRToShape hlr_shapes(hlr_brep); + hlr_compound_unmirrored = hlr_shapes.VCompound(); + } if (!hlr_compound_unmirrored.IsNull()) { - // Compound 3D curves for mirroring to work ShapeFix_Edge sfe; TopExp_Explorer exp(hlr_compound_unmirrored, TopAbs_EDGE); @@ -1092,9 +1116,8 @@ void SvgSerializer::finalize() { resetScale(); - if (use_hlr) { - hlr.Nullify(); - } + if (hlr_brep) hlr_brep.Nullify(); + if (hlr_poly) hlr_poly.Nullify(); } } diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index 73555e125d..f1b3740ad6 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include @@ -126,7 +128,7 @@ protected: bool with_section_heights_from_storey_, rescale, print_space_names_, print_space_areas_; bool draw_door_arcs_, is_floor_plan_; bool auto_section_, auto_elevation_; - bool use_namespace_; + bool use_namespace_, use_hlr_poly_; IfcParse::IfcFile* file; IfcUtil::IfcBaseEntity* storey_; @@ -140,7 +142,8 @@ protected: std::list element_buffer_; - Handle(HLRBRep_Algo) hlr; + Handle(HLRBRep_Algo) hlr_brep; + Handle(HLRBRep_PolyAlgo) hlr_poly; std::string namespace_prefix_; public: @@ -160,6 +163,7 @@ public: , auto_section_(false) , auto_elevation_(false) , use_namespace_(false) + , use_hlr_poly_(false) , file(0) , storey_(0) , xcoords_begin(0) @@ -213,6 +217,10 @@ public: namespace_prefix_ = use_namespace_ ? "ifc:" : "data-"; } + void setUseHlrPoly(bool b) { + use_hlr_poly_ = b; + } + void setScale(double s) { scale_ = s; } void setDrawingCenter(double x, double y) { center_x_ = x; center_y_ = y;