mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Create writable argument copies when duplicating entity instances
This commit is contained in:
@@ -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<IfcUtil::IfcBaseClass*> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <typename T> 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<int>(*a));
|
||||
break;
|
||||
case IfcUtil::Argument_BOOL:
|
||||
this->setArgument(i, static_cast<bool>(*a));
|
||||
break;
|
||||
case IfcUtil::Argument_DOUBLE:
|
||||
this->setArgument(i, static_cast<double>(*a));
|
||||
break;
|
||||
case IfcUtil::Argument_STRING:
|
||||
this->setArgument(i, static_cast<std::string>(*a));
|
||||
break;
|
||||
case IfcUtil::Argument_VECTOR_INT:
|
||||
this->setArgument(i, static_cast< std::vector<int> >(*a));
|
||||
break;
|
||||
case IfcUtil::Argument_VECTOR_DOUBLE:
|
||||
this->setArgument(i, static_cast< std::vector<double> >(*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<const char*, int> 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<IfcUtil::IfcBaseClass*>(*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<IfcUtil::IfcBaseClass*> 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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user