SVG prefiltering elements based on large faces

This commit is contained in:
Thomas Krijnen
2023-06-29 13:08:22 +02:00
parent 212b707464
commit 09d7cd97c8
3 changed files with 376 additions and 122 deletions
+11 -119
View File
@@ -725,31 +725,6 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
}
}
namespace {
class hlr_writer {
const TopoDS_Shape& shape_;
public:
typedef void result_type;
hlr_writer(const TopoDS_Shape& shape) : shape_(shape)
{}
void operator()(boost::blank&) const {
throw std::runtime_error("");
}
void operator()(Handle(HLRBRep_Algo)& algo) const {
algo->Add(shape_);
}
void operator()(Handle(HLRBRep_PolyAlgo)& algo) const {
BRepMesh_IncrementalMesh(shape_, 0.10);
algo->Load(shape_);
}
};
}
namespace {
int infront_or_behind(const gp_Pln& pln, const gp_Pnt& p) {
auto d = (p.XYZ() - pln.Location().XYZ()).Dot(pln.Axis().Direction().XYZ());
@@ -1171,22 +1146,16 @@ void SvgSerializer::write(const geometry_data& data) {
if (is_floor_plan_) {
if (storey) {
if (storey_hlr.find(storey) == storey_hlr.end()) {
if (use_hlr_poly_) {
storey_hlr[storey] = new HLRBRep_PolyAlgo;
} else {
storey_hlr[storey] = new HLRBRep_Algo;
}
auto it = storey_hlr.find(storey);
if (it == storey_hlr.end()) {
it = storey_hlr.insert({ storey, hlr_t(use_prefiltering_, use_hlr_poly_, projection_plane) }).first;
}
hlr_writer vis(*compound_to_hlr);
boost::apply_visitor(vis, storey_hlr[storey]);
it->second.add(*compound_to_hlr);
} else {
Logger::Warning("Unable to invoke HLR due to absence of storey containment", data.product);
}
}
else {
hlr_writer vis(*compound_to_hlr);
boost::apply_visitor(vis, hlr);
} else if (hlr) {
hlr->add(*compound_to_hlr);
}
}
}
@@ -1721,81 +1690,8 @@ std::array<std::array<double, 3>, 3> SvgSerializer::resize() {
return m;
}
namespace {
template <typename T>
TopoDS_Compound occt_join(T t) {
BRep_Builder B;
TopoDS_Compound C;
B.MakeCompound(C);
if (!t.IsNull()) {
TopoDS_Iterator it(t);
for (; it.More(); it.Next()) {
B.Add(C, it.Value());
}
}
return C;
}
template <typename T, typename... Ts>
TopoDS_Compound occt_join(T t, Ts... tss) {
BRep_Builder B;
TopoDS_Compound C;
B.MakeCompound(C);
if (!t.IsNull()) {
TopoDS_Iterator it(t);
for (; it.More(); it.Next()) {
B.Add(C, it.Value());
}
}
auto rest = occt_join(tss...);
if (!rest.IsNull()) {
TopoDS_Iterator it(rest);
for (; it.More(); it.Next()) {
B.Add(C, it.Value());
}
}
return C;
}
class hlr_calc {
private:
const HLRAlgo_Projector& projector_;
public:
typedef TopoDS_Shape result_type;
hlr_calc(const HLRAlgo_Projector& projector) : projector_(projector)
{}
TopoDS_Shape operator()(boost::blank&) const {
throw std::runtime_error("");
}
TopoDS_Shape operator()(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());
}
TopoDS_Shape operator()(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());
}
};
}
void SvgSerializer::draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name) {
gp_Trsf trsf;
trsf.SetTransformation(pln.Position());
HLRAlgo_Projector projector(trsf, false, 1.);
hlr_calc vis(projector);
TopoDS_Shape hlr_compound_unmirrored = boost::apply_visitor(vis, drawing_name.first ? this->storey_hlr[drawing_name.first] : hlr);
TopoDS_Shape hlr_compound_unmirrored = (drawing_name.first ? this->storey_hlr.find(drawing_name.first)->second : *hlr).build();
if (!hlr_compound_unmirrored.IsNull()) {
// Compound 3D curves for mirroring to work
@@ -2086,12 +1982,9 @@ void SvgSerializer::finalize() {
pln = &section.plane;
}
if (use_hlr) {
if (use_hlr_poly_) {
hlr = new HLRBRep_PolyAlgo;
} else {
hlr = new HLRBRep_Algo;
}
// @todo do we have always have pln here?
if (use_hlr && pln) {
hlr = new hlr_t(use_prefiltering_, use_hlr_poly_, *pln);
}
section_data_ = std::vector<section_data>{ sd };
@@ -2165,8 +2058,7 @@ void SvgSerializer::finalize() {
resetScale();
// @todo does this probably call Nullify()
hlr = boost::blank();
delete hlr;
}
}