Skip to content

Commit 10682fb

Browse files
committed
Fix python binding
1 parent df6b7a3 commit 10682fb

File tree

9 files changed

+89
-32
lines changed

9 files changed

+89
-32
lines changed

src/ifcparse/IfcEntityInstanceData.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ namespace {
7373
return array_.storage_ptr->index(index_);
7474
} else {
7575
std::string str;
76-
array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str);
76+
if (!array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str).ok()) {
77+
return TypeEncoder::encode_type<boost::blank>() - 'A';
78+
}
7779
return (size_t) str[0] - 'A';
7880
}
7981
}

src/ifcparse/IfcEntityInstanceData.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,54 @@ struct AttributeValue {
334334
unsigned int size() const;
335335

336336
IfcUtil::ArgumentType type() const;
337+
338+
template<typename Visitor>
339+
auto apply_visitor(Visitor&& visitor) const {
340+
switch (type()) {
341+
case IfcUtil::Argument_DERIVED:
342+
return visitor(Derived{});
343+
case IfcUtil::Argument_INT:
344+
return visitor((int)*this);
345+
case IfcUtil::Argument_BOOL:
346+
return visitor((bool)*this);
347+
case IfcUtil::Argument_LOGICAL: {
348+
boost::logic::tribool tb = *this;
349+
return visitor(tb);
350+
}
351+
case IfcUtil::Argument_DOUBLE:
352+
return visitor((double)*this);
353+
case IfcUtil::Argument_STRING:
354+
return visitor((std::string)*this);
355+
case IfcUtil::Argument_BINARY:
356+
return visitor((boost::dynamic_bitset<>)*this);
357+
case IfcUtil::Argument_ENUMERATION:
358+
return visitor((EnumerationReference)*this);
359+
case IfcUtil::Argument_ENTITY_INSTANCE:
360+
return visitor((IfcUtil::IfcBaseClass*)*this);
361+
case IfcUtil::Argument_AGGREGATE_OF_INT:
362+
return visitor((std::vector<int>)*this);
363+
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE:
364+
return visitor((std::vector<double>)*this);
365+
case IfcUtil::Argument_AGGREGATE_OF_STRING:
366+
return visitor((std::vector<std::string>)*this);
367+
case IfcUtil::Argument_AGGREGATE_OF_BINARY:
368+
return visitor((std::vector<boost::dynamic_bitset<>>)*this);
369+
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE:
370+
return visitor((boost::shared_ptr<aggregate_of_instance>)*this);
371+
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT:
372+
return visitor((std::vector<std::vector<int>>)*this);
373+
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE:
374+
return visitor((std::vector<std::vector<double>>)*this);
375+
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE:
376+
return visitor((boost::shared_ptr<aggregate_of_aggregate_of_instance>)*this);
377+
case IfcUtil::Argument_EMPTY_AGGREGATE:
378+
return visitor(empty_aggregate_t{});
379+
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE:
380+
return visitor(empty_aggregate_of_aggregate_t{});
381+
default:
382+
return visitor(Blank{});
383+
}
384+
}
337385
};
338386

339387
struct rocks_db_attribute_storage {

src/ifcparse/IfcFile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::rocksdb_instance_i
344344
}
345345
*/
346346

