mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Work on python wrapper
This commit is contained in:
+1
-12
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
+32
-23
@@ -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,25 +1648,27 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
||||
byid[new_id] = new_entity;
|
||||
}
|
||||
|
||||
// The mapping by reference is updated.
|
||||
IfcEntityList::ptr entity_attributes(new IfcEntityList);
|
||||
try {
|
||||
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;
|
||||
if (ty->as_entity()) {
|
||||
// The mapping by reference is updated.
|
||||
IfcEntityList::ptr entity_attributes(new IfcEntityList);
|
||||
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());
|
||||
}
|
||||
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 {
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
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) {
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user