Skip to content

Commit f674493

Browse files
committed
Fixed retrieving attributes derived in subtype Convert argument type enumeration to python string Add ability to iterate over all instances from python
1 parent dbc60be commit f674493

File tree

10 files changed

+97
-17
lines changed

10 files changed

+97
-17
lines changed

src/ifcexpressparser/templates.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
8989
const std::string& GetAttributeName(Enum t, unsigned char a);
9090
bool GetAttributeOptional(Enum t, unsigned char a);
91+
bool GetAttributeDerived(Enum t, unsigned char a);
9192
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
9293
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
9394
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
@@ -167,6 +168,8 @@
167168
"""
168169

169170
rt_implementation = """
171+
#include <set>
172+
170173
#include "../ifcparse/%(schema_name)s.h"
171174
#include "../ifcparse/%(schema_name)s-rt.h"
172175
#include "../ifcparse/IfcException.h"
@@ -183,6 +186,8 @@
183186
std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;
184187
std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;
185188
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> > inverse_map;
189+
std::map<Type::Enum,std::set<int> > derived_map;
190+
186191
void InitDescriptorMap() {
187192
IfcEntityDescriptor* current;
188193
%(entity_descriptors)s
@@ -196,6 +201,10 @@
196201
%(inverse_implementations)s
197202
}
198203
204+
void InitDerivedMap() {
205+
%(derived_field_statements)s
206+
}
207+
199208
int Type::GetAttributeIndex(Enum t, const std::string& a) {
200209
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
201210
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
@@ -231,6 +240,12 @@
231240
else return i->second->getArgumentOptional(a);
232241
}
233242
243+
bool Type::GetAttributeDerived(Enum t, unsigned char a) {
244+
if (derived_map.empty()) ::InitDerivedMap();
245+
std::map<Type::Enum,std::set<int> >::const_iterator i = derived_map.find(t);
246+
return i != derived_map.end() && i->second.find(a) != i->second.end();
247+
}
248+
234249
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
235250
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
236251
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
@@ -262,8 +277,12 @@
262277
}
263278
264279
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
265-
Type::Enum type = e->type();
266-
%(derived_field_statements)s
280+
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
281+
if (i != derived_map.end()) {
282+
for (std::set<int>::const_iterator it = i->second.begin(); it != i->second.end(); ++it) {
283+
e->setArgumentDerived(*it);
284+
}
285+
}
267286
}
268287
"""
269288

@@ -280,8 +299,8 @@
280299

281300
enumeration_descriptor_value = ' values.push_back("%(name)s");'
282301

283-
derived_field_statement = ' if (type == Type::%(type)s) { %(statements)s}';
284-
derived_field_statement_attrs = 'e->setArgumentDerived(%d); '
302+
derived_field_statement = ' {std::set<int> idxs; %(statements)sderived_map[Type::%(type)s] = idxs;}';
303+
derived_field_statement_attrs = 'idxs.insert(%d); '
285304

286305
simpletype = """%(documentation)s
287306
typedef %(type)s %(name)s;

src/ifcparse/Ifc2x3-rt.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#ifndef USE_IFC4
2828

29+
#include <set>
30+
2931
#include "../ifcparse/Ifc2x3.h"
3032
#include "../ifcparse/Ifc2x3-rt.h"
3133
#include "../ifcparse/IfcException.h"
@@ -42,6 +44,8 @@ using namespace IfcUtil;
4244
std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;
4345
std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;
4446
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> > inverse_map;
47+
std::map<Type::Enum,std::set<int> > derived_map;
48+
4549
void InitDescriptorMap() {
4650
IfcEntityDescriptor* current;
4751
current = entity_descriptor_map[Type::IfcAbsorbedDoseMeasure] = new IfcEntityDescriptor(Type::IfcAbsorbedDoseMeasure,0);
@@ -4166,6 +4170,12 @@ void InitInverseMap() {
41664170
inverse_map.insert(std::make_pair(std::make_pair(Type::IfcTypeObject, "ObjectTypeOf"), std::make_pair(Type::IfcRelDefinesByType, 5)));
41674171
}
41684172

4173+
void InitDerivedMap() {
4174+
{std::set<int> idxs; idxs.insert(2); idxs.insert(3); idxs.insert(4); idxs.insert(5); derived_map[Type::IfcGeometricRepresentationSubContext] = idxs;}
4175+
{std::set<int> idxs; idxs.insert(0); idxs.insert(1); derived_map[Type::IfcOrientedEdge] = idxs;}
4176+
{std::set<int> idxs; idxs.insert(0); derived_map[Type::IfcSIUnit] = idxs;}
4177+
}
4178+
41694179
int Type::GetAttributeIndex(Enum t, const std::string& a) {
41704180
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
41714181
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
@@ -4201,6 +4211,12 @@ bool Type::GetAttributeOptional(Enum t, unsigned char a) {
42014211
else return i->second->getArgumentOptional(a);
42024212
}
42034213

4214+
bool Type::GetAttributeDerived(Enum t, unsigned char a) {
4215+
if (derived_map.empty()) ::InitDerivedMap();
4216+
std::map<Type::Enum,std::set<int> >::const_iterator i = derived_map.find(t);
4217+
return i != derived_map.end() && i->second.find(a) != i->second.end();
4218+
}
4219+
42044220
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
42054221
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
42064222
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
@@ -4232,9 +4248,11 @@ Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
42324248
}
42334249

42344250
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
4235-
Type::Enum type = e->type();
4236-
if (type == Type::IfcGeometricRepresentationSubContext) { e->setArgumentDerived(2); e->setArgumentDerived(3); e->setArgumentDerived(4); e->setArgumentDerived(5); }
4237-
if (type == Type::IfcOrientedEdge) { e->setArgumentDerived(0); e->setArgumentDerived(1); }
4238-
if (type == Type::IfcSIUnit) { e->setArgumentDerived(0); }
4251+
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
4252+
if (i != derived_map.end()) {
4253+
for (std::set<int>::const_iterator it = i->second.begin(); it != i->second.end(); ++it) {
4254+
e->setArgumentDerived(*it);
4255+
}
4256+
}
42394257
}
42404258
#endif