347-
const IfcParse::declaration* IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::operator*() const {
347+
IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::value_type const& IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::operator*() const {
348348
return storage_->file->schema()->declarations()[*read_id_()];
349349
}
350350

src/ifcparse/IfcFile.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ struct parse_context {
135135
#include <vector>
136136
#include <list>
137137

138+
#ifndef SWIG
139+
138140
template <typename... Iterators>
139141
class variant_iterator {
140142
public:
@@ -211,6 +213,8 @@ class variant_iterator {
211213
variant_type it_;
212214
};
213215

216+
#endif
217+
214218
namespace impl {
215219
struct in_memory_file_storage {
216220
IfcParse::IfcSpfLexer* tokens;
@@ -236,7 +240,7 @@ namespace impl {
236240
in_memory_file_storage(const in_memory_file_storage&) = delete;
237241
in_memory_file_storage(const in_memory_file_storage&&) = delete;
238242

239-
class type_iterator : private entities_by_type_t::const_iterator {
243+
class type_iterator : public entities_by_type_t::const_iterator {
240244
public:
241245
using iterator_category = std::forward_iterator_tag;
242246
using value_type = entities_by_type_t::key_type;
@@ -267,12 +271,6 @@ namespace impl {
267271
operator++();
268272
return tmp;
269273
}
270-
271-
bool operator!=(const type_iterator& other) const {
272-
const entities_by_type_t::const_iterator& self_ = *this;
273-
const entities_by_type_t::const_iterator& other_ = other;
274-
return self_ != other_;
275-
}
276274
};
277275

278276

@@ -547,7 +545,11 @@ namespace impl {
547545
return !(*this == other);
548546
}
549547

550-
const IfcParse::declaration* operator*() const;
548+
value_type const& operator*() const;
549+
550+
value_type const* operator->() const {
551+
return &operator*();
552+
}
551553
};
552554

553555
// @todo rocksdb_instance_iterator?

src/ifcparse/IfcParse.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,25 +2310,23 @@ IfcUtil::IfcBaseClass* IfcFile::instance_by_guid(const std::string& guid) {
23102310
IfcFile::type_iterator IfcFile::types_begin() const {
23112311
return std::visit([](const auto& x) {
23122312
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, std::monostate>) {
2313-
throw std::runtime_error("Storage not initialized");
2314-
return (IfcFile::type_iterator) impl::rocks_db_file_storage::rocksdb_types_iterator{};
2313+
return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} };
23152314
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::in_memory_file_storage>) {
2316-
return (IfcFile::type_iterator) x.bytype_excl_.begin();
2315+
return IfcFile::type_iterator{ x.bytype_excl_.begin() };
23172316
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
2318-
return (IfcFile::type_iterator) impl::rocks_db_file_storage::rocksdb_types_iterator(&x);
2317+
return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator(&x) };
23192318
}
23202319
}, storage_);
23212320
}
23222321

23232322
IfcFile::type_iterator IfcFile::types_end() const {
23242323
return std::visit([](const auto& x) {
23252324
if constexpr (std::is_same_v<std::decay_t<decltype(x)>, std::monostate>) {
2326-
throw std::runtime_error("Storage not initialized");
2327-
return (IfcFile::type_iterator)impl::rocks_db_file_storage::rocksdb_types_iterator{};
2325+
return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} };
23282326
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::in_memory_file_storage>) {
2329-
return (IfcFile::type_iterator)x.bytype_excl_.end();
2327+
return IfcFile::type_iterator{ x.bytype_excl_.end() };
23302328
} else if constexpr (std::is_same_v<std::decay_t<decltype(x)>, impl::rocks_db_file_storage>) {
2331-
return (IfcFile::type_iterator)impl::rocks_db_file_storage::rocksdb_types_iterator{};
2329+
return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} };
23322330
}
23332331
}, storage_);
23342332
}

src/ifcwrap/IfcParseWrapper.i

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ private:
2929
%ignore IfcParse::IfcFile::schema;
3030
%ignore IfcParse::IfcFile::begin;
3131
%ignore IfcParse::IfcFile::end;
32+
%ignore IfcParse::IfcFile::types_begin;
33+
%ignore IfcParse::IfcFile::types_end;
34+
%ignore IfcParse::IfcFile::internal_guid_map;
35+
%ignore IfcParse::IfcFile::storage_;
36+
37+
%ignore in_memory_file_storage;
38+
%ignore rocks_db_file_storage;
3239

3340
%ignore parse_context;
3441

