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
- mkdir build-ifc2x3 build-ifc4
- 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
- sudo make install
- ./examples/IfcOpenHouse
- ./examples/IfcAdvancedHouse
- test -f IfcOpenHouse.ifc
- test -f IfcAdvancedHouse.ifc
- cd ../../test
- /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(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(USE_IFC4 "Use IFC 4 instead of IFC 2x3 (full rebuild recommended when switching this)" OFF)
OPTION(BUILD_IFCPYTHON "Build IfcPython." ON)
OPTION(BUILD_EXAMPLES "Build example applications." ON)
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")
add_definitions(-DUSE_IFC4)
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()
# 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
def open(fn=None):
return file(ifcopenshell_wrapper.open(os.path.abspath(fn))) if fn else file()
def open(fn):
return file(ifcopenshell_wrapper.open(os.path.abspath(fn)))
def create_entity(type, *args, **kwargs):
@@ -51,8 +51,8 @@ class entity_instance(object):
>>> #423=IfcProductDefinitionShape($,$,(#409,#421))
"""
def __init__(self, e):
if isinstance(e, str):
e = ifcopenshell_wrapper.new_IfcBaseClass(e)
if isinstance(e, tuple):
e = ifcopenshell_wrapper.new_IfcBaseClass(*e)
super(entity_instance, self).__setattr__('wrapped_data', e)
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'])
>>> True
"""
def __init__(self, f=None):
self.wrapped_data = f or ifcopenshell_wrapper.file()
def __init__(self, f=None, schema=None):
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):
e = entity_instance(type)
e = entity_instance((self.schema, type))
self.wrapped_data.add(e.wrapped_data)
e.wrapped_data.this.disown()
attrs = list(enumerate(args)) + \
@@ -24,6 +24,4 @@ from __future__ import print_function
from . import ifcopenshell_wrapper
version = ifcopenshell_wrapper.version()
schema_identifier = ifcopenshell_wrapper.schema_identifier()
get_supertype = ifcopenshell_wrapper.get_supertype
get_log = ifcopenshell_wrapper.get_log
+17 -8
View File
@@ -1249,6 +1249,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
MaxId = 0;
tokens = 0;
stream = 0;
schema_ = 0;
setDefaultHeaderValues();
@@ -1270,8 +1271,6 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
// Purposely empty catch block
}
schema_ = 0;
if (schemas.size() == 1) {
try {
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.
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) {
Argument* attr = we->getArgument(i);
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) {
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.
const IfcParse::declaration* ty = &new_entity->declaration();
{
if (ty->as_entity()) {
IfcEntityList::ptr insts = instances_by_type_excl_subtypes(ty);
if (!insts) {
insts = IfcEntityList::ptr(new IfcEntityList());
@@ -1604,7 +1611,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
insts->push(new_entity);
}
for (;;) {
for (; ty->as_entity();) {
IfcEntityList::ptr insts = instances_by_type(ty);
if (!insts) {
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;
if (!new_entity->data().file) {
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
@@ -1641,6 +1648,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
byid[new_id] = new_entity;
}
if (ty->as_entity()) {
// The mapping by reference is updated.
IfcEntityList::ptr entity_attributes(new IfcEntityList);
try {
@@ -1661,6 +1669,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
Logger::Error(e);
}
}
}
return new_entity;
}
+1 -1
View File
@@ -3,7 +3,7 @@
#include <map>
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()) {
return this->as_entity()->is(name);
+2 -2
View File
@@ -268,11 +268,11 @@ namespace IfcParse {
}
if (attr == 0) {
if (index < attributes_.size()) {
return attributes_[index];
attr = attributes_[index];
}
index -= attributes_.size();
}
return 0;
return attr;
}
public:
+42 -13
View File
@@ -24,10 +24,9 @@ private:
IfcEntityInstanceData();
};
%ignore IfcParse::IfcFile::Init;
%ignore IfcParse::IfcFile::entityByGuid;
%ignore IfcParse::IfcFile::register_inverse;
%ignore IfcParse::IfcFile::unregister_inverse;
%ignore IfcParse::IfcFile::schema;
%ignore operator<<;
%ignore IfcParse::FileDescription::FileDescription;
@@ -44,15 +43,8 @@ private:
%ignore IfcUtil::IfcBaseClass::is;
%rename("by_id") entityById;
%rename("by_type") entitiesByType;
%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("by_id") instance_by_id;
%rename("by_type") instances_by_type;
%rename("entity_instance") IfcBaseClass;
%rename("file") IfcFile;
%rename("add") addEntity;
@@ -102,10 +94,16 @@ static const std::string& helper_fn_declaration_get_name(const IfcParse::declara
return ts;
}
std::string schema_name() const {
if ($self->schema() == 0) return "";
return $self->schema()->name();
}
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
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();
}
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()) {
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;
}
std::vector<std::string> getInverseAttributeNames() const {
std::vector<std::string> get_inverse_attribute_names() const {
if (!$self->declaration().as_entity()) {
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 {
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) {
@@ -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());
}
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) {
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->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/IfcFile.h"
%include "../ifcparse/IfcBaseClass.h"
%include "../ifcparse/IfcSchema.h"
// The IfcFile* returned by open() is to be freed by SWIG/Python
%newobject open;
+1
View File
@@ -78,6 +78,7 @@
#include "../ifcparse/Ifc4.h"
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSchema.h"
#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
# representation, except for any instance name identifiers.
f2 = ifcopenshell.open()
f2 = ifcopenshell.file(schema=f.schema)
prop2 = f2.add(prop)
assert str(prop) == str(prop2).replace(str(prop2.id()), str(prop.id()))
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)
# Enumeration of entity type names
g = ifcopenshell.open()
g = ifcopenshell.file(schema=f.schema)
p = g.createIfcCartesianPoint((0.,0.))
assert len(g.types()) == 1
assert "IfcPoint" in g.types_with_super()