2015-01-05 14:11:42 +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/>. *
|
|
|
|
|
* *
|
|
|
|
|
********************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
2015-09-13 15:00:21 +02:00
|
|
|
#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
2015-01-05 14:11:42 +00:00
|
|
|
#include "../ifcparse/IfcWritableEntity.h"
|
|
|
|
|
|
|
|
|
|
#include "../ifcparse/IfcUtil.h"
|
|
|
|
|
#include "../ifcparse/IfcWrite.h"
|
|
|
|
|
|
|
|
|
|
#ifdef USE_IFC4
|
|
|
|
|
#include "../ifcparse/Ifc4-latebound.h"
|
|
|
|
|
#else
|
|
|
|
|
#include "../ifcparse/Ifc2x3-latebound.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "IfcLateBoundEntity.h"
|
|
|
|
|
|
|
|
|
|
using namespace IfcUtil;
|
|
|
|
|
|
|
|
|
|
IfcWrite::IfcWritableEntity* IfcParse::IfcLateBoundEntity::writable_entity() {
|
|
|
|
|
IfcWrite::IfcWritableEntity* e;
|
|
|
|
|
if (entity->isWritable()) {
|
|
|
|
|
e = (IfcWrite::IfcWritableEntity*) entity;
|
|
|
|
|
} else {
|
|
|
|
|
entity = e = new IfcWrite::IfcWritableEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(const std::string& s) {
|
2015-09-13 15:00:21 +02:00
|
|
|
_type = IfcSchema::Type::FromString(boost::to_upper_copy(s));
|
2015-01-05 14:11:42 +00:00
|
|
|
entity = new IfcWrite::IfcWritableEntity(_type);
|
2015-02-19 20:20:47 +00:00
|
|
|
for (unsigned i = 0; i < getArgumentCount(); ++i) {
|
|
|
|
|
// Side effect of this is that a NULL attribute is created.
|
|
|
|
|
entity->getArgument(i);
|
|
|
|
|
}
|
2015-01-05 14:11:42 +00:00
|
|
|
IfcSchema::Type::PopulateDerivedFields(writable_entity());
|
|
|
|
|
}
|
|
|
|
|
IfcParse::IfcLateBoundEntity::IfcLateBoundEntity(IfcAbstractEntity* e) {
|
|
|
|
|
entity = e;
|
|
|
|
|
_type = e->type();
|
|
|
|
|
}
|
|
|
|
|
unsigned int IfcParse::IfcLateBoundEntity::id() const {
|
|
|
|
|
if (entity->file) {
|
|
|
|
|
return static_cast<unsigned int>(entity->id());
|
|
|
|
|
} else {
|
|
|
|
|
throw IfcException("Entity not bound to a file");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool IfcParse::IfcLateBoundEntity::is(IfcSchema::Type::Enum v) const {
|
|
|
|
|
IfcSchema::Type::Enum _ty = _type;
|
|
|
|
|
if (v == _ty) return true;
|
|
|
|
|
while (_ty != -1) {
|
|
|
|
|
_ty = IfcSchema::Type::Parent(_ty);
|
|
|
|
|
if (v == _ty) return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string IfcParse::IfcLateBoundEntity::is_a() const {
|
|
|
|
|
return IfcSchema::Type::ToString(_type);
|
|
|
|
|
}
|
|
|
|
|
bool IfcParse::IfcLateBoundEntity::is_a(const std::string& s) const {
|
2015-09-13 15:00:21 +02:00
|
|
|
return is(IfcSchema::Type::FromString(boost::to_upper_copy(s)));
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
|
|
|
|
IfcSchema::Type::Enum IfcParse::IfcLateBoundEntity::type() const {
|
|
|
|
|
return _type;
|
|
|
|
|
}
|
|
|
|
|
unsigned int IfcParse::IfcLateBoundEntity::getArgumentCount() const {
|
|
|
|
|
return IfcSchema::Type::GetAttributeCount(_type);
|
|
|
|
|
}
|
|
|
|
|
IfcUtil::ArgumentType IfcParse::IfcLateBoundEntity::getArgumentType(unsigned int i) const {
|
2015-11-21 23:05:28 +02:00
|
|
|
return IfcSchema::Type::GetAttributeDerived(_type, (unsigned char)i)
|
2015-01-05 14:11:42 +00:00
|
|
|
? IfcUtil::Argument_DERIVED
|
2015-11-21 23:05:28 +02:00
|
|
|
: IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-02-17 19:48:41 +00:00
|
|
|
IfcSchema::Type::Enum IfcParse::IfcLateBoundEntity::getArgumentEntity(unsigned int i) const {
|
2015-11-21 23:05:28 +02:00
|
|
|
return IfcSchema::Type::GetAttributeEntity(_type, (unsigned char)i);
|
2015-02-17 19:48:41 +00:00
|
|
|
}
|
2015-01-05 14:11:42 +00:00
|
|
|
Argument* IfcParse::IfcLateBoundEntity::getArgument(unsigned int i) const {
|
|
|
|
|
return entity->getArgument(i);
|
|
|
|
|
}
|
|
|
|
|
const char* IfcParse::IfcLateBoundEntity::getArgumentName(unsigned int i) const {
|
2015-11-21 23:05:28 +02:00
|
|
|
return IfcSchema::Type::GetAttributeName(_type, (unsigned char)i).c_str();
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-01-21 17:01:22 +00:00
|
|
|
bool IfcParse::IfcLateBoundEntity::getArgumentOptionality(unsigned int i) const {
|
2015-11-21 23:05:28 +02:00
|
|
|
return IfcSchema::Type::GetAttributeOptional(_type, (unsigned char)i);
|
2015-01-21 17:01:22 +00:00
|
|
|
}
|
|
|
|
|
|
2015-01-05 14:11:42 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::invalid_argument(unsigned int i, const std::string& t) {
|
2015-11-21 23:05:28 +02:00
|
|
|
const std::string arg_name = IfcSchema::Type::GetAttributeName(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
throw IfcException(t + " is not a valid type for '" + arg_name + "'");
|
|
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsNull(unsigned int i) {
|
2015-11-21 23:05:28 +02:00
|
|
|
bool is_optional = IfcSchema::Type::GetAttributeOptional(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
if (is_optional) {
|
|
|
|
|
writable_entity()->setArgument(i);
|
|
|
|
|
} else invalid_argument(i,"NULL");
|
|
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsInt(unsigned int i, int v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
if (arg_type == Argument_INT) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
|
|
|
|
} else if ( (arg_type == Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
|
|
|
|
|
writable_entity()->setArgument(i, v == 1);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"INTEGER");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsBool(unsigned int i, bool v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
if (arg_type == Argument_BOOL) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"BOOLEAN");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsDouble(unsigned int i, double v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
if (arg_type == Argument_DOUBLE) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"REAL");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsString(unsigned int i, const std::string& a) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-01-05 14:11:42 +00:00
|
|
|
if (arg_type == Argument_STRING) {
|
2015-04-07 15:06:56 +00:00
|
|
|
writable_entity()->setArgument(i,a);
|
2015-01-05 14:11:42 +00:00
|
|
|
} else if (arg_type == Argument_ENUMERATION) {
|
2015-11-21 23:05:28 +02:00
|
|
|
std::pair<const char*, int> enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEntity(_type, (unsigned char)i), a);
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i, enum_data.second, enum_data.first);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else if (arg_type == Argument_BINARY) {
|
2015-06-17 11:27:02 +00:00
|
|
|
if (valid_binary_string(a)) {
|
|
|
|
|
boost::dynamic_bitset<> bits(a);
|
|
|
|
|
writable_entity()->setArgument(i, bits);
|
|
|
|
|
} else {
|
|
|
|
|
throw IfcException("String not a valid binary representation");
|
|
|
|
|
}
|
2015-01-05 14:11:42 +00:00
|
|
|
} else invalid_argument(i,"STRING");
|
|
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfInt(unsigned int i, const std::vector<int>& v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-04-07 15:06:56 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_INT) {
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"AGGREGATE OF INT");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfDouble(unsigned int i, const std::vector<double>& v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-04-07 15:06:56 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_DOUBLE) {
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"AGGREGATE OF DOUBLE");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfString(unsigned int i, const std::vector<std::string>& v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-04-07 15:06:56 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_STRING) {
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else if (arg_type == Argument_AGGREGATE_OF_BINARY) {
|
|
|
|
|
std::vector< boost::dynamic_bitset<> > bits;
|
|
|
|
|
bits.reserve(v.size());
|
|
|
|
|
for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it) {
|
2015-06-17 11:27:02 +00:00
|
|
|
if (valid_binary_string(*it)) {
|
|
|
|
|
bits.push_back(boost::dynamic_bitset<>(*it));
|
|
|
|
|
} else {
|
|
|
|
|
throw IfcException("String not a valid binary representation");
|
|
|
|
|
}
|
2015-04-07 15:06:56 +00:00
|
|
|
}
|
|
|
|
|
writable_entity()->setArgument(i, bits);
|
|
|
|
|
} else invalid_argument(i,"AGGREGATE OF STRING");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsEntityInstance(unsigned int i, IfcParse::IfcLateBoundEntity* v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-04-07 15:06:56 +00:00
|
|
|
if (arg_type == Argument_ENTITY_INSTANCE) {
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"ENTITY INSTANCE");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfEntityInstance(unsigned int i, IfcEntityList::ptr v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-04-07 15:06:56 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
2015-01-05 14:11:42 +00:00
|
|
|
writable_entity()->setArgument(i,v);
|
2015-04-07 15:06:56 +00:00
|
|
|
} else invalid_argument(i,"AGGREGATE OF ENTITY INSTANCE");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfAggregateOfInt(unsigned int i, const std::vector< std::vector<int> >& v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-06-17 11:27:02 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
|
|
|
|
} else invalid_argument(i,"AGGREGATE OF AGGREGATE OF INT");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
2015-06-17 11:27:02 +00:00
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfAggregateOfDouble(unsigned int i, const std::vector< std::vector<double> >& v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-06-17 11:27:02 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
|
|
|
|
} else invalid_argument(i,"AGGREGATE OF AGGREGATE OF DOUBLE");
|
|
|
|
|
}
|
|
|
|
|
void IfcParse::IfcLateBoundEntity::setArgumentAsAggregateOfAggregateOfEntityInstance(unsigned int i, IfcEntityListList::ptr v) {
|
2015-11-21 23:05:28 +02:00
|
|
|
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type, (unsigned char)i);
|
2015-06-17 11:27:02 +00:00
|
|
|
if (arg_type == Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
|
|
|
|
|
writable_entity()->setArgument(i,v);
|
|
|
|
|
} else invalid_argument(i,"AGGREGATE OF AGGREGATE OF ENTITY INSTANCE");
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
|
|
|
|
unsigned IfcParse::IfcLateBoundEntity::getArgumentIndex(const std::string& a) const {
|
|
|
|
|
return IfcSchema::Type::GetAttributeIndex(_type,a);
|
|
|
|
|
}
|
|
|
|
|
std::string IfcParse::IfcLateBoundEntity::toString() {
|
|
|
|
|
return entity->toString(false);
|
|
|
|
|
}
|
|
|
|
|
IfcEntityList::ptr IfcParse::IfcLateBoundEntity::get_inverse(const std::string& a) {
|
|
|
|
|
std::pair<IfcSchema::Type::Enum, unsigned> inv = IfcSchema::Type::GetInverseAttribute(_type, a);
|
2015-01-10 22:13:52 +00:00
|
|
|
return entity->getInverse(inv.first, inv.second);
|
2015-01-05 14:11:42 +00:00
|
|
|
}
|
|
|
|
|
bool IfcParse::IfcLateBoundEntity::is_valid() {
|
|
|
|
|
const unsigned arg_count = getArgumentCount();
|
|
|
|
|
bool valid = true;
|
|
|
|
|
std::ostringstream oss;
|
|
|
|
|
oss << "Argument ";
|
|
|
|
|
for (unsigned i = 0; i < arg_count; ++i) {
|
|
|
|
|
bool is_null = true;
|
|
|
|
|
try {
|
|
|
|
|
const Argument& arg = *getArgument(i);
|
|
|
|
|
is_null = arg.isNull();
|
|
|
|
|
} catch(IfcException) {}
|
2015-11-21 23:05:28 +02:00
|
|
|
if (!IfcSchema::Type::GetAttributeOptional(_type, (unsigned char)i) && is_null) {
|
2015-01-05 14:11:42 +00:00
|
|
|
if (!valid) {
|
|
|
|
|
oss << ", ";
|
|
|
|
|
}
|
|
|
|
|
oss << "\"" << getArgumentName(i) << "\"";
|
|
|
|
|
valid = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
oss << " not optional";
|
|
|
|
|
if (!valid) {
|
|
|
|
|
throw IfcException(oss.str());
|
|
|
|
|
}
|
|
|
|
|
return valid;
|
|
|
|
|
}
|
2015-02-27 13:41:33 +00:00
|
|
|
|
|
|
|
|
std::vector<std::string> IfcParse::IfcLateBoundEntity::getAttributeNames() const {
|
|
|
|
|
std::vector<std::string> return_value;
|
|
|
|
|
return_value.reserve(getArgumentCount());
|
|
|
|
|
for (unsigned i = 0; i < getArgumentCount(); ++i) {
|
|
|
|
|
return_value.push_back(getArgumentName(i));
|
|
|
|
|
}
|
|
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> IfcParse::IfcLateBoundEntity::getInverseAttributeNames() const {
|
|
|
|
|
std::vector<std::string> return_value;
|
|
|
|
|
std::set<std::string> values = IfcSchema::Type::GetInverseAttributeNames(_type);
|
|
|
|
|
std::copy(values.begin(), values.end(), std::back_inserter(return_value));
|
|
|
|
|
return return_value;
|
|
|
|
|
}
|