Let context_ids coexist with curves and solid settings.

This commit is contained in:
Dion Moult
2021-09-22 18:58:32 +10:00
committed by Thomas Krijnen
parent 514c5eb790
commit c57daf8aed
3 changed files with 127 additions and 111 deletions
+90 -80
View File
@@ -253,98 +253,113 @@ namespace IfcGeom {
Logger::Error(e); Logger::Error(e);
} }
std::set<std::string> allowed_context_types; representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
allowed_context_types.insert("model"); ok_mapped_representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
allowed_context_types.insert("plan");
allowed_context_types.insert("notdefined");
std::set<std::string> context_types;
if (!settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
// Really this should only be 'Model', as per
// the standard 'Design' is deprecated. So,
// just for backwards compatibility:
context_types.insert("model");
context_types.insert("design");
// Some earlier (?) versions DDS-CAD output their own ContextTypes
context_types.insert("model view");
context_types.insert("detail view");
}
if (settings.get(IteratorSettings::INCLUDE_CURVES)) {
context_types.insert("plan");
}
double lowest_precision_encountered = std::numeric_limits<double>::infinity(); double lowest_precision_encountered = std::numeric_limits<double>::infinity();
bool any_precision_encountered = false; bool any_precision_encountered = false;
representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list); if (settings.context_ids().size() != 0) {
ok_mapped_representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list); for (auto context_id : settings.context_ids()) {
IfcSchema::IfcGeometricRepresentationContext* context = ifc_file->instance_by_id(context_id)->as<IfcSchema::IfcGeometricRepresentationContext>();
representations->push(context->RepresentationsInContext());
IfcSchema::IfcGeometricRepresentationContext::list::it it; try {
IfcSchema::IfcGeometricRepresentationSubContext::list::it jt; if (context->Precision() && *context->Precision() < lowest_precision_encountered) {
IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts = lowest_precision_encountered = *context->Precision();
ifc_file->instances_by_type<IfcSchema::IfcGeometricRepresentationContext>(); any_precision_encountered = true;
IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list);
for (it = contexts->begin(); it != contexts->end(); ++it) {
IfcSchema::IfcGeometricRepresentationContext* context = *it;
if (context->declaration().is(IfcSchema::IfcGeometricRepresentationSubContext::Class())) {
// Continue, as the list of subcontexts will be considered
// by the parent's context inverse attributes.
continue;
}
try {
if (context->ContextType()) {
std::string context_type = *context->ContextType();
boost::to_lower(context_type);
if (allowed_context_types.find(context_type) == allowed_context_types.end()) {
Logger::Warning(std::string("ContextType '") + *context->ContextType() + "' not allowed:", context);
} }
if (context_types.find(context_type) != context_types.end()) { } catch (const std::exception& e) {
Logger::Error(e);
}
}
} else {
std::set<std::string> allowed_context_types;
allowed_context_types.insert("model");
allowed_context_types.insert("plan");
allowed_context_types.insert("notdefined");
std::set<std::string> context_types;
if (!settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
// Really this should only be 'Model', as per
// the standard 'Design' is deprecated. So,
// just for backwards compatibility:
context_types.insert("model");
context_types.insert("design");
// Some earlier (?) versions DDS-CAD output their own ContextTypes
context_types.insert("model view");
context_types.insert("detail view");
}
if (settings.get(IteratorSettings::INCLUDE_CURVES)) {
context_types.insert("plan");
}
IfcSchema::IfcGeometricRepresentationContext::list::it it;
IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts =
ifc_file->instances_by_type<IfcSchema::IfcGeometricRepresentationContext>();
IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list);
for (it = contexts->begin(); it != contexts->end(); ++it) {
IfcSchema::IfcGeometricRepresentationContext* context = *it;
if (context->declaration().is(IfcSchema::IfcGeometricRepresentationSubContext::Class())) {
// Continue, as the list of subcontexts will be considered
// by the parent's context inverse attributes.
continue;
}
try {
if (context->ContextType()) {
std::string context_type = *context->ContextType();
boost::to_lower(context_type);
if (allowed_context_types.find(context_type) == allowed_context_types.end()) {
Logger::Warning(std::string("ContextType '") + *context->ContextType() + "' not allowed:", context);
}
if (context_types.find(context_type) != context_types.end()) {
filtered_contexts->push(context);
}
}
} catch (const std::exception& e) {
Logger::Error(e);
}
}
// In case no contexts are identified based on their ContextType, all contexts are
// considered. Note that sub contexts are excluded as they are considered later on.
if (filtered_contexts->size() == 0) {
for (it = contexts->begin(); it != contexts->end(); ++it) {
IfcSchema::IfcGeometricRepresentationContext* context = *it;
if (!context->declaration().is(IfcSchema::IfcGeometricRepresentationSubContext::Class())) {
filtered_contexts->push(context); filtered_contexts->push(context);
} }
} }
} catch (const std::exception& e) {
Logger::Error(e);
} }
}
// In case no contexts are identified based on their ContextType, all contexts are for (it = filtered_contexts->begin(); it != filtered_contexts->end(); ++it) {
// considered. Note that sub contexts are excluded as they are considered later on.
if (filtered_contexts->size() == 0) {
for (it = contexts->begin(); it != contexts->end(); ++it) {
IfcSchema::IfcGeometricRepresentationContext* context = *it; IfcSchema::IfcGeometricRepresentationContext* context = *it;
if (!context->declaration().is(IfcSchema::IfcGeometricRepresentationSubContext::Class())) {
filtered_contexts->push(context); representations->push(context->RepresentationsInContext());
try {
if (context->Precision() && *context->Precision() < lowest_precision_encountered) {
lowest_precision_encountered = *context->Precision();
any_precision_encountered = true;
}
} catch (const std::exception& e) {
Logger::Error(e);
} }
}
}
for (it = filtered_contexts->begin(); it != filtered_contexts->end(); ++it) { IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
IfcSchema::IfcGeometricRepresentationContext* context = *it; for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
representations->push((*jt)->RepresentationsInContext());
representations->push(context->RepresentationsInContext());
try {
if (context->Precision() && *context->Precision() < lowest_precision_encountered) {
lowest_precision_encountered = *context->Precision();
any_precision_encountered = true;
} }
} catch (const std::exception& e) { // There is no need for full recursion as the following is governed by the schema:
Logger::Error(e); // WR31: The parent context shall not be another geometric representation sub context.
} }
IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts(); if (representations->size() == 0) {
for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) { Logger::Warning("No representations encountered in relevant contexts, using all");
representations->push((*jt)->RepresentationsInContext()); representations = ifc_file->instances_by_type<IfcSchema::IfcRepresentation>();
} }
// There is no need for full recursion as the following is governed by the schema:
// WR31: The parent context shall not be another geometric representation sub context.
}
for (auto context_id : settings.context_ids()) {
IfcSchema::IfcGeometricRepresentationContext* context = ifc_file->instance_by_id(context_id)->as<IfcSchema::IfcGeometricRepresentationContext>();
representations->push(context->RepresentationsInContext());
} }
if (any_precision_encountered) { if (any_precision_encountered) {
@@ -362,11 +377,6 @@ namespace IfcGeom {
kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-5); kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-5);
} }
if (representations->size() == 0) {
Logger::Warning("No representations encountered in relevant contexts, using all");
representations = ifc_file->instances_by_type<IfcSchema::IfcRepresentation>();
}
if (representations->size() == 0) { if (representations->size() == 0) {
Logger::Warning("No representations encountered, aborting"); Logger::Warning("No representations encountered, aborting");
initialization_outcome_ = false; initialization_outcome_ = false;
+4 -2
View File
@@ -887,6 +887,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresenta
// @nb the selection is partly duplicated from convert_curves() but it's needed as a // @nb the selection is partly duplicated from convert_curves() but it's needed as a
// geometric set by it's static class definition does not inform us of the type of elements. // geometric set by it's static class definition does not inform us of the type of elements.
// @todo handle this better so that this doesn't log an error. // @todo handle this better so that this doesn't log an error.
const bool include_curves = getValue(GV_DIMENSIONALITY) != +1;
const bool include_solids_and_surfaces = getValue(GV_DIMENSIONALITY) != -1;
aggregate_of_instance::ptr elements = l->Elements(); aggregate_of_instance::ptr elements = l->Elements();
if ( !elements->size() ) return false; if ( !elements->size() ) return false;
@@ -900,11 +902,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresenta
if (!(convert_shapes(element, items) && flatten_shape_list(items, s, false))) { if (!(convert_shapes(element, items) && flatten_shape_list(items, s, false))) {
continue; continue;
} }
} else if (shape_type(element) == ST_SHAPE) { } else if (shape_type(element) == ST_SHAPE && include_solids_and_surfaces) {
if (!convert_shape(element, s)) { if (!convert_shape(element, s)) {
continue; continue;
} }
} else if (shape_type(element) == ST_WIRE) { } else if (shape_type(element) == ST_WIRE && include_curves) {
TopoDS_Wire w; TopoDS_Wire w;
if (!convert_wire(element, w)) { if (!convert_wire(element, w)) {
continue; continue;
+9 -5
View File
@@ -54,30 +54,34 @@ bool IfcGeom::Kernel::convert_shape(const IfcBaseInterface* l, TopoDS_Shape& r)
const unsigned int id = l->data().id(); const unsigned int id = l->data().id();
bool success = false; bool success = false;
bool processed = false; bool processed = false;
bool ignored = false;
#ifndef NO_CACHE #ifndef NO_CACHE
std::map<int,TopoDS_Shape>::const_iterator it = cache.Shape.find(id); std::map<int,TopoDS_Shape>::const_iterator it = cache.Shape.find(id);
if ( it != cache.Shape.end() ) { r = it->second; return true; } if ( it != cache.Shape.end() ) { r = it->second; return true; }
#endif #endif
const bool include_curves = getValue(GV_DIMENSIONALITY) != +1;
const bool include_solids_and_surfaces = getValue(GV_DIMENSIONALITY) != -1;
IfcGeom::ShapeType st = shape_type(l); IfcGeom::ShapeType st = shape_type(l);
ignored = (!include_solids_and_surfaces && (st == ST_SHAPE || st == ST_FACE)) || (!include_curves && (st == ST_WIRE || st == ST_CURVE));
if (st == ST_SHAPELIST) { if (st == ST_SHAPELIST) {
processed = true; processed = true;
IfcRepresentationShapeItems items; IfcRepresentationShapeItems items;
success = convert_shapes(l, items) && flatten_shape_list(items, r, false); success = convert_shapes(l, items) && flatten_shape_list(items, r, false);
} else if (st == ST_SHAPE) { } else if (st == ST_SHAPE && include_solids_and_surfaces) {
#include "IfcRegisterConvertShape.h" #include "IfcRegisterConvertShape.h"
} else if (st == ST_FACE) { } else if (st == ST_FACE && include_solids_and_surfaces) {
processed = true; processed = true;
success = convert_face(l, r); success = convert_face(l, r);
} else if (st == ST_WIRE) { } else if (st == ST_WIRE && include_curves) {
processed = true; processed = true;
TopoDS_Wire w; TopoDS_Wire w;
success = convert_wire(l, w); success = convert_wire(l, w);
if (success) { if (success) {
r = w; r = w;
} }
} else if (st == ST_CURVE) { } else if (st == ST_CURVE && include_curves) {
processed = true; processed = true;
Handle(Geom_Curve) crv; Handle(Geom_Curve) crv;
TopoDS_Wire w; TopoDS_Wire w;
@@ -98,7 +102,7 @@ bool IfcGeom::Kernel::convert_shape(const IfcBaseInterface* l, TopoDS_Shape& r)
BRepCheck_Analyzer ana(r); BRepCheck_Analyzer ana(r);
Logger::Notice("Valid: " + std::to_string(ana.IsValid()), l); Logger::Notice("Valid: " + std::to_string(ana.IsValid()), l);
} }
} else { } else if (!ignored) {
const char* const msg = processed const char* const msg = processed
? "Failed to convert:" ? "Failed to convert:"
: "No operation defined for:"; : "No operation defined for:";