diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 10c7b93912..344f0ac5f1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -562,10 +562,10 @@ file(GLOB IFCGEOM_CPP_FILES ../src/ifcgeom/*.cpp) set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES}) foreach(schema 2x3 4) -add_library(IfcGeom_ifc${schema} ${IFCGEOM_FILES}) -set_target_properties(IfcGeom_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}") -TARGET_LINK_LIBRARIES(IfcGeom_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES}) -list(APPEND IfcGeom_libraries IfcGeom_ifc${schema}) +add_library(IfcGeom_occt_ifc${schema} ${IFCGEOM_FILES}) +set_target_properties(IfcGeom_occt_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}") +TARGET_LINK_LIBRARIES(IfcGeom_occt_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES}) +list(APPEND IfcGeom_libraries IfcGeom_occt_ifc${schema}) endforeach() ### CGAL @@ -576,10 +576,10 @@ file(GLOB IFCGEOM_CPP_FILES ../src/ifcgeom/kernels/cgal/*.cpp) set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES}) foreach(schema 2x3 4) -add_library(IfcGeom_CGAL_ifc${schema} ${IFCGEOM_FILES}) -set_target_properties(IfcGeom_CGAL_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}") -TARGET_LINK_LIBRARIES(IfcGeom_CGAL_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES}) -list(APPEND IfcGeom_CGAL_libraries IfcGeom_CGAL_ifc${schema}) +add_library(IfcGeom_cgal_ifc${schema} ${IFCGEOM_FILES}) +set_target_properties(IfcGeom_cgal_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}") +TARGET_LINK_LIBRARIES(IfcGeom_cgal_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES}) +list(APPEND IfcGeom_libraries IfcGeom_cgal_ifc${schema}) endforeach() # IfcGeom, schema and kernel agnostic @@ -695,7 +695,7 @@ INSTALL(FILES ${SCHEMA_AGNOSTIC_H_FILES} DESTINATION ${INCLUDEDIR}/ifcgeom_schema_agnostic ) -INSTALL(TARGETS IfcGeom_ifc2x3 IfcGeom_ifc4 IfcGeom +INSTALL(TARGETS IfcGeom ${IfcGeom_libraries} ARCHIVE DESTINATION ${LIBDIR} LIBRARY DESTINATION ${LIBDIR} RUNTIME DESTINATION ${BINDIR} diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index f4466798bd..ab564c11f2 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -333,8 +333,6 @@ public: bool is_identity_transform(IfcUtil::IfcBaseClass*); - IfcSchema::IfcRelVoidsElement::list::ptr find_openings(IfcSchema::IfcProduct* product); - IfcSchema::IfcRepresentation* find_representation(const IfcSchema::IfcProduct*, const std::string&); std::pair initializeUnits(IfcSchema::IfcUnitAssignment*); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 2dd9f4129b..efe0339cbe 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -216,10 +216,10 @@ namespace { }; } -void MAKE_INIT_FN(KernelImplementation_)(IfcGeom::impl::KernelFactoryImplementation* mapping) { +void MAKE_INIT_FN(KernelImplementation_opencascade_)(IfcGeom::impl::KernelFactoryImplementation* mapping) { static const std::string schema_name = STRINGIFY(IfcSchema); MAKE_TYPE_NAME(factory_t) factory; - mapping->bind(schema_name, factory); + mapping->bind(schema_name, "opencascade", factory); } #define Kernel MAKE_TYPE_NAME(Kernel) @@ -1407,35 +1407,6 @@ void IfcGeom::Kernel::sequence_of_point_to_wire(const TColgp_SequenceOfPnt& p, T w = builder.Wire(); } -IfcSchema::IfcRelVoidsElement::list::ptr IfcGeom::Kernel::find_openings(IfcSchema::IfcProduct* product) { - - IfcSchema::IfcRelVoidsElement::list::ptr openings(new IfcSchema::IfcRelVoidsElement::list); - if ( product->declaration().is(IfcSchema::IfcElement::Class()) && !product->declaration().is(IfcSchema::IfcOpeningElement::Class()) ) { - IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product; - openings = element->HasOpenings(); - } - - // Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements? - IfcSchema::IfcObjectDefinition* obdef = product->as(); - for (;;) { -#ifdef USE_IFC4 - IfcSchema::IfcRelAggregates::list::ptr decomposes = obdef->Decomposes(); -#else - IfcSchema::IfcRelDecomposes::list::ptr decomposes = obdef->Decomposes(); -#endif - if (decomposes->size() != 1) break; - IfcSchema::IfcObjectDefinition* rel_obdef = (*decomposes->begin())->RelatingObject(); - if ( rel_obdef->declaration().is(IfcSchema::IfcElement::Class()) && !rel_obdef->declaration().is(IfcSchema::IfcOpeningElement::Class()) ) { - IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)rel_obdef; - openings->push(element->HasOpenings()); - } - - obdef = rel_obdef; - } - - return openings; -} - const IfcSchema::IfcMaterial* IfcGeom::Kernel::get_single_material_association(const IfcSchema::IfcProduct* product) { IfcSchema::IfcMaterial* single_material = 0; IfcSchema::IfcRelAssociatesMaterial::list::ptr associated_materials = product->HasAssociations()->as(); @@ -1569,7 +1540,7 @@ IfcGeom::NativeElement* IfcGeom::Kernel::create_brep_for_representation_a // Does the IfcElement have any IfcOpenings? // Note that openings for IfcOpeningElements are not processed - IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product); + IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product)->as(); const std::string product_type = product->declaration().name(); ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type); diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index 1a808195cb..fcb766ca11 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -1,6 +1,8 @@ #include "CgalKernel.h" #include "CgalConversionResult.h" +#define CgalKernel MAKE_TYPE_NAME(CgalKernel) + bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRepresentation* l, ConversionResults& shapes) { IfcSchema::IfcRepresentationItem::list::ptr items = l->Items(); bool part_succes = false; @@ -12,7 +14,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRepresentation* l, Convers } else { cgal_shape_t s; if (convert_shape(representation_item, s)) { - shapes.push_back(ConversionResult(new CgalShape(s), get_style(representation_item))); + shapes.push_back(ConversionResult(representation_item->data().id(), new CgalShape(s))); part_succes |= true; } } @@ -21,6 +23,6 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRepresentation* l, Convers return part_succes; } -bool IfcGeom::CgalKernel::convert(const Ifc2x3::IfcExtrudedAreaSolid*, cgal_shape_t&) { +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid*, cgal_shape_t&) { throw std::runtime_error("Not implemented IfcExtrudedAreaSolid"); } diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp index e2da8ecd97..3b9ee4d2d3 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp @@ -1,6 +1,15 @@ #include "CgalKernel.h" #include "CgalConversionResult.h" -void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const { +template +void triangulate_helper(const cgal_shape_t, const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) { throw std::runtime_error("Not implemented Triangulate()"); } + +void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const { + triangulate_helper(shape_, settings, place, t, surface_style_id); +} + +void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const { + triangulate_helper(shape_, settings, place, t, surface_style_id); +} diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.h b/src/ifcgeom/kernels/cgal/CgalConversionResult.h index 3fb4bb7e67..3b076b487f 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.h +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.h @@ -20,7 +20,7 @@ #ifndef CGALCONVERSIONRESULT_H #define CGALCONVERSIONRESULT_H -#include "../../../ifcgeom/ConversionResult.h" +#include "../../../ifcgeom_schema_agnostic/ConversionResult.h" namespace IfcGeom { @@ -37,17 +37,28 @@ namespace IfcGeom { // Get cell from placement as 4x3 matrix as implemented in OCCT. We'll have to check exact semantics. throw std::runtime_error("Not implemented"); } + virtual void Multiply(const ConversionResultPlacement* other) { // Multiply matrix as implemented in OCCT. We'll have to check exact semantics. throw std::runtime_error("Not implemented"); } + virtual void PreMultiply(const ConversionResultPlacement* other) { // PreMultiply matrix as implemented in OCCT. We'll have to check exact semantics. throw std::runtime_error("Not implemented"); } + virtual ConversionResultPlacement* clone() const { return new CgalPlacement(trsf_); } + + virtual ConversionResultPlacement* inverted() const { + throw std::runtime_error("Not implemented"); + } + + virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement*) const { + throw std::runtime_error("Not implemented"); + } private: cgal_placement_t trsf_; }; @@ -61,13 +72,21 @@ namespace IfcGeom { const cgal_shape_t& shape() const { return shape_; } operator const cgal_shape_t& () { return shape_; } + virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation * t, int surface_style_id) const; + virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const; + virtual void Serialize(std::string&) const { throw std::runtime_error("Not implemented"); } + virtual ConversionResultShape* clone() const { return new CgalShape(shape_); } + + virtual int surface_genus() const { + throw std::runtime_error("Not implemented"); + } private: cgal_shape_t shape_; }; diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp b/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp index f3002292d4..6a11d8fa46 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp @@ -23,22 +23,22 @@ #include "CgalKernel.h" #include "CgalConversionResult.h" -using namespace IfcSchema; -using namespace IfcUtil; +#define CgalKernel MAKE_TYPE_NAME(CgalKernel) +using namespace IfcUtil; bool IfcGeom::CgalKernel::convert_shapes(const IfcBaseClass* l, ConversionResults& r) { if (shape_type(l) != ST_SHAPELIST) { cgal_shape_t shp; if (convert_shape(l, shp)) { - r.push_back(IfcGeom::ConversionResult(new CgalShape(shp), get_style(l->as()))); + r.push_back(IfcGeom::ConversionResult(l->data().id(), new CgalShape(shp))); return true; } return false; } #include "CgalEntityMappingShapes.h" - Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); + Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); return false; } @@ -48,7 +48,7 @@ IfcGeom::ShapeType IfcGeom::CgalKernel::shape_type(const IfcBaseClass* l) { } bool IfcGeom::CgalKernel::convert_shape(const IfcBaseClass* l, cgal_shape_t& r) { - const unsigned int id = l->entity->id(); + const unsigned int id = l->data().id(); bool success = false; bool processed = false; bool ignored = false; @@ -76,25 +76,25 @@ bool IfcGeom::CgalKernel::convert_shape(const IfcBaseClass* l, cgal_shape_t& r) const char* const msg = processed ? "Failed to convert:" : "No operation defined for:"; - Logger::Message(Logger::LOG_ERROR, msg, l->entity); + Logger::Message(Logger::LOG_ERROR, msg, l); } return success; } bool IfcGeom::CgalKernel::convert_wire(const IfcBaseClass* l, cgal_wire_t& r) { #include "CgalEntityMappingWire.h" - Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); + Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); return false; } bool IfcGeom::CgalKernel::convert_face(const IfcBaseClass* l, cgal_face_t& r) { #include "CgalEntityMappingFace.h" - Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); + Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); return false; } bool IfcGeom::CgalKernel::convert_curve(const IfcBaseClass* l, cgal_curve_t& r) { #include "CgalEntityMappingCurve.h" - Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); + Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); return false; } diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index eb2ecedf38..3908ded811 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -25,7 +25,6 @@ * * ********************************************************************************/ -#include "../../../ifcparse/IfcUtil.h" #include "../../../ifcparse/IfcParse.h" SHAPES(IfcRepresentation); diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingCurve.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingCurve.h index ac6736626a..5bebf39992 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingCurve.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingCurve.h @@ -1,6 +1,6 @@ #include "CgalEntityMappingUndefine.h" #define CURVE(T) \ - if ( l->is(T::Class()) ) return convert((T*)l,r); + if (l->declaration().is(IfcSchema::T::Class())) return convert((IfcSchema::T*)l,r); #include "CgalEntityMappingDefine.h" #include "CgalEntityMapping.h" \ No newline at end of file diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingFace.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingFace.h index ccebad4e33..65087a1a5f 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingFace.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingFace.h @@ -1,6 +1,6 @@ #include "CgalEntityMappingUndefine.h" #define FACE(T) \ - if ( l->is(T::Class()) ) return convert((T*)l,r); + if (l->declaration().is(IfcSchema::T::Class())) return convert((IfcSchema::T*)l,r); #include "CgalEntityMappingDefine.h" #include "CgalEntityMapping.h" \ No newline at end of file diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingShape.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingShape.h index 736df52c62..14dc9d51e1 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingShape.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingShape.h @@ -1,17 +1,17 @@ #include "CgalEntityMappingUndefine.h" #define SHAPE(T) \ - if ( !processed && l->is(T::Class()) ) { \ + if ( !processed && l->declaration().is(IfcSchema::T::Class()) ) { \ processed = true; \ try { \ - if ( convert((T*)l,r) ) { \ + if (convert((IfcSchema::T*)l, r) ) { \ success = true; \ } \ } catch (const std::exception& e) { \ - Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", l->entity); \ + Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", l); \ return false; \ } \ if (!success) { \ - Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \ + Logger::Message(Logger::LOG_ERROR,"Failed to convert:", l); \ return false; \ } \ } diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingShapeType.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingShapeType.h index 21e6a0cd31..ec25d81d25 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingShapeType.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingShapeType.h @@ -1,14 +1,14 @@ #include "CgalEntityMappingUndefine.h" #define SHAPES(T) \ - if ( l->is(T::Class()) ) return ST_SHAPELIST; + if (l->declaration().is(IfcSchema::T::Class())) return ST_SHAPELIST; #define SHAPE(T) \ - if ( l->is(T::Class()) ) return ST_SHAPE; + if (l->declaration().is(IfcSchema::T::Class())) return ST_SHAPE; #define WIRE(T) \ - if ( l->is(T::Class()) ) return ST_WIRE; + if (l->declaration().is(IfcSchema::T::Class())) return ST_WIRE; #define FACE(T) \ - if ( l->is(T::Class()) ) return ST_FACE; + if (l->declaration().is(IfcSchema::T::Class())) return ST_FACE; #define CURVE(T) \ - if ( l->is(T::Class()) ) return ST_CURVE; + if (l->declaration().is(IfcSchema::T::Class())) return ST_CURVE; #include "CgalEntityMappingDefine.h" #include "CgalEntityMapping.h" diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingShapes.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingShapes.h index 778a5399ac..700b4a08a2 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingShapes.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingShapes.h @@ -1,10 +1,10 @@ #include "CgalEntityMappingUndefine.h" #define SHAPES(T) \ - if ( l->is(T::Class()) ) { \ + if (l->declaration().is(IfcSchema::T::Class())) { \ try { \ - return convert((T*)l,r); \ + return convert((IfcSchema::T*)l,r); \ } catch (const std::exception& e) { \ - Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", l->entity); \ + Logger::Message(Logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", l); \ } \ return false; \ } diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMappingWire.h b/src/ifcgeom/kernels/cgal/CgalEntityMappingWire.h index ed5461ba75..459ad8267c 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMappingWire.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMappingWire.h @@ -1,6 +1,6 @@ #include "CgalEntityMappingUndefine.h" #define WIRE(T) \ - if ( l->is(T::Class()) ) return convert((T*)l,r); + if (l->declaration().is(IfcSchema::T::Class())) return convert((IfcSchema::T*)l,r); #include "CgalEntityMappingDefine.h" #include "CgalEntityMapping.h" diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index f4f830cbee..42e2a36010 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -23,6 +23,23 @@ #include "CgalKernel.h" #include "CgalConversionResult.h" +namespace { + struct MAKE_TYPE_NAME(factory_t) { + IfcGeom::Kernel* operator()(IfcParse::IfcFile* file) const { + IfcGeom::MAKE_TYPE_NAME(Kernel)* k = new IfcGeom::MAKE_TYPE_NAME(Kernel); + return k; + } + }; +} + +void MAKE_INIT_FN(KernelImplementation_cgal_)(IfcGeom::impl::KernelFactoryImplementation* mapping) { + static const std::string schema_name = STRINGIFY(IfcSchema); + MAKE_TYPE_NAME(factory_t) factory; + mapping->bind(schema_name, "cgal", factory); +} + +#define CgalKernel MAKE_TYPE_NAME(CgalKernel) + bool IfcGeom::CgalKernel::is_identity_transform(IfcUtil::IfcBaseClass* l) { Logger::Message(Logger::LOG_ERROR, "Not implemented is_identity_transform()"); return false; @@ -70,7 +87,7 @@ bool IfcGeom::CgalKernel::is_identity_transform(IfcUtil::IfcBaseClass* l) { IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_representation_and_product( const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product) { - IfcGeom::Representation::Native* shape; + IfcGeom::Representation::BRep* shape; IfcGeom::ConversionResults shapes, shapes2; if (!convert_shapes(representation, shapes)) { @@ -83,11 +100,13 @@ IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_representat int parent_id = -1; try { - IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product); - if (parent_object) { - parent_id = parent_object->entity->id(); + IfcUtil::IfcBaseEntity* parent_object = get_decomposing_entity(product); + if (parent_object && parent_object->as()) { + parent_id = parent_object->data().id(); } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } const std::string name = product->hasName() ? product->Name() : ""; const std::string guid = product->GlobalId(); @@ -97,18 +116,21 @@ IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_representat // convert(product->ObjectPlacement(), trsf); } catch (...) {} + std::stringstream representation_id_builder; + representation_id_builder << representation->data().id(); + // Does the IfcElement have any IfcOpenings? // Note that openings for IfcOpeningElements are not processed - IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product); + IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product)->as(); - const std::string product_type = IfcSchema::Type::ToString(product->type()); + const std::string product_type = product->declaration().name(); ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type); if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) { Logger::Message(Logger::LOG_ERROR, "Not implemented opening subtractions"); } - shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes); + shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes); std::string context_string = ""; if (representation->hasRepresentationIdentifier()) { @@ -118,14 +140,15 @@ IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_representat } return new NativeElement( - product->entity->id(), + product->data().id(), parent_id, name, product_type, guid, context_string, new CgalPlacement(trsf), - boost::shared_ptr(shape) + boost::shared_ptr(shape), + product ); } @@ -135,11 +158,13 @@ IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_processed_r { int parent_id = -1; try { - IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product); - if (parent_object) { - parent_id = parent_object->entity->id(); + IfcUtil::IfcBaseEntity* parent_object = get_decomposing_entity(product); + if (parent_object && parent_object->as()) { + parent_id = parent_object->data().id(); } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } const std::string name = product->hasName() ? product->Name() : ""; const std::string guid = product->GlobalId(); @@ -156,16 +181,17 @@ IfcGeom::NativeElement* IfcGeom::CgalKernel::create_brep_for_processed_r context_string = representation->ContextOfItems()->ContextType(); } - const std::string product_type = IfcSchema::Type::ToString(product->type()); + const std::string product_type = product->declaration().name(); return new NativeElement( - product->entity->id(), + product->data().id(), parent_id, name, product_type, guid, context_string, new CgalPlacement(trsf), - brep->geometry_pointer() + brep->geometry_pointer(), + product ); } diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index a3e7167624..8eef64f8da 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -52,7 +52,7 @@ namespace IfcGeom { std::map Shape; }; - class IFC_GEOM_API CgalKernel : public AbstractKernel { + class IFC_GEOM_API MAKE_TYPE_NAME(CgalKernel) : public Kernel { public: #ifndef NO_CACHE diff --git a/src/ifcgeom_schema_agnostic/Kernel.cpp b/src/ifcgeom_schema_agnostic/Kernel.cpp index ecd738a048..ecc9562e97 100644 --- a/src/ifcgeom_schema_agnostic/Kernel.cpp +++ b/src/ifcgeom_schema_agnostic/Kernel.cpp @@ -5,14 +5,14 @@ #include #include -IfcGeom::Kernel::Kernel(IfcParse::IfcFile* file) { +IfcGeom::Kernel::Kernel(const std::string& geometry_library, IfcParse::IfcFile* file) { if (file != 0) { if (file->schema() == 0) { throw IfcParse::IfcException("No schema associated with file"); } const std::string& schema_name = file->schema()->name(); - implementation_ = impl::kernel_implementations().construct(schema_name, file); + implementation_ = impl::kernel_implementations().construct(schema_name, geometry_library, file); } } @@ -48,23 +48,27 @@ IfcGeom::impl::KernelFactoryImplementation& IfcGeom::impl::kernel_implementation return impl; } -extern void init_KernelImplementation_Ifc2x3(IfcGeom::impl::KernelFactoryImplementation*); -extern void init_KernelImplementation_Ifc4(IfcGeom::impl::KernelFactoryImplementation*); +extern void init_KernelImplementation_opencascade_Ifc2x3(IfcGeom::impl::KernelFactoryImplementation*); +extern void init_KernelImplementation_opencascade_Ifc4(IfcGeom::impl::KernelFactoryImplementation*); +extern void init_KernelImplementation_cgal_Ifc2x3(IfcGeom::impl::KernelFactoryImplementation*); +extern void init_KernelImplementation_cgal_Ifc4(IfcGeom::impl::KernelFactoryImplementation*); IfcGeom::impl::KernelFactoryImplementation::KernelFactoryImplementation() { - init_KernelImplementation_Ifc2x3(this); - init_KernelImplementation_Ifc4(this); + init_KernelImplementation_opencascade_Ifc2x3(this); + init_KernelImplementation_opencascade_Ifc4(this); + init_KernelImplementation_cgal_Ifc2x3(this); + init_KernelImplementation_cgal_Ifc4(this); } -void IfcGeom::impl::KernelFactoryImplementation::bind(const std::string& schema_name, IfcGeom::impl::kernel_fn fn) { +void IfcGeom::impl::KernelFactoryImplementation::bind(const std::string& schema_name, const std::string& geometry_library, IfcGeom::impl::kernel_fn fn) { const std::string schema_name_lower = boost::to_lower_copy(schema_name); - this->insert(std::make_pair(schema_name_lower, fn)); + this->insert(std::make_pair(std::make_pair(schema_name_lower, geometry_library), fn)); } -IfcGeom::Kernel* IfcGeom::impl::KernelFactoryImplementation::construct(const std::string& schema_name, IfcParse::IfcFile* file) { +IfcGeom::Kernel* IfcGeom::impl::KernelFactoryImplementation::construct(const std::string& schema_name, const std::string& geometry_library, IfcParse::IfcFile* file) { const std::string schema_name_lower = boost::to_lower_copy(schema_name); - std::map::const_iterator it; - it = this->find(schema_name_lower); + std::map, IfcGeom::impl::kernel_fn>::const_iterator it; + it = this->find(std::make_pair(schema_name_lower, geometry_library)); if (it == end()) { throw IfcParse::IfcException("No geometry kernel registered for " + schema_name); } @@ -216,4 +220,42 @@ bool IfcGeom::Kernel::is_manifold(const TopoDS_Shape& a) { return true; } -} \ No newline at end of file +} + +namespace { + template + IfcEntityList::ptr find_openings_helper(typename Schema::IfcProduct* product) { + + typename IfcEntityList::ptr openings(new IfcEntityList); + if (product->declaration().is(Schema::IfcElement::Class()) && !product->declaration().is(Schema::IfcOpeningElement::Class())) { + typename Schema::IfcElement* element = (typename Schema::IfcElement*)product; + openings = element->HasOpenings()->generalize(); + } + + // Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements? + typename Schema::IfcObjectDefinition* obdef = product->as(); + for (;;) { + auto decomposes = obdef->Decomposes()->generalize(); + if (decomposes->size() != 1) break; + typename Schema::IfcObjectDefinition* rel_obdef = (*decomposes->begin())->as()->RelatingObject(); + if (rel_obdef->declaration().is(Schema::IfcElement::Class()) && !rel_obdef->declaration().is(Schema::IfcOpeningElement::Class())) { + typename Schema::IfcElement* element = (typename Schema::IfcElement*)rel_obdef; + openings->push(element->HasOpenings()->generalize()); + } + + obdef = rel_obdef; + } + + return openings; + } +} + +IfcEntityList::ptr IfcGeom::Kernel::find_openings(IfcUtil::IfcBaseEntity* inst) { + if (inst->as()) { + return find_openings_helper(inst->as()); + } else if (inst->as()) { + return find_openings_helper(inst->as()); + } else { + throw IfcParse::IfcException("Unexpected entity " + inst->declaration().name()); + } +} diff --git a/src/ifcgeom_schema_agnostic/Kernel.h b/src/ifcgeom_schema_agnostic/Kernel.h index 5f1fdac66c..75c93d2c39 100644 --- a/src/ifcgeom_schema_agnostic/Kernel.h +++ b/src/ifcgeom_schema_agnostic/Kernel.h @@ -52,7 +52,7 @@ namespace IfcGeom { GV_DIMENSIONALITY }; - Kernel(IfcParse::IfcFile* file_ = 0); + Kernel(const std::string& geometry_library, IfcParse::IfcFile* file_ = 0); virtual ~Kernel() {} @@ -85,16 +85,17 @@ namespace IfcGeom { static bool is_manifold(const TopoDS_Shape& a); static IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity*); static std::map get_layers(IfcUtil::IfcBaseEntity*); + static IfcEntityList::ptr find_openings(IfcUtil::IfcBaseEntity* product); }; namespace impl { typedef boost::function1 kernel_fn; - class KernelFactoryImplementation : public std::map { + class KernelFactoryImplementation : public std::map, kernel_fn> { public: KernelFactoryImplementation(); - void bind(const std::string& schema_name, kernel_fn); - Kernel* construct(const std::string& schema_name, IfcParse::IfcFile*); + void bind(const std::string& schema_name, const std::string& geometry_library, kernel_fn); + Kernel* construct(const std::string& schema_name, const std::string& geometry_library, IfcParse::IfcFile*); }; KernelFactoryImplementation& kernel_implementations(); diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 720448294a..d1af9174f4 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -501,7 +501,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) { auto storeys = f->instances_by_type("IfcBuildingStorey"); if (!storeys || storeys->size() == 0) { - IfcGeom::Kernel kernel(f); + IfcGeom::Kernel kernel("opencascade", f); std::vector to_derive_from; to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));