mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 13:43:40 +00:00
Let context_ids coexist with curves and solid settings.
This commit is contained in:
committed by
Thomas Krijnen
parent
514c5eb790
commit
c57daf8aed
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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:";
|
||||||
|
|||||||
Reference in New Issue
Block a user