src/ifcparse/Ifc2x3-rt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace Type {
4040
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
4141
const std::string& GetAttributeName(Enum t, unsigned char a);
4242
bool GetAttributeOptional(Enum t, unsigned char a);
43+
bool GetAttributeDerived(Enum t, unsigned char a);
4344
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
4445
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
4546
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);

src/ifcparse/Ifc4-rt.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#ifdef USE_IFC4
2828

29+
#include <set>
30+
2931
#include "../ifcparse/Ifc4.h"
3032
#include "../ifcparse/Ifc4-rt.h"
3133
#include "../ifcparse/IfcException.h"
@@ -42,6 +44,8 @@ using namespace IfcUtil;
4244
std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;
4345
std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;
4446
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> > inverse_map;
47+
std::map<Type::Enum,std::set<int> > derived_map;
48+
4549
void InitDescriptorMap() {
4650
IfcEntityDescriptor* current;
4751
current = entity_descriptor_map[Type::IfcAbsorbedDoseMeasure] = new IfcEntityDescriptor(Type::IfcAbsorbedDoseMeasure,0);
@@ -4854,6 +4858,13 @@ void InitInverseMap() {
48544858
inverse_map.insert(std::make_pair(std::make_pair(Type::IfcTypeResource, "ResourceOf"), std::make_pair(Type::IfcRelAssignsToResource, 6)));
48554859
}
48564860

4861+
void InitDerivedMap() {
4862+
{std::set<int> idxs; idxs.insert(2); idxs.insert(3); idxs.insert(4); idxs.insert(5); derived_map[Type::IfcGeometricRepresentationSubContext] = idxs;}
4863+
{std::set<int> idxs; idxs.insert(3); derived_map[Type::IfcMirroredProfileDef] = idxs;}
4864+
{std::set<int> idxs; idxs.insert(0); idxs.insert(1); derived_map[Type::IfcOrientedEdge] = idxs;}
4865+
{std::set<int> idxs; idxs.insert(0); derived_map[Type::IfcSIUnit] = idxs;}
4866+
}
4867+
48574868
int Type::GetAttributeIndex(Enum t, const std::string& a) {
48584869
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
48594870
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
@@ -4889,6 +4900,12 @@ bool Type::GetAttributeOptional(Enum t, unsigned char a) {
48894900
else return i->second->getArgumentOptional(a);
48904901
}
48914902

4903+
bool Type::GetAttributeDerived(Enum t, unsigned char a) {
4904+
if (derived_map.empty()) ::InitDerivedMap();
4905+
std::map<Type::Enum,std::set<int> >::const_iterator i = derived_map.find(t);
4906+
return i != derived_map.end() && i->second.find(a) != i->second.end();
4907+
}
4908+
48924909
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
48934910
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
48944911
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
@@ -4920,10 +4937,11 @@ Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
49204937
}
49214938

49224939
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
4923-
Type::Enum type = e->type();
4924-
if (type == Type::IfcGeometricRepresentationSubContext) { e->setArgumentDerived(2); e->setArgumentDerived(3); e->setArgumentDerived(4); e->setArgumentDerived(5); }
4925-
if (type == Type::IfcMirroredProfileDef) { e->setArgumentDerived(3); }
4926-
if (type == Type::IfcOrientedEdge) { e->setArgumentDerived(0); e->setArgumentDerived(1); }
4927-
if (type == Type::IfcSIUnit) { e->setArgumentDerived(0); }
4940+
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
4941+
if (i != derived_map.end()) {
4942+
for (std::set<int>::const_iterator it = i->second.begin(); it != i->second.end(); ++it) {
4943+
e->setArgumentDerived(*it);
4944+
}
4945+
}
49284946
}
49294947
#endif

