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

This commit is contained in:
Thomas Krijnen
2015-02-17 19:48:41 +00:00
parent def1328a91
commit ee87466521
27 changed files with 4161 additions and 2488 deletions
+5
View File
@@ -103,6 +103,11 @@ class Header:
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"); '
argument_type_function_body = argument_type_function_body_switch_stmt + argument_type_function_body_tail
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 ""
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"); '
argument_entity_function_body = argument_entity_function_body_switch_stmt + argument_entity_function_body_tail
constructor_arguments = ", ".join("%(full_type)s v%(index)d_%(name)s"%a for a in mapping.get_assignable_arguments(type))
@@ -32,7 +32,7 @@ class LateBoundImplementation:
entity_descriptors.append(templates.entity_descriptor % {
'type' : name,
'parent_statement' : '0',
'entity_descriptor_attributes' : templates.entity_descriptor_attribute % {
'entity_descriptor_attributes' : templates.entity_descriptor_attribute_without_entity % {
'name' : 'wrappedValue',
'optional' : 'false',
'type' : mapping.make_argument_type(mapping.schema.types[name].type)
@@ -49,12 +49,14 @@ class LateBoundImplementation:
entity_descriptor_attributes = []
for arg in constructor_arguments:
if not arg['is_inherited']:
tmpl = templates.entity_descriptor_attribute_enum if arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION' else templates.entity_descriptor_attribute
is_enumeration = arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION'
tmpl = templates.entity_descriptor_attribute_with_entity
entity_name = arg['argument_type'] if is_enumeration else arg['argument_entity'].split('::')[1]
entity_descriptor_attributes.append(tmpl % {
'name' : arg['name'],
'optional' : 'true' if arg['is_optional'] else 'false',
'type' : arg['argument_type_enum'],
'enum_type' : arg['argument_type']
'name' : arg['name'],
'optional' : 'true' if arg['is_optional'] else 'false',
'type' : arg['argument_type_enum'],
'entity_name': entity_name
})
emitted_entities.add(name)
+7
View File
@@ -66,6 +66,12 @@ class Mapping:
return self.is_array(self.schema.types[type].type.type)
else:
return False
def make_argument_entity(self, attr):
type = attr.type if hasattr(attr, 'type') else attr
while isinstance(type, nodes.AggregationType): type = type.type
if type in self.express_to_cpp_typemapping or isinstance(type, nodes.BinaryType): return "Type::UNDEFINED"
else: return "Type::%s" % type
def make_argument_type(self, attr):
def _make_argument_type(type):
@@ -191,6 +197,7 @@ class Mapping:
'is_derived' : attr.name in derived,
'is_templated_list' : self.is_templated_list(attr),
'argument_type_enum' : self.make_argument_type(attr),
'argument_entity' : self.make_argument_entity(attr),
'argument_type' : attr.type
} for i, attr in attrs if include(attr)]
+12 -15
View File
@@ -60,7 +60,7 @@ namespace %(schema_name)s {
namespace Type {
typedef enum {
%(types)s, ALL
%(types)s, UNDEFINED
} Enum;
Enum Parent(Enum v);
Enum FromString(const std::string& s);
@@ -88,12 +88,12 @@ namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
Enum GetAttributeEntity(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
@@ -211,6 +211,13 @@ ArgumentType Type::GetAttributeType(Enum t, unsigned char a) {
else return i->second->getArgumentType(a);
}
Type::Enum Type::GetAttributeEntity(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentEntity(a);
}
const std::string& Type::GetAttributeName(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
@@ -250,17 +257,6 @@ std::pair<Type::Enum, unsigned> Type::GetInverseAttribute(Enum t, const std::str
throw IfcException("Attribute not found");
}
Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else {
Type::Enum t = i->second->getArgumentEnumerationClass(a);
if ( t == Type::ALL ) throw IfcException("Not an enumeration");
else return t;
}
}
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
if (i != derived_map.end()) {
@@ -275,8 +271,8 @@ entity_descriptor = """ current = entity_descriptor_map[Type::%(type)s] = new
%(entity_descriptor_attributes)s"""
entity_descriptor_parent = "entity_descriptor_map.find(Type::%(type)s)->second"
entity_descriptor_attribute = ' current->add("%(name)s",%(optional)s,%(type)s);'
entity_descriptor_attribute_enum = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(enum_type)s);'
entity_descriptor_attribute_without_entity = ' current->add("%(name)s",%(optional)s,%(type)s);'
entity_descriptor_attribute_with_entity = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(entity_name)s);'
enumeration_descriptor = """ values.clear(); values.reserve(128);
%(enumeration_descriptor_values)s
@@ -329,6 +325,7 @@ class %(name)s %(superclass)s{
public:
%(attributes)s virtual unsigned int getArgumentCount() const { return %(argument_count)d; }
virtual IfcUtil::ArgumentType getArgumentType(unsigned int i) const {%(argument_type_function_body)s}
virtual Type::Enum getArgumentEntity(unsigned int i) const {%(argument_entity_function_body)s}
virtual const char* getArgumentName(unsigned int i) const {%(argument_name_function_body)s}
virtual Argument* getArgument(unsigned int i) const { return entity->getArgument(i); }
%(inverse)s bool is(Type::Enum v) const;
+2 -2
View File
@@ -100,8 +100,8 @@
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include "../ifcparse/IfcSIPrefix.h"
#include "../ifcgeom/IfcGeom.h"
#include "../ifcgeom/IfcGeomUtils.h"
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing builder;
@@ -1015,7 +1015,7 @@ std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn
}
if ( unit ) {
if ( unit->hasPrefix() ) {
value *= IfcGeom::Utils::UnitPrefixToValue(unit->Prefix());
value *= IfcParse::IfcSIPrefixToValue(unit->Prefix());
}
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
@@ -88,8 +88,14 @@ class file(object):
return entity_instance(self.wrapped_data.by_id(key))
elif isinstance(key, str):
return entity_instance(self.wrapped_data.by_guid(key))
def add(self, inst):
return entity_instance(self.wrapped_data.add(inst.wrapped_data))
def by_type(self, type):
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
def traverse(self, inst):
return [entity_instance(e) for e in self.wrapped_data.traverse(inst.wrapped_data)]
def remove(self, inst):
return self.wrapped_data.remove(inst.wrapped_data)
def __iter__(self):
return iter(self[id] for id in self.wrapped_data.entity_names())
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -38,12 +38,12 @@ namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
Enum GetAttributeEntity(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -38,12 +38,12 @@ namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
Enum GetAttributeEntity(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
+766
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -87,7 +87,7 @@ namespace IfcUtil {
public:
IfcEntityDescriptor(IfcSchema::Type::Enum type, IfcEntityDescriptor* parent)
: type(type), parent(parent) {}
void add(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type = IfcSchema::Type::ALL) {
void add(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type = IfcSchema::Type::UNDEFINED) {
arguments.push_back(IfcArgumentDescriptor(name, optional, argument_type, data_type));
}
unsigned getArgumentCount() const {
@@ -111,10 +111,10 @@ namespace IfcUtil {
? parent->getArgumentOptional(i)
: get_argument(i-a).optional;
}
IfcSchema::Type::Enum getArgumentEnumerationClass(unsigned i) const {
IfcSchema::Type::Enum getArgumentEntity(unsigned i) const {
const unsigned a = argument_start();
return i < a
? parent->getArgumentEnumerationClass(i)
? parent->getArgumentEntity(i)
: get_argument(i-a).data_type;
}
unsigned getArgumentIndex(const std::string& s) const {
+16 -1
View File
@@ -21,6 +21,7 @@
#define IFCFILE_H
#include <map>
#include <set>
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcSpfHeader.h"
@@ -38,6 +39,8 @@ public:
typedef std::map<unsigned int, unsigned int> offset_by_id_t;
typedef entity_by_id_t::const_iterator const_iterator;
private:
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
bool _create_latebound_entities;
entity_by_id_t byid;
@@ -46,12 +49,15 @@ private:
entity_by_guid_t byguid;
offset_by_id_t offsets;
entity_entity_map_t entity_file_map;
unsigned int lastId;
unsigned int MaxId;
IfcSpfHeader _header;
void setDefaultHeaderValues();
void traverse(IfcUtil::IfcBaseClass*, std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr list, int level, int max_level);
public:
IfcParse::IfcSpfLexer* tokens;
IfcParse::IfcSpfStream* stream;
@@ -96,6 +102,11 @@ public:
/// Returns the entity with the specified GlobalId
IfcSchema::IfcRoot* EntityByGuid(const std::string& guid);
/// Performs a depth-first traversal, returning all entity instance
/// attributes as a flat list. NB: includes the root instance specified
/// in the first function argument.
IfcEntityList::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level=-1);
bool Init(const std::string& fn);
bool Init(std::istream& fn, int len);
bool Init(void* data, int len);
@@ -105,15 +116,19 @@ public:
unsigned int FreshId() { return ++MaxId; }
void AddEntity(IfcUtil::IfcBaseClass* entity);
IfcUtil::IfcBaseClass* AddEntity(IfcUtil::IfcBaseClass* entity);
void AddEntities(IfcEntityList::ptr es);
void removeEntity(IfcUtil::IfcBaseClass* entity);
const IfcSpfHeader& header() const { return _header; }
IfcSpfHeader& header() { return _header; }
std::string createTimestamp() const;
bool create_latebound_entities() const { return _create_latebound_entities; }
std::pair<IfcSchema::IfcNamedUnit*, double> getUnit(IfcSchema::IfcUnitEnum::IfcUnitEnum);
};
}
+1 -1
View File
@@ -99,7 +99,7 @@ IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory
IfcSchema::IfcSIUnit* unit2a = new IfcSchema::IfcSIUnit(IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT,
boost::none, IfcSchema::IfcSIUnitName::IfcSIUnitName_RADIAN);
IfcSchema::IfcMeasureWithUnit* unit2b = new IfcSchema::IfcMeasureWithUnit(
new IfcWrite::IfcSelectHelper(0.017453293, IfcSchema::Type::IfcPlaneAngleMeasure), unit2a);
new IfcSchema::IfcPlaneAngleMeasure(0.017453293), unit2a);
IfcSchema::IfcConversionBasedUnit* unit2 = new IfcSchema::IfcConversionBasedUnit(dimexp,
IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT, "Degrees", unit2b);
+4 -1
View File
@@ -89,6 +89,9 @@ IfcUtil::ArgumentType IfcParse::IfcLateBoundEntity::getArgumentType(unsigned int
? IfcUtil::Argument_DERIVED
: IfcSchema::Type::GetAttributeType(_type,i);
}
IfcSchema::Type::Enum IfcParse::IfcLateBoundEntity::getArgumentEntity(unsigned int i) const {
return IfcSchema::Type::GetAttributeEntity(_type, i);
}
Argument* IfcParse::IfcLateBoundEntity::getArgument(unsigned int i) const {
return entity->getArgument(i);
}
@@ -134,7 +137,7 @@ void IfcParse::IfcLateBoundEntity::setArgument(unsigned int i, const std::string
if (arg_type == Argument_STRING) {
writable_entity()->setArgument(i,a);
} else if (arg_type == Argument_ENUMERATION) {
std::pair<const char*, int> enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEnumerationClass(_type, i), a);
std::pair<const char*, int> enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEntity(_type, i), a);
writable_entity()->setArgument(i, enum_data.second, enum_data.first);
} else invalid_argument(i,"STRING");
}
+1
View File
@@ -49,6 +49,7 @@ namespace IfcParse {
unsigned int id() const;
unsigned int getArgumentCount() const;
IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
IfcSchema::Type::Enum getArgumentEntity(unsigned int i) const;
Argument* getArgument(unsigned int i) const;
const char* getArgumentName(unsigned int i) const;
unsigned getArgumentIndex(const std::string& a) const;
+314 -54
View File
@@ -17,6 +17,7 @@
* *
********************************************************************************/
#include <set>
#include <algorithm>
#include <string>
#include <stdio.h>
@@ -35,6 +36,7 @@
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/IfcLateBoundEntity.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSIPrefix.h"
using namespace IfcParse;
@@ -804,12 +806,15 @@ IfcFile::IfcFile(bool create_latebound_entities)
bool IfcFile::Init(const std::string& fn) {
return IfcFile::Init(new IfcSpfStream(fn));
}
bool IfcFile::Init(std::istream& f, int len) {
return IfcFile::Init(new IfcSpfStream(f,len));
}
bool IfcFile::Init(void* data, int len) {
return IfcFile::Init(new IfcSpfStream(data,len));
}
bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
// Initialize a "C" locale for locale-independent
// number parsing. See comment above on line 41.
@@ -920,13 +925,142 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
Logger::Status("\rDone scanning file ");
return true;
}
void IfcFile::traverse(IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBaseClass*>& visited, IfcEntityList::ptr list, int level, int max_level) {
if (visited.find(instance) != visited.end()) {
return;
}
visited.insert(instance);
list->push(instance);
if (level >= max_level && max_level > 0) return;
for (unsigned i = 0; i < instance->getArgumentCount(); ++i) {
Argument* arg = instance->getArgument(i);
if (arg->type() == IfcUtil::Argument_ENTITY) {
traverse(*arg, visited, list, level + 1, max_level);
} else if (arg->type() == IfcUtil::Argument_ENTITY_LIST) {
IfcEntityList::ptr entity_list_attribute = *arg;
for (IfcEntityList::it it = entity_list_attribute->begin(); it != entity_list_attribute->end(); ++it) {
traverse(*it, visited, list, level + 1, max_level);
}
} else if (arg->type() == IfcUtil::Argument_ENTITY_LIST_LIST) {
IfcEntityListList::ptr entity_list_attribute = *arg;
for (IfcEntityListList::outer_it it = entity_list_attribute->begin(); it != entity_list_attribute->end(); ++it) {
for (IfcEntityListList::inner_it jt = it->begin(); jt != it->end(); ++jt) {
traverse(*jt, visited, list, level + 1, max_level);
}
}
}
}
}
IfcEntityList::ptr IfcFile::traverse(IfcUtil::IfcBaseClass* instance, int max_level) {
std::set<IfcUtil::IfcBaseClass*> visited;
IfcEntityList::ptr return_value(new IfcEntityList);
traverse(instance, visited, return_value, 0, max_level);
return return_value;
}
void IfcFile::AddEntities(IfcEntityList::ptr es) {
for( IfcEntityList::it i = es->begin(); i != es->end(); ++ i ) {
AddEntity(*i);
}
}
void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
if ( entity->is(IfcSchema::Type::IfcRoot) ) {
IfcUtil::IfcBaseClass* IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
// If this instance has been inserted before, return
// a reference to the copy that was created from it.
entity_entity_map_t::iterator it = entity_file_map.find(entity);
if (it != entity_file_map.end()) {
return it->second;
}
// Obtain all forward references by a depth-first
// traversal and add them to the file.
{ IfcEntityList::ptr entity_attributes = traverse(entity, 1);
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
if (*it != entity) {
entity_file_map.insert(entity_entity_map_t::value_type(*it, AddEntity(*it)));
}
} }
// See whether the instance is already part of a file
if (entity->entity->file != 0) {
if (entity->entity->file == this) {
// If it is part of this file
// nothing needs to be done.
return entity;
}
// An instance is being added from another file. A copy of the
// container and entity is created. The attribute references
// need to be updated to point to instances in this file.
IfcFile* other_file = entity->entity->file;
IfcWrite::IfcWritableEntity* we = new IfcWrite::IfcWritableEntity(entity->entity);
if (this->create_latebound_entities()) {
entity = new IfcLateBoundEntity(we);
} else {
entity = IfcSchema::SchemaEntity(we);
}
// In case an entity is added that contains geometry, the unit
// information needs to be accounted for for IfcLengthMeasures.
boost::optional<double> conversion_factor;
for (unsigned i = 0; i < we->getArgumentCount(); ++i) {
Argument* attr = we->getArgument(i);
IfcUtil::ArgumentType attr_type = attr->type();
if (attr_type == IfcUtil::Argument_ENTITY) {
we->setArgument(i, entity_file_map[*attr]);
} else if (attr_type == IfcUtil::Argument_ENTITY_LIST) {
IfcEntityList::ptr instances = *attr;
IfcEntityList::ptr new_instances(new IfcEntityList);
for (IfcEntityList::it it = instances->begin(); it != instances->end(); ++it) {
new_instances->push(entity_file_map[*it]);
}
we->setArgument(i, new_instances);
} else if (attr_type == IfcUtil::Argument_ENTITY_LIST_LIST) {
IfcEntityListList::ptr instances = *attr;
IfcEntityListList::ptr new_instances(new IfcEntityListList);
for (IfcEntityListList::outer_it it = instances->begin(); it != instances->end(); ++it) {
std::vector<IfcUtil::IfcBaseClass*> list;
for (IfcEntityListList::inner_it jt = it->begin(); jt != it->end(); ++jt) {
list.push_back(entity_file_map[*jt]);
}
new_instances->push(list);
}
we->setArgument(i, new_instances);
} else if (entity->getArgumentEntity(i) == IfcSchema::Type::IfcLengthMeasure ||
entity->getArgumentEntity(i) == IfcSchema::Type::IfcPositiveLengthMeasure)
{
if (!conversion_factor) {
conversion_factor = other_file->getUnit(IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT).second /
getUnit(IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT).second;
}
if (attr_type == IfcUtil::Argument_DOUBLE) {
double v = *attr;
v *= *conversion_factor;
we->setArgument(i, v);
} else if (attr_type == IfcUtil::Argument_VECTOR_DOUBLE) {
std::vector<double> v = *attr;
for (std::vector<double>::iterator it = v.begin(); it != v.end(); ++it) {
(*it) *= *conversion_factor;
}
we->setArgument(i, v);
}
}
}
// A new entity instance name is generated and
// the instance is pointed to this file.
we->file = this;
we->setId(FreshId());
}
// For subtypes of IfcRoot, the GUID mapping needs to be updated.
if (entity->is(IfcSchema::Type::IfcRoot)) {
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) entity;
try {
const std::string guid = ifc_root->GlobalId();
@@ -941,6 +1075,7 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
}
}
// The mapping by entity type is updated.
IfcSchema::Type::Enum ty = entity->type();
do {
IfcEntityList::ptr instances_by_type = EntitiesByType(ty);
@@ -953,92 +1088,181 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
} while ( ty > -1 );
int new_id = -1;
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
if ( entity->entity->isWritable() ) {
if ( ! entity->entity->file ) entity->entity->file = this;
if (entity->entity->isWritable() && !entity->entity->file) {
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
entity->entity->file = this;
new_id = entity->entity->isWritable()->setId();
} else {
// TODO: Detect and fix ENTITY_INSTANCE_NAME collisions
new_id = entity->entity->id();
}
if ( byid.find(new_id) != byid.end() ) {
if (byid.find(new_id) != byid.end()) {
// This should not happen
std::stringstream ss;
ss << "Overwriting entity with id " << new_id;
Logger::Message(Logger::LOG_WARNING,ss.str());
Logger::Message(Logger::LOG_WARNING, ss.str());
}
// The mapping by entity instance name is updated.
byid[new_id] = entity;
unsigned arg_count = entity->entity->getArgumentCount();
for (unsigned i = 0; i < arg_count; ++i) {
Argument* arg = entity->entity->getArgument(i);
// The mapping by reference is updated.
IfcEntityList::ptr entity_attributes = traverse(entity, 1);
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
try {
if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
unsigned entity_attribute_id = entity_attribute->entity->id();
IfcEntityList::ptr refs = EntitiesByReference(entity_attribute_id);
if (!refs) {
refs = IfcEntityList::ptr(new IfcEntityList);
byref[entity_attribute_id] = refs;
}
refs->push(entity);
}
} catch (IfcParse::IfcException&) {}
}
// Create a flat list of entity instances referenced by the instance that is being added
IfcEntityList::ptr entity_attributes(new IfcEntityList);
if (arg->type() == IfcUtil::Argument_ENTITY) {
IfcUtil::IfcBaseClass* entity_attribute = *arg;
entity_attributes->push(entity_attribute);
} else if (arg->type() == IfcUtil::Argument_ENTITY_LIST) {
IfcEntityList::ptr entity_list_attribute = *arg;
entity_attributes->push(entity_list_attribute);
} else if (arg->type() == IfcUtil::Argument_ENTITY_LIST_LIST) {
IfcEntityListList::ptr entity_list_attribute = *arg;
for (IfcEntityListList::outer_it it = entity_list_attribute->begin(); it != entity_list_attribute->end(); ++it) {
for (IfcEntityListList::inner_it jt = it->begin(); jt != it->end(); ++jt) {
entity_attributes->push(*jt);
return entity;
}
IfcWrite::IfcWritableEntity* make_writable(IfcUtil::IfcBaseClass* instance) {
if (instance->entity->isWritable()) {
return instance->entity->isWritable();
}
IfcWrite::IfcWritableEntity* return_value;
instance->entity = return_value = new IfcWrite::IfcWritableEntity(instance->entity);
return return_value;
}
void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
const unsigned id = entity->entity->id();
IfcUtil::IfcBaseClass* file_entity = EntityById(id);
// TODO: Create a set of weak relations. Inverse relations that do not dictate an
// instance to be retained. For example: when deleting an IfcRepresentation, the
// individual IfcRepresentationItems can not be deleted if an IfcStyledItem is
// related. Hence, the IfcRepresentationItem::StyledByItem relation could be
// characterized as weak.
std::set<IfcSchema::Type::Enum> weak_roots;
if (entity != file_entity) {
throw IfcParse::IfcException("Instance not part of this file");
}
std::set<IfcUtil::IfcBaseClass*> deletion_queue;
IfcEntityList::ptr references = EntitiesByReference(id);
// Alter entity instances with INVERSE relations to the entity being
// deleted. This is necessary to maintain a valid IFC file, because
// dangling references to it's entities name should be removed. At this
// moment, inversely related instances affected by the removal of the
// entity being deleted are not deleted themselves.
if (references) {
for (IfcEntityList::it it = references->begin(); it != references->end(); ++it) {
IfcUtil::IfcBaseEntity* related_instance = (IfcUtil::IfcBaseEntity*) *it;
for (unsigned i = 0; i < related_instance->getArgumentCount(); ++i) {
Argument* attr = related_instance->getArgument(i);
if (attr->isNull()) continue;
IfcUtil::ArgumentType attr_type = related_instance->getArgumentType(i);
switch(attr_type) {
case IfcUtil::Argument_ENTITY: {
IfcUtil::IfcBaseClass* instance_attribute = *attr;
if (instance_attribute == entity) {
make_writable(related_instance)->setArgument(i);
// deletion_queue.insert(related_instance);
} }
break;
case IfcUtil::Argument_ENTITY_LIST: {
IfcEntityList::ptr instance_list = *attr;
if (instance_list->contains(entity)) {
instance_list->remove(entity);
make_writable(related_instance)->setArgument(i, instance_list);
/* if (instance_list->size() == 0) {
deletion_queue.insert(related_instance);
} */
} }
break;
case IfcUtil::Argument_ENTITY_LIST_LIST: {
IfcEntityListList::ptr instance_list_list = *attr;
if (instance_list_list->contains(entity)) {
IfcEntityListList::ptr new_list(new IfcEntityListList);
for (IfcEntityListList::outer_it it = instance_list_list->begin(); it != instance_list_list->end(); ++it) {
std::vector<IfcUtil::IfcBaseClass*> instances = *it;
std::vector<IfcUtil::IfcBaseClass*>::const_iterator jt;
while ((jt = std::find(instances.begin(), instances.end(), entity)) != instances.end()) {
instances.erase(jt);
}
new_list->push(instances);
}
make_writable(related_instance)->setArgument(i, new_list);
/* if (new_list->totalSize() == 0) {
deletion_queue.insert(related_instance);
} */
} }
break;
default: break;
}
}
}
byref.erase(byref.find(id));
}
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
try {
if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
// At this point simple types are IfcSelectHelper instances
// which are not writable and do not have an instance name.
if (entity_attribute->entity->isWritable()) {
if ( ! entity_attribute->entity->file ) {
entity_attribute->entity->file = this;
}
entity_attribute->entity->isWritable()->setId();
}
unsigned entity_attribute_id = entity_attribute->entity->id();
IfcEntityList::ptr refs = EntitiesByReference(entity_attribute_id);
if (!refs) {
refs = IfcEntityList::ptr(new IfcEntityList);
byref[entity_attribute_id] = refs;
}
refs->push(entity);
}
} catch (IfcParse::IfcException&) {}
IfcEntityList::ptr entity_attributes = traverse(entity, 1);
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
if (entity_attribute == entity) continue;
EntitiesByReference(entity_attribute->entity->id())->remove(entity);
if (EntitiesByReference(entity_attribute->entity->id())->filtered(weak_roots)->size() == 0) {
deletion_queue.insert(entity_attribute);
}
}
if (entity->is(IfcSchema::Type::IfcRoot)) {
const std::string global_id = ((IfcSchema::IfcRoot*) entity)->GlobalId();
byguid.erase(byguid.find(global_id));
}
byid.erase(byid.find(id));
IfcEntityList::ptr instances_of_same_type = EntitiesByType(entity->type());
instances_of_same_type->remove(entity);
while (!deletion_queue.empty()) {
removeEntity(*deletion_queue.begin());
deletion_queue.erase(deletion_queue.begin());
}
delete entity->entity;
delete entity;
}
IfcEntityList::ptr IfcFile::EntitiesByType(IfcSchema::Type::Enum t) {
entities_by_type_t::const_iterator it = bytype.find(t);
return (it == bytype.end()) ? IfcEntityList::ptr() : it->second;
}
IfcEntityList::ptr IfcFile::EntitiesByType(const std::string& t) {
std::string ty = t;
for (std::string::iterator p = ty.begin(); p != ty.end(); ++p ) *p = toupper(*p);
return EntitiesByType(IfcSchema::Type::FromString(ty));
}
IfcEntityList::ptr IfcFile::EntitiesByReference(int t) {
entities_by_ref_t::const_iterator it = byref.find(t);
return (it == byref.end()) ? IfcEntityList::ptr() : it->second;
}
IfcUtil::IfcBaseClass* IfcFile::EntityById(int id) {
entity_by_id_t::const_iterator it = byid.find(id);
if ( it == byid.end() ) {
offset_by_id_t::const_iterator it2 = offsets.find(id);
if ( it2 == offsets.end() ) throw IfcException("Entity not found");
const unsigned int offset = (*it2).second;
Entity* e = new Entity(id,this,offset);
IfcUtil::IfcBaseClass* entity = IfcSchema::SchemaEntity(e);
byid[id] = entity;
return entity;
if (it == byid.end()) {
throw IfcException("Entity not found");
}
return it->second;
}
IfcSchema::IfcRoot* IfcFile::EntityByGuid(const std::string& guid) {
entity_by_guid_t::const_iterator it = byguid.find(guid);
if ( it == byguid.end() ) {
@@ -1065,6 +1289,7 @@ IfcFile::~IfcFile() {
IfcFile::entity_by_id_t::const_iterator IfcFile::begin() const {
return byid.begin();
}
IfcFile::entity_by_id_t::const_iterator IfcFile::end() const {
return byid.end();
}
@@ -1109,7 +1334,7 @@ IfcEntityList::ptr IfcFile::getInverse(int instance_id, IfcSchema::Type::Enum ty
if (!all) return l;
for(IfcEntityList::it it = all->begin(); it != all->end(); ++it) {
bool valid = type == IfcSchema::Type::ALL || (*it)->is(type);
bool valid = type == IfcSchema::Type::UNDEFINED || (*it)->is(type);
if (valid && attribute_index >= 0) {
Argument* arg = (*it)->entity->getArgument(attribute_index);
if (arg->type() == IfcUtil::Argument_ENTITY) {
@@ -1151,3 +1376,38 @@ void IfcFile::setDefaultHeaderValues() {
header().file_schema().schema_identifiers(schema_identifiers);
}
std::pair<IfcSchema::IfcNamedUnit*, double> IfcFile::getUnit(IfcSchema::IfcUnitEnum::IfcUnitEnum type) {
std::pair<IfcSchema::IfcNamedUnit*, double> return_value((IfcSchema::IfcNamedUnit*)0, 1.);
IfcSchema::IfcProject::list::ptr projects = EntitiesByType<IfcSchema::IfcProject>();
if (projects->size() == 1) {
IfcSchema::IfcProject* project = *projects->begin();
IfcEntityList::ptr units = project->UnitsInContext()->Units();
for (IfcEntityList::it it = units->begin(); it != units->end(); ++it) {
IfcSchema::IfcUnit* unit = *it;
if (unit->is(IfcSchema::Type::IfcNamedUnit)) {
IfcSchema::IfcNamedUnit* named_unit = (IfcSchema::IfcNamedUnit*) unit;
if (named_unit->UnitType() != type) {
continue;
}
IfcSchema::IfcSIUnit* unit = 0;
if (named_unit->is(IfcSchema::Type::IfcConversionBasedUnit)) {
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)named_unit;
IfcSchema::IfcMeasureWithUnit* mu = u->ConversionFactor();
return_value.second *= static_cast<double>(*mu->ValueComponent()->entity->getArgument(0));
return_value.first = named_unit;
if (mu->UnitComponent()->is(IfcSchema::Type::IfcSIUnit)) {
unit = (IfcSchema::IfcSIUnit*) mu->UnitComponent();
}
} else if (named_unit->is(IfcSchema::Type::IfcSIUnit)) {
return_value.first = unit = (IfcSchema::IfcSIUnit*) named_unit;
}
if (unit) {
if (unit->hasPrefix()) {
return_value.second *= IfcSIPrefixToValue(unit->Prefix());
}
}
}
}
}
return return_value;
}
@@ -16,12 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#include "IfcSIPrefix.h"
#include "../ifcparse/IfcParse.h"
#include "IfcGeomUtils.h"
double IfcGeom::Utils::UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v ) {
double IfcParse::IfcSIPrefixToValue(IfcSchema::IfcSIPrefix::IfcSIPrefix v) {
if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_EXA ) return 1.e18;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PETA ) return 1.e15;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_TERA ) return 1.e12;
@@ -38,5 +35,5 @@ double IfcGeom::Utils::UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PICO ) return 1.e-12;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_FEMTO ) return 1.e-15;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_ATTO ) return 1.e-18;
else return 1.f;
else return 1.;
}
@@ -17,14 +17,13 @@
* *
********************************************************************************/
#ifndef IFCGEOMUTILS_H
#define IFCGEOMUTILS_H
#ifndef IFCSIPREFIX
#define IFCSIPREFIX
namespace IfcGeom {
#include "../ifcparse/IfcParse.h"
namespace Utils {
double UnitPrefixToValue(IfcSchema::IfcSIPrefix::IfcSIPrefix v);
}
namespace IfcParse {
double IfcSIPrefixToValue(IfcSchema::IfcSIPrefix::IfcSIPrefix v);
}
#endif
+23
View File
@@ -41,6 +41,29 @@ IfcUtil::IfcBaseClass* IfcEntityList::operator[] (int i) {
bool IfcEntityList::contains(IfcUtil::IfcBaseClass* instance) const {
return std::find(ls.begin(), ls.end(), instance) != ls.end();
}
void IfcEntityList::remove(IfcUtil::IfcBaseClass* instance) {
std::vector<IfcUtil::IfcBaseClass*>::const_iterator it;
while ((it = std::find(ls.begin(), ls.end(), instance)) != ls.end()) {
ls.erase(it);
}
}
IfcEntityList::ptr IfcEntityList::filtered(const std::set<IfcSchema::Type::Enum>& entities) {
IfcEntityList::ptr return_value(new IfcEntityList);
for (it it = begin(); it != end(); ++it) {
bool contained = false;
for (std::set<IfcSchema::Type::Enum>::const_iterator jt = entities.begin(); jt != entities.end(); ++jt) {
if ((*it)->is(*jt)) {
contained = true;
break;
}
}
if (!contained) {
return_value->push(*it);
}
}
return return_value;
}
unsigned int IfcUtil::IfcBaseType::getArgumentCount() const { return 1; }
Argument* IfcUtil::IfcBaseType::getArgument(unsigned int i) const { return entity->getArgument(i); }
+33 -9
View File
@@ -20,6 +20,7 @@
#ifndef IFCUTIL_H
#define IFCUTIL_H
#include <set>
#include <string>
#include <vector>
#include <sstream>
@@ -66,22 +67,23 @@ namespace IfcUtil {
IfcAbstractEntity* entity;
virtual bool is(IfcSchema::Type::Enum v) const = 0;
virtual IfcSchema::Type::Enum type() const = 0;
};
class IfcBaseEntity : public IfcBaseClass {
public:
virtual unsigned int getArgumentCount() const = 0;
virtual ArgumentType getArgumentType(unsigned int i) const = 0;
virtual IfcSchema::Type::Enum getArgumentEntity(unsigned int i) const = 0;
virtual Argument* getArgument(unsigned int i) const = 0;
virtual const char* getArgumentName(unsigned int i) const = 0;
};
class IfcBaseEntity : public IfcBaseClass {
};
// TODO: Investigate whether these should be template classes instead
class IfcBaseType : public IfcBaseEntity {
public:
virtual unsigned int getArgumentCount() const;
virtual Argument* getArgument(unsigned int i) const;
virtual const char* getArgumentName(unsigned int i) const;
unsigned int getArgumentCount() const;
Argument* getArgument(unsigned int i) const;
const char* getArgumentName(unsigned int i) const;
IfcSchema::Type::Enum getArgumentEntity(unsigned int i) const { return IfcSchema::Type::UNDEFINED; }
};
}
@@ -103,10 +105,12 @@ public:
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
const bool all = U::Class() == IfcSchema::Type::ALL;
const bool all = U::Class() == IfcSchema::Type::UNDEFINED;
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->is(U::Class())) r->push((U*)*i);
return r;
}
void remove(IfcUtil::IfcBaseClass*);
IfcEntityList::ptr filtered(const std::set<IfcSchema::Type::Enum>& entities);
};
template <class T>
@@ -133,6 +137,12 @@ public:
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->is(U::Class())) r->push((U*)*i);
return r;
}
void remove(T* t) {
typename std::vector<T*>::const_iterator it;
while ((it = std::find(ls.begin(), ls.end(), t)) != ls.end()) {
ls.erase(it);
}
}
};
template <class T>
@@ -157,6 +167,13 @@ public:
outer_it begin() const { return ls.begin(); }
outer_it end() const { return ls.end(); }
int size() const { return ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += it->size();
}
return accum;
}
bool contains(IfcUtil::IfcBaseClass* instance) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<IfcUtil::IfcBaseClass*>& inner = *it;
@@ -192,7 +209,14 @@ public:
void push(const std::vector<T*>& t) {ls.push_back(t);}
outer_it begin() { return ls.begin(); }
outer_it end() { return ls.end(); }
unsigned int size() const { return (unsigned int) ls.size(); }
int size() const { return ls.size(); }
int totalSize() const {
int accum = 0;
for (outer_it it = begin(); it != end(); ++it) {
accum += it->size();
}
return accum;
}
bool contains(T* t) const {
for (outer_it it = begin(); it != end(); ++it) {
const std::vector<T*>& inner = *it;
-49
View File
@@ -341,55 +341,6 @@ IfcUtil::ArgumentType IfcWriteArgument::type() const {
return static_cast<IfcUtil::ArgumentType>(container.which());
}
IfcEntityList::ptr IfcSelectHelperEntity::getInverse(IfcSchema::Type::Enum, int) {throw IfcParse::IfcException("Invalid cast");}
std::string IfcSelectHelperEntity::datatype() const { return IfcSchema::Type::ToString(_type); }
Argument* IfcSelectHelperEntity::getArgument(unsigned int i) {
if ( i != 0 ) throw IfcParse::IfcException("Invalid cast");
return arg;
}
unsigned int IfcSelectHelperEntity::getArgumentCount() const { return 1; }
IfcSchema::Type::Enum IfcSelectHelperEntity::type() const { return _type; }
bool IfcSelectHelperEntity::is(IfcSchema::Type::Enum t) const { return _type == t; }
std::string IfcSelectHelperEntity::toString(bool upper) const {
std::stringstream ss;
std::string dt = datatype();
if ( upper ) {
for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
}
ss << dt << "(" << arg->toString(upper) << ")";
return ss.str();
}
unsigned int IfcSelectHelperEntity::id() { throw IfcParse::IfcException("Invalid cast"); }
IfcWrite::IfcWritableEntity* IfcSelectHelperEntity::isWritable() { throw IfcParse::IfcException("Invalid cast"); }
IfcSelectHelper::IfcSelectHelper(const std::string& v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(const char* const v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set<std::string>(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(int v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(double v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(bool v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
bool IfcSelectHelper::is(IfcSchema::Type::Enum t) const { return entity->is(t); }
IfcSchema::Type::Enum IfcSelectHelper::type() const { return entity->type(); }
EntityBuffer* EntityBuffer::i = 0;
EntityBuffer* EntityBuffer::instance() {
if ( ! i ) {
-37
View File
@@ -119,43 +119,6 @@ namespace IfcWrite {
IfcUtil::ArgumentType type() const;
};
/// An entity to help with passing of SELECT arguments that
/// consist of simple types, for example useful to initialize
/// a new IfcProperty.
/// Proper memory management is difficult for now, so beware.
class IfcSelectHelperEntity : public IfcAbstractEntity {
private:
IfcSchema::Type::Enum _type;
IfcWriteArgument* arg;
public:
// FIXME: Make this a non-pointer argument and implement a copy constructor
IfcSelectHelperEntity(IfcSchema::Type::Enum t, IfcWriteArgument* a) : _type(t), arg(a) {}
IfcEntityList::ptr getInverse(IfcSchema::Type::Enum type, int attribute_index);
std::string datatype() const;
Argument* getArgument(unsigned int i);
unsigned int getArgumentCount() const;
IfcSchema::Type::Enum type() const;
bool is(IfcSchema::Type::Enum t) const;
std::string toString(bool upper = false) const;
unsigned int id();
IfcWritableEntity* isWritable();
};
/// A helper class for passing of SELECT arguments that
/// consist of simple types, for example useful to initialize
/// a new IfcProperty.
/// Proper memory management is difficult for now, so beware.
class IfcSelectHelper : public IfcUtil::IfcBaseClass {
public:
IfcSelectHelper(const std::string& v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcText);
IfcSelectHelper(const char* const v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcText);
IfcSelectHelper(int v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcInteger);
IfcSelectHelper(double v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcReal);
IfcSelectHelper(bool v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcBoolean);
bool is(IfcSchema::Type::Enum t) const;
IfcSchema::Type::Enum type() const;
};
/// A helper class for the creation of IFC GlobalIds.
class IfcGuidHelper {
private:
+11 -2
View File
@@ -39,6 +39,9 @@ namespace IfcUtil {
%ignore IfcParse::IfcFile::EntityById;
%ignore IfcParse::IfcFile::EntityByGuid;
%ignore IfcParse::IfcFile::AddEntity;
%ignore IfcParse::IfcFile::removeEntity;
%ignore IfcParse::IfcFile::traverse(IfcUtil::IfcBaseClass*, int);
%ignore IfcParse::IfcFile::traverse(IfcUtil::IfcBaseClass*);
%ignore operator<<;
%ignore IfcParse::FileDescription::FileDescription;
@@ -182,8 +185,14 @@ namespace IfcUtil {
IfcParse::IfcLateBoundEntity* by_guid(const std::string& guid) {
return (IfcParse::IfcLateBoundEntity*) $self->EntityByGuid(guid);
}
void add(IfcParse::IfcLateBoundEntity* e) {
$self->AddEntity(e);
IfcParse::IfcLateBoundEntity* add(IfcParse::IfcLateBoundEntity* e) {
return (IfcParse::IfcLateBoundEntity*) $self->AddEntity(e);
}
void remove(IfcParse::IfcLateBoundEntity* e) {
$self->removeEntity(e);
}
IfcEntityList::ptr traverse(IfcParse::IfcLateBoundEntity* e, int max_level=-1) {
return $self->traverse(e, max_level);
}
void write(const std::string& fn) {
std::ofstream f(fn.c_str());