2012-08-11 13:24:08 +00:00
|
|
|
/********************************************************************************
|
2012-07-19 13:07:55 +00:00
|
|
|
* *
|
|
|
|
|
* 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 <http://www.gnu.org/licenses/>. *
|
|
|
|
|
* *
|
|
|
|
|
********************************************************************************/
|
|
|
|
|
|
2015-02-03 13:53:36 +00:00
|
|
|
#include <iomanip>
|
|
|
|
|
#include <locale>
|
2015-11-30 22:59:21 +01:00
|
|
|
#include <limits>
|
2014-06-11 10:24:11 +00:00
|
|
|
|
2015-09-13 15:00:21 +02:00
|
|
|
#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
2012-11-04 16:26:33 +00:00
|
|
|
#include "../ifcparse/IfcParse.h"
|
|
|
|
|
#include "../ifcparse/IfcWrite.h"
|
|
|
|
|
#include "../ifcparse/IfcWritableEntity.h"
|
|
|
|
|
#include "../ifcparse/IfcCharacterDecoder.h"
|
2015-01-05 14:11:42 +00:00
|
|
|
#include "../ifcparse/IfcFile.h"
|
2012-07-19 13:07:55 +00:00
|
|
|
|
2015-03-12 17:54:52 +00:00
|
|
|
#ifdef USE_IFC4
|
|
|
|
|
#include "../ifcparse/Ifc4-latebound.h"
|
|
|
|
|
#else
|
|
|
|
|
#include "../ifcparse/Ifc2x3-latebound.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2012-07-19 13:07:55 +00:00
|
|
|
using namespace IfcWrite;
|
|
|
|
|
|
2014-02-17 22:13:55 +00:00
|
|
|
IfcWritableEntity::IfcWritableEntity(IfcSchema::Type::Enum t) {
|
2012-07-19 13:07:55 +00:00
|
|
|
_type = t;
|
|
|
|
|
_id = 0;
|
2012-08-11 13:24:08 +00:00
|
|
|
file = 0;
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
IfcWritableEntity::~IfcWritableEntity() {
|
|
|
|
|
delete _id;
|
2016-05-29 18:12:57 +06:00
|
|
|
for (std::map<int,Argument*>::iterator it = args.begin(); it != args.end(); ++it)
|
|
|
|
|
delete it->second;
|
2013-08-04 04:49:08 +00:00
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
int IfcWritableEntity::setId(int i) {
|
2014-05-05 16:17:28 +00:00
|
|
|
if (i > 0) {
|
|
|
|
|
delete _id;
|
|
|
|
|
return *(_id = new int(i));
|
|
|
|
|
} else {
|
|
|
|
|
if (_id) { return *_id; }
|
|
|
|
|
else {
|
|
|
|
|
delete _id;
|
|
|
|
|
return *(_id = new int(file->FreshId()));
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
IfcWritableEntity::IfcWritableEntity(IfcAbstractEntity* e)
|
|
|
|
|
{
|
2012-08-11 13:24:08 +00:00
|
|
|
file = e->file;
|
2012-07-19 13:07:55 +00:00
|
|
|
_type = e->type();
|
|
|
|
|
_id = new int(e->id());
|
|
|
|
|
|
|
|
|
|
const unsigned int count = e->getArgumentCount();
|
|
|
|
|
for ( unsigned int i = 0; i < count; ++ i ) {
|
2015-03-12 17:54:52 +00:00
|
|
|
this->setArgument(i, e->getArgument(i));
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
}
|
2015-01-10 22:13:52 +00:00
|
|
|
|
|
|
|
|
IfcEntityList::ptr IfcWritableEntity::getInverse(IfcSchema::Type::Enum type, int attribute_index) {
|
|
|
|
|
if (file) {
|
|
|
|
|
int id = _id ? *_id : setId();
|
|
|
|
|
return file->getInverse(id, type, attribute_index);
|
|
|
|
|
} else {
|
|
|
|
|
throw IfcParse::IfcException("Instance not part of a file");
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-04 14:42:55 +00:00
|
|
|
std::string IfcWritableEntity::datatype() const { return IfcSchema::Type::ToString(_type); }
|
2015-02-19 20:20:47 +00:00
|
|
|
Argument* IfcWritableEntity::getArgument (unsigned int i) {
|
|
|
|
|
if (args[i] == 0) {
|
|
|
|
|
_setArgument(i, boost::none);
|
|
|
|
|
}
|
|
|
|
|
return args[i];
|
|
|
|
|
}
|
2015-11-03 17:58:08 +02:00
|
|
|
unsigned int IfcWritableEntity::getArgumentCount() const { return (unsigned)args.size(); }
|
2014-02-17 22:13:55 +00:00
|
|
|
IfcSchema::Type::Enum IfcWritableEntity::type() const { return _type; }
|
|
|
|
|
bool IfcWritableEntity::is(IfcSchema::Type::Enum v) const { return _type == v; }
|
2014-05-04 14:42:55 +00:00
|
|
|
std::string IfcWritableEntity::toString(bool upper) const {
|
2012-07-19 13:07:55 +00:00
|
|
|
std::stringstream ss;
|
2015-02-17 20:23:21 +00:00
|
|
|
ss.imbue(std::locale::classic());
|
|
|
|
|
|
2012-07-19 13:07:55 +00:00
|
|
|
std::string dt = datatype();
|
2015-01-25 10:50:12 +00:00
|
|
|
if (upper) {
|
2015-09-13 15:00:21 +02:00
|
|
|
boost::to_upper(dt);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2015-01-25 10:50:12 +00:00
|
|
|
|
|
|
|
|
if (_id && !IfcSchema::Type::IsSimple(type())) {
|
|
|
|
|
ss << "#" << *_id;
|
|
|
|
|
ss << "=";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ss << dt << "(";
|
|
|
|
|
for (std::map<int,Argument*>::const_iterator it = args.begin(); it != args.end(); ++ it) {
|
2012-07-19 13:07:55 +00:00
|
|
|
if ( it != args.begin() ) ss << ",";
|
|
|
|
|
ss << it->second->toString(upper);
|
|
|
|
|
}
|
|
|
|
|
ss << ")";
|
2015-01-25 10:50:12 +00:00
|
|
|
|
2012-07-19 13:07:55 +00:00
|
|
|
return ss.str();
|
|
|
|
|
}
|
2016-04-19 16:44:08 +02:00
|
|
|
unsigned int IfcWritableEntity::id() {
|
|
|
|
|
if (!file) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
if ( !_id ) {
|
|
|
|
|
_id = new int(file->FreshId());
|
|
|
|
|
}
|
|
|
|
|
return *_id;
|
|
|
|
|
}
|
2014-11-02 18:36:51 +00:00
|
|
|
IfcWritableEntity* IfcWritableEntity::isWritable() { return this; }
|
2012-07-19 13:07:55 +00:00
|
|
|
bool IfcWritableEntity::arg_writable(int i) {
|
|
|
|
|
std::map<int,bool>::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;
|
|
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
|
|
|
|
|
template <typename T> void IfcWritableEntity::_setArgument(int i, const T& t) {
|
2012-08-11 13:24:08 +00:00
|
|
|
if ( arg_writable(i) ) delete args[i];
|
2016-10-09 12:42:39 +02:00
|
|
|
IfcWriteArgument* arg = new IfcWriteArgument;
|
2013-08-04 04:49:08 +00:00
|
|
|
args[i] = arg;
|
|
|
|
|
arg->set(t);
|
2012-08-11 13:24:08 +00:00
|
|
|
arg_writable(i,true);
|
|
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
|
|
|
|
|
void IfcWritableEntity::setArgument(int i) {
|
|
|
|
|
_setArgument(i, boost::none);
|
|
|
|
|
}
|
2015-03-12 17:54:52 +00:00
|
|
|
|
2016-11-08 17:24:08 +01:00
|
|
|
void IfcWritableEntity::setArgument(int i, Argument* a, IfcUtil::ArgumentType attr_type) {
|
|
|
|
|
if (attr_type == IfcUtil::Argument_UNKNOWN) {
|
|
|
|
|
attr_type = a->type();
|
|
|
|
|
}
|
2015-03-12 17:54:52 +00:00
|
|
|
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));
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
2015-04-07 19:26:01 +00:00
|
|
|
case IfcUtil::Argument_BINARY: {
|
|
|
|
|
boost::dynamic_bitset<> attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
|
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_INT: {
|
2015-03-13 10:40:31 +00:00
|
|
|
std::vector<int> attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
2015-04-07 15:06:56 +00:00
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: {
|
2015-03-13 10:40:31 +00:00
|
|
|
std::vector<double> attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
2015-04-07 15:06:56 +00:00
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_STRING: {
|
2015-03-13 10:40:31 +00:00
|
|
|
std::vector<std::string> attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
2015-04-07 15:06:56 +00:00
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_BINARY: {
|
|
|
|
|
std::vector< boost::dynamic_bitset<> > attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
2015-03-12 17:54:52 +00:00
|
|
|
case IfcUtil::Argument_ENUMERATION: {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcSchema::Type::Enum ty = IfcSchema::Type::GetAttributeEntity(_type, (unsigned char)i);
|
2015-03-12 17:54:52 +00:00
|
|
|
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); }
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
|
|
|
|
case IfcUtil::Argument_ENTITY_INSTANCE: {
|
2015-03-12 17:54:52 +00:00
|
|
|
this->setArgument(i, static_cast<IfcUtil::IfcBaseClass*>(*a)); }
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
|
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
|
2015-03-12 17:54:52 +00:00
|
|
|
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); }
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
2015-06-16 12:58:07 +00:00
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: {
|
|
|
|
|
std::vector< std::vector<int> > attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
|
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: {
|
|
|
|
|
std::vector< std::vector<double> > attr_value = *a;
|
|
|
|
|
this->setArgument(i, attr_value); }
|
|
|
|
|
break;
|
2015-04-07 15:06:56 +00:00
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
|
2015-03-12 17:54:52 +00:00
|
|
|
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); }
|
2015-04-07 15:06:56 +00:00
|
|
|
break;
|
2016-11-08 17:24:08 +01:00
|
|
|
case IfcUtil::Argument_EMPTY_AGGREGATE:
|
|
|
|
|
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE: {
|
|
|
|
|
IfcUtil::ArgumentType t2 = IfcSchema::Type::GetAttributeType(type(), (unsigned) i);
|
|
|
|
|
this->setArgument(i, a, t2); }
|
|
|
|
|
break;
|
2015-04-07 15:06:56 +00:00
|
|
|
default:
|
2015-03-12 17:54:52 +00:00
|
|
|
case IfcUtil::Argument_UNKNOWN:
|
2016-11-08 17:24:08 +01:00
|
|
|
throw IfcParse::IfcException(std::string("Unknown attribute encountered: '") + a->toString() + "' at index '" + boost::lexical_cast<std::string>(i) + "'");
|
2015-03-12 17:54:52 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-10 09:36:34 +00:00
|
|
|
void IfcWritableEntity::setArgumentDerived(int i) {
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, IfcWriteArgument::Derived());
|
2012-11-10 09:36:34 +00:00
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,int v) {
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-11-04 16:26:33 +00:00
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,bool v) {
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,int v, const char* c){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, IfcWriteArgument::EnumerationReference(v, c));
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,const std::string& v){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2015-04-07 15:06:56 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,const boost::dynamic_bitset<>& v){
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,double v){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,IfcUtil::IfcBaseClass* v){
|
2013-08-04 04:49:08 +00:00
|
|
|
if ( v ) {
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
} else {
|
|
|
|
|
_setArgument(i, boost::none);
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,IfcEntityList::ptr v){
|
|
|
|
|
if ( v.get() ) {
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
} else {
|
|
|
|
|
_setArgument(i, boost::none);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,IfcEntityListList::ptr v){
|
2013-08-04 04:49:08 +00:00
|
|
|
if ( v.get() ) {
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
} else {
|
|
|
|
|
_setArgument(i, boost::none);
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector<double>& v){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2015-06-16 12:58:07 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector< std::vector<double> >& v){
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector<std::string>& v){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector<int>& v){
|
2013-08-04 04:49:08 +00:00
|
|
|
_setArgument(i, v);
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2015-06-16 12:58:07 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector< std::vector<int> >& v){
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
}
|
2015-04-07 15:06:56 +00:00
|
|
|
void IfcWritableEntity::setArgument(int i,const std::vector< boost::dynamic_bitset<> >& v){
|
|
|
|
|
_setArgument(i, v);
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
|
2013-08-04 04:49:08 +00:00
|
|
|
class SizeVisitor : public boost::static_visitor<int> {
|
|
|
|
|
public:
|
2015-11-23 15:52:12 +02:00
|
|
|
int operator()(const boost::none_t& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const IfcWriteArgument::Derived& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const int& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const bool& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const double& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const std::string& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const boost::dynamic_bitset<>& /*i*/) const { return -1; }
|
2015-11-03 17:58:08 +02:00
|
|
|
int operator()(const std::vector<int>& i) const { return (int)i.size(); }
|
|
|
|
|
int operator()(const std::vector<double>& i) const { return (int)i.size(); }
|
|
|
|
|
int operator()(const std::vector< std::vector<int> >& i) const { return (int)i.size(); }
|
|
|
|
|
int operator()(const std::vector< std::vector<double> >& i) const { return (int)i.size(); }
|
|
|
|
|
int operator()(const std::vector<std::string>& i) const { return (int)i.size(); }
|
|
|
|
|
int operator()(const std::vector< boost::dynamic_bitset<> >& i) const { return (int)i.size(); }
|
2015-11-23 15:52:12 +02:00
|
|
|
int operator()(const IfcWriteArgument::EnumerationReference& /*i*/) const { return -1; }
|
|
|
|
|
int operator()(const IfcUtil::IfcBaseClass* const& /*i*/) const { return -1; }
|
2015-01-10 22:13:52 +00:00
|
|
|
int operator()(const IfcEntityList::ptr& i) const { return i->size(); }
|
|
|
|
|
int operator()(const IfcEntityListList::ptr& i) const { return i->size(); }
|
2013-08-04 04:49:08 +00:00
|
|
|
};
|
2012-11-10 09:36:34 +00:00
|
|
|
|
2013-08-04 04:49:08 +00:00
|
|
|
class StringBuilderVisitor : public boost::static_visitor<void> {
|
|
|
|
|
private:
|
2015-11-21 23:05:28 +02:00
|
|
|
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
|
|
|
|
|
StringBuilderVisitor& operator =(const StringBuilderVisitor&); //N/A
|
|
|
|
|
|
2013-08-04 04:49:08 +00:00
|
|
|
std::ostringstream& data;
|
|
|
|
|
template <typename T> void serialize(const std::vector<T>& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (typename std::vector<T>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
data << *it;
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
data << ")";
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
// The REAL token definition from the IFC SPF standard does not necessarily match
|
|
|
|
|
// the output of the C++ ostream formatting operation.
|
|
|
|
|
// REAL = [ SIGN ] DIGIT { DIGIT } "." { DIGIT } [ "E" [ SIGN ] DIGIT { DIGIT } ] .
|
|
|
|
|
std::string format_double(const double& d) {
|
|
|
|
|
std::ostringstream oss;
|
2015-02-03 13:53:36 +00:00
|
|
|
oss.imbue(std::locale::classic());
|
2015-11-30 22:59:21 +01:00
|
|
|
oss << std::setprecision(std::numeric_limits<double>::digits10) << d;
|
2013-08-04 04:49:08 +00:00
|
|
|
const std::string str = oss.str();
|
|
|
|
|
oss.str("");
|
|
|
|
|
std::string::size_type e = str.find('e');
|
|
|
|
|
if (e == std::string::npos) {
|
|
|
|
|
e = str.find('E');
|
|
|
|
|
}
|
|
|
|
|
const std::string mantissa = str.substr(0,e);
|
|
|
|
|
oss << mantissa;
|
|
|
|
|
if (mantissa.find('.') == std::string::npos) {
|
|
|
|
|
oss << ".";
|
|
|
|
|
}
|
|
|
|
|
if (e != std::string::npos) {
|
|
|
|
|
oss << "E";
|
|
|
|
|
oss << str.substr(e+1);
|
|
|
|
|
}
|
|
|
|
|
return oss.str();
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2015-04-07 15:06:56 +00:00
|
|
|
|
|
|
|
|
std::string format_binary(const boost::dynamic_bitset<>& b) {
|
|
|
|
|
std::ostringstream oss;
|
|
|
|
|
oss.imbue(std::locale::classic());
|
|
|
|
|
oss.put('"');
|
|
|
|
|
oss << std::hex << std::setw(1);
|
2015-11-03 17:58:08 +02:00
|
|
|
unsigned c = (unsigned)b.size();
|
2015-06-17 11:22:43 +00:00
|
|
|
unsigned n = (4 - (c % 4)) & 3;
|
2015-04-07 15:06:56 +00:00
|
|
|
oss << n;
|
|
|
|
|
for (unsigned i = 0; i < c + n;) {
|
|
|
|
|
unsigned accum = 0;
|
|
|
|
|
for (int j = 0; j < 4; ++j, ++i) {
|
|
|
|
|
unsigned bit = i < n ? 0 : b.test(c - i + n - 1) ? 1 : 0;
|
|
|
|
|
accum |= bit << (3-j);
|
|
|
|
|
}
|
|
|
|
|
oss << accum;
|
|
|
|
|
}
|
|
|
|
|
oss.put('"');
|
|
|
|
|
return oss.str();
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-04 04:49:08 +00:00
|
|
|
bool upper;
|
|
|
|
|
public:
|
|
|
|
|
StringBuilderVisitor(std::ostringstream& stream, bool upper = false)
|
|
|
|
|
: data(stream), upper(upper) {}
|
2015-11-23 15:52:12 +02:00
|
|
|
void operator()(const boost::none_t& /*i*/) { data << "$"; }
|
|
|
|
|
void operator()(const IfcWriteArgument::Derived& /*i*/) { data << "*"; }
|
2013-08-04 04:49:08 +00:00
|
|
|
void operator()(const int& i) { data << i; }
|
|
|
|
|
void operator()(const bool& i) { data << (i ? ".T." : ".F."); }
|
|
|
|
|
void operator()(const double& i) { data << format_double(i); }
|
2015-04-07 15:06:56 +00:00
|
|
|
void operator()(const boost::dynamic_bitset<>& i) { data << format_binary(i); }
|
2013-08-04 04:49:08 +00:00
|
|
|
void operator()(const std::string& i) {
|
|
|
|
|
std::string s = i;
|
2015-01-25 10:50:12 +00:00
|
|
|
if (upper) {
|
|
|
|
|
data << static_cast<std::string>(IfcCharacterEncoder(s));
|
|
|
|
|
} else {
|
|
|
|
|
data << '\'' << s << '\'';
|
|
|
|
|
}
|
2012-11-04 16:26:33 +00:00
|
|
|
}
|
2015-01-16 16:26:40 +00:00
|
|
|
void operator()(const std::vector<int>& i);
|
|
|
|
|
void operator()(const std::vector<double>& i);
|
|
|
|
|
void operator()(const std::vector<std::string>& i);
|
2015-04-07 15:06:56 +00:00
|
|
|
void operator()(const std::vector< boost::dynamic_bitset<> >& i);
|
2013-08-04 04:49:08 +00:00
|
|
|
void operator()(const IfcWriteArgument::EnumerationReference& i) {
|
|
|
|
|
data << "." << i.enumeration_value << ".";
|
2012-11-04 16:26:33 +00:00
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
void operator()(const IfcUtil::IfcBaseClass* const& i) {
|
2013-08-04 04:49:08 +00:00
|
|
|
IfcAbstractEntity* e = i->entity;
|
2014-02-17 22:13:55 +00:00
|
|
|
if ( IfcSchema::Type::IsSimple(e->type()) ) {
|
2013-08-04 04:49:08 +00:00
|
|
|
data << e->toString(upper);
|
2012-07-19 13:07:55 +00:00
|
|
|
} else {
|
2013-08-04 04:49:08 +00:00
|
|
|
data << "#" << e->id();
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
void operator()(const IfcEntityList::ptr& i) {
|
2013-08-04 04:49:08 +00:00
|
|
|
data << "(";
|
|
|
|
|
for (IfcEntityList::it it = i->begin(); it != i->end(); ++it) {
|
|
|
|
|
if (it != i->begin()) data << ",";
|
|
|
|
|
(*this)(*it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
2015-06-16 12:58:07 +00:00
|
|
|
void operator()(const std::vector< std::vector<int> >& i);
|
|
|
|
|
void operator()(const std::vector< std::vector<double> >& i);
|
2014-05-04 14:42:55 +00:00
|
|
|
void operator()(const IfcEntityListList::ptr& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (IfcEntityListList::outer_it outer_it = i->begin(); outer_it != i->end(); ++outer_it) {
|
|
|
|
|
if (outer_it != i->begin()) data << ",";
|
2016-04-19 16:44:08 +02:00
|
|
|
data << "(";
|
2014-05-04 14:42:55 +00:00
|
|
|
for (IfcEntityListList::inner_it inner_it = outer_it->begin(); inner_it != outer_it->end(); ++inner_it) {
|
|
|
|
|
if (inner_it != outer_it->begin()) data << ",";
|
|
|
|
|
(*this)(*inner_it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
2013-08-04 04:49:08 +00:00
|
|
|
operator std::string() { return data.str(); }
|
|
|
|
|
};
|
|
|
|
|
|
2015-01-16 16:26:40 +00:00
|
|
|
template <>
|
|
|
|
|
void StringBuilderVisitor::serialize(const std::vector<std::string>& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (std::vector<std::string>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
if (upper) {
|
|
|
|
|
std::string s = IfcCharacterEncoder(*it);
|
|
|
|
|
data << s;
|
|
|
|
|
} else {
|
|
|
|
|
data << *it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
|
void StringBuilderVisitor::serialize(const std::vector<double>& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (std::vector<double>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
data << format_double(*it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-07 15:06:56 +00:00
|
|
|
template <>
|
|
|
|
|
void StringBuilderVisitor::serialize(const std::vector< boost::dynamic_bitset<> >& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (std::vector< boost::dynamic_bitset<> >::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
data << format_binary(*it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-16 16:26:40 +00:00
|
|
|
void StringBuilderVisitor::operator()(const std::vector<int>& i) { serialize(i); }
|
|
|
|
|
void StringBuilderVisitor::operator()(const std::vector<double>& i) { serialize(i); }
|
|
|
|
|
void StringBuilderVisitor::operator()(const std::vector<std::string>& i) { serialize(i); }
|
2015-04-07 15:06:56 +00:00
|
|
|
void StringBuilderVisitor::operator()(const std::vector< boost::dynamic_bitset<> >& i) { serialize(i); }
|
2015-06-16 12:58:07 +00:00
|
|
|
void StringBuilderVisitor::operator()(const std::vector< std::vector<int> >& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (std::vector< std::vector<int> >::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
serialize(*it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
|
|
|
|
void StringBuilderVisitor::operator()(const std::vector< std::vector<double> >& i) {
|
|
|
|
|
data << "(";
|
|
|
|
|
for (std::vector< std::vector<double> >::const_iterator it = i.begin(); it != i.end(); ++it) {
|
|
|
|
|
if (it != i.begin()) data << ",";
|
|
|
|
|
serialize(*it);
|
|
|
|
|
}
|
|
|
|
|
data << ")";
|
|
|
|
|
}
|
2015-01-16 16:26:40 +00:00
|
|
|
|
2013-08-04 04:49:08 +00:00
|
|
|
IfcWriteArgument::operator int() const { return as<int>(); }
|
|
|
|
|
IfcWriteArgument::operator bool() const { return as<bool>(); }
|
|
|
|
|
IfcWriteArgument::operator double() const { return as<double>(); }
|
2015-02-17 22:14:09 +00:00
|
|
|
IfcWriteArgument::operator std::string() const {
|
|
|
|
|
if (type() == IfcUtil::Argument_ENUMERATION) {
|
|
|
|
|
return as<EnumerationReference>().enumeration_value;
|
|
|
|
|
}
|
|
|
|
|
return as<std::string>();
|
|
|
|
|
}
|
2015-04-07 15:06:56 +00:00
|
|
|
IfcWriteArgument::operator IfcUtil::IfcBaseClass*() const { return as<IfcUtil::IfcBaseClass*>(); }
|
|
|
|
|
IfcWriteArgument::operator boost::dynamic_bitset<>() const { return as< boost::dynamic_bitset<> >(); }
|
2013-08-04 04:49:08 +00:00
|
|
|
IfcWriteArgument::operator std::vector<double>() const { return as<std::vector<double> >(); }
|
|
|
|
|
IfcWriteArgument::operator std::vector<int>() const { return as<std::vector<int> >(); }
|
|
|
|
|
IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vector<std::string > >(); }
|
2015-04-07 15:06:56 +00:00
|
|
|
IfcWriteArgument::operator std::vector< boost::dynamic_bitset<> >() const { return as< std::vector< boost::dynamic_bitset<> > >(); }
|
2014-05-04 14:42:55 +00:00
|
|
|
IfcWriteArgument::operator IfcEntityList::ptr() const { return as<IfcEntityList::ptr>(); }
|
2015-06-16 12:58:07 +00:00
|
|
|
IfcWriteArgument::operator std::vector< std::vector<int> >() const { return as<std::vector< std::vector<int> > >(); }
|
|
|
|
|
IfcWriteArgument::operator std::vector< std::vector<double> >() const { return as<std::vector< std::vector<double> > >(); }
|
2016-04-19 16:44:08 +02:00
|
|
|
IfcWriteArgument::operator IfcEntityListList::ptr() const { return as<IfcEntityListList::ptr>(); }
|
2015-01-05 14:11:42 +00:00
|
|
|
bool IfcWriteArgument::isNull() const { return type() == IfcUtil::Argument_NULL; }
|
2015-11-23 15:52:12 +02:00
|
|
|
Argument* IfcWriteArgument::operator [] (unsigned int /*i*/) const { throw IfcParse::IfcException("Invalid cast"); }
|
2013-08-04 04:49:08 +00:00
|
|
|
std::string IfcWriteArgument::toString(bool upper) const {
|
|
|
|
|
std::ostringstream str;
|
2015-02-17 20:23:21 +00:00
|
|
|
str.imbue(std::locale::classic());
|
2013-08-04 04:49:08 +00:00
|
|
|
StringBuilderVisitor v(str, upper);
|
|
|
|
|
container.apply_visitor(v);
|
|
|
|
|
return v;
|
|
|
|
|
}
|
2015-01-10 22:13:52 +00:00
|
|
|
unsigned int IfcWriteArgument::size() const {
|
2013-08-04 04:49:08 +00:00
|
|
|
SizeVisitor v;
|
|
|
|
|
const int size = container.apply_visitor(v);
|
|
|
|
|
if (size == -1) {
|
|
|
|
|
throw IfcParse::IfcException("Invalid cast");
|
|
|
|
|
} else {
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-19 13:07:55 +00:00
|
|
|
|
2014-11-02 18:36:51 +00:00
|
|
|
IfcUtil::ArgumentType IfcWriteArgument::type() const {
|
2015-01-05 14:11:42 +00:00
|
|
|
return static_cast<IfcUtil::ArgumentType>(container.which());
|
2014-11-02 18:36:51 +00:00
|
|
|
}
|
|
|
|
|
|
2012-08-11 13:24:08 +00:00
|
|
|
EntityBuffer* EntityBuffer::i = 0;
|
|
|
|
|
EntityBuffer* EntityBuffer::instance() {
|
|
|
|
|
if ( ! i ) {
|
|
|
|
|
i = new EntityBuffer();
|
2014-05-04 14:42:55 +00:00
|
|
|
i->buffer = IfcEntityList::ptr(new IfcEntityList);
|
2012-08-11 13:24:08 +00:00
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
IfcEntityList::ptr EntityBuffer::Get() {
|
2012-08-11 13:24:08 +00:00
|
|
|
return instance()->buffer;
|
|
|
|
|
}
|
|
|
|
|
void EntityBuffer::Clear() {
|
2014-05-04 14:42:55 +00:00
|
|
|
instance()->buffer = IfcEntityList::ptr(new IfcEntityList);
|
2012-08-11 13:24:08 +00:00
|
|
|
}
|
2014-05-04 14:42:55 +00:00
|
|
|
void EntityBuffer::Add(IfcUtil::IfcBaseClass* e) {
|
2012-08-11 13:24:08 +00:00
|
|
|
instance()->buffer->push(e);
|
|
|
|
|
}
|