src/ifcparse/Ifc4-rt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace Type {
4040
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
4141
const std::string& GetAttributeName(Enum t, unsigned char a);
4242
bool GetAttributeOptional(Enum t, unsigned char a);
43+
bool GetAttributeDerived(Enum t, unsigned char a);
4344
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
4445
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
4546
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);

src/ifcparse/IfcUntypedEntity.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ unsigned int IfcParse::IfcUntypedEntity::getArgumentCount() const {
5454
return IfcSchema::Type::GetAttributeCount(_type);
5555
}
5656
IfcUtil::ArgumentType IfcParse::IfcUntypedEntity::getArgumentType(unsigned int i) const {
57-
return IfcSchema::Type::GetAttributeType(_type,i);
57+
return IfcSchema::Type::GetAttributeDerived(_type, i)
58+
? IfcUtil::Argument_DERIVED
59+
: IfcSchema::Type::GetAttributeType(_type,i);
5860
}
5961
ArgumentPtr IfcParse::IfcUntypedEntity::getArgument(unsigned int i) const {
6062
return entity->getArgument(i);

src/ifcparse/IfcUtil.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ inline T* reinterpret_pointer_cast(F* from) {
5353

5454
namespace IfcUtil {
5555
enum ArgumentType {
56-
Argument_INT, Argument_BOOL, Argument_DOUBLE, Argument_STRING, Argument_VECTOR_INT, Argument_VECTOR_DOUBLE, Argument_VECTOR_STRING, Argument_ENTITY, Argument_ENTITY_LIST, Argument_ENTITY_LIST_LIST, Argument_ENUMERATION, Argument_UNKNOWN
56+
Argument_INT, Argument_BOOL, Argument_DOUBLE, Argument_STRING, Argument_VECTOR_INT, Argument_VECTOR_DOUBLE, Argument_VECTOR_STRING, Argument_ENTITY, Argument_ENTITY_LIST, Argument_ENTITY_LIST_LIST, Argument_ENUMERATION, Argument_DERIVED, Argument_UNKNOWN
5757
};
5858
}
5959

src/ifcwrap/IfcPython.i

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,15 @@
7676
}
7777
}
7878

79+
%typemap(out) IfcUtil::ArgumentType {
80+
const char* strs[] = {"INT", "BOOL", "DOUBLE", "STRING", "VECTOR_INT", "VECTOR_DOUBLE", "VECTOR_STRING", "ENTITY", "ENTITY_LIST", "ENTITY_LIST_LIST", "ENUMERATION", "DERIVED", "UNKNOWN"};
81+
$result = SWIG_Python_str_FromChar(strs[$1]);
82+
}
83+
7984
%typemap(out) std::pair<IfcUtil::ArgumentType,ArgumentPtr> {
8085
const Argument& arg = *($1.second);
8186
const IfcUtil::ArgumentType type = $1.first;
82-
if (arg.isNull()) {
87+
if (arg.isNull() || type == IfcUtil::Argument_DERIVED) {
8388
Py_INCREF(Py_None);
8489
$result = Py_None;
8590
} else {

src/ifcwrap/Interface.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ namespace IfcParse {
8585
void AddEntity(IfcUtil::IfcSchemaEntity e);
8686
IfcFile();
8787
~IfcFile();
88+
89+
std::vector<int> entity_names() const {
90+
std::vector<int> keys;
91+
keys.reserve(byid.size());
92+
for (MapEntityById::const_iterator it = byid.begin(); it != byid.end(); ++ it) {
93+
keys.push_back(it->first);
94+
}
95+
return keys;
96+
}
8897
};
8998

9099
IfcParse::IfcFile* open(const std::string& s) {

src/ifcwrap/ifc.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ def wrap_value(v):
3030
classes = list(map(type, v))
3131
if ifc_wrapper.entity_instance in classes: return list(map(wrap, v))
3232
return v
33+
def attribute_type(self, attr):
34+
attr_idx = attr if isinstance(attr, int) else self.wrapped_data.get_argument_index(attr)
35+
return self.wrapped_data.get_argument_type(attr_idx)
36+
def attribute_name(self, attr_idx):
37+
return self.wrapped_data.get_argument_name(attr_idx)
3338
def __setattr__(self, key, value):
3439
self[self.wrapped_data.get_argument_index(key)] = value
3540
def __getitem__(self, key):
36-
return entity_instance.wrap_value(self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name)))
41+
return entity_instance.wrap_value(self.wrapped_data.get_argument(key))
3742
def __setitem__(self, idx, value):
3843
self.wrapped_data.set_argument(idx, entity_instance.map_value(value))
3944
def __len__(self): return len(self.wrapped_data)
@@ -63,6 +68,8 @@ def by_type(self, type):
6368
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
6469
def write(self, fn):
6570
self.wrapped_data.write(fn)
71+
def __iter__(self):
72+
return iter(self[id] for id in self.wrapped_data.entity_names())
6673

6774

6875
class guid:

0 commit comments

Comments
 (0)