Work on python wrapper

This commit is contained in:
Thomas Krijnen
2017-12-31 12:20:13 +01:00
parent 05e6f56911
commit e2f79ec1ba
12 changed files with 94 additions and 72 deletions
+1 -12
View File
@@ -51,19 +51,8 @@ script:
- cd cmake - cd cmake
- mkdir build-ifc2x3 build-ifc4 - mkdir build-ifc2x3 build-ifc4
- cd build-ifc2x3 - cd build-ifc2x3
- cmake -DCOLLADA_SUPPORT=True -DOPENCOLLADA_INCLUDE_DIR=/usr/local/include/opencollada -DOPENCOLLADA_LIBRARY_DIR=/usr/local/lib/opencollada -DPCRE_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DUSE_IFC4=False -DBUILD_IFCPYTHON=True -DUNICODE_SUPPORT=True -DOCC_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DPYTHON_LIBRARY=/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_EXECUTABLE=/usr/bin/python2.7 .. - cmake -DCOLLADA_SUPPORT=True -DOPENCOLLADA_INCLUDE_DIR=/usr/local/include/opencollada -DOPENCOLLADA_LIBRARY_DIR=/usr/local/lib/opencollada -DPCRE_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DBUILD_EXAMPLES=Off -DBUILD_IFCPYTHON=True -DUNICODE_SUPPORT=True -DOCC_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DPYTHON_LIBRARY=/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_EXECUTABLE=/usr/bin/python2.7 ..
- make -j - make -j
- sudo make install - sudo make install
- ./examples/IfcOpenHouse
- ./examples/IfcAdvancedHouse
- test -f IfcOpenHouse.ifc
- test -f IfcAdvancedHouse.ifc
- cd ../../test - cd ../../test
- /usr/bin/python2.7 tests.py - /usr/bin/python2.7 tests.py
- cd ../cmake/build-ifc4
- cmake -DCOLLADA_SUPPORT=True -DOPENCOLLADA_INCLUDE_DIR=/usr/local/include/opencollada -DOPENCOLLADA_LIBRARY_DIR=/usr/local/lib/opencollada -DPCRE_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DUSE_IFC4=True -DBUILD_IFCPYTHON=True -DUNICODE_SUPPORT=True -DOCC_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu -DPYTHON_LIBRARY=/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_EXECUTABLE=/usr/bin/python2.7 ..
- make -j
- ./examples/IfcOpenHouse
- ./examples/IfcAdvancedHouse
- test -f IfcOpenHouse.ifc
- test -f IfcAdvancedHouse.ifc
-9
View File
@@ -25,7 +25,6 @@ OPTION(UNICODE_SUPPORT "Build IfcOpenShell with Unicode support (requires ICU)."
OPTION(COLLADA_SUPPORT "Build IfcConvert with COLLADA support (requires OpenCOLLADA)." ON) OPTION(COLLADA_SUPPORT "Build IfcConvert with COLLADA support (requires OpenCOLLADA)." ON)
OPTION(ENABLE_BUILD_OPTIMIZATIONS "Enable certain compiler and linker optimizations on RelWithDebInfo and Release builds." OFF) OPTION(ENABLE_BUILD_OPTIMIZATIONS "Enable certain compiler and linker optimizations on RelWithDebInfo and Release builds." OFF)
OPTION(IFCCONVERT_DOUBLE_PRECISION "IfcConvert: Use double precision floating-point numbers." ON) OPTION(IFCCONVERT_DOUBLE_PRECISION "IfcConvert: Use double precision floating-point numbers." ON)
OPTION(USE_IFC4 "Use IFC 4 instead of IFC 2x3 (full rebuild recommended when switching this)" OFF)
OPTION(BUILD_IFCPYTHON "Build IfcPython." ON) OPTION(BUILD_IFCPYTHON "Build IfcPython." ON)
OPTION(BUILD_EXAMPLES "Build example applications." ON) OPTION(BUILD_EXAMPLES "Build example applications." ON)
OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only." OFF) OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only." OFF)
@@ -488,14 +487,6 @@ if(COMPILE_SCHEMA)
list(REMOVE_ITEM IFC_RELEASE_NOT_USED "4") list(REMOVE_ITEM IFC_RELEASE_NOT_USED "4")
add_definitions(-DUSE_IFC4) add_definitions(-DUSE_IFC4)
endif() endif()
else()
if(USE_IFC4)
add_definitions(-DUSE_IFC4)
set(IFC_RELEASE_NOT_USED "2x3")
else()
add_definitions(-DUSE_IFC2x3) # TODO Make all caps? i.e. USE_IFC2X3
set(IFC_RELEASE_NOT_USED "4")
endif()
endif() endif()
# Boost >= 1.58 requires BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE to build on some Linux distros. # Boost >= 1.58 requires BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE to build on some Linux distros.
@@ -59,8 +59,8 @@ from .file import file
from .entity_instance import entity_instance from .entity_instance import entity_instance
def open(fn=None): def open(fn):
return file(ifcopenshell_wrapper.open(os.path.abspath(fn))) if fn else file() return file(ifcopenshell_wrapper.open(os.path.abspath(fn)))
def create_entity(type, *args, **kwargs): def create_entity(type, *args, **kwargs):
@@ -51,8 +51,8 @@ class entity_instance(object):
>>> #423=IfcProductDefinitionShape($,$,(#409,#421)) >>> #423=IfcProductDefinitionShape($,$,(#409,#421))
""" """
def __init__(self, e): def __init__(self, e):
if isinstance(e, str): if isinstance(e, tuple):
e = ifcopenshell_wrapper.new_IfcBaseClass(e) e = ifcopenshell_wrapper.new_IfcBaseClass(*e)
super(entity_instance, self).__setattr__('wrapped_data', e) super(entity_instance, self).__setattr__('wrapped_data', e)
def __getattr__(self, name): def __getattr__(self, name):
+8 -3
View File
@@ -55,11 +55,16 @@ class file(object):
print(products[0] == ifc_file[122] == ifc_file['2XQ$n5SLP5MBLyL442paFx']) print(products[0] == ifc_file[122] == ifc_file['2XQ$n5SLP5MBLyL442paFx'])
>>> True >>> True
""" """
def __init__(self, f=None): def __init__(self, f=None, schema=None):
self.wrapped_data = f or ifcopenshell_wrapper.file() if f is not None:
self.wrapped_data = f
else:
args = filter(None, [schema])
args = map(ifcopenshell_wrapper.schema_by_name, args)
self.wrapped_data = ifcopenshell_wrapper.file(*args)
def create_entity(self, type, *args, **kwargs): def create_entity(self, type, *args, **kwargs):
e = entity_instance(type) e = entity_instance((self.schema, type))
self.wrapped_data.add(e.wrapped_data) self.wrapped_data.add(e.wrapped_data)
e.wrapped_data.this.disown() e.wrapped_data.this.disown()
attrs = list(enumerate(args)) + \ attrs = list(enumerate(args)) + \
@@ -24,6 +24,4 @@ from __future__ import print_function
from . import ifcopenshell_wrapper from . import ifcopenshell_wrapper
version = ifcopenshell_wrapper.version() version = ifcopenshell_wrapper.version()
schema_identifier = ifcopenshell_wrapper.schema_identifier()
get_supertype = ifcopenshell_wrapper.get_supertype
get_log = ifcopenshell_wrapper.get_log get_log = ifcopenshell_wrapper.get_log
+32 -23
View File
@@ -1249,6 +1249,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
MaxId = 0; MaxId = 0;
tokens = 0; tokens = 0;
stream = 0; stream = 0;
schema_ = 0;
setDefaultHeaderValues(); setDefaultHeaderValues();
@@ -1270,8 +1271,6 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
// Purposely empty catch block // Purposely empty catch block
} }
schema_ = 0;
if (schemas.size() == 1) { if (schemas.size() == 1) {
try { try {
schema_ = IfcParse::schema_by_name(schemas.front()); schema_ = IfcParse::schema_by_name(schemas.front());
@@ -1493,13 +1492,21 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
// information needs to be accounted for for IfcLengthMeasures. // information needs to be accounted for for IfcLengthMeasures.
double conversion_factor = std::numeric_limits<double>::quiet_NaN(); double conversion_factor = std::numeric_limits<double>::quiet_NaN();
std::vector<const IfcParse::entity::attribute*> attribute_types = entity->declaration().as_entity()->all_attributes();
for (unsigned i = 0; i < we->getArgumentCount(); ++i) { for (unsigned i = 0; i < we->getArgumentCount(); ++i) {
Argument* attr = we->getArgument(i); Argument* attr = we->getArgument(i);
IfcUtil::ArgumentType attr_type = attr->type(); IfcUtil::ArgumentType attr_type = attr->type();
IfcParse::declaration* decl = attribute_types[i]->type_of_attribute()->as_named_type()->declared_type(); IfcParse::declaration* decl = 0;
if (entity->declaration().as_entity()) {
decl = 0;
const parameter_type* pt = entity->declaration().as_entity()->attribute_by_index(i)->type_of_attribute();
while (pt->as_aggregation_type()) {
pt = pt->as_aggregation_type()->type_of_element();
}
if (pt->as_named_type()) {
decl = pt->as_named_type()->declared_type();
}
}
if (attr_type == IfcUtil::Argument_ENTITY_INSTANCE) { if (attr_type == IfcUtil::Argument_ENTITY_INSTANCE) {
entity_entity_map_t::const_iterator eit = entity_file_map.find(*attr); entity_entity_map_t::const_iterator eit = entity_file_map.find(*attr);
@@ -1595,7 +1602,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
// The mapping by entity type is updated. // The mapping by entity type is updated.
const IfcParse::declaration* ty = &new_entity->declaration(); const IfcParse::declaration* ty = &new_entity->declaration();
{ if (ty->as_entity()) {
IfcEntityList::ptr insts = instances_by_type_excl_subtypes(ty); IfcEntityList::ptr insts = instances_by_type_excl_subtypes(ty);
if (!insts) { if (!insts) {
insts = IfcEntityList::ptr(new IfcEntityList()); insts = IfcEntityList::ptr(new IfcEntityList());
@@ -1604,7 +1611,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
insts->push(new_entity); insts->push(new_entity);
} }
for (;;) { for (; ty->as_entity();) {
IfcEntityList::ptr insts = instances_by_type(ty); IfcEntityList::ptr insts = instances_by_type(ty);
if (!insts) { if (!insts) {
insts = IfcEntityList::ptr(new IfcEntityList()); insts = IfcEntityList::ptr(new IfcEntityList());
@@ -1620,7 +1627,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
} }
} }
if (new_entity->declaration().as_entity()) { if (ty->as_entity()) {
int new_id = -1; int new_id = -1;
if (!new_entity->data().file) { if (!new_entity->data().file) {
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set // For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
@@ -1641,25 +1648,27 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
byid[new_id] = new_entity; byid[new_id] = new_entity;
} }
// The mapping by reference is updated. if (ty->as_entity()) {
IfcEntityList::ptr entity_attributes(new IfcEntityList); // The mapping by reference is updated.
try { IfcEntityList::ptr entity_attributes(new IfcEntityList);
entity_attributes = traverse(new_entity, 1);
} catch (const std::exception& e) {
Logger::Error(e);
}
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
if (*it == new_entity) continue;
try { try {
if (entity_attribute->declaration().as_entity()) { entity_attributes = traverse(new_entity, 1);
unsigned entity_attribute_id = entity_attribute->data().id();
byref[entity_attribute_id].push_back(new_entity->data().id());
}
} catch (const std::exception& e) { } catch (const std::exception& e) {
Logger::Error(e); Logger::Error(e);
} }
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
if (*it == new_entity) continue;
try {
if (entity_attribute->declaration().as_entity()) {
unsigned entity_attribute_id = entity_attribute->data().id();
byref[entity_attribute_id].push_back(new_entity->data().id());
}
} catch (const std::exception& e) {
Logger::Error(e);
}
}
} }
return new_entity; return new_entity;
+1 -1
View File
@@ -3,7 +3,7 @@
#include <map> #include <map>
bool IfcParse::declaration::is(const std::string& name) const { bool IfcParse::declaration::is(const std::string& name) const {
if (name_ == name) return true; if (name_lower_ == boost::to_lower_copy(name)) return true;
if (this->as_entity()) { if (this->as_entity()) {
return this->as_entity()->is(name); return this->as_entity()->is(name);
+2 -2
View File
@@ -268,11 +268,11 @@ namespace IfcParse {
} }
if (attr == 0) { if (attr == 0) {
if (index < attributes_.size()) { if (index < attributes_.size()) {
return attributes_[index]; attr = attributes_[index];
} }
index -= attributes_.size(); index -= attributes_.size();
} }
return 0; return attr;
} }
public: public:
+43 -14
View File
@@ -24,10 +24,9 @@ private:
IfcEntityInstanceData(); IfcEntityInstanceData();
}; };
%ignore IfcParse::IfcFile::Init;
%ignore IfcParse::IfcFile::entityByGuid;
%ignore IfcParse::IfcFile::register_inverse; %ignore IfcParse::IfcFile::register_inverse;
%ignore IfcParse::IfcFile::unregister_inverse; %ignore IfcParse::IfcFile::unregister_inverse;
%ignore IfcParse::IfcFile::schema;
%ignore operator<<; %ignore operator<<;
%ignore IfcParse::FileDescription::FileDescription; %ignore IfcParse::FileDescription::FileDescription;
@@ -44,15 +43,8 @@ private:
%ignore IfcUtil::IfcBaseClass::is; %ignore IfcUtil::IfcBaseClass::is;
%rename("by_id") entityById; %rename("by_id") instance_by_id;
%rename("by_type") entitiesByType; %rename("by_type") instances_by_type;
%rename("__len__") getArgumentCount;
%rename("get_argument_type") getArgumentType;
%rename("get_argument_name") getArgumentName;
%rename("get_argument_index") getArgumentIndex;
%rename("get_argument_optionality") getArgumentOptionality;
%rename("get_attribute_names") getAttributeNames;
%rename("get_inverse_attribute_names") getInverseAttributeNames;
%rename("entity_instance") IfcBaseClass; %rename("entity_instance") IfcBaseClass;
%rename("file") IfcFile; %rename("file") IfcFile;
%rename("add") addEntity; %rename("add") addEntity;
@@ -102,10 +94,16 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
return ts; return ts;
} }
std::string schema_name() const {
if ($self->schema() == 0) return "";
return $self->schema()->name();
}
%pythoncode %{ %pythoncode %{
if _newclass: if _newclass:
# Hide the getters with read-only property implementations # Hide the getters with read-only property implementations
header = property(header) header = property(header)
schema = property(schema_name)
%} %}
} }
@@ -146,7 +144,15 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
return $self->data().id(); return $self->data().id();
} }
std::vector<std::string> getAttributeNames() const { 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 {
if (!$self->declaration().as_entity()) { if (!$self->declaration().as_entity()) {
return std::vector<std::string>(1, "wrappedValue"); return std::vector<std::string>(1, "wrappedValue");
} }
@@ -164,7 +170,7 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
return attr_names; return attr_names;
} }
std::vector<std::string> getInverseAttributeNames() const { std::vector<std::string> get_inverse_attribute_names() const {
if (!$self->declaration().as_entity()) { if (!$self->declaration().as_entity()) {
return std::vector<std::string>(0); return std::vector<std::string>(0);
} }
@@ -223,7 +229,13 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
} }
unsigned get_argument_index(const std::string& a) const { unsigned get_argument_index(const std::string& a) const {
return $self->declaration().as_entity()->attribute_index(a); 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());
}
} }
IfcEntityList::ptr get_inverse(const std::string& a) { IfcEntityList::ptr get_inverse(const std::string& a) {
@@ -239,6 +251,22 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
throw IfcParse::IfcException(a + " not found on " + $self->declaration().name()); throw IfcParse::IfcException(a + " not found on " + $self->declaration().name());
} }
const char* const get_argument_type(unsigned int i) const {
IfcUtil::ArgumentType arg_type = IfcUtil::from_parameter_type($self->declaration().as_entity()->attribute_by_index(i)->type_of_attribute());
return IfcUtil::ArgumentTypeToString(arg_type);
}
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());
}
}
void setArgumentAsNull(unsigned int i) { void setArgumentAsNull(unsigned int i) {
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional(); bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
if (is_optional) { if (is_optional) {
@@ -488,6 +516,7 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
%include "../ifcparse/IfcSpfHeader.h" %include "../ifcparse/IfcSpfHeader.h"
%include "../ifcparse/IfcFile.h" %include "../ifcparse/IfcFile.h"
%include "../ifcparse/IfcBaseClass.h" %include "../ifcparse/IfcBaseClass.h"
%include "../ifcparse/IfcSchema.h"
// The IfcFile* returned by open() is to be freed by SWIG/Python // The IfcFile* returned by open() is to be freed by SWIG/Python
%newobject open; %newobject open;
+1
View File
@@ -78,6 +78,7 @@
#include "../ifcparse/Ifc4.h" #include "../ifcparse/Ifc4.h"
#include "../ifcparse/IfcBaseClass.h" #include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/IfcFile.h" #include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSchema.h"
#include <BRepTools_ShapeSet.hxx> #include <BRepTools_ShapeSet.hxx>
%} %}
+2 -2
View File
@@ -49,7 +49,7 @@ assert prop.NominalValue.wrappedValue in str(prop)
# An instance added to a new file yields the same string # An instance added to a new file yields the same string
# representation, except for any instance name identifiers. # representation, except for any instance name identifiers.
f2 = ifcopenshell.open() f2 = ifcopenshell.file(schema=f.schema)
prop2 = f2.add(prop) prop2 = f2.add(prop)
assert str(prop) == str(prop2).replace(str(prop2.id()), str(prop.id())) assert str(prop) == str(prop2).replace(str(prop2.id()), str(prop.id()))
assert prop2.id() == 1 assert prop2.id() == 1
@@ -61,7 +61,7 @@ assert f2.add(app).get_info(False, True) == app.get_info(False, True)
assert "Version" in dir(app) assert "Version" in dir(app)
# Enumeration of entity type names # Enumeration of entity type names
g = ifcopenshell.open() g = ifcopenshell.file(schema=f.schema)
p = g.createIfcCartesianPoint((0.,0.)) p = g.createIfcCartesianPoint((0.,0.))
assert len(g.types()) == 1 assert len(g.types()) == 1
assert "IfcPoint" in g.types_with_super() assert "IfcPoint" in g.types_with_super()