Skip to content

Commit f4463d2

Browse files
committed
Crazy factory implementation
1 parent a792a7e commit f4463d2

8 files changed

Lines changed: 179 additions & 53 deletions

cmake/CMakeLists.txt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -551,20 +551,11 @@ if(NOT MSVC)
551551
endif()
552552
endif()
553553

554-
set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom_ifc2x3 IfcGeom_ifc4)
554+
set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom IfcGeom_ifc2x3 IfcGeom_ifc4 Iterator)
555555

556556
# IfcParse
557557
file(GLOB IFCPARSE_H_FILES ../src/ifcparse/*.h)
558558
file(GLOB IFCPARSE_CPP_FILES ../src/ifcparse/*.cpp)
559-
560-
foreach(IFC_RELEASE ${IFC_RELEASE_NOT_USED})
561-
files_for_ifc_version(${IFC_RELEASE} SOURCE_FILES_NOT_USED)
562-
foreach(SOURCE_FILE ${SOURCE_FILES_NOT_USED})
563-
list(REMOVE_ITEM IFCPARSE_CPP_FILES ${SOURCE_FILE})
564-
list(REMOVE_ITEM IFCPARSE_H_FILES ${SOURCE_FILE})
565-
endforeach()
566-
endforeach()
567-
568559
set(IFCPARSE_FILES ${IFCPARSE_CPP_FILES} ${IFCPARSE_H_FILES})
569560

570561
add_library(IfcParse ${IFCPARSE_FILES})
@@ -582,16 +573,22 @@ set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
582573
add_library(IfcGeom_ifc2x3 ${IFCGEOM_FILES})
583574
add_library(IfcGeom_ifc4 ${IFCGEOM_FILES})
584575

585-
set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
586-
set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
587-
588-
set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS -DIfcSchema=Ifc2x3)
576+
set_target_properties(IfcGeom_ifc2x3 PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc2x3")
589577
# TODO: Detect based on IfcSchema
590-
set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS "-DIfcSchema=Ifc4 -DUSE_IFC4")
578+
set_target_properties(IfcGeom_ifc4 PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc4 -DUSE_IFC4")
591579

592580
TARGET_LINK_LIBRARIES(IfcGeom_ifc2x3 IfcParse ${OPENCASCADE_LIBRARIES})
593581
TARGET_LINK_LIBRARIES(IfcGeom_ifc4 IfcParse ${OPENCASCADE_LIBRARIES})
594582

583+
# Iterator
584+
file(GLOB ITERATOR_H_FILES ../src/iterator/*.h)
585+
file(GLOB ITERATOR_CPP_FILES ../src/iterator/*.cpp)
586+
set(ITERATOR_FILES ${ITERATOR_H_FILES} ${ITERATOR_CPP_FILES})
587+
588+
add_library(Iterator ${ITERATOR_FILES})
589+
set_target_properties(Iterator PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
590+
TARGET_LINK_LIBRARIES(Iterator IfcGeom_ifc2x3 IfcGeom_ifc4)
591+
595592
# IfcConvert
596593
file(GLOB IFCCONVERT_CPP_FILES ../src/ifcconvert/*.cpp)
597594
file(GLOB IFCCONVERT_H_FILES ../src/ifcconvert/*.h)

src/ifcgeom/IfcGeomElement.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ namespace IfcGeom {
124124
const std::string& context() const { return _context; }
125125
const std::string& unique_id() const { return _unique_id; }
126126
const Transformation<P>& transformation() const { return _transformation; }
127-
IfcSchema::IfcProduct* product() const { return product_; }
127+
IfcUtil::IfcBaseClass* product() const { return product_; }
128128
const std::vector<const IfcGeom::Element<P>*> parents() const { return _parents; }
129129
void SetParents(std::vector<const IfcGeom::Element<P>*> newparents) { _parents = newparents; }
130130

src/ifcgeom/IfcGeomFilter.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ namespace IfcGeom
123123
struct string_arg_filter : public wildcard_filter
124124
{
125125
// Using this for now in order to overcome the fact that different classes have the argument at different indices.
126-
typedef std::map<IfcSchema::Enum::Class(), unsigned short> arg_map_t;
126+
typedef std::map<const IfcParse::declaration*, unsigned short> arg_map_t;
127127
arg_map_t args;
128128

129129
/// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged.
130130
string_arg_filter(arg_map_t args) : args(args) { assert_arguments(); }
131-
string_arg_filter(IfcSchema::Enum::Class() type, unsigned short index) { args[type] = index; assert_arguments(); }
131+
string_arg_filter(const IfcParse::declaration* type, unsigned short index) { args[type] = index; assert_arguments(); }
132132
string_arg_filter(
133-
IfcSchema::Enum::Class() type1, unsigned short index1,
134-
IfcSchema::Enum::Class() type2, unsigned short index2)
133+
const IfcParse::declaration* type1, unsigned short index1,
134+
const IfcParse::declaration* type2, unsigned short index2)
135135
{
136136
args[type1] = index1;
137137
args[type2] = index2;
@@ -141,7 +141,8 @@ namespace IfcGeom
141141
/// @todo this won't be needed when we have the generic argument name access
142142
void assert_arguments()
143143
{
144-
#ifndef NDEBUG
144+
// TODO
145+
#if 0
145146
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
146147
IfcEntityInstanceData dummy(it->first);
147148
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy);
@@ -155,7 +156,7 @@ namespace IfcGeom
155156
std::string value(IfcSchema::IfcProduct* prod) const
156157
{
157158
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
158-
if (prod->declaration().is(it->first) && it->second < prod->data().getArgumentCount() &&
159+
if (prod->declaration().is(*it->first) && it->second < prod->data().getArgumentCount() &&
159160
prod->data().getArgument(it->second)->type() == IfcUtil::Argument_STRING) {
160161
Argument *arg = prod->data().getArgument(it->second);
161162
if (!arg->isNull()) {
@@ -184,16 +185,19 @@ namespace IfcGeom
184185
patterns.push_back("\"" + r.str() + "\"");
185186
}
186187

188+
// TODO
189+
#if 0
187190
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
188191
IfcEntityInstanceData dummy(it->first);
189-
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy);
192+
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy);
190193
try {
191194
ss << " " << IfcSchema::ToString::Class()(it->first) << "." << base->declaration().as_entity()->all_attributes()[it->second]->name();
192195
} catch (const std::exception& e) {
193196
Logger::Error(e);
194197
}
195198
delete base;
196199
}
200+
#endif
197201

198202
ss << " values " << boost::algorithm::join(patterns, " ");
199203
description = ss.str();
@@ -254,13 +258,15 @@ namespace IfcGeom
254258
//populate(types);
255259
}
256260

257-
std::set<IfcSchema::Enum::Class()> values;
261+
std::set<const IfcParse::declaration*> values;
258262

259-
void populate(const std::set<std::string>& types)
263+
void populate(const std::set<std::string>&)
260264
{
265+
// TODO
266+
#if 0
261267
values.clear();
262268
foreach(const std::string& type, types) {
263-
IfcSchema::Enum::Class() ty;
269+
const IfcParse::declaration* ty;
264270
try {
265271
ty = IfcSchema::FromString::Class()(boost::to_upper_copy(type));
266272
} catch (const IfcParse::IfcException&) {
@@ -269,13 +275,14 @@ namespace IfcGeom
269275
values.insert(ty);
270276
/// @todo Add child classes so that containment in set can be in O(log n)
271277
}
278+
#endif
272279
}
273280

274281
bool match(IfcSchema::IfcProduct* prod) const
275282
{
276283
// The set is iterated over to able to filter on subtypes.
277-
foreach(IfcSchema::Enum::Class() type, values) {
278-
if (prod->declaration().is(type)) {
284+
foreach(const IfcParse::declaration* type, values) {
285+
if (prod->declaration().is(*type)) {
279286
return true;
280287
}
281288
}
@@ -289,12 +296,15 @@ namespace IfcGeom
289296

290297
void update_description()
291298
{
299+
// TODO
300+
#if 0
292301
std::stringstream ss;
293302
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities";
294303
foreach(IfcSchema::Enum::Class() type, values) {
295304
ss << " " << IfcSchema::ToString::Class()(type);
296305
}
297306
description = ss.str();
307+
#endif
298308
}
299309
};
300310
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "IfcGeomIteratorImplementation.h"
2+
#include "../iterator/IteratorImplementation.h"
3+
4+
namespace IfcGeom {
5+
template class MAKE_TYPE_NAME(IteratorImplementation_)<float>;
6+
template class MAKE_TYPE_NAME(IteratorImplementation_)<double>;
7+
}
8+
9+
#define MAKE_INIT_FN__(a, b) init_ ## a ## b
10+
#define MAKE_INIT_FN_(a, b) MAKE_INIT_FN__(a, b)
11+
#define MAKE_INIT_FN(t) MAKE_INIT_FN_(t, IfcSchema)
12+
13+
#define STRINGIFY(x) #x
14+
#define TOSTRING(x) STRINGIFY(x)
15+
16+
void MAKE_INIT_FN(IteratorImplementation_)() {
17+
static const std::string schema_name = TOSTRING(IfcSchema);
18+
19+
struct {
20+
IteratorImplementation<float>* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const {
21+
return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<float>(settings, file);
22+
}
23+
} factory_float;
24+
25+
struct {
26+
IteratorImplementation<double>* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const {
27+
return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<double>(settings, file);
28+
}
29+
} factory_double;
30+
31+
static Registrar< IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<float> > float_registration(schema_name, factory_float);
32+
static Registrar< IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<double> > double_registration(schema_name, factory_double);
33+
}

src/ifcgeom/IfcGeomIterator.h renamed to src/ifcgeom/IfcGeomIteratorImplementation.h

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
#include "../ifcgeom/IfcRepresentationShapeItem.h"
8383
#include "../ifcgeom/IfcGeomFilter.h"
8484

85+
#include "../iterator/IteratorImplementation.h"
86+
8587
// The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration
8688
#ifdef min
8789
#undef min
@@ -90,13 +92,18 @@
9092
#undef max
9193
#endif
9294

95+
#define MAKE_TYPE_NAME__(a, b) a ## b
96+
#define MAKE_TYPE_NAME_(a, b) MAKE_TYPE_NAME__(a, b)
97+
#define MAKE_TYPE_NAME(t) MAKE_TYPE_NAME_(t, IfcSchema)
98+
9399
namespace IfcGeom {
94100

95101
template <typename P>
96-
class Iterator {
102+
class MAKE_TYPE_NAME(IteratorImplementation_) : public IteratorImplementation<P> {
97103
private:
98-
Iterator(const Iterator&); // N/I
99-
Iterator& operator=(const Iterator&); // N/I
104+
105+
MAKE_TYPE_NAME(IteratorImplementation_)(const MAKE_TYPE_NAME(IteratorImplementation_)&); // N/I
106+
MAKE_TYPE_NAME(IteratorImplementation_)& operator=(const MAKE_TYPE_NAME(IteratorImplementation_)&); // N/I
100107

101108
Kernel kernel;
102109
IteratorSettings settings;
@@ -136,7 +143,7 @@ namespace IfcGeom {
136143
};
137144

138145
void initUnits() {
139-
IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType<IfcSchema::IfcProject>();
146+
IfcSchema::IfcProject::list::ptr projects = ifc_file->instances_by_type<IfcSchema::IfcProject>();
140147
if (projects->size() == 1) {
141148
IfcSchema::IfcProject* project = *projects->begin();
142149
std::pair<std::string, double> length_unit = kernel.initializeUnits(project->UnitsInContext());
@@ -147,7 +154,9 @@ namespace IfcGeom {
147154

148155
/// @todo public/private sections all over the place: move all public to the beginning of the class
149156
public:
150-
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file, std::vector<IfcGeom::filter_t>& filters)
157+
typedef P Precision;
158+
159+
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file, std::vector<IfcGeom::filter_t>& filters)
151160
: settings(settings)
152161
, ifc_file(file)
153162
, owns_ifc_file(false)
@@ -191,7 +200,7 @@ namespace IfcGeom {
191200
IfcSchema::IfcGeometricRepresentationContext::list::it it;
192201
IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
193202
IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts =
194-
ifc_file->entitiesByType<IfcSchema::IfcGeometricRepresentationContext>();
203+
ifc_file->instances_by_type<IfcSchema::IfcGeometricRepresentationContext>();
195204

196205
IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list);
197206

@@ -286,7 +295,7 @@ namespace IfcGeom {
286295
bounds_max_.SetCoord(i, -std::numeric_limits<double>::infinity());
287296
}
288297

289-
IfcSchema::IfcProduct::list::ptr products = ifc_file->entitiesByType<IfcSchema::IfcProduct>();
298+
IfcSchema::IfcProduct::list::ptr products = ifc_file->instances_by_type<IfcSchema::IfcProduct>();
290299
for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) {
291300
IfcSchema::IfcProduct* product = *iter;
292301
if (product->hasObjectPlacement()) {
@@ -493,7 +502,7 @@ namespace IfcGeom {
493502

494503
/// Moves to the next shape representation, create its geometry, and returns the associated product.
495504
/// Use get() to retrieve the created geometry.
496-
IfcSchema::IfcProduct* next() {
505+
IfcUtil::IfcBaseClass* next() {
497506
// Increment the iterator over the list of products using the current
498507
// shape representation
499508
if (ifcproducts) {
@@ -575,8 +584,8 @@ namespace IfcGeom {
575584
IfcSchema::IfcProduct* ifc_product = 0;
576585

577586
try {
578-
IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id);
579-
instance_type = IfcSchema::ToString::Class()(ifc_entity->declaration().type());
587+
IfcUtil::IfcBaseClass* ifc_entity = ifc_file->instance_by_id(id);
588+
instance_type = ifc_entity->declaration().name();
580589

581590
if (ifc_entity->declaration().is(IfcSchema::IfcRoot::Class())) {
582591
IfcSchema::IfcRoot* ifc_root = ifc_entity->as<IfcSchema::IfcRoot>();
@@ -624,7 +633,7 @@ namespace IfcGeom {
624633
return ifc_object;
625634
}
626635

627-
IfcSchema::IfcProduct* create() {
636+
IfcUtil::IfcBaseClass* create() {
628637
IfcGeom::BRepElement<P>* next_shape_model = 0;
629638
IfcGeom::SerializedElement<P>* next_serialization = 0;
630639
IfcGeom::TriangulationElement<P>* next_triangulation = 0;
@@ -684,45 +693,42 @@ namespace IfcGeom {
684693
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES)
685694
? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
686695
if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
687-
kernel.set_conversion_placement_rel_to(IfcSchema::IfcSite::Class());
696+
kernel.set_conversion_placement_rel_to(&IfcSchema::IfcSite::Class());
688697
}
689698
}
690699

691700
bool owns_ifc_file;
692701
public:
693-
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file)
702+
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file)
694703
: settings(settings)
695704
, ifc_file(file)
696705
, owns_ifc_file(false)
697706
{
698707
_initialize();
699708
}
700-
Iterator(const IteratorSettings& settings, const std::string& filename)
709+
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, const std::string& filename)
701710
: settings(settings)
702-
, ifc_file(new IfcParse::IfcFile)
711+
, ifc_file(new IfcParse::IfcFile(filename))
703712
, owns_ifc_file(true)
704713
{
705-
ifc_file->Init(filename);
706714
_initialize();
707715
}
708-
Iterator(const IteratorSettings& settings, void* data, int length)
716+
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, void* data, int length)
709717
: settings(settings)
710-
, ifc_file(new IfcParse::IfcFile)
718+
, ifc_file(new IfcParse::IfcFile(data, length))
711719
, owns_ifc_file(true)
712720
{
713-
ifc_file->Init(data, length);
714721
_initialize();
715722
}
716-
Iterator(const IteratorSettings& settings, std::istream& filestream, int length)
723+
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, std::istream& filestream, int length)
717724
: settings(settings)
718-
, ifc_file(new IfcParse::IfcFile)
725+
, ifc_file(new IfcParse::IfcFile(filestream, length))
719726
, owns_ifc_file(true)
720727
{
721-
ifc_file->Init(filestream, length);
722728
_initialize();
723729
}
724730

725-
~Iterator() {
731+
~MAKE_TYPE_NAME(IteratorImplementation_)() {
726732
if (owns_ifc_file) {
727733
delete ifc_file;
728734
}

src/ifcparse/IfcLogger.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class IFC_PARSE_API Logger {
4848
static const char* severity_strings[];
4949
static boost::optional<IfcUtil::IfcBaseClass*> current_product;
5050
public:
51-
template <typename Schema>
52-
static void SetProduct(boost::optional<typename Schema::IfcProduct*> product) {
51+
52+
static void SetProduct(boost::optional<IfcUtil::IfcBaseClass*> product) {
5353
current_product = product;
5454
}
5555

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "IteratorImplementation.h"
2+
3+
template <typename P>
4+
IteratorFactoryImplementation<P>& iterator_implementations() {
5+
static IteratorFactoryImplementation<P> impl;
6+
return impl;
7+
}
8+
9+
template IteratorFactoryImplementation<float>& iterator_implementations<float>();
10+
template IteratorFactoryImplementation<double>& iterator_implementations<double>();
11+
12+
#define INIT(a) extern void init_##a(); init_##a();
13+
14+
template <typename P>
15+
IteratorFactoryImplementation<P>::IteratorFactoryImplementation() {
16+
INIT(IteratorImplementation_Ifc2x3);
17+
INIT(IteratorImplementation_Ifc4);
18+
}
19+
20+
template <class P>
21+
void IteratorFactoryImplementation<P>::bind(const std::string& schema_name, typename get_factory_type<P>::type fn) {
22+
this->insert(std::make_pair(schema_name, fn));
23+
}
24+
25+
template IteratorFactoryImplementation<float>;
26+
template IteratorFactoryImplementation<double>;

0 commit comments

Comments
 (0)