diff --git a/src/ifcparse/IfcGuidHelper.cpp b/src/ifcparse/IfcGuidHelper.cpp
new file mode 100644
index 0000000000..3be07519a2
--- /dev/null
+++ b/src/ifcparse/IfcGuidHelper.cpp
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * *
+ * This file is part of IfcOpenShell. *
+ * *
+ * IfcOpenShell is free software: you can redistribute it and/or modify *
+ * it under the terms of the Lesser GNU General Public License as published by *
+ * the Free Software Foundation, either version 3.0 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * IfcOpenShell is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * Lesser GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the Lesser GNU General Public License *
+ * along with this program. If not, see . *
+ * *
+ ********************************************************************************/
+
+/********************************************************************************
+ * *
+ * Please consider this a placeholder for an actual GlobalId generation *
+ * algorithm. A real implementation could for example be based on Boost::uuid *
+ * *
+ ********************************************************************************/
+
+#include
+
+#include "IfcWrite.h"
+
+static const char* chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
+
+IfcWrite::IfcGuidHelper::IfcGuidHelper() {
+ if ( ! seeded ) { srand((unsigned int)time(0)); seeded = true; }
+ data.resize(length);
+ for ( unsigned int i = 0; i < length; ++ i ) {
+ data[i] = chars[rand()%length];
+ }
+}
+IfcWrite::IfcGuidHelper::operator std::string() const {
+ return data;
+}
+
+bool IfcWrite::IfcGuidHelper::seeded = false;
\ No newline at end of file
diff --git a/src/ifcparse/IfcWritableEntity.h b/src/ifcparse/IfcWritableEntity.h
new file mode 100644
index 0000000000..f2f950b67f
--- /dev/null
+++ b/src/ifcparse/IfcWritableEntity.h
@@ -0,0 +1,73 @@
+/********************************************************************************
+ * *
+ * This file is part of IfcOpenShell. *
+ * *
+ * IfcOpenShell is free software: you can redistribute it and/or modify *
+ * it under the terms of the Lesser GNU General Public License as published by *
+ * the Free Software Foundation, either version 3.0 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * IfcOpenShell is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * Lesser GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the Lesser GNU General Public License *
+ * along with this program. If not, see . *
+ * *
+ ********************************************************************************/
+
+/********************************************************************************
+ * *
+ * This namespace provides implementations of Argument and Entity that use STL *
+ * containers for their datatypes and are not just lazy references to the *
+ * IFC-SPF file. Therefore they can be modified by the client application. *
+ * *
+ * An IfcWritableEntity can be constructed from a regular IfcParse entity to be *
+ * able to modify the data in existing IFC files. *
+ * *
+ ********************************************************************************/
+
+#ifndef IFCWRITABLEENTITY_H
+#define IFCWRITABLEENTITY_H
+
+#include "IfcUtil.h"
+
+namespace IfcWrite {
+ class IfcWritableEntity : public IfcAbstractEntity {
+ private:
+ std::map writemask;
+ std::map args;
+ Ifc2x3::Type::Enum _type;
+ int* _id;
+ bool arg_writable(int i);
+ void arg_writable(int i, bool b);
+ public:
+ IfcWritableEntity(Ifc2x3::Type::Enum t);
+ int setId(int i=-1);
+ IfcWritableEntity(IfcAbstractEntity* e);
+ IfcEntities getInverse(Ifc2x3::Type::Enum c = Ifc2x3::Type::ALL);
+ IfcEntities getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a);
+ std::string datatype();
+ ArgumentPtr getArgument (unsigned int i);
+ unsigned int getArgumentCount();
+ Ifc2x3::Type::Enum type() const;
+ bool is(Ifc2x3::Type::Enum v) const;
+ std::string toString(bool upper=false);
+ unsigned int id();
+ bool isWritable();
+ void setArgument(int i,int v);
+ void setArgument(int i,int v, const char* c);
+ void setArgument(int i,const Nullable& v);
+ void setArgument(int i,const std::string& v);
+ void setArgument(int i,double v);
+ void setArgument(int i,IfcUtil::IfcSchemaEntity v);
+ void setArgument(int i,IfcEntities v);
+ void setArgument(int i,const std::vector& v);
+ void setArgument(int i,const std::vector& v);
+ void setArgument(int i,const std::vector& v);
+ };
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/ifcparse/IfcWrite.cpp b/src/ifcparse/IfcWrite.cpp
new file mode 100644
index 0000000000..dddd688112
--- /dev/null
+++ b/src/ifcparse/IfcWrite.cpp
@@ -0,0 +1,372 @@
+/********************************************************************************
+ * *
+ * This file is part of IfcOpenShell. *
+ * *
+ * IfcOpenShell is free software: you can redistribute it and/or modify *
+ * it under the terms of the Lesser GNU General Public License as published by *
+ * the Free Software Foundation, either version 3.0 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * IfcOpenShell is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * Lesser GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the Lesser GNU General Public License *
+ * along with this program. If not, see . *
+ * *
+ ********************************************************************************/
+
+#include "IfcParse.h"
+#include "IfcWrite.h"
+#include "IfcWritableEntity.h"
+
+using namespace IfcWrite;
+
+IfcWritableEntity::IfcWritableEntity(Ifc2x3::Type::Enum t) {
+ _type = t;
+ _id = 0;
+}
+int IfcWritableEntity::setId(int i) {
+ return *(_id = new int(i > 0 ? i : Ifc::FreshId()));
+}
+IfcWritableEntity::IfcWritableEntity(IfcAbstractEntity* e)
+{
+ _type = e->type();
+ _id = new int(e->id());
+
+ const unsigned int count = e->getArgumentCount();
+ for ( unsigned int i = 0; i < count; ++ i ) {
+ args[i] = e->getArgument(i);
+ writemask[i] = false;
+ }
+}
+// TODO: Reove redundancy with IfcParse::Entity
+IfcEntities IfcWritableEntity::getInverse(Ifc2x3::Type::Enum c) {
+ IfcEntities l = IfcEntities(new IfcEntityList());
+ int id = _id ? *_id : setId();
+ IfcEntities all = Ifc::EntitiesByReference(id);
+ if ( ! all ) return l;
+ for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
+ if ( c == Ifc2x3::Type::ALL || (*it)->is(c) ) {
+ l->push(*it);
+ }
+ }
+ return l;
+}
+IfcEntities IfcWritableEntity::getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a) {
+ IfcEntities l = IfcEntities(new IfcEntityList());
+ IfcEntities all = getInverse(c);
+ for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
+ const std::string s = *(*it)->entity->getArgument(i);
+ if ( s == a ) {
+ l->push(*it);
+ }
+ }
+ return l;
+}
+
+std::string IfcWritableEntity::datatype() { return Ifc2x3::Type::ToString(_type); }
+ArgumentPtr IfcWritableEntity::getArgument (unsigned int i) { if ( i >= getArgumentCount() ) throw; return args[i]; }
+unsigned int IfcWritableEntity::getArgumentCount() {return args.size(); }
+Ifc2x3::Type::Enum IfcWritableEntity::type() const { return _type; }
+bool IfcWritableEntity::is(Ifc2x3::Type::Enum v) const { return _type == v; }
+std::string IfcWritableEntity::toString(bool upper) {
+ std::stringstream ss;
+ std::string dt = datatype();
+ if ( upper ) {
+ for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
+ }
+ if ( _id ) ss << "#" << *_id;
+ ss << "=" << dt << "(";
+ for ( std::map::const_iterator it = args.begin(); it != args.end(); ++ it ) {
+ if ( it != args.begin() ) ss << ",";
+ const ArgumentPtr a = it->second;
+ ss << it->second->toString(upper);
+ }
+ ss << ")";
+ return ss.str();
+}
+unsigned int IfcWritableEntity::id() { if ( !_id ) _id = new int(Ifc::FreshId()); return *_id; }
+bool IfcWritableEntity::isWritable() { return true; }
+bool IfcWritableEntity::arg_writable(int i) {
+ std::map::const_iterator it = writemask.find(i);
+ if ( it == writemask.end() ) return false;
+ else return it->second;
+}
+void IfcWritableEntity::arg_writable(int i, bool b) {
+ writemask[i] = b;
+}
+void IfcWritableEntity::setArgument(int i,int v) {
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,int v, const char* c){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteEnumerationArgument(v,c);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,const std::string& v){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,const Nullable& v){
+ if ( arg_writable(i) ) delete args[i];
+ if ( v.IsNull() ) new IfcWriteNullArgument();
+ else args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,double v){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,IfcUtil::IfcSchemaEntity v){
+ if ( arg_writable(i) ) delete args[i];
+ if ( v ) args[i] = new IfcWriteIntegralArgument(v);
+ else args[i] = new IfcWriteNullArgument();
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,IfcEntities v){
+ if ( arg_writable(i) ) delete args[i];
+ if ( v.get() ) args[i] = new IfcWriteEntityListArgument(v);
+ else args[i] = new IfcWriteNullArgument();
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,const std::vector& v){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,const std::vector& v){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+void IfcWritableEntity::setArgument(int i,const std::vector& v){
+ if ( arg_writable(i) ) delete args[i];
+ args[i] = new IfcWriteIntegralArgument(v);
+ arg_writable(i,true);
+}
+
+IfcWriteNullArgument::operator int() const { throw; }
+IfcWriteNullArgument::operator bool() const { throw; }
+IfcWriteNullArgument::operator double() const { throw; }
+IfcWriteNullArgument::operator std::string() const { throw; }
+IfcWriteNullArgument::operator std::vector() const { throw; }
+IfcWriteNullArgument::operator std::vector() const { throw; }
+IfcWriteNullArgument::operator std::vector() const { throw; }
+IfcWriteNullArgument::operator IfcUtil::IfcSchemaEntity() const { throw; }
+IfcWriteNullArgument::operator IfcEntities() const { throw; }
+bool IfcWriteNullArgument::isNull() const { return true; }
+ArgumentPtr IfcWriteNullArgument::operator [] (unsigned int i) const { throw; }
+std::string IfcWriteNullArgument::toString(bool upper) const { return "$"; }
+unsigned int IfcWriteNullArgument::Size() const { throw; }
+
+IfcWriteEntityListArgument::IfcWriteEntityListArgument(const IfcEntities& v) { value = v; }
+IfcWriteEntityListArgument::operator int() const { throw; }
+IfcWriteEntityListArgument::operator bool() const { throw; }
+IfcWriteEntityListArgument::operator double() const { throw; }
+IfcWriteEntityListArgument::operator std::string() const { throw; }
+IfcWriteEntityListArgument::operator std::vector() const { throw; }
+IfcWriteEntityListArgument::operator std::vector() const { throw; }
+IfcWriteEntityListArgument::operator std::vector() const { throw; }
+IfcWriteEntityListArgument::operator IfcUtil::IfcSchemaEntity() const { throw; }
+IfcWriteEntityListArgument::operator IfcEntities() const { return value; }
+bool IfcWriteEntityListArgument::isNull() const { return false; }
+unsigned int IfcWriteEntityListArgument::Size() const { return value->Size(); }
+ArgumentPtr IfcWriteEntityListArgument::operator [] (unsigned int i) const { throw; }
+std::string IfcWriteEntityListArgument::toString(bool upper) const {
+ std::ostringstream ss;
+ ss << "(";
+ for ( IfcEntityList::it it = value->begin(); it != value->end(); ++ it ) {
+ if ( it != value->begin() ) ss << ",";
+ IfcAbstractEntity* e = (*it)->entity;
+ if ( Ifc2x3::Type::IsSimple(e->type()) ) {
+ ss << e->toString(upper);
+ } else {
+ ss << "#" << e->id();
+ }
+ }
+ ss << ")";
+ return ss.str();
+}
+
+IfcWriteEnumerationArgument::IfcWriteEnumerationArgument(int v, const char* c) {data=v; enumeration_value = c;}
+IfcWriteEnumerationArgument::operator int() const { throw; }
+IfcWriteEnumerationArgument::operator bool() const { throw; }
+IfcWriteEnumerationArgument::operator double() const { throw; }
+IfcWriteEnumerationArgument::operator std::string() const { return std::string(enumeration_value); }
+IfcWriteEnumerationArgument::operator std::vector() const { throw; }
+IfcWriteEnumerationArgument::operator std::vector() const { throw; }
+IfcWriteEnumerationArgument::operator std::vector() const { throw; }
+IfcWriteEnumerationArgument::operator IfcUtil::IfcSchemaEntity() const { throw; }
+IfcWriteEnumerationArgument::operator IfcEntities() const { throw; }
+bool IfcWriteEnumerationArgument::isNull() const { return false; }
+ArgumentPtr IfcWriteEnumerationArgument::operator [] (unsigned int i) const { throw; }
+std::string IfcWriteEnumerationArgument::toString(bool upper) const { return std::string(".") + enumeration_value + '.';}
+unsigned int IfcWriteEnumerationArgument::Size() const { throw; }
+
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(int v) {data=new int(v); type = Argument_INT;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(bool v) {data=new bool(v); type = Argument_BOOL;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(double v) {data=new double(v); type = Argument_DOUBLE;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(const std::string& v) {data=new std::string(v); type = Argument_STRING;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(const std::vector v) {data=new std::vector(v); type = Argument_VECTOR_INT;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(const std::vector v) {data=new std::vector(v); type = Argument_VECTOR_DOUBLE;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(const std::vector v) {data=new std::vector(v); type = Argument_VECTOR_STRING;}
+IfcWriteIntegralArgument::IfcWriteIntegralArgument(IfcUtil::IfcSchemaEntity v) {data=v; type = Argument_ENTITY;}
+IfcWriteIntegralArgument::~IfcWriteIntegralArgument() {
+ switch ( type ) {
+ case Argument_INT:
+ delete (int*) data;
+ break;
+ case Argument_BOOL:
+ delete (bool*) data;
+ break;
+ case Argument_DOUBLE:
+ delete (double*) data;
+ break;
+ case Argument_STRING:
+ delete (std::string*) data;
+ break;
+ case Argument_VECTOR_INT:
+ delete (std::vector*) data;
+ break;
+ case Argument_VECTOR_DOUBLE:
+ delete (std::vector*) data;
+ break;
+ case Argument_VECTOR_STRING:
+ delete (std::vector*) data;
+ break;
+ case Argument_ENTITY:
+ break;
+ }
+}
+IfcWriteIntegralArgument::operator int() const { if ( type != Argument_INT ) throw; return *(int*)data; }
+IfcWriteIntegralArgument::operator bool() const { if ( type != Argument_BOOL ) throw; return *(bool*)data; }
+IfcWriteIntegralArgument::operator double() const { if ( type != Argument_DOUBLE ) throw; return *(double*)data; }
+IfcWriteIntegralArgument::operator std::string() const { if ( type != Argument_STRING ) throw; return *(std::string*)data; }
+IfcWriteIntegralArgument::operator std::vector() const { if ( type != Argument_VECTOR_DOUBLE ) throw; return *(std::vector*)data; }
+IfcWriteIntegralArgument::operator std::vector() const { if ( type != Argument_VECTOR_INT ) throw; return *(std::vector*)data; }
+IfcWriteIntegralArgument::operator std::vector() const { if ( type != Argument_VECTOR_STRING ) throw; return *(std::vector*)data; }
+IfcWriteIntegralArgument::operator IfcUtil::IfcSchemaEntity() const { if ( type != Argument_ENTITY ) throw; return (IfcUtil::IfcSchemaEntity)data; }
+IfcWriteIntegralArgument::operator IfcEntities() const { throw; }
+bool IfcWriteIntegralArgument::isNull() const { return false; }
+unsigned int IfcWriteIntegralArgument::Size() const {
+ switch ( type ) {
+ case Argument_VECTOR_INT:
+ return ((std::vector*) data)->size();
+ break;
+ case Argument_VECTOR_DOUBLE:
+ return ((std::vector*) data)->size();
+ break;
+ case Argument_VECTOR_STRING:
+ return ((std::vector*) data)->size();
+ break;
+ default:
+ throw;
+ break;
+ }
+}
+ArgumentPtr IfcWriteIntegralArgument::operator [] (unsigned int i) const { throw; }
+std::string IfcWriteIntegralArgument::toString(bool upper) const {
+ std::ostringstream ss;
+ switch ( type ) {
+ case Argument_INT:
+ ss << *(int*)data;
+ break;
+ case Argument_BOOL:
+ ss << ((*(bool*) data) ? ".T." : ".F.");
+ break;
+ case Argument_DOUBLE:
+ ss << *(double*) data;
+ break;
+ case Argument_STRING:
+ ss << '\'' << *(std::string*) data << '\'';
+ break;
+ case Argument_VECTOR_INT:
+ ss << "(";
+ {const std::vector& v = *(std::vector*) data;
+ for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++ it ) {
+ if ( it != v.begin() ) ss << ",";
+ ss << *it;
+ }}
+ ss << ")";
+ break;
+ case Argument_VECTOR_DOUBLE:
+ ss << "(";
+ {const std::vector& v = *(std::vector*) data;
+ for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++ it ) {
+ if ( it != v.begin() ) ss << ",";
+ ss << *it;
+ }}
+ ss << ")";
+ break;
+ case Argument_VECTOR_STRING:
+ ss << "(";
+ {const std::vector& v = *(std::vector*) data;
+ for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++ it ) {
+ if ( it != v.begin() ) ss << ",";
+ ss << '\'' << *it << '\'';
+ }}
+ ss << ")";
+ break;
+ case Argument_ENTITY:
+ {IfcAbstractEntity* e = ((IfcUtil::IfcSchemaEntity)data)->entity;
+ if ( Ifc2x3::Type::IsSimple(e->type()) ) {
+ ss << e->toString(upper);
+ } else {
+ ss << "#" << e->id();
+ }}
+ break;
+ default: throw;
+ }
+ return ss.str();
+}
+
+IfcEntities IfcSelectHelperEntity::getInverse(Ifc2x3::Type::Enum,int,const std::string &) {throw;}
+IfcEntities IfcSelectHelperEntity::getInverse(Ifc2x3::Type::Enum) {throw;}
+std::string IfcSelectHelperEntity::datatype() { return Ifc2x3::Type::ToString(_type); }
+ArgumentPtr IfcSelectHelperEntity::getArgument(unsigned int i) {
+ if ( i != 0 ) throw;
+ return arg;
+}
+unsigned int IfcSelectHelperEntity::getArgumentCount() { return 1; }
+Ifc2x3::Type::Enum IfcSelectHelperEntity::type() const { return _type; }
+bool IfcSelectHelperEntity::is(Ifc2x3::Type::Enum t) const { return _type == t; }
+std::string IfcSelectHelperEntity::toString(bool upper) {
+ std::stringstream ss;
+ std::string dt = datatype();
+ if ( upper ) {
+ for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
+ }
+ ss << dt << "(" << arg->toString(upper) << ")";
+ return ss.str();
+}
+unsigned int IfcSelectHelperEntity::id() { throw; }
+bool IfcSelectHelperEntity::isWritable() { throw; }
+
+IfcSelectHelper::IfcSelectHelper(const std::string& v, Ifc2x3::Type::Enum t) {
+ IfcWriteArgument* a = new IfcWriteIntegralArgument(v);
+ this->entity = new IfcSelectHelperEntity(t,a);
+}
+IfcSelectHelper::IfcSelectHelper(const char* const v, Ifc2x3::Type::Enum t) {
+ IfcWriteArgument* a = new IfcWriteIntegralArgument(std::string(v));
+ this->entity = new IfcSelectHelperEntity(t,a);
+}
+IfcSelectHelper::IfcSelectHelper(int v, Ifc2x3::Type::Enum t) {
+ IfcWriteArgument* a = new IfcWriteIntegralArgument(v);
+ this->entity = new IfcSelectHelperEntity(t,a);
+}
+IfcSelectHelper::IfcSelectHelper(float v, Ifc2x3::Type::Enum t) {
+ IfcWriteArgument* a = new IfcWriteIntegralArgument(v);
+ this->entity = new IfcSelectHelperEntity(t,a);
+}
+IfcSelectHelper::IfcSelectHelper(bool v, Ifc2x3::Type::Enum t) {
+ IfcWriteArgument* a = new IfcWriteIntegralArgument(v);
+ this->entity = new IfcSelectHelperEntity(t,a);
+}
+bool IfcSelectHelper::is(Ifc2x3::Type::Enum t) const { return entity->is(t); }
+Ifc2x3::Type::Enum IfcSelectHelper::type() const { return entity->type(); }
\ No newline at end of file
diff --git a/src/ifcparse/IfcWrite.h b/src/ifcparse/IfcWrite.h
new file mode 100644
index 0000000000..3b3e288f2d
--- /dev/null
+++ b/src/ifcparse/IfcWrite.h
@@ -0,0 +1,194 @@
+/********************************************************************************
+ * *
+ * This file is part of IfcOpenShell. *
+ * *
+ * IfcOpenShell is free software: you can redistribute it and/or modify *
+ * it under the terms of the Lesser GNU General Public License as published by *
+ * the Free Software Foundation, either version 3.0 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * IfcOpenShell is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * Lesser GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the Lesser GNU General Public License *
+ * along with this program. If not, see . *
+ * *
+ ********************************************************************************/
+
+/********************************************************************************
+ * *
+ * This namespace provides implementations of Argument and Entity that use STL *
+ * containers for their datatypes and are not just lazy references to the *
+ * IFC-SPF file. Therefore they can be modified by the client application. *
+ * *
+ ********************************************************************************/
+
+#ifndef IFCWRITE_H
+#define IFCWRITE_H
+
+#include "IfcUtil.h"
+#include "IfcParse.h"
+
+namespace IfcWrite {
+
+ /// A placeholder class for grouping functionality geared towards writing IFC files
+ class IfcWriteArgument : public Argument {
+
+ };
+
+ /// A null argument. It will always serialize to $
+ class IfcWriteNullArgument : public IfcWriteArgument {
+ public:
+ operator int() const;
+ operator bool() const;
+ operator double() const;
+ operator std::string() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator IfcUtil::IfcSchemaEntity() const;
+ operator IfcEntities() const;
+ bool isNull() const;
+ ArgumentPtr operator [] (unsigned int i) const;
+ std::string toString(bool upper=false) const;
+ unsigned int Size() const;
+ };
+
+ /// An entity list argument. It will serialize to (#1,#2,#3)
+ /// with possibly a datatype identifier for SELECT types, e.g:
+ /// (IFCREAL(1.0),IFCINTEGER(1))
+ class IfcWriteEntityListArgument : public IfcWriteArgument {
+ private:
+ IfcEntities value;
+ public:
+ IfcWriteEntityListArgument(const IfcEntities& v);
+ operator int() const;
+ operator bool() const;
+ operator double() const;
+ operator std::string() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator IfcUtil::IfcSchemaEntity() const;
+ operator IfcEntities() const;
+ bool isNull() const;
+ unsigned int Size() const;
+ ArgumentPtr operator [] (unsigned int i) const;
+ std::string toString(bool upper=false) const;
+ };
+
+ /// An enumeration argument. It will serialize to e.g:
+ /// .USERDEFINED. To initialize the argument a string representation
+ /// has to be explicitely passed of the enumeration value which
+ /// is stored internally as an integer. The argument itself
+ /// does not keep track of what schema enumeration type is
+ /// represented.
+ class IfcWriteEnumerationArgument : public IfcWriteArgument {
+ private:
+ int data;
+ const char* enumeration_value;
+ public:
+ IfcWriteEnumerationArgument(int v, const char* c);
+ operator int() const;
+ operator bool() const;
+ operator double() const;
+ operator std::string() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator IfcUtil::IfcSchemaEntity() const;
+ operator IfcEntities() const;
+ bool isNull() const;
+ ArgumentPtr operator [] (unsigned int i) const;
+ std::string toString(bool upper=false) const;
+ unsigned int Size() const;
+ };
+
+ /// An argument for all remaining types of arguments. For example:
+ /// #123 | 1 | 'Value' | (1.0,2.0,3.0). All data is casted to a
+ /// void pointer.
+ class IfcWriteIntegralArgument : public IfcWriteArgument {
+ private:
+ void* data;
+ IfcUtil::ArgumentType type;
+ public:
+ IfcWriteIntegralArgument(int v);
+ IfcWriteIntegralArgument(bool v);
+ IfcWriteIntegralArgument(double v);
+ IfcWriteIntegralArgument(const std::string& v);
+ IfcWriteIntegralArgument(const std::vector v);
+ IfcWriteIntegralArgument(const std::vector v);
+ IfcWriteIntegralArgument(const std::vector v);
+ IfcWriteIntegralArgument(IfcUtil::IfcSchemaEntity v);
+ ~IfcWriteIntegralArgument();
+ operator int() const;
+ operator bool() const;
+ operator double() const;
+ operator std::string() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator std::vector() const;
+ operator IfcUtil::IfcSchemaEntity() const;
+ operator IfcEntities() const;
+ bool isNull() const;
+ unsigned int Size() const;
+ ArgumentPtr operator [] (unsigned int i) const;
+ std::string toString(bool upper=false) const;
+ };
+
+ /// An entity to help with passing of SELECT arguments that
+ /// consist of simple types, for example useful to initialize
+ /// a new IfcProperty.
+ /// Proper memory management is difficult for now, so beware.
+ class IfcSelectHelperEntity : public IfcAbstractEntity {
+ private:
+ Ifc2x3::Type::Enum _type;
+ IfcWriteArgument* arg;
+ public:
+ // FIXME: Make this a non-pointer argument and implement a copy constructor
+ IfcSelectHelperEntity(Ifc2x3::Type::Enum t, IfcWriteArgument* a) : _type(t), arg(a) {}
+ IfcEntities getInverse(Ifc2x3::Type::Enum,int,const std::string &);
+ IfcEntities getInverse(Ifc2x3::Type::Enum);
+ std::string datatype();
+ ArgumentPtr getArgument(unsigned int i);
+ unsigned int getArgumentCount();
+ Ifc2x3::Type::Enum type() const;
+ bool is(Ifc2x3::Type::Enum t) const;
+ std::string toString(bool upper = false);
+ unsigned int id();
+ bool isWritable();
+ };
+
+ /// A helper class for passing of SELECT arguments that
+ /// consist of simple types, for example useful to initialize
+ /// a new IfcProperty.
+ /// Proper memory management is difficult for now, so beware.
+ class IfcSelectHelper : public IfcUtil::IfcBaseClass {
+ public:
+ IfcSelectHelper(const std::string& v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcText);
+ IfcSelectHelper(const char* const v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcText);
+ IfcSelectHelper(int v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcInteger);
+ IfcSelectHelper(float v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcReal);
+ IfcSelectHelper(bool v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcBoolean);
+ bool is(Ifc2x3::Type::Enum t) const;
+ Ifc2x3::Type::Enum type() const;
+ };
+
+ /// A helper class for the creation of IFC GlobalIds.
+ /// At this moment an actual UUID is not generated according to
+ /// the ISO standard, but merely a sequence of random characters.
+ class IfcGuidHelper {
+ private:
+ std::string data;
+ static bool seeded;
+ public:
+ static const unsigned int length = 22;
+ IfcGuidHelper();
+ operator std::string() const;
+ };
+
+}
+
+#endif
\ No newline at end of file