This commit is contained in:
Thomas Krijnen
2024-08-20 20:21:35 +02:00
parent 9c323f91dd
commit 261fb895eb
16 changed files with 273 additions and 467 deletions
+1 -1
View File
@@ -1505,7 +1505,7 @@ namespace latebound_access {
IfcUtil::IfcBaseClass* create(IfcParse::IfcFile& f, const std::string& entity) {
auto decl = f.schema()->declaration_by_name(entity);
auto data = IfcEntityInstanceData(storage_t(decl->as_entity()->attribute_count()));
auto inst = f.schema()->instantiate(entity, std::move(data));
auto inst = f.schema()->instantiate(decl, std::move(data));
if (decl->is("IfcRoot")) {
IfcParse::IfcGlobalId guid;
latebound_access::set(inst, "GlobalId", (std::string) guid);
+2
View File
@@ -55,6 +55,8 @@
* *
********************************************************************************/
#define _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR
#ifndef IFCGEOMITERATOR_H
#define IFCGEOMITERATOR_H
+8 -11
View File
@@ -86,20 +86,17 @@ class IFC_PARSE_API IfcBaseInterface {
};
class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
protected:
uint32_t identity_;
protected:
static std::atomic_uint32_t counter_;
uint32_t identity_;
public:
uint32_t id_;
IfcParse::IfcFile* file_;
protected:
IfcEntityInstanceData data_;
static bool is_null(const IfcBaseClass* not_this) {
return not_this == nullptr;
}
public:
uint32_t id_;
IfcParse::IfcFile* file_;
public:
IfcBaseClass(IfcEntityInstanceData&& data)
: identity_(counter_++)
, data_(std::move(data))
+26 -4
View File
@@ -419,14 +419,36 @@ std::wstring IfcUtil::convert_utf8(const std::string& string) {
// bug in msvc 2015 and 2017, unsure if fixed in later versions
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
bool is_ascii = true;
for (char c : s) {
if (static_cast<unsigned char>(c) >= 128) {
is_ascii = false;
break;
}
}
if (is_ascii) {
return std::u32string(s.begin(), s.end());
} else {
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
}
}
#else
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& string) {
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(string);
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
bool is_ascii = true;
for (char c : s) {
if (static_cast<unsigned char>(c) >= 128) {
is_ascii = false;
break;
}
}
if (is_ascii) {
return std::u32string(s.begin(), s.end());
} else {
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(s);
}
}
#endif
+4
View File
@@ -167,6 +167,10 @@ class IFC_PARSE_API IfcEntityInstanceData {
: storage_(std::move(storage))
{}
IfcEntityInstanceData(IfcEntityInstanceData&& other) noexcept
: storage_(std::move(other.storage_))
{}
IfcEntityInstanceData(const IfcEntityInstanceData& data);
IfcEntityInstanceData& operator=(IfcEntityInstanceData&& other) {
+58 -59
View File
@@ -141,7 +141,7 @@ namespace {
} else if (t.type == IfcParse::Token_FLOAT) {
fn(IfcParse::TokenFunc::asFloat(t));
} else if (t.type == IfcParse::Token_IDENTIFIER) {
fn(InstanceReference{ IfcParse::TokenFunc::asIdentifier(t) });
fn(IfcParse::reference_or_simple_type{ InstanceReference{ IfcParse::TokenFunc::asIdentifier(t) } });
} else if (t.type == IfcParse::Token_INT) {
fn(IfcParse::TokenFunc::asInt(t));
} else if (t.type == IfcParse::Token_STRING) {
@@ -150,26 +150,31 @@ namespace {
}
template <typename Fn>
void construct_(IfcParse::parse_context& p, Fn fn) {
void construct_(IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) {
if (p.tokens_.empty()) {
// @todo based on type create appropate empty aggregate
return;
}
decltype(p.tokens_) p_tokens_filtered;
std::vector<uint8_t> first_type;
get_token_type(first_type, p.tokens_.front());
std::copy_if(
p.tokens_.begin(),
p.tokens_.end(),
std::back_inserter(p_tokens_filtered),
[first_type](auto& x) {
std::vector<uint8_t> nth_type;
get_token_type(nth_type, x);
return can_coerce(first_type, nth_type);
// @todo instead of ugly if-else we could also default initialize the respective
// variant types below.
if (aggr) {
auto aggr_type = IfcUtil::make_aggregate(IfcUtil::from_parameter_type(aggr->type_of_element()));
if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
fn(std::vector<int>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
fn(std::vector<double>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_STRING) {
fn(std::vector<std::string>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) {
fn(std::vector<boost::dynamic_bitset<>>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
fn(aggregate_of_instance::ptr(new aggregate_of_instance));
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
fn(std::vector<std::vector<int>>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
fn(std::vector<std::vector<double>>{});
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
fn(aggregate_of_aggregate_of_instance::ptr(new aggregate_of_aggregate_of_instance));
}
}
);
if (p.tokens_.size() != p_tokens_filtered.size()) {
// warning
return;
}
typedef boost::variant<
@@ -188,25 +193,28 @@ namespace {
possible_aggregation_types_t aggregate_storage;
for (auto& t : p_tokens_filtered) {
boost::apply_visitor([&aggregate_storage](auto& v) {
auto append_to_aggregate_storage = [&aggregate_storage](auto v) {
if constexpr (is_type_in_variant_v<possible_aggregation_types_t, std::vector<std::decay_t<decltype(v)>>>) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
} else {
auto* vec_ptr = boost::get< std::vector<std::decay_t<decltype(v)>>>(&aggregate_storage);
if (vec_ptr) {
vec_ptr->push_back(v);
} else {
// inconsistent aggregate valuation
}
}
} else {
// unsupported aggregate type
}
};
for (auto& t : p.tokens_) {
boost::apply_visitor([&aggregate_storage, &append_to_aggregate_storage, aggr](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
// @todo get aggregate of enumeration
dispatch_token(v, nullptr, [&aggregate_storage](auto v) {
if constexpr (std::is_same_v<decltype(v), InstanceReference>) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<IfcParse::reference_or_simple_type>{ v };
} else {
boost::get< std::vector<IfcParse::reference_or_simple_type>>(aggregate_storage).push_back(v);
}
} else if constexpr (is_type_in_variant_v<possible_aggregation_types_t, std::vector<std::decay_t<decltype(v)>>>) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
} else {
boost::get< std::vector<std::decay_t<decltype(v)>>>(aggregate_storage).push_back(v);
}
}
});
dispatch_token(v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
/*construct_(*v, [&aggregate_storage](auto& v) {
if (aggregate_storage.which() == 0) {
@@ -217,11 +225,7 @@ namespace {
});*/
// Too deeply nested list
} else {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<IfcParse::reference_or_simple_type>{ v };
} else {
boost::get<std::vector<IfcParse::reference_or_simple_type>>(aggregate_storage).push_back(v);
}
append_to_aggregate_storage(v);
}
}, t);
}
@@ -246,17 +250,8 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
}
);
}
std::vector<IfcUtil::ArgumentType> attr_types;
std::transform(
parameter_types.begin(),
parameter_types.end(),
std::back_inserter(attr_types),
IfcUtil::from_parameter_type
);
if (decl && (tokens_.size() != attr_types.size())) {
if (decl && (tokens_.size() != parameter_types.size())) {
// warning
}
@@ -265,17 +260,15 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
}
storage_t storage(decl
? (std::min)(attr_types.size(), tokens_.size())
? (std::min)(parameter_types.size(), tokens_.size())
: tokens_.size()
);
auto it = tokens_.begin();
auto jt = attr_types.begin();
auto kt = parameter_types.begin();
for (; it != tokens_.end() && (!decl || jt != attr_types.end()); ++it) {
for (; it != tokens_.end() && (!decl || kt != parameter_types.end()); ++it) {
auto& token = *it;
// @todo coerce to expected type, e.g empty -> std::vector<int>, bool -> logical
// auto& attr_type = *jt;
const IfcParse::parameter_type* param_type = nullptr;
if (decl) {
param_type = *kt;
@@ -286,20 +279,26 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
boost::apply_visitor([this, &storage, name, &references_to_resolve, index, it, param_type](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
dispatch_token(v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, [this, &storage, name, &references_to_resolve, index](auto v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, InstanceReference>) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::reference_or_simple_type>) {
references_to_resolve.push_back(std::make_pair(
// @todo previously this was storage but apparently the
// pointer is not constant with the moving and temporary nature
// maybe it ought to be and in that case a pointer is more direct
MutableAttributeValue{ name, index },
unresolved_references::value_type::second_type{v}
v
));
} else {
storage.set(index, v);
}
});
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
construct_(*v, [this, &storage, name, &references_to_resolve, index](auto& v) {
auto pt = param_type;
if (pt) {
while (pt->as_named_type()) {
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
}
}
construct_(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
references_to_resolve.push_back({ {name, index }, v });
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
@@ -314,7 +313,7 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
}, token);
if (decl) {
++jt, ++kt;
++kt;
}
}
+6 -6
View File
@@ -104,7 +104,7 @@ class IFC_PARSE_API IfcFile {
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef boost::unordered_map<uint32_t, IfcUtil::IfcBaseClass*> entity_by_iden_t;
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
typedef std::tuple<int, int, int> inverse_attr_record;
typedef std::tuple<int, short, short> inverse_attr_record;
enum INVERSE_ATTR {
INSTANCE_ID,
INSTANCE_TYPE,
@@ -165,10 +165,10 @@ class IFC_PARSE_API IfcFile {
entity_by_id_t byid_;
// this is for simple types
entity_by_iden_t byidentity_;
entities_by_type_t bytype_;
// entities_by_type_t bytype_;
entities_by_type_t bytype_excl_;
entities_by_ref_t byref_;
entities_by_ref_excl_t byref_excl_;
// entities_by_ref_t byref_;
entities_by_ref_t byref_excl_;
entity_by_guid_t byguid_;
entity_entity_map_t entity_file_map_;
@@ -222,8 +222,8 @@ class IFC_PARSE_API IfcFile {
type_iterator types_begin() const;
type_iterator types_end() const;
type_iterator types_incl_super_begin() const;
type_iterator types_incl_super_end() const;
// type_iterator types_incl_super_begin() const;
// type_iterator types_incl_super_end() const;
/// Returns all entities in the file that match the template argument.
/// NOTE: This also returns subtypes of the requested type, for example:
+1 -1
View File
@@ -446,7 +446,7 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
data.storage_.set(relating_index, relating_object);
data.storage_.set(related_index, related_objects);
T* t = (T*)Schema::get_schema().instantiate(T::Class().name(), std::move(data));
T* t = (T*)Schema::get_schema().instantiate(&T::Class(), std::move(data));
addEntity(t);
}
}
+9 -3
View File
@@ -17,6 +17,8 @@
* *
********************************************************************************/
#define _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR
#include "IfcLogger.h"
#include "Argument.h"
@@ -147,8 +149,12 @@ void Logger::SetOutput(std::wostream* stream1, std::wostream* stream2) {
}
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
// static std::mutex mtx;
// std::lock_guard<std::mutex> lock(mtx);
if (type < verbosity_) {
return;
}
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
if (type == LOG_PERF) {
if (!first_timepoint_) {
@@ -166,7 +172,7 @@ void Logger::Message(Logger::Severity type, const std::string& message, const If
if (type > max_severity_) {
max_severity_ = type;
}
if (((log2_ != nullptr) || (wlog2_ != nullptr)) && type >= verbosity_) {
if (((log2_ != nullptr) || (wlog2_ != nullptr))) {
if (format_ == FMT_PLAIN) {
if (log2_ != nullptr) {
plain_text_message(*log2_, current_product_, type, message, instance);
+103 -355
View File
@@ -693,27 +693,6 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
next = tokens->Next();
}
/*
std::vector<Argument*>* vector = 0;
vector_or_array<Argument*> filler(attributes, num_attributes);
if (attributes == 0) {
if (num_attributes != 0) {
// If num_attributes is zero we know this is a top-level entity instance (or header entity) being parsed.
// There can only be parsed one of these at a time, so we can reuse the vector we have defined at the file
// scope.
if (entity != nullptr) {
vector = &internal_attribute_vector_;
} else {
vector = &internal_attribute_vector_simple_type_;
}
vector->clear();
} else {
vector = new std::vector<Argument*>;
}
filler = vector_or_array<Argument*>(vector);
}
*/
size_t attribute_index_within_data = 0;
size_t return_value = 0;
@@ -737,7 +716,8 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
try {
parse_context ps;
load(0, nullptr, ps, -1);
auto* simple_type_instance = schema_->instantiate(TokenFunc::asStringRef(next), ps.construct(-1, references_to_resolve, schema_->declaration_by_name(TokenFunc::asStringRef(next))));
auto decl = schema_->declaration_by_name(TokenFunc::asStringRef(next));
auto* simple_type_instance = schema_->instantiate(decl, ps.construct(-1, references_to_resolve, decl));
//@todo decide addEntity(((IfcUtil::IfcBaseClass*)*entity));
context.push(simple_type_instance);
simple_type_instance->file_ = this;
@@ -766,10 +746,6 @@ IfcEntityInstanceData IfcParse::read(unsigned int i, IfcFile* f) {
parse_context pc;
f->load(i, ty->as_entity(), pc, -1);
return IfcEntityInstanceData(pc.construct(i, f->references_to_resolve, ty));
/*std::ostringstream oss;
d.toString(oss);
auto osss = oss.str();
std::wcout << osss.c_str() << std::endl;*/
}
void IfcParse::IfcFile::try_read_semicolon() {
@@ -783,37 +759,16 @@ void IfcParse::IfcFile::try_read_semicolon() {
void IfcParse::IfcFile::register_inverse(unsigned id_from, const IfcParse::entity* from_entity, Token t, int attribute_index) {
// Assume a check on token type has already been performed
const auto* e = from_entity;
byref_excl_[t.value_int].push_back(id_from);
while (e != nullptr) {
byref_[{t.value_int, e->index_in_schema(), attribute_index}].push_back(id_from);
e = e->supertype();
}
byref_excl_[{t.value_int, e->index_in_schema(), attribute_index}].push_back(id_from);
}
void IfcParse::IfcFile::register_inverse(unsigned id_from, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass* inst, int attribute_index) {
const auto* e = from_entity;
byref_excl_[inst->id()].push_back(id_from);
while (e != nullptr) {
byref_[{inst->id(), e->index_in_schema(), attribute_index}].push_back(id_from);
e = e->supertype();
}
byref_excl_[{inst->id(), e->index_in_schema(), attribute_index}].push_back(id_from);
}
void IfcParse::IfcFile::unregister_inverse(unsigned id_from, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass* inst, int attribute_index) {
const auto* entity = from_entity;
while (entity != nullptr) {
std::vector<int>& ids = byref_[{inst->id(), entity->index_in_schema(), attribute_index}];
std::vector<int>::iterator iter = std::find(ids.begin(), ids.end(), id_from);
if (iter == ids.end()) {
// @todo inverses also need to be populated when multiple instances are added to a new file.
// throw IfcParse::IfcException("Instance not found among inverses");
} else {
ids.erase(iter);
}
entity = entity->supertype();
}
std::vector<int>& ids = byref_excl_[inst->id()];
std::vector<int>& ids = byref_excl_[{inst->id(), from_entity->index_in_schema(), attribute_index}];
std::vector<int>::iterator iter = std::find(ids.begin(), ids.end(), id_from);
if (iter == ids.end()) {
// @todo inverses also need to be populated when multiple instances are added to a new file.
@@ -917,7 +872,7 @@ namespace {
}
void operator()(const IfcUtil::IfcBaseClass* const& i) {
if (i->declaration().as_entity() == nullptr) {
i->data().toString(data_, true);
i->toString(data_, upper_);
} else {
data_ << "#" << i->id();
}
@@ -1025,20 +980,6 @@ namespace {
void IfcEntityInstanceData::toString(std::ostream& ss, bool upper, const entity* decl) const {
ss.imbue(std::locale::classic());
/*
std::string dt;
if (type_ != nullptr) {
dt = type()->name();
if (upper) {
boost::to_upper(dt);
}
if ((type()->as_entity() != nullptr) || id_ != 0) {
ss << "#" << id_ << "=";
}
}
*/
ss << "(";
StringBuilderVisitor vis(ss, upper);
@@ -1206,149 +1147,8 @@ void IfcUtil::IfcBaseClass::set_attribute_value(size_t i, const T& t) {
}
data_.storage_.set(i, t);
auto new_attribute = data_.get_attribute_value(i);
/*
Argument* new_attribute = a;
if (make_copy) {
if (attr_type == IfcUtil::Argument_UNKNOWN) {
attr_type = a->type();
} else if (a->isNull()) {
attr_type = IfcUtil::Argument_NULL;
}
IfcWrite::IfcWriteArgument* copy = new IfcWrite::IfcWriteArgument();
switch (attr_type) {
case IfcUtil::Argument_NULL:
copy->set(boost::blank());
break;
case IfcUtil::Argument_DERIVED:
copy->set(IfcWrite::IfcWriteArgument::Derived());
break;
case IfcUtil::Argument_INT:
copy->set(static_cast<int>(*a));
break;
case IfcUtil::Argument_BOOL:
copy->set(static_cast<bool>(*a));
break;
case IfcUtil::Argument_LOGICAL: {
boost::logic::tribool tb = *a;
copy->set(tb);
break;
}
case IfcUtil::Argument_DOUBLE:
copy->set(static_cast<double>(*a));
break;
case IfcUtil::Argument_STRING:
copy->set(static_cast<std::string>(*a));
break;
case IfcUtil::Argument_BINARY: {
boost::dynamic_bitset<> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_INT: {
std::vector<int> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: {
std::vector<double> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_STRING: {
std::vector<std::string> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_BINARY: {
std::vector<boost::dynamic_bitset<>> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_ENUMERATION: {
std::string enum_literal = a->toString();
// Remove leading and trailing '.'
enum_literal = enum_literal.substr(1, enum_literal.size() - 2);
const IfcParse::enumeration_type* enum_type = type()->as_enumeration_type() != nullptr
? type()->as_enumeration_type()
: type()->as_entity()->attribute_by_index(i)->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type();
std::vector<std::string>::const_iterator it = std::find(
enum_type->enumeration_items().begin(),
enum_type->enumeration_items().end(),
enum_literal);
if (it == enum_type->enumeration_items().end()) {
throw IfcParse::IfcException(enum_literal + " does not name a valid item for " + enum_type->name());
}
copy->set(IfcWrite::IfcWriteArgument::EnumerationReference(it - enum_type->enumeration_items().begin(), it->c_str()));
break;
}
case IfcUtil::Argument_ENTITY_INSTANCE: {
copy->set(static_cast<IfcUtil::IfcBaseClass*>(*a));
break;
}
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
aggregate_of_instance::ptr instances = *a;
aggregate_of_instance::ptr mapped_instances(new aggregate_of_instance);
// @todo mapped_instances are not actually mapped to the file using add().
for (aggregate_of_instance::it it = instances->begin(); it != instances->end(); ++it) {
mapped_instances->push(*it);
}
copy->set(mapped_instances);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: {
std::vector<std::vector<int>> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: {
std::vector<std::vector<double>> attr_value = *a;
copy->set(attr_value);
break;
}
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
aggregate_of_aggregate_of_instance::ptr instances = *a;
aggregate_of_aggregate_of_instance::ptr mapped_instances(new aggregate_of_aggregate_of_instance);
for (aggregate_of_aggregate_of_instance::outer_it it = instances->begin(); it != instances->end(); ++it) {
std::vector<IfcUtil::IfcBaseClass*> inner;
for (aggregate_of_aggregate_of_instance::inner_it jt = it->begin(); jt != it->end(); ++jt) {
inner.push_back(*jt);
}
mapped_instances->push(inner);
}
copy->set(mapped_instances);
break;
}
case IfcUtil::Argument_EMPTY_AGGREGATE:
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE: {
IfcUtil::ArgumentType t2 = IfcUtil::from_parameter_type(type()->as_entity()->attribute_by_index(i)->type_of_attribute());
delete copy;
copy = 0;
setArgument(i, a, t2, make_copy);
break;
}
default:
case IfcUtil::Argument_UNKNOWN:
throw IfcParse::IfcException(std::string("Unknown attribute encountered: '") + a->toString() + "' at index '" + boost::lexical_cast<std::string>(i) + "'");
break;
}
if (copy == nullptr) {
return;
}
new_attribute = copy;
}
*/
if (file_ != nullptr) {
// Register inverse indices in file
register_inverse_visitor visitor(*file_, this);
@@ -1385,16 +1185,19 @@ IfcFile::IfcFile(const std::string& fn, bool mmap) {
}
#else
IfcFile::IfcFile(const std::string& path) {
initialize_(new IfcSpfStream(path));
IfcSpfStream s(path);
initialize_(&s);
}
#endif
IfcFile::IfcFile(std::istream& stream, int length) {
initialize_(new IfcSpfStream(stream, length));
IfcSpfStream s(stream, length);
initialize_(&s);
}
IfcFile::IfcFile(void* data, int length) {
initialize_(new IfcSpfStream(data, length));
IfcSpfStream s(data, length);
initialize_(&s);
}
IfcFile::IfcFile(IfcParse::IfcSpfStream* s) {
@@ -1493,7 +1296,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
parse_context ps;
load(current_id, entity_type->as_entity(), ps, -1);
instance = schema_->instantiate(entity_type->name(), ps.construct(current_id, references_to_resolve, entity_type));
instance = schema_->instantiate(entity_type, ps.construct(current_id, references_to_resolve, entity_type));
instance->file_ = this;
instance->id_ = current_id;
@@ -1525,27 +1328,10 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
const IfcParse::declaration* ty = &instance->declaration();
{
aggregate_of_instance::ptr insts = instances_by_type_excl_subtypes(ty);
if (!insts) {
insts = aggregate_of_instance::ptr(new aggregate_of_instance());
bytype_excl_[ty] = insts;
}
insts->push(instance);
}
for (;;) {
aggregate_of_instance::ptr insts = instances_by_type(ty);
if (!insts) {
insts = aggregate_of_instance::ptr(new aggregate_of_instance());
bytype_[ty] = insts;
}
insts->push(instance);
const IfcParse::declaration* pt = ty->as_entity()->supertype();
if (pt != nullptr) {
ty = pt;
} else {
break;
if (bytype_excl_.find(ty) == bytype_excl_.end()) {
bytype_excl_[ty].reset(new aggregate_of_instance());
}
bytype_excl_[ty]->push(instance);
}
if (byid_.find(current_id) != byid_.end()) {
@@ -1588,6 +1374,8 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
Logger::Status("\rDone scanning file ");
delete tokens;
for (auto& p : references_to_resolve) {
boost::apply_visitor([this, &p](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, reference_or_simple_type>) {
@@ -1602,6 +1390,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
}, v));
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
aggregate_of_instance::ptr instances(new aggregate_of_instance);
instances->reserve(v.size());
for (auto& p : v) {
instances->push(boost::apply_visitor([this](auto inst) {
IfcUtil::IfcBaseClass* ptr;
@@ -1810,7 +1599,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id)
IfcFile* other_file = entity->file_;
IfcEntityInstanceData we(entity->data());
new_entity = schema()->instantiate(entity->declaration().name(), std::move(we));
new_entity = schema()->instantiate(&entity->declaration(), std::move(we));
// In case an entity is added that contains geometry, the unit
// information needs to be accounted for for IfcLengthMeasures.
@@ -1931,7 +1720,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id)
Logger::Message(Logger::LOG_WARNING, ss.str());
}
byguid_[guid] = new_entity;
} catch (const IfcException& ex) {
} catch (const std::exception& ex) {
Logger::Message(Logger::LOG_ERROR, ex.what());
}
}
@@ -1940,28 +1729,10 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id)
const IfcParse::declaration* ty = &new_entity->declaration();
if (ty->as_entity() != nullptr) {
aggregate_of_instance::ptr insts = instances_by_type_excl_subtypes(ty);
if (!insts) {
insts = aggregate_of_instance::ptr(new aggregate_of_instance());
bytype_excl_[ty] = insts;
}
insts->push(new_entity);
}
for (; ty->as_entity() != nullptr;) {
aggregate_of_instance::ptr insts = instances_by_type(ty);
if (!insts) {
insts = aggregate_of_instance::ptr(new aggregate_of_instance());
bytype_[ty] = insts;
}
insts->push(new_entity);
const IfcParse::declaration* pt = ty->as_entity()->supertype();
if (pt != nullptr) {
ty = pt;
} else {
break;
if (bytype_excl_.find(ty) == bytype_excl_.end()) {
bytype_excl_[ty].reset(new aggregate_of_instance());
}
bytype_excl_[ty]->push(new_entity);
}
if (ty->as_entity() != nullptr) {
@@ -2106,11 +1877,11 @@ void IfcFile::process_deletion_() {
}
if (!batch_mode_) {
byref_.erase(
byref_.lower_bound({id, -1, -1}),
byref_.upper_bound({id, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()}));
byref_excl_.erase(
byref_excl_.lower_bound({id, -1, -1}),
byref_excl_.upper_bound({id, std::numeric_limits<short>::max(), std::numeric_limits<short>::max()}));
byref_excl_.erase(id);
// byref_excl_.erase(id);
// This is based on traversal which needs instances to still be contained in the map.
// another option would be to keep byid intact for the remainder of this loop
@@ -2124,21 +1895,14 @@ void IfcFile::process_deletion_() {
// Do not update inverses for simple types (which have id()==0 in IfcOpenShell).
if (name != 0) {
{
auto lower = byref_.lower_bound({name, -1, -1});
auto upper = byref_.upper_bound({name, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()});
auto lower = byref_excl_.lower_bound({name, -1, -1});
auto upper = byref_excl_.upper_bound({name, std::numeric_limits<short>::max(), std::numeric_limits<short>::max()});
for (auto byref_it = lower; byref_it != upper; ++byref_it) {
auto& ids = byref_it->second;
ids.erase(std::remove(ids.begin(), ids.end(), id), ids.end());
}
}
{
auto byref_it = byref_excl_.find(name);
if (byref_it != byref_excl_.end()) {
auto& ids = byref_it->second;
ids.erase(std::remove(ids.begin(), ids.end(), id), ids.end());
}
}
}
}
}
@@ -2158,27 +1922,12 @@ void IfcFile::process_deletion_() {
const IfcParse::declaration* ty = &entity->declaration();
{
aggregate_of_instance::ptr instances_of_same_type = instances_by_type_excl_subtypes(ty);
instances_of_same_type->remove(entity);
if (instances_of_same_type->size() == 0) {
bytype_excl_.erase(ty);
}
}
for (;;) {
aggregate_of_instance::ptr instances_of_same_type = instances_by_type(ty);
if (instances_of_same_type) {
instances_of_same_type->remove(entity);
}
if (instances_of_same_type->size() == 0) {
bytype_.erase(ty);
}
const IfcParse::declaration* pt = ty->as_entity()->supertype();
if (pt != nullptr) {
ty = pt;
} else {
break;
auto it = bytype_excl_.find(ty);
if (it != bytype_excl_.end()) {
it->second->remove(entity);
if (it->second->size() == 0) {
bytype_excl_.erase(ty);
}
}
}
@@ -2196,24 +1945,8 @@ void IfcFile::process_deletion_() {
}
if (batch_mode_) {
for (auto it = byref_.begin(); it != byref_.end();) {
bool do_delete = batch_deletion_ids_.get<1>().find(std::get<INSTANCE_ID>(it->first)) != batch_deletion_ids_.get<1>().end();
if (!do_delete) {
it->second.erase(std::remove_if(it->second.begin(), it->second.end(), [this](int x) {
return batch_deletion_ids_.get<1>().find(x) != batch_deletion_ids_.get<1>().end();
}),
it->second.end());
do_delete = it->second.empty();
}
if (do_delete) {
it = byref_.erase(it);
} else {
++it;
}
}
for (auto it = byref_excl_.begin(); it != byref_excl_.end();) {
bool do_delete = batch_deletion_ids_.get<1>().find(it->first) != batch_deletion_ids_.get<1>().end();
bool do_delete = batch_deletion_ids_.get<1>().find(std::get<INSTANCE_ID>(it->first)) != batch_deletion_ids_.get<1>().end();
if (!do_delete) {
it->second.erase(std::remove_if(it->second.begin(), it->second.end(), [this](int x) {
return batch_deletion_ids_.get<1>().find(x) != batch_deletion_ids_.get<1>().end();
@@ -2232,14 +1965,40 @@ void IfcFile::process_deletion_() {
batch_deletion_ids_.clear();
}
namespace {
template <typename Fn>
void visit_subtypes(const IfcParse::entity* ent, Fn fn) {
fn(ent);
for (auto& st : ent->subtypes()) {
visit_subtypes(st, fn);
}
}
template <typename Fn>
void visit_supertypes(const IfcParse::entity* ent, Fn fn) {
fn(ent);
if (ent->supertype()) {
visit_supertypes(ent->supertype(), fn);
}
}
}
aggregate_of_instance::ptr IfcFile::instances_by_type(const IfcParse::declaration* t) {
entities_by_type_t::const_iterator it = bytype_.find(t);
return (it == bytype_.end()) ? aggregate_of_instance::ptr() : it->second;
aggregate_of_instance::ptr insts(new aggregate_of_instance);
if (t->as_entity()) {
visit_subtypes(t->as_entity(), [this, &insts](const IfcParse::entity* ent) {
auto it = bytype_excl_.find(ent);
if (it != bytype_excl_.end()) {
insts->push(it->second);
}
});
}
return insts;
}
aggregate_of_instance::ptr IfcFile::instances_by_type_excl_subtypes(const IfcParse::declaration* t) {
entities_by_type_t::const_iterator it = bytype_excl_.find(t);
return (it == bytype_excl_.end()) ? aggregate_of_instance::ptr() : it->second;
return (it == bytype_excl_.end()) ? aggregate_of_instance::ptr(new aggregate_of_instance) : it->second;
}
aggregate_of_instance::ptr IfcFile::instances_by_type(const std::string& t) {
@@ -2251,9 +2010,13 @@ aggregate_of_instance::ptr IfcFile::instances_by_type_excl_subtypes(const std::s
}
aggregate_of_instance::ptr IfcFile::instances_by_reference(int t) {
auto lower = byref_excl_.lower_bound({ t, -1, -1 });
auto upper = byref_excl_.upper_bound({ t, std::numeric_limits<short>::max(), std::numeric_limits<short>::max() });
aggregate_of_instance::ptr ret(new aggregate_of_instance);
for (auto& i : byref_excl_[t]) {
ret->push(instance_by_id(i));
for (auto it = lower; it != upper; ++it) {
for (auto& i : it->second) {
ret->push(instance_by_id(i));
}
}
return ret;
}
@@ -2286,8 +2049,6 @@ IfcFile::~IfcFile() {
for (auto* entity : entities_to_delete) {
delete entity;
}
delete stream;
delete tokens;
}
IfcFile::entity_by_id_t::const_iterator IfcFile::begin() const {
@@ -2306,14 +2067,6 @@ IfcFile::type_iterator IfcFile::types_end() const {
return bytype_excl_.end();
}
IfcFile::type_iterator IfcFile::types_incl_super_begin() const {
return bytype_.begin();
}
IfcFile::type_iterator IfcFile::types_incl_super_end() const {
return bytype_.end();
}
namespace {
struct id_instance_pair_sorter {
bool operator()(const IfcParse::IfcFile::entity_by_id_t::value_type& a, const IfcParse::IfcFile::entity_by_id_t::value_type& b) const {
@@ -2362,8 +2115,8 @@ std::string IfcFile::createTimestamp() const {
std::vector<int> IfcFile::get_inverse_indices(int instance_id) {
std::vector<int> return_value;
auto lower = byref_.lower_bound({instance_id, -1, -1});
auto upper = byref_.upper_bound({instance_id, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()});
auto lower = byref_excl_.lower_bound({instance_id, -1, -1});
auto upper = byref_excl_.upper_bound({instance_id, std::numeric_limits<short>::max(), std::numeric_limits<short>::max()});
// Mapping of instance id to attribute offset.
std::map<int, std::vector<int>> mapping;
@@ -2401,39 +2154,43 @@ std::vector<int> IfcFile::get_inverse_indices(int instance_id) {
}
aggregate_of_instance::ptr IfcFile::getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index) {
// @todo is this mutex still necessary?
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
if (type == nullptr && attribute_index == -1) {
return instances_by_reference(instance_id);
}
aggregate_of_instance::ptr return_value(new aggregate_of_instance);
if (attribute_index == -1) {
auto lower = byref_.lower_bound({instance_id, type->index_in_schema(), -1});
auto upper = byref_.upper_bound({instance_id, type->index_in_schema(), std::numeric_limits<int>::max()});
visit_subtypes(type->as_entity(), [this, attribute_index, instance_id, &return_value](const IfcParse::declaration* ent) {
if (attribute_index == -1) {
auto lower = byref_excl_.lower_bound({ instance_id, ent->index_in_schema(), -1 });
auto upper = byref_excl_.upper_bound({ instance_id, ent->index_in_schema(), std::numeric_limits<short>::max() });
for (auto it = lower; it != upper; ++it) {
for (auto& i : it->second) {
return_value->push(instance_by_id(i));
for (auto it = lower; it != upper; ++it) {
for (auto& i : it->second) {
return_value->push(instance_by_id(i));
}
}
} else {
auto it = byref_excl_.find({ instance_id, ent->index_in_schema(), attribute_index });
if (it != byref_excl_.end()) {
for (auto& i : it->second) {
return_value->push(instance_by_id(i));
}
}
}
} else {
auto it = byref_.find({instance_id, type->index_in_schema(), attribute_index});
if (it != byref_.end()) {
for (auto& i : it->second) {
return_value->push(instance_by_id(i));
}
}
}
});
return return_value;
}
size_t IfcFile::getTotalInverses(int instance_id) {
return byref_excl_[instance_id].size();
size_t n = 0;
auto lower = byref_excl_.lower_bound({ instance_id, -1, -1 });
auto upper = byref_excl_.upper_bound({ instance_id, std::numeric_limits<short>::max(), std::numeric_limits<short>::max() });
for (auto it = lower; it != upper; ++it) {
n += it->second.size();
}
return n;
}
void IfcFile::setDefaultHeaderValues() {
@@ -2531,11 +2288,7 @@ void IfcParse::IfcFile::build_inverses_(IfcUtil::IfcBaseClass* inst) {
if (attr->declaration().as_entity() != nullptr) {
unsigned entity_attribute_id = attr->id();
const auto* decl = inst->declaration().as_entity();
byref_excl_[entity_attribute_id].push_back(inst->id());
while (decl != nullptr) {
byref_[{entity_attribute_id, decl->index_in_schema(), idx}].push_back(inst->id());
decl = decl->supertype();
}
byref_excl_[{entity_attribute_id, decl->index_in_schema(), idx}].push_back(inst->id());
}
};
@@ -2552,15 +2305,6 @@ std::atomic_uint32_t IfcUtil::IfcBaseClass::counter_(0);
bool IfcParse::IfcFile::guid_map_ = true;
/*
template <typename T>
void IfcUtil::IfcBaseClass::set_value(int index, const T& value) {
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
attr->set(value);
data_->setArgument(index, attr);
}
*/
void IfcUtil::IfcBaseClass::unset_attribute_value(size_t index) {
data_.storage_.set(index, Blank{});
}
@@ -2571,7 +2315,11 @@ void IfcUtil::IfcBaseClass::toString(std::ostream& out, bool upper) const
if (ent) {
out << "#" << as<IfcUtil::IfcBaseEntity>()->id() << "=";
}
out << declaration().name_uc();
if (upper) {
out << declaration().name_uc();
} else {
out << declaration().name();
}
data().toString(out, upper, ent);
}
+3 -3
View File
@@ -152,11 +152,11 @@ IfcParse::schema_definition::~schema_definition() {
delete factory_;
}
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(const std::string& type_name, IfcEntityInstanceData&& data) const {
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const {
if (factory_ != nullptr) {
return (*factory_)(declaration_by_name(type_name), std::move(data));
return (*factory_)(decl, std::move(data));
}
return new IfcUtil::IfcLateBoundEntity(declaration_by_name(type_name), std::move(data));
return new IfcUtil::IfcLateBoundEntity(decl, std::move(data));
}
void IfcParse::register_schema(schema_definition* schema) {
+1 -1
View File
@@ -507,7 +507,7 @@ class IFC_PARSE_API schema_definition {
const std::string& name() const { return name_; }
IfcUtil::IfcBaseClass* instantiate(const std::string& type_name, IfcEntityInstanceData&& data) const;
IfcUtil::IfcBaseClass* instantiate(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const;
};
IFC_PARSE_API const schema_definition* schema_by_name(const std::string&);
+1 -1
View File
@@ -503,7 +503,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
}
}
IfcUtil::IfcBaseClass* newinst = state->file->schema()->instantiate(decl->name(), std::move(untyped));
IfcUtil::IfcBaseClass* newinst = state->file->schema()->instantiate(decl, std::move(untyped));
if (state->dialect == ifcxml_dialect_ifc4) {
// In IFC2X3 not added directly because attrs such as GlobalId are in
+26 -1
View File
@@ -34,6 +34,8 @@ variant - which is the maximum size of its constituents - is reduced.
#include <memory>
#include <tuple>
#include "IfcException.h"
namespace impl {
// Trait to detect unique_ptr
template <typename...> struct is_unique_ptr : std::false_type {};
@@ -216,7 +218,13 @@ public:
template<typename T>
const T& get(std::size_t index) const {
if (size_and_indices_[index + 1] != impl::TypeIndex<T, Types...>::value) {
throw std::bad_cast();
// @todo this IfcException is silly. Figure out what
// to do, but at the moment it is specifically caught
// in various places.
throw IfcParse::IfcException(
"Type held at index " + std::to_string(index) + " is " +
get_type_name(index) + " and not " + typeid(T).name()
);
}
using V = typename std::tuple_element<impl::TypeIndex_v<T, Types...>, impl::MapTypes_t<Types... >>::type;
if constexpr (impl::is_unique_ptr<V>::value) {
@@ -290,6 +298,23 @@ private:
return decltype(std::declval<Visitor>()(std::declval<typename std::tuple_element_t<0, impl::MapTypes_t<Types...>> &>())){};
}
}
template <size_t I>
const char* get_type_name_impl(size_t i) const {
if constexpr (I == 0) {
return "";
} else {
if (i == I - 1) {
return typeid(std::tuple_element_t<I - 1, std::tuple<Types...>>).name();
} else {
return get_type_name_impl<I - 1>(i);
}
}
}
const char* get_type_name(size_t i) const {
return get_type_name_impl<sizeof...(Types)>(i);
}
};
#endif
+21 -19
View File
@@ -186,6 +186,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
return ts;
}
/*
std::vector<std::string> types_with_super() const {
const size_t n = std::distance($self->types_incl_super_begin(), $self->types_incl_super_end());
std::vector<std::string> ts;
@@ -193,6 +194,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
std::transform($self->types_incl_super_begin(), $self->types_incl_super_end(), std::back_inserter(ts), helper_fn_declaration_get_name);
return ts;
}
*/
std::string schema_name() const {
if ($self->schema() == 0) return "";
@@ -368,7 +370,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsNull(unsigned int i) {
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
if (is_optional) {
self->data().storage_.set(i, Blank{});
self->set_attribute_value(i, Blank{});
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -377,9 +379,9 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsInt(unsigned int i, int v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_INT) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else if ( (arg_type == IfcUtil::Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -388,7 +390,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsBool(unsigned int i, bool v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_BOOL) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -397,7 +399,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsLogical(unsigned int i, boost::logic::tribool v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_LOGICAL) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -406,7 +408,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsDouble(unsigned int i, double v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_DOUBLE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -415,15 +417,15 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsString(unsigned int i, const std::string& a) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_STRING) {
self->data().storage_.set(i, a);
self->set_attribute_value(i, a);
} else if (arg_type == IfcUtil::Argument_ENUMERATION) {
const IfcParse::enumeration_type* enum_type = $self->declaration().schema()->declaration_by_name($self->declaration().type())->as_entity()->
attribute_by_index(i)->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type();
self->data().storage_.set(i, EnumerationReference(enum_type, enum_type->lookup_enum_offset(a)));
self->set_attribute_value(i, EnumerationReference(enum_type, enum_type->lookup_enum_offset(a)));
} else if (arg_type == IfcUtil::Argument_BINARY) {
if (IfcUtil::valid_binary_string(a)) {
boost::dynamic_bitset<> bits(a);
self->data().storage_.set(i, bits);
self->set_attribute_value(i, bits);
} else {
throw IfcParse::IfcException("String not a valid binary representation");
}
@@ -435,7 +437,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfInt(unsigned int i, const std::vector<int>& v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -444,7 +446,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfDouble(unsigned int i, const std::vector<double>& v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -453,7 +455,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfString(unsigned int i, const std::vector<std::string>& v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_STRING) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else if (arg_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) {
std::vector< boost::dynamic_bitset<> > bits;
bits.reserve(v.size());
@@ -464,7 +466,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
throw IfcParse::IfcException("String not a valid binary representation");
}
}
self->data().storage_.set(i, bits);
self->set_attribute_value(i, bits);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -473,7 +475,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsEntityInstance(unsigned int i, IfcUtil::IfcBaseClass* v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_ENTITY_INSTANCE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -482,7 +484,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfEntityInstance(unsigned int i, aggregate_of_instance::ptr v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -491,7 +493,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfAggregateOfInt(unsigned int i, const std::vector< std::vector<int> >& v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -500,7 +502,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfAggregateOfDouble(unsigned int i, const std::vector< std::vector<double> >& v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -509,7 +511,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
void setArgumentAsAggregateOfAggregateOfEntityInstance(unsigned int i, aggregate_of_aggregate_of_instance::ptr v) {
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
self->data().storage_.set(i, v);
self->set_attribute_value(i, v);
} else {
throw IfcParse::IfcException("Attribute not set");
}
@@ -590,7 +592,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier);
const IfcParse::declaration* decl = schema->declaration_by_name(name);
IfcEntityInstanceData data(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1));
return schema->instantiate(decl->name(), std::move(data));
return schema->instantiate(decl, std::move(data));
}
%}
+3 -2
View File
@@ -64,10 +64,8 @@ assert "Version" in dir(app)
g = ifcopenshell.file(schema=f.schema)
p = g.createIfcCartesianPoint((0.,0.))
assert len(g.types()) == 1
assert "IfcPoint" in g.types_with_super()
g.remove(p)
assert len(g.types()) == 0
assert len(g.types_with_super()) == 0
# Some operations on ifcopenshell.entity_instance
assert f[22].Id == ''
@@ -92,6 +90,9 @@ assert f[288].ConnectedTo == (rel,)
# Some operations on ifcopenshell.guid
assert len(ifcopenshell.guid.compress(uuid.uuid1().hex)) == 22
# reopen, because we messed with the units
f = ifcopenshell.open("input/acad2010_walls.ifc")
# Test the BVH tree
tree_settings = ifcopenshell.geom.settings()
tree_settings.set(tree_settings.DISABLE_OPENING_SUBTRACTIONS, True)