diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b68671d7ec..90697d839e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -551,20 +551,11 @@ if(NOT MSVC) endif() endif() -set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom_ifc2x3 IfcGeom_ifc4) +set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom IfcGeom_ifc2x3 IfcGeom_ifc4 Iterator) # IfcParse file(GLOB IFCPARSE_H_FILES ../src/ifcparse/*.h) file(GLOB IFCPARSE_CPP_FILES ../src/ifcparse/*.cpp) - -foreach(IFC_RELEASE ${IFC_RELEASE_NOT_USED}) - files_for_ifc_version(${IFC_RELEASE} SOURCE_FILES_NOT_USED) - foreach(SOURCE_FILE ${SOURCE_FILES_NOT_USED}) - list(REMOVE_ITEM IFCPARSE_CPP_FILES ${SOURCE_FILE}) - list(REMOVE_ITEM IFCPARSE_H_FILES ${SOURCE_FILE}) - endforeach() -endforeach() - set(IFCPARSE_FILES ${IFCPARSE_CPP_FILES} ${IFCPARSE_H_FILES}) add_library(IfcParse ${IFCPARSE_FILES}) @@ -582,16 +573,22 @@ set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES}) add_library(IfcGeom_ifc2x3 ${IFCGEOM_FILES}) add_library(IfcGeom_ifc4 ${IFCGEOM_FILES}) -set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS) -set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS) - -set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS -DIfcSchema=Ifc2x3) +set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc2x3") # TODO: Detect based on IfcSchema -set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS "-DIfcSchema=Ifc4 -DUSE_IFC4") +set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc4 -DUSE_IFC4") TARGET_LINK_LIBRARIES(IfcGeom_ifc2x3 IfcParse ${OPENCASCADE_LIBRARIES}) TARGET_LINK_LIBRARIES(IfcGeom_ifc4 IfcParse ${OPENCASCADE_LIBRARIES}) +# Iterator +file(GLOB ITERATOR_H_FILES ../src/iterator/*.h) +file(GLOB ITERATOR_CPP_FILES ../src/iterator/*.cpp) +set(ITERATOR_FILES ${ITERATOR_H_FILES} ${ITERATOR_CPP_FILES}) + +add_library(Iterator ${ITERATOR_FILES}) +set_target_properties(Iterator PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS) +TARGET_LINK_LIBRARIES(Iterator IfcGeom_ifc2x3 IfcGeom_ifc4) + # IfcConvert file(GLOB IFCCONVERT_CPP_FILES ../src/ifcconvert/*.cpp) file(GLOB IFCCONVERT_H_FILES ../src/ifcconvert/*.h) diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index 1054822c06..cf488f5d60 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -124,7 +124,7 @@ namespace IfcGeom { const std::string& context() const { return _context; } const std::string& unique_id() const { return _unique_id; } const Transformation

