diff --git a/.travis.yml b/.travis.yml index 0ff20a99a7..5510469322 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,14 @@ install: sudo apt-get install -y \ libocct-data-exchange-dev libocct-foundation-dev libocct-modeling-algorithms-dev libocct-modeling-data-dev \ libboost-system-dev libboost-program-options-dev libboost-regex-dev libboost-thread-dev libboost-date-time-dev libboost-iostreams-dev libboost-filesystem-dev \ - build-essential cmake libicu-dev python2.7 libpython2.7-dev swig zlib1g liblzma5 opencollada-dev - + build-essential cmake python2.7 libpython2.7-dev swig zlib1g liblzma5 opencollada-dev wget apt-transport-https + - sudo mkdir -p /usr/include/json/nlohmann/ + - sudo wget https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp -O /usr/include/json/nlohmann/json.hpp + - sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' + - sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list' + - sudo apt-get update -qq && sudo apt-get install -y dart + - export PATH=$PATH:/usr/lib/dart/bin:$HOME/.pub-cache/bin + - git clone https://github.com/KhronosGroup/glTF-Validator && pushd glTF-Validator && pub get && pub global activate --source path ./ && popd script: - pwd @@ -24,13 +30,15 @@ script: - cd build - | cmake \ - -DOCC_INCLUDE_DIR=/usr/include/occt \ + -DOCC_INCLUDE_DIR=/usr/include/opencascade \ -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 \ -DLIBXML2_INCLUDE_DIR=/usr/include/libxml2 \ -DLIBXML2_LIBRARIES="/usr/lib/x86_64-linux-gnu/libxml2.a;/lib/x86_64-linux-gnu/libz.so.1;/lib/x86_64-linux-gnu/liblzma.so.5" \ + -DGLTF_SUPPORT=On \ + -DJSON_INCLUDE_DIR=/usr/include/json \ .. - sudo make -j2 install @@ -38,6 +46,12 @@ script: - /usr/bin/python2.7 tests.py - cd input + + - /usr/local/bin/IfcConvert -yv acad2010_walls.ifc acad2010_walls.glb + - gltf_validator acad2010_walls.glb + + - python -c "from __future__ import print_function; import ifcopenshell; f = ifcopenshell.open('encoding.ifc'); print(f[1][0])" | grep "'a' 1m³ ≤ 5m³ ≥ 10m³" + - | (for i in *.ifc; do \ echo $i | tee -a log; \ @@ -49,4 +63,4 @@ script: - grep -v 0$ statuses | wc -l - echo Succeeded - grep 0$ statuses - - grep 0$ statuses | wc -l \ No newline at end of file + - grep 0$ statuses | wc -l diff --git a/README.md b/README.md index 122b40c7af..8d032f471e 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,6 @@ Dependencies * [Open Cascade](http://opencascade.org) - *optional*, but required for building IfcGeom ([official](http://www.opencascade.org/getocc/download/loadocc/), "OCCT", or [community edition](https://github.com/tpaviot/oce), "OCE") For converting IFC representation items into BRep solids and tesselated meshes -* [ICU](http://site.icu-project.org/) - *optional* - For handling code pages and Unicode in the parser * [OpenCOLLADA](https://github.com/khronosGroup/OpenCOLLADA/) - *optional* For IfcConvert to be able to write tessellated Collada (.dae) files * [SWIG](http://www.swig.org/) and [Python](https://www.python.org/) - *optional* @@ -85,7 +83,7 @@ Note: where `make -j` is written, add a number roughly equal to the amount of CP **1)** Install most of the prerequisites and dependencies: - $ sudo apt-get install git cmake gcc g++ libboost-all-dev libicu-dev + $ sudo apt-get install git cmake gcc g++ libboost-all-dev **2a)** Either use an OCE package from your operating system's software repository diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 69788ee5a4..630e74b551 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -31,9 +31,9 @@ set(HAS_MAX TRUE) endif() endforeach() -OPTION(UNICODE_SUPPORT "Build IfcOpenShell with Unicode support (requires ICU)." ON) OPTION(COLLADA_SUPPORT "Build IfcConvert with COLLADA support (requires OpenCOLLADA)." ON) OPTION(IFCXML_SUPPORT "Build IfcParse with ifcXML support (requires libxml2)." ON) +OPTION(GLTF_SUPPORT "Build IfcConvert with glTF support (requires json.hpp)." 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(BUILD_IFCGEOM "Build IfcGeom." ON) @@ -103,8 +103,6 @@ ENDMACRO() UNIFY_ENVVARS_AND_CACHE(OCC_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(OCC_LIBRARY_DIR) -UNIFY_ENVVARS_AND_CACHE(ICU_INCLUDE_DIR) -UNIFY_ENVVARS_AND_CACHE(ICU_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(OPENCOLLADA_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(OPENCOLLADA_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(LIBXML2_INCLUDE_DIR) @@ -118,6 +116,17 @@ UNIFY_ENVVARS_AND_CACHE(GMP_LIBRARY_DIR) UNIFY_ENVVARS_AND_CACHE(MPFR_INCLUDE_DIR) UNIFY_ENVVARS_AND_CACHE(MPFR_LIBRARY_DIR) +if (GLTF_SUPPORT) +UNIFY_ENVVARS_AND_CACHE(JSON_INCLUDE_DIR) +FIND_FILE(json_hpp "json.hpp" ${JSON_INCLUDE_DIR}/nlohmann) +IF(json_hpp) + MESSAGE(STATUS "JSON for Modern C++ header file found") +ELSE() + MESSAGE(FATAL_ERROR "Unable to find JSON for Modern C++ header file, aborting") +ENDIF() +add_definitions(-DWITH_GLTF) +endif() + # Set INSTALL_RPATH for target MACRO(SET_INSTALL_RPATHS _target _paths) SET(${_target}_rpaths "") @@ -326,43 +335,6 @@ endif() endif(BUILD_IFCGEOM) -IF(UNICODE_SUPPORT) - # Find ICU - IF("${ICU_INCLUDE_DIR}" STREQUAL "") - MESSAGE(STATUS "No ICU include directory specified") - ENDIF() - - IF("${ICU_LIBRARY_DIR}" STREQUAL "") - MESSAGE(STATUS "No ICU library directory specified") - FIND_LIBRARY(icu NAMES icuuc icuucd PATHS ${ICU_LIBRARY_DIR}) - ELSE() - FIND_LIBRARY(icu NAMES icuuc icuucd PATHS ${ICU_LIBRARY_DIR} NO_DEFAULT_PATH) - ENDIF() - - IF(icu) - GET_FILENAME_COMPONENT(ICU_LIBRARY_DIR ${icu} PATH) - - ADD_DEFINITIONS(-DHAVE_ICU) - MESSAGE(STATUS "ICU libraries found") - # NOTE icudata appears to be icudt on Windows/MSVC and icudata on others - # dl is included to resolve dlopen and friends symbols - IF(WIN32) - FIND_LIBRARY(icudt NAMES icudt PATHS ${ICU_LIBRARY_DIR} NO_DEFAULT_PATH) - SET(ICU_LIBRARIES ${icu} ${icudt}) - add_debug_variants(ICU_LIBRARIES "${ICU_LIBRARIES}" d) - # TODO MinGW build would appear to be using dynamic ICU regardless of this definition. - ADD_DEFINITIONS(-DU_STATIC_IMPLEMENTATION) # required for static ICU - ELSE() - FIND_LIBRARY(icudt NAMES icudata PATHS ${ICU_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(icui18n NAMES icui18n PATHS ${ICU_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(dl NAMES dl) - SET(ICU_LIBRARIES ${icu} ${icudt} ${dl} ${icui18n}) - ENDIF() - ELSE() - MESSAGE(FATAL_ERROR "UNICODE_SUPPORT enabled, but unable to find ICU. Disable UNICODE_SUPPORT or fix ICU paths to proceed.") - ENDIF() -ENDIF() - IF(COLLADA_SUPPORT AND BUILD_CONVERT) # Find OpenCOLLADA IF("${OPENCOLLADA_INCLUDE_DIR}" STREQUAL "") @@ -525,7 +497,7 @@ if (IFCCONVERT_DOUBLE_PRECISION) endif() INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS} - ${ICU_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR} + ${Boost_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIR} ${JSON_INCLUDE_DIR} ${CGAL_INCLUDE_DIR} ${GMP_INCLUDE_DIR} ${MPFR_INCLUDE_DIR} ) @@ -613,10 +585,6 @@ set_target_properties(IfcParse PROPERTIES COMPILE_FLAGS -DIFC_PARSE_EXPORTS) TARGET_LINK_LIBRARIES(IfcParse ${Boost_LIBRARIES} ${BCRYPT_LIBRARIES} ${LIBXML2_LIBRARIES}) -IF(UNICODE_SUPPORT) - TARGET_LINK_LIBRARIES(IfcParse ${ICU_LIBRARIES}) -ENDIF() - if (BUILD_IFCGEOM) foreach(kernel opencascade cgal) @@ -625,11 +593,16 @@ file(GLOB IFCGEOM_H_FILES ../src/ifcgeom/schema_agnostic/${kernel}/*.h) file(GLOB IFCGEOM_CPP_FILES ../src/ifcgeom/schema_agnostic/${kernel}/*.cpp) set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES}) +<<<<<<< HEAD add_library(IfcGeom_${kernel} ${IFCGEOM_FILES}) set_target_properties(IfcGeom_${kernel} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS") target_link_libraries(IfcGeom_${kernel} IfcParse ${${KERNEL_UPPER}_LIBRARIES}) list(APPEND IfcGeom_libraries IfcGeom_${kernel}) endforeach() +======= +add_library(IfcGeom_ifc2x3 STATIC ${IFCGEOM_FILES}) +add_library(IfcGeom_ifc4 STATIC ${IFCGEOM_FILES}) +>>>>>>> v0.6.0 foreach(schema 2x3 4) @@ -675,8 +648,8 @@ file(GLOB SERIALIZERS_S_H_FILES ../src/serializers/schema_dependent/*.h) file(GLOB SERIALIZERS_S_CPP_FILES ../src/serializers/schema_dependent/*.cpp) set(SERIALIZERS_S_FILES ${SERIALIZERS_S_H_FILES} ${SERIALIZERS_S_CPP_FILES}) -add_library(Serializers_ifc2x3 ${SERIALIZERS_S_FILES}) -add_library(Serializers_ifc4 ${SERIALIZERS_S_FILES}) +add_library(Serializers_ifc2x3 STATIC ${SERIALIZERS_S_FILES}) +add_library(Serializers_ifc4 STATIC ${SERIALIZERS_S_FILES}) set_target_properties(Serializers_ifc2x3 PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc2x3 ${CONVERT_PRECISION}") # TODO: Detect based on IfcSchema @@ -697,13 +670,13 @@ set(IFCCONVERT_FILES ${IFCCONVERT_CPP_FILES} ${IFCCONVERT_H_FILES}) ADD_EXECUTABLE(IfcConvert ${IFCCONVERT_FILES}) set_target_properties(IfcConvert PROPERTIES COMPILE_FLAGS "${CONVERT_PRECISION}") -TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES} ${ICU_LIBRARIES}) +TARGET_LINK_LIBRARIES(IfcConvert ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES}) if ((NOT WIN32) AND BUILD_SHARED_LIBS) # Only set RPATHs when building shared libraries (i.e. IfcParse and # IfcGeom are dynamically linked). Not necessarily a perfect solution # but probably a good indication of whether RPATHs are necessary. - SET_INSTALL_RPATHS(IfcConvert "${IFCOPENSHELL_LIBARY_DIR};${OCC_LIBRARY_DIR};${Boost_LIBRARY_DIRS};${OPENCOLLADA_LIBRARY_DIR};${ICU_LIBRARY_DIR}") + SET_INSTALL_RPATHS(IfcConvert "${IFCOPENSHELL_LIBARY_DIR};${OCC_LIBRARY_DIR};${Boost_LIBRARY_DIRS};${OPENCOLLADA_LIBRARY_DIR}") endif() INSTALL(TARGETS IfcConvert @@ -721,10 +694,10 @@ file(GLOB CPP_FILES ../src/ifcgeomserver/*.cpp) file(GLOB H_FILES ../src/ifcgeomserver/*.h) set(SOURCE_FILES ${CPP_FILES} ${H_FILES}) ADD_EXECUTABLE(IfcGeomServer ${SOURCE_FILES}) -TARGET_LINK_LIBRARIES(IfcGeomServer ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${ICU_LIBRARIES}) +TARGET_LINK_LIBRARIES(IfcGeomServer ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES}) if ((NOT WIN32) AND BUILD_SHARED_LIBS) - SET_INSTALL_RPATHS(IfcGeomServer "${IFCOPENSHELL_LIBARY_DIR};${OCC_LIBRARY_DIR};${Boost_LIBRARY_DIRS};${ICU_LIBRARY_DIR}") + SET_INSTALL_RPATHS(IfcGeomServer "${IFCOPENSHELL_LIBARY_DIR};${OCC_LIBRARY_DIR};${Boost_LIBRARY_DIRS}") endif() INSTALL(TARGETS IfcGeomServer diff --git a/nix/build-all.py b/nix/build-all.py index c47830922c..d648223491 100644 --- a/nix/build-all.py +++ b/nix/build-all.py @@ -28,6 +28,9 @@ # if building with USE_OCCT additionally: # # * freetype * glx.h # # # +# if building with -shared # +# * libgl1-mesa-dev libxext-dev libxmu-dev libxmu-headers libxi-dev # +# # # on debian 7.8 these can be obtained with: # # $ apt-get install git gcc g++ autoconf bison bzip2 # # libfreetype6-dev mesa-common-dev # @@ -71,7 +74,6 @@ BOOST_VERSION="1.69.0" PCRE_VERSION="8.39" LIBXML_VERSION="2.9.3" CMAKE_VERSION="3.4.1" -ICU_VERSION="56.1" SWIG_VERSION="3.0.12" GMP_VERSION="6.1.2" MPFR_VERSION="3.1.5" @@ -184,7 +186,7 @@ cecho(""" - How many compiler processes may be run in parallel. """) dependency_tree = { - 'IfcParse': ('icu', 'boost', 'libxml2'), + 'IfcParse': ('boost', 'libxml2'), 'IfcGeom': ('IfcParse', 'occ', 'cgal', 'voxel'), 'IfcConvert': ('IfcGeom', 'OpenCOLLADA'), 'OpenCOLLADA': ('libxml2', 'pcre'), @@ -192,7 +194,6 @@ dependency_tree = { 'IfcOpenShell-Python': ('python', 'swig', 'IfcGeom'), 'voxel': ('occ',), 'swig': ('pcre',), - 'icu': (), 'boost': (), 'libxml2': (), 'python': (), @@ -208,8 +209,19 @@ def v(dep): for x in v(d): yield x -if len(sys.argv[1:]): - targets = set(sum((list(v(target)) for target in sys.argv[1:]), [])) +tgts = [s for s in sys.argv[1:] if not s.startswith("-")] +flags = set(s for s in sys.argv[1:] if s.startswith("-")) + +BUILD_STATIC = not "-shared" in flags +ENABLE_FLAG = "--enable-static" if BUILD_STATIC else "--enable-shared" +DISABLE_FLAG = "--disable-shared" if BUILD_STATIC else "--disable-static" +LINK_TYPE = "static" if BUILD_STATIC else "shared" +LINK_TYPE_UCFIRST = LINK_TYPE[0].upper() + LINK_TYPE[1:] +LIBRARY_EXT = "a" if BUILD_STATIC else "so" +PIC = "-fPIC" if BUILD_STATIC else "" + +if len(tgts): + targets = set(sum((list(v(target)) for target in tgts), [])) else: targets = set(dependency_tree.keys()) @@ -272,7 +284,6 @@ def run(cmds, cwd=None): return stdout.strip() BOOST_VERSION_UNDERSCORE=BOOST_VERSION.replace(".", "_") -ICU_VERSION_UNDERSCORE=ICU_VERSION.replace(".", "_") CMAKE_VERSION_2=CMAKE_VERSION[:CMAKE_VERSION.rindex('.')] OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,) @@ -302,12 +313,6 @@ def run_cmake(arg1, cmake_args, cmake_dir=None, cwd=None): cmake_path= os.path.join(DEPS_DIR, "install", "cmake-%s" % (CMAKE_VERSION,), "bin", "cmake") run([cmake_path, P]+cmake_args+["-DCMAKE_BUILD_TYPE=%s" % (BUILD_CFG,)], cwd=cwd) -def run_icu(arg1, icu_args, cwd): - PLATFORM=get_os() - if PLATFORM == "Darwin": - PLATFORM="MacOSX" - run([bash, "../source/runConfigureICU", PLATFORM]+icu_args+["--prefix=%s/install/%s" % (DEPS_DIR, arg1)], cwd=cwd) - def git_clone(clone_url, target_dir, revision=None): """Lazily clones the `git` repository denoted by `clone_url` into `target_dir`, i.e. skips cloning if `target_dir` exists (naively assumes @@ -401,9 +406,7 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d os.makedirs(extract_build_dir) logger.info("\rConfiguring %s..." % (name,)) - if mode == "icu": - run_icu(name, build_tool_args, cwd=extract_build_dir) - elif mode == "autoconf": + if mode == "autoconf": run_autoconf(name, build_tool_args, cwd=extract_build_dir) elif mode == "cmake": run_cmake(name, build_tool_args, cwd=extract_build_dir) @@ -440,41 +443,34 @@ if get_os() == "Darwin": # If the linker supports GC sections, set it up to reduce binary file size # -fPIC is required for the shared libraries to work -try: - CXXFLAGS=os.environ["CXXFLAGS"] -except KeyError: - CXXFLAGS="" -try: - CFLAGS=os.environ["CFLAGS"] -except KeyError: - CFLAGS="" -try: - LDFLAGS=os.environ["LDFLAGS"] -except KeyError: - LDFLAGS="" +CXXFLAGS=os.environ.get("CXXFLAGS", "") +CFLAGS=os.environ.get("CFLAGS", "") +LDFLAGS=os.environ.get("LDFLAGS", "") if sp.call([bash, "-c", "ld --gc-sections 2>&1 | grep -- --gc-sections &> /dev/null"]) != 0: - CXXFLAGS_MINIMAL="%s -fPIC %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CXXFLAGS_MINIMAL"]=CXXFLAGS_MINIMAL - CFLAGS_MINIMAL="%s -fPIC %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CFLAGS_MINIMAL"]=CFLAGS_MINIMAL - CXXFLAGS="%s -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CXXFLAGS"]=CXXFLAGS - CFLAGS="%s -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden %s"% (CFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CFLAGS"]=CFLAGS + CXXFLAGS_MINIMAL="%s %s %s" % (CXXFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + CFLAGS_MINIMAL="%s %s %s" % (CFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + if BUILD_STATIC: + CXXFLAGS="%s %s -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + CFLAGS="%s %s -fdata-sections -ffunction-sections -fvisibility=hidden %s"% (CFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + else: + CXXFLAGS=CXXFLAGS_MINIMAL + CFLAGS=CFLAGS_MINIMAL LDFLAGS="%s -Wl,--gc-sections %s" % (LDFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["LDFLAGS"]=LDFLAGS else: - CXXFLAGS_MINIMAL="%s -fPIC %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CXXFLAGS_MINIMAL"]=CXXFLAGS_MINIMAL - CFLAGS_MINIMAL="%s -fPIC %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CFLAGS_MINIMAL"]=CFLAGS_MINIMAL - CXXFLAGS="%s -fPIC -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CXXFLAGS"]=CXXFLAGS - CFLAGS="%s -fPIC -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["CFLAGS"]=CFLAGS + CXXFLAGS_MINIMAL="%s %s %s" % (CXXFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + CFLAGS_MINIMAL="%s %s %s" % (CFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + if BUILD_STATIC: + CXXFLAGS="%s %s -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CXXFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + CFLAGS="%s %s -fvisibility=hidden -fvisibility-inlines-hidden %s" % (CFLAGS, PIC, str.join(" ", ADDITIONAL_ARGS)) + else: + CXXFLAGS=CXXFLAGS_MINIMAL + CFLAGS=CFLAGS_MINIMAL LDFLAGS="%s %s" % (LDFLAGS, str.join(" ", ADDITIONAL_ARGS)) - os.environ["LDFLAGS"]=LDFLAGS + +os.environ["CXXFLAGS"] = CXXFLAGS +os.environ["CFLAGS"] = CFLAGS +os.environ["LDFLAGS"] = LDFLAGS # Some dependencies need a more recent CMake version than most distros provide build_dependency(name="cmake-%s" % (CMAKE_VERSION,), mode="autoconf", build_tool_args=[], download_url="https://cmake.org/files/v%s" % (CMAKE_VERSION_2,), download_name="cmake-%s.tar.gz" % (CMAKE_VERSION,)) @@ -501,7 +497,7 @@ if "pcre" in targets: build_dependency( name="pcre-{PCRE_VERSION}".format(**locals()), mode="autoconf", - build_tool_args=["--disable-shared"], + build_tool_args=[DISABLE_FLAG], download_url="https://downloads.sourceforge.net/project/pcre/pcre/{PCRE_VERSION}/".format(**locals()), download_name="pcre-{PCRE_VERSION}.tar.bz2".format(**locals()) ) @@ -525,7 +521,7 @@ if USE_OCCT and "occ" in targets: mode="cmake", build_tool_args=[ "-DINSTALL_DIR={DEPS_DIR}/install/occt-{OCCT_VERSION}".format(**locals()), - "-DBUILD_LIBRARY_TYPE=Static", + "-DBUILD_LIBRARY_TYPE={LINK_TYPE_UCFIRST}".format(**locals()), "-DBUILD_MODULE_Draw=0", ], download_url = "https://git.dev.opencascade.org/repos/occt.git", @@ -562,7 +558,8 @@ if "libxml2" in targets: "autoconf", build_tool_args=[ "--without-python", - "--disable-shared", + ENABLE_FLAG, + DISABLE_FLAG, "--without-zlib", "--without-iconv", "--without-lzma" @@ -577,10 +574,10 @@ if "OpenCOLLADA" in targets: "cmake", build_tool_args=[ "-DLIBXML2_INCLUDE_DIR={DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/include/libxml2".format(**locals()), - "-DLIBXML2_LIBRARIES={DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.a".format(**locals()), + "-DLIBXML2_LIBRARIES={DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.{LIBRARY_EXT}".format(**locals()), "-DPCRE_INCLUDE_DIR={DEPS_DIR}/install/pcre-{PCRE_VERSION}/include".format(**locals()), - "-DPCRE_PCREPOSIX_LIBRARY={DEPS_DIR}/install/pcre-{PCRE_VERSION}/lib/libpcreposix.a".format(**locals()), - "-DPCRE_PCRE_LIBRARY={DEPS_DIR}/install/pcre-{PCRE_VERSION}/lib/libpcre.a".format(**locals()), + "-DPCRE_PCREPOSIX_LIBRARY={DEPS_DIR}/install/pcre-{PCRE_VERSION}/lib/libpcreposix.{LIBRARY_EXT}".format(**locals()), + "-DPCRE_PCRE_LIBRARY={DEPS_DIR}/install/pcre-{PCRE_VERSION}/lib/libpcre.{LIBRARY_EXT}".format(**locals()), "-DCMAKE_INSTALL_PREFIX={DEPS_DIR}/install/OpenCOLLADA/".format(**locals()) ], download_url="https://github.com/KhronosGroup/OpenCOLLADA.git", @@ -637,7 +634,7 @@ if "boost" in targets: "--with-thread", "--with-date_time", "--with-iostreams", - "link=static" + "link={LINK_TYPE}".format(**locals()) ] + \ BOOST_ADDRESS_MODEL + \ list(map(str_concat("cxxflags"), CXXFLAGS.strip().split(' '))) + \ @@ -647,6 +644,7 @@ if "boost" in targets: download_name="boost_{BOOST_VERSION_UNDERSCORE}.tar.bz2".format(**locals()) ) +<<<<<<< HEAD if "icu" in targets: build_dependency( name="icu-{ICU_VERSION}".format(**locals()), @@ -706,6 +704,7 @@ cmake_args=[ "-DUSE_MMAP=" "OFF", "-DBUILD_EXAMPLES=" "OFF", "-DBUILD_IFCPYTHON=" "OFF", + "-DBUILD_SHARED_LIBS=" +OFF_ON[not BUILD_STATIC], "-DBUILD_IFCGEOM=" +OFF_ON["IfcGeom" in targets], "-DBUILD_GEOMSERVER=" +OFF_ON["IfcGeomServer" in targets], "-DBUILD_CONVERT=" +OFF_ON["IfcConvert" in targets], @@ -740,12 +739,6 @@ if "OpenCOLLADA" in targets: "-DOPENCOLLADA_LIBRARY_DIR=" "{DEPS_DIR}/install/OpenCOLLADA/lib/opencollada".format(**locals()) ]) -if "icu" in targets: - cmake_args.extend([ - "-DICU_INCLUDE_DIR=" "{DEPS_DIR}/install/icu-{ICU_VERSION}/include".format(**locals()), - "-DICU_LIBRARY_DIR=" "{DEPS_DIR}/install/icu-{ICU_VERSION}/lib".format(**locals()) - ]) - if "pcre" in targets: cmake_args.append( "-DPCRE_LIBRARY_DIR=" "{DEPS_DIR}/install/pcre-{PCRE_VERSION}/lib".format(**locals()) @@ -754,7 +747,7 @@ if "pcre" in targets: if "libxml2" in targets: cmake_args.extend([ "-DLIBXML2_INCLUDE_DIR=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/include/libxml2".format(**locals()), - "-DLIBXML2_LIBRARIES=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.a".format(**locals()) + "-DLIBXML2_LIBRARIES=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.{LIBRARY_EXT}".format(**locals()) ]) run_cmake("", cmake_args, cmake_dir=CMAKE_DIR, cwd=executables_dir) @@ -789,18 +782,17 @@ if "IfcOpenShell-Python" in targets: run_cmake("", cmake_args=[ + "-DBUILD_SHARED_LIBS=" "OFF" if BUILD_STATIC else "ON", "-DBOOST_ROOT=" "{DEPS_DIR}/install/boost-{BOOST_VERSION}".format(**locals()), "-DOCC_INCLUDE_DIR=" +occ_include_dir, "-DOCC_LIBRARY_DIR=" +occ_library_dir, - "-DICU_INCLUDE_DIR=" "{DEPS_DIR}/install/icu-{ICU_VERSION}/include".format(**locals()), - "-DICU_LIBRARY_DIR=" "{DEPS_DIR}/install/icu-{ICU_VERSION}/lib".format(**locals()), "-DPYTHON_LIBRARY=" +PYTHON_LIBRARY, "-DPYTHON_EXECUTABLE=" +PYTHON_EXECUTABLE, "-DPYTHON_INCLUDE_DIR=" +PYTHON_INCLUDE, "-DSWIG_EXECUTABLE=" "{DEPS_DIR}/install/swig/bin/swig".format(**locals()), "-DCMAKE_INSTALL_PREFIX=" "{DEPS_DIR}/install/ifcopenshell/tmp".format(**locals()), "-DLIBXML2_INCLUDE_DIR=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/include/libxml2".format(**locals()), - "-DLIBXML2_LIBRARIES=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.a".format(**locals()), + "-DLIBXML2_LIBRARIES=" "{DEPS_DIR}/install/libxml2-{LIBXML_VERSION}/lib/libxml2.{LIBRARY_EXT}".format(**locals()), "-DCOLLADA_SUPPORT=OFF" ], cmake_dir=CMAKE_DIR, cwd=python_dir) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index e9571dcfe1..015c5c492d 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -27,6 +27,7 @@ ********************************************************************************/ #include "../serializers/ColladaSerializer.h" +#include "../serializers/GltfSerializer.h" #include "../serializers/IgesSerializer.h" #include "../serializers/StepSerializer.h" #include "../serializers/WavefrontObjSerializer.h" @@ -92,6 +93,9 @@ void print_usage(bool suggest_help = true) << " .obj WaveFront OBJ (a .mtl file is also created)\n" #ifdef WITH_OPENCOLLADA << " .dae Collada Digital Assets Exchange\n" +#endif +#ifdef WITH_GLTF + << " .glb glTF Binary glTF v2.0\n" #endif << " .stp STEP Standard for the Exchange of Product Data\n" << " .igs IGES Initial Graphics Exchange Specification\n" @@ -531,6 +535,7 @@ int main(int argc, char** argv) { const path_t OBJ = IfcUtil::path::from_utf8(".obj"), MTL = IfcUtil::path::from_utf8(".mtl"), DAE = IfcUtil::path::from_utf8(".dae"), + GLB = IfcUtil::path::from_utf8(".glb"), STP = IfcUtil::path::from_utf8(".stp"), IGS = IfcUtil::path::from_utf8(".igs"), SVG = IfcUtil::path::from_utf8(".svg"), @@ -656,6 +661,10 @@ int main(int argc, char** argv) { #ifdef WITH_OPENCOLLADA } else if (output_extension == DAE) { serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); +#endif +#ifdef WITH_GLTF + } else if (output_extension == GLB) { + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); #endif } else if (output_extension == STP) { serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), settings); diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomFunctions.cpp b/src/ifcgeom/kernels/opencascade/IfcGeomFunctions.cpp index 09e0d01d99..ff7cfc5eff 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomFunctions.cpp +++ b/src/ifcgeom/kernels/opencascade/IfcGeomFunctions.cpp @@ -2683,8 +2683,17 @@ bool IfcGeom::Kernel::triangulate_wire(const TopoDS_Wire& wire, TopTools_ListOfS // Validation for (int i = 1; i <= mape.Extent(); ++i) { +#if OCC_VERSION_HEX >= 0x70000 TopTools_ListOfShape val; if (!mapn.FindFromKey(mape.FindKey(i), val)) { +#else + bool contains = false; + try { + TopTools_ListOfShape val = mapn.FindFromKey(mape.FindKey(i)); + contains = true; + } catch (Standard_NoSuchObject&) {} + if (!contains) { +#endif // All existing edges need to exist in the new faces Logger::Error("Internal error, missing edge from triangulation"); if (faceset_helper_ != nullptr) { diff --git a/src/ifcparse/IfcCharacterDecoder.cpp b/src/ifcparse/IfcCharacterDecoder.cpp index 1f565d37b0..24e2dbce00 100644 --- a/src/ifcparse/IfcCharacterDecoder.cpp +++ b/src/ifcparse/IfcCharacterDecoder.cpp @@ -70,89 +70,26 @@ using namespace IfcParse; using namespace IfcWrite; -#ifdef HAVE_ICU -#include -#endif - -void IfcCharacterDecoder::addChar(std::stringstream& s,const UChar32& ch) { -#ifdef HAVE_ICU - if ( destination ) { - /* Note: The extraction buffer is of size 5, because in the UTF-8 encoding the - maximum length in bytes is 4. We add 1 for the NUL character. In other encodings - the length could be higher, but we have not taken that into account. */ - char extraction_buffer[5] = {}; - icu::UnicodeString(ch).extract(extraction_buffer,5,destination,status); - extraction_buffer[4] = '\0'; - s << extraction_buffer; - } else { - std::stringstream s2; - s2 << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (int) ch; - s << s2.str(); - } -#else - (void)ch; - s.put(substitution_character); -#endif -} IfcCharacterDecoder::IfcCharacterDecoder(IfcParse::IfcSpfStream* f) { file = f; -#ifdef HAVE_ICU - if (destination) ucnv_close(destination); - if (compatibility_converter) ucnv_close(compatibility_converter); - destination = 0; - compatibility_converter = 0; + codepage_ = 0; +} - if (mode == DEFAULT) { - destination = ucnv_open(0, &status); - } else if (mode == UTF8) { - destination = ucnv_open("utf-8", &status); - } else if (mode == LATIN) { - destination = ucnv_open("iso-8859-1", &status); - } - if (compatibility_charset.empty()) { - compatibility_charset = ucnv_getDefaultName(); - } - compatibility_converter = ucnv_open(compatibility_charset.c_str(), &status); -#endif -} IfcCharacterDecoder::~IfcCharacterDecoder() { -#ifdef HAVE_ICU - if ( destination ) ucnv_close(destination); - if ( converter ) ucnv_close(converter); - if ( compatibility_converter ) ucnv_close(compatibility_converter); - destination = 0; - converter = 0; - compatibility_converter = 0; - ucnv_flushCache(); -#endif } + IfcCharacterDecoder::operator std::string() { unsigned int parse_state = 0; - std::stringstream s; - s.put('\''); + builder_.clear(); + builder_.push_back('\''); char current_char; int codepage = 1; unsigned int hex = 0; unsigned int hex_count = 0; -#ifdef HAVE_ICU - unsigned int old_hex = 0; // for compatibility_mode -#endif + while ( (current_char = file->Peek()) != 0 ) { if ( EXPECTS_CHARACTER(parse_state) ) { -#ifdef HAVE_ICU - if ( previous_codepage != codepage ) { - if ( converter ) ucnv_close(converter); - char encoder[11] = {'i','s','o','-','8','8','5','9','-', static_cast(codepage + 0x30) }; - converter = ucnv_open(encoder, &status); - } - const char characters[2] = { static_cast(current_char + 0x80) }; - const char* char_array = &characters[0]; - UChar32 ch = ucnv_getNextUChar(converter,&char_array,char_array+1,&status); - addChar(s,ch); -#else - UChar32 ch = 0; - addChar(s,ch); -#endif + builder_.push_back(IfcUtil::convert_codepage(codepage, current_char + 0x80)); parse_state = 0; } else if ( current_char == '\'' && ! parse_state ) { parse_state = APOSTROPHE; @@ -192,31 +129,15 @@ IfcCharacterDecoder::operator std::string() { hex += HEX_TO_INT(current_char); if ( (hex_count == 2 && !(parse_state & EXTENDED2)) || (hex_count == 4 && !(parse_state & EXTENDED4)) || - (hex_count == 8) ) { -#ifdef HAVE_ICU - if (compatibility_mode) { - if (old_hex == 0) { - old_hex = hex; - } else { - char characters[3] = { (char)old_hex, (char)hex }; - const char* char_array = &characters[0]; - UChar32 ch = ucnv_getNextUChar(compatibility_converter,&char_array,char_array+2,&status); - addChar(s,ch); - old_hex = 0; - } - } - else { -#endif - addChar(s,(UChar32) hex); -#ifdef HAVE_ICU - } -#endif - if ( hex_count == 2 ) parse_state = 0; - else { - CLEAR_HEX(parse_state); - parse_state |= ENCOUNTERED_HEX; - } - hex = hex_count = 0; + (hex_count == 8) ) + { + builder_.push_back(hex); + if ( hex_count == 2 ) parse_state = 0; + else { + CLEAR_HEX(parse_state); + parse_state |= ENCOUNTERED_HEX; + } + hex = hex_count = 0; } } else if ( parse_state && !( (current_char == '\\' && parse_state == FIRST_SOLIDUS) || @@ -226,14 +147,40 @@ IfcCharacterDecoder::operator std::string() { throw IfcInvalidTokenException(file->Tell(), current_char); } else { parse_state = hex = hex_count = 0; - // NOTE: this is in fact wrong, this ought to be the representation of the character. - // In UTF-8 this is the same, but we should not rely on that. - s.put(current_char); + builder_.push_back(current_char); } file->Inc(); } - s.put('\''); - return s.str(); + builder_.push_back('\''); + + if (mode == UTF8) { + return IfcUtil::convert_utf8(builder_); + } else if (mode == SUBSTITUTE) { + std::string r; + r.reserve(builder_.size()); + const char& sub = substitution_character; + std::transform(builder_.begin(), builder_.end(), std::back_inserter(r), [&sub](wchar_t c) { + if (c >= 0x20 && c <= 0x7e) { + return (char)c; + } else { + return sub; + } + }); + return r; + } else if (mode == ESCAPE) { + std::stringstream str; + str << std::hex << std::setw(4) << std::setfill('0'); + std::for_each(builder_.begin(), builder_.end(), [&str](wchar_t c) { + if (c >= 0x20 && c <= 0x7e) { + str.put((char)c); + } else { + str << "\\u" << c; + } + }); + return str.str(); + } else { + throw IfcParse::IfcException("Invalid conversion mode"); + } } void IfcCharacterDecoder::dryRun() { @@ -298,60 +245,28 @@ void IfcCharacterDecoder::dryRun() { file->Inc(); } } -#ifdef HAVE_ICU -UConverter* IfcCharacterDecoder::destination = 0; -UConverter* IfcCharacterDecoder::converter = 0; -UConverter* IfcCharacterDecoder::compatibility_converter = 0; -int IfcCharacterDecoder::previous_codepage = -1; -UErrorCode IfcCharacterDecoder::status = U_ZERO_ERROR; -#endif -#ifdef HAVE_ICU + IfcCharacterDecoder::ConversionMode IfcCharacterDecoder::mode = IfcCharacterDecoder::UTF8; - -// Many BIM software (eg. Revit, ArchiCAD, ...) has wrong behavior -bool IfcCharacterDecoder::compatibility_mode = false; -std::string IfcCharacterDecoder::compatibility_charset = ""; - -#else char IfcCharacterDecoder::substitution_character = '_'; -#endif - - -IfcCharacterEncoder::IfcCharacterEncoder(const std::string& input) { -#ifdef HAVE_ICU - if ( !converter) converter = ucnv_open("utf-8", &status); -#endif - str = input; -} - -IfcCharacterEncoder::~IfcCharacterEncoder() { -#ifdef HAVE_ICU - if ( converter) ucnv_close(converter); - converter = 0; -#endif -} +IfcCharacterEncoder::IfcCharacterEncoder(const std::string& input) + : str(IfcUtil::convert_utf8(input)) {} + IfcCharacterEncoder::operator std::string() { std::ostringstream oss; oss.put('\''); -#ifdef HAVE_ICU + // Either 2 or 4 to uses \X2 or \X4 respectively. // Currently hardcoded to 4, but \X2 might be // sufficient for nearly all purposes. const int num_bytes = 4; const std::string num_bytes_str = std::string(1,num_bytes + 0x30); - - - UChar32 ch; - - const char* source = str.c_str(); - const char* limit = source + str.size(); - + bool in_extended = false; - while(source < limit) { - ch = ucnv_getNextUChar(converter, &source, limit, &status); + for (auto it = str.begin(); it != str.end(); ++it) { + auto ch = *it; const bool within_spf_range = ch >= 0x20 && ch <= 0x7e; if ( in_extended && within_spf_range ) { oss << "\\X0\\"; @@ -368,26 +283,61 @@ IfcCharacterEncoder::operator std::string() { } if ( in_extended ) oss << "\\X0\\"; -#else - for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) { - char ch = *i; - const bool within_spf_range = ch >= 0x20 && ch <= 0x7e; - if (within_spf_range) { - if ( ch == '\\' || ch == '\'' ) { - oss.put(ch); - } - oss.put(ch); - } else { - oss.put('_'); - } - } -#endif + oss.put('\''); return oss.str(); } +/* +Generate with: -#ifdef HAVE_ICU -UErrorCode IfcCharacterEncoder::status = U_ZERO_ERROR; -UConverter* IfcCharacterEncoder::converter = 0; -#endif +import codecs, string +codecs.register_error('zero', lambda e: (chr(0),e.start + 1)) +def _(): + for i in range(1,17): + try: + chrs = bytes(range(256)).decode('iso-8859-%d' % i, errors='zero') + except: chrs = "\x00" * 256 + yield str(list(map(ord, chrs))).translate(string.maketrans("[]", "{}")) + +"{%s}" % ",".join(_()) +*/ +std::wstring::value_type IfcUtil::convert_codepage(int codepage, int c) { + if (codepage < 1 || codepage > 16 || codepage == 12) { + throw IfcParse::IfcException("Invalid codepage"); + } + if (c < 0 || c > 255) { + throw IfcParse::IfcException("Invalid character ordinal"); + } + static std::array, 16> codepage_data = { { + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 728, 321, 164, 317, 346, 167, 168, 352, 350, 356, 377, 173, 381, 379, 176, 261, 731, 322, 180, 318, 347, 711, 184, 353, 351, 357, 378, 733, 382, 380, 340, 193, 194, 258, 196, 313, 262, 199, 268, 201, 280, 203, 282, 205, 206, 270, 272, 323, 327, 211, 212, 336, 214, 215, 344, 366, 218, 368, 220, 221, 354, 223, 341, 225, 226, 259, 228, 314, 263, 231, 269, 233, 281, 235, 283, 237, 238, 271, 273, 324, 328, 243, 244, 337, 246, 247, 345, 367, 250, 369, 252, 253, 355, 729}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 294, 728, 163, 164, 0, 292, 167, 168, 304, 350, 286, 308, 173, 0, 379, 176, 295, 178, 179, 180, 181, 293, 183, 184, 305, 351, 287, 309, 189, 0, 380, 192, 193, 194, 0, 196, 266, 264, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 209, 210, 211, 212, 288, 214, 215, 284, 217, 218, 219, 220, 364, 348, 223, 224, 225, 226, 0, 228, 267, 265, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 241, 242, 243, 244, 289, 246, 247, 285, 249, 250, 251, 252, 365, 349, 729}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 312, 342, 164, 296, 315, 167, 168, 352, 274, 290, 358, 173, 381, 175, 176, 261, 731, 343, 180, 297, 316, 711, 184, 353, 275, 291, 359, 330, 382, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 298, 272, 325, 332, 310, 212, 213, 214, 215, 216, 370, 218, 219, 220, 360, 362, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 299, 273, 326, 333, 311, 244, 245, 246, 247, 248, 371, 250, 251, 252, 361, 363, 729}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 173, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 8470, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 167, 1118, 1119}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 1548, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1563, 0, 0, 0, 1567, 0, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 0, 0, 0, 0, 0, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8216, 8217, 163, 8364, 8367, 166, 167, 168, 169, 890, 171, 172, 173, 0, 8213, 176, 177, 178, 179, 900, 901, 902, 183, 904, 905, 906, 187, 908, 189, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 0, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 0}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 0, 162, 163, 164, 165, 166, 167, 168, 169, 215, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 247, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8215, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 0, 0, 8206, 8207, 0}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 286, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 304, 350, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 287, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 305, 351, 255}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 274, 290, 298, 296, 310, 167, 315, 272, 352, 358, 381, 173, 362, 330, 176, 261, 275, 291, 299, 297, 311, 183, 316, 273, 353, 359, 382, 8213, 363, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 207, 208, 325, 332, 211, 212, 213, 214, 360, 216, 370, 218, 219, 220, 221, 222, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 239, 240, 326, 333, 243, 244, 245, 246, 361, 248, 371, 250, 251, 252, 253, 254, 312}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 0, 0, 0, 0, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 0, 0, 0, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 8221, 162, 163, 164, 8222, 166, 167, 216, 169, 342, 171, 172, 173, 174, 198, 176, 177, 178, 179, 8220, 181, 182, 183, 248, 185, 343, 187, 188, 189, 190, 230, 260, 302, 256, 262, 196, 197, 280, 274, 268, 201, 377, 278, 290, 310, 298, 315, 352, 323, 325, 211, 332, 213, 214, 215, 370, 321, 346, 362, 220, 379, 381, 223, 261, 303, 257, 263, 228, 229, 281, 275, 269, 233, 378, 279, 291, 311, 299, 316, 353, 324, 326, 243, 333, 245, 246, 247, 371, 322, 347, 363, 252, 380, 382, 8217}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 7682, 7683, 163, 266, 267, 7690, 167, 7808, 169, 7810, 7691, 7922, 173, 174, 376, 7710, 7711, 288, 289, 7744, 7745, 182, 7766, 7809, 7767, 7811, 7776, 7923, 7812, 7813, 7777, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 372, 209, 210, 211, 212, 213, 214, 7786, 216, 217, 218, 219, 220, 221, 374, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 373, 241, 242, 243, 244, 245, 246, 7787, 248, 249, 250, 251, 252, 253, 375, 255}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 8364, 165, 352, 167, 353, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 381, 181, 182, 183, 382, 185, 186, 187, 338, 339, 376, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}}, + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 261, 321, 8364, 8222, 352, 167, 353, 169, 536, 171, 377, 173, 378, 379, 176, 177, 268, 322, 381, 8221, 182, 183, 382, 269, 537, 187, 338, 339, 376, 380, 192, 193, 194, 258, 196, 262, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 272, 323, 210, 211, 212, 336, 214, 346, 368, 217, 218, 219, 220, 280, 538, 223, 224, 225, 226, 259, 228, 263, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 273, 324, 242, 243, 244, 337, 246, 347, 369, 249, 250, 251, 252, 281, 539, 255}} + }}; + auto r = codepage_data[codepage - 1][c]; + if (r == 0) { + throw IfcParse::IfcException("Character not defined"); + } + return r; +} + +std::string IfcUtil::convert_utf8(const std::wstring& s) { + return std::wstring_convert>().to_bytes(s); +} + +std::wstring IfcUtil::convert_utf8(const std::string& s) { + return std::wstring_convert>().from_bytes(s); +} \ No newline at end of file diff --git a/src/ifcparse/IfcCharacterDecoder.h b/src/ifcparse/IfcCharacterDecoder.h index 1bd88b969b..d178099c05 100644 --- a/src/ifcparse/IfcCharacterDecoder.h +++ b/src/ifcparse/IfcCharacterDecoder.h @@ -29,43 +29,27 @@ #include #include - -#ifdef HAVE_ICU -#include "unicode/ucnv.h" -#include "unicode/unistr.h" -#else -typedef unsigned int UChar32; -#endif +#include #include "../ifcparse/IfcSpfStream.h" +namespace IfcUtil { + std::wstring::value_type convert_codepage(int codepage, int c); + std::string convert_utf8(const std::wstring& s); + std::wstring convert_utf8(const std::string& s); +} + namespace IfcParse { class IFC_PARSE_API IfcCharacterDecoder { private: IfcParse::IfcSpfStream* file; -#ifdef HAVE_ICU - static UConverter* destination; - static UConverter* converter; - static UConverter* compatibility_converter; - static int previous_codepage; - static UErrorCode status; -#endif - void addChar(std::stringstream& s,const UChar32& ch); + std::wstring builder_; + int codepage_; public: -#ifdef HAVE_ICU - enum ConversionMode {DEFAULT,UTF8,LATIN,JSON,PYTHON}; + enum ConversionMode {SUBSTITUTE, UTF8, ESCAPE}; static ConversionMode mode; - - // Many BIM software (eg. Revit, ArchiCAD, ...) has wrong behavior to encode characters. - // It just translate to extended string in system default code page, not unicode. - // If you want to process these strings, set true. - static bool compatibility_mode; - static std::string compatibility_charset; - -#else static char substitution_character; -#endif IfcCharacterDecoder(IfcParse::IfcSpfStream* file); ~IfcCharacterDecoder(); void dryRun(); @@ -78,14 +62,9 @@ namespace IfcWrite { class IFC_PARSE_API IfcCharacterEncoder { private: - std::string str; -#ifdef HAVE_ICU - static UErrorCode status; - static UConverter* converter; -#endif + std::wstring str; public: IfcCharacterEncoder(const std::string& input); - ~IfcCharacterEncoder(); operator std::string(); }; diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt index 858d1ff9d3..92ad91de80 100644 --- a/src/ifcwrap/CMakeLists.txt +++ b/src/ifcwrap/CMakeLists.txt @@ -56,14 +56,12 @@ SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON) SWIG_ADD_MODULE(ifcopenshell_wrapper python IfcPython.i) if("$ENV{LDFLAGS}" MATCHES ".undefined.suppress") # On osx there is some state in the python dylib. With `-Wl,undefined,suppress` we can ignore the missing symbols at compile time. -SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} - ${ICU_LIBRARIES} ${Boost_LIBRARIES}) +SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES}) else() -SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${PYTHON_LIBRARIES} ${OPENCASCADE_LIBRARIES} - ${ICU_LIBRARIES} ${Boost_LIBRARIES}) +SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${PYTHON_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES}) endif() if ((NOT WIN32) AND BUILD_SHARED_LIBS) - SET_INSTALL_RPATHS(${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} "${IFCDIRS};${OCC_LIBRARY_DIR};${ICU_LIBRARY_DIR}") + SET_INSTALL_RPATHS(${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} "${IFCDIRS};${OCC_LIBRARY_DIR}") endif() # Try to find the Python interpreter to get the site-packages diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp new file mode 100644 index 0000000000..a9881c0183 --- /dev/null +++ b/src/serializers/GltfSerializer.cpp @@ -0,0 +1,327 @@ +/******************************************************************************** + * * + * 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 . * + * * + ********************************************************************************/ + +#ifdef WITH_GLTF + +#include "GltfSerializer.h" + +#include "../ifcparse/utils.h" + +#include + +static const uint32_t GLTF = 0x46546C67U; +static const uint32_t JSON = 0x4E4F534A; +static const uint32_t BIN = 0x004E4942; + +static const uint32_t CT_BYTE = 5120; +static const uint32_t CT_UNSIGNED_BYTE = 5121; +static const uint32_t CT_SHORT = 5122; +static const uint32_t CT_UNSIGNED_SHORT = 5123; +static const uint32_t CT_UNSIGNED_INT = 5125; +static const uint32_t CT_FLOAT = 5126; + +static const uint32_t PRIM_POINTS = 0; +static const uint32_t PRIM_LINES = 1; +static const uint32_t PRIM_LINE_LOOP = 2; +static const uint32_t PRIM_LINE_STRIP = 3; +static const uint32_t PRIM_TRIANGLES = 4; +static const uint32_t PRIM_TRIANGLE_STRIP = 5; +static const uint32_t PRIM_TRIANGLE_FAN = 6; + +GltfSerializer::GltfSerializer(const std::string& filename, const SerializerSettings& settings) + : GeometrySerializer(settings) + , filename_(filename) + , tmp_filename1_(filename + ".indices.tmp") + , tmp_filename2_(filename + ".vertices.tmp") + , fstream_(IfcUtil::path::from_utf8(filename).c_str(), std::ios_base::binary) + , tmp_fstream1_(IfcUtil::path::from_utf8(tmp_filename1_).c_str(), std::ios_base::binary) + , tmp_fstream2_(IfcUtil::path::from_utf8(tmp_filename2_).c_str(), std::ios_base::binary) + {} + +bool GltfSerializer::ready() { + return fstream_.is_open() && tmp_fstream1_.is_open() && tmp_fstream2_.is_open(); +} + +void GltfSerializer::writeHeader() { + json_["asset"]["generator"] = "IfcOpenShell IfcConvert " IFCOPENSHELL_VERSION; + json_["asset"]["version"] = "2.0"; + json_["scene"] = 0; + + node_array_ = json::array(); + json_["accessors"] = json::array(); + json_["scenes"] = json::array(); + json_["nodes"] = json::array(); + json_["meshes"] = json::array(); + json_["materials"] = json::array(); +} + +int GltfSerializer::writeMaterial(const IfcGeom::Material& style) { + auto it = materials_.find(style.name()); + if (it != materials_.end()) { + return it->second; + } + + int idx = json_["materials"].size(); + materials_[style.name()] = idx; + + std::array base; + base.fill(1.0); + if (style.hasDiffuse()) { + for (int i = 0; i < 3; ++i) { + base[i] = style.diffuse()[i]; + } + } + if (style.hasTransparency()) { + base[3] = 1. - style.transparency(); + } + + json_["materials"].push_back({ {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}}} }); + + if (style.hasTransparency() && style.transparency() > 1.e-9) { + json_["materials"].back()["alphaMode"] = "BLEND"; + } + + return idx; +} + +template +struct stride_name { static const char* const value; }; +template <> +const char* const stride_name<1U>::value = "SCALAR"; +template <> +const char* const stride_name<3U>::value = "VEC3"; + +template +struct component_type { static const uint32_t value; }; +template <> +const uint32_t component_type::value = CT_UNSIGNED_INT; +template <> +const uint32_t component_type::value = CT_FLOAT; + +template +size_t write_accessor(json& j, std::ofstream& ofs, It begin, It end) { + auto num = std::distance(begin, end) / N; + + json accessor = json::object(); + + accessor["bufferView"] = N == 1 ? 0 : 1; + accessor["byteOffset"] = (size_t)ofs.tellp(); + accessor["componentType"] = component_type::value; + accessor["count"] = num; + + std::array min, max; + min.fill(std::numeric_limits::max()); + max.fill(std::numeric_limits::min()); + for (auto it = begin; it != end; it += N) { + for (size_t i = 0; i < N; ++i) { + const float& v = *(it + i); + if (v < min[i]) { + min[i] = v; + } + if (v > max[i]) { + max[i] = v; + } + } + } + accessor["min"] = min; + accessor["max"] = max; + accessor["type"] = stride_name::value; + + ofs.write((const char*)&*begin, sizeof(typename It::value_type) * num * N); + + j["accessors"].push_back(accessor); + + return j["accessors"].size() - 1; +} + +void GltfSerializer::write(const IfcGeom::TriangulationElement* o) { + node_array_.push_back(json_["nodes"].size()); + + const std::vector& m = o->transformation().matrix().data(); + // nb: note that this contains the Y-UP transform as well. + const std::array matrix_flat = { + m[0], m[ 2], m[ 1], 0, + m[3], m[ 5], m[ 4], 0, + m[6], m[ 8], m[ 7], 0, + m[9], m[11], m[10], 1 + }; + static const std::array identity_matrix = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}; + + json node; + if (matrix_flat != identity_matrix) { + // glTF validator complains about identity matrices + node["matrix"] = matrix_flat; + } + + int current_mesh_index; + + // See if this mesh has already been processed + auto it = meshes_.find(o->geometry().id()); + if (it == meshes_.end()) { + + auto mid1 = o->geometry().material_ids().begin(); + auto mid0 = mid1; + auto fid0 = o->geometry().faces().begin(); + + json mesh; + mesh["name"] = o->geometry().id(); + + while (true) { + // In glTF we need to decompose a mesh into several primitives + // with a constant material. In the triangulations coming from + // IfcOpenShell the materials are encoded in an additional set + // of indices. Therefore we loop over the material indices to + // find equal ranges of materials. Triangle indices then need + // to be updated to reference the vertices only for the current + // material. + mid1++; + + if ((mid1 == o->geometry().material_ids().end()) || (*mid1 != *mid0)) { + auto n = std::distance(mid0, mid1); + auto fid1 = fid0 + n * 3; + + auto idx_range = std::minmax_element(fid0, fid1); + const auto& idx_begin = *idx_range.first; + const auto& idx_end = *idx_range.second + 1; + + std::vector idx_transformed; + idx_transformed.reserve((n * 3)); + std::transform(fid0, fid1, std::back_inserter(idx_transformed), [idx_begin](int i) { + return i - idx_begin; + }); + + json primitive = json::object(); + + primitive["indices"] = write_accessor<1U>(json_, tmp_fstream1_, idx_transformed.begin(), idx_transformed.end()); + + auto vbegin = o->geometry().verts().begin(); + std::vector vf(vbegin + idx_begin * 3, vbegin + idx_end * 3); + primitive["attributes"]["POSITION"] = write_accessor<3U>(json_, tmp_fstream2_, vf.begin(), vf.end()); + + auto nbegin = o->geometry().normals().begin(); + std::vector nf(nbegin + idx_begin * 3, nbegin + idx_end * 3); + primitive["attributes"]["NORMAL"] = write_accessor<3U>(json_, tmp_fstream2_, nf.begin(), nf.end()); + + primitive["material"] = writeMaterial(o->geometry().materials()[*mid0]); + primitive["mode"] = PRIM_TRIANGLES; + + mesh["primitives"].push_back(primitive); + + if (mid1 == o->geometry().material_ids().end()) { + break; + } + + mid0 = mid1; + fid0 = fid1; + } + } + + json_["meshes"].push_back(mesh); + + meshes_[o->geometry().id()] = current_mesh_index = json_["meshes"].size() - 1; + } else { + current_mesh_index = it->second; + } + + node["mesh"] = current_mesh_index; + json_["nodes"].push_back(node); +} + +template +struct padding_char { static const char value; }; +template <> +const char padding_char::value = ' '; +template <> +const char padding_char::value = '\x00'; + +uint32_t padding_for(uint32_t length) { + return ((4 - (length % 4)) % 4); +} + +template +void write_padding(std::ostream& fs, uint32_t N) { + uint32_t padding = padding_for(N); + for (uint32_t i = 0; i < padding; ++i) { + fs.put(padding_char::value); + } +} + +template +void write_header(std::ostream& fs, uint32_t N) { + uint32_t padding = padding_for(N); + uint32_t header[] = { N + padding, iden }; + fs.write((const char*)header, sizeof(header)); +} + +template +void write_block(std::ostream& fs, It begin, It end) { + uint32_t N = std::distance(begin, end); + write_header(fs, N); + fs.write((const char*)&*begin, N); + write_padding(fs, N); +} + +void GltfSerializer::finalize() { + tmp_fstream1_.close(); + tmp_fstream2_.close(); + + std::vector binary_contents; + // nb: uint32_t is the max buffer size in glTF + uint32_t indices_length, binary_length; + { + std::ifstream ifs(IfcUtil::path::from_utf8(tmp_filename1_).c_str(), std::ios::binary); + ifs.ignore(std::numeric_limits::max()); + indices_length = ifs.gcount(); + } + { + std::ifstream ifs(IfcUtil::path::from_utf8(tmp_filename2_).c_str(), std::ios::binary); + ifs.ignore(std::numeric_limits::max()); + binary_length = indices_length + ifs.gcount(); + } + + json scene_0; + scene_0["nodes"] = node_array_; + json_["scenes"].push_back(scene_0); + json_["bufferViews"].push_back({ {"buffer", 0}, { "byteLength", indices_length } }); + json_["bufferViews"].push_back({ {"buffer", 0}, {"byteStride", 12}, { "byteOffset", indices_length }, { "byteLength", binary_length - indices_length } }); + json_["buffers"].push_back({ {"byteLength", binary_length} }); + + std::string json_contents = json_.dump(); + uint32_t json_length = (uint32_t) json_contents.size(); + + uint32_t header[] = { GLTF, 2U, 12 + 8 + json_length + padding_for(json_length) + 8 + binary_length + padding_for(binary_length) }; + fstream_.write((const char*)header, sizeof(header)); + + write_block(fstream_, json_contents.begin(), json_contents.end()); + write_header(fstream_, binary_length); + { + std::ifstream ifs(IfcUtil::path::from_utf8(tmp_filename1_).c_str(), std::ios::binary); + fstream_ << ifs.rdbuf(); + } + { + std::ifstream ifs(IfcUtil::path::from_utf8(tmp_filename2_).c_str(), std::ios::binary); + fstream_ << ifs.rdbuf(); + } + write_padding(fstream_, binary_length); + + IfcUtil::path::delete_file(tmp_filename1_); + IfcUtil::path::delete_file(tmp_filename2_); +} + +#endif diff --git a/src/serializers/GltfSerializer.h b/src/serializers/GltfSerializer.h new file mode 100644 index 0000000000..34be625543 --- /dev/null +++ b/src/serializers/GltfSerializer.h @@ -0,0 +1,55 @@ +/******************************************************************************** + * * + * 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 . * + * * + ********************************************************************************/ + +#ifndef GLTFSERIALIZER_H +#define GLTFSERIALIZER_H + +#ifdef WITH_GLTF + +#include "../serializers/GeometrySerializer.h" + +#include +using json = nlohmann::json; + +#include + +class GltfSerializer : public GeometrySerializer { +private: + std::string filename_, tmp_filename1_, tmp_filename2_; + std::ofstream fstream_, tmp_fstream1_, tmp_fstream2_; + std::map materials_, meshes_; + json json_, node_array_; + + int writeMaterial(const IfcGeom::Material& style); +public: + GltfSerializer(const std::string& filename, const SerializerSettings& settings); + virtual ~GltfSerializer() {} + bool ready(); + void writeHeader(); + void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::BRepElement* /*o*/) {} + void finalize(); + bool isTesselated() const { return true; } + void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {} + void setFile(IfcParse::IfcFile*) {} +}; + +#endif + +#endif diff --git a/test/input b/test/input index a75c92451c..75e1b3aca9 160000 --- a/test/input +++ b/test/input @@ -1 +1 @@ -Subproject commit a75c92451c8e5b63641b57ed8216849b0121d33d +Subproject commit 75e1b3aca98f3503c4e77044e8054a1689573ba4 diff --git a/win/build-deps.cmd b/win/build-deps.cmd index 53dced8eb8..d4bae43551 100644 --- a/win/build-deps.cmd +++ b/win/build-deps.cmd @@ -195,37 +195,10 @@ call .\b2 toolset=msvc%BOOST_VC_VER% runtime-link=static address-model=%ARCH_BIT variant=%DEBUG_OR_RELEASE_LOWERCASE% %BOOST_LIBS% stage --stagedir=stage/vs%VS_VER%-%VS_PLATFORM% IF NOT %ERRORLEVEL%==0 GOTO :Error -:ICU -set DEPENDENCY_NAME=ICU -set DEPENDENCY_DIR=N/A -set ICU_VER=58.2 -set ICU_ZIP=icu-%ICU_VER%-vs%VS_VER%.7z -cd "%DEPS_DIR%" -call :DownloadFile https://www.npcglib.org/~stathis/downloads/%ICU_ZIP% "%DEPS_DIR%" %ICU_ZIP% -IF NOT %ERRORLEVEL%==0 GOTO :Error -call :ExtractArchive %ICU_ZIP% "%DEPS_DIR%" "%INSTALL_DIR%\icu" -IF NOT %ERRORLEVEL%==0 GOTO :Error -:: Rename lib and bin directories to predictable form -IF EXIST "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%". ( - pushd "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%" - IF EXIST bin. ren bin bin%ARCH_BITS%" - IF EXIST lib. ren lib lib%ARCH_BITS%" - popd -) - -IF EXIST "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\". ( - robocopy "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\include" "%INSTALL_DIR%\icu\include" /E /IS /njh /njs - IF NOT EXIST "%INSTALL_DIR%\icu\lib". mkdir "%INSTALL_DIR%\icu\lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicutest%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icutest%POSTFIX_D%.lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicutu%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icutu%POSTFIX_D%.lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicuuc%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icuuc%POSTFIX_D%.lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicudt%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icudt%POSTFIX_D%.lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicuin%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icuin%POSTFIX_D%.lib" - copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicuio%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icuio%POSTFIX_D%.lib" - REM NOTE not available in 58.2 at least, nor needed by us. - REM copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\sicule%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\icule%POSTFIX_D%.lib" - REM copy /y "%DEPS_DIR%\icu-%ICU_VER%-vs%VS_VER%\lib%ARCH_BITS%\siculx%POSTFIX_D%.lib" "%INSTALL_DIR%\icu\lib\iculx%POSTFIX_D%.lib" -) +:JSON +set DEPENDENCY_NAME=JSON for Modern C++ v3.6.1 +IF NOT EXIST "%INSTALL_DIR%\json\nlohmann". mkdir "%INSTALL_DIR%\json\nlohmann" +call :DownloadFile https://github.com/nlohmann/json/releases/download/v3.6.1/json.hpp "%INSTALL_DIR%\json\nlohmann" json.hpp :OpenCOLLADA :: Note OpenCOLLADA has only Release and Debug builds. diff --git a/win/run-cmake.bat b/win/run-cmake.bat index e46ad6ccd0..8154b3a4bc 100755 --- a/win/run-cmake.bat +++ b/win/run-cmake.bat @@ -64,8 +64,6 @@ set BOOST_VER=%BOOST_VERSION:.=_% set BOOST_ROOT=%DEPS_DIR%\boost_%BOOST_VER% set BOOST_LIBRARYDIR=%BOOST_ROOT%\stage\vs%VS_VER%-%VS_PLATFORM%\lib -set ICU_INCLUDE_DIR=%INSTALL_DIR%\icu\include -set ICU_LIBRARY_DIR=%INSTALL_DIR%\icu\lib if not defined OCC_INCLUDE_DIR set OCC_INCLUDE_DIR=%INSTALL_DIR%\oce\include\oce if not defined OCC_LIBRARY_DIR set OCC_LIBRARY_DIR=%INSTALL_DIR%\oce\Win%ARCH_BITS%\lib set OPENCOLLADA_INCLUDE_DIR=%INSTALL_DIR%\OpenCOLLADA\include\opencollada @@ -79,7 +77,7 @@ set PYTHON_LIBRARY=%PYTHONHOME%\libs\python%PY_VER_MAJOR_MINOR%.lib set PYTHON_EXECUTABLE=%PYTHONHOME%\python.exe set SWIG_DIR=%INSTALL_DIR%\swigwin set PATH=%PATH%;%SWIG_DIR%;%PYTHONHOME% -set THREEDS_MAX_SDK_HOME=C:\Program Files\Autodesk\3ds Max 2016 SDK\maxsdk +set JSON_INCLUDE_DIR=%INSTALL_DIR%\json echo. call cecho.cmd 0 10 "Script configuration:" @@ -89,8 +87,6 @@ echo. call cecho.cmd 0 10 "Dependency Environment Variables for %PROJECT_NAME%:" echo BOOST_ROOT = %BOOST_ROOT% echo BOOST_LIBRARYDIR = %BOOST_LIBRARYDIR% -echo ICU_INCLUDE_DIR = %ICU_INCLUDE_DIR% -echo ICU_LIBRARY_DIR = %ICU_LIBRARY_DIR% echo OCC_INCLUDE_DIR = %OCC_INCLUDE_DIR% echo OCC_LIBRARY_DIR = %OCC_LIBRARY_DIR% echo OPENCOLLADA_INCLUDE_DIR = %OPENCOLLADA_INCLUDE_DIR% @@ -102,7 +98,7 @@ echo PYTHON_INCLUDE_DIR = %PYTHON_INCLUDE_DIR% echo PYTHON_LIBRARY = %PYTHON_LIBRARY% echo PYTHON_EXECUTABLE = %PYTHON_EXECUTABLE% echo SWIG_DIR = %SWIG_DIR% -echo THREEDS_MAX_SDK_HOME = %THREEDS_MAX_SDK_HOME% +echo JSON_INCLUDE_DIR = %JSON_INCLUDE_DIR% echo. echo CMAKE_INSTALL_PREFIX = %CMAKE_INSTALL_PREFIX% echo.