Files
IfcOpenShell/src/ifcwrap/IfcParseWrapper.i
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

918 lines
29 KiB
OpenEdge ABL
Raw Normal View History

/********************************************************************************
2015-01-16 16:26:40 +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 *
2015-01-16 16:26:40 +00:00
* 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 *
2015-01-16 16:26:40 +00:00
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
2017-06-05 17:26:58 +02:00
// A class declaration to silence SWIG warning about base classes being
// undefined, the constructor is private so that SWIG does not wrap them
class IfcEntityInstanceData {
2015-01-16 16:26:40 +00:00
private:
2017-06-05 17:26:58 +02:00
IfcEntityInstanceData();
2015-01-16 16:26:40 +00:00
};
2017-07-03 15:43:56 +02:00
%ignore IfcParse::IfcFile::register_inverse;
%ignore IfcParse::IfcFile::unregister_inverse;
2017-12-31 12:20:13 +01:00
%ignore IfcParse::IfcFile::schema;
2018-07-08 10:32:26 +02:00
%ignore IfcParse::IfcFile::begin;
%ignore IfcParse::IfcFile::end;
%ignore operator<<;
%ignore IfcParse::FileDescription::FileDescription;
%ignore IfcParse::FileName::FileName;
%ignore IfcParse::FileSchema::FileSchema;
%ignore IfcParse::IfcFile::tokens;
2015-01-16 16:26:40 +00:00
%ignore IfcParse::IfcSpfHeader::IfcSpfHeader(IfcSpfLexer*);
%ignore IfcParse::IfcSpfHeader::lexer;
%ignore IfcParse::IfcSpfHeader::stream;
2015-01-16 16:26:40 +00:00
%ignore IfcParse::HeaderEntity::is;
%ignore IfcParse::IfcFile::type_iterator;
2017-06-05 17:26:58 +02:00
%ignore IfcUtil::IfcBaseClass::is;
2017-12-31 12:20:13 +01:00
%rename("by_id") instance_by_id;
%rename("by_type") instances_by_type;
2020-06-07 12:49:39 +02:00
%rename("by_type_excl_subtypes") instances_by_type_excl_subtypes;
2017-06-05 17:26:58 +02:00
%rename("entity_instance") IfcBaseClass;
%rename("file") IfcFile;
2017-06-05 17:26:58 +02:00
%rename("add") addEntity;
%rename("remove") removeEntity;
class attribute_value_derived {};
2017-12-22 13:51:11 +01:00
%{
class attribute_value_derived {};
%}
%extend attribute_value_derived {
%pythoncode %{
def __bool__(self): return False
def __repr__(self): return '*'
%}
}
%inline %{
static bool feature_use_attribute_value_derived = false;
void set_feature(const std::string& x, PyObject* v) {
if (PyBool_Check(v) && x == "use_attribute_value_derived") {
feature_use_attribute_value_derived = v == Py_True;
} else {
throw std::runtime_error("Invalid feature specification");
}
}
PyObject* get_feature(const std::string& x) {
if (x == "use_attribute_value_derived") {
return PyBool_FromLong(feature_use_attribute_value_derived);
} else {
throw std::runtime_error("Invalid feature specification");
}
}
%}
%{
2017-12-22 13:51:11 +01:00
static const std::string& helper_fn_declaration_get_name(const IfcParse::declaration* decl) {
return decl->name();
}
2018-05-29 10:34:38 +02:00
static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClass* inst, unsigned i) {
const IfcParse::parameter_type* pt = 0;
if (inst->declaration().as_entity()) {
pt = inst->declaration().as_entity()->attribute_by_index(i)->type_of_attribute();
2018-11-19 17:13:28 +01:00
if (inst->declaration().as_entity()->derived()[i]) {
return IfcUtil::Argument_DERIVED;
}
2018-05-29 10:34:38 +02:00
} else if (inst->declaration().as_type_declaration() && i == 0) {
pt = inst->declaration().as_type_declaration()->declared_type();
2021-02-14 17:22:15 +01:00
} else if (inst->declaration().as_enumeration_type() && i == 0) {
// Enumeration is always from string in Python
return IfcUtil::Argument_STRING;
2018-05-29 10:34:38 +02:00
}
if (pt == 0) {
return IfcUtil::Argument_UNKNOWN;
} else {
return IfcUtil::from_parameter_type(pt);
}
}
2017-12-22 13:51:11 +01:00
%}
%extend IfcParse::IfcFile {
2017-06-05 17:26:58 +02:00
IfcUtil::IfcBaseClass* by_guid(const std::string& guid) {
2017-12-22 13:51:11 +01:00
return $self->instance_by_guid(guid);
}
2021-07-29 15:15:51 +02:00
aggregate_of_instance::ptr get_inverse(IfcUtil::IfcBaseClass* e) {
2017-12-22 13:51:11 +01:00
return $self->getInverse(e->data().id(), 0, -1);
}
std::vector<int> get_inverse_indices(IfcUtil::IfcBaseClass* e) {
return $self->get_inverse_indices(e->data().id());
}
int get_total_inverses(IfcUtil::IfcBaseClass* e) {
return $self->getTotalInverses(e->data().id());
}
void write(const std::string& fn) {
2020-07-05 11:40:17 +02:00
std::ofstream f(IfcUtil::path::from_utf8(fn).c_str());
f << (*$self);
}
2017-06-05 17:26:58 +02:00
2019-05-22 16:18:48 +02:00
std::string to_string() {
std::stringstream s;
s << (*$self);
return s.str();
}
std::vector<unsigned> entity_names() const {
std::vector<unsigned> keys;
keys.reserve(std::distance($self->begin(), $self->end()));
for (IfcParse::IfcFile::entity_by_id_t::const_iterator it = $self->begin(); it != $self->end(); ++ it) {
keys.push_back(it->first);
}
return keys;
}
2017-06-05 17:26:58 +02:00
std::vector<std::string> types() const {
const size_t n = std::distance($self->types_begin(), $self->types_end());
std::vector<std::string> ts;
ts.reserve(n);
2017-12-22 13:51:11 +01:00
std::transform($self->types_begin(), $self->types_end(), std::back_inserter(ts), helper_fn_declaration_get_name);
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;
ts.reserve(n);
2017-12-22 13:51:11 +01:00
std::transform($self->types_incl_super_begin(), $self->types_incl_super_end(), std::back_inserter(ts), helper_fn_declaration_get_name);
return ts;
}
2017-12-31 12:20:13 +01:00
std::string schema_name() const {
if ($self->schema() == 0) return "";
return $self->schema()->name();
}
%pythoncode %{
# Hide the getters with read-only property implementations
header = property(header)
2019-05-31 14:33:40 +02:00
schema = property(schema_name)
%}
}
2017-06-05 17:26:58 +02:00
%extend IfcUtil::IfcBaseClass {
int get_attribute_category(const std::string& name) const {
2017-12-22 13:51:11 +01:00
if (!$self->declaration().as_entity()) {
2017-07-27 10:21:37 +02:00
return name == "wrappedValue";
}
2017-12-11 17:20:22 +01:00
{
const std::vector<const IfcParse::attribute*> attrs = $self->declaration().as_entity()->all_attributes();
std::vector<const IfcParse::attribute*>::const_iterator it = attrs.begin();
2017-12-11 17:20:22 +01:00
for (; it != attrs.end(); ++it) {
if ((*it)->name() == name) {
return 1;
}
}
}
{
const std::vector<const IfcParse::inverse_attribute*> attrs = $self->declaration().as_entity()->all_inverse_attributes();
std::vector<const IfcParse::inverse_attribute*>::const_iterator it = attrs.begin();
2017-12-11 17:20:22 +01:00
for (; it != attrs.end(); ++it) {
if ((*it)->name() == name) {
return 2;
}
}
2017-12-11 17:20:22 +01:00
}
return 0;
}
// id() is defined on IfcBaseEntity and not on IfcBaseClass, in order
// to expose it to the Python wrapper it is simply duplicated here.
2017-08-02 16:08:07 +02:00
// Same applies to the two methods reimplemented below.
int id() const {
2017-12-11 17:20:22 +01:00
return $self->data().id();
}
2017-08-02 16:08:07 +02:00
2017-12-31 12:20:13 +01:00
int __len__() const {
if ($self->declaration().as_entity()) {
return $self->declaration().as_entity()->attribute_count();
} else {
return 1;
}
}
std::vector<std::string> get_attribute_names() const {
2017-12-11 17:20:22 +01:00
if (!$self->declaration().as_entity()) {
2017-08-02 16:08:07 +02:00
return std::vector<std::string>(1, "wrappedValue");
}
2017-12-11 17:20:22 +01:00
const std::vector<const IfcParse::attribute*> attrs = $self->declaration().as_entity()->all_attributes();
2017-12-11 17:20:22 +01:00
std::vector<std::string> attr_names;
attr_names.reserve(attrs.size());
std::vector<const IfcParse::attribute*>::const_iterator it = attrs.begin();
2017-12-11 17:20:22 +01:00
for (; it != attrs.end(); ++it) {
attr_names.push_back((*it)->name());
}
return attr_names;
2017-08-02 16:08:07 +02:00
}
2017-12-31 12:20:13 +01:00
std::vector<std::string> get_inverse_attribute_names() const {
2017-12-11 17:20:22 +01:00
if (!$self->declaration().as_entity()) {
2017-08-02 16:08:07 +02:00
return std::vector<std::string>(0);
}
2017-12-11 17:20:22 +01:00
const std::vector<const IfcParse::inverse_attribute*> attrs = $self->declaration().as_entity()->all_inverse_attributes();
2017-12-11 17:20:22 +01:00
std::vector<std::string> attr_names;
attr_names.reserve(attrs.size());
std::vector<const IfcParse::inverse_attribute*>::const_iterator it = attrs.begin();
2017-12-11 17:20:22 +01:00
for (; it != attrs.end(); ++it) {
attr_names.push_back((*it)->name());
}
return attr_names;
2017-08-02 16:08:07 +02:00
}
2017-06-05 17:26:58 +02:00
bool is_a(const std::string& s) {
2017-12-22 13:51:11 +01:00
return self->declaration().is(s);
2017-06-05 17:26:58 +02:00
}
2021-12-02 11:05:36 +01:00
std::string is_a(bool with_schema=false) const {
auto t = self->declaration().name();
if (with_schema) {
t = self->declaration().schema()->name() + "." + t;
}
return t;
2017-06-05 17:26:58 +02:00
}
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(unsigned i) {
2017-12-11 17:20:22 +01:00
return std::pair<IfcUtil::ArgumentType,Argument*>($self->data().getArgument(i)->type(), $self->data().getArgument(i));
}
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(const std::string& a) {
2017-12-11 17:20:22 +01:00
unsigned i = $self->declaration().as_entity()->attribute_index(a);
return std::pair<IfcUtil::ArgumentType,Argument*>($self->data().getArgument(i)->type(), $self->data().getArgument(i));
}
2017-06-05 17:26:58 +02:00
bool __eq__(IfcUtil::IfcBaseClass* other) const {
2021-09-11 12:59:48 +02:00
return $self->identity() == other->identity();
2017-06-05 17:26:58 +02:00
}
std::string __repr__() const {
2017-12-11 17:20:22 +01:00
return $self->data().toString();
}
2022-10-08 17:18:47 +02:00
std::string to_string(bool valid_spf) const {
return $self->data().toString(valid_spf);
}
// Just something to have a somewhat sensible value to hash
size_t file_pointer() const {
2017-12-11 17:20:22 +01:00
return reinterpret_cast<size_t>($self->data().file);
}
2017-06-05 17:26:58 +02:00
unsigned get_argument_index(const std::string& a) const {
2017-12-31 12:20:13 +01:00
if ($self->declaration().as_entity()) {
return $self->declaration().as_entity()->attribute_index(a);
} else if (a == "wrappedValue") {
return 0;
} else {
throw IfcParse::IfcException(a + " not found on " + $self->declaration().name());
}
2017-06-05 17:26:58 +02:00
}
2021-07-29 15:15:51 +02:00
aggregate_of_instance::ptr get_inverse(const std::string& a) {
if ($self->declaration().as_entity()) {
return ((IfcUtil::IfcBaseEntity*)$self)->get_inverse(a);
} else {
throw IfcParse::IfcException(a + " not found on " + $self->declaration().name());
2017-12-11 17:20:22 +01:00
}
2017-06-05 17:26:58 +02:00
}
2017-12-31 12:20:13 +01:00
const char* const get_argument_type(unsigned int i) const {
2018-05-29 10:34:38 +02:00
return IfcUtil::ArgumentTypeToString(helper_fn_attribute_type($self, i));
2017-12-31 12:20:13 +01:00
}
const std::string& get_argument_name(unsigned int i) const {
if ($self->declaration().as_entity()) {
return $self->declaration().as_entity()->attribute_by_index(i)->name();
} else if (i == 0) {
static std::string WRAPPED = "wrappedValue";
return WRAPPED;
} else {
throw IfcParse::IfcException(boost::lexical_cast<std::string>(i) + " out of bounds on " + $self->declaration().name());
}
}
2017-06-05 17:26:58 +02:00
void setArgumentAsNull(unsigned int i) {
2017-12-11 17:20:22 +01:00
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
2017-06-05 17:26:58 +02:00
if (is_optional) {
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, new IfcWrite::IfcWriteArgument());
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsInt(unsigned int i, int v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_INT) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
2017-06-05 17:26:58 +02:00
} else if ( (arg_type == IfcUtil::Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v == 1);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsBool(unsigned int i, bool v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_BOOL) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
2021-07-29 16:32:45 +02:00
}
}
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) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
2017-12-11 17:20:22 +01:00
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsDouble(unsigned int i, double v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_DOUBLE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsString(unsigned int i, const std::string& a) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_STRING) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(a);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
2017-06-05 17:26:58 +02:00
} else if (arg_type == IfcUtil::Argument_ENUMERATION) {
2017-12-22 13:51:11 +01:00
const IfcParse::enumeration_type* enum_type = $self->declaration().schema()->declaration_by_name($self->declaration().type())->as_entity()->
2017-12-11 17:20:22 +01:00
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(),
a);
if (it == enum_type->enumeration_items().end()) {
throw IfcParse::IfcException(a + " does not name a valid item for " + enum_type->name());
}
2017-06-05 17:26:58 +02:00
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
2017-12-11 17:20:22 +01:00
arg->set(IfcWrite::IfcWriteArgument::EnumerationReference(it - enum_type->enumeration_items().begin(), it->c_str()));
self->data().setArgument(i, arg);
2017-06-05 17:26:58 +02:00
} else if (arg_type == IfcUtil::Argument_BINARY) {
if (IfcUtil::valid_binary_string(a)) {
boost::dynamic_bitset<> bits(a);
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(bits);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
2017-06-05 17:26:58 +02:00
} else {
throw IfcParse::IfcException("String not a valid binary representation");
}
2017-12-11 17:20:22 +01:00
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsAggregateOfInt(unsigned int i, const std::vector<int>& v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsAggregateOfDouble(unsigned int i, const std::vector<double>& v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsAggregateOfString(unsigned int i, const std::vector<std::string>& v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_STRING) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
2017-06-05 17:26:58 +02:00
} else if (arg_type == IfcUtil::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) {
if (IfcUtil::valid_binary_string(*it)) {
bits.push_back(boost::dynamic_bitset<>(*it));
} else {
throw IfcParse::IfcException("String not a valid binary representation");
}
}
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(bits);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsEntityInstance(unsigned int i, IfcUtil::IfcBaseClass* v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_ENTITY_INSTANCE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
2021-07-29 15:15:51 +02:00
void setArgumentAsAggregateOfEntityInstance(unsigned int i, aggregate_of_instance::ptr v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsAggregateOfAggregateOfInt(unsigned int i, const std::vector< std::vector<int> >& v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
void setArgumentAsAggregateOfAggregateOfDouble(unsigned int i, const std::vector< std::vector<double> >& v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
2021-07-29 15:15:51 +02:00
void setArgumentAsAggregateOfAggregateOfEntityInstance(unsigned int i, aggregate_of_aggregate_of_instance::ptr v) {
2018-05-29 10:34:38 +02:00
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
2017-06-05 17:26:58 +02:00
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(v);
2017-12-11 17:20:22 +01:00
self->data().setArgument(i, arg);
} else {
throw IfcParse::IfcException("Attribute not set");
}
2017-06-05 17:26:58 +02:00
}
}
%extend IfcParse::IfcSpfHeader {
%pythoncode %{
# Hide the getters with read-only property implementations
file_description = property(file_description)
file_name = property(file_name)
file_schema = property(file_schema)
%}
};
%extend IfcParse::FileDescription {
%pythoncode %{
# Hide the getters with read-write property implementations
description = property(description, description)
implementation_level = property(implementation_level, implementation_level)
%}
};
%extend IfcParse::FileName {
%pythoncode %{
name = property(name, name)
time_stamp = property(time_stamp, time_stamp)
author = property(author, author)
organization = property(organization, organization)
preprocessor_version = property(preprocessor_version, preprocessor_version)
originating_system = property(originating_system, originating_system)
authorization = property(authorization, authorization)
%}
};
%extend IfcParse::FileSchema {
%pythoncode %{
# Hide the getters with read-write property implementations
schema_identifiers = property(schema_identifiers, schema_identifiers)
%}
};
2016-08-06 18:19:27 +03:00
%include "../ifcparse/ifc_parse_api.h"
%include "../ifcparse/IfcSpfHeader.h"
%include "../ifcparse/IfcFile.h"
2017-06-05 17:26:58 +02:00
%include "../ifcparse/IfcBaseClass.h"
2017-12-31 12:20:13 +01:00
%include "../ifcparse/IfcSchema.h"
// The IfcFile* returned by open() is to be freed by SWIG/Python
%newobject open;
2017-08-22 09:15:02 +01:00
%newobject read;
2021-03-27 10:00:41 +01:00
%newobject parse_ifcxml;
2020-06-19 22:03:41 +02:00
%inline %{
2017-08-22 09:15:02 +01:00
IfcParse::IfcFile* open(const std::string& fn) {
2017-12-22 13:51:11 +01:00
IfcParse::IfcFile* f = new IfcParse::IfcFile(fn);
2017-08-22 09:15:02 +01:00
return f;
}
2017-12-22 13:51:11 +01:00
2017-08-22 09:15:02 +01:00
IfcParse::IfcFile* read(const std::string& data) {
char* copiedData = new char[data.length()];
memcpy(copiedData, data.c_str(), data.length());
2017-12-22 13:51:11 +01:00
IfcParse::IfcFile* f = new IfcParse::IfcFile((void *)copiedData, data.length());
return f;
}
2016-09-01 12:28:17 +03:00
const char* version() {
return IFCOPENSHELL_VERSION;
}
2016-04-17 15:27:05 +02:00
2017-12-22 13:51:11 +01:00
IfcUtil::IfcBaseClass* new_IfcBaseClass(const std::string& schema_identifier, const std::string& name) {
const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier);
const IfcParse::declaration* decl = schema->declaration_by_name(name);
IfcEntityInstanceData* data = new IfcEntityInstanceData(decl);
2017-12-11 17:20:22 +01:00
2018-01-29 15:02:36 +01:00
for (size_t i = 0; i < data->getArgumentCount(); ++i) {
data->setArgument(i, new IfcWrite::IfcWriteArgument());
}
2017-12-11 17:20:22 +01:00
2017-12-22 13:51:11 +01:00
if (decl->as_entity()) {
const std::vector<bool>& derived = decl->as_entity()->derived();
2017-12-11 17:20:22 +01:00
std::vector<bool>::const_iterator it = derived.begin();
size_t index = 0;
for (; it != derived.end(); ++it, ++index) {
if (*it) {
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
arg->set(IfcWrite::IfcWriteArgument::Derived());
data->setArgument(index, arg);
}
}
}
2017-12-22 13:51:11 +01:00
return schema->instantiate(data);
2017-06-05 17:26:58 +02:00
}
2017-08-19 16:54:06 +02:00
%}
%extend IfcParse::named_type {
%pythoncode %{
def __repr__(self):
return repr(self.declared_type())
%}
}
%extend IfcParse::simple_type {
%pythoncode %{
def __repr__(self):
return "<%s>" % self.declared_type()
%}
}
%extend IfcParse::aggregation_type {
std::string type_of_aggregation_string() const {
static const char* const aggr_strings[] = {"array", "bag", "list", "set"};
return aggr_strings[(int) $self->type_of_aggregation()];
}
%pythoncode %{
def __repr__(self):
format_bound = lambda i: "?" if i == -1 else str(i)
return "<%s [%s:%s] of %r>" % (
self.type_of_aggregation_string(),
format_bound(self.bound1()),
format_bound(self.bound2()),
self.type_of_element()
)
%}
}
%extend IfcParse::type_declaration {
%pythoncode %{
def __repr__(self):
return "<type %s: %r>" % (self.name(), self.declared_type())
%}
2021-12-02 11:39:28 +01:00
std::vector<std::string> argument_types() {
std::vector<std::string> r;
auto at = IfcUtil::Argument_UNKNOWN;
auto pt = $self->declared_type();
if (pt) {
at = IfcUtil::from_parameter_type(pt);
}
r.push_back(IfcUtil::ArgumentTypeToString(at));
return r;
}
}
%extend IfcParse::select_type {
%pythoncode %{
def __repr__(self):
return "<select %s: (%s)>" % (self.name(), " | ".join(map(repr, self.select_list())))
%}
}
%extend IfcParse::enumeration_type {
%pythoncode %{
def __repr__(self):
return "<enumeration %s: (%s)>" % (self.name(), ", ".join(self.enumeration_items()))
%}
2021-12-02 11:39:28 +01:00
std::vector<std::string> argument_types() {
std::vector<std::string> r;
r.push_back(IfcUtil::ArgumentTypeToString(IfcUtil::Argument_STRING));
return r;
}
}
%extend IfcParse::attribute {
%pythoncode %{
def __repr__(self):
return "<attribute %s%s: %s>" % (self.name(), "?" if self.optional() else "", self.type_of_attribute())
%}
}
%extend IfcParse::inverse_attribute {
std::string type_of_aggregation_string() const {
static const char* const aggr_strings[] = {"bag", "set", ""};
return aggr_strings[(int) $self->type_of_aggregation()];
}
%pythoncode %{
def __repr__(self):
format_bound = lambda i: "?" if i == -1 else str(i)
return "<inverse %s: %s [%s:%s] of %r for %r>" % (
self.name(),
self.type_of_aggregation_string(),
format_bound(self.bound1()),
format_bound(self.bound2()),
self.entity_reference(),
self.attribute_reference()
)
%}
}
%extend IfcParse::entity {
%pythoncode %{
def __repr__(self):
return "<entity %s>" % (self.name())
%}
2021-10-25 11:52:05 +02:00
std::vector<std::string> argument_types() {
size_t i = 0;
std::vector<std::string> r;
for (auto& attr : $self->all_attributes()) {
auto at = IfcUtil::Argument_UNKNOWN;
auto pt = attr->type_of_attribute();
if ($self->derived()[i++]) {
at = IfcUtil::Argument_DERIVED;
2021-12-02 11:05:36 +01:00
} else if (!pt) {
2021-10-25 11:52:05 +02:00
at = IfcUtil::Argument_UNKNOWN;
2021-12-02 11:05:36 +01:00
} else {
at = IfcUtil::from_parameter_type(pt);
2021-10-25 11:52:05 +02:00
}
2021-12-02 11:05:36 +01:00
r.push_back(IfcUtil::ArgumentTypeToString(at));
2021-10-25 11:52:05 +02:00
}
return r;
}
}
%extend IfcParse::schema_definition {
%pythoncode %{
def __repr__(self):
return "<schema %s>" % (self.name())
%}
}
2017-08-19 16:54:06 +02:00
%{
static std::stringstream ifcopenshell_log_stream;
%}
%init %{
Logger::SetOutput(0, &ifcopenshell_log_stream);
%}
%inline %{
std::string get_log() {
std::string log = ifcopenshell_log_stream.str();
ifcopenshell_log_stream.str("");
return log;
}
void turn_on_detailed_logging() {
Logger::SetOutput(&std::cout, &std::cout);
Logger::Verbosity(Logger::LOG_DEBUG);
}
void turn_off_detailed_logging() {
Logger::SetOutput(0, &ifcopenshell_log_stream);
Logger::Verbosity(Logger::LOG_WARNING);
}
2022-02-26 14:53:09 +01:00
void set_log_format_json() {
ifcopenshell_log_stream.str("");
Logger::OutputFormat(Logger::FMT_JSON);
}
void set_log_format_text() {
ifcopenshell_log_stream.str("");
Logger::OutputFormat(Logger::FMT_PLAIN);
}
2017-08-22 09:15:02 +01:00
%}
2021-01-10 12:36:47 +01:00
%{
PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v);
// @todo refactor this to remove duplication with the typemap.
// except this is calls the above function in case of instances.
PyObject* convert_cpp_attribute_to_python(IfcUtil::ArgumentType type, Argument& arg) {
if (!arg.isNull() && type != IfcUtil::Argument_DERIVED) {
try {
switch(type) {
case IfcUtil::Argument_INT: {
int v = arg;
return pythonize(v);
break; }
case IfcUtil::Argument_BOOL: {
bool v = arg;
return pythonize(v);
break; }
2022-01-17 11:19:30 +01:00
case IfcUtil::Argument_LOGICAL: {
boost::logic::tribool v = arg;
return pythonize(v);
break; }
2021-01-10 12:36:47 +01:00
case IfcUtil::Argument_DOUBLE: {
double v = arg;
return pythonize(v);
break; }
case IfcUtil::Argument_ENUMERATION:
case IfcUtil::Argument_STRING: {
std::string v = arg;
return pythonize(v);
break; }
case IfcUtil::Argument_BINARY: {
boost::dynamic_bitset<> v = arg;
return pythonize(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_INT: {
std::vector<int> v = arg;
return pythonize_vector(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: {
std::vector<double> v = arg;
return pythonize_vector(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_STRING: {
std::vector<std::string> v = arg;
return pythonize_vector(v);
break; }
case IfcUtil::Argument_ENTITY_INSTANCE: {
IfcUtil::IfcBaseClass* v = arg;
return get_info_cpp(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
2021-07-29 15:15:51 +02:00
aggregate_of_instance::ptr v = arg;
2021-01-10 12:36:47 +01:00
auto r = PyTuple_New(v->size());
for (unsigned i = 0; i < v->size(); ++i) {
PyTuple_SetItem(r, i, get_info_cpp((*v)[i]));
}
return r;
break; }
case IfcUtil::Argument_AGGREGATE_OF_BINARY: {
std::vector< boost::dynamic_bitset<> > v = arg;
return pythonize_vector(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: {
std::vector< std::vector<int> > v = arg;
return pythonize_vector2(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: {
std::vector< std::vector<double> > v = arg;
return pythonize_vector2(v);
break; }
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
2021-07-29 15:15:51 +02:00
aggregate_of_aggregate_of_instance::ptr vs = arg;
2021-01-10 12:36:47 +01:00
auto rs = PyTuple_New(vs->size());
for (auto it = vs->begin(); it != vs->end(); ++it) {
2021-07-29 15:15:51 +02:00
aggregate_of_instance::ptr v_i = arg;
2021-01-10 12:36:47 +01:00
auto r = PyTuple_New(v_i->size());
for (unsigned i = 0; i < v_i->size(); ++i) {
PyTuple_SetItem(r, i, get_info_cpp((*v_i)[i]));
}
PyTuple_SetItem(rs, std::distance(vs->begin(), it), r);
}
return rs;
break; }
case IfcUtil::Argument_EMPTY_AGGREGATE: {
return PyTuple_New(0);
break; }
}
} catch(...) {}
}
Py_INCREF(Py_None);
return Py_None;
}
%}
%inline %{
PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v) {
PyObject *d = PyDict_New();
2021-08-25 18:44:35 +02:00
if (v->declaration().as_entity()) {
const std::vector<const IfcParse::attribute*> attrs = v->declaration().as_entity()->all_attributes();
std::vector<const IfcParse::attribute*>::const_iterator it = attrs.begin();
auto dit = v->declaration().as_entity()->derived().begin();
for (; it != attrs.end(); ++it, ++dit) {
const std::string& name_cpp = (*it)->name();
auto name_py = pythonize(name_cpp);
auto attr_type = *dit
? IfcUtil::Argument_DERIVED
: IfcUtil::from_parameter_type((*it)->type_of_attribute());
auto value_cpp = v->data().getArgument(std::distance(attrs.begin(), it));
auto value_py = convert_cpp_attribute_to_python(attr_type, *value_cpp);
PyDict_SetItem(d, name_py, value_py);
2021-12-13 10:32:05 +01:00
Py_DECREF(name_py);
Py_DECREF(value_py);
2021-08-25 18:44:35 +02:00
}
const std::string& id_cpp = "id";
auto id_py = pythonize(id_cpp);
auto id_v_py = pythonize(v->data().id());
PyDict_SetItem(d, id_py, id_v_py);
2021-12-13 10:32:05 +01:00
Py_DECREF(id_py);
Py_DECREF(id_v_py);
2021-08-25 18:44:35 +02:00
} else {
const std::string& name_cpp = "wrappedValue";
2021-01-10 12:36:47 +01:00
auto name_py = pythonize(name_cpp);
2021-08-25 18:44:35 +02:00
auto value_cpp = v->data().getArgument(0);
auto value_py = convert_cpp_attribute_to_python(value_cpp->type(), *value_cpp);
2021-01-10 12:36:47 +01:00
PyDict_SetItem(d, name_py, value_py);
2021-12-13 10:32:05 +01:00
Py_DECREF(name_py);
Py_DECREF(value_py);
2021-01-10 12:36:47 +01:00
}
2021-08-25 18:44:35 +02:00
2021-01-10 12:36:47 +01:00
// @todo type and id can be static?
const std::string& type_cpp = "type";
auto type_py = pythonize(type_cpp);
const std::string& type_v_cpp = v->declaration().name();
auto type_v_py = pythonize(type_v_cpp);
PyDict_SetItem(d, type_py, type_v_py);
2021-12-13 10:32:05 +01:00
Py_DECREF(type_py);
Py_DECREF(type_v_py);
2021-01-10 12:36:47 +01:00
return d;
}
%}