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