Merge pull request #31 from aothms/cmake_compile_schema

Add option to compile (external) schema by cmake + general improvements
This commit is contained in:
Thomas Krijnen
2016-02-18 15:43:52 +01:00
20 changed files with 264 additions and 105 deletions
+2
View File
@@ -184,4 +184,6 @@ enum_header.EnumHeader(mapping).emit()
implementation.Implementation(mapping).emit()
latebound_header.LateBoundHeader(mapping).emit()
latebound_implementation.LateBoundImplementation(mapping).emit()
sys.stdout.write(schema.name)
"""%('\n'.join(statements)))
+34
View File
@@ -0,0 +1,34 @@
###############################################################################
# #
# 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 #
# 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 #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
class Base(object):
"""
A base class for all code generation classes. Currently only working around
some python 2/3 incompatibilities in terms of unicode file handling.
"""
def emit(self):
import platform
if tuple(map(int, platform.python_version_tuple())) < (2, 8):
from io import open as unicode_open
else:
unicode_open = open
unicode = lambda x, *args, **kwargs: x
f = unicode_open(self.file_name, 'w', encoding='utf-8')
f.write(unicode(repr(self), encoding='utf-8', errors='ignore'))
f.close()
+8 -3
View File
@@ -27,11 +27,15 @@
# #
###############################################################################
import re,csv
import re
import os
import csv
try: from html.entities import entitydefs
except: from htmlentitydefs import entitydefs
make_absolute = lambda fn: os.path.join(os.path.dirname(os.path.realpath(__file__)), fn)
name_to_oid = {}
oid_to_desc = {}
oid_to_name = {}
@@ -39,6 +43,7 @@ oid_to_pid = {}
regices = list(zip([re.compile(s,re.M) for s in [r'<[\w\n=" \-/\.;_\t:%#,\?\(\)]+>',r'(\n[\t ]*){2,}',r'^[\t ]+']],['','\n\n',' ']))
definition_files = ['DocEntity.csv', 'DocEnumeration.csv', 'DocDefined.csv', 'DocSelect.csv']
definition_files = map(make_absolute, definition_files)
for fn in definition_files:
with open(fn) as f:
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
@@ -46,11 +51,11 @@ for fn in definition_files:
oid_to_name[oid] = name
oid_to_desc[oid] = desc
with open('DocEntityAttributes.csv') as f:
with open(make_absolute('DocEntityAttributes.csv')) as f:
for pid, x, oid in csv.reader(f, delimiter=';', quotechar='"'):
oid_to_pid[oid] = pid
with open('DocAttribute.csv') as f:
with open(make_absolute('DocAttribute.csv')) as f:
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
pid = oid_to_pid[oid]
pname = oid_to_name[pid]
+6 -5
View File
@@ -18,8 +18,9 @@
###############################################################################
import templates
import codegen
class EnumHeader:
class EnumHeader(codegen.Base):
def __init__(self, mapping):
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
@@ -30,9 +31,9 @@ class EnumHeader:
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%senum.h'%self.schema_name
def __repr__(self):
return self.str
def emit(self):
f = open('%senum.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+6 -6
View File
@@ -17,10 +17,11 @@
# #
###############################################################################
import codegen
import templates
import documentation
class Header:
class Header(codegen.Base):
def __init__(self, mapping):
declarations = []
@@ -123,10 +124,9 @@ class Header:
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%s.h'%self.schema_name
def __repr__(self):
return self.str
def emit(self):
f = open('%s.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+6 -6
View File
@@ -17,9 +17,10 @@
# #
###############################################################################
import codegen
import templates
class Implementation:
class Implementation(codegen.Base):
def __init__(self, mapping):
enumeration_functions = []
entity_implementations = []
@@ -230,10 +231,9 @@ class Implementation:
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%s.cpp'%self.schema_name
def __repr__(self):
return self.str
def emit(self):
f = open('%s.cpp'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+6 -5
View File
@@ -17,9 +17,10 @@
# #
###############################################################################
import codegen
import templates
class LateBoundHeader:
class LateBoundHeader(codegen.Base):
def __init__(self, mapping):
self.str = templates.lb_header % {
'schema_name_upper' : mapping.schema.name.upper(),
@@ -27,9 +28,9 @@ class LateBoundHeader:
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%s-latebound.h'%self.schema_name
def __repr__(self):
return self.str
def emit(self):
f = open('%s-latebound.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
@@ -17,9 +17,10 @@
# #
###############################################################################
import codegen
import templates
class LateBoundImplementation:
class LateBoundImplementation(codegen.Base):
def __init__(self, mapping):
schema_name = mapping.schema.name.capitalize()
@@ -110,10 +111,9 @@ class LateBoundImplementation:
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%s-latebound.cpp'%self.schema_name
def __repr__(self):
return self.str
def emit(self):
f = open('%s-latebound.cpp'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+4 -2
View File
@@ -17,6 +17,8 @@
# #
###############################################################################
from __future__ import print_function
import sys
import nodes
import templates
@@ -33,11 +35,11 @@ class Mapping:
'binary' : 'boost::dynamic_bitset<>'
}
supported_argument_types = {
supported_argument_types = set([
'INT', 'BOOL', 'DOUBLE', 'STRING', 'BINARY', 'ENUMERATION', 'ENTITY_INSTANCE',
'AGGREGATE_OF_INT', 'AGGREGATE_OF_DOUBLE', 'AGGREGATE_OF_STRING', 'AGGREGATE_OF_BINARY', 'AGGREGATE_OF_ENTITY_INSTANCE',
'AGGREGATE_OF_AGGREGATE_OF_INT', 'AGGREGATE_OF_AGGREGATE_OF_DOUBLE', 'AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE',
}
])
def __init__(self, schema):
self.schema = schema
+9 -4
View File
@@ -18,8 +18,13 @@
###############################################################################
import nodes
import platform
import collections
if tuple(map(int, platform.python_version_tuple())) < (2, 7):
import ordereddict
collections.OrderedDict = ordereddict.OrderedDict
class Schema:
def is_enumeration(self, v):
return str(v) in self.enumerations
@@ -34,12 +39,12 @@ class Schema:
def __init__(self, parsetree):
self.name = parsetree[1]
sort = lambda d: collections.OrderedDict(sorted(d.items()))
sort = lambda d: collections.OrderedDict(sorted(d))
self.types = sort({t.name:t for t in parsetree if isinstance(t, nodes.TypeDeclaration)})
self.entities = sort({t.name:t for t in parsetree if isinstance(t, nodes.EntityDeclaration)})
self.types = sort([(t.name,t) for t in parsetree if isinstance(t, nodes.TypeDeclaration)])
self.entities = sort([(t.name,t) for t in parsetree if isinstance(t, nodes.EntityDeclaration)])
of_type = lambda *types: sort({a: b.type.type for a,b in self.types.items() if any(isinstance(b.type.type, ty) for ty in types)})
of_type = lambda *types: sort([(a, b.type.type) for a,b in self.types.items() if any(isinstance(b.type.type, ty) for ty in types)])
self.enumerations = of_type(nodes.EnumerationType)
self.selects = of_type(nodes.SelectType)
+8
View File
@@ -893,7 +893,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPlane* l, TopoDS_Shape& face)
gp_Pln pln;
convert(l, pln);
Handle_Geom_Surface surf = new Geom_Plane(pln);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(surf);
#else
face = BRepBuilderAPI_MakeFace(surf, getValue(GV_PRECISION));
#endif
return true;
}
@@ -942,7 +946,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBSplineSurfaceWithKnots* l, To
}
Handle_Geom_Surface surf = new Geom_BSplineSurface(Poles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(surf);
#else
face = BRepBuilderAPI_MakeFace(surf, getValue(GV_PRECISION));
#endif
return true;
}
+7 -1
View File
@@ -63,6 +63,9 @@
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
@@ -95,7 +98,6 @@
#include <Poly_Triangulation.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -106,7 +108,11 @@
#include "../ifcgeom/IfcGeom.h"
#if OCC_VERSION_HEX < 0x60900
#ifdef _MSC_VER
#pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.")
#else
#warning "You are linking against linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade."
#endif
#endif
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
+6
View File
@@ -65,6 +65,8 @@
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
@@ -870,7 +872,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCylindricalSurface* l, TopoDS_
gp_Trsf trsf;
IfcGeom::Kernel::convert(l->Position(),trsf);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius())).Face().Moved(trsf);
#else
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius()), getValue(GV_PRECISION)).Face().Moved(trsf);
#endif
return true;
}
+10
View File
@@ -23,6 +23,8 @@
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/version.hpp>
#include <boost/lexical_cast.hpp>
#include "../ifcparse/IfcGlobalId.h"
#include "../ifcparse/IfcException.h"
@@ -87,7 +89,11 @@ IfcParse::IfcGlobalId::IfcGlobalId() {
std::vector<unsigned char> v(uuid_data.size());
std::copy(uuid_data.begin(), uuid_data.end(), v.begin());
string_data = compress(&v[0]);
#if BOOST_VERSION < 104400
formatted_string = boost::lexical_cast<std::string>(uuid_data);
#else
formatted_string = boost::uuids::to_string(uuid_data);
#endif
#ifndef NDEBUG
std::vector<unsigned char> test_vector;
@@ -106,7 +112,11 @@ IfcParse::IfcGlobalId::IfcGlobalId(const std::string& s)
std::vector<unsigned char> v;
expand(string_data, v);
std::copy(v.begin(), v.end(), uuid_data.begin());
#if BOOST_VERSION < 104400
formatted_string = boost::lexical_cast<std::string>(uuid_data);
#else
formatted_string = boost::uuids::to_string(uuid_data);
#endif
#ifndef NDEBUG
const std::string test_string = compress(&uuid_data.data[0]);
+24 -16
View File
@@ -54,21 +54,29 @@ SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON)
SWIG_ADD_MODULE(ifcopenshell_wrapper python IfcPython.i)
SWIG_LINK_LIBRARIES(ifcopenshell_wrapper IfcParse IfcGeom ${PYTHON_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${ICU_LIBRARIES})
# To install IfcPython let's get the site-packages dir from python
EXECUTE_PROCESS(COMMAND
python -c "import sys; from distutils.sysconfig import get_python_lib; sys.stdout.write(get_python_lib())"
OUTPUT_VARIABLE python_package_dir)
# Try to find the Python interpreter to get the site-packages
# directory in which the wrapper can be installed.
FIND_PACKAGE(PythonInterp)
IF(PYTHONINTERP_FOUND)
EXECUTE_PROCESS(
COMMAND ${PYTHON_EXECUTABLE} -c "import sys; from distutils.sysconfig import get_python_lib; sys.stdout.write(get_python_lib())"
OUTPUT_VARIABLE python_package_dir
)
IF("${python_package_dir}" STREQUAL "")
MESSAGE(FATAL_ERROR "Python executable not in PATH, aborting")
IF("${python_package_dir}" STREQUAL "")
MESSAGE(WARNING "Unable to locate Python site-package directory, unable to install the Python wrapper")
ELSE()
INSTALL(FILES
"${CMAKE_BINARY_DIR}/ifcwrap/ifcopenshell_wrapper.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/__init__.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/guid.py"
DESTINATION "${python_package_dir}/ifcopenshell")
INSTALL(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/geom/__init__.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/geom/occ_utils.py"
DESTINATION "${python_package_dir}/ifcopenshell/geom")
INSTALL(TARGETS _ifcopenshell_wrapper DESTINATION "${python_package_dir}/ifcopenshell")
ENDIF()
ELSE()
MESSAGE(WARNING "No Python interpreter found, unable to install the Python wrapper")
ENDIF()
INSTALL(FILES
"${CMAKE_BINARY_DIR}/ifcwrap/ifcopenshell_wrapper.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/__init__.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/guid.py"
DESTINATION "${python_package_dir}/ifcopenshell")
INSTALL(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/geom/__init__.py"
DESTINATION "${python_package_dir}/ifcopenshell/geom")
INSTALL(TARGETS _ifcopenshell_wrapper DESTINATION "${python_package_dir}/ifcopenshell")