mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-07 08:21:42 +00:00
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9d003c22f | |||
| 2e71e002fc | |||
| 40ed2fe3ab | |||
| 379fe632a3 | |||
| 2ecaee9024 | |||
| f9a3c9a994 | |||
| 77acbff50b | |||
| 3f2cad0490 | |||
| 5ec974ff94 | |||
| 2c585b649a | |||
| 36c28f3953 | |||
| d1763237d2 | |||
| e8544d78ee | |||
| e715a9467d | |||
| 1f8c12a4c8 | |||
| 89a6eac535 | |||
| d1ffb329c8 | |||
| 4396126a43 | |||
| 7448feed44 | |||
| 6bc4046b17 | |||
| 1a83e52935 | |||
| f16d42ba14 | |||
| 75135fe45d | |||
| de89ab31cf | |||
| c8a4f1bbd2 | |||
| 5be1858767 | |||
| ace1db739f | |||
| 80504310b6 | |||
| a4dae9650f | |||
| c27a995480 | |||
| 5b4c54abd2 | |||
| 57d0beedee | |||
| d0ba675b1b | |||
| f4f2fa9535 | |||
| 67707914b9 | |||
| 12766d61d4 | |||
| 34374cba41 | |||
| f8bb04eae3 | |||
| aee8cbe479 | |||
| cb36e10279 | |||
| 7ca44b5677 | |||
| a6921b83a1 | |||
| c3c94b9c59 | |||
| 576ef336fc | |||
| b1fb541912 | |||
| 6345b052da | |||
| 061554d921 | |||
| bcaa412f4b | |||
| 9f6536b263 | |||
| 226581f76e | |||
| e833d0cd13 | |||
| ed3c95d9d7 | |||
| 7a4823a1bc | |||
| 80c0932174 | |||
| 73a238e7b0 | |||
| b95900f154 | |||
| da66e3c908 | |||
| e04cc47022 | |||
| ce427698d9 | |||
| d3beae1374 | |||
| 389d481364 | |||
| 3efd88b0d6 | |||
| 0a5388f386 | |||
| 71fa002707 | |||
| dd80115aa2 | |||
| bc66710fec | |||
| 921241fbdd | |||
| 44b9dd64f6 | |||
| bfa77255a5 | |||
| b125c651a8 | |||
| eb1c81514b |
@@ -14,10 +14,6 @@ jobs:
|
||||
runner: macos-14
|
||||
arch: x64
|
||||
oldarch:
|
||||
- os: macos
|
||||
runner: macos-14
|
||||
arch: arm64
|
||||
oldarch: m1
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
@@ -47,6 +43,7 @@ jobs:
|
||||
|
||||
- name: Unpack Dependencies
|
||||
run: |
|
||||
rm -rf ./build/*/*/*/install/*gmp* ./build/*/*/*/install/*cgal*
|
||||
install_root=$(find ./build -maxdepth 4 -type d -name install 2>/dev/null | head -n 1 || true)
|
||||
[ -n "$install_root" ] && find "$install_root" -type f -name 'cache-*.tar.gz' -maxdepth 1 -exec tar -xzf {} -C "$install_root" \; || true
|
||||
|
||||
@@ -75,8 +72,8 @@ jobs:
|
||||
/usr/local/bin/brew install gettext openssl
|
||||
fi
|
||||
set -o pipefail
|
||||
CXXFLAGS="-O3" CFLAGS="-O3 ${DARWIN_C_SOURCE}" ADD_COMMIT_SHA=1 BUILD_CFG=Release \
|
||||
python3 ./nix/build-all.py -v --diskcleanup ${MAC_INTEL} \
|
||||
IFCOS_SCHEMAS=4 CXXFLAGS="-O3" CFLAGS="-O3 ${DARWIN_C_SOURCE}" ADD_COMMIT_SHA=1 BUILD_CFG=Release \
|
||||
python3 ./nix/build-all.py -v -py-313 --diskcleanup ${MAC_INTEL} \
|
||||
| tee build.log
|
||||
|
||||
- name: Upload Build Logs
|
||||
|
||||
@@ -49,6 +49,19 @@ jobs:
|
||||
ifcopenshell_build/*/*/logs/*.log
|
||||
retention-days: 30
|
||||
|
||||
- name: Run wheel tests
|
||||
run: |
|
||||
cp -r IfcOpenShell/pyodide/test test
|
||||
# venv set up in build_pyodide.sh.
|
||||
source .venv/bin/activate
|
||||
uv pip install pytest-pyodide
|
||||
PYODIDE_ROOT_DIST=`pyodide config get pyodide_root`/dist
|
||||
# `pytest-pyodide` requires pyodide in 'pyodide' directory in cwd, when running `pytest`.
|
||||
cp -r $PYODIDE_ROOT_DIST test/pyodide
|
||||
cp dist/ifcopenshell-*.whl test/pyodide
|
||||
cd test
|
||||
pytest --capture=no
|
||||
|
||||
- name: Pack Dependencies
|
||||
run: |
|
||||
cd ifcopenshell_build
|
||||
|
||||
@@ -26,6 +26,7 @@ jobs:
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
uv tool install ruff
|
||||
uv tool install black
|
||||
uv tool install poethepoet
|
||||
|
||||
# black doesn't catch all syntax errors, so we check them explicitly.
|
||||
- name: Check syntax errors
|
||||
@@ -40,15 +41,16 @@ jobs:
|
||||
- name: Black formatter
|
||||
id: black
|
||||
run: |
|
||||
uvx black --diff --check .
|
||||
black --diff --check .
|
||||
continue-on-error: true
|
||||
|
||||
- name: Ruff check
|
||||
id: ruff
|
||||
run: |
|
||||
uvx ruff check
|
||||
# It's actually Python 3.6, but ruff only supports 3.7+, but it should do.
|
||||
uvx ruff check nix/build-all.py --target-version py37
|
||||
ERROR=0
|
||||
poe ruff-main || ERROR=1
|
||||
poe ruff-old || ERROR=1
|
||||
exit $ERROR
|
||||
continue-on-error: true
|
||||
|
||||
- name: Final check
|
||||
|
||||
@@ -74,7 +74,9 @@ jobs:
|
||||
with:
|
||||
key: ubuntu-22.04-${{ runner.arch }}
|
||||
|
||||
# rocksdb on debian distros misses RTTI?
|
||||
# RTTI is only enabled by default in Debug builds of rocksdb.
|
||||
# Distros are using Release builds, so we're compiling it ourselves with RTTI forced on.
|
||||
# https://github.com/facebook/rocksdb/blob/a3aa44a7167b8336f9bc15c8aba063260268ff68/CMakeLists.txt#L433
|
||||
- name: build rocksdb
|
||||
run: |
|
||||
git clone https://github.com/facebook/rocksdb --branch v9.11.2
|
||||
@@ -112,7 +114,6 @@ jobs:
|
||||
-DOCC_LIBRARY_DIR=/usr/lib/x86_64-linux-gnu \
|
||||
-DPYTHON_EXECUTABLE:FILEPATH=${{ env.pythonLocation }}/bin/python \
|
||||
-DPYTHON_INCLUDE_DIR:PATH=${{ env.pythonLocation }}/include/python3.11 \
|
||||
-DPYTHON_LIBRARY:FILEPATH=${{ env.pythonLocation }}/lib/libpython3.11.so \
|
||||
-DCOLLADA_SUPPORT=Off \
|
||||
-DUSE_MMAP=On \
|
||||
"-DSCHEMA_VERSIONS=2x3;4;4x3_add2" \
|
||||
|
||||
@@ -52,7 +52,7 @@ Contents
|
||||
| [ifcdiff](https://docs.ifcopenshell.org/ifcdiff.html) | Compare changes between IFC models | LGPL-3.0-or-later | [](https://pypi.org/project/ifcdiff/) |
|
||||
| [ifcfm](https://docs.ifcopenshell.org/ifcfm.html) | Extract IFC data for FM handover requirements | LGPL-3.0-or-later | [](https://pypi.org/project/ifcfm/) |
|
||||
| [ifcmax](https://docs.ifcopenshell.org/ifcmax.html) | Historic extension for IFC support in 3DS Max | LGPL-3.0-or-later\* | [](https://docs.ifcopenshell.org/ifcmax.html)
|
||||
| [ifcopenshell-python](https://docs.ifcopenshell.org/ifcopenshell-python.html) | Python library for IFC manipulation | LGPL-3.0-or-later\* | [](https://docs.ifcopenshell.org/ifcopenshell-python/installation.html) [](https://github.com/IfcOpenShell/IfcOpenShell/releases?q=ifcopenshell-python&expanded=true) [](https://pypi.org/project/ifcopenshell/) [](https://anaconda.org/conda-forge/ifcopenshell) [](https://anaconda.org/ifcopenshell/ifcopenshell) [](https://hub.docker.com/r/aecgeeks/ifcopenshell) [](https://aur.archlinux.org/packages/ifcopenshell) [](https://aur.archlinux.org/packages/ifcopenshell-git) |
|
||||
| [ifcopenshell-python](https://docs.ifcopenshell.org/ifcopenshell-python.html) | Python library for IFC manipulation | LGPL-3.0-or-later\* | [](https://docs.ifcopenshell.org/ifcopenshell-python/installation.html) [](https://github.com/IfcOpenShell/IfcOpenShell/releases?q=ifcopenshell-python&expanded=true) [](https://pypi.org/project/ifcopenshell/) [](https://anaconda.org/conda-forge/ifcopenshell) [](https://anaconda.org/ifcopenshell/ifcopenshell) [](https://hub.docker.com/r/aecgeeks/ifcopenshell) [](https://aur.archlinux.org/packages/ifcopenshell) [](https://aur.archlinux.org/packages/ifcopenshell-git) [Pyodide WASM Wheels](https://github.com/IfcOpenShell/wasm-wheels#pyodide-test-wheels) |
|
||||
| [ifcpatch](https://docs.ifcopenshell.org/ifcpatch.html) | Utility to run pre-packaged scripts to manipulate IFCs | LGPL-3.0-or-later | [](https://pypi.org/project/ifcpatch/) |
|
||||
| [ifcsverchok](https://docs.ifcopenshell.org/ifcsverchok.html) | Blender Add-on for visual node programming with IFC | GPL-3.0-or-later | [](https://github.com/IfcOpenShell/IfcOpenShell/releases?q=ifcsverchok&expanded=true)
|
||||
| [ifctester](https://docs.ifcopenshell.org/ifctester.html) | Library, CLI and webapp for IDS model auditing | LGPL-3.0-or-later | [](https://pypi.org/project/ifctester/) |
|
||||
|
||||
@@ -454,7 +454,7 @@ if(NOT MINIMAL_BUILD)
|
||||
# First try config mode (probably works with vcpkg, Conan, macOS brew installs, but not on ubuntu 22.04)
|
||||
# CONFIG is provided using root path, so no need to clear sysroot here.
|
||||
restore_wasm_sysroot()
|
||||
find_package(LibXml2 REQUIRED CONFIG)
|
||||
find_package(LibXml2 QUIET CONFIG)
|
||||
clear_wasm_sysroot()
|
||||
|
||||
if(NOT LibXml2_FOUND)
|
||||
|
||||
+63
-33
@@ -18,8 +18,6 @@
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
# ruff: noqa: UP035
|
||||
|
||||
"""
|
||||
Example usage:
|
||||
# Build all targets by default.
|
||||
@@ -210,34 +208,53 @@ assert platform.system() == "Darwin" or not MAC_CROSS_COMPILE_INTEL
|
||||
|
||||
WASM = "wasm" in flags
|
||||
"""Build WASM outside pyodide build environment."""
|
||||
WASM_DEBUG = False
|
||||
WASM_CMAKE_IS_USING_INIT_VARS = False
|
||||
if WASM:
|
||||
if "WASM_PYTHON_PATH" in os.environ:
|
||||
wasm_python_path = os.environ["WASM_PYTHON_PATH"]
|
||||
# Deduce version from path, assuming format .../python-X.Y.Z
|
||||
version_match = re.search(r"python-(\d+)\.(\d+)\.(\d+)", wasm_python_path)
|
||||
assert version_match, f"Could not deduce python version from '{wasm_python_path}'"
|
||||
python_version = version_match.group(1)
|
||||
os.environ["PYVERSION"] = python_version
|
||||
os.environ["PYTHONINCLUDE"] = f"{wasm_python_path}/include/python{python_version.rpartition('.')[0]}"
|
||||
os.environ["SIDE_MODULE_CFLAGS"] = ""
|
||||
# Required, otherwise library will compile as .a, not .so.
|
||||
os.environ["SIDE_MODULE_LDFLAGS"] = "-s SIDE_MODULE=1"
|
||||
# We're outside pyodide build environment, so need to provide toolchain file ourselves.
|
||||
assert "WASM_TOOLCHAIN_FILE" in os.environ, "WASM_TOOLCHAIN_FILE must be set when WASM_PYTHON_PATH is provided"
|
||||
WASM_DEBUG = True
|
||||
|
||||
def get_pyodide_config_var(var_name: str) -> str:
|
||||
output = sp.check_output(["pyodide", "config", "get", var_name], encoding="utf-8").strip()
|
||||
return output
|
||||
|
||||
if "PYODIDE_ROOT" not in os.environ:
|
||||
cecho("WARNING. Couldn't find 'PYODIDE_ROOT' in environment variables.", YELLOW)
|
||||
cecho("Assuming building wasm outside pyodide build environment and resetting necessary variables.", YELLOW)
|
||||
os.environ["SIDE_MODULE_CFLAGS"] = get_pyodide_config_var("cflags")
|
||||
os.environ["SIDE_MODULE_LDFLAGS"] = get_pyodide_config_var("ldflags")
|
||||
# Override cmake toolchain for all `emcmake` calls,
|
||||
# needed for shared libraries (resulting .so wrapper)
|
||||
# and to ensure compilation is pyodide compatible (e.g. `-fwasm-exceptions` is used in compilation flags).
|
||||
os.environ["CMAKE_TOOLCHAIN_FILE"] = get_pyodide_config_var("cmake_toolchain_file")
|
||||
required_vars = (
|
||||
# E.g. '3.13.2'.
|
||||
"PYVERSION",
|
||||
# 'include' folder in WASM-Python installation.
|
||||
# e.g. '/pyodide/cpython/installs/python-3.13.2/include/python3.13'
|
||||
"PYTHONINCLUDE",
|
||||
"SIDE_MODULE_CFLAGS",
|
||||
"SIDE_MODULE_LDFLAGS",
|
||||
"CMAKE_TOOLCHAIN_FILE",
|
||||
)
|
||||
missing_vars = [v for v in required_vars if v not in os.environ]
|
||||
assert not missing_vars, f"Some variables required for WASM compilation are missing: {', '.join(missing_vars)}"
|
||||
|
||||
def get_pyodide_build_version() -> "tuple[int, ...]":
|
||||
pyodide_build_suffix = "pyodide-build version:"
|
||||
output = sp.check_output(["pyodide", "--version"], encoding="utf-8").strip()
|
||||
assert pyodide_build_suffix in output, output
|
||||
version_line = next(l for l in output.splitlines() if l.startswith(pyodide_build_suffix))
|
||||
version = version_line.partition(":")[2].strip()
|
||||
return tuple(map(int, version.split(".")))
|
||||
|
||||
# Pyodide still in transition from `FLAGS` to `FLAGS_INIT`.
|
||||
# `FLAGS_INIT` allow us to provide flags using environment variables
|
||||
# and providing `FLAGS` directly would break pyodide toolchain.
|
||||
WASM_CMAKE_IS_USING_INIT_VARS = get_pyodide_build_version() >= (0, 30, 8)
|
||||
|
||||
# pyodide provide empty `CXXFLAGS`, leading to issues using C++ files compiled with `-fexceptions`
|
||||
# which is used by OCCT.
|
||||
# https://github.com/pyodide/pyodide-build/issues/251
|
||||
side_module_cxx_flags = os.environ.get("SIDE_MODULE_CXXFLAGS", "")
|
||||
if side_module_cxx_flags.strip():
|
||||
print("SIDE_MODULE_CXXFLAGS are already passed from pyodide build ('{side_module_cxx_flags}').")
|
||||
print("Maybe it's time to stop overriding them in the script?")
|
||||
|
||||
os.environ["SIDE_MODULE_CXXFLAGS"] = os.environ["SIDE_MODULE_CFLAGS"]
|
||||
|
||||
# Set defaults for missing empty environment variables
|
||||
|
||||
USE_OCCT = os.environ.get("USE_OCCT", "true").lower() == "true"
|
||||
@@ -365,11 +382,13 @@ if MAC_CROSS_COMPILE_INTEL:
|
||||
MAC_CROSS_COMPILE_INTEL_BJAM_ARGS = ["architecture=x86"]
|
||||
MAC_CROSS_COMPILE_INTEL_CXX = "clang++ -arch x86_64"
|
||||
MAC_CROSS_COMPILE_INTEL_CC = "clang -arch x86_64"
|
||||
MAC_CROSS_COMPILE_INTEL_AUTOCONF_HOST_ARGS = ["--host=x86_64-apple-darwin"]
|
||||
else:
|
||||
MAC_CROSS_COMPILE_INTEL_ARGS = []
|
||||
MAC_CROSS_COMPILE_INTEL_BJAM_ARGS = []
|
||||
MAC_CROSS_COMPILE_INTEL_CXX = ""
|
||||
MAC_CROSS_COMPILE_INTEL_CC = ""
|
||||
MAC_CROSS_COMPILE_INTEL_AUTOCONF_HOST_ARGS = []
|
||||
|
||||
OFF_ON = ["OFF", "ON"]
|
||||
BUILD_STATIC = "shared" not in flags
|
||||
@@ -421,6 +440,7 @@ required_commands = [git, bunzip2, tar, cc, cplusplus, autoconf, automake, make,
|
||||
if "wasm" in flags:
|
||||
# Skip swig build for WASM.
|
||||
required_commands.append("swig")
|
||||
required_commands.append("pyodide")
|
||||
required_commands.remove(yacc)
|
||||
|
||||
for cmd in required_commands:
|
||||
@@ -562,16 +582,27 @@ def run_cmake(arg1, cmake_args: "list[str]", cmake_dir: Union[str, None] = None,
|
||||
if "wasm" in flags:
|
||||
wasm.append("emcmake")
|
||||
|
||||
cmake_flags: list[str] = []
|
||||
if not WASM or not WASM_CMAKE_IS_USING_INIT_VARS:
|
||||
# For WASM we provide flags using just environment variables.
|
||||
# If we provide them using cmake vars, it will override emscripten toolchain flags.
|
||||
# Unsure if we need this in general even for non-WASM builds.
|
||||
cmake_flags.extend(
|
||||
[
|
||||
f"-DCMAKE_CXX_FLAGS='{os.environ['CXXFLAGS']}'",
|
||||
f"-DCMAKE_C_FLAGS='{os.environ['CFLAGS']}'",
|
||||
]
|
||||
)
|
||||
|
||||
run(
|
||||
[
|
||||
*wasm,
|
||||
"cmake",
|
||||
P,
|
||||
*cmake_flags,
|
||||
*cmake_args,
|
||||
f"-DCMAKE_BUILD_TYPE={BUILD_CFG}",
|
||||
f"-DBUILD_SHARED_LIBS={OFF_ON[not BUILD_STATIC]}",
|
||||
f"-DCMAKE_CXX_FLAGS='{os.environ['CXXFLAGS']}'",
|
||||
f"-DCMAKE_C_FLAGS='{os.environ['CFLAGS']}'",
|
||||
f"-DCMAKE_SHARED_LINKER_FLAGS={os.environ['LDFLAGS']}",
|
||||
],
|
||||
cwd=cwd,
|
||||
@@ -1166,7 +1197,9 @@ if "cgal" in targets:
|
||||
OLD_CC = None
|
||||
if MAC_CROSS_COMPILE_INTEL:
|
||||
OLD_CC = os.environ.get("CC")
|
||||
# Otherwise it's using arm64 `gcc` and fails to build gmp.
|
||||
os.environ["CC"] = MAC_CROSS_COMPILE_INTEL_CC
|
||||
gmp_args.extend(MAC_CROSS_COMPILE_INTEL_AUTOCONF_HOST_ARGS)
|
||||
|
||||
build_dependency(
|
||||
name=f"gmp-{GMP_VERSION}",
|
||||
@@ -1419,13 +1452,7 @@ if "IfcOpenShell-Python" in targets:
|
||||
# On OSX the actual Python library is not linked against.
|
||||
ADDITIONAL_ARGS = ""
|
||||
if platform.system() == "Darwin":
|
||||
ADDITIONAL_ARGS = "-Wl,-flat_namespace,-undefined,suppress"
|
||||
|
||||
if "wasm" in flags:
|
||||
ADDITIONAL_ARGS = "-Wl,-undefined,suppress"
|
||||
# Override CMAKE_TOOLCHAIN_FILE because by default emscripten doesn't support building shared binaries.
|
||||
if WASM_DEBUG:
|
||||
os.environ["CMAKE_TOOLCHAIN_FILE"] = os.environ["WASM_TOOLCHAIN_FILE"]
|
||||
ADDITIONAL_ARGS = "-Wl,-undefined,dynamic_lookup"
|
||||
|
||||
# NOTE: We don't use `CXXFLAGS` for wrappers, so wrapper is compiled with different flags
|
||||
# (e.g. ` -fdata-sections` is missing, which is set by default for executables)
|
||||
@@ -1490,7 +1517,7 @@ if "IfcOpenShell-Python" in targets:
|
||||
|
||||
logger.info(f"\rBuilding python {python_version} wrapper... ")
|
||||
|
||||
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}", "ifcopenshell_wrapper"], cwd=python_dir)
|
||||
run([make, f"-j{IFCOS_NUM_BUILD_PROCS}", "ifcopenshell_wrapper", "VERBOSE=1"], cwd=python_dir)
|
||||
run([make, "install/local"], cwd=os.path.join(python_dir, "ifcwrap"))
|
||||
|
||||
if python_executable:
|
||||
@@ -1516,7 +1543,10 @@ if "IfcOpenShell-Python" in targets:
|
||||
return module_dir
|
||||
|
||||
if "wasm" in flags:
|
||||
compile_python_wrapper(os.environ["PYVERSION"], os.environ["PYTHONINCLUDE"])
|
||||
compile_python_wrapper(
|
||||
run(["pyodide", "config", "get", "python_version"]),
|
||||
run(["pyodide", "config", "get", "python_include_dir"]),
|
||||
)
|
||||
# Copy setup.py where pyodide build system expects it.
|
||||
shutil.copy(REPO_PATH / "pyodide" / "setup.py", REPO_PATH)
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ since it's pure cmake without any additional moving parts.
|
||||
|
||||
- setup pyodide environment, see above
|
||||
- clone IfcOpenShell repo next to it to `IfcOpenShell` folder
|
||||
- setup debug build environment using `source pyodide/debug_build_env.sh /path/to/pyodide_root`
|
||||
- run `python nix/build-all.py -wasm -py-313` in `IfcOpenShell`
|
||||
- it will produce Python package in `IfcOpenShell/ifcopenshell`
|
||||
- run `pyodide build`
|
||||
|
||||
@@ -41,7 +41,7 @@ def pack_dependencies(install_dir: Path) -> None:
|
||||
def unpack_dependencies(install_dir: Path) -> None:
|
||||
# `filter` argument was fully introduced in 3.12
|
||||
# and results in deprecation warnings in 3.12-3.13, if not provided.
|
||||
tar_filter: "dict[Literal['filter'], Literal['data']]" = (
|
||||
tar_filter: dict[Literal["filter"], Literal["data"]] = (
|
||||
{"filter": "data"} if bool(sys.version_info >= (3, 12)) else {}
|
||||
)
|
||||
for tar_path in install_dir.glob(f"{CACHE_PREFIX}*.tar.gz"):
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <pyodide_root>"
|
||||
exit 1
|
||||
fi
|
||||
export PYODIDE_ROOT=$(readlink -f "$1")
|
||||
export PATH="$PYODIDE_ROOT/emsdk/emsdk:$PYODIDE_ROOT/emsdk/emsdk/node/22.16.0_64bit/bin:$PYODIDE_ROOT/emsdk/emsdk/upstream/emscripten:$PATH"
|
||||
# build-all.py vars.
|
||||
export WASM_PYTHON_PATH="$PYODIDE_ROOT/cpython/installs/python-3.13.2"
|
||||
export WASM_TOOLCHAIN_FILE="$PYODIDE_ROOT/pyodide-build/pyodide_build/tools/cmake/Modules/Platform/Emscripten.cmake"
|
||||
+2
-3
@@ -5,8 +5,7 @@ import os
|
||||
from pathlib import Path
|
||||
|
||||
import tomllib
|
||||
from setuptools import Extension, setup
|
||||
|
||||
from setuptools import Extension, find_packages, setup
|
||||
|
||||
REPO_FOLDER = Path(__file__).parent
|
||||
|
||||
@@ -37,7 +36,7 @@ setup(
|
||||
author_email="thomas@aecgeeks.com",
|
||||
url="https://ifcopenshell.org",
|
||||
install_requires=get_dependencies(),
|
||||
packages=["ifcopenshell"],
|
||||
packages=find_packages(include=["ifcopenshell", "ifcopenshell.*"]),
|
||||
package_data={
|
||||
# "*.so" is needed to include prebuilt binary extension. Otherwise it would try to build it and fail.
|
||||
"ifcopenshell": ["util/schema/*.json", "util/schema/*.ifc", "*.so"],
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
WHEEL_FILENAME = next(
|
||||
p.name for p in (Path.cwd() / "pyodide").iterdir() if p.name.startswith("ifcopenshell-") and p.suffix == ".whl"
|
||||
)
|
||||
|
||||
|
||||
def test_ifcopenshell_import(selenium):
|
||||
selenium.load_package("micropip")
|
||||
# Important to test it with `micropip.install`
|
||||
# without any dependencies loaded to ensure micropip will load them automatically.
|
||||
selenium.run_async(
|
||||
f"""
|
||||
import micropip
|
||||
await micropip.install(f"./{WHEEL_FILENAME}")
|
||||
import ifcopenshell
|
||||
ifc_file = ifcopenshell.file()
|
||||
wall = ifc_file.create_entity("IfcWall")
|
||||
wall1 = ifc_file.by_type("IfcWall")[0]
|
||||
print(wall, wall1)
|
||||
assert wall == wall1, "Wall entity doesn't match"
|
||||
wall.Name = "Test"
|
||||
assert wall.Name == "Test", f"Entity name wasn't changed: {{wall}}"
|
||||
print(wall)
|
||||
"""
|
||||
)
|
||||
@@ -62,3 +62,14 @@ ignore = [
|
||||
"UP031", # Replace % with .format
|
||||
"UP032", # Replace .format with f-string
|
||||
]
|
||||
|
||||
[tool.poe.tasks]
|
||||
|
||||
ruff-main = "ruff check --extend-exclude nix/build-all.py"
|
||||
# It's actually Python 3.6, but ruff only supports 3.7+, but it should do.
|
||||
ruff-old = "ruff check nix/build-all.py --target-version py37"
|
||||
ruff.sequence = ["ruff-main", "ruff-old"]
|
||||
|
||||
black = "black ."
|
||||
|
||||
format.sequence = ["black", "ruff-main", "ruff-old"]
|
||||
|
||||
@@ -374,7 +374,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc
|
||||
#endif
|
||||
|
||||
#ifdef SCHEMA_HAS_IfcMaterialConstituentSet
|
||||
if (associated_material->as<IfcSchema::IfcMaterialConstituentSet>()) {
|
||||
if (associated_material->as<IfcSchema::IfcMaterialConstituentSet>() && associated_material->as<IfcSchema::IfcMaterialConstituentSet>()->MaterialConstituents()) {
|
||||
IfcSchema::IfcMaterialConstituentSet* constituentset = associated_material->as<IfcSchema::IfcMaterialConstituentSet>();
|
||||
if (settings_.get<settings::LayersetFirst>().value ? constituentset->MaterialConstituents()->get()->size() >= 1 : constituentset->MaterialConstituents()->get()->size() == 1) {
|
||||
IfcSchema::IfcMaterialConstituent* constituent = (*constituentset->MaterialConstituents()->get()->begin());
|
||||
|
||||
@@ -11,9 +11,15 @@ BUILDDIR = _build
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@echo ""
|
||||
@echo "You can also do 'make server' to launch html server for previously built html docs."
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
server:
|
||||
python -m http.server 8080 --directory $(BUILDDIR)/html
|
||||
.PHONY: server Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
|
||||
@@ -178,13 +178,19 @@ to launch a simple notebook.
|
||||
Web Assembly
|
||||
------------
|
||||
|
||||
IfcOpenShell is available as technology preview to be run using WASM. This
|
||||
allows you to run IfcOpenShell in a browser using pyodide. This implementation
|
||||
is incredibly heavy and will incur a long load time, but once loaded, will give
|
||||
you full access to the entire IfcOpenShell API.
|
||||
To run IfcOpenShell in a browser using pyodide, we have available pyodide WASM
|
||||
packages at `wasm-wheels
|
||||
<https://github.com/IfcOpenShell/wasm-wheels#pyodide-test-wheels>`__ repository.
|
||||
|
||||
`Click here <https://github.com/IfcOpenShell/wasm-preview>`__ to learn how to
|
||||
use WASM.
|
||||
There is also a technology preview to be run using WASM. This implementation
|
||||
is incredibly heavy and will incur a long load time, but once loaded, will give
|
||||
you full access to the entire IfcOpenShell API:
|
||||
|
||||
- the latest preview - `here
|
||||
<https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.8.0/src/pyodide/demo-app/README.md>`__
|
||||
|
||||
- an older preview, that may have some additional information - `here
|
||||
<https://github.com/IfcOpenShell/wasm-preview>`__
|
||||
|
||||
Using Bonsai
|
||||
------------
|
||||
|
||||
@@ -251,7 +251,7 @@ nest formulas, for example ``concat(title("foo"), lower("Bar"))`` will produce
|
||||
"``int({{value}})``", "``int(3.123)``", "``3``", "Truncates the decimal part of the ``{{value}}``."
|
||||
"``number({{value}}[, {{decimal_separator}}[, {{thousands_separator}}]])``", "``number(1234.56, "","", ""."")``", "``1.234,56``", "Formats {{value}} with an optional custom {{decimal_separator}} and {{thousands_separator}}. The default separators are ``.`` and ``,``."
|
||||
"``metric_length({{value}}, {{precision}}, {{decimals}})``", "``metric_length(3.123, 0.1, 2)``", "``3.10``", "Rounds ``{{value}}`` to the nearest ``{{precision}}`` then displays using a certain amount of decimal places."
|
||||
"``imperial_length({{value}}, {{precision}}, {{input_unit}}, {{output_unit}})``", "``imperial_length(3.22, 4, ""foot"")``", "``3' - 3 3/4""``", "``The {{value}}`` may be specified either as ``foot`` or ``inch`` depending on ``{{input_unit}}``. The ``{{value}}`` is then rounded to the nearest ``1/{{precision}}`` inch then formatted using fractional feet and inches if ``{{output_unit}}`` is set to ``foot`` or just inches if ``{{output_unit}}`` is set to ``inch``."
|
||||
"``imperial_length({{value}}, {{precision}}, {{input_unit}}, {{output_unit}}, {{suppress_zero_inches}})``", "``imperial_length(3.0, 4, ""foot"", ""foot"", true)`` OR ``imperial_length(3.0, 4, ""foot"", ""foot"", false)``", "``3'`` OR ``3' - 0""``", "The ``{{value}}`` may be specified either as ``foot`` or ``inch`` depending on ``{{input_unit}}``. The ``{{value}}`` is then rounded to the nearest ``1/{{precision}}`` inch, then formatted using fractional feet and inches if ``{{output_unit}}`` is set to ``foot``, or just inches if ``{{output_unit}}`` is set to ``inch``. When ``{{suppress_zero_inches}}`` is ``true`` (default), measurements with zero inches will omit the inch portion (e.g., ``3'`` instead of ``3' - 0""``)."
|
||||
|
||||
When using queries in an IfcAnnotation tag surround with backticks.
|
||||
Examples:
|
||||
|
||||
@@ -148,13 +148,16 @@ format_grammar = lark.Lark(
|
||||
int: "int(" function ")"
|
||||
format_length: metric_length | imperial_length
|
||||
metric_length: "metric_length(" function "," NUMBER "," NUMBER ")"
|
||||
imperial_length: "imperial_length(" function "," NUMBER ["," ESCAPED_STRING "," ESCAPED_STRING] ")"
|
||||
imperial_length: "imperial_length(" function "," NUMBER ["," ESCAPED_STRING "," ESCAPED_STRING ["," boolean]] ")"
|
||||
lower: "lower(" function ")"
|
||||
upper: "upper(" function ")"
|
||||
title: "title(" function ")"
|
||||
concat: "concat(" function ("," function)* ")"
|
||||
substr: "substr(" function "," SIGNED_INT ["," SIGNED_INT] ")"
|
||||
boolean: TRUE | FALSE
|
||||
|
||||
TRUE: "true" | "True" | "TRUE"
|
||||
FALSE: "false" | "False" | "FALSE"
|
||||
// Embed common.lark for packaging
|
||||
DIGIT: "0".."9"
|
||||
HEXDIGIT: "a".."f"|"A".."F"|DIGIT
|
||||
@@ -218,6 +221,17 @@ class FormatTransformer(lark.Transformer):
|
||||
elif len(args) == 2:
|
||||
return str(args[0])[int(args[1]) :]
|
||||
|
||||
def boolean(self, args):
|
||||
if not args:
|
||||
return True
|
||||
token = args[0]
|
||||
if hasattr(token, "type"):
|
||||
return token.type == "TRUE"
|
||||
value = str(token).lower()
|
||||
if hasattr(token, "value"):
|
||||
value = str(token.value).lower()
|
||||
return value in ("true", "1", "yes")
|
||||
|
||||
def round(self, args):
|
||||
value = Decimal(0.0 if args[0] == "None" else args[0] or 0.0)
|
||||
nearest = Decimal(args[1])
|
||||
@@ -248,13 +262,27 @@ class FormatTransformer(lark.Transformer):
|
||||
if len(args) == 2:
|
||||
input_unit, output_unit = "foot", "foot"
|
||||
value, precision = args
|
||||
else:
|
||||
suppress_zero_inches = True
|
||||
elif len(args) == 3:
|
||||
value, precision, suppress_zero_inches = args
|
||||
input_unit, output_unit = "foot", "foot"
|
||||
elif len(args) == 4:
|
||||
value, precision, input_unit, output_unit = args
|
||||
input_unit = "inch" if input_unit == "inch" else "foot"
|
||||
output_unit = "inch" if output_unit == "inch" else "foot"
|
||||
suppress_zero_inches = True
|
||||
else:
|
||||
value, precision, input_unit, output_unit, suppress_zero_inches = args
|
||||
input_unit = "inch" if input_unit == "inch" else "foot"
|
||||
output_unit = "inch" if output_unit == "inch" else "foot"
|
||||
|
||||
return ifcopenshell.util.unit.format_length(
|
||||
float(value), int(precision), unit_system="imperial", input_unit=input_unit, output_unit=output_unit
|
||||
float(value),
|
||||
int(precision),
|
||||
suppress_zero_inches=suppress_zero_inches,
|
||||
unit_system="imperial",
|
||||
input_unit=input_unit,
|
||||
output_unit=output_unit,
|
||||
)
|
||||
|
||||
def int(self, args: list[str]) -> str:
|
||||
|
||||
Reference in New Issue
Block a user