Skip to content

Commit ee87466

Browse files
committed
1) Implement a breadth-first traversal of forward references 2) implement entity instance deletion from a file 3) recursively copy entity instances to another file
1 parent def1328 commit ee87466

27 files changed

Lines changed: 4161 additions & 2488 deletions

src/ifcexpressparser/header.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ def write_inverse(attr):
103103
argument_type_function_body_tail = (" return %s::getArgumentType(i); "%type.supertypes[0]) if len(type.supertypes) == 1 else ' throw IfcParse::IfcException("argument out of range"); '
104104

105105
argument_type_function_body = argument_type_function_body_switch_stmt + argument_type_function_body_tail
106+
107+
argument_entity_function_body_switch_stmt = " switch (i) {%s}"%("".join(['case %d: return %s; '%(i+argument_start, mapping.make_argument_entity(attr)) for i, attr in enumerate(type.attributes)])) if len(type.attributes) else ""
108+
argument_entity_function_body_tail = (" return %s::getArgumentEntity(i); "%type.supertypes[0]) if len(type.supertypes) == 1 else ' throw IfcParse::IfcException("argument out of range"); '
109+
110+
argument_entity_function_body = argument_entity_function_body_switch_stmt + argument_entity_function_body_tail
106111

107112
constructor_arguments = ", ".join("%(full_type)s v%(index)d_%(name)s"%a for a in mapping.get_assignable_arguments(type))
108113