& transformation() const { return _transformation; } - IfcSchema::IfcProduct* product() const { return product_; } + IfcUtil::IfcBaseClass* product() const { return product_; } const std::vector*> parents() const { return _parents; } void SetParents(std::vector*> newparents) { _parents = newparents; } diff --git a/src/ifcgeom/IfcGeomFilter.h b/src/ifcgeom/IfcGeomFilter.h index 887800937d..292e4024c5 100644 --- a/src/ifcgeom/IfcGeomFilter.h +++ b/src/ifcgeom/IfcGeomFilter.h @@ -123,15 +123,15 @@ namespace IfcGeom struct string_arg_filter : public wildcard_filter { // Using this for now in order to overcome the fact that different classes have the argument at different indices. - typedef std::map arg_map_t; + typedef std::map arg_map_t; arg_map_t args; /// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged. string_arg_filter(arg_map_t args) : args(args) { assert_arguments(); } - string_arg_filter(IfcSchema::Enum::Class() type, unsigned short index) { args[type] = index; assert_arguments(); } + string_arg_filter(const IfcParse::declaration* type, unsigned short index) { args[type] = index; assert_arguments(); } string_arg_filter( - IfcSchema::Enum::Class() type1, unsigned short index1, - IfcSchema::Enum::Class() type2, unsigned short index2) + const IfcParse::declaration* type1, unsigned short index1, + const IfcParse::declaration* type2, unsigned short index2) { args[type1] = index1; args[type2] = index2; @@ -141,7 +141,8 @@ namespace IfcGeom /// @todo this won't be needed when we have the generic argument name access void assert_arguments() { -#ifndef NDEBUG + // TODO +#if 0 for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { IfcEntityInstanceData dummy(it->first); IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy); @@ -155,7 +156,7 @@ namespace IfcGeom std::string value(IfcSchema::IfcProduct* prod) const { for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { - if (prod->declaration().is(it->first) && it->second < prod->data().getArgumentCount() && + if (prod->declaration().is(*it->first) && it->second < prod->data().getArgumentCount() && prod->data().getArgument(it->second)->type() == IfcUtil::Argument_STRING) { Argument *arg = prod->data().getArgument(it->second); if (!arg->isNull()) { @@ -184,9 +185,11 @@ namespace IfcGeom patterns.push_back("\"" + r.str() + "\""); } + // TODO +#if 0 for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { IfcEntityInstanceData dummy(it->first); - IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy); + IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy); try { ss << " " << IfcSchema::ToString::Class()(it->first) << "." << base->declaration().as_entity()->all_attributes()[it->second]->name(); } catch (const std::exception& e) { @@ -194,6 +197,7 @@ namespace IfcGeom } delete base; } +#endif ss << " values " << boost::algorithm::join(patterns, " "); description = ss.str(); @@ -254,13 +258,15 @@ namespace IfcGeom //populate(types); } - std::set values; + std::set values; - void populate(const std::set& types) + void populate(const std::set&) { + // TODO +#if 0 values.clear(); foreach(const std::string& type, types) { - IfcSchema::Enum::Class() ty; + const IfcParse::declaration* ty; try { ty = IfcSchema::FromString::Class()(boost::to_upper_copy(type)); } catch (const IfcParse::IfcException&) { @@ -269,13 +275,14 @@ namespace IfcGeom values.insert(ty); /// @todo Add child classes so that containment in set can be in O(log n) } +#endif } bool match(IfcSchema::IfcProduct* prod) const { // The set is iterated over to able to filter on subtypes. - foreach(IfcSchema::Enum::Class() type, values) { - if (prod->declaration().is(type)) { + foreach(const IfcParse::declaration* type, values) { + if (prod->declaration().is(*type)) { return true; } } @@ -289,12 +296,15 @@ namespace IfcGeom void update_description() { + // TODO +#if 0 std::stringstream ss; ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities"; foreach(IfcSchema::Enum::Class() type, values) { ss << " " << IfcSchema::ToString::Class()(type); } description = ss.str(); +#endif } }; } diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.cpp b/src/ifcgeom/IfcGeomIteratorImplementation.cpp new file mode 100644 index 0000000000..6c6dffecdd --- /dev/null +++ b/src/ifcgeom/IfcGeomIteratorImplementation.cpp @@ -0,0 +1,33 @@ +#include "IfcGeomIteratorImplementation.h" +#include "../iterator/IteratorImplementation.h" + +namespace IfcGeom { + template class MAKE_TYPE_NAME(IteratorImplementation_); + template class MAKE_TYPE_NAME(IteratorImplementation_); +} + +#define MAKE_INIT_FN__(a, b) init_ ## a ## b +#define MAKE_INIT_FN_(a, b) MAKE_INIT_FN__(a, b) +#define MAKE_INIT_FN(t) MAKE_INIT_FN_(t, IfcSchema) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +void MAKE_INIT_FN(IteratorImplementation_)() { + static const std::string schema_name = TOSTRING(IfcSchema); + + struct { + IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { + return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)(settings, file); + } + } factory_float; + + struct { + IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { + return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)(settings, file); + } + } factory_double; + + static Registrar< IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_) > float_registration(schema_name, factory_float); + static Registrar< IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_) > double_registration(schema_name, factory_double); +} \ No newline at end of file diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIteratorImplementation.h similarity index 93% rename from src/ifcgeom/IfcGeomIterator.h rename to src/ifcgeom/IfcGeomIteratorImplementation.h index f44840068e..998d49bf40 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -82,6 +82,8 @@ #include "../ifcgeom/IfcRepresentationShapeItem.h" #include "../ifcgeom/IfcGeomFilter.h" +#include "../iterator/IteratorImplementation.h" + // The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration #ifdef min #undef min @@ -90,13 +92,18 @@ #undef max #endif +#define MAKE_TYPE_NAME__(a, b) a ## b +#define MAKE_TYPE_NAME_(a, b) MAKE_TYPE_NAME__(a, b) +#define MAKE_TYPE_NAME(t) MAKE_TYPE_NAME_(t, IfcSchema) + namespace IfcGeom { template - class Iterator { + class MAKE_TYPE_NAME(IteratorImplementation_) : public IteratorImplementation

{ private: - Iterator(const Iterator&); // N/I - Iterator& operator=(const Iterator&); // N/I + + MAKE_TYPE_NAME(IteratorImplementation_)(const MAKE_TYPE_NAME(IteratorImplementation_)&); // N/I + MAKE_TYPE_NAME(IteratorImplementation_)& operator=(const MAKE_TYPE_NAME(IteratorImplementation_)&); // N/I Kernel kernel; IteratorSettings settings; @@ -136,7 +143,7 @@ namespace IfcGeom { }; void initUnits() { - IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType(); + IfcSchema::IfcProject::list::ptr projects = ifc_file->instances_by_type(); if (projects->size() == 1) { IfcSchema::IfcProject* project = *projects->begin(); std::pair length_unit = kernel.initializeUnits(project->UnitsInContext()); @@ -147,7 +154,9 @@ namespace IfcGeom { /// @todo public/private sections all over the place: move all public to the beginning of the class public: - Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file, std::vector& filters) + typedef P Precision; + + MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file, std::vector& filters) : settings(settings) , ifc_file(file) , owns_ifc_file(false) @@ -191,7 +200,7 @@ namespace IfcGeom { IfcSchema::IfcGeometricRepresentationContext::list::it it; IfcSchema::IfcGeometricRepresentationSubContext::list::it jt; IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts = - ifc_file->entitiesByType(); + ifc_file->instances_by_type(); IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list); @@ -286,7 +295,7 @@ namespace IfcGeom { bounds_max_.SetCoord(i, -std::numeric_limits::infinity()); } - IfcSchema::IfcProduct::list::ptr products = ifc_file->entitiesByType(); + IfcSchema::IfcProduct::list::ptr products = ifc_file->instances_by_type(); for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) { IfcSchema::IfcProduct* product = *iter; if (product->hasObjectPlacement()) { @@ -493,7 +502,7 @@ namespace IfcGeom { /// Moves to the next shape representation, create its geometry, and returns the associated product. /// Use get() to retrieve the created geometry. - IfcSchema::IfcProduct* next() { + IfcUtil::IfcBaseClass* next() { // Increment the iterator over the list of products using the current // shape representation if (ifcproducts) { @@ -575,8 +584,8 @@ namespace IfcGeom { IfcSchema::IfcProduct* ifc_product = 0; try { - IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id); - instance_type = IfcSchema::ToString::Class()(ifc_entity->declaration().type()); + IfcUtil::IfcBaseClass* ifc_entity = ifc_file->instance_by_id(id); + instance_type = ifc_entity->declaration().name(); if (ifc_entity->declaration().is(IfcSchema::IfcRoot::Class())) { IfcSchema::IfcRoot* ifc_root = ifc_entity->as(); @@ -624,7 +633,7 @@ namespace IfcGeom { return ifc_object; } - IfcSchema::IfcProduct* create() { + IfcUtil::IfcBaseClass* create() { IfcGeom::BRepElement

* next_shape_model = 0; IfcGeom::SerializedElement

* next_serialization = 0; IfcGeom::TriangulationElement

* next_triangulation = 0; @@ -684,45 +693,42 @@ namespace IfcGeom { kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) { - kernel.set_conversion_placement_rel_to(IfcSchema::IfcSite::Class()); + kernel.set_conversion_placement_rel_to(&IfcSchema::IfcSite::Class()); } } bool owns_ifc_file; public: - Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file) + MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file) : settings(settings) , ifc_file(file) , owns_ifc_file(false) { _initialize(); } - Iterator(const IteratorSettings& settings, const std::string& filename) + MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, const std::string& filename) : settings(settings) - , ifc_file(new IfcParse::IfcFile) + , ifc_file(new IfcParse::IfcFile(filename)) , owns_ifc_file(true) { - ifc_file->Init(filename); _initialize(); } - Iterator(const IteratorSettings& settings, void* data, int length) + MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, void* data, int length) : settings(settings) - , ifc_file(new IfcParse::IfcFile) + , ifc_file(new IfcParse::IfcFile(data, length)) , owns_ifc_file(true) { - ifc_file->Init(data, length); _initialize(); } - Iterator(const IteratorSettings& settings, std::istream& filestream, int length) + MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, std::istream& filestream, int length) : settings(settings) - , ifc_file(new IfcParse::IfcFile) + , ifc_file(new IfcParse::IfcFile(filestream, length)) , owns_ifc_file(true) { - ifc_file->Init(filestream, length); _initialize(); } - ~Iterator() { + ~MAKE_TYPE_NAME(IteratorImplementation_)() { if (owns_ifc_file) { delete ifc_file; } diff --git a/src/ifcparse/IfcLogger.h b/src/ifcparse/IfcLogger.h index 003eabceaf..e440934fd7 100644 --- a/src/ifcparse/IfcLogger.h +++ b/src/ifcparse/IfcLogger.h @@ -48,8 +48,8 @@ private: static const char* severity_strings[]; static boost::optional current_product; public: - template - static void SetProduct(boost::optional product) { + + static void SetProduct(boost::optional product) { current_product = product; } diff --git a/src/iterator/IteratorImplementation.cpp b/src/iterator/IteratorImplementation.cpp new file mode 100644 index 0000000000..99b7cdbc9b --- /dev/null +++ b/src/iterator/IteratorImplementation.cpp @@ -0,0 +1,26 @@ +#include "IteratorImplementation.h" + +template +IteratorFactoryImplementation

& iterator_implementations() { + static IteratorFactoryImplementation

impl; + return impl; +} + +template IteratorFactoryImplementation& iterator_implementations(); +template IteratorFactoryImplementation& iterator_implementations(); + +#define INIT(a) extern void init_##a(); init_##a(); + +template +IteratorFactoryImplementation

::IteratorFactoryImplementation() { + INIT(IteratorImplementation_Ifc2x3); + INIT(IteratorImplementation_Ifc4); +} + +template +void IteratorFactoryImplementation

::bind(const std::string& schema_name, typename get_factory_type

::type fn) { + this->insert(std::make_pair(schema_name, fn)); +} + +template IteratorFactoryImplementation; +template IteratorFactoryImplementation; diff --git a/src/iterator/IteratorImplementation.h b/src/iterator/IteratorImplementation.h new file mode 100644 index 0000000000..d1cb24966d --- /dev/null +++ b/src/iterator/IteratorImplementation.h @@ -0,0 +1,54 @@ +#ifndef ITERATOR_IMPLEMENTATION_H +#define ITERATOR_IMPLEMENTATION_H + +#include "../ifcparse/IfcFile.h" +#include "../ifcgeom/IfcGeomIteratorSettings.h" + +#include + +#include +#include + +template +class IteratorImplementation; + +typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_fn; +typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_double_fn; + +template +struct get_factory_type {}; + +template <> +struct get_factory_type { + typedef iterator_float_fn type; +}; + +template <> +struct get_factory_type { + typedef iterator_double_fn type; +}; + +template +class IteratorFactoryImplementation : public std::map::type> { +public: + IteratorFactoryImplementation(); + void bind(const std::string& schema_name, typename get_factory_type

::type fn); +}; + +template +IteratorFactoryImplementation

& iterator_implementations(); + +template +class Registrar { +public: + Registrar(const std::string& schema_name, const typename get_factory_type::type& fn) { + iterator_implementations().bind(schema_name, fn); + } +}; + +template +class IteratorImplementation { + +}; + +#endif \ No newline at end of file