diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index d00bda2049..c8c24e5188 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -382,7 +382,9 @@ bool TokenFunc::isKeyword(const Token& t) { } bool TokenFunc::isInt(const Token& t) { - if (isOperator(t)) return false; + if (isOperator(t) || isString(t) || isEnumeration(t)) { + return false; + } const std::string str = asString(t); const char* start = str.c_str(); char* end; @@ -397,7 +399,9 @@ bool TokenFunc::isBool(const Token& t) { } bool TokenFunc::isFloat(const Token& t) { - if (isOperator(t)) return false; + if (isOperator(t) || isString(t) || isEnumeration(t)) { + return false; + } const std::string str = asString(t); const char* start = str.c_str(); char* end; @@ -623,6 +627,10 @@ IfcUtil::ArgumentType TokenArgument::type() const { return IfcUtil::Argument_ENUMERATION; } else if (TokenFunc::isIdentifier(token)) { return IfcUtil::Argument_ENTITY; + } else if (TokenFunc::isOperator(token, '$')) { + return IfcUtil::Argument_NULL; + } else if (TokenFunc::isOperator(token, '*')) { + return IfcUtil::Argument_DERIVED; } else { return IfcUtil::Argument_UNKNOWN; } @@ -991,7 +999,9 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) { entity_file_map.insert(entity_entity_map_t::value_type(*it, addEntity(*it))); } } - } catch (...) {} + } catch (...) { + Logger::Message(Logger::LOG_ERROR, "Failed to visit forward references of", entity->entity); + } // See whether the instance is already part of a file if (entity->entity->file != 0) { @@ -1020,12 +1030,16 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) { Argument* attr = we->getArgument(i); IfcUtil::ArgumentType attr_type = attr->type(); if (attr_type == IfcUtil::Argument_ENTITY) { - we->setArgument(i, entity_file_map[*attr]); + entity_entity_map_t::const_iterator eit = entity_file_map.find(*attr); + if (eit == entity_file_map.end()) throw IfcParse::IfcException("Unable to map instance to file"); + we->setArgument(i, eit->second); } else if (attr_type == IfcUtil::Argument_ENTITY_LIST) { IfcEntityList::ptr instances = *attr; IfcEntityList::ptr new_instances(new IfcEntityList); for (IfcEntityList::it it = instances->begin(); it != instances->end(); ++it) { - new_instances->push(entity_file_map[*it]); + entity_entity_map_t::const_iterator eit = entity_file_map.find(*it); + if (eit == entity_file_map.end()) throw IfcParse::IfcException("Unable to map instance to file"); + new_instances->push(eit->second); } we->setArgument(i, new_instances); } else if (attr_type == IfcUtil::Argument_ENTITY_LIST_LIST) { @@ -1034,7 +1048,9 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) { for (IfcEntityListList::outer_it it = instances->begin(); it != instances->end(); ++it) { std::vector list; for (IfcEntityListList::inner_it jt = it->begin(); jt != it->end(); ++jt) { - list.push_back(entity_file_map[*jt]); + entity_entity_map_t::const_iterator eit = entity_file_map.find(*jt); + if (eit == entity_file_map.end()) throw IfcParse::IfcException("Unable to map instance to file"); + list.push_back(eit->second); } new_instances->push(list); } diff --git a/src/ifcparse/IfcWritableEntity.h b/src/ifcparse/IfcWritableEntity.h index 90c60c7c67..832ec2d145 100644 --- a/src/ifcparse/IfcWritableEntity.h +++ b/src/ifcparse/IfcWritableEntity.h @@ -61,7 +61,8 @@ namespace IfcWrite { unsigned int id(); IfcWritableEntity* isWritable(); - void setArgument(int i); + void setArgument(int i); + void setArgument(int i, Argument* a); void setArgumentDerived(int i); void setArgument(int i,bool v); void setArgument(int i,int v); diff --git a/src/ifcparse/IfcWrite.cpp b/src/ifcparse/IfcWrite.cpp index f0b95e1fc9..a95fa39cc8 100644 --- a/src/ifcparse/IfcWrite.cpp +++ b/src/ifcparse/IfcWrite.cpp @@ -26,6 +26,12 @@ #include "../ifcparse/IfcCharacterDecoder.h" #include "../ifcparse/IfcFile.h" +#ifdef USE_IFC4 +#include "../ifcparse/Ifc4-latebound.h" +#else +#include "../ifcparse/Ifc2x3-latebound.h" +#endif + using namespace IfcWrite; IfcWritableEntity::IfcWritableEntity(IfcSchema::Type::Enum t) { @@ -56,8 +62,7 @@ IfcWritableEntity::IfcWritableEntity(IfcAbstractEntity* e) const unsigned int count = e->getArgumentCount(); for ( unsigned int i = 0; i < count; ++ i ) { - args[i] = e->getArgument(i); - writemask[i] = false; + this->setArgument(i, e->getArgument(i)); } } @@ -131,6 +136,76 @@ template void IfcWritableEntity::_setArgument(int i, const T& t) { void IfcWritableEntity::setArgument(int i) { _setArgument(i, boost::none); } + +void IfcWritableEntity::setArgument(int i, Argument* a) { + IfcWrite::IfcWriteArgument* wa = new IfcWrite::IfcWriteArgument(this); + IfcUtil::ArgumentType attr_type = a->type(); + switch(attr_type) { + case IfcUtil::Argument_NULL: + this->setArgument(i); + break; + case IfcUtil::Argument_DERIVED: + this->setArgumentDerived(i); + break; + case IfcUtil::Argument_INT: + this->setArgument(i, static_cast(*a)); + break; + case IfcUtil::Argument_BOOL: + this->setArgument(i, static_cast(*a)); + break; + case IfcUtil::Argument_DOUBLE: + this->setArgument(i, static_cast(*a)); + break; + case IfcUtil::Argument_STRING: + this->setArgument(i, static_cast(*a)); + break; + case IfcUtil::Argument_VECTOR_INT: + this->setArgument(i, static_cast< std::vector >(*a)); + break; + case IfcUtil::Argument_VECTOR_DOUBLE: + this->setArgument(i, static_cast< std::vector >(*a)); + break; + case IfcUtil::Argument_VECTOR_STRING: + this->setArgument(i, static_cast< std::vector< std::string > >(*a)); + break; + case IfcUtil::Argument_ENUMERATION: { + IfcSchema::Type::Enum ty = IfcSchema::Type::GetAttributeEntity(_type, i); + std::string enum_literal = a->toString(); + // Remove leading and trailing '.' + enum_literal = enum_literal.substr(1, enum_literal.size() - 2); + std::pair enum_ref = IfcSchema::Type::GetEnumerationIndex(ty, enum_literal); + this->setArgument(i, enum_ref.second, enum_ref.first); } + break; + case IfcUtil::Argument_ENTITY: { + this->setArgument(i, static_cast(*a)); } + break; + case IfcUtil::Argument_ENTITY_LIST: { + IfcEntityList::ptr instances = *a; + IfcEntityList::ptr mapped_instances(new IfcEntityList); + for (IfcEntityList::it it = instances->begin(); it != instances->end(); ++it) { + mapped_instances->push(*it); + } + this->setArgument(i, mapped_instances); } + break; + case IfcUtil::Argument_ENTITY_LIST_LIST: { + IfcEntityListList::ptr instances = *a; + IfcEntityListList::ptr mapped_instances(new IfcEntityListList); + for (IfcEntityListList::outer_it it = instances->begin(); it != instances->end(); ++it) { + std::vector inner; + for (IfcEntityListList::inner_it jt = it->begin(); jt != it->end(); ++jt) { + inner.push_back(*jt); + } + mapped_instances->push(inner); + } + this->setArgument(i, mapped_instances); } + break; + case IfcUtil::Argument_UNKNOWN: + throw IfcParse::IfcException("Unknown argument encountered"); + break; + } +} + + void IfcWritableEntity::setArgumentDerived(int i) { _setArgument(i, IfcWriteArgument::Derived()); }