diff --git a/src/ifcparse/IfcFile.h b/src/ifcparse/IfcFile.h index e950efd1ec..115877e18f 100644 --- a/src/ifcparse/IfcFile.h +++ b/src/ifcparse/IfcFile.h @@ -66,7 +66,7 @@ private: bool parsing_complete_; - const schema_definition* schema_; + const IfcParse::schema_definition* schema_; entity_by_id_t byid; entities_by_type_t bytype; @@ -173,7 +173,7 @@ public: void register_inverse(unsigned, IfcUtil::IfcBaseClass*); void unregister_inverse(unsigned, IfcUtil::IfcBaseClass*); - const schema_definition* schema() const { return schema_; } + const IfcParse::schema_definition* schema() const { return schema_; } }; } diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index e9df0a58fd..b39873d0cf 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -1124,9 +1124,15 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar std::string enum_literal = a->toString(); // Remove leading and trailing '.' enum_literal = enum_literal.substr(1, enum_literal.size() - 2); - const IfcParse::enumeration_type* enum_type = get_schema().declaration_by_name(type())->as_entity()->all_attributes()[i]->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type(); - - std::vector::const_iterator it = std::find(enum_type->enumeration_items().begin(), enum_type->enumeration_items().end(), enum_literal); + + const IfcParse::enumeration_type* enum_type = get_schema().declaration_by_name(type())->as_entity()-> + attribute_by_index(i)->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type(); + + std::vector::const_iterator it = std::find( + enum_type->enumeration_items().begin(), + enum_type->enumeration_items().end(), + enum_literal); + if (it == enum_type->enumeration_items().end()) { throw IfcParse::IfcException(enum_literal + " does not name a valid item for " + enum_type->name()); } diff --git a/src/ifcparse/IfcSchema.h b/src/ifcparse/IfcSchema.h index c3167c67ee..9eb5962393 100644 --- a/src/ifcparse/IfcSchema.h +++ b/src/ifcparse/IfcSchema.h @@ -212,7 +212,6 @@ namespace IfcParse { std::string name_; aggregate_type type_of_aggregation_; int bound1_, bound2_; - parameter_type* type_of_element_; const entity* entity_reference_; const attribute* attribute_reference_; public: @@ -252,6 +251,21 @@ namespace IfcParse { return attr->name() == name_; } }; + + const attribute* attribute_by_index_(size_t& index) const { + const attribute* attr = 0; + if (supertype_) { + attr = supertype_->attribute_by_index_(index); + } + if (attr == 0) { + if (index < attributes_.size()) { + return attributes_[index]; + } + index -= attributes_.size(); + } + return 0; + } + public: entity(const std::string& name, entity* supertype) : declaration(name) @@ -310,6 +324,22 @@ namespace IfcParse { return attrs; } + const attribute* attribute_by_index(size_t index) const { + const attribute* attr = attribute_by_index_(index); + if (attr == 0) { + throw IfcParse::IfcException("Attribute index out of bounds"); + } + return attr; + } + + size_t attribute_count() const { + size_t super_count = 0; + if (supertype_) { + super_count = supertype_->attribute_count(); + } + return super_count + attributes_.size(); + } + ptrdiff_t attribute_index(const attribute* attr) const { const entity* current = this; ptrdiff_t index = -1; diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 05a39fd4c6..794a6ef1cf 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -60,7 +60,7 @@ } IfcEntityList::ptr select_box(IfcUtil::IfcBaseClass* e, bool completely_within = false, double extend=-1.e-5) const { - if (!e->is(IfcSchema::Type::IfcProduct)) { + if (!e->declaration().is(IfcSchema::Type::IfcProduct)) { throw IfcParse::IfcException("Instance should be an IfcProduct"); } std::vector ps = $self->select_box((IfcSchema::IfcProduct*)e, completely_within, extend); @@ -78,7 +78,7 @@ } IfcEntityList::ptr select(IfcUtil::IfcBaseClass* e, bool completely_within = false) const { - if (!e->is(IfcSchema::Type::IfcProduct)) { + if (!e->declaration().is(IfcSchema::Type::IfcProduct)) { throw IfcParse::IfcException("Instance should be an IfcProduct"); } std::vector ps = $self->select((IfcSchema::IfcProduct*)e, completely_within); @@ -301,7 +301,7 @@ struct ShapeRTTI : public boost::static_visitor %inline %{ boost::variant*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) { - IfcParse::IfcFile* file = instance->entity->file; + IfcParse::IfcFile* file = instance->data().file; IfcSchema::IfcProject::list::ptr projects = file->entitiesByType(); if (projects->size() != 1) { throw IfcParse::IfcException("Not a single IfcProject instance"); @@ -313,9 +313,9 @@ struct ShapeRTTI : public boost::static_visitor kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES) ? (settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); std::pair length_unit = kernel.initializeUnits(project->UnitsInContext()); - if (instance->is(IfcSchema::Type::IfcProduct)) { + if (instance->declaration().is(IfcSchema::Type::IfcProduct)) { if (representation) { - if (!representation->is(IfcSchema::Type::IfcRepresentation)) { + if (!representation->declaration().is(IfcSchema::Type::IfcRepresentation)) { throw IfcParse::IfcException("Supplied representation not of type IfcRepresentation"); } } @@ -392,11 +392,11 @@ struct ShapeRTTI : public boost::static_visitor } IfcSchema::IfcRepresentationContext* ctx = ifc_representation->ContextOfItems(); - if (!ctx->is(IfcSchema::Type::IfcGeometricRepresentationContext)) { + if (!ctx->declaration().is(IfcSchema::Type::IfcGeometricRepresentationContext)) { throw IfcParse::IfcException("Context not of type IfcGeometricRepresentationContext"); } IfcSchema::IfcGeometricRepresentationContext* context = (IfcSchema::IfcGeometricRepresentationContext*) ctx; - if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) { + if (context->declaration().is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) { IfcSchema::IfcGeometricRepresentationSubContext* subcontext = (IfcSchema::IfcGeometricRepresentationSubContext*) context; context = subcontext->ParentContext(); } @@ -429,11 +429,11 @@ struct ShapeRTTI : public boost::static_visitor } } else { if (!representation) { - if (instance->is(IfcSchema::Type::IfcRepresentationItem) || instance->is(IfcSchema::Type::IfcRepresentation)) { + if (instance->declaration().is(IfcSchema::Type::IfcRepresentationItem) || instance->declaration().is(IfcSchema::Type::IfcRepresentation)) { IfcGeom::IfcRepresentationShapeItems shapes; if (kernel.convert_shapes(instance, shapes)) { - IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), IfcSchema::Type::ToString(instance->type())); - IfcGeom::Representation::BRep brep(element_settings, boost::lexical_cast(instance->entity->id()), shapes); + IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), IfcSchema::Type::ToString(instance->declaration().type())); + IfcGeom::Representation::BRep brep(element_settings, boost::lexical_cast(instance->data().id()), shapes); try { if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) { return new IfcGeom::Representation::Serialization(brep); diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 2119d5d29f..eefa58e813 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -24,8 +24,6 @@ private: IfcEntityInstanceData(); }; -#define invalid_argument(i, arg_name) { throw IfcParse::IfcException(IfcSchema::Type::GetAttributeName(self->entity->type(), (unsigned char)i) + " is not a valid type for '" + arg_name + "'"); } - %ignore IfcParse::IfcFile::Init; %ignore IfcParse::IfcFile::entityByGuid; %ignore IfcParse::IfcFile::register_inverse; @@ -65,7 +63,7 @@ private: return $self->entityByGuid(guid); } IfcEntityList::ptr get_inverse(IfcUtil::IfcBaseClass* e) { - return $self->getInverse(e->entity->id(), IfcSchema::Type::UNDEFINED, -1); + return $self->getInverse(e->data().id(), IfcSchema::Type::UNDEFINED, -1); } void write(const std::string& fn) { @@ -108,180 +106,243 @@ private: %extend IfcUtil::IfcBaseClass { int get_attribute_category(const std::string& name) const { - if (IfcSchema::Type::IsSimple($self->type())) { + if (IfcSchema::Type::IsSimple($self->declaration().type())) { return name == "wrappedValue"; } - IfcUtil::IfcBaseEntity* self_ = (IfcUtil::IfcBaseEntity*) self; - const std::vector names = self_->getAttributeNames(); - if (std::find(names.begin(), names.end(), name) != names.end()) { - return 1; - } else { - const std::vector names = self_->getInverseAttributeNames(); - if (std::find(names.begin(), names.end(), name) != names.end()) { - return 2; - } else { - return 0; + + { + const std::vector attrs = $self->declaration().as_entity()->all_attributes(); + std::vector::const_iterator it = attrs.begin(); + for (; it != attrs.end(); ++it) { + if ((*it)->name() == name) { + return 1; } } + } + + { + const std::vector attrs = $self->declaration().as_entity()->all_inverse_attributes(); + std::vector::const_iterator it = attrs.begin(); + for (; it != attrs.end(); ++it) { + if ((*it)->name() == name) { + return 2; + } + } + } + + return 0; } // id() is defined on IfcBaseEntity and not on IfcBaseClass, in order // to expose it to the Python wrapper it is simply duplicated here. // Same applies to the two methods reimplemented below. int id() const { - return $self->entity->id(); + return $self->data().id(); } std::vector getAttributeNames() const { - if (IfcSchema::Type::IsSimple($self->type())) { + if (!$self->declaration().as_entity()) { return std::vector(1, "wrappedValue"); } - IfcUtil::IfcBaseEntity* self_ = (IfcUtil::IfcBaseEntity*) self; - return self_->getAttributeNames(); + + const std::vector attrs = $self->declaration().as_entity()->all_attributes(); + + std::vector attr_names; + attr_names.reserve(attrs.size()); + + std::vector::const_iterator it = attrs.begin(); + for (; it != attrs.end(); ++it) { + attr_names.push_back((*it)->name()); + } + + return attr_names; } std::vector getInverseAttributeNames() const { - if (IfcSchema::Type::IsSimple($self->type())) { + if (!$self->declaration().as_entity()) { return std::vector(0); } - IfcUtil::IfcBaseEntity* self_ = (IfcUtil::IfcBaseEntity*) self; - return self_->getInverseAttributeNames(); + + const std::vector attrs = $self->declaration().as_entity()->all_inverse_attributes(); + + std::vector attr_names; + attr_names.reserve(attrs.size()); + + std::vector::const_iterator it = attrs.begin(); + for (; it != attrs.end(); ++it) { + attr_names.push_back((*it)->name()); + } + + return attr_names; } bool is_a(const std::string& s) { - return self->is(IfcSchema::Type::FromString(boost::to_upper_copy(s))); + return self->declaration().is(IfcSchema::Type::FromString(boost::to_upper_copy(s))); } std::string is_a() const { - return IfcSchema::Type::ToString(self->entity->type()); + return self->declaration().name(); } std::pair get_argument(unsigned i) { - return std::pair($self->getArgumentType(i), $self->getArgument(i)); + return std::pair($self->data().getArgument(i)->type(), $self->data().getArgument(i)); } std::pair get_argument(const std::string& a) { - unsigned i = IfcSchema::Type::GetAttributeIndex($self->type(), a); - return std::pair($self->getArgumentType(i), $self->getArgument(i)); + unsigned i = $self->declaration().as_entity()->attribute_index(a); + return std::pair($self->data().getArgument(i)->type(), $self->data().getArgument(i)); } bool __eq__(IfcUtil::IfcBaseClass* other) const { if ($self == other) { return true; } - if (IfcSchema::Type::IsSimple($self->type()) || IfcSchema::Type::IsSimple(other->type())) { + if (IfcSchema::Type::IsSimple($self->declaration().type()) || IfcSchema::Type::IsSimple(other->declaration().type())) { /// @todo return false; } else { IfcUtil::IfcBaseEntity* self_ = (IfcUtil::IfcBaseEntity*) self; IfcUtil::IfcBaseEntity* other_ = (IfcUtil::IfcBaseEntity*) other; - return self_->id() == other_->id() && self_->entity->file == other_->entity->file; + return self_->data().id() == other_->data().id() && self_->data().file == other_->data().file; } } std::string __repr__() const { - return $self->entity->toString(); + return $self->data().toString(); } // Just something to have a somewhat sensible value to hash size_t file_pointer() const { - return reinterpret_cast($self->entity->file); + return reinterpret_cast($self->data().file); } unsigned get_argument_index(const std::string& a) const { - return IfcSchema::Type::GetAttributeIndex(self->entity->type(), a); + return $self->declaration().as_entity()->attribute_index(a); } IfcEntityList::ptr get_inverse(const std::string& a) { - std::pair inv = IfcSchema::Type::GetInverseAttribute(self->entity->type(), a); - return self->entity->getInverse(inv.first, inv.second); + const std::vector attrs = $self->declaration().as_entity()->all_inverse_attributes(); + std::vector::const_iterator it = attrs.begin(); + for (; it != attrs.end(); ++it) { + if ((*it)->name() == a) { + return self->data().getInverse( + (*it)->entity_reference()->type(), + (*it)->entity_reference()->attribute_index((*it)->attribute_reference())); + } + } + throw IfcParse::IfcException(a + " not found on " + $self->declaration().name()); } void setArgumentAsNull(unsigned int i) { - bool is_optional = IfcSchema::Type::GetAttributeOptional(self->entity->type(), (unsigned char)i); + bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional(); if (is_optional) { - self->entity->setArgument(i, new IfcWrite::IfcWriteArgument()); - } else invalid_argument(i,"NULL"); + self->data().setArgument(i, new IfcWrite::IfcWriteArgument()); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsInt(unsigned int i, int v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_INT) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); + self->data().setArgument(i, arg); } else if ( (arg_type == IfcUtil::Argument_BOOL) && ( (v == 0) || (v == 1) ) ) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v == 1); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"INTEGER"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsBool(unsigned int i, bool v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_BOOL) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"BOOLEAN"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsDouble(unsigned int i, double v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_DOUBLE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"REAL"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsString(unsigned int i, const std::string& a) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_STRING) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(a); - self->entity->setArgument(i, arg); + self->data().setArgument(i, arg); } else if (arg_type == IfcUtil::Argument_ENUMERATION) { - std::pair enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEntity(self->entity->type(), (unsigned char)i), a); + const IfcParse::enumeration_type* enum_type = get_schema().declaration_by_name($self->declaration().type())->as_entity()-> + attribute_by_index(i)->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type(); + + std::vector::const_iterator it = std::find( + enum_type->enumeration_items().begin(), + enum_type->enumeration_items().end(), + a); + + if (it == enum_type->enumeration_items().end()) { + throw IfcParse::IfcException(a + " does not name a valid item for " + enum_type->name()); + } + IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); - arg->set(IfcWrite::IfcWriteArgument::EnumerationReference(enum_data.second, enum_data.first)); - self->entity->setArgument(i, arg); + arg->set(IfcWrite::IfcWriteArgument::EnumerationReference(it - enum_type->enumeration_items().begin(), it->c_str())); + self->data().setArgument(i, arg); } else if (arg_type == IfcUtil::Argument_BINARY) { if (IfcUtil::valid_binary_string(a)) { boost::dynamic_bitset<> bits(a); IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(bits); - self->entity->setArgument(i, arg); + self->data().setArgument(i, arg); } else { throw IfcParse::IfcException("String not a valid binary representation"); } - } else invalid_argument(i,"STRING"); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfInt(unsigned int i, const std::vector& v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_INT) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF INT"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfDouble(unsigned int i, const std::vector& v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF DOUBLE"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfString(unsigned int i, const std::vector& v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_STRING) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); + self->data().setArgument(i, arg); } else if (arg_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) { std::vector< boost::dynamic_bitset<> > bits; bits.reserve(v.size()); @@ -294,53 +355,65 @@ private: } IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(bits); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF STRING"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsEntityInstance(unsigned int i, IfcUtil::IfcBaseClass* v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_ENTITY_INSTANCE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"ENTITY INSTANCE"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfEntityInstance(unsigned int i, IfcEntityList::ptr v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF ENTITY INSTANCE"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfAggregateOfInt(unsigned int i, const std::vector< std::vector >& v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF AGGREGATE OF INT"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfAggregateOfDouble(unsigned int i, const std::vector< std::vector >& v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF AGGREGATE OF DOUBLE"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } void setArgumentAsAggregateOfAggregateOfEntityInstance(unsigned int i, IfcEntityListList::ptr v) { - IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(self->entity->type(), (unsigned char)i); + IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute()); if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) { IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); arg->set(v); - self->entity->setArgument(i, arg); - } else invalid_argument(i,"AGGREGATE OF AGGREGATE OF ENTITY INSTANCE"); + self->data().setArgument(i, arg); + } else { + throw IfcParse::IfcException("Attribute not set"); + } } } @@ -448,8 +521,28 @@ private: IfcUtil::IfcBaseClass* new_IfcBaseClass(const std::string& s) { IfcSchema::Type::Enum ty = IfcSchema::Type::FromString(boost::to_upper_copy(s)); IfcEntityInstanceData* data = new IfcEntityInstanceData(ty); - data->setArgument(IfcSchema::Type::GetAttributeCount(ty) - 1, new IfcWrite::IfcWriteArgument()); - IfcSchema::Type::PopulateDerivedFields(data); + + size_t attr_count = 1; + if (get_schema().declaration_by_name(ty)->as_entity()) { + attr_count = get_schema().declaration_by_name(ty)->as_entity()->attribute_count(); + } + + data->setArgument(attr_count - 1, new IfcWrite::IfcWriteArgument()); + + if (get_schema().declaration_by_name(ty)->as_entity()) { + const std::vector& derived = get_schema().declaration_by_name(ty)->as_entity()->derived(); + std::vector::const_iterator it = derived.begin(); + + size_t index = 0; + for (; it != derived.end(); ++it, ++index) { + if (*it) { + IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument(); + arg->set(IfcWrite::IfcWriteArgument::Derived()); + data->setArgument(index, arg); + } + } + } + return IfcSchema::SchemaEntity(data); } %} diff --git a/src/ifcwrap/IfcPython.i b/src/ifcwrap/IfcPython.i index 8eab101db1..9dd6311559 100644 --- a/src/ifcwrap/IfcPython.i +++ b/src/ifcwrap/IfcPython.i @@ -76,12 +76,6 @@ #include "../ifcparse/IfcBaseClass.h" #include "../ifcparse/IfcFile.h" - - #ifdef USE_IFC4 - #include "../ifcparse/Ifc4-latebound.h" - #else - #include "../ifcparse/Ifc2x3-latebound.h" - #endif #include %}