mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
Work on runtime representation of schema
This commit is contained in:
@@ -188,7 +188,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement<double>* o) {
|
||||
// Iterate over the decomposing element to find the parent IfcBuildingStorey
|
||||
decomposition_element::list::ptr decomposes = obdef->Decomposes();
|
||||
if (!decomposes->size()) {
|
||||
if (obdef->is(IfcSchema::Type::IfcElement)) {
|
||||
if (obdef->declaration().is(IfcSchema::Type::IfcElement)) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr containment = ((IfcSchema::IfcElement*)obdef)->ContainedInStructure();
|
||||
if (!containment->size()) {
|
||||
break;
|
||||
@@ -210,7 +210,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement<double>* o) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obdef->is(IfcSchema::Type::IfcBuildingStorey)) {
|
||||
if (obdef->declaration().is(IfcSchema::Type::IfcBuildingStorey)) {
|
||||
storey = static_cast<IfcSchema::IfcBuildingStorey*>(obdef);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,15 +39,15 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY_INSTANCE: {
|
||||
IfcUtil::IfcBaseClass* e = *argument;
|
||||
if (Type::IsSimple(e->type())) {
|
||||
if (Type::IsSimple(e->declaration().type())) {
|
||||
IfcUtil::IfcBaseType* f = (IfcUtil::IfcBaseType*) e;
|
||||
value = format_attribute(f->getArgument(0), f->getArgumentType(0));
|
||||
} else if (e->is(IfcSchema::Type::IfcSIUnit) || e->is(IfcSchema::Type::IfcConversionBasedUnit)) {
|
||||
value = format_attribute(f->data().getArgument(0), f->data().getArgument(0)->type());
|
||||
} else if (e->declaration().is(IfcSchema::Type::IfcSIUnit) || e->declaration().is(IfcSchema::Type::IfcConversionBasedUnit)) {
|
||||
// Some string concatenation to have a unit name as a XML attribute.
|
||||
|
||||
std::string unit_name;
|
||||
|
||||
if (e->is(IfcSchema::Type::IfcSIUnit)) {
|
||||
if (e->declaration().is(IfcSchema::Type::IfcSIUnit)) {
|
||||
IfcSchema::IfcSIUnit* unit = (IfcSchema::IfcSIUnit*) e;
|
||||
unit_name = IfcSchema::IfcSIUnitName::ToString(unit->Name());
|
||||
if (unit->hasPrefix()) {
|
||||
@@ -71,18 +71,20 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
||||
// over the entity attributes and writes them as xml attributes of the node.
|
||||
ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) {
|
||||
ptree child;
|
||||
const unsigned n = instance->getArgumentCount();
|
||||
const unsigned n = instance->data().getArgumentCount();
|
||||
std::vector<const IfcParse::entity::attribute*> attributes = instance->declaration().all_attributes();
|
||||
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
const Argument* argument = instance->getArgument(i);
|
||||
const Argument* argument = instance->data().getArgument(i);
|
||||
if (argument->isNull()) continue;
|
||||
|
||||
std::string argument_name = instance->getArgumentName(i);
|
||||
std::string argument_name = attributes[i]->name();
|
||||
std::map<std::string, std::string>::const_iterator argument_name_it;
|
||||
argument_name_it = argument_name_map.find(argument_name);
|
||||
if (argument_name_it != argument_name_map.end()) {
|
||||
argument_name = argument_name_it->second;
|
||||
}
|
||||
const IfcUtil::ArgumentType argument_type = instance->getArgumentType(i);
|
||||
const IfcUtil::ArgumentType argument_type = instance->data().getArgument(i)->type();
|
||||
|
||||
boost::optional<std::string> value;
|
||||
try {
|
||||
@@ -101,7 +103,7 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, boo
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree.add_child(Type::ToString(instance->type()), child);
|
||||
return tree.add_child(Type::ToString(instance->declaration().type()), child);
|
||||
}
|
||||
|
||||
// A function to be called recursively. Template specialization is used
|
||||
@@ -130,7 +132,7 @@ template <>
|
||||
void descend(IfcProduct* product, ptree& tree) {
|
||||
ptree& child = format_entity_instance(product, tree);
|
||||
|
||||
if (product->is(Type::IfcSpatialStructureElement)) {
|
||||
if (product->declaration().is(Type::IfcSpatialStructureElement)) {
|
||||
IfcSpatialStructureElement* structure = (IfcSpatialStructureElement*) product;
|
||||
|
||||
IfcProduct::list::ptr elements = get_related
|
||||
@@ -154,7 +156,7 @@ void descend(IfcProduct* product, ptree& tree) {
|
||||
|
||||
for (IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) {
|
||||
IfcObjectDefinition* ob = *it;
|
||||
if (ob->is(Type::IfcSpatialStructureElement)) {
|
||||
if (ob->declaration().is(Type::IfcSpatialStructureElement)) {
|
||||
descend((IfcProduct*)ob, child);
|
||||
} else {
|
||||
descend(ob, child);
|
||||
@@ -167,7 +169,7 @@ void descend(IfcProduct* product, ptree& tree) {
|
||||
|
||||
for (IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) {
|
||||
IfcPropertySetDefinition* pset = *it;
|
||||
if (pset->is(Type::IfcPropertySet)) {
|
||||
if (pset->declaration().is(Type::IfcPropertySet)) {
|
||||
format_entity_instance(pset, child, true);
|
||||
}
|
||||
}
|
||||
@@ -190,7 +192,7 @@ void descend(IfcProject* project, ptree& tree) {
|
||||
|
||||
for (IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) {
|
||||
IfcObjectDefinition* ob = *it;
|
||||
if (ob->is(Type::IfcSpatialStructureElement)) {
|
||||
if (ob->declaration().is(Type::IfcSpatialStructureElement)) {
|
||||
descend((IfcProduct*)ob, child);
|
||||
} else {
|
||||
descend(ob, child);
|
||||
@@ -202,7 +204,7 @@ void descend(IfcProject* project, ptree& tree) {
|
||||
void format_properties(IfcProperty::list::ptr properties, ptree& node) {
|
||||
for (IfcProperty::list::it it = properties->begin(); it != properties->end(); ++it) {
|
||||
IfcProperty* p = *it;
|
||||
if (p->is(Type::IfcComplexProperty)) {
|
||||
if (p->declaration().is(Type::IfcComplexProperty)) {
|
||||
IfcComplexProperty* complex = (IfcComplexProperty*) p;
|
||||
format_properties(complex->HasProperties(), node);
|
||||
} else {
|
||||
|
||||
@@ -204,16 +204,20 @@ class Implementation:
|
||||
|
||||
simple_type_impl.append(templates.simpletype_impl_comment % {'name': class_name})
|
||||
simple_type_impl.extend(map(compose, map(lambda x: (class_name, attr_type, superclass, "(IfcAbstractEntity*)0")+x, (
|
||||
('getArgumentType', templates.const_function, 'IfcUtil::ArgumentType', ('unsigned int i',), templates.simpletype_impl_argument_type ),
|
||||
('getArgument', templates.const_function, 'Argument*', ('unsigned int i',), templates.simpletype_impl_argument ),
|
||||
('is', templates.const_function, 'bool', ('Type::Enum v',), simpletype_impl_is ),
|
||||
('type', templates.const_function, 'Type::Enum', (), templates.simpletype_impl_type ),
|
||||
#('getArgumentType', templates.const_function, 'IfcUtil::ArgumentType', ('unsigned int i',), templates.simpletype_impl_argument_type ),
|
||||
#('getArgument', templates.const_function, 'Argument*', ('unsigned int i',), templates.simpletype_impl_argument ),
|
||||
#('is', templates.const_function, 'bool', ('Type::Enum v',), simpletype_impl_is ),
|
||||
#('type', templates.const_function, 'Type::Enum', (), templates.simpletype_impl_type ),
|
||||
('Class', templates.function, 'Type::Enum', (), templates.simpletype_impl_class ),
|
||||
('declaration', templates.const_function, 'const IfcParse::type_declaration&', (), templates.simpletype_impl_declaration ),
|
||||
('', constructor, '', ('IfcAbstractEntity* e',), templates.simpletype_impl_explicit_constructor),
|
||||
('', constructor, '', ("%s v" % type_str,), simpletype_impl_constructor ),
|
||||
('', templates.cast_function, type_str, (), simpletype_impl_cast )
|
||||
))))
|
||||
simple_type_impl.append('')
|
||||
|
||||
external_definitions = ["extern entity* %s_type;" % n for n in mapping.schema.entities.keys() ] + \
|
||||
["extern type_declaration* %s_type;" % n for n in mapping.schema.simpletypes.keys()]
|
||||
|
||||
self.str = templates.implementation % {
|
||||
'schema_name_upper' : mapping.schema.name.upper(),
|
||||
@@ -226,7 +230,8 @@ class Implementation:
|
||||
'simple_type_statement' : simple_type_statements,
|
||||
'parent_type_statements' : catnl(parent_type_statements),
|
||||
'entity_implementations' : catnl(entity_implementations),
|
||||
'simple_type_impl' : catnl(simple_type_impl)
|
||||
'simple_type_impl' : catnl(simple_type_impl),
|
||||
'external_definitions' : catnl(external_definitions)
|
||||
}
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
@@ -26,7 +26,10 @@ class SchemaClass:
|
||||
def __init__(self, mapping):
|
||||
|
||||
class UnmetDependenciesException(Exception): pass
|
||||
|
||||
|
||||
schema_name = mapping.schema.name
|
||||
declared_types = []
|
||||
|
||||
def get_declared_type(type, emitted_names=None):
|
||||
if isinstance(type, nodes.AggregationType):
|
||||
aggr_type = type.aggregate_type
|
||||
@@ -47,7 +50,22 @@ class SchemaClass:
|
||||
|
||||
self.schema_name = mapping.schema.name.capitalize()
|
||||
|
||||
statements = ['','#include "../ifcparse/IfcSchema.h"','','void populate() {']
|
||||
statements = ['',
|
||||
'#include "../ifcparse/IfcSchema.h"',
|
||||
'',
|
||||
'using namespace IfcParse;'
|
||||
'']
|
||||
|
||||
collections_by_type = (('entity', mapping.schema.entities ),
|
||||
('type_declaration', mapping.schema.simpletypes ),
|
||||
('select_type', mapping.schema.selects ),
|
||||
('enumeration_type', mapping.schema.enumerations))
|
||||
|
||||
for cpp_type, collection in collections_by_type:
|
||||
for name in collection.keys():
|
||||
statements.append('%(cpp_type)s* %(name)s_type = 0;' % locals())
|
||||
|
||||
statements.append('schema_definition* populate_schema() {')
|
||||
|
||||
emitted_types = set()
|
||||
while len(emitted_types) < len(mapping.schema.simpletypes):
|
||||
@@ -59,16 +77,19 @@ class SchemaClass:
|
||||
except UnmetDependenciesException:
|
||||
continue
|
||||
|
||||
statements.append(' declaration* %(name)s_type = new type_declaration("%(name)s", %(declared_type)s);' % locals())
|
||||
statements.append(' %(name)s_type = new type_declaration(IfcSchema::Type::%(name)s, %(declared_type)s);' % locals())
|
||||
emitted_types.add(name)
|
||||
|
||||
declared_types.append('%(name)s_type' % locals())
|
||||
|
||||
for name, enum in mapping.schema.enumerations.items():
|
||||
statements.append(' declaration* %(name)s_type;' % locals())
|
||||
statements.append(' {')
|
||||
statements.append(' std::vector<std::string> items; items.reserve(%d);' % len(enum.values))
|
||||
statements.extend(map(lambda v: ' items.push_back("%s");' % v, sorted(enum.values)))
|
||||
statements.append(' %(name)s_type = new enumeration_type("%(name)s", items);' % locals())
|
||||
statements.append(' %(name)s_type = new enumeration_type(IfcSchema::Type::%(name)s, items);' % locals())
|
||||
statements.append(' }')
|
||||
|
||||
declared_types.append('%(name)s_type' % locals())
|
||||
|
||||
emitted_entities = set()
|
||||
while len(emitted_entities) < len(mapping.schema.entities):
|
||||
@@ -76,8 +97,10 @@ class SchemaClass:
|
||||
if name in emitted_entities: continue
|
||||
if len(type.supertypes) == 0 or set(type.supertypes) < emitted_entities:
|
||||
supertype = '0' if len(type.supertypes) == 0 else '%s_type' % type.supertypes[0]
|
||||
statements.append(' entity* %(name)s_type = new entity("%(name)s", %(supertype)s);' % locals())
|
||||
statements.append(' %(name)s_type = new entity(IfcSchema::Type::%(name)s, %(supertype)s);' % locals())
|
||||
emitted_entities.add(name)
|
||||
|
||||
declared_types.append('%(name)s_type' % locals())
|
||||
|
||||
emmited = emitted_types | emitted_entities | set(mapping.schema.enumerations.keys())
|
||||
|
||||
@@ -86,15 +109,18 @@ class SchemaClass:
|
||||
for name, type in mapping.schema.selects.items():
|
||||
if name in emitted_selects: continue
|
||||
if set(type.values) < emmited:
|
||||
statements.append(' declaration* %(name)s_type;' % locals())
|
||||
statements.append(' {')
|
||||
statements.append(' std::vector<const declaration*> items; items.reserve(%d);' % len(type.values))
|
||||
statements.extend(map(lambda v: ' items.push_back(%s_type);' % v, sorted(type.values)))
|
||||
statements.append(' %(name)s_type = new select_type("%(name)s", items);' % locals())
|
||||
statements.append(' %(name)s_type = new select_type(IfcSchema::Type::%(name)s, items);' % locals())
|
||||
statements.append(' }')
|
||||
emitted_selects.add(name)
|
||||
emmited.add(name)
|
||||
|
||||
declared_types.append('%(name)s_type' % locals())
|
||||
|
||||
num_declarations = len(declared_types)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
derived = set(mapping.derived_in_supertype(type))
|
||||
attribute_names = list(map(operator.attrgetter('name'), mapping.arguments(type)))
|
||||
@@ -109,8 +135,22 @@ class SchemaClass:
|
||||
statements.append(' ' + " ".join(map(lambda b: 'derived.push_back(%s);' % str(b in derived).lower(), attribute_names)))
|
||||
statements.append(' %(name)s_type->set_attributes(attributes, derived);' % locals())
|
||||
statements.append(' }')
|
||||
|
||||
statements.extend(('}','',''))
|
||||
|
||||
statements.append('')
|
||||
statements.append(' std::vector<const declaration*> declarations; declarations.reserve(%(num_declarations)d);' % locals())
|
||||
for type_name in declared_types:
|
||||
statements.append(' declarations.push_back(%(type_name)s);' % locals())
|
||||
|
||||
statements.append(' return new schema_definition("%(schema_name)s", declarations, true);' % locals())
|
||||
|
||||
statements.extend(('}',''))
|
||||
|
||||
statements.extend(('const schema_definition& get_schema() {',
|
||||
'',
|
||||
' static const schema_definition* s = populate_schema();',
|
||||
' return *s;',
|
||||
'}','',''))
|
||||
|
||||
self.str = "\n".join(statements)
|
||||
def __repr__(self):
|
||||
return self.str
|
||||
|
||||
@@ -28,9 +28,12 @@ header = """
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/%(schema_name)senum.h"
|
||||
|
||||
const IfcParse::schema_definition& get_schema();
|
||||
|
||||
#define IfcSchema %(schema_name)s
|
||||
|
||||
namespace %(schema_name)s {
|
||||
@@ -103,6 +106,7 @@ namespace Type {
|
||||
|
||||
implementation= """
|
||||
#include "../ifcparse/%(schema_name)s.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
#include "../ifcparse/IfcWritableEntity.h"
|
||||
@@ -111,6 +115,9 @@ using namespace %(schema_name)s;
|
||||
using namespace IfcParse;
|
||||
using namespace IfcWrite;
|
||||
|
||||
// External definitions
|
||||
%(external_definitions)s
|
||||
|
||||
IfcUtil::IfcBaseClass* %(schema_name)s::SchemaEntity(IfcAbstractEntity* e) {
|
||||
switch(e->type()) {
|
||||
%(schema_entity_statements)s
|
||||
@@ -326,10 +333,7 @@ derived_field_statement_attrs = 'idxs.insert(%d); '
|
||||
simpletype = """%(documentation)s
|
||||
class %(name)s : public %(superclass)s {
|
||||
public:
|
||||
virtual IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
|
||||
virtual Argument* getArgument(unsigned int i) const;
|
||||
bool is(Type::Enum v) const;
|
||||
Type::Enum type() const;
|
||||
virtual const IfcParse::type_declaration& declaration() const;
|
||||
static Type::Enum Class();
|
||||
explicit %(name)s (IfcAbstractEntity* e);
|
||||
%(name)s (%(type)s v);
|
||||
@@ -339,16 +343,17 @@ public:
|
||||
|
||||
simpletype_impl_comment = "// Function implementations for %(name)s"
|
||||
simpletype_impl_argument_type = "if (i == 0) { return %(attr_type)s; } else { throw IfcParse::IfcAttributeOutOfRangeException(\"Argument index out of range\"); }"
|
||||
simpletype_impl_argument = "return entity->getArgument(i);"
|
||||
simpletype_impl_argument = "return data_->getArgument(i);"
|
||||
simpletype_impl_is_with_supertype = "return v == Type::%(class_name)s || %(superclass)s::is(v);"
|
||||
simpletype_impl_is_without_supertype = "return v == %(class_name)s::Class();"
|
||||
simpletype_impl_type = "return Type::%(class_name)s;"
|
||||
simpletype_impl_class = "return Type::%(class_name)s;"
|
||||
simpletype_impl_explicit_constructor = "entity = e;"
|
||||
simpletype_impl_constructor = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v); entity = e;"
|
||||
simpletype_impl_constructor_templated = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v->generalize()); entity = e;"
|
||||
simpletype_impl_cast = "return *entity->getArgument(0);"
|
||||
simpletype_impl_cast_templated = "IfcEntityList::ptr es = *entity->getArgument(0); return es->as<%(underlying_type)s>();"
|
||||
simpletype_impl_explicit_constructor = "data_ = e;"
|
||||
simpletype_impl_constructor = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v); data_ = e;"
|
||||
simpletype_impl_constructor_templated = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v->generalize()); data_ = e;"
|
||||
simpletype_impl_cast = "return *data_->getArgument(0);"
|
||||
simpletype_impl_cast_templated = "IfcEntityList::ptr es = *data_->getArgument(0); return es->as<%(underlying_type)s>();"
|
||||
simpletype_impl_declaration = "return *%(class_name)s_type;"
|
||||
|
||||
select = """%(documentation)s
|
||||
typedef IfcUtil::IfcBaseClass %(name)s;
|
||||
@@ -365,13 +370,7 @@ const char* ToString(%(name)s v);
|
||||
entity = """%(documentation)s
|
||||
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;
|
||||
Type::Enum type() const;
|
||||
%(attributes)s %(inverse)s virtual const IfcParse::entity& declaration() const;
|
||||
static Type::Enum Class();
|
||||
%(name)s (IfcAbstractEntity* e);
|
||||
%(name)s (%(constructor_arguments)s);
|
||||
@@ -393,11 +392,12 @@ const char* %(name)s::ToString(%(name)s v) {
|
||||
"""
|
||||
|
||||
entity_implementation = """// Function implementations for %(name)s
|
||||
%(attributes)s%(inverse)sbool %(name)s::is(Type::Enum v) const { return v == Type::%(name)s%(parent_type_test)s; }
|
||||
Type::Enum %(name)s::type() const { return Type::%(name)s; }
|
||||
%(attributes)s
|
||||
%(inverse)s
|
||||
const IfcParse::entity& %(name)s::declaration() const { return *%(name)s_type; }
|
||||
Type::Enum %(name)s::Class() { return Type::%(name)s; }
|
||||
%(name)s::%(name)s(IfcAbstractEntity* e) : %(superclass)s { if (!e) return; if (!e->is(Type::%(name)s)) throw IfcException("Unable to find find keyword in schema"); entity = e; }
|
||||
%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass)s { IfcWritableEntity* e = new IfcWritableEntity(Class());%(constructor_implementation)s entity = e; EntityBuffer::Add(this); }
|
||||
%(name)s::%(name)s(IfcAbstractEntity* e) : %(superclass)s { if (!e) return; if (!e->is(Type::%(name)s)) throw IfcException("Unable to find find keyword in schema"); data_ = e; }
|
||||
%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass)s { IfcWritableEntity* e = new IfcWritableEntity(Class());%(constructor_implementation)s data_ = e; EntityBuffer::Add(this); }
|
||||
"""
|
||||
|
||||
optional_attribute_description = "/// Whether the optional attribute %s is defined for this %s"
|
||||
@@ -423,19 +423,19 @@ parent_type_stmt = ' if(v==%(name)s%(padding)s) { return %(parent)s; }'
|
||||
|
||||
parent_type_test = " || %s::is(v)"
|
||||
|
||||
optional_attr_stmt = "return !entity->getArgument(%(index)d)->isNull();"
|
||||
optional_attr_stmt = "return !data_->getArgument(%(index)d)->isNull();"
|
||||
|
||||
get_attr_stmt = "return *entity->getArgument(%(index)d);"
|
||||
get_attr_stmt_enum = "return %(type)s::FromString(*entity->getArgument(%(index)d));"
|
||||
get_attr_stmt_entity = "return (%(type)s)((IfcUtil::IfcBaseClass*)(*entity->getArgument(%(index)d)));"
|
||||
get_attr_stmt_array = "IfcEntityList::ptr es = *entity->getArgument(%(index)d); return es->as<%(list_instance_type)s>();"
|
||||
get_attr_stmt_nested_array = "IfcEntityListList::ptr es = *entity->getArgument(%(index)d); return es->as<%(list_instance_type)s>();"
|
||||
get_attr_stmt = "return *data_->getArgument(%(index)d);"
|
||||
get_attr_stmt_enum = "return %(type)s::FromString(*data_->getArgument(%(index)d));"
|
||||
get_attr_stmt_entity = "return (%(type)s)((IfcUtil::IfcBaseClass*)(*data_->getArgument(%(index)d)));"
|
||||
get_attr_stmt_array = "IfcEntityList::ptr es = *data_->getArgument(%(index)d); return es->as<%(list_instance_type)s>();"
|
||||
get_attr_stmt_nested_array = "IfcEntityListList::ptr es = *data_->getArgument(%(index)d); return es->as<%(list_instance_type)s>();"
|
||||
|
||||
get_inverse = "return entity->getInverse(Type::%(type)s, %(index)d)->as<%(type)s>();"
|
||||
get_inverse = "return data_->getInverse(Type::%(type)s, %(index)d)->as<%(type)s>();"
|
||||
|
||||
set_attr_stmt = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v);"
|
||||
set_attr_stmt_enum = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v,%(type)s::ToString(v));"
|
||||
set_attr_stmt_array = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v->generalize());"
|
||||
set_attr_stmt = "if ( ! data_->isWritable() ) { data_ = new IfcWritableEntity(data_); } ((IfcWritableEntity*)data_)->setArgument(%(index)d,v);"
|
||||
set_attr_stmt_enum = "if ( ! data_->isWritable() ) { data_ = new IfcWritableEntity(data_); } ((IfcWritableEntity*)data_)->setArgument(%(index)d,v,%(type)s::ToString(v));"
|
||||
set_attr_stmt_array = "if ( ! data_->isWritable() ) { data_ = new IfcWritableEntity(data_); } ((IfcWritableEntity*)data_)->setArgument(%(index)d,v->generalize());"
|
||||
|
||||
constructor_stmt = " e->setArgument(%(index)d,(%(name)s));"
|
||||
constructor_stmt_enum = " e->setArgument(%(index)d,%(name)s,%(type)s::ToString(%(name)s));"
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom/IfcGeomShapeType.h"
|
||||
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = cache.T.find(E->entity->id());\
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = cache.T.find(E->data().id());\
|
||||
if ( it != cache.T.end() ) { e = it->second; return true; }
|
||||
#define CACHE(T,E,e) cache.T[E->entity->id()] = e;
|
||||
#define CACHE(T,E,e) cache.T[E->data().id()] = e;
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
#ifdef USE_IFC4
|
||||
IfcEntityList::ptr style_assignments = (*jt)->Styles();
|
||||
for (IfcEntityList::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
if (!(*kt)->is(IfcSchema::Type::IfcPresentationStyleAssignment)) {
|
||||
if (!(*kt)->declaration().is(IfcSchema::Type::IfcPresentationStyleAssignment)) {
|
||||
continue;
|
||||
}
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = (IfcSchema::IfcPresentationStyleAssignment*) *kt;
|
||||
@@ -152,12 +152,12 @@ public:
|
||||
IfcEntityList::ptr styles = style_assignment->Styles();
|
||||
for (IfcEntityList::it lt = styles->begin(); lt != styles->end(); ++lt) {
|
||||
IfcUtil::IfcBaseClass* style = *lt;
|
||||
if (style->is(IfcSchema::Type::IfcSurfaceStyle)) {
|
||||
if (style->declaration().is(IfcSchema::Type::IfcSurfaceStyle)) {
|
||||
IfcSchema::IfcSurfaceStyle* surface_style = (IfcSchema::IfcSurfaceStyle*) style;
|
||||
if (surface_style->Side() != IfcSchema::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
|
||||
IfcEntityList::ptr styles_elements = surface_style->Styles();
|
||||
for (IfcEntityList::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
|
||||
if ((*mt)->is(T::Class())) {
|
||||
if ((*mt)->declaration().is(T::Class())) {
|
||||
return std::make_pair(surface_style, (T*) *mt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircle* l, Handle(Geom_Curve)& curve) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
if ( r < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l);
|
||||
return false;
|
||||
}
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement* placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
if (placement->declaration().is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
@@ -106,7 +106,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)
|
||||
double x = l->SemiAxis1() * getValue(GV_LENGTH_UNIT);
|
||||
double y = l->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
if (x < ALMOST_ZERO || y < ALMOST_ZERO) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l);
|
||||
return false;
|
||||
}
|
||||
// Open Cascade does not allow ellipses of which the minor radius
|
||||
@@ -116,7 +116,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)
|
||||
const bool rotated = y > x;
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement* placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
if (placement->declaration().is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
|
||||
@@ -102,7 +102,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
|
||||
Handle(Geom_Surface) face_surface;
|
||||
bool reversed_face_surface = false;
|
||||
const bool is_face_surface = l->is(IfcSchema::Type::IfcFaceSurface);
|
||||
const bool is_face_surface = l->declaration().is(IfcSchema::Type::IfcFaceSurface);
|
||||
|
||||
if (is_face_surface) {
|
||||
IfcSchema::IfcFaceSurface* fs = (IfcSchema::IfcFaceSurface*) l;
|
||||
@@ -124,7 +124,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
|
||||
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
|
||||
IfcSchema::IfcFaceBound* bound = *it;
|
||||
if (bound->is(IfcSchema::Type::IfcFaceOuterBound)) num_outer_bounds ++;
|
||||
if (bound->declaration().is(IfcSchema::Type::IfcFaceOuterBound)) num_outer_bounds ++;
|
||||
}
|
||||
|
||||
// The number of outer bounds should be one according to the schema. Also Open Cascade
|
||||
@@ -132,7 +132,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
// the face will still be processed as long as there are no holes. A compound of faces
|
||||
// is returned in that case.
|
||||
if (num_bounds > 1 && num_outer_bounds > 1 && num_bounds != num_outer_bounds) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid configuration of boundaries for:", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid configuration of boundaries for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
|
||||
bool same_sense = bound->Orientation();
|
||||
const bool is_interior =
|
||||
!bound->is(IfcSchema::Type::IfcFaceOuterBound) &&
|
||||
!bound->declaration().is(IfcSchema::Type::IfcFaceOuterBound) &&
|
||||
(num_bounds > 1) &&
|
||||
(num_outer_bounds < num_bounds);
|
||||
|
||||
@@ -168,7 +168,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
|
||||
/*
|
||||
The approach below does not result in a significant speed-up
|
||||
if (loop->is(IfcSchema::Type::IfcPolyLoop) && processed == 0 && face_surface.IsNull()) {
|
||||
if (loop->declaration().is(IfcSchema::Type::IfcPolyLoop) && processed == 0 && face_surface.IsNull()) {
|
||||
IfcSchema::IfcPolyLoop* polyloop = (IfcSchema::IfcPolyLoop*) loop;
|
||||
IfcSchema::IfcCartesianPoint::list::ptr points = polyloop->Polygon();
|
||||
|
||||
@@ -323,7 +323,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRoundedRectangleProfileDef* l,
|
||||
const double r = l->RoundingRadius() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || r < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleHollowProfileDef* l,
|
||||
const double r2 = fr2 ? l->InnerFilletRadius() * getValue(GV_LENGTH_UNIT) : 0.;
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrapeziumProfileDef* l, TopoDS
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x1 < ALMOST_ZERO || w < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Sh
|
||||
bool doFillet2 = doFillet1;
|
||||
double x2 = x1, dy2 = dy1, f2 = f1;
|
||||
|
||||
if (l->is(IfcSchema::Type::IfcAsymmetricIShapeProfileDef)) {
|
||||
if (l->declaration().is(IfcSchema::Type::IfcAsymmetricIShapeProfileDef)) {
|
||||
IfcSchema::IfcAsymmetricIShapeProfileDef* assym = (IfcSchema::IfcAsymmetricIShapeProfileDef*) l;
|
||||
x2 = assym->TopFlangeWidth() / 2. * getValue(GV_LENGTH_UNIT);
|
||||
doFillet2 = assym->hasTopFlangeFilletRadius();
|
||||
@@ -443,7 +443,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Sh
|
||||
}
|
||||
|
||||
if ( x1 < ALMOST_ZERO || x2 < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || dy1 < ALMOST_ZERO || dy2 < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcZShapeProfileDef* l, TopoDS_Sh
|
||||
}
|
||||
|
||||
if ( x == 0.0f || y == 0.0f || dx == 0.0f || dy == 0.0f ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCShapeProfileDef* l, TopoDS_Sh
|
||||
}
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcLShapeProfileDef* l, TopoDS_Sh
|
||||
}
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcLShapeProfileDef* l, TopoDS_Sh
|
||||
const double det = a1*b2 - a2*b1;
|
||||
|
||||
if (ALMOST_THE_SAME(det, 0.)) {
|
||||
Logger::Message(Logger::LOG_NOTICE, "Legs do not intersect for:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Legs do not intersect for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcUShapeProfileDef* l, TopoDS_Sh
|
||||
}
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -642,7 +642,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Sh
|
||||
const double webSlope = hasWebSlope ? (l->WebSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -690,7 +690,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Sh
|
||||
const double det = a1*b2 - a2*b1;
|
||||
|
||||
if (ALMOST_THE_SAME(det, 0.)) {
|
||||
Logger::Message(Logger::LOG_NOTICE, "Web and flange do not intersect for:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Web and flange do not intersect for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -713,7 +713,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Sh
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
if ( r == 0.0f ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -737,7 +737,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleHollowProfileDef* l, Top
|
||||
const double t = l->WallThickness() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( r == 0.0f || t == 0.0f ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_S
|
||||
double ry = l->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( rx < ALMOST_ZERO || ry < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
||||
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
if ( fes->declaration().is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
|
||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||
gp_Trsf opening_trsf;
|
||||
@@ -190,7 +190,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||
TopoDS_Shape entity_shape;
|
||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
|
||||
entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
|
||||
} else {
|
||||
entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
|
||||
@@ -202,7 +202,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(it4->Shape(),opening_shape_solid);
|
||||
const gp_GTrsf& opening_shape_gtrsf = it4->Placement();
|
||||
if ( opening_shape_gtrsf.Form() == gp_Other ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to opening of:", entity);
|
||||
}
|
||||
const TopoDS_Shape& opening_shape = opening_shape_gtrsf.Form() == gp_Other
|
||||
? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape()
|
||||
@@ -212,7 +212,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
|
||||
opening_volume = shape_volume(opening_shape);
|
||||
if ( opening_volume <= ALMOST_ZERO )
|
||||
Logger::Message(Logger::LOG_WARNING,"Empty opening for:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Empty opening for:", entity);
|
||||
original_shape_volume = shape_volume(entity_shape);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
// Add the original in case subtraction fails
|
||||
builder.Add(compound, exp.Current());
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to process subtraction:", entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
fix.Perform();
|
||||
brep_cut_result = fix.Shape();
|
||||
} catch (...) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Shape healing failed on opening subtraction result", entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Shape healing failed on opening subtraction result", entity);
|
||||
}
|
||||
|
||||
BRepCheck_Analyzer analyser(brep_cut_result);
|
||||
@@ -274,13 +274,13 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
const double volume_after_subtraction = shape_volume(entity_shape);
|
||||
|
||||
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
|
||||
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Subtraction yields unchanged volume:", entity);
|
||||
}
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR,"Invalid result from subtraction:",entity->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid result from subtraction:", entity);
|
||||
}
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to process subtraction:", entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
||||
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
if ( fes->declaration().is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
|
||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||
gp_Trsf opening_trsf;
|
||||
@@ -339,7 +339,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||
TopoDS_Shape entity_shape;
|
||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
|
||||
entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
|
||||
} else {
|
||||
entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
|
||||
@@ -360,7 +360,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
// Apparently processing the boolean operation failed or resulted in an invalid result
|
||||
// in which case the original shape without the subtractions is returned instead
|
||||
// we try convert the openings in the original way, one by one.
|
||||
Logger::Message(Logger::LOG_WARNING,"Subtracting combined openings compound failed:",entity->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Subtracting combined openings compound failed:", entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -855,7 +855,7 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
try {
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object->entity->id();
|
||||
parent_id = parent_object->data().id();
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
@@ -870,12 +870,12 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
// Note that openings for IfcOpeningElements are not processed
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
||||
if ( product->is(IfcSchema::Type::IfcElement) && !product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
if ( product->declaration().is(IfcSchema::Type::IfcElement) && !product->declaration().is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
if ( product->declaration().is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)product;
|
||||
#ifdef USE_IFC4
|
||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
||||
@@ -885,14 +885,14 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#endif
|
||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
||||
if ( obdef->declaration().is(IfcSchema::Type::IfcElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
||||
const std::string product_type = IfcSchema::Type::ToString(product->declaration().type());
|
||||
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
||||
|
||||
if ( !settings.disable_opening_subtractions() && openings && openings->size() ) {
|
||||
@@ -908,7 +908,7 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
convert_openings(product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Error processing openings for:", product);
|
||||
}
|
||||
if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
@@ -916,15 +916,15 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
}
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), opened_shapes);
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->data().id(), opened_shapes);
|
||||
} else if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), shapes);
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->data().id(), shapes);
|
||||
} else {
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), shapes);
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation->data().id(), shapes);
|
||||
}
|
||||
|
||||
std::string context_string = "";
|
||||
@@ -935,7 +935,7 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
||||
}
|
||||
|
||||
return new BRepElement<P>(
|
||||
product->entity->id(),
|
||||
product->data().id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
@@ -950,14 +950,14 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem
|
||||
IfcSchema::IfcObjectDefinition* parent = 0;
|
||||
|
||||
// In case of an opening element, parent to the RelatingBuildingElement
|
||||
if ( product->is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
if ( product->declaration().is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)product;
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
|
||||
if ( voids->size() ) {
|
||||
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
|
||||
parent = ifc_void->RelatingBuildingElement();
|
||||
}
|
||||
} else if ( product->is(IfcSchema::Type::IfcElement ) ) {
|
||||
} else if ( product->declaration().is(IfcSchema::Type::IfcElement ) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||
// Incase of a RelatedBuildingElement parent to the opening element
|
||||
@@ -980,13 +980,13 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem
|
||||
}
|
||||
// Parent decompositions to the RelatingObject
|
||||
if (!parent) {
|
||||
IfcEntityList::ptr parents = product->entity->getInverse(IfcSchema::Type::IfcRelAggregates, -1);
|
||||
parents->push(product->entity->getInverse(IfcSchema::Type::IfcRelNests, -1));
|
||||
IfcEntityList::ptr parents = product->data().getInverse(IfcSchema::Type::IfcRelAggregates, -1);
|
||||
parents->push(product->data().getInverse(IfcSchema::Type::IfcRelNests, -1));
|
||||
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
|
||||
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef;
|
||||
#ifdef USE_IFC4
|
||||
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
if (decompose->declaration().is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
|
||||
} else {
|
||||
continue;
|
||||
@@ -1022,19 +1022,19 @@ std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn
|
||||
IfcUtil::IfcBaseClass* base = *it;
|
||||
IfcSchema::IfcSIUnit* unit = 0;
|
||||
double value = 1.f;
|
||||
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
if ( base->declaration().is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base;
|
||||
current_unit_name = u->Name();
|
||||
IfcSchema::IfcMeasureWithUnit* u2 = u->ConversionFactor();
|
||||
IfcSchema::IfcUnit* u3 = u2->UnitComponent();
|
||||
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
if ( u3->declaration().is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*) u3;
|
||||
}
|
||||
IfcSchema::IfcValue* v = u2->ValueComponent();
|
||||
// Quick hack to get the numeric value from an IfcValue:
|
||||
const double f = *v->entity->getArgument(0);
|
||||
const double f = *v->data().getArgument(0);
|
||||
value *= f;
|
||||
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
} else if ( base->declaration().is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*)base;
|
||||
}
|
||||
if ( unit ) {
|
||||
|
||||
@@ -282,21 +282,21 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
|
||||
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l->entity);
|
||||
if ( ! l->declaration().is(IfcSchema::Type::IfcLocalPlacement) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l);
|
||||
return false;
|
||||
}
|
||||
IfcSchema::IfcLocalPlacement* current = (IfcSchema::IfcLocalPlacement*)l;
|
||||
while (1) {
|
||||
gp_Trsf trsf2;
|
||||
IfcSchema::IfcAxis2Placement* relplacement = current->RelativePlacement();
|
||||
if ( relplacement->is(IfcSchema::Type::IfcAxis2Placement3D) ) {
|
||||
if ( relplacement->declaration().is(IfcSchema::Type::IfcAxis2Placement3D) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2);
|
||||
trsf.PreMultiply(trsf2);
|
||||
}
|
||||
if ( current->hasPlacementRelTo() ) {
|
||||
IfcSchema::IfcObjectPlacement* relto = current->PlacementRelTo();
|
||||
if ( relto->is(IfcSchema::Type::IfcLocalPlacement) )
|
||||
if ( relto->declaration().is(IfcSchema::Type::IfcLocalPlacement) )
|
||||
current = (IfcSchema::IfcLocalPlacement*)current->PlacementRelTo();
|
||||
else break;
|
||||
} else break;
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace IfcGeom {
|
||||
|
||||
for (it = contexts->begin(); it != contexts->end(); ++it) {
|
||||
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
||||
if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
if (context->declaration().is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
// Continue, as the list of subcontexts will be considered
|
||||
// by the parent's context inverse attributes.
|
||||
continue;
|
||||
@@ -197,7 +197,7 @@ namespace IfcGeom {
|
||||
if (filtered_contexts->size() == 0) {
|
||||
for (it = contexts->begin(); it != contexts->end(); ++it) {
|
||||
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
||||
if (!context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
if (!context->declaration().is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
filtered_contexts->push(context);
|
||||
}
|
||||
}
|
||||
@@ -306,7 +306,7 @@ namespace IfcGeom {
|
||||
IfcSchema::IfcProduct::list::ptr unfiltered_products(new IfcSchema::IfcProduct::list);
|
||||
|
||||
for ( IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
||||
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
||||
if ( (*it)->declaration().is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
||||
IfcSchema::IfcProductDefinitionShape* pds = (IfcSchema::IfcProductDefinitionShape*)*it;
|
||||
unfiltered_products->push(pds->ShapeOfProduct());
|
||||
} else {
|
||||
@@ -316,7 +316,7 @@ namespace IfcGeom {
|
||||
|
||||
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
|
||||
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
|
||||
unfiltered_products->push((*it)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>());
|
||||
unfiltered_products->push((*it)->data().getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>());
|
||||
}
|
||||
|
||||
// Filter the products based on the set of entities being included or excluded for
|
||||
@@ -324,7 +324,7 @@ namespace IfcGeom {
|
||||
for ( IfcSchema::IfcProduct::list::it it = unfiltered_products->begin(); it != unfiltered_products->end(); ++it ) {
|
||||
bool found = false;
|
||||
for (std::set<IfcSchema::Type::Enum>::const_iterator jt = entities_to_include_or_exclude.begin(); jt != entities_to_include_or_exclude.end(); ++jt) {
|
||||
if ((*it)->is(*jt)) {
|
||||
if ((*it)->declaration().is(*jt)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -398,7 +398,7 @@ namespace IfcGeom {
|
||||
try {
|
||||
const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id);
|
||||
instance_type = IfcSchema::Type::ToString(ifc_entity->type());
|
||||
if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) {
|
||||
if ( ifc_entity->declaration().is(IfcSchema::Type::IfcProduct) ) {
|
||||
IfcSchema::IfcProduct* ifc_product = (IfcSchema::IfcProduct*)ifc_entity;
|
||||
|
||||
product_guid = ifc_product->GlobalId();
|
||||
@@ -408,7 +408,7 @@ namespace IfcGeom {
|
||||
try {
|
||||
IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product);
|
||||
if (parent_object) {
|
||||
parent_id = parent_object->entity->id();
|
||||
parent_id = parent_object->data().id();
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, std::tr1::arra
|
||||
bool process_colour(IfcSchema::IfcColourOrFactor* colour_or_factor, std::tr1::array<double, 3>& rgb) {
|
||||
if (colour_or_factor == 0) {
|
||||
return false;
|
||||
} else if (colour_or_factor->is(IfcSchema::Type::IfcColourRgb)) {
|
||||
} else if (colour_or_factor->declaration().is(IfcSchema::Type::IfcColourRgb)) {
|
||||
return process_colour(static_cast<IfcSchema::IfcColourRgb*>(colour_or_factor), rgb);
|
||||
} else if (colour_or_factor->is(IfcSchema::Type::IfcNormalisedRatioMeasure)) {
|
||||
} else if (colour_or_factor->declaration().is(IfcSchema::Type::IfcNormalisedRatioMeasure)) {
|
||||
return process_colour(static_cast<IfcSchema::IfcNormalisedRatioMeasure*>(colour_or_factor), rgb);
|
||||
} else {
|
||||
return false;
|
||||
@@ -55,7 +55,7 @@ const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepr
|
||||
if (shading_styles.second == 0) {
|
||||
return 0;
|
||||
}
|
||||
int surface_style_id = shading_styles.first->entity->id();
|
||||
int surface_style_id = shading_styles.first->data().id();
|
||||
std::map<int,SurfaceStyle>::const_iterator it = cache.Style.find(surface_style_id);
|
||||
if (it != cache.Style.end()) {
|
||||
return &(it->second);
|
||||
@@ -70,7 +70,7 @@ const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepr
|
||||
if (process_colour(shading_styles.second->SurfaceColour(), rgb)) {
|
||||
surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
|
||||
}
|
||||
if (shading_styles.second->is(IfcSchema::Type::IfcSurfaceStyleRendering)) {
|
||||
if (shading_styles.second->declaration().is(IfcSchema::Type::IfcSurfaceStyleRendering)) {
|
||||
IfcSchema::IfcSurfaceStyleRendering* rendering_style = static_cast<IfcSchema::IfcSurfaceStyleRendering*>(shading_styles.second);
|
||||
if (rendering_style->hasDiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) {
|
||||
SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().get_value_or(SurfaceStyle::ColorComponent(1,1,1));
|
||||
@@ -87,12 +87,12 @@ const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepr
|
||||
}
|
||||
if (rendering_style->hasSpecularHighlight()) {
|
||||
IfcSchema::IfcSpecularHighlightSelect* highlight = rendering_style->SpecularHighlight();
|
||||
if (highlight->is(IfcSchema::Type::IfcSpecularRoughness)) {
|
||||
if (highlight->declaration().is(IfcSchema::Type::IfcSpecularRoughness)) {
|
||||
double roughness = *((IfcSchema::IfcSpecularRoughness*)highlight);
|
||||
if (roughness >= 1e-9) {
|
||||
surface_style.Specularity().reset(1.0 / roughness);
|
||||
}
|
||||
} else if (highlight->is(IfcSchema::Type::IfcSpecularExponent)) {
|
||||
} else if (highlight->declaration().is(IfcSchema::Type::IfcSpecularExponent)) {
|
||||
surface_style.Specularity().reset(*((IfcSchema::IfcSpecularExponent*)highlight));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,10 +148,8 @@ namespace IfcGeom {
|
||||
try {
|
||||
BRepMesh_IncrementalMesh(s, settings().deflection_tolerance());
|
||||
} catch(...) {
|
||||
|
||||
// TODO: Catch outside
|
||||
// Logger::Message(Logger::LOG_ERROR,"Failed to triangulate shape:",ifc_file->entityById(_id)->entity);
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to triangulate shape");
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -230,8 +230,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcR
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcHalfSpaceSolid* l, TopoDS_Shape& shape) {
|
||||
IfcSchema::IfcSurface* surface = l->BaseSurface();
|
||||
if ( ! surface->is(IfcSchema::Type::IfcPlane) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface->entity);
|
||||
if ( ! surface->declaration().is(IfcSchema::Type::IfcPlane) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface);
|
||||
return false;
|
||||
}
|
||||
gp_Pln pln;
|
||||
@@ -261,7 +261,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, Ifc
|
||||
for( IfcEntityList::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* shell_style = 0;
|
||||
if ((*it)->is(IfcSchema::Type::IfcRepresentationItem)) {
|
||||
if ((*it)->declaration().is(IfcSchema::Type::IfcRepresentationItem)) {
|
||||
shell_style = get_style((IfcSchema::IfcRepresentationItem*)*it);
|
||||
}
|
||||
if (convert_shape(*it,s)) {
|
||||
@@ -277,7 +277,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
TopoDS_Wire boundary_wire;
|
||||
IfcSchema::IfcBooleanOperand* operand1 = l->FirstOperand();
|
||||
IfcSchema::IfcBooleanOperand* operand2 = l->SecondOperand();
|
||||
bool is_halfspace = operand2->is(IfcSchema::Type::IfcHalfSpaceSolid);
|
||||
bool is_halfspace = operand2->declaration().is(IfcSchema::Type::IfcHalfSpaceSolid);
|
||||
|
||||
if ( shape_type(operand1) == ST_SHAPELIST ) {
|
||||
if (!(convert_shapes(operand1, items1) && flatten_shape_list(items1, s1, true))) {
|
||||
@@ -290,13 +290,13 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
{ TopoDS_Solid temp_solid;
|
||||
s1 = ensure_fit_for_subtraction(s1, temp_solid); }
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid representation item for boolean operation", operand1->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid representation item for boolean operation", operand1);
|
||||
return false;
|
||||
}
|
||||
|
||||
const double first_operand_volume = shape_volume(s1);
|
||||
if ( first_operand_volume <= ALMOST_ZERO )
|
||||
Logger::Message(Logger::LOG_WARNING,"Empty solid for:",l->FirstOperand()->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Empty solid for:", l->FirstOperand());
|
||||
|
||||
bool shape2_processed = false;
|
||||
if ( shape_type(operand2) == ST_SHAPELIST ) {
|
||||
@@ -308,19 +308,19 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
s2 = ensure_fit_for_subtraction(s2, temp_solid);
|
||||
}
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid representation item for boolean operation", operand2->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid representation item for boolean operation", operand2);
|
||||
}
|
||||
|
||||
if (!shape2_processed) {
|
||||
shape = s1;
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert SecondOperand of:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to convert SecondOperand of:", l);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_halfspace) {
|
||||
const double second_operand_volume = shape_volume(s2);
|
||||
if ( second_operand_volume <= ALMOST_ZERO )
|
||||
Logger::Message(Logger::LOG_WARNING,"Empty solid for:",operand2->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Empty solid for:", operand2);
|
||||
}
|
||||
|
||||
const IfcSchema::IfcBooleanOperator::IfcBooleanOperator op = l->Operator();
|
||||
@@ -337,7 +337,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
fix.Perform();
|
||||
result = fix.Shape();
|
||||
} catch (...) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Shape healing failed on boolean result", l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Shape healing failed on boolean result", l);
|
||||
}
|
||||
|
||||
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
|
||||
@@ -350,9 +350,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
if ( valid_cut ) {
|
||||
const double volume_after_subtraction = shape_volume(shape);
|
||||
if ( ALMOST_THE_SAME(first_operand_volume,volume_after_subtraction) )
|
||||
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Subtraction yields unchanged volume:", l);
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to process subtraction:", l);
|
||||
shape = s1;
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh
|
||||
builder.Add(face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_WARNING,"Invalid face:",(*it)->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Invalid face:", *it);
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
@@ -438,7 +438,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh
|
||||
}
|
||||
} catch(...) {}
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_WARNING,"Failed to sew faceset:",l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l);
|
||||
}
|
||||
}
|
||||
if (!valid_shell) {
|
||||
@@ -455,7 +455,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh
|
||||
builder.Add(compound,face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_WARNING,"Invalid face:",(*it)->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Invalid face:", *it);
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
@@ -467,16 +467,16 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentationShapeItems& shapes) {
|
||||
gp_GTrsf gtrsf;
|
||||
IfcSchema::IfcCartesianTransformationOperator* transform = l->MappingTarget();
|
||||
if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
||||
if ( transform->declaration().is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3DnonUniform*)transform,gtrsf);
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity);
|
||||
} else if ( transform->declaration().is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform);
|
||||
return false;
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) {
|
||||
} else if ( transform->declaration().is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) {
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf);
|
||||
gtrsf = trsf;
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) {
|
||||
} else if ( transform->declaration().is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) {
|
||||
gp_Trsf2d trsf_2d;
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator2D*)transform,trsf_2d);
|
||||
gtrsf = (gp_Trsf) trsf_2d;
|
||||
@@ -484,7 +484,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentati
|
||||
IfcSchema::IfcRepresentationMap* map = l->MappingSource();
|
||||
IfcSchema::IfcAxis2Placement* placement = map->MappingOrigin();
|
||||
gp_Trsf trsf;
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
if (placement->declaration().is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf_2d;
|
||||
@@ -531,11 +531,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresenta
|
||||
if (convert_shape(element, s)) {
|
||||
part_succes = true;
|
||||
const IfcGeom::SurfaceStyle* style = 0;
|
||||
if (element->is(IfcSchema::Type::IfcPoint)) {
|
||||
if (element->declaration().is(IfcSchema::Type::IfcPoint)) {
|
||||
style = get_style((IfcSchema::IfcPoint*) element);
|
||||
} else if (element->is(IfcSchema::Type::IfcCurve)) {
|
||||
} else if (element->declaration().is(IfcSchema::Type::IfcCurve)) {
|
||||
style = get_style((IfcSchema::IfcCurve*) element);
|
||||
} else if (element->is(IfcSchema::Type::IfcSurface)) {
|
||||
} else if (element->declaration().is(IfcSchema::Type::IfcSurface)) {
|
||||
style = get_style((IfcSchema::IfcSurface*) element);
|
||||
}
|
||||
shapes.push_back(IfcRepresentationShapeItem(s, style ? style : parent_style));
|
||||
@@ -644,8 +644,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_S
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangularTrimmedSurface* l, TopoDS_Shape& face) {
|
||||
if (!l->BasisSurface()->is(IfcSchema::Type::IfcPlane)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", l->BasisSurface()->entity);
|
||||
if (!l->BasisSurface()->declaration().is(IfcSchema::Type::IfcPlane)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", l->BasisSurface());
|
||||
return false;
|
||||
}
|
||||
gp_Pln pln;
|
||||
@@ -663,8 +663,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l,
|
||||
TopoDS_Shape face;
|
||||
TopoDS_Wire wire, section;
|
||||
|
||||
if (!l->ReferenceSurface()->is(IfcSchema::Type::IfcPlane)) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Reference surface not supported", l->ReferenceSurface()->entity);
|
||||
if (!l->ReferenceSurface()->declaration().is(IfcSchema::Type::IfcPlane)) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Reference surface not supported", l->ReferenceSurface());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -689,7 +689,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l,
|
||||
for (TopExp_Explorer exp(wire, TopAbs_VERTEX); exp.More(); exp.Next()) {
|
||||
if (pln.Distance(BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))) > ALMOST_ZERO) {
|
||||
directrix_on_plane = false;
|
||||
Logger::Message(Logger::LOG_WARNING, "The Directrix does not lie on the ReferenceSurface", l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "The Directrix does not lie on the ReferenceSurface", l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -804,7 +804,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shap
|
||||
}
|
||||
|
||||
if (!is_valid) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to subtract inner radius void for:", l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to subtract inner radius void for:", l);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS
|
||||
for (std::vector< std::vector<double> >::const_iterator it = coordinates.begin(); it != coordinates.end(); ++it) {
|
||||
const std::vector<double>& coords = *it;
|
||||
if (coords.size() != 3) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on Coordinates", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on Coordinates", l);
|
||||
return false;
|
||||
}
|
||||
points.push_back(gp_Pnt(coords[0] * getValue(GV_LENGTH_UNIT),
|
||||
@@ -849,7 +849,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS
|
||||
for(std::vector< std::vector<int> >::const_iterator it = indices.begin(); it != indices.end(); ++ it) {
|
||||
const std::vector<int>& tri = *it;
|
||||
if (tri.size() != 3) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on CoordIndex", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on CoordIndex", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -857,7 +857,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS
|
||||
const int max_index = *std::max_element(tri.begin(), tri.end());
|
||||
|
||||
if (min_index < 1 || max_index > points.size()) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Contents of CoordIndex out of bounds", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Contents of CoordIndex out of bounds", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -914,7 +914,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS
|
||||
}
|
||||
} catch(...) {}
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) {
|
||||
if ( getValue(GV_PLANEANGLE_UNIT)<0 ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Creating a composite curve without unit information:", l);
|
||||
|
||||
// Temporarily pretend we do have unit information
|
||||
setValue(GV_PLANEANGLE_UNIT,1.0);
|
||||
@@ -148,7 +148,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire
|
||||
IfcSchema::IfcCurve* curve = (*it)->ParentCurve();
|
||||
TopoDS_Wire wire2;
|
||||
if ( !convert_wire(curve,wire2) ) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert curve:",curve->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to convert curve:", curve);
|
||||
continue;
|
||||
}
|
||||
if ( ! (*it)->SameSense() ) wire2.Reverse();
|
||||
@@ -167,7 +167,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire
|
||||
w.Add(wire2);
|
||||
//last_vertex = w.Vertex();
|
||||
if ( w.Error() != BRepBuilderAPI_WireDone ) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to join curve segments:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to join curve segments:", l);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
IfcSchema::IfcCurve* basis_curve = l->BasisCurve();
|
||||
bool isConic = basis_curve->is(IfcSchema::Type::IfcConic);
|
||||
bool isConic = basis_curve->declaration().is(IfcSchema::Type::IfcConic);
|
||||
double parameterFactor = isConic ? getValue(GV_PLANEANGLE_UNIT) : getValue(GV_LENGTH_UNIT);
|
||||
Handle(Geom_Curve) curve;
|
||||
if ( !convert_curve(basis_curve,curve) ) return false;
|
||||
@@ -194,10 +194,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for ( IfcEntityList::it it = trims1->begin(); it != trims1->end(); it ++ ) {
|
||||
IfcUtil::IfcBaseClass* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
if ( i->declaration().is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
|
||||
has_pnts[sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
} else if ( i->declaration().is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcSchema::IfcParameterValue*)i);
|
||||
flts[sense_agreement] = value * parameterFactor;
|
||||
has_flts[sense_agreement] = true;
|
||||
@@ -205,10 +205,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
}
|
||||
for ( IfcEntityList::it it = trims2->begin(); it != trims2->end(); it ++ ) {
|
||||
IfcUtil::IfcBaseClass* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
if ( i->declaration().is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
|
||||
has_pnts[1-sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
} else if ( i->declaration().is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcSchema::IfcParameterValue*)i);
|
||||
flts[1-sense_agreement] = value * parameterFactor;
|
||||
has_flts[1-sense_agreement] = true;
|
||||
@@ -218,7 +218,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
bool trim_cartesian_failed = !trim_cartesian;
|
||||
if ( trim_cartesian ) {
|
||||
if ( pnts[0].Distance(pnts[1]) < getValue(GV_WIRE_CREATION_TOLERANCE) ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Skipping segment with length below tolerance level:", l);
|
||||
return false;
|
||||
}
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
@@ -230,7 +230,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
if ( ! e.IsDone() ) {
|
||||
BRepBuilderAPI_EdgeError err = e.Error();
|
||||
if ( err == BRepBuilderAPI_PointProjectionFailed ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Point projection failed for:",l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, "Point projection failed for:", l);
|
||||
trim_cartesian_failed = true;
|
||||
}
|
||||
} else {
|
||||
@@ -242,12 +242,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
||||
// is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because
|
||||
// the vector is normalised when passed to Geom_Line constructor the magnitude
|
||||
// needs to be factored in with the IfcParameterValue here.
|
||||
if ( basis_curve->is(IfcSchema::Type::IfcLine) ) {
|
||||
if ( basis_curve->declaration().is(IfcSchema::Type::IfcLine) ) {
|
||||
IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve);
|
||||
const double magnitude = line->Dir()->Magnitude();
|
||||
flts[0] *= magnitude; flts[1] *= magnitude;
|
||||
}
|
||||
if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) {
|
||||
if ( basis_curve->declaration().is(IfcSchema::Type::IfcEllipse) ) {
|
||||
IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
|
||||
double x = ellipse->SemiAxis1() * getValue(GV_LENGTH_UNIT);
|
||||
double y = ellipse->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
@@ -311,7 +311,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& resu
|
||||
// A loop should consist of at least three vertices
|
||||
int original_count = polygon.Length();
|
||||
if (original_count < 3) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -321,11 +321,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& resu
|
||||
int count = polygon.Length();
|
||||
if (original_count - count != 0) {
|
||||
std::stringstream ss; ss << (original_count - count) << " edges removed for:";
|
||||
Logger::Message(Logger::LOG_WARNING, ss.str(), l->entity);
|
||||
Logger::Message(Logger::LOG_WARNING, ss.str(), l);
|
||||
}
|
||||
|
||||
if (count < 3) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -346,8 +346,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryOpenProfileDef* l, To
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry();
|
||||
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry();
|
||||
if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity);
|
||||
if (!pnt1->declaration().is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->declaration().is(IfcSchema::Type::IfcCartesianPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& res
|
||||
// assumed that a topological wire can be crafted from it. After which an
|
||||
// attempt is made to reconstruct it from the individual curves and the vertices
|
||||
// of the IfcEdgeCurve.
|
||||
const bool is_bounded = l->EdgeGeometry()->is(IfcSchema::Type::IfcBoundedCurve);
|
||||
const bool is_bounded = l->EdgeGeometry()->declaration().is(IfcSchema::Type::IfcBoundedCurve);
|
||||
|
||||
if (!is_bounded && convert_curve(l->EdgeGeometry(), crv)) {
|
||||
mw.Add(BRepBuilderAPI_MakeEdge(crv, p1, p2));
|
||||
@@ -424,15 +424,15 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& resu
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdge* l, TopoDS_Wire& result) {
|
||||
if (!l->EdgeStart()->is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->is(IfcSchema::Type::IfcVertexPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l->entity);
|
||||
if (!l->EdgeStart()->declaration().is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->declaration().is(IfcSchema::Type::IfcVertexPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry();
|
||||
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry();
|
||||
if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity);
|
||||
if (!pnt1->declaration().is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->declaration().is(IfcSchema::Type::IfcCartesianPoint)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace IfcUtil;
|
||||
|
||||
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||
#include "IfcRegisterConvertShapes.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ IfcGeom::ShapeType IfcGeom::Kernel::shape_type(const IfcBaseClass* l) {
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
const unsigned int id = l->entity->id();
|
||||
const unsigned int id = l->data().id();
|
||||
bool success = false;
|
||||
bool processed = false;
|
||||
bool ignored = false;
|
||||
@@ -81,7 +81,7 @@ bool IfcGeom::Kernel::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
const char* const msg = processed
|
||||
? "Failed to convert:"
|
||||
: "No operation defined for:";
|
||||
Logger::Message(Logger::LOG_ERROR, msg, l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, msg, l);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@@ -92,18 +92,18 @@ bool IfcGeom::Kernel::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) {
|
||||
if (IfcGeom::Kernel::convert_curve(l, curve)) {
|
||||
return IfcGeom::Kernel::convert_curve_to_wire(curve, r);
|
||||
}
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert_face(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
#include "IfcRegisterConvertFace.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert_curve(const IfcBaseClass* l, Handle(Geom_Curve)& r) {
|
||||
#include "IfcRegisterConvertCurve.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
|
||||
return false;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CURVE(T) \
|
||||
if ( l->is(T::Class()) ) return convert((T*)l,r);
|
||||
if ( l->declaration().is(T::Class()) ) return convert(l->as<T>(), r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define FACE(T) \
|
||||
if ( l->is(T::Class()) ) return convert((T*)l,r);
|
||||
if ( l->declaration().is(T::Class()) ) return convert(l->as<T>(), r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define SHAPE(T) \
|
||||
if ( !processed && l->is(T::Class()) ) { \
|
||||
if ( !processed && l->declaration().is(T::Class()) ) { \
|
||||
processed = true; \
|
||||
try { \
|
||||
if ( convert((T*)l,r) ) { \
|
||||
if ( convert(l->as<T>(), r) ) { \
|
||||
success = true; \
|
||||
} \
|
||||
} catch(...) { } \
|
||||
if ( !success) { \
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to convert:", l); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define SHAPES(T) \
|
||||
if ( l->is(T::Class()) ) { \
|
||||
if ( l->declaration().is(T::Class()) ) { \
|
||||
try { \
|
||||
return convert((T*)l,r); \
|
||||
return convert(l->as<T>(), r); \
|
||||
} catch (...) { } \
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to convert:", l); \
|
||||
return false; \
|
||||
}
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define WIRE(T) \
|
||||
if ( l->is(T::Class()) ) return convert((T*)l,r);
|
||||
if ( l->declaration().is(T::Class()) ) return convert((T*)l,r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define SHAPES(T) \
|
||||
if ( l->is(T::Class()) ) return ST_SHAPELIST;
|
||||
if ( l->declaration().is(T::Class()) ) return ST_SHAPELIST;
|
||||
#define SHAPE(T) \
|
||||
if ( l->is(T::Class()) ) return ST_SHAPE;
|
||||
if ( l->declaration().is(T::Class()) ) return ST_SHAPE;
|
||||
#define WIRE(T) \
|
||||
if ( l->is(T::Class()) ) return ST_WIRE;
|
||||
if ( l->declaration().is(T::Class()) ) return ST_WIRE;
|
||||
#define FACE(T) \
|
||||
if ( l->is(T::Class()) ) return ST_FACE;
|
||||
if ( l->declaration().is(T::Class()) ) return ST_FACE;
|
||||
#define CURVE(T) \
|
||||
if ( l->is(T::Class()) ) return ST_CURVE;
|
||||
if ( l->declaration().is(T::Class()) ) return ST_CURVE;
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
+2951
-1191
File diff suppressed because it is too large
Load Diff
+7860
-6785
File diff suppressed because it is too large
Load Diff
+836
-5102
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,8 @@ public:
|
||||
private:
|
||||
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
||||
|
||||
const schema_definition* schema_;
|
||||
|
||||
bool _create_latebound_entities;
|
||||
|
||||
entity_by_id_t byid;
|
||||
@@ -131,6 +133,8 @@ public:
|
||||
bool create_latebound_entities() const { return _create_latebound_entities; }
|
||||
|
||||
std::pair<IfcSchema::IfcNamedUnit*, double> getUnit(IfcSchema::IfcUnitEnum::IfcUnitEnum);
|
||||
|
||||
const schema_definition* schema() const { return schema_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory
|
||||
|
||||
void IfcHierarchyHelper::relatePlacements(IfcSchema::IfcProduct* parent, IfcSchema::IfcProduct* product) {
|
||||
IfcSchema::IfcObjectPlacement* place = product->hasObjectPlacement() ? product->ObjectPlacement() : 0;
|
||||
if (place && place->is(IfcSchema::Type::IfcLocalPlacement)) {
|
||||
if (place && place->declaration().is(IfcSchema::Type::IfcLocalPlacement)) {
|
||||
IfcSchema::IfcLocalPlacement* local_place = (IfcSchema::IfcLocalPlacement*) place;
|
||||
if (parent->hasObjectPlacement()) {
|
||||
local_place->setPlacementRelTo(parent->ObjectPlacement());
|
||||
|
||||
@@ -36,10 +36,10 @@ using namespace IfcUtil;
|
||||
|
||||
IfcWrite::IfcWritableEntity* IfcParse::IfcLateBoundEntity::writable_entity() {
|
||||
IfcWrite::IfcWritableEntity* e;
|
||||
if (entity->isWritable()) {
|
||||
e = (IfcWrite::IfcWritableEntity*) entity;
|
||||
if (data_->isWritable()) {
|
||||
e = (IfcWrite::IfcWritableEntity*) data_;
|
||||
} else {
|
||||
entity = e = new IfcWrite::IfcWritableEntity(entity);
|
||||
data_ = e = new IfcWrite::IfcWritableEntity(data_);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -47,20 +47,25 @@ IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(const std::string& s) {
|
||||
std::string S = s;
|
||||
for (std::string::iterator i = S.begin(); i != S.end(); ++i ) *i = toupper(*i);
|
||||
_type = IfcSchema::Type::FromString(S);
|
||||
entity = new IfcWrite::IfcWritableEntity(_type);
|
||||
data_ = new IfcWrite::IfcWritableEntity(_type);
|
||||
for (unsigned i = 0; i < getArgumentCount(); ++i) {
|
||||
// Side effect of this is that a NULL attribute is created.
|
||||
entity->getArgument(i);
|
||||
data_->getArgument(i);
|
||||
}
|
||||
IfcSchema::Type::PopulateDerivedFields(writable_entity());
|
||||
}
|
||||
IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(IfcAbstractEntity* e) {
|
||||
entity = e;
|
||||
data_ = e;
|
||||
_type = e->type();
|
||||
}
|
||||
/*
|
||||
const IfcParse::entity& IfcParse::IfcLateBoundEntity::entity() {
|
||||
return *get_schema().declaration_by_name(IfcSchema::Type::ToString(_type));
|
||||
}
|
||||
*/
|
||||
unsigned int IfcParse::IfcLateBoundEntity::id() const {
|
||||
if (entity->file) {
|
||||
return static_cast<unsigned int>(entity->id());
|
||||
if (data_->file) {
|
||||
return static_cast<unsigned int>(data_->id());
|
||||
} else {
|
||||
throw IfcException("Entity not bound to a file");
|
||||
}
|
||||
@@ -97,7 +102,7 @@ IfcSchema::Type::Enum IfcParse::IfcLateBoundEntity::getArgumentEntity(unsigned i
|
||||
return IfcSchema::Type::GetAttributeEntity(_type, i);
|
||||
}
|
||||
Argument* IfcParse::IfcLateBoundEntity::getArgument(unsigned int i) const {
|
||||
return entity->getArgument(i);
|
||||
return data_->getArgument(i);
|
||||
}
|
||||
const char* IfcParse::IfcLateBoundEntity::getArgumentName(unsigned int i) const {
|
||||
return IfcSchema::Type::GetAttributeName(_type,i).c_str();
|
||||
@@ -215,11 +220,11 @@ unsigned IfcParse::IfcLateBoundEntity::getArgumentIndex(const std::string& a) co
|
||||
return IfcSchema::Type::GetAttributeIndex(_type,a);
|
||||
}
|
||||
std::string IfcParse::IfcLateBoundEntity::toString() {
|
||||
return entity->toString(false);
|
||||
return data_->toString(false);
|
||||
}
|
||||
IfcEntityList::ptr IfcParse::IfcLateBoundEntity::get_inverse(const std::string& a) {
|
||||
std::pair<IfcSchema::Type::Enum, unsigned> inv = IfcSchema::Type::GetInverseAttribute(_type, a);
|
||||
return entity->getInverse(inv.first, inv.second);
|
||||
return data_->getInverse(inv.first, inv.second);
|
||||
}
|
||||
bool IfcParse::IfcLateBoundEntity::is_valid() {
|
||||
const unsigned arg_count = getArgumentCount();
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace IfcParse {
|
||||
// that in the IfcFile class the distinction what entity type to be created is
|
||||
// no longer necessary and weird diagonal casts when creating geometry from
|
||||
// IfcLateBoundEntities are eliminated.
|
||||
class IfcLateBoundEntity : public IfcUtil::IfcBaseEntity {
|
||||
class IfcLateBoundEntity : public IfcUtil::IfcBaseClass { // TODO: -Entity or -Type?
|
||||
private:
|
||||
IfcSchema::Type::Enum _type;
|
||||
IfcWrite::IfcWritableEntity* writable_entity();
|
||||
@@ -79,6 +79,20 @@ namespace IfcParse {
|
||||
std::string toString();
|
||||
|
||||
bool is_valid();
|
||||
|
||||
// const IfcParse::entity& entity();
|
||||
|
||||
const IfcAbstractEntity& data() const { return *data_; }
|
||||
IfcAbstractEntity& data() { return *data_; }
|
||||
|
||||
virtual const IfcParse::declaration& declaration() const {
|
||||
if (data().file) {
|
||||
throw;
|
||||
// data().file->
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+117
-98
@@ -37,6 +37,7 @@
|
||||
#include "../ifcparse/IfcLateBoundEntity.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcSIPrefix.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
|
||||
using namespace IfcParse;
|
||||
|
||||
@@ -764,7 +765,7 @@ EntityArgument::operator IfcEntityListList::ptr() const { throw IfcException("Ar
|
||||
unsigned int EntityArgument::size() const { return 1; }
|
||||
Argument* EntityArgument::operator [] (unsigned int i) const { throw IfcException("Argument is not a list of arguments"); }
|
||||
std::string EntityArgument::toString(bool upper) const {
|
||||
return entity->entity->toString(upper);
|
||||
return entity->data().toString(upper);
|
||||
}
|
||||
//return entity->entity->toString(); }
|
||||
bool EntityArgument::isNull() const { return false; }
|
||||
@@ -879,11 +880,10 @@ IfcEntityList::ptr Entity::getInverse(IfcSchema::Type::Enum type, int attribute_
|
||||
}
|
||||
|
||||
bool Entity::is(IfcSchema::Type::Enum v) const { return _type == v; }
|
||||
unsigned int Entity::id() { return _id; }
|
||||
unsigned int Entity::id() const { return _id; }
|
||||
|
||||
IfcWrite::IfcWritableEntity* Entity::isWritable() {
|
||||
return 0;
|
||||
}
|
||||
const IfcWrite::IfcWritableEntity* Entity::isWritable() const { return 0; }
|
||||
IfcWrite::IfcWritableEntity* Entity::isWritable() { return 0; }
|
||||
|
||||
IfcFile::IfcFile(bool create_latebound_entities)
|
||||
: _create_latebound_entities(create_latebound_entities)
|
||||
@@ -892,6 +892,9 @@ IfcFile::IfcFile(bool create_latebound_entities)
|
||||
, tokens(0)
|
||||
, MaxId(0)
|
||||
{
|
||||
if (!create_latebound_entities) {
|
||||
schema_ = &get_schema();
|
||||
}
|
||||
setDefaultHeaderValues();
|
||||
}
|
||||
|
||||
@@ -961,7 +964,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
||||
std::stringstream ss; ss << "\r#" << currentId;
|
||||
Logger::Status(ss.str(), false);
|
||||
}
|
||||
if ( entity->is(IfcSchema::Type::IfcRoot) ) {
|
||||
if ( entity->declaration().is(IfcSchema::Type::IfcRoot) ) {
|
||||
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) entity;
|
||||
try {
|
||||
const std::string guid = ifc_root->GlobalId();
|
||||
@@ -976,7 +979,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
||||
}
|
||||
}
|
||||
|
||||
IfcSchema::Type::Enum ty = entity->type();
|
||||
IfcSchema::Type::Enum ty = entity->declaration().type();
|
||||
do {
|
||||
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
||||
if (!instances_by_type) {
|
||||
@@ -1031,8 +1034,9 @@ void IfcFile::traverse(IfcUtil::IfcBaseClass* instance, std::set<IfcUtil::IfcBas
|
||||
|
||||
if (level >= max_level && max_level > 0) return;
|
||||
|
||||
for (unsigned i = 0; i < instance->getArgumentCount(); ++i) {
|
||||
Argument* arg = instance->getArgument(i);
|
||||
auto attributes = instance->declaration().as_entity()->all_attributes();
|
||||
for (unsigned i = 0; i < attributes.size(); ++i) {
|
||||
Argument* arg = instance->data().getArgument(i);
|
||||
|
||||
if (arg->type() == IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
traverse(*arg, visited, list, level + 1, max_level);
|
||||
@@ -1065,10 +1069,10 @@ void IfcFile::addEntities(IfcEntityList::ptr es) {
|
||||
}
|
||||
}
|
||||
|
||||
IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* instance) {
|
||||
// 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);
|
||||
entity_entity_map_t::iterator it = entity_file_map.find(instance);
|
||||
if (it != entity_file_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
@@ -1076,39 +1080,44 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
// Obtain all forward references by a depth-first
|
||||
// traversal and add them to the file.
|
||||
try {
|
||||
IfcEntityList::ptr entity_attributes = traverse(entity, 1);
|
||||
IfcEntityList::ptr entity_attributes = traverse(instance, 1);
|
||||
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
||||
if (*it != entity) {
|
||||
if (*it != instance) {
|
||||
entity_file_map.insert(entity_entity_map_t::value_type(*it, addEntity(*it)));
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to visit forward references of", entity->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to visit forward references of", instance);
|
||||
}
|
||||
|
||||
// See whether the instance is already part of a file
|
||||
if (entity->entity->file != 0) {
|
||||
if (entity->entity->file == this) {
|
||||
if (instance->data().file != 0) {
|
||||
if (instance->data().file == this) {
|
||||
// If it is part of this file
|
||||
// nothing needs to be done.
|
||||
return entity;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// An instance is being added from another file. A copy of the
|
||||
// container and entity is created. The attribute references
|
||||
// container and instance 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);
|
||||
IfcFile* other_file = instance->data().file;
|
||||
|
||||
// TODO: Proper copy constructor
|
||||
IfcWrite::IfcWritableEntity* we = new IfcWrite::IfcWritableEntity(&instance->data());
|
||||
|
||||
if (this->create_latebound_entities()) {
|
||||
entity = new IfcLateBoundEntity(we);
|
||||
instance = new IfcLateBoundEntity(we);
|
||||
} else {
|
||||
entity = IfcSchema::SchemaEntity(we);
|
||||
instance = IfcSchema::SchemaEntity(we);
|
||||
}
|
||||
|
||||
// In case an entity is added that contains geometry, the unit
|
||||
// In case an instance is added that contains geometry, the unit
|
||||
// information needs to be accounted for for IfcLengthMeasures.
|
||||
boost::optional<double> conversion_factor;
|
||||
|
||||
const schema_definition* s = schema();
|
||||
|
||||
for (unsigned i = 0; i < we->getArgumentCount(); ++i) {
|
||||
Argument* attr = we->getArgument(i);
|
||||
IfcUtil::ArgumentType attr_type = attr->type();
|
||||
@@ -1138,23 +1147,31 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
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_AGGREGATE_OF_DOUBLE) {
|
||||
std::vector<double> v = *attr;
|
||||
for (std::vector<double>::iterator it = v.begin(); it != v.end(); ++it) {
|
||||
(*it) *= *conversion_factor;
|
||||
} else if (s) {
|
||||
const entity* e = instance->declaration().as_entity();
|
||||
if (e) {
|
||||
const std::vector<const entity::attribute*> attrs = e->all_attributes();
|
||||
const parameter_type* pt = attrs[i]->type_of_attribute();
|
||||
while (pt->as_aggregation_type()) {
|
||||
pt = pt->as_aggregation_type()->type_of_element();
|
||||
}
|
||||
if (pt->is(IfcSchema::Type::IfcLengthMeasure)) {
|
||||
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_AGGREGATE_OF_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);
|
||||
}
|
||||
}
|
||||
we->setArgument(i, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1166,13 +1183,13 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
}
|
||||
|
||||
// For subtypes of IfcRoot, the GUID mapping needs to be updated.
|
||||
if (entity->is(IfcSchema::Type::IfcRoot)) {
|
||||
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) entity;
|
||||
if (instance->declaration().is(IfcSchema::Type::IfcRoot)) {
|
||||
IfcSchema::IfcRoot* ifc_root = (IfcSchema::IfcRoot*) instance;
|
||||
try {
|
||||
const std::string guid = ifc_root->GlobalId();
|
||||
if ( byguid.find(guid) != byguid.end() ) {
|
||||
std::stringstream ss;
|
||||
ss << "Overwriting entity with guid " << guid;
|
||||
ss << "Overwriting instance with guid " << guid;
|
||||
Logger::Message(Logger::LOG_WARNING,ss.str());
|
||||
}
|
||||
byguid[guid] = ifc_root;
|
||||
@@ -1181,74 +1198,75 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
}
|
||||
}
|
||||
|
||||
// The mapping by entity type is updated.
|
||||
IfcSchema::Type::Enum ty = entity->type();
|
||||
// The mapping by instance type is updated.
|
||||
IfcSchema::Type::Enum ty = instance->declaration().type();
|
||||
do {
|
||||
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
||||
if (!instances_by_type) {
|
||||
instances_by_type = IfcEntityList::ptr(new IfcEntityList());
|
||||
bytype[ty] = instances_by_type;
|
||||
}
|
||||
instances_by_type->push(entity);
|
||||
instances_by_type->push(instance);
|
||||
ty = IfcSchema::Type::Parent(ty);
|
||||
} while ( ty > -1 );
|
||||
|
||||
int new_id = -1;
|
||||
if (entity->entity->isWritable() && !entity->entity->file) {
|
||||
if (instance->data().isWritable() && !instance->data().file) {
|
||||
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
|
||||
entity->entity->file = this;
|
||||
new_id = entity->entity->isWritable()->setId();
|
||||
instance->data().file = this;
|
||||
new_id = instance->data().isWritable()->setId();
|
||||
} else {
|
||||
new_id = entity->entity->id();
|
||||
new_id = instance->data().id();
|
||||
}
|
||||
|
||||
if (byid.find(new_id) != byid.end()) {
|
||||
// This should not happen
|
||||
std::stringstream ss;
|
||||
ss << "Overwriting entity with id " << new_id;
|
||||
ss << "Overwriting instance with id " << new_id;
|
||||
Logger::Message(Logger::LOG_WARNING, ss.str());
|
||||
}
|
||||
|
||||
// The mapping by entity instance name is updated.
|
||||
byid[new_id] = entity;
|
||||
byid[new_id] = instance;
|
||||
|
||||
// The mapping by reference is updated.
|
||||
IfcEntityList::ptr entity_attributes(new IfcEntityList);
|
||||
try {
|
||||
entity_attributes = traverse(entity, 1);
|
||||
entity_attributes = traverse(instance, 1);
|
||||
} catch (...) {}
|
||||
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
|
||||
IfcUtil::IfcBaseClass* entity_attribute = *it;
|
||||
if (*it == entity) continue;
|
||||
if (*it == instance) continue;
|
||||
try {
|
||||
if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
|
||||
unsigned entity_attribute_id = entity_attribute->entity->id();
|
||||
// if (!IfcSchema::Type::IsSimple(entity_attribute->type())) {
|
||||
if (!entity_attribute->declaration().as_entity()) {
|
||||
unsigned entity_attribute_id = entity_attribute->data().id();
|
||||
IfcEntityList::ptr refs = entitiesByReference(entity_attribute_id);
|
||||
if (!refs) {
|
||||
refs = IfcEntityList::ptr(new IfcEntityList);
|
||||
byref[entity_attribute_id] = refs;
|
||||
}
|
||||
refs->push(entity);
|
||||
refs->push(instance);
|
||||
}
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
}
|
||||
|
||||
return entity;
|
||||
return instance;
|
||||
}
|
||||
|
||||
IfcWrite::IfcWritableEntity* make_writable(IfcUtil::IfcBaseClass* instance) {
|
||||
if (instance->entity->isWritable()) {
|
||||
return instance->entity->isWritable();
|
||||
if (instance->data().isWritable()) {
|
||||
return instance->data().isWritable();
|
||||
}
|
||||
|
||||
IfcWrite::IfcWritableEntity* return_value;
|
||||
instance->entity = return_value = new IfcWrite::IfcWritableEntity(instance->entity);
|
||||
IfcWrite::IfcWritableEntity* return_value = new IfcWrite::IfcWritableEntity(&instance->data());
|
||||
instance->data(return_value);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
const unsigned id = entity->entity->id();
|
||||
IfcUtil::IfcBaseClass* file_entity = entityById(id);
|
||||
void IfcFile::removeEntity(IfcUtil::IfcBaseClass* instance) {
|
||||
const unsigned id = instance->data().id();
|
||||
IfcUtil::IfcBaseClass* file_instance = 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
|
||||
@@ -1257,38 +1275,40 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
// characterized as weak.
|
||||
std::set<IfcSchema::Type::Enum> weak_roots;
|
||||
|
||||
if (entity != file_entity) {
|
||||
if (instance != file_instance) {
|
||||
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
|
||||
// Alter entity instances with INVERSE relations to the instance 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.
|
||||
// instance 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);
|
||||
for (unsigned i = 0; i < related_instance->data().getArgumentCount(); ++i) {
|
||||
|
||||
Argument* attr = related_instance->data().getArgument(i);
|
||||
if (attr->isNull()) continue;
|
||||
|
||||
IfcUtil::ArgumentType attr_type = related_instance->getArgumentType(i);
|
||||
IfcUtil::ArgumentType attr_type = attr->type();
|
||||
|
||||
switch(attr_type) {
|
||||
case IfcUtil::Argument_ENTITY_INSTANCE: {
|
||||
IfcUtil::IfcBaseClass* instance_attribute = *attr;
|
||||
if (instance_attribute == entity) {
|
||||
if (instance_attribute == instance) {
|
||||
make_writable(related_instance)->setArgument(i);
|
||||
// deletion_queue.insert(related_instance);
|
||||
} }
|
||||
break;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
IfcEntityList::ptr instance_list = *attr;
|
||||
if (instance_list->contains(entity)) {
|
||||
instance_list->remove(entity);
|
||||
if (instance_list->contains(instance)) {
|
||||
instance_list->remove(instance);
|
||||
make_writable(related_instance)->setArgument(i, instance_list);
|
||||
/* if (instance_list->size() == 0) {
|
||||
deletion_queue.insert(related_instance);
|
||||
@@ -1297,12 +1317,12 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
break;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
IfcEntityListList::ptr instance_list_list = *attr;
|
||||
if (instance_list_list->contains(entity)) {
|
||||
if (instance_list_list->contains(instance)) {
|
||||
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*>::iterator jt;
|
||||
while ((jt = std::find(instances.begin(), instances.end(), entity)) != instances.end()) {
|
||||
while ((jt = std::find(instances.begin(), instances.end(), instance)) != instances.end()) {
|
||||
instances.erase(jt);
|
||||
}
|
||||
new_list->push(instances);
|
||||
@@ -1320,33 +1340,33 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
byref.erase(byref.find(id));
|
||||
}
|
||||
|
||||
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);
|
||||
IfcEntityList::ptr instance_attributes = traverse(instance, 1);
|
||||
for (IfcEntityList::it it = instance_attributes->begin(); it != instance_attributes->end(); ++it) {
|
||||
IfcUtil::IfcBaseClass* instance_attribute = *it;
|
||||
if (instance_attribute == instance) continue;
|
||||
entitiesByReference(instance_attribute->data().id())->remove(instance);
|
||||
if (entitiesByReference(instance_attribute->data().id())->filtered(weak_roots)->size() == 0) {
|
||||
deletion_queue.insert(instance_attribute);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity->is(IfcSchema::Type::IfcRoot)) {
|
||||
const std::string global_id = ((IfcSchema::IfcRoot*) entity)->GlobalId();
|
||||
IfcSchema::IfcRoot* root = instance->as<IfcSchema::IfcRoot>();
|
||||
if (root) {
|
||||
const std::string global_id = root->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);
|
||||
IfcEntityList::ptr instances_of_same_type = entitiesByType(instance->declaration().type());
|
||||
instances_of_same_type->remove(instance);
|
||||
|
||||
while (!deletion_queue.empty()) {
|
||||
removeEntity(*deletion_queue.begin());
|
||||
deletion_queue.erase(deletion_queue.begin());
|
||||
}
|
||||
|
||||
delete entity->entity;
|
||||
delete entity;
|
||||
delete instance;
|
||||
}
|
||||
|
||||
IfcEntityList::ptr IfcFile::entitiesByType(IfcSchema::Type::Enum t) {
|
||||
@@ -1385,7 +1405,6 @@ IfcSchema::IfcRoot* IfcFile::entityByGuid(const std::string& guid) {
|
||||
// FIXME: Test destructor to delete entity and arg allocations
|
||||
IfcFile::~IfcFile() {
|
||||
for( entity_by_id_t::const_iterator it = byid.begin(); it != byid.end(); ++ it ) {
|
||||
delete it->second->entity;
|
||||
delete it->second;
|
||||
}
|
||||
delete stream;
|
||||
@@ -1405,8 +1424,8 @@ std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
|
||||
|
||||
for ( IfcFile::entity_by_id_t::const_iterator it = f.begin(); it != f.end(); ++ it ) {
|
||||
const IfcUtil::IfcBaseClass* e = it->second;
|
||||
if (!IfcSchema::Type::IsSimple(e->type())) {
|
||||
os << e->entity->toString(true) << ";" << std::endl;
|
||||
if (!IfcSchema::Type::IsSimple(e->data().type())) {
|
||||
os << e->data().toString(true) << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,9 +1459,9 @@ 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::UNDEFINED || (*it)->is(type);
|
||||
bool valid = type == IfcSchema::Type::UNDEFINED || (*it)->declaration().is(type);
|
||||
if (valid && attribute_index >= 0) {
|
||||
Argument* arg = (*it)->entity->getArgument(attribute_index);
|
||||
Argument* arg = (*it)->data().getArgument(attribute_index);
|
||||
if (arg->type() == IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
valid = instance == *arg;
|
||||
} else if (arg->type() == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
@@ -1490,21 +1509,21 @@ std::pair<IfcSchema::IfcNamedUnit*, double> IfcFile::getUnit(IfcSchema::IfcUnitE
|
||||
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)) {
|
||||
if (unit->declaration().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)) {
|
||||
if (named_unit->declaration().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.second *= static_cast<double>(*mu->ValueComponent()->data().getArgument(0));
|
||||
return_value.first = named_unit;
|
||||
if (mu->UnitComponent()->is(IfcSchema::Type::IfcSIUnit)) {
|
||||
if (mu->UnitComponent()->declaration().is(IfcSchema::Type::IfcSIUnit)) {
|
||||
unit = (IfcSchema::IfcSIUnit*) mu->UnitComponent();
|
||||
}
|
||||
} else if (named_unit->is(IfcSchema::Type::IfcSIUnit)) {
|
||||
} else if (named_unit->declaration().is(IfcSchema::Type::IfcSIUnit)) {
|
||||
return_value.first = unit = (IfcSchema::IfcSIUnit*) named_unit;
|
||||
}
|
||||
if (unit) {
|
||||
|
||||
@@ -257,7 +257,8 @@ namespace IfcParse {
|
||||
std::string datatype() const;
|
||||
IfcSchema::Type::Enum type() const;
|
||||
bool is(IfcSchema::Type::Enum v) const;
|
||||
unsigned int id();
|
||||
unsigned int id() const;
|
||||
const IfcWrite::IfcWritableEntity* isWritable() const;
|
||||
IfcWrite::IfcWritableEntity* isWritable();
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "IfcSchema.h"
|
||||
|
||||
bool IfcParse::declaration::is(const std::string& name) const {
|
||||
return is(IfcSchema::Type::FromString(name));
|
||||
}
|
||||
|
||||
bool IfcParse::declaration::is(IfcSchema::Type::Enum name) const {
|
||||
if (this->as_entity()) {
|
||||
return this->as_entity()->is(name);
|
||||
} else {
|
||||
return this->name() == IfcSchema::Type::ToString(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcParse::named_type::is(const std::string& name) const {
|
||||
return declared_type()->is(name);
|
||||
}
|
||||
|
||||
bool IfcParse::named_type::is(IfcSchema::Type::Enum name) const {
|
||||
return declared_type()->is(name);
|
||||
}
|
||||
+277
-204
@@ -24,222 +24,295 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
class declaration;
|
||||
class type_declaration;
|
||||
class select_type;
|
||||
class enumeration_type;
|
||||
class entity;
|
||||
#ifdef USE_IFC4
|
||||
#include "../ifcparse/Ifc4enum.h"
|
||||
#else
|
||||
#include "../ifcparse/Ifc2x3enum.h"
|
||||
#endif
|
||||
|
||||
class parameter_type {
|
||||
};
|
||||
namespace IfcParse {
|
||||
|
||||
class named_type : public parameter_type {
|
||||
protected:
|
||||
declaration* declared_type_;
|
||||
public:
|
||||
named_type(declaration* declared_type)
|
||||
: declared_type_(declared_type) {}
|
||||
class declaration;
|
||||
|
||||
class type_declaration;
|
||||
class select_type;
|
||||
class enumeration_type;
|
||||
class entity;
|
||||
|
||||
declaration* declared_type() const { return declared_type_; }
|
||||
};
|
||||
class named_type;
|
||||
class simple_type;
|
||||
class aggregation_type;
|
||||
|
||||
class simple_type : public parameter_type {
|
||||
public:
|
||||
typedef enum { binary_type, boolean_type, integer_type, logical_type, number_type, real_type, string_type } data_type;
|
||||
protected:
|
||||
data_type declared_type_;
|
||||
public:
|
||||
simple_type(data_type declared_type)
|
||||
: declared_type_(declared_type) {}
|
||||
class parameter_type {
|
||||
public:
|
||||
virtual const named_type* as_named_type() const { return static_cast<named_type*>(0); }
|
||||
virtual const simple_type* as_simple_type() const { return static_cast<simple_type*>(0); }
|
||||
virtual const aggregation_type* as_aggregation_type() const { return static_cast<aggregation_type*>(0); }
|
||||
|
||||
data_type declared_type() const { return declared_type_; }
|
||||
};
|
||||
virtual bool is(const std::string& name) const { return false; }
|
||||
virtual bool is(IfcSchema::Type::Enum name) const { return false; }
|
||||
};
|
||||
|
||||
class aggregation_type : public parameter_type {
|
||||
public:
|
||||
typedef enum { array_type, bag_type, list_type, set_type } aggregate_type;
|
||||
protected:
|
||||
aggregate_type type_of_aggregation_;
|
||||
int bound1_, bound2_;
|
||||
parameter_type* type_of_element_;
|
||||
public:
|
||||
aggregation_type(aggregate_type type_of_aggregation, int bound1, int bound2, parameter_type* type_of_element)
|
||||
: type_of_aggregation_(type_of_aggregation)
|
||||
, bound1_(bound1)
|
||||
, bound2_(bound2)
|
||||
, type_of_element_(type_of_element)
|
||||
{}
|
||||
|
||||
aggregate_type type_of_aggregation() const { type_of_aggregation_; }
|
||||
int bound1() const { return bound1_; }
|
||||
int bound2() const { return bound2_; }
|
||||
parameter_type* type_of_element() const { return type_of_element_; }
|
||||
};
|
||||
|
||||
class declaration {
|
||||
protected:
|
||||
std::string name_;
|
||||
|
||||
public:
|
||||
declaration(const std::string& name)
|
||||
: name_(name) {}
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
virtual const type_declaration* as_type_declaration() const { return static_cast<type_declaration*>(0); }
|
||||
virtual const select_type* as_select_type() const { return static_cast<select_type*>(0); }
|
||||
virtual const enumeration_type* as_enumeration_type() const { return static_cast<enumeration_type*>(0); }
|
||||
virtual const entity* as_entity() const { return static_cast<entity*>(0); }
|
||||
};
|
||||
|
||||
class type_declaration : public declaration {
|
||||
protected:
|
||||
const parameter_type* declared_type_;
|
||||
|
||||
public:
|
||||
type_declaration(const std::string& name, const parameter_type* declared_type)
|
||||
: declaration(name)
|
||||
, declared_type_(declared_type) {}
|
||||
|
||||
const parameter_type* declared_type() const { return declared_type_; }
|
||||
|
||||
virtual const type_declaration* as_type_declaration() const { return this; }
|
||||
};
|
||||
|
||||
class select_type : public declaration {
|
||||
protected:
|
||||
std::vector<const declaration*> select_list_;
|
||||
public:
|
||||
select_type(const std::string& name, const std::vector<const declaration*>& select_list)
|
||||
: declaration(name)
|
||||
, select_list_(select_list) {}
|
||||
|
||||
const std::vector<const declaration*>& select_list() const { return select_list_; }
|
||||
|
||||
virtual const select_type* as_select_type() const { return this; }
|
||||
};
|
||||
|
||||
class enumeration_type : public declaration {
|
||||
protected:
|
||||
std::vector<std::string> enumeration_items_;
|
||||
public:
|
||||
enumeration_type(const std::string& name, const std::vector<std::string>& enumeration_items)
|
||||
: declaration(name)
|
||||
, enumeration_items_(enumeration_items) {}
|
||||
|
||||
const std::vector<std::string>& enumeration_items() const { return enumeration_items_; }
|
||||
|
||||
virtual const enumeration_type* as_enumeration_type() const { return this; }
|
||||
};
|
||||
|
||||
class entity : public declaration {
|
||||
public:
|
||||
class attribute {
|
||||
class named_type : public parameter_type {
|
||||
protected:
|
||||
declaration* declared_type_;
|
||||
public:
|
||||
named_type(declaration* declared_type)
|
||||
: declared_type_(declared_type) {}
|
||||
|
||||
declaration* declared_type() const { return declared_type_; }
|
||||
|
||||
virtual const named_type* as_named_type() const { return this; }
|
||||
|
||||
virtual bool is(const std::string& name) const;
|
||||
virtual bool is(IfcSchema::Type::Enum name) const;
|
||||
};
|
||||
|
||||
class simple_type : public parameter_type {
|
||||
public:
|
||||
typedef enum { binary_type, boolean_type, integer_type, logical_type, number_type, real_type, string_type } data_type;
|
||||
protected:
|
||||
data_type declared_type_;
|
||||
public:
|
||||
simple_type(data_type declared_type)
|
||||
: declared_type_(declared_type) {}
|
||||
|
||||
data_type declared_type() const { return declared_type_; }
|
||||
|
||||
virtual const simple_type* as_simple_type() const { return this; }
|
||||
};
|
||||
|
||||
class aggregation_type : public parameter_type {
|
||||
public:
|
||||
typedef enum { array_type, bag_type, list_type, set_type } aggregate_type;
|
||||
protected:
|
||||
aggregate_type type_of_aggregation_;
|
||||
int bound1_, bound2_;
|
||||
parameter_type* type_of_element_;
|
||||
public:
|
||||
aggregation_type(aggregate_type type_of_aggregation, int bound1, int bound2, parameter_type* type_of_element)
|
||||
: type_of_aggregation_(type_of_aggregation)
|
||||
, bound1_(bound1)
|
||||
, bound2_(bound2)
|
||||
, type_of_element_(type_of_element)
|
||||
{}
|
||||
|
||||
aggregate_type type_of_aggregation() const { type_of_aggregation_; }
|
||||
int bound1() const { return bound1_; }
|
||||
int bound2() const { return bound2_; }
|
||||
parameter_type* type_of_element() const { return type_of_element_; }
|
||||
|
||||
virtual const aggregation_type* as_aggregation_type() const { return this; }
|
||||
};
|
||||
|
||||
class declaration {
|
||||
protected:
|
||||
// std::string name_;
|
||||
IfcSchema::Type::Enum name_;
|
||||
|
||||
public:
|
||||
declaration(IfcSchema::Type::Enum name)
|
||||
: name_(name) {}
|
||||
declaration(const std::string& name)
|
||||
: name_(IfcSchema::Type::FromString(name)) {}
|
||||
|
||||
std::string name() const { return IfcSchema::Type::ToString(name_); }
|
||||
|
||||
virtual const type_declaration* as_type_declaration() const { return static_cast<type_declaration*>(0); }
|
||||
virtual const select_type* as_select_type() const { return static_cast<select_type*>(0); }
|
||||
virtual const enumeration_type* as_enumeration_type() const { return static_cast<enumeration_type*>(0); }
|
||||
virtual const entity* as_entity() const { return static_cast<entity*>(0); }
|
||||
|
||||
// TODO: Type checking by Enum value
|
||||
bool is(const std::string& name) const;
|
||||
bool is(IfcSchema::Type::Enum name) const;
|
||||
|
||||
IfcSchema::Type::Enum type() const {
|
||||
return name_;
|
||||
}
|
||||
};
|
||||
|
||||
class type_declaration : public declaration {
|
||||
protected:
|
||||
const parameter_type* declared_type_;
|
||||
|
||||
public:
|
||||
type_declaration(const std::string& name, const parameter_type* declared_type)
|
||||
: declaration(name)
|
||||
, declared_type_(declared_type) {}
|
||||
type_declaration(IfcSchema::Type::Enum name, const parameter_type* declared_type)
|
||||
: declaration(name)
|
||||
, declared_type_(declared_type) {}
|
||||
|
||||
const parameter_type* declared_type() const { return declared_type_; }
|
||||
|
||||
virtual const type_declaration* as_type_declaration() const { return this; }
|
||||
};
|
||||
|
||||
class select_type : public declaration {
|
||||
protected:
|
||||
std::vector<const declaration*> select_list_;
|
||||
public:
|
||||
select_type(const std::string& name, const std::vector<const declaration*>& select_list)
|
||||
: declaration(name)
|
||||
, select_list_(select_list) {}
|
||||
select_type(IfcSchema::Type::Enum name, const std::vector<const declaration*>& select_list)
|
||||
: declaration(name)
|
||||
, select_list_(select_list) {}
|
||||
|
||||
const std::vector<const declaration*>& select_list() const { return select_list_; }
|
||||
|
||||
virtual const select_type* as_select_type() const { return this; }
|
||||
};
|
||||
|
||||
class enumeration_type : public declaration {
|
||||
protected:
|
||||
std::vector<std::string> enumeration_items_;
|
||||
public:
|
||||
enumeration_type(const std::string& name, const std::vector<std::string>& enumeration_items)
|
||||
: declaration(name)
|
||||
, enumeration_items_(enumeration_items) {}
|
||||
enumeration_type(IfcSchema::Type::Enum name, const std::vector<std::string>& enumeration_items)
|
||||
: declaration(name)
|
||||
, enumeration_items_(enumeration_items) {}
|
||||
|
||||
const std::vector<std::string>& enumeration_items() const { return enumeration_items_; }
|
||||
|
||||
virtual const enumeration_type* as_enumeration_type() const { return this; }
|
||||
};
|
||||
|
||||
class entity : public declaration {
|
||||
public:
|
||||
class attribute {
|
||||
protected:
|
||||
std::string name_;
|
||||
const parameter_type* type_of_attribute_;
|
||||
bool optional_;
|
||||
|
||||
public:
|
||||
attribute(const std::string& name, parameter_type* type_of_attribute, bool optional)
|
||||
: name_(name)
|
||||
, type_of_attribute_(type_of_attribute)
|
||||
, optional_(optional) {}
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
const parameter_type* type_of_attribute() const { return type_of_attribute_; }
|
||||
bool optional() const { return optional_; }
|
||||
};
|
||||
|
||||
protected:
|
||||
const entity* supertype_; /* NB: IFC explicitly allows only single inheritance */
|
||||
std::vector<const entity*> subtypes_;
|
||||
|
||||
std::vector<const attribute*> attributes_;
|
||||
std::vector<bool> derived_;
|
||||
|
||||
public:
|
||||
entity(const std::string& name, entity* supertype)
|
||||
: declaration(name)
|
||||
, supertype_(supertype)
|
||||
{}
|
||||
entity(IfcSchema::Type::Enum name, entity* supertype)
|
||||
: declaration(name)
|
||||
, supertype_(supertype)
|
||||
{}
|
||||
|
||||
bool is(const std::string& name) const {
|
||||
return is(IfcSchema::Type::FromString(name));
|
||||
}
|
||||
|
||||
bool is(IfcSchema::Type::Enum name) const {
|
||||
if (name == name_) return true;
|
||||
else if (supertype_) return supertype_->is(name);
|
||||
else return false;
|
||||
}
|
||||
|
||||
void set_subtypes(const std::vector<const entity*>& subtypes) {
|
||||
subtypes_ = subtypes;
|
||||
}
|
||||
|
||||
void set_attributes(const std::vector<const attribute*>& attributes, const std::vector<bool>& derived) {
|
||||
attributes_ = attributes;
|
||||
derived_ = derived;
|
||||
}
|
||||
|
||||
const std::vector<const entity*>& subtypes() const { return subtypes_; }
|
||||
const std::vector<const attribute*>& attributes() const { return attributes_; }
|
||||
const std::vector<bool>& derived() const { return derived_; }
|
||||
|
||||
const std::vector<const attribute*> all_attributes() const {
|
||||
std::vector<const attribute*> attrs;
|
||||
attrs.reserve(derived_.size());
|
||||
std::vector<const attribute*>::iterator it = attrs.begin();
|
||||
if (supertype_) {
|
||||
const std::vector<const attribute*> supertype_attrs = supertype_->all_attributes();
|
||||
it = std::copy(supertype_attrs.begin(), supertype_attrs.end(), it);
|
||||
}
|
||||
std::copy(attributes_.begin(), attributes_.end(), it);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
virtual const entity* as_entity() const { return this; }
|
||||
};
|
||||
|
||||
class schema_definition {
|
||||
private:
|
||||
bool built_in_;
|
||||
|
||||
std::string name_;
|
||||
const parameter_type* type_of_attribute_;
|
||||
bool optional_;
|
||||
|
||||
std::vector<const declaration*> declarations_;
|
||||
|
||||
std::vector<const type_declaration*> type_declarations_;
|
||||
std::vector<const select_type*> select_types_;
|
||||
std::vector<const enumeration_type*> enumeration_types_;
|
||||
|
||||
class declaration_by_name_cmp : public std::binary_function<const declaration*, const std::string&, bool> {
|
||||
public:
|
||||
bool operator()(const declaration* decl, const std::string& name) {
|
||||
return decl->name() < name;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
attribute(const std::string& name, parameter_type* type_of_attribute, bool optional)
|
||||
schema_definition(const std::string& name, const std::vector<const declaration*>& declarations, const bool built_in = false)
|
||||
: name_(name)
|
||||
, type_of_attribute_(type_of_attribute)
|
||||
, optional_(optional) {}
|
||||
, declarations_(declarations)
|
||||
, built_in_(built_in)
|
||||
{
|
||||
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
|
||||
if ((**it).as_type_declaration()) type_declarations_.push_back((**it).as_type_declaration());
|
||||
if ((**it).as_select_type()) select_types_.push_back((**it).as_select_type());
|
||||
if ((**it).as_enumeration_type()) enumeration_types_.push_back((**it).as_enumeration_type());
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
const parameter_type* type_of_attribute() const { return type_of_attribute_; }
|
||||
bool optional() const { return optional_; }
|
||||
~schema_definition() {
|
||||
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
const declaration* declaration_by_name(const std::string& name) const {
|
||||
std::vector<const declaration*>::const_iterator it = std::lower_bound(declarations_.begin(), declarations_.end(), name, declaration_by_name_cmp());
|
||||
if (it == declarations_.end() || (**it).name() != name) {
|
||||
throw;
|
||||
} else {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
||||
const declaration* declaration_by_name(IfcSchema::Type::Enum name) const {
|
||||
if (!built_in_) throw;
|
||||
return declaration_by_name(IfcSchema::Type::ToString(name));
|
||||
}
|
||||
|
||||
const std::vector<const declaration*>& declarations() { return declarations_; }
|
||||
const std::vector<const type_declaration*>& type_declarations() { return type_declarations_; }
|
||||
const std::vector<const select_type*>& select_types() { return select_types_; }
|
||||
const std::vector<const enumeration_type*>& enumeration_types() { return enumeration_types_; }
|
||||
};
|
||||
|
||||
protected:
|
||||
const entity* supertype_; /* NB: IFC explicitly allows only single inheritance */
|
||||
std::vector<const entity*> subtypes_;
|
||||
}
|
||||
|
||||
std::vector<const attribute*> attributes_;
|
||||
std::vector<bool> derived_;
|
||||
|
||||
public:
|
||||
entity(const std::string& name, entity* supertype)
|
||||
: declaration(name)
|
||||
, supertype_(supertype)
|
||||
{}
|
||||
|
||||
void set_subtypes(const std::vector<const entity*>& subtypes) {
|
||||
subtypes_ = subtypes;
|
||||
}
|
||||
|
||||
void set_attributes(const std::vector<const attribute*>& attributes, const std::vector<bool>& derived) {
|
||||
attributes_ = attributes;
|
||||
derived_ = derived;
|
||||
}
|
||||
|
||||
const std::vector<const entity*>& subtypes() const { return subtypes_; }
|
||||
const std::vector<const attribute*>& attributes() const { return attributes_; }
|
||||
const std::vector<bool>& derived() const { return derived_; }
|
||||
|
||||
const std::vector<const attribute*> all_attributes() const {
|
||||
std::vector<const attribute*> attrs;
|
||||
attrs.reserve(derived_.size());
|
||||
std::vector<const attribute*>::iterator it = attrs.begin();
|
||||
if (supertype_) {
|
||||
const std::vector<const attribute*> supertype_attrs = supertype_->all_attributes();
|
||||
it = std::copy(supertype_attrs.begin(), supertype_attrs.end(), it);
|
||||
}
|
||||
std::copy(attributes_.begin(), attributes_.end(), it);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
virtual const entity* as_entity() const { return this; }
|
||||
};
|
||||
|
||||
class schema_definition {
|
||||
private:
|
||||
std::string name_;
|
||||
|
||||
std::vector<const declaration*> declarations_;
|
||||
|
||||
std::vector<const type_declaration*> type_declarations_;
|
||||
std::vector<const select_type*> select_types_;
|
||||
std::vector<const enumeration_type*> enumeration_types_;
|
||||
|
||||
class declaration_by_name_cmp : public std::binary_function<const declaration*, const std::string&, bool> {
|
||||
public:
|
||||
bool operator()(const declaration* decl, const std::string& name) {
|
||||
return decl->name() < name;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
schema_definition(const std::string& name, const std::vector<const declaration*>& declarations)
|
||||
: name_(name)
|
||||
, declarations_(declarations)
|
||||
{
|
||||
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
|
||||
if ((**it).as_type_declaration()) type_declarations_.push_back((**it).as_type_declaration());
|
||||
if ((**it).as_select_type()) select_types_.push_back((**it).as_select_type());
|
||||
if ((**it).as_enumeration_type()) enumeration_types_.push_back((**it).as_enumeration_type());
|
||||
}
|
||||
}
|
||||
|
||||
~schema_definition() {
|
||||
for (std::vector<const declaration*>::const_iterator it = declarations_.begin(); it != declarations_.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
const declaration* declaration_by_name(const std::string& name) {
|
||||
std::vector<const declaration*>::const_iterator it = std::lower_bound(declarations_.begin(), declarations_.end(), name, declaration_by_name_cmp());
|
||||
if (it == declarations_.end() || (**it).name() != name) {
|
||||
throw;
|
||||
} else {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<const declaration*>& declarations() { return declarations_; }
|
||||
const std::vector<const type_declaration*>& type_declarations() { return type_declarations_; }
|
||||
const std::vector<const select_type*>& select_types() { return select_types_; }
|
||||
const std::vector<const enumeration_type*>& enumeration_types() { return enumeration_types_; }
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,11 @@ public:
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
unsigned int id() {
|
||||
unsigned int id() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const IfcWrite::IfcWritableEntity* isWritable() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ IfcEntityList::ptr IfcEntityList::filtered(const std::set<IfcSchema::Type::Enum>
|
||||
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)) {
|
||||
if ((*it)->declaration().is(*jt)) {
|
||||
contained = true;
|
||||
break;
|
||||
}
|
||||
@@ -69,9 +69,9 @@ IfcEntityList::ptr IfcEntityList::filtered(const std::set<IfcSchema::Type::Enum>
|
||||
}
|
||||
|
||||
|
||||
unsigned int IfcUtil::IfcBaseType::getArgumentCount() const { return 1; }
|
||||
Argument* IfcUtil::IfcBaseType::getArgument(unsigned int i) const { return entity->getArgument(i); }
|
||||
const char* IfcUtil::IfcBaseType::getArgumentName(unsigned int i) const { if (i == 0) { return "wrappedValue"; } else { throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); } }
|
||||
// unsigned int IfcUtil::IfcBaseType::getArgumentCount() const { return 1; }
|
||||
// Argument* IfcUtil::IfcBaseType::getArgument(unsigned int i) const { return entity->getArgument(i); }
|
||||
// const char* IfcUtil::IfcBaseType::getArgumentName(unsigned int i) const { if (i == 0) { return "wrappedValue"; } else { throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); } }
|
||||
|
||||
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
log1 = l1;
|
||||
@@ -80,10 +80,10 @@ void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
log2 = &log_stream;
|
||||
}
|
||||
}
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, IfcAbstractEntity* entity) {
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* entity) {
|
||||
if ( log2 && type >= verbosity ) {
|
||||
(*log2) << "[" << severity_strings[type] << "] " << message << std::endl;
|
||||
if ( entity ) (*log2) << entity->toString() << std::endl;
|
||||
if ( entity ) (*log2) << entity->data().toString() << std::endl;
|
||||
}
|
||||
}
|
||||
void Logger::Status(const std::string& message, bool new_line) {
|
||||
@@ -143,4 +143,13 @@ bool IfcUtil::valid_binary_string(const std::string& s) {
|
||||
if (*it != '0' && *it != '1') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IfcUtil::IfcBaseClass::~IfcBaseClass() {
|
||||
delete data_;
|
||||
}
|
||||
|
||||
void IfcUtil::IfcBaseClass::data(IfcAbstractEntity* d) {
|
||||
delete data_;
|
||||
data_ = d;
|
||||
}
|
||||
+45
-18
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/SharedPointer.h"
|
||||
|
||||
#ifdef USE_IFC4
|
||||
@@ -40,6 +41,13 @@ class Argument;
|
||||
class IfcEntityList;
|
||||
class IfcEntityListList;
|
||||
class IfcAbstractEntity;
|
||||
|
||||
namespace IfcParse { // these have to be declared first in order for the virtual function below to be covariant. separate into different header file
|
||||
class declaration;
|
||||
class entity;
|
||||
class type_declaration;
|
||||
}
|
||||
|
||||
namespace IfcWrite {
|
||||
class IfcWritableEntity;
|
||||
}
|
||||
@@ -72,35 +80,53 @@ namespace IfcUtil {
|
||||
const char* ArgumentTypeToString(ArgumentType argument_type);
|
||||
|
||||
class IfcBaseClass {
|
||||
protected:
|
||||
IfcAbstractEntity* data_;
|
||||
public:
|
||||
IfcAbstractEntity* entity;
|
||||
virtual bool is(IfcSchema::Type::Enum v) const = 0;
|
||||
virtual IfcSchema::Type::Enum type() const = 0;
|
||||
IfcBaseClass() : data_(0) {}
|
||||
IfcBaseClass(IfcAbstractEntity* d) : data_(d) {}
|
||||
virtual ~IfcBaseClass();
|
||||
|
||||
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;
|
||||
const IfcAbstractEntity& data() const { return *data_; }
|
||||
IfcAbstractEntity& data() { return *data_; }
|
||||
|
||||
void data(IfcAbstractEntity* d);
|
||||
|
||||
virtual const IfcParse::declaration& declaration() const = 0;
|
||||
|
||||
template <class T>
|
||||
T* as() {
|
||||
return is(T::Class())
|
||||
return declaration().is(T::Class())
|
||||
? static_cast<T*>(this)
|
||||
: static_cast<T*>(0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T* as() const {
|
||||
return declaration().is(T::Class())
|
||||
? static_cast<const T*>(this)
|
||||
: static_cast<const T*>(0);
|
||||
}
|
||||
private:
|
||||
IfcBaseClass(const IfcBaseClass&);
|
||||
IfcBaseClass& operator=(const IfcBaseClass&);
|
||||
};
|
||||
|
||||
class IfcBaseEntity : public IfcBaseClass {
|
||||
public:
|
||||
IfcBaseEntity() : IfcBaseClass() {}
|
||||
IfcBaseEntity(IfcAbstractEntity* d) : IfcBaseClass(d) {}
|
||||
|
||||
virtual const IfcParse::entity& declaration() const = 0;
|
||||
};
|
||||
|
||||
// TODO: Investigate whether these should be template classes instead
|
||||
class IfcBaseType : public IfcBaseEntity {
|
||||
class IfcBaseType : public IfcBaseClass {
|
||||
public:
|
||||
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; }
|
||||
IfcBaseType() : IfcBaseClass() {}
|
||||
IfcBaseType(IfcAbstractEntity* d) : IfcBaseClass(d) {}
|
||||
|
||||
virtual const IfcParse::type_declaration& declaration() const = 0;
|
||||
};
|
||||
|
||||
bool valid_binary_string(const std::string& s);
|
||||
@@ -125,7 +151,7 @@ public:
|
||||
typename U::list::ptr as() {
|
||||
typename U::list::ptr r(new typename U::list);
|
||||
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);
|
||||
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->declaration().is(U::Class())) r->push((U*)*i);
|
||||
return r;
|
||||
}
|
||||
void remove(IfcUtil::IfcBaseClass*);
|
||||
@@ -153,7 +179,7 @@ public:
|
||||
typename U::list::ptr as() {
|
||||
typename U::list::ptr r(new typename U::list);
|
||||
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);
|
||||
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->declaration().is(U::Class())) r->push((U*)*i);
|
||||
return r;
|
||||
}
|
||||
void remove(T* t) {
|
||||
@@ -305,7 +331,8 @@ public:
|
||||
virtual IfcSchema::Type::Enum type() const = 0;
|
||||
virtual bool is(IfcSchema::Type::Enum v) const = 0;
|
||||
virtual std::string toString(bool upper=false) const = 0;
|
||||
virtual unsigned int id() = 0;
|
||||
virtual unsigned int id() const = 0;
|
||||
virtual const IfcWrite::IfcWritableEntity* isWritable() const = 0;
|
||||
virtual IfcWrite::IfcWritableEntity* isWritable() = 0;
|
||||
};
|
||||
|
||||
@@ -325,7 +352,7 @@ public:
|
||||
static void Verbosity(Severity v);
|
||||
static Severity Verbosity();
|
||||
/// Log a message to the output stream
|
||||
static void Message(Severity type, const std::string& message, IfcAbstractEntity* entity=0);
|
||||
static void Message(Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance=0);
|
||||
static void Status(const std::string& message, bool new_line=true);
|
||||
static void ProgressBar(int progress);
|
||||
static std::string GetLog();
|
||||
|
||||
@@ -40,12 +40,17 @@
|
||||
namespace IfcWrite {
|
||||
class IfcWritableEntity : public IfcAbstractEntity {
|
||||
private:
|
||||
// Mutable because calling id() will generate a fresh id on
|
||||
// the current file, in case none has been assigned previously
|
||||
mutable int* _id;
|
||||
|
||||
std::map<int,bool> writemask;
|
||||
std::map<int,Argument*> args;
|
||||
IfcSchema::Type::Enum _type;
|
||||
int* _id;
|
||||
|
||||
bool arg_writable(int i);
|
||||
void arg_writable(int i, bool b);
|
||||
|
||||
template <typename T> void _setArgument(int i, const T&);
|
||||
public:
|
||||
IfcWritableEntity(IfcSchema::Type::Enum t);
|
||||
@@ -60,7 +65,8 @@ namespace IfcWrite {
|
||||
IfcSchema::Type::Enum type() const;
|
||||
bool is(IfcSchema::Type::Enum v) const;
|
||||
std::string toString(bool upper=false) const;
|
||||
unsigned int id();
|
||||
unsigned int id() const;
|
||||
const IfcWritableEntity* isWritable() const;
|
||||
IfcWritableEntity* isWritable();
|
||||
|
||||
void setArgument(int i, Argument* a);
|
||||
|
||||
@@ -109,12 +109,13 @@ std::string IfcWritableEntity::toString(bool upper) const {
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
unsigned int IfcWritableEntity::id() {
|
||||
unsigned int IfcWritableEntity::id() const {
|
||||
if ( !_id ) {
|
||||
_id = new int(file->FreshId());
|
||||
}
|
||||
return *_id;
|
||||
}
|
||||
const IfcWritableEntity* IfcWritableEntity::isWritable() const { return this; }
|
||||
IfcWritableEntity* IfcWritableEntity::isWritable() { return this; }
|
||||
bool IfcWritableEntity::arg_writable(int i) {
|
||||
std::map<int,bool>::const_iterator it = writemask.find(i);
|
||||
@@ -390,11 +391,11 @@ public:
|
||||
data << "." << i.enumeration_value << ".";
|
||||
}
|
||||
void operator()(const IfcUtil::IfcBaseClass* const& i) {
|
||||
IfcAbstractEntity* e = i->entity;
|
||||
if ( IfcSchema::Type::IsSimple(e->type()) ) {
|
||||
data << e->toString(upper);
|
||||
const IfcAbstractEntity& e = i->data();
|
||||
if ( IfcSchema::Type::IsSimple(e.type()) ) {
|
||||
data << e.toString(upper);
|
||||
} else {
|
||||
data << "#" << e->id();
|
||||
data << "#" << e.id();
|
||||
}
|
||||
}
|
||||
void operator()(const IfcEntityList::ptr& i) {
|
||||
|
||||
Reference in New Issue
Block a user