From 675e1982ee4baf847e73cbc11f0ecdf1f44a54bf Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 1 Jul 2024 20:34:51 +0200 Subject: [PATCH] Move macro logic into template function; mark failures as intended #4915 --- src/ifcgeom/kernels/opencascade/solid.cpp | 2 +- src/ifcgeom/mapping/IfcMappedItem.cpp | 4 +++ src/ifcgeom/mapping/IfcRepresentation.cpp | 40 +++++++---------------- src/ifcgeom/mapping/bind_convert_impl.i | 29 +--------------- src/ifcgeom/mapping/mapping.cpp | 39 ++++++++++++---------- src/ifcgeom/mapping/mapping.h | 40 +++++++++++++++++++++++ 6 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/ifcgeom/kernels/opencascade/solid.cpp b/src/ifcgeom/kernels/opencascade/solid.cpp index cb6c69d9df..cb8112ab25 100644 --- a/src/ifcgeom/kernels/opencascade/solid.cpp +++ b/src/ifcgeom/kernels/opencascade/solid.cpp @@ -101,7 +101,7 @@ bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& return !result.IsNull(); } -bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid , IfcGeom::ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::ConversionResults& results) { TopoDS_Shape shape; if (!convert(solid, shape)) { return false; diff --git a/src/ifcgeom/mapping/IfcMappedItem.cpp b/src/ifcgeom/mapping/IfcMappedItem.cpp index acf97aef3a..8c9bbf631d 100644 --- a/src/ifcgeom/mapping/IfcMappedItem.cpp +++ b/src/ifcgeom/mapping/IfcMappedItem.cpp @@ -33,6 +33,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem* inst) { // @todo allow for multiple levels of matrix? auto shapes = taxonomy::dcast(map(rmap->MappedRepresentation())); if (shapes == nullptr) { + if (failed_on_purpose_.find(rmap->MappedRepresentation()) != failed_on_purpose_.end()) { + // propagate + failed_on_purpose_.insert(inst); + } return shapes; } diff --git a/src/ifcgeom/mapping/IfcRepresentation.cpp b/src/ifcgeom/mapping/IfcRepresentation.cpp index 1015b34db9..e1f51d10d2 100644 --- a/src/ifcgeom/mapping/IfcRepresentation.cpp +++ b/src/ifcgeom/mapping/IfcRepresentation.cpp @@ -26,6 +26,16 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { auto items = map_to_collection(this, inst->Items()); if (!items) { + auto its = inst->Items(); + bool empty_on_purpose = true; + for (auto& itm : *its) { + if (failed_on_purpose_.find(itm) == failed_on_purpose_.end()) { + empty_on_purpose = false; + } + } + if (empty_on_purpose) { + failed_on_purpose_.insert(inst); + } return nullptr; } @@ -53,37 +63,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { }); if (filtered->children.empty()) { + failed_on_purpose_.insert(inst); return nullptr; } return filtered; } - -/* -taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* l, ConversionResults& shapes) { - IfcSchema::IfcRepresentationItem::list::ptr items = inst->Items(); - bool part_succes = false; - if ( items->size() ) { - for ( IfcSchema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++ it ) { - IfcSchema::IfcRepresentationptr representation_item = *it; - if ( shape_type(representation_item) == ST_SHAPELIST ) { - part_succes |= convert_shapes(*it, shapes); - } else { - TopoDS_Shape s; - if (convert_shape(representation_item, s)) { - if (s.ShapeType() == TopAbs_COMPOUND && TopoDS_Iterator(s).More() && TopoDS_Iterator(s).Value().ShapeType() == TopAbs_SOLID) { - TopoDS_Iterator topo_it(s); - for (; topo_it.More(); topo_it.Next()) { - shapes.push_back(ConversionResult(representation_item->data().id(), topo_it.Value(), get_style(representation_item))); - } - } else { - shapes.push_back(ConversionResult(representation_item->data().id(), s, get_style(representation_item))); - } - part_succes |= true; - } - } - } - } - return part_succes; -} -*/ \ No newline at end of file diff --git a/src/ifcgeom/mapping/bind_convert_impl.i b/src/ifcgeom/mapping/bind_convert_impl.i index e22cde0ddf..995e74c0d4 100644 --- a/src/ifcgeom/mapping/bind_convert_impl.i +++ b/src/ifcgeom/mapping/bind_convert_impl.i @@ -3,33 +3,6 @@ #endif #define BIND(T) \ - if (!item && inst->as()) { \ - matched = true; \ - try { \ - item = map_impl(inst->as()); \ - if (item != nullptr) { \ - if (item->instance == nullptr) { \ - item->instance = inst; \ - } \ - try { \ - if (inst->as() && !inst->as() && \ - /* @todo */ \ - (item->kind() == taxonomy::SOLID || item->kind() == taxonomy::SHELL || item->kind() == taxonomy::COLLECTION || item->kind() == taxonomy::EXTRUSION) \ - ) { \ - auto style = find_style(inst->as()); \ - if (style) { \ - taxonomy::cast(item)->surface_style = taxonomy::cast(map(style)); \ - } \ - } \ - } catch (const std::exception& e) { \ - Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst); \ - } \ - } else {\ - Logger::Message(Logger::LOG_ERROR,"Failed to convert:", inst);\ - } \ - } catch (const std::exception& e) { \ - Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst); \ - } \ - } + process_mapping(matched, item, inst); #include "mapping.i" diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp index cff5f6a6ee..2fc0c062f8 100644 --- a/src/ifcgeom/mapping/mapping.cpp +++ b/src/ifcgeom/mapping/mapping.cpp @@ -416,24 +416,6 @@ namespace { return std::make_pair(nullptr, nullptr); } - const IfcSchema::IfcStyledItem* find_style(const IfcSchema::IfcRepresentationItem* representation_item) { - // For certain representation items, most notably boolean operands, - // a style definition might reside on one of its operands. - representation_item = find_item_carrying_style(representation_item); - - if (representation_item->as()) { - return representation_item->as(); - } - - IfcSchema::IfcStyledItem::list::ptr styled_items = representation_item->StyledByItem(); - if (styled_items->size()) { - // StyledByItem is a SET [0:1] OF IfcStyledItem, so we return after the first IfcStyledItem: - return *styled_items->begin(); - } - - return nullptr; - } - bool process_colour(IfcSchema::IfcColourRgb* colour, double* rgb) { if (colour != 0) { rgb[0] = colour->Red(); @@ -464,6 +446,24 @@ namespace { } } +const IfcSchema::IfcStyledItem* mapping::find_style(const IfcSchema::IfcRepresentationItem* representation_item) { + // For certain representation items, most notably boolean operands, + // a style definition might reside on one of its operands. + representation_item = find_item_carrying_style(representation_item); + + if (representation_item->as()) { + return representation_item->as(); + } + + IfcSchema::IfcStyledItem::list::ptr styled_items = representation_item->StyledByItem(); + if (styled_items->size()) { + // StyledByItem is a SET [0:1] OF IfcStyledItem, so we return after the first IfcStyledItem: + return *styled_items->begin(); + } + + return nullptr; +} + taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMaterial* material) { IfcSchema::IfcMaterialDefinitionRepresentation::list::ptr defs = material->HasRepresentation(); for (IfcSchema::IfcMaterialDefinitionRepresentation::list::it jt = defs->begin(); jt != defs->end(); ++jt) { @@ -500,6 +500,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { IfcSchema::IfcSurfaceStyleShading* shading = style_pair.second; if (style == nullptr) { + // @todo we should probably log something that the kind of style, + // such as IfcCurveStyle, in this collections are unsupported. + failed_on_purpose_.insert(inst); return nullptr; } diff --git a/src/ifcgeom/mapping/mapping.h b/src/ifcgeom/mapping/mapping.h index 798d173017..39bc014f3b 100644 --- a/src/ifcgeom/mapping/mapping.h +++ b/src/ifcgeom/mapping/mapping.h @@ -31,6 +31,46 @@ namespace geometry { void initialize_units_(); void addRepresentationsFromContextIds(IfcSchema::IfcRepresentation::list::ptr&); void addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation::list::ptr&); + + // Set of instances to mark failures that are intended, such as representations not + // resulting in any items due to dimensionality filters. + std::set failed_on_purpose_; + + template + void process_mapping(bool& matched, taxonomy::ptr& item, IfcUtil::IfcBaseInterface const * inst) { + if (!item && inst->as()) { + matched = true; + try { + item = map_impl(inst->as()); + if (item != nullptr) { + if (item->instance == nullptr) { + item->instance = inst; + } + try { + if (inst->as() && !inst->as() && + /* @todo */ + (item->kind() == taxonomy::SOLID || item->kind() == taxonomy::SHELL || item->kind() == taxonomy::COLLECTION || item->kind() == taxonomy::EXTRUSION) + ) { + auto style = find_style(inst->as()); + if (style) { + auto mstyle = map(style); + if (mstyle) { + taxonomy::cast(item)->surface_style = taxonomy::cast(mstyle); + } + } + } + } catch (const std::exception& e) { + Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst); + } + } else if (failed_on_purpose_.find(inst) == failed_on_purpose_.end()) { + Logger::Message(Logger::LOG_ERROR, "Failed to convert:", inst); + } + } catch (const std::exception& e) { + Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst); + } + } + } + const IfcSchema::IfcStyledItem* find_style(const IfcSchema::IfcRepresentationItem*); public: POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) { initialize_units_();