src/ifcexpressparser/latebound_implementation.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, mapping):
3232
entity_descriptors.append(templates.entity_descriptor % {
3333
'type' : name,
3434
'parent_statement' : '0',
35-
'entity_descriptor_attributes' : templates.entity_descriptor_attribute % {
35+
'entity_descriptor_attributes' : templates.entity_descriptor_attribute_without_entity % {
3636
'name' : 'wrappedValue',
3737
'optional' : 'false',
3838
'type' : mapping.make_argument_type(mapping.schema.types[name].type)
@@ -49,12 +49,14 @@ def __init__(self, mapping):
4949
entity_descriptor_attributes = []
5050
for arg in constructor_arguments:
5151
if not arg['is_inherited']:
52-
tmpl = templates.entity_descriptor_attribute_enum if arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION' else templates.entity_descriptor_attribute
52+
is_enumeration = arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION'
53+
tmpl = templates.entity_descriptor_attribute_with_entity
54+
entity_name = arg['argument_type'] if is_enumeration else arg['argument_entity'].split('::')[1]
5355
entity_descriptor_attributes.append(tmpl % {
54-
'name' : arg['name'],
55-
'optional' : 'true' if arg['is_optional'] else 'false',
56-
'type' : arg['argument_type_enum'],
57-
'enum_type' : arg['argument_type']
56+
'name' : arg['name'],
57+
'optional' : 'true' if arg['is_optional'] else 'false',
58+
'type' : arg['argument_type_enum'],
59+
'entity_name': entity_name
5860
})
5961

6062
emitted_entities.add(name)

src/ifcexpressparser/mapping.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ def is_array(self, type):
6666
return self.is_array(self.schema.types[type].type.type)
6767
else:
6868
return False
69+
70+
def make_argument_entity(self, attr):
71+
type = attr.type if hasattr(attr, 'type') else attr
72+
while isinstance(type, nodes.AggregationType): type = type.type
73+
if type in self.express_to_cpp_typemapping or isinstance(type, nodes.BinaryType): return "Type::UNDEFINED"
74+
else: return "Type::%s" % type
6975

7076
def make_argument_type(self, attr):
7177
def _make_argument_type(type):
@@ -191,6 +197,7 @@ def include(attr):
191197
'is_derived' : attr.name in derived,
192198
'is_templated_list' : self.is_templated_list(attr),
193199
'argument_type_enum' : self.make_argument_type(attr),
200+
'argument_entity' : self.make_argument_entity(attr),
194201
'argument_type' : attr.type
195202
} for i, attr in attrs if include(attr)]
196203

src/ifcexpressparser/templates.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
6161
namespace Type {
6262
typedef enum {
63-
%(types)s, ALL
63+
%(types)s, UNDEFINED
6464
} Enum;
6565
Enum Parent(Enum v);
6666
Enum FromString(const std::string& s);
@@ -88,12 +88,12 @@
8888
int GetAttributeCount(Enum t);
8989
int GetAttributeIndex(Enum t, const std::string& a);
9090
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
91+
Enum GetAttributeEntity(Enum t, unsigned char a);
9192
const std::string& GetAttributeName(Enum t, unsigned char a);
9293
bool GetAttributeOptional(Enum t, unsigned char a);
9394
bool GetAttributeDerived(Enum t, unsigned char a);
9495
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
9596
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
96-
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
9797
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
9898
}}
9999
@@ -211,6 +211,13 @@
211211
else return i->second->getArgumentType(a);
212212
}
213213
214+
Type::Enum Type::GetAttributeEntity(Enum t, unsigned char a) {
215+
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
216+
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
217+
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
218+
else return i->second->getArgumentEntity(a);
219+
}
220+
214221
const std::string& Type::GetAttributeName(Enum t, unsigned char a) {
215222
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
216223
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
@@ -250,17 +257,6 @@
250257
throw IfcException("Attribute not found");
251258
}
252259
253-
Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
254-
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
255-
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
256-
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
257-
else {
258-
Type::Enum t = i->second->getArgumentEnumerationClass(a);
259-
if ( t == Type::ALL ) throw IfcException("Not an enumeration");
260-
else return t;
261-
}
262-
}
263-
264260
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
265261
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
266262
if (i != derived_map.end()) {
@@ -275,8 +271,8 @@
275271
%(entity_descriptor_attributes)s"""
276272

277273
entity_descriptor_parent = "entity_descriptor_map.find(Type::%(type)s)->second"
278-
entity_descriptor_attribute = ' current->add("%(name)s",%(optional)s,%(type)s);'
279-
entity_descriptor_attribute_enum = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(enum_type)s);'
274+
entity_descriptor_attribute_without_entity = ' current->add("%(name)s",%(optional)s,%(type)s);'
275+
entity_descriptor_attribute_with_entity = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(entity_name)s);'
280276

281277
enumeration_descriptor = """ values.clear(); values.reserve(128);
282278
%(enumeration_descriptor_values)s
@@ -329,6 +325,7 @@ class %(name)s %(superclass)s{
329325
public:
330326
%(attributes)s virtual unsigned int getArgumentCount() const { return %(argument_count)d; }
331327
virtual IfcUtil::ArgumentType getArgumentType(unsigned int i) const {%(argument_type_function_body)s}
328+
virtual Type::Enum getArgumentEntity(unsigned int i) const {%(argument_entity_function_body)s}
332329
virtual const char* getArgumentName(unsigned int i) const {%(argument_name_function_body)s}
333330
virtual Argument* getArgument(unsigned int i) const { return entity->getArgument(i); }
334331
%(inverse)s bool is(Type::Enum v) const;

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@
100100
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
101101
#include <TopTools_ListIteratorOfListOfShape.hxx>
102102

103+
#include "../ifcparse/IfcSIPrefix.h"
103104
#include "../ifcgeom/IfcGeom.h"
104-
#include "../ifcgeom/IfcGeomUtils.h"
105105

106106
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
107107
BRepOffsetAPI_Sewing builder;
@@ -1015,7 +1015,7 @@ std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn
10151015
}
10161016
if ( unit ) {
10171017
if ( unit->hasPrefix() ) {
1018-
value *= IfcGeom::Utils::UnitPrefixToValue(unit->Prefix());
1018+
value *= IfcParse::IfcSIPrefixToValue(unit->Prefix());
10191019
}
10201020
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
10211021
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {

src/ifcopenshell-python/ifcopenshell/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,14 @@ def __getitem__(self, key):
8888
return entity_instance(self.wrapped_data.by_id(key))
8989
elif isinstance(key, str):
9090
return entity_instance(self.wrapped_data.by_guid(key))
91+
def add(self, inst):
92+
return entity_instance(self.wrapped_data.add(inst.wrapped_data))
9193
def by_type(self, type):
9294
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
95+
def traverse(self, inst):
96+
return [entity_instance(e) for e in self.wrapped_data.traverse(inst.wrapped_data)]
97+
def remove(self, inst):
98+
return self.wrapped_data.remove(inst.wrapped_data)
9399
def __iter__(self):
94100
return iter(self[id] for id in self.wrapped_data.entity_names())
95101

0 commit comments

Comments
 (0)