Apply openings in batches sorted by increasing detail

This commit is contained in:
Thomas Krijnen
2018-11-23 11:45:23 +01:00
parent 029859ee84
commit 7c1071f588
+41 -8
View File
@@ -706,10 +706,19 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
return true; return true;
} }
#else #else
namespace {
struct opening_sorter {
bool operator()(const std::pair<double, TopoDS_Shape>& a, const std::pair<double, TopoDS_Shape>& b) const {
return a.first > b.first;
}
};
}
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) { const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
TopTools_ListOfShape opening_shapelist; std::vector< std::pair<double, TopoDS_Shape> > opening_vector;
for (IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++it) { for (IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++it) {
IfcSchema::IfcRelVoidsElement* v = *it; IfcSchema::IfcRelVoidsElement* v = *it;
@@ -748,12 +757,14 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
gp_GTrsf gtrsf = opening_shapes[i].Placement(); gp_GTrsf gtrsf = opening_shapes[i].Placement();
gtrsf.PreMultiply(opening_trsf); gtrsf.PreMultiply(opening_trsf);
TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, gtrsf); TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, gtrsf);
opening_shapelist.Append(opening_shape); opening_vector.push_back(std::make_pair(min_edge_length(opening_shape), opening_shape));
} }
} }
} }
std::sort(opening_vector.begin(), opening_vector.end(), opening_sorter());
// Iterate over the shapes of the IfcProduct // Iterate over the shapes of the IfcProduct
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) { for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
TopoDS_Shape entity_shape_solid; TopoDS_Shape entity_shape_solid;
@@ -764,13 +775,35 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
} }
TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf); TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf);
TopoDS_Shape result; TopoDS_Shape result = entity_shape;
if (boolean_operation(entity_shape, opening_shapelist, BOPAlgo_CUT, result)) {
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(result, &it3->Style())); auto it = opening_vector.begin();
} else { auto jt = it;
Logger::Message(Logger::LOG_ERROR, "Opening subtraction failed:", entity->entity);
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style())); for (;; ++it) {
if (it == opening_vector.end() || jt->first / it->first > 10.) {
TopTools_ListOfShape opening_list;
for (auto kt = jt; kt < it; ++kt) {
opening_list.Append(kt->second);
} }
TopoDS_Shape intermediate_result;
if (boolean_operation(result, opening_list, BOPAlgo_CUT, intermediate_result)) {
result = intermediate_result;
} else {
Logger::Message(Logger::LOG_ERROR, "Opening subtraction failed for " + boost::lexical_cast<std::string>(std::distance(jt, it)) + " openings", entity->entity);
}
jt = it;
}
if (it == opening_vector.end()) {
break;
}
}
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(result, &it3->Style()));
} }
return true; return true;
} }