mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
#3660 setSegmentProjection() / --svg-segment-projection options
This commit is contained in:
@@ -205,31 +205,52 @@ namespace {
|
||||
class hlr_calc {
|
||||
private:
|
||||
const HLRAlgo_Projector& projector_;
|
||||
const std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>>* product_shapes_ = nullptr;
|
||||
|
||||
public:
|
||||
typedef TopoDS_Shape result_type;
|
||||
typedef std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>> result_type;
|
||||
|
||||
hlr_calc(const HLRAlgo_Projector& projector) : projector_(projector)
|
||||
{}
|
||||
|
||||
TopoDS_Shape operator()(boost::blank&) const {
|
||||
void set_product_shape(const std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>>* product_shapes) {
|
||||
product_shapes_ = product_shapes;
|
||||
}
|
||||
|
||||
result_type operator()(boost::blank&) const {
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
|
||||
TopoDS_Shape operator()(opencascade::handle<HLRBRep_Algo>& algo) {
|
||||
result_type operator()(opencascade::handle<HLRBRep_Algo>& algo) {
|
||||
algo->Projector(projector_);
|
||||
algo->Update();
|
||||
algo->Hide();
|
||||
HLRBRep_HLRToShape hlr_shapes(algo);
|
||||
return occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound());
|
||||
if (product_shapes_) {
|
||||
std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>> r;
|
||||
for (auto& p : *product_shapes_) {
|
||||
r.push_back({ p.first, occt_join(hlr_shapes.OutLineVCompound(p.second), hlr_shapes.VCompound(p.second)) });
|
||||
}
|
||||
return r;
|
||||
} else {
|
||||
return { {nullptr, occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound())}};
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape operator()(opencascade::handle<HLRBRep_PolyAlgo>& algo) {
|
||||
result_type operator()(opencascade::handle<HLRBRep_PolyAlgo>& algo) {
|
||||
algo->Projector(projector_);
|
||||
algo->Update();
|
||||
HLRBRep_PolyHLRToShape hlr_shapes;
|
||||
hlr_shapes.Update(algo);
|
||||
return occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound());
|
||||
if (product_shapes_) {
|
||||
std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>> r;
|
||||
for (auto& p : *product_shapes_) {
|
||||
r.push_back({ p.first, occt_join(hlr_shapes.OutLineVCompound(p.second), hlr_shapes.VCompound(p.second)) });
|
||||
}
|
||||
return r;
|
||||
} else {
|
||||
return { {nullptr, occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound()) } };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -240,13 +261,13 @@ namespace {
|
||||
gp_XYZ dxyz, xdir, ydir;
|
||||
|
||||
public:
|
||||
std::list<TopoDS_Shape>::const_iterator item;
|
||||
TopoDS_Shape* item;
|
||||
TopoDS_Face face;
|
||||
bool is_convex;
|
||||
// @note copying the BRepTopAdaptor_FClass2d didn't work so it's a pointer
|
||||
BRepTopAdaptor_FClass2d* fclass;
|
||||
|
||||
face_info(std::list<TopoDS_Shape>::const_iterator it, const TopoDS_Face& fa)
|
||||
face_info(TopoDS_Shape* it, const TopoDS_Face& fa)
|
||||
: item(it)
|
||||
, face(fa)
|
||||
, fclass(nullptr)
|
||||
@@ -334,17 +355,19 @@ namespace {
|
||||
hlr_brep_or_poly_t engine_;
|
||||
bool use_prefiltering_;
|
||||
bool use_hlr_poly_;
|
||||
bool segment_projection_;
|
||||
gp_Ax1 view_direction_;
|
||||
HLRAlgo_Projector projector_;
|
||||
|
||||
std::multimap<double, face_info> large_ortho_faces_;
|
||||
std::list<TopoDS_Shape> items_;
|
||||
std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>> items_;
|
||||
|
||||
public:
|
||||
|
||||
prefiltered_hlr(bool use_prefiltering, bool use_hlr_poly, const gp_Pln& view_direction)
|
||||
prefiltered_hlr(bool use_prefiltering, bool use_hlr_poly, bool segment_projection, const gp_Pln& view_direction)
|
||||
: use_prefiltering_(use_prefiltering)
|
||||
, use_hlr_poly_(use_hlr_poly)
|
||||
, segment_projection_(segment_projection)
|
||||
// @nb negative z in accordance with occt projector convention (and opengl)
|
||||
, view_direction_(view_direction.Axis())
|
||||
{
|
||||
@@ -359,7 +382,7 @@ namespace {
|
||||
projector_ = HLRAlgo_Projector(trsf, false, 1.);
|
||||
}
|
||||
|
||||
bool is_obscured_(std::list<TopoDS_Shape>::const_iterator sit) {
|
||||
bool is_obscured_(TopoDS_Shape* sit) {
|
||||
const TopoDS_Shape& s = *sit;
|
||||
|
||||
double min_d = std::numeric_limits<double>::infinity();
|
||||
@@ -393,9 +416,9 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
|
||||
void add(const TopoDS_Shape& s) {
|
||||
void add(const TopoDS_Shape& s, const IfcUtil::IfcBaseEntity* product) {
|
||||
if (!use_prefiltering_) {
|
||||
items_.insert(items_.end(), s);
|
||||
items_.insert(items_.end(), {product, s});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -434,7 +457,7 @@ namespace {
|
||||
|
||||
Logger::Notice("Included " + std::to_string(n_faces_included) + " faces out of " + std::to_string(n_total) + " after prefiltering");
|
||||
|
||||
auto it = items_.insert(items_.end(), C);
|
||||
auto it = items_.insert(items_.end(), { product, C });
|
||||
|
||||
{
|
||||
TopExp_Explorer exp(C, TopAbs_FACE);
|
||||
@@ -458,7 +481,7 @@ namespace {
|
||||
auto d = -(pnt.XYZ() - view_direction_.Location().XYZ()).Dot(view_direction_.Direction().XYZ());
|
||||
|
||||
if (d > 1.e-5) {
|
||||
large_ortho_faces_.insert({ d, face_info(it, face) });
|
||||
large_ortho_faces_.insert({ d, face_info(&it->second, face) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,15 +490,15 @@ namespace {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items_.insert(items_.end(), s);
|
||||
items_.insert(items_.end(), { product, s });
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape build() {
|
||||
std::list<std::pair<const IfcUtil::IfcBaseEntity*, TopoDS_Shape>> build() {
|
||||
size_t n_included = 0;
|
||||
for (auto it = items_.begin(); it != items_.end(); ++it) {
|
||||
if (!use_prefiltering_ || !is_obscured_(it)) {
|
||||
hlr_writer vis(*it);
|
||||
if (!use_prefiltering_ || !is_obscured_(&it->second)) {
|
||||
hlr_writer vis(it->second);
|
||||
boost::apply_visitor(vis, engine_);
|
||||
n_included++;
|
||||
}
|
||||
@@ -483,7 +506,11 @@ namespace {
|
||||
if (use_prefiltering_) {
|
||||
Logger::Notice("Included " + std::to_string(n_included) + " elements out of " + std::to_string(items_.size()) + " after prefiltering");
|
||||
}
|
||||
|
||||
hlr_calc vis(projector_);
|
||||
if (true) {
|
||||
vis.set_product_shape(&items_);
|
||||
}
|
||||
return boost::apply_visitor(vis, engine_);
|
||||
}
|
||||
};
|
||||
@@ -517,7 +544,7 @@ protected:
|
||||
storey_height_display_types storey_height_display_;
|
||||
bool draw_door_arcs_, is_floor_plan_;
|
||||
bool auto_section_, auto_elevation_;
|
||||
bool use_namespace_, use_hlr_poly_, use_prefiltering_, always_project_, polygonal_;
|
||||
bool use_namespace_, use_hlr_poly_, use_prefiltering_, segment_projection_, always_project_, polygonal_;
|
||||
bool emit_building_storeys_;
|
||||
bool no_css_;
|
||||
bool unify_inputs_;
|
||||
@@ -570,6 +597,7 @@ public:
|
||||
, use_namespace_(false)
|
||||
, use_hlr_poly_(false)
|
||||
, use_prefiltering_(false)
|
||||
, segment_projection_(false)
|
||||
, always_project_(false)
|
||||
, polygonal_(false)
|
||||
, emit_building_storeys_(true)
|
||||
@@ -657,6 +685,14 @@ public:
|
||||
return use_prefiltering_;
|
||||
}
|
||||
|
||||
void setSegmentProjection(bool b) {
|
||||
segment_projection_ = b;
|
||||
}
|
||||
|
||||
bool getSegmentProjection() const {
|
||||
return segment_projection_;
|
||||
}
|
||||
|
||||
void setPolygonal(bool b) {
|
||||
polygonal_ = b;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user