@@ -154,7 +161,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
154161
std::vector<unsigned> entity_names() const {
155162
std::vector<unsigned> keys;
156163
keys.reserve(std::distance($self->begin(), $self->end()));
157-
for (IfcParse::IfcFile::entity_by_id_t::const_iterator it = $self->begin(); it != $self->end(); ++ it) {
164+
for (auto it = $self->begin(); it != $self->end(); ++ it) {
158165
keys.push_back(it->first);
159166
}
160167
return keys;
@@ -286,15 +293,15 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
286293
}
287294

288295
AttributeValue get_argument(unsigned i) {
289-
return $self->data().get_attribute_value(i);
296+
return $self->get_attribute_value(i);
290297
}
291298

292299
AttributeValue get_argument(const std::string& a) {
293300
auto i = $self->declaration().as_entity()->attribute_index(a);
294301
if (i == -1) {
295302
throw std::runtime_error("Attribute '" + a + "' not found on entity named " + $self->declaration().name());
296303
}
297-
return $self->data().get_attribute_value((unsigned)i);
304+
return $self->get_attribute_value((unsigned)i);
298305
}
299306

300307
bool __eq__(IfcUtil::IfcBaseClass* other) const {
@@ -595,7 +602,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
595602
IfcUtil::IfcBaseClass* new_IfcBaseClass(const std::string& schema_identifier, const std::string& name) {
596603
const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier);
597604
const IfcParse::declaration* decl = schema->declaration_by_name(name);
598-
IfcEntityInstanceData data(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1));
605+
IfcEntityInstanceData data(in_memory_attribute_storage(decl->as_entity() ? decl->as_entity()->attribute_count() : 1));
599606
auto inst = schema->instantiate(decl, std::move(data));
600607
if (auto entinst = inst->as<IfcUtil::IfcBaseEntity>()) {
601608
entinst->populate_derived();
@@ -763,8 +770,8 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
763770

764771
// @todo refactor this to remove duplication with the typemap.
765772
// except this is calls the above function in case of instances.
766-
PyObject* convert_cpp_attribute_to_python(AttributeValue arg, bool include_identifier = true) {
767-
return arg.array_->apply_visitor([include_identifier](auto& v){
773+
PyObject* convert_cpp_attribute_to_python(IfcUtil::IfcBaseClass* instance, size_t attribute_index, bool include_identifier = true) {
774+
return instance->get_attribute_value(attribute_index).apply_visitor([include_identifier](const auto& v){
768775
using U = std::decay_t<decltype(v)>;
769776
if constexpr (is_std_vector_v<U>) {
770777
return pythonize_vector(v);
@@ -802,7 +809,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
802809
} else {
803810
return pythonize(v);
804811
}
805-
}, arg.index_);
812+
});
806813
}
807814
%}
808815
%inline %{
@@ -819,7 +826,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
819826
auto attr_type = *dit
820827
? IfcUtil::Argument_DERIVED
821828
: IfcUtil::from_parameter_type((*it)->type_of_attribute());
822-
auto value_cpp = v->data().get_attribute_value(std::distance(attrs.begin(), it));
829+
auto value_cpp = v->get_attribute_value(std::distance(attrs.begin(), it));
823830
auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier);
824831
PyDict_SetItem(d, name_py, value_py);
825832
Py_DECREF(name_py);
@@ -836,7 +843,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
836843
} else {
837844
const std::string& name_cpp = "wrappedValue";
838845
auto name_py = pythonize(name_cpp);
839-
auto value_cpp = v->data().get_attribute_value(0);
846+
auto value_cpp = v->get_attribute_value(0);
840847
auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier);
841848
PyDict_SetItem(d, name_py, value_py);
842849
Py_DECREF(name_py);

src/ifcwrap/utils/typemaps_out.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
// of our typemap. So the attribute conversion block
3737
// is wrapped in a try-catch block manually.
3838
try {
39-
$result = $1.array_->apply_visitor([](auto& v){
39+
$result = $1.apply_visitor([](const auto& v){
4040
using U = std::decay_t<decltype(v)>;
4141
if constexpr (is_std_vector_v<U>) {
4242
return pythonize_vector(v);
@@ -58,7 +58,7 @@
5858
} else {
5959
return pythonize(v);
6060
}
61-
}, $1.index_);
61+
});
6262
} catch(IfcParse::IfcException& e) {
6363
SWIG_exception(SWIG_RuntimeError, e.what());
6464
} catch(...) {

src/serializers/RocksDbSerializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string&
1414
options.create_if_missing = true;
1515
options.merge_operator.reset(new ConcatenateIdMergeOperator());
1616
rocksdb::Status status = rocksdb::DB::Open(options, rocksdb_filename, &db_);*/
17-
output_file_ = new IfcParse::IfcFile(file_->schema(), IfcParse::rocksdb, rocksdb_filename_);
17+
output_file_ = new IfcParse::IfcFile(file_->schema(), IfcParse::FT_ROCKSDB, rocksdb_filename_);
1818
}
1919

2020
void RocksDbSerializer::finalize()

win/build-deps.cmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,12 @@ IF EXIST "%INSTALL_DIR%\swigwin" (
516516
goto :cgal
517517
)
518518

519-
set SWIG_VERSION=3.0.12
519+
set SWIG_VERSION=4.3.0
520520
set DEPENDENCY_NAME=SWIG %SWIG_VERSION%
521521
set DEPENDENCY_DIR=N/A
522522
set SWIG_ZIP=swigwin-%SWIG_VERSION%.zip
523523
cd "%DEPS_DIR%"
524-
call :DownloadFile https://github.com/aothms/swigwin-3.0.12/raw/refs/heads/main/swigwin-3.0.12.zip "%DEPS_DIR%" %SWIG_ZIP%
524+
call :DownloadFile https://sourceforge.net/projects/swig/files/swigwin/swigwin-%SWIG_VERSION%/%SWIG_ZIP% "%DEPS_DIR%" %SWIG_ZIP%
525525
IF NOT %ERRORLEVEL%==0 GOTO :Error
526526
call :ExtractArchive %SWIG_ZIP% "%DEPS_DIR%" "%DEPS_DIR%\swigwin"
527527
IF NOT %ERRORLEVEL%==0 GOTO :Error

0 commit comments

Comments
 (0)