From da0af775700c6218f29a03521e6f22a696612590 Mon Sep 17 00:00:00 2001 From: aothms Date: Thu, 18 Feb 2016 13:17:15 +0100 Subject: [PATCH] Compatibility for older versions of cmake, python, open cascade, boost --- cmake/CMakeLists.txt | 31 +++++++++++++---- src/ifcexpressparser/codegen.py | 34 +++++++++++++++++++ src/ifcexpressparser/enum_header.py | 11 +++--- src/ifcexpressparser/header.py | 12 +++---- src/ifcexpressparser/implementation.py | 12 +++---- src/ifcexpressparser/latebound_header.py | 11 +++--- .../latebound_implementation.py | 12 +++---- src/ifcexpressparser/mapping.py | 6 ++-- src/ifcexpressparser/schema.py | 13 ++++--- src/ifcgeom/IfcGeomFaces.cpp | 8 +++++ src/ifcgeom/IfcGeomFunctions.cpp | 8 ++++- src/ifcgeom/IfcGeomShapes.cpp | 6 ++++ src/ifcparse/IfcGlobalId.cpp | 10 ++++++ 13 files changed, 133 insertions(+), 41 deletions(-) create mode 100644 src/ifcexpressparser/codegen.py diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 0bace9a278..71963665ca 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -17,7 +17,7 @@ # # ################################################################################ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.5) project (IfcOpenShell) @@ -297,11 +297,23 @@ if(COMPILE_SCHEMA) set(IFC_RELEASE_NOT_USED "2x3" "4") # Install pyparsing if necessary - execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip "list" OUTPUT_VARIABLE PYTHON_PACKAGE_LIST) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip freeze OUTPUT_VARIABLE PYTHON_PACKAGE_LIST) + if ("${PYTHON_PACKAGE_LIST}" STREQUAL "") + execute_process(COMMAND pip freeze OUTPUT_VARIABLE PYTHON_PACKAGE_LIST) + if ("${PYTHON_PACKAGE_LIST}" STREQUAL "") + message(WARNING "Failed to find pip. Pip is required to automatically install pyparsing") + endif() + endif() string(FIND "${PYTHON_PACKAGE_LIST}" pyparsing PYPARSING_FOUND) if ("${PYPARSING_FOUND}" STREQUAL "-1") message(STATUS "Installing pyparsing") - execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip "install" --user pyparsing) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip "install" --user pyparsing RESULT_VARIABLE SUCCESS) + if (NOT "${SUCCESS}" STREQUAL "0") + execute_process(COMMAND pip "install" --user pyparsing RESULT_VARIABLE SUCCESS) + if (NOT "${SUCCESS}" STREQUAL "0") + message(WARNING "Failed to automatically install pyparsing. Please install manually") + endif() + endif() else() message(STATUS "Python interpreter with pyparsing found") endif() @@ -310,7 +322,12 @@ if(COMPILE_SCHEMA) message(STATUS "Compiling schema, this will take a while...") execute_process(COMMAND ${PYTHON_EXECUTABLE} bootstrap.py express.bnf WORKING_DIRECTORY ../src/ifcexpressparser - OUTPUT_FILE express_parser.py) + OUTPUT_FILE express_parser.py + RESULT_VARIABLE SUCCESS) + + if (NOT "${SUCCESS}" STREQUAL "0") + MESSAGE(FATAL_ERROR "Failed to bootstrap parser. Make sure pyparsing is installed") + endif() # Generate code execute_process(COMMAND ${PYTHON_EXECUTABLE} ../ifcexpressparser/express_parser.py ../../${COMPILE_SCHEMA} @@ -318,10 +335,12 @@ if(COMPILE_SCHEMA) OUTPUT_VARIABLE COMPILED_SCHEMA_NAME) # Prevent the schema that had just been compiled from being excluded - if(${COMPILED_SCHEMA_NAME} STREQUAL "IFC2X3") + if("${COMPILED_SCHEMA_NAME}" STREQUAL "IFC2X3") list(REMOVE_ITEM IFC_RELEASE_NOT_USED "2x3") - elseif(${COMPILED_SCHEMA_NAME} STREQUAL "IFC4") + add_definitions(-DUSE_IFC2x3) + elseif("${COMPILED_SCHEMA_NAME}" STREQUAL "IFC4") list(REMOVE_ITEM IFC_RELEASE_NOT_USED "4") + add_definitions(-DUSE_IFC4) endif() else() if(USE_IFC4) diff --git a/src/ifcexpressparser/codegen.py b/src/ifcexpressparser/codegen.py new file mode 100644 index 0000000000..6370b3dc87 --- /dev/null +++ b/src/ifcexpressparser/codegen.py @@ -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 . # +# # +############################################################################### + +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() diff --git a/src/ifcexpressparser/enum_header.py b/src/ifcexpressparser/enum_header.py index 96993ec13f..eb382a3e7a 100644 --- a/src/ifcexpressparser/enum_header.py +++ b/src/ifcexpressparser/enum_header.py @@ -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() diff --git a/src/ifcexpressparser/header.py b/src/ifcexpressparser/header.py index 51f4a89242..449506bc0f 100644 --- a/src/ifcexpressparser/header.py +++ b/src/ifcexpressparser/header.py @@ -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() - diff --git a/src/ifcexpressparser/implementation.py b/src/ifcexpressparser/implementation.py index f4e0759da3..f26581cf0e 100644 --- a/src/ifcexpressparser/implementation.py +++ b/src/ifcexpressparser/implementation.py @@ -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() - diff --git a/src/ifcexpressparser/latebound_header.py b/src/ifcexpressparser/latebound_header.py index bf2db78f3e..251a288073 100644 --- a/src/ifcexpressparser/latebound_header.py +++ b/src/ifcexpressparser/latebound_header.py @@ -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() diff --git a/src/ifcexpressparser/latebound_implementation.py b/src/ifcexpressparser/latebound_implementation.py index fe9e600ecd..1303d000ff 100644 --- a/src/ifcexpressparser/latebound_implementation.py +++ b/src/ifcexpressparser/latebound_implementation.py @@ -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() - diff --git a/src/ifcexpressparser/mapping.py b/src/ifcexpressparser/mapping.py index ee536697fd..5b9721e191 100644 --- a/src/ifcexpressparser/mapping.py +++ b/src/ifcexpressparser/mapping.py @@ -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 diff --git a/src/ifcexpressparser/schema.py b/src/ifcexpressparser/schema.py index 74d62bfacb..18335f3cdf 100644 --- a/src/ifcexpressparser/schema.py +++ b/src/ifcexpressparser/schema.py @@ -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) diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp index 6d83f90609..91753fc137 100644 --- a/src/ifcgeom/IfcGeomFaces.cpp +++ b/src/ifcgeom/IfcGeomFaces.cpp @@ -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; } diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 1ed8ee1627..14dd47230f 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -63,6 +63,9 @@ #include #include #include +#include + +#include #include #include @@ -95,7 +98,6 @@ #include #include -#include #include #include #include @@ -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) { diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index 0e1b0747cb..008ce6a9e8 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -65,6 +65,8 @@ #include #include #include +#include + #include #include @@ -859,7 +861,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; } diff --git a/src/ifcparse/IfcGlobalId.cpp b/src/ifcparse/IfcGlobalId.cpp index f6ab34b48c..e70189071f 100644 --- a/src/ifcparse/IfcGlobalId.cpp +++ b/src/ifcparse/IfcGlobalId.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "../ifcparse/IfcGlobalId.h" #include "../ifcparse/IfcException.h" @@ -87,7 +89,11 @@ IfcParse::IfcGlobalId::IfcGlobalId() { std::vector 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(uuid_data); +#else formatted_string = boost::uuids::to_string(uuid_data); +#endif #ifndef NDEBUG std::vector test_vector; @@ -106,7 +112,11 @@ IfcParse::IfcGlobalId::IfcGlobalId(const std::string& s) std::vector v; expand(string_data, v); std::copy(v.begin(), v.end(), uuid_data.begin()); +#if BOOST_VERSION < 104400 + formatted_string = boost::lexical_cast(uuid_data); +#else formatted_string = boost::uuids::to_string(uuid_data); +#endif #ifndef NDEBUG const std::string test_string = compress(&uuid_data.data[0]);