diff --git a/CMakeLists.txt b/CMakeLists.txt index 41cb75eaa..00012e569 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,27 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release") add_definitions(-DSWIG_PYTHON_SILENT_MEMLEAK) endif(CMAKE_BUILD_TYPE STREQUAL "Release") +######################### +# On Windows, see #1347 # +######################### +if(WIN32 AND OCCT_ESSENTIALS_ROOT) + # Générer le fichier config.py.in + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/config.py.in + "# Configuration file generated by CMake + +OCCT_ESSENTIALS_ROOT = \"@OCCT_ESSENTIALS_ROOT@\" + ") + configure_file( + ${CMAKE_CURRENT_BINARY_DIR}/config.py.in + ${CMAKE_CURRENT_BINARY_DIR}/config.py + @ONLY + ) + set(OCCT_ESSENTIALS_PATH ${OCCT_ESSENTIALS_ROOT}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.py + DESTINATION ${PYTHONOCC_INSTALL_DIRECTORY} + ) +endif() + ################################ # OCE include and lib location # ################################ diff --git a/INSTALL.md b/INSTALL.md index 977dcc57b..33b93e70f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,127 +1,355 @@ -Build pythonocc-7.8.1 from scratch on a fresh Ubuntu 22.04 install ------------------------------------------------------------------- +# Building pythonOCC 7.8.1 - Complete Guide for Linux and Windows -Requirements ------------- +## Table of Contents +- [Linux Build Guide](#linux-build-guide) + - [Prerequisites (Linux)](#prerequisites-linux) + - [System Requirements (Linux)](#system-requirements-linux) + - [Build Process (Linux)](#build-process-linux) + - [1. Installing System Dependencies](#1-installing-system-dependencies-linux) + - [2. Building SWIG](#2-building-swig-linux) + - [3. Building OpenCascade](#3-building-opencascade-linux) + - [4. Building pythonOCC](#4-building-pythonocc-linux) + - [Optional Features (Linux)](#optional-features-linux) +- [Windows Build Guide](#windows-build-guide) + - [Prerequisites (Windows)](#prerequisites-windows) + - [System Requirements (Windows)](#system-requirements-windows) + - [Build Process (Windows)](#build-process-windows) + - [1. Installing Required Software](#1-installing-required-software-windows) + - [2. Installing OpenCascade](#2-installing-opencascade-windows) + - [3. Building pythonOCC](#3-building-pythonocc-windows) + - [Optional Features (Windows)](#optional-features-windows) +- [Common Steps](#common-steps) + - [Testing](#testing) + - [Demo Applications](#demo-applications) -pythonOCC-7.8.1 needs the following libraries or programs to be installed before you -can compile/use it: +# Linux Build Guide -* the python programming language (). Python 3.9 or more is required. -* OpenCascade 7.8.1 () -* SWIG 4.2.1 () -* rapidjson () for Gltf import/export -* cmake +## Prerequisites (Linux) + +Before starting the build process, ensure your system meets these requirements: + +- Ubuntu 22.04 LTS (fresh installation recommended) +- At least 8GB of free disk space +- Internet connection for downloading packages +- Sudo privileges + +## System Requirements (Linux) + +pythonOCC 7.8.1 requires the following components: + +| Component | Version | Purpose | +|-----------|---------|---------| +| Python | ≥ 3.9 | Runtime environment | +| OpenCascade | 7.8.1 | Core CAD functionality | +| SWIG | 4.2.1 | Interface generation | +| CMake | ≥ 3.1 | Build system | + +## Build Process (Linux) + +### 1. Installing System Dependencies (Linux) + +First, update your system and install required packages: -All the necessary libraries can be downloaded/installed using apt: ```bash sudo apt-get update -sudo apt-get install -y wget libglu1-mesa-dev libgl1-mesa-dev libxmu-dev libxi-dev build-essential cmake libfreetype6-dev tk-dev python3-dev rapidjson-dev python3 git python3-pip libpcre2-dev +sudo apt-get install -y \ + wget \ + libglu1-mesa-dev \ + libgl1-mesa-dev \ + libxmu-dev \ + libxi-dev \ + build-essential \ + cmake \ + libfreetype6-dev \ + tk-dev \ + python3-dev \ + rapidjson-dev \ + python3 \ + git \ + python3-pip \ + libpcre2-dev ``` -Build swig ----------- -The required swgi version is 4.2.1. Unfortunately, the ubuntu ppa only provides an outdated. If swig 4.2.1 is not available on your machine, you have to download/build by yourself (depends on libpcre2, previously installed): +### 2. Building SWIG (Linux) + +SWIG 4.2.1 is required but not available in Ubuntu's default repositories. Build it from source: + ```bash wget http://prdownloads.sourceforge.net/swig/swig-4.2.1.tar.gz tar -zxvf swig-4.2.1.tar.gz cd swig-4.2.1 -./configure && make -j4 && make install +./configure +make -j$(nproc) +sudo make install ``` -Build OpenCascade ------------------ -Download/extract version 7.8.1 https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/V7_8_1.tar.gz +### 3. Building OpenCascade (Linux) + +Download and extract OpenCascade 7.8.1: ```bash wget https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/V7_8_1.tar.gz tar -xvzf V7_8_1.tar.gz -``` - -Prepare the build stage: -```bash cd OCCT-7.8.1 mkdir cmake-build cd cmake-build ``` -Choose an installation destination. Default is /usr/local, but it is better to set up -an other folder so that it's easier to work with concurrent versions. -```bash -$ cmake -DINSTALL_DIR=/opt/occt781 -DBUILD_RELEASE_DISABLE_EXCEPTIONS=OFF .. -``` -then +Configure and build OpenCascade: + ```bash -make -j4 +cmake -DINSTALL_DIR=/opt/occt781 \ + -DBUILD_RELEASE_DISABLE_EXCEPTIONS=OFF \ + .. + +make -j$(nproc) sudo make install ``` -and finally add the libraries to the system + +Add OpenCascade libraries to the system: + ```bash -echo "/opt/occt781/lib" >> /etc/ld.so.conf.d/occt.conf +sudo bash -c 'echo "/opt/occt781/lib" >> /etc/ld.so.conf.d/occt.conf' +sudo ldconfig ``` -Build pythonocc ---------------- -First create a local copy of the git repository: +### 4. Building pythonOCC (Linux) + +Clone and build pythonOCC: + ```bash git clone https://github.com/tpaviot/pythonocc-core.git -``` -then -```bash cd pythonocc-core mkdir cmake-build && cd cmake-build -# Path to the installation folder -PYTHONOCC_INSTALL_DIRECTORY= +# Set installation directory (optional) +PYTHONOCC_INSTALL_DIRECTORY=${PYTHONOCC_INSTALL_DIRECTORY:-/usr/local} cmake \ - -DOCCT_INCLUDE_DIR=/opt/occt781/include/opencascade \ - -DOCCT_LIBRARY_DIR=/opt/occt781/lib \ - -DCMAKE_BUILD_TYPE=Release \ - -DPYTHONOCC_INSTALL_DIRECTORY=$PYTHONOCC_INSTALL_DIRECTORY \ - .. + -DOCCT_INCLUDE_DIR=/opt/occt781/include/opencascade \ + -DOCCT_LIBRARY_DIR=/opt/occt781/lib \ + -DCMAKE_BUILD_TYPE=Release \ + -DPYTHONOCC_INSTALL_DIRECTORY=$PYTHONOCC_INSTALL_DIRECTORY \ + .. -make -j4 && make install +make -j$(nproc) && sudo make install +``` + +Add OpenCascade libraries to your environment: -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/build/occt781/lib +```bash +echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/occt781/lib' >> ~/.bashrc +source ~/.bashrc ``` -If `PYTHONOCC_INSTALL_DIRECTORY` is unset, it will be installed to `site-packages/OCC`. Also add your LD_LIBRARY_PATH in your .bashrc file. +# Windows Build Guide + +## Prerequisites (Windows) + +Before starting the build process, ensure your system meets these requirements: + +- Windows 10 or 11 (64-bit) +- At least 10GB of free disk space +- Internet connection for downloading packages +- Administrator privileges + +## System Requirements (Windows) + +| Component | Version | Download Link | +|-----------|---------|---------------| +| Visual Studio | 2019 or 2022 Community | [Download](https://visualstudio.microsoft.com/downloads/) | +| Python | ≥ 3.9 | [Download](https://www.python.org/downloads/) | +| CMake | ≥ 3.1 | [Download](https://cmake.org/download/) | +| Git | Latest | [Download](https://git-scm.com/download/win) | +| RapidJSON | Latest | [Download](https://github.com/Tencent/rapidjson.git) | +| SWIG | 4.2.1 | [Download](http://www.swig.org/download.html) | +| OpenCascade | 7.8.1 | [Download](https://dev.opencascade.org/download) | + +## Build Process (Windows) + +### 1. Installing Required Software (Windows) + +1. Install Visual Studio 2019/2022 Community Edition: + - During installation, select "Desktop development with C++" + - Include "Windows 10 SDK" and "MSBuild" + +2. Install Python 3.9 or later: + - Download and run the installer + - Check "Add Python to PATH" + - Choose "Customize installation" + - Select "pip" and "py launcher" + - Install for all users + +3. Install CMake: + - Download and run the installer + - Add CMake to the system PATH for all users -Build pythonocc with numpy support ----------------------------------- -numpy enables fast STL file loading. In order to benefit from this feature, you must install the numpy package (including the dev part), and compile pythonocc with: +4. Install Git: + - Download and run the installer + - Use Git from Windows Command Prompt + - Use OpenSSL library + +5. Install SWIG: + - Download SWIG 4.2.1 for Windows + - Extract to C:\swigwin + - Add C:\swigwin to the system PATH + +6. Install RapidJSON + - Clone the git repository git clone https://github.com/Tencent/rapidjson.git + +Binaries for dependencies can be downloaded at https://dev.opencascade.org/resources/download/3rd-party-components + +### 2. Installing OpenCascade (Windows) + +1. Download OpenCascade 7.8.1 for Windows +2. Extract to, for example, occt-7.8.1 + +If the binaries are not available, consider compiling by yourself OCCT on Windows. Refer to the official OpenCascade Technology documentation https://dev.opencascade.org/doc/overview/html/build_upgrade.html + +When installing OpenCascade and third-party libraries, you should have a structure similar to the one described at https://dev.opencascade.org/doc/overview/html/index.html#intro_install_windows + +C:\OpenCASCADE-7.8.1-vc10-64 +├── ffmpeg-3.3.4-gpl-64 +├── freeimage-3.17.0-vc10-64 +├── freetype-2.6.3-vc10-64 +├── occt-7.8.1 +├── qt486-vc10-64 +├── tclkit-86-64 +├── vtk-6.1.0-vc10-64 +└── zlib-1.2.8-vc10-64 + +### 3. Building pythonOCC (Windows) + +1. Clone the repository: +```batch +git clone https://github.com/tpaviot/pythonocc-core.git +cd pythonocc-core +``` + +2. Create build directory: +```batch +mkdir cmake-build +cd cmake-build +``` + +3. Configure with CMake: +```batch +cmake -G "Visual Studio 16 2019" -A x64 ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DOCCT_INCLUDE_DIR=C:\OpenCASCADE-7.8.1-vc10-64\occt-7.8.1\inc ^ + -DOCCT_LIBRARY_DIR=C:\OpenCASCADE-7.8.1-vc10-64\occt-7.8.1\win64\vc14\lib ^ + -DOCCT_ESSENTIALS_ROOT=C:\OpenCASCADE-7.8.1-vc10-64 + .. +``` + +If using CMake GUI, make sure to set these two variables before clicking the "Generate" button: +``` +OCCT_INCLUDE_DIR=C:\OpenCASCADE-7.8.1-vc10-64\occt-7.8.1\inc +OCCT_LIBRARY_DIR=C:\OpenCASCADE-7.8.1-vc10-64\occt-7.8.1\win64\vc14\lib +``` + +4. Build: +```batch +cmake --build . --config Release +``` + +5. Install: +```batch +cmake --install . +``` + +# Common Steps + +## Optional Features + +### NumPy Support + +To enable fast STL file loading with NumPy support: + +1. Install NumPy: ```bash - -DPYTHONOCC_MESHDS_NUMPY=ON +pip install numpy ``` -simple test ------------ +2. Add the following CMake flag during pythonOCC configuration: ```bash -$ python +-DPYTHONOCC_MESHDS_NUMPY=ON +``` + +### Additional Dependencies + +Install additional Python packages for full functionality: + +```bash +pip install svgwrite numpy numpy-stl matplotlib PyQt5 +``` + +## Testing + +### Quick Test + +Verify the installation: + +```python +python3 >>> from OCC.Core.gp import gp_Pnt >>> p = gp_Pnt(1., 2., 3.) >>> p.X() 1.0 ->>> ``` -additional dependencies ------------------------ -Additional python packages are required if you want to benefit from all pythonocc features. -``` -pip install svgwrite numpy numpy-stl matplotlib PyQt5 -``` +### Full Test Suite -test ----- -In order to check that everything is ok, run the pythonocc unittest suite: +Run the complete test suite: ```bash pip install pytest pytest ``` -demos ------ -Download/test demos available at +## Demo Applications + +Try the demo applications: + +```bash +git clone https://github.com/tpaviot/pythonocc-demos +cd pythonocc-demos +python3 examples/core_classic_occ_bottle.py +``` + +## Troubleshooting + +### Linux Issues + +1. **Library not found errors**: + ```bash + sudo ldconfig + ``` + +2. **SWIG version mismatch**: + - Ensure no other SWIG versions are installed + - Verify installation: `swig -version` + +### Windows Issues + +1. **DLL not found errors**: + - Verify PATH environment variable includes OpenCascade bin directory + - Check Visual Studio installation + - if you encounter the following error: + +2. **DLL not found** for 3rd part libraries: + +If it was not done at build time, you can define the OCCT_ESSENTIALS_ROOT path +at run time, by setting the env var: + +```batch +setx OCCT_ESSENTIALS_ROOT "%CASROOT%\win64\vc14\bin" +``` + +3. **CMake configuration errors**: + - Ensure all paths use backslashes + - Verify Visual Studio installation + - Check environment variables + +For more examples and documentation, visit: +- [Demo Repository](https://github.com/tpaviot/pythonocc-demos) diff --git a/src/Display/WebGl/flask_server.py b/src/Display/WebGl/flask_server.py index 1a7f86760..6584e1dd7 100644 --- a/src/Display/WebGl/flask_server.py +++ b/src/Display/WebGl/flask_server.py @@ -3,7 +3,7 @@ import sys import uuid -from OCC.Display.WebGl.threejs_renderer import ( +from threejs_renderer import ( ThreejsRenderer, OCC_VERSION, THREEJS_RELEASE, diff --git a/src/Display/WebGl/simple_server.py b/src/Display/WebGl/simple_server.py index e78a41575..6d0cb288a 100644 --- a/src/Display/WebGl/simple_server.py +++ b/src/Display/WebGl/simple_server.py @@ -93,10 +93,15 @@ def start_server(addr="127.0.0.1", port=8080, x3d_path=".", open_webbrowser=Fals httpd = HTTPServer((addr, port), SimpleHTTPRequestHandler) print(f"\n## Serving {x3d_path} using SimpleHTTPServer") display_hostname = "localhost" - if addr == "0.0.0.0": # Did not consider ipv6 `::` because httpd does not support it + if ( + addr == "0.0.0.0" + ): # Did not consider ipv6 `::` because httpd does not support it display_hostname = get_interface_ip(socket.AF_INET) print(f"## Running on all addresses ({addr})") - print("## Open your webbrowser at the URL: http://%s:%i" % (display_hostname, port)) + print( + "## Open your webbrowser at the URL: http://%s:%i" + % (display_hostname, port) + ) # open webbrowser if open_webbrowser: webbrowser.open("http://%s:%i" % (display_hostname, port), new=2) diff --git a/src/Display/WebGl/threejs_renderer.py b/src/Display/WebGl/threejs_renderer.py index b5422b66f..56dd2060a 100644 --- a/src/Display/WebGl/threejs_renderer.py +++ b/src/Display/WebGl/threejs_renderer.py @@ -1,4 +1,4 @@ -##Copyright 2011-2019 Thomas Paviot (tpaviot@gmail.com) +##Copyright 2011-2024 Thomas Paviot (tpaviot@gmail.com) ## ##This file is part of pythonOCC. ## @@ -168,7 +168,6 @@ def export_edgedata_to_json(edge_hash, point_set): """ import * as THREE from 'three'; import { TrackballControls } from 'three/addons/controls/TrackballControls.js'; -import Stats from 'three/addons/libs/stats.module.js' var camera, scene, renderer, object, stats, container, shape_material; var controls; @@ -202,21 +201,21 @@ def export_edgedata_to_json(edge_hash, point_set): camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 200); camera.position.z = 100; - //controls = new THREE.OrbitControls(camera); - //controls = new THREE.OrbitControls(camera); - // for selection + raycaster = new THREE.Raycaster(); mouse = new THREE.Vector2(); - // create scene + scene = new THREE.Scene(); - scene.add(new THREE.AmbientLight(0x101010)); - directionalLight = new THREE.DirectionalLight(0xffffff); - directionalLight.position.x = 1; - directionalLight.position.y = -1; - directionalLight.position.z = 2; - directionalLight.position.normalize(); + scene.background = new THREE.Color(0xf0f0f0); + const ambientLight = new THREE.AmbientLight(0x404040, 1.5); + scene.add(ambientLight); + + directionalLight = new THREE.DirectionalLight(0xffffff, 1); + directionalLight.position.set(1, 1, 1).normalize(); scene.add(directionalLight); - light1 = new THREE.PointLight(0xffffff); + + light1 = new THREE.PointLight(0xffffff, 0.8); + light1.position.set(50, 50, 50); scene.add(light1); $Uniforms @@ -231,39 +230,42 @@ def export_edgedata_to_json(edge_hash, point_set): renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio( window.devicePixelRatio ); container.appendChild(renderer.domElement); - //renderer.gammaInput = true; - //renderer.gammaOutput = true; - // for shadow rendering + + // shadow rendering renderer.shadowMap.enabled = true; - renderer.shadowMap.type = THREE.PCFShadowMap; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + + // tone mapping + renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.toneMappingExposure = 1.0; + renderer.outputColorSpace = THREE.SRGBColorSpace; + controls = new TrackballControls(camera, renderer.domElement); - // show stats, is it really useful ? - stats = new Stats(); - stats.domElement.style.position = 'absolute'; - stats.domElement.style.top = '2%'; - stats.domElement.style.left = '1%'; - container.appendChild(stats.domElement); - // add events + document.addEventListener('keypress', onDocumentKeyPress, false); document.addEventListener('click', onDocumentMouseClick, false); window.addEventListener('resize', onWindowResize, false); } + function animate() { requestAnimationFrame(animate); controls.update(); render(); stats.update(); } + function update_lights() { if (directionalLight != undefined) { directionalLight.position.copy(camera.position); } } + function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } + function onDocumentKeyPress(event) { event.preventDefault(); if (event.key=="t") { // t key @@ -283,6 +285,7 @@ def export_edgedata_to_json(edge_hash, point_set): } } } + function onDocumentMouseClick(event) { event.preventDefault(); mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; @@ -306,11 +309,13 @@ def export_edgedata_to_json(edge_hash, point_set): selected_target = target; } } + function fit_to_scene() { // compute bounding sphere of whole scene var center = new THREE.Vector3(0,0,0); var radiuses = new Array(); var positions = new Array(); + // compute center of all objects scene.traverse(function(child) { if (child instanceof THREE.Mesh) { @@ -323,9 +328,11 @@ def export_edgedata_to_json(edge_hash, point_set): radiuses.push(radius); } }); + if (radiuses.length > 0) { center.divideScalar(radiuses.length*0.7); } + var maxRad = 1.; // compute bounding radius for (var ichild = 0; ichild < radiuses.length; ++ichild) { @@ -335,6 +342,7 @@ def export_edgedata_to_json(edge_hash, point_set): maxRad = totalDist; } } + maxRad = maxRad * 0.7; // otherwise the scene seems to be too far away camera.lookAt(center); var direction = new THREE.Vector3().copy(camera.position).sub(controls.target); @@ -348,18 +356,21 @@ def export_edgedata_to_json(edge_hash, point_set): var pnew = new THREE.Vector3().copy(center).add(direction); // change near far values to avoid culling of objects camera.position.set(pnew.x, pnew.y, pnew.z); - camera.far = lnew*50; - camera.near = lnew*50*0.001; + camera.far = lnew * 50; + camera.near = lnew * 50 * 0.001; camera.updateProjectionMatrix(); controls.target = center; controls.update(); + // adds and adjust a grid helper if needed gridHelper = new THREE.GridHelper(maxRad*4, 10) scene.add(gridHelper); + // axisHelper axisHelper = new THREE.AxesHelper(maxRad); scene.add(axisHelper); } + function render() { //@IncrementTime@ TODO UNCOMMENT update_lights(); @@ -384,57 +395,6 @@ def get_str(self): ) -# class HTMLBody_Part1: -# def __init__(self, vertex_shader=None, fragment_shader=None, uniforms=None): -# self._vertex_shader = vertex_shader -# self._fragment_shader = fragment_shader -# self._uniforms = uniforms - -# def get_str(self): -# global BODY_TEMPLATE_PART2 -# # get the location where pythonocc is running from -# body_str = BODY_TEMPLATE_PART1.replace("@VERSION@", VERSION) -# if self._fragment_shader is not None: -# vertex_shader_string_definition = f'' -# fragment_shader_string_definition = f'' -# shader_material_definition = """ -# var vertexShader = document.getElementById('vertexShader').textContent; -# var fragmentShader = document.getElementById('fragmentShader').textContent; -# var shader_material = new THREE.ShaderMaterial({uniforms: uniforms, -# vertexShader: vertexShader, -# fragmentShader: fragmentShader}); -# """ -# if self._uniforms is None: -# body_str = body_str.replace("@Uniforms@", "uniforms ={};\n") -# BODY_TEMPLATE_PART2 = BODY_TEMPLATE_PART2.replace("@IncrementTime@", "") -# else: -# body_str = body_str.replace("@Uniforms@", self._uniforms) -# if "time" in self._uniforms: -# BODY_TEMPLATE_PART2 = BODY_TEMPLATE_PART2.replace( -# "@IncrementTime@", "uniforms.time.value += 0.05;" -# ) -# else: -# BODY_TEMPLATE_PART2 = BODY_TEMPLATE_PART2.replace("@IncrementTime@", "") -# body_str = body_str.replace( -# "@VertexShaderDefinition@", vertex_shader_string_definition -# ) -# body_str = body_str.replace( -# "@FragmentShaderDefinition@", fragment_shader_string_definition -# ) -# body_str = body_str.replace( -# "@ShaderMaterialDefinition@", shader_material_definition -# ) -# body_str = body_str.replace("@ShapeMaterial@", "shader_material") -# else: -# body_str = body_str.replace("@Uniforms@", "") -# body_str = body_str.replace("@VertexShaderDefinition@", "") -# body_str = body_str.replace("@FragmentShaderDefinition@", "") -# body_str = body_str.replace("@ShaderMaterialDefinition@", "") -# body_str = body_str.replace("@ShapeMaterial@", "phong_material") -# body_str = body_str.replace("@IncrementTime@", "") -# return body_str - - class ThreejsRenderer: def __init__(self, path=None): self._path = tempfile.mkdtemp() if not path else path @@ -443,7 +403,7 @@ def __init__(self, path=None): self._3js_shapes = {} self._3js_edges = {} self.spinning_cursor = spinning_cursor() - print(f"## threejs renderer") + print("## threejs renderer") def DisplayShape( self, @@ -506,7 +466,6 @@ def DisplayShape( line_width, ] # generate the mesh - # tess.ExportShapeToThreejs(shape_hash, shape_full_path) # and also to JSON with open(shape_full_path, "w") as json_file: json_file.write(tess.ExportShapeToThreejsJSONString(shape_uuid)) @@ -559,6 +518,7 @@ def generate_html_file(self): f"specular:{color_to_hex(specular_color)},", "shininess:%g," % shininess, "side: THREE.DoubleSide,", + "flatShading:false", ) ) if transparency > 0.0: @@ -606,11 +566,6 @@ def generate_html_file(self): "ShaderMaterialDefinition": "", } ) - # fp.write(HTMLBody_Part1().get_str()) - # fp.write("".join(shape_string_list)) - # fp.write("".join(edge_string_list)) - ## then write header part 2 - # fp.write(BODY_TEMPLATE_PART2) fp.write(main_js) # write the index.html file diff --git a/src/PkgBase/__init__.py b/src/PkgBase/__init__.py index 31012c1cd..15fc6f115 100644 --- a/src/PkgBase/__init__.py +++ b/src/PkgBase/__init__.py @@ -1,8 +1,51 @@ +import os +from pathlib import Path +import platform + +# Version number PYTHONOCC_VERSION_MAJOR = 7 PYTHONOCC_VERSION_MINOR = 8 PYTHONOCC_VERSION_PATCH = 1 -# Empty for official releases, set to -dev, -rc1, etc for development releases +# Empty for official releases, set to -dev, -rc1, etc for development releases PYTHONOCC_VERSION_DEVEL = "" VERSION = f"{PYTHONOCC_VERSION_MAJOR}.{PYTHONOCC_VERSION_MINOR}.{PYTHONOCC_VERSION_PATCH}{PYTHONOCC_VERSION_DEVEL}" + + +def initialize_occt_libraries(occt_essentials_path) -> None: + """ + Initializes the OCCT libraries by adding all DLL directories to the DLL search path. + + Raises: + AssertionError: If the OCCT_ESSENTIALS_ROOT environment variable is not set. + """ + if not os.path.exists(occt_essentials_path): + raise AssertionError( + f"OCCT_ESSENTIALS_ROOT({occt_essentials_path}) is not set correctly." + ) + + for root, dirs, files in os.walk(occt_essentials_path): + if "debug" in root.lower(): + continue + for file in files: + if Path(file).suffix.lower() == ".dll": + os.add_dll_directory(root) + break + + +# on windows, see #1347 +if platform.system() == "windows": + try: + # OCC_ESSENTIALS_ROOT was defined at build time + # and is available in config.py + from .config import OCCT_ESSENTIALS_ROOT + + initialize_occt_libraries(occt_essentials_path=OCCT_ESSENTIALS_ROOT) + except ( + ImportError + ): # anyway, still possible to set up the OCC_ESSENTIALS_ROOT env var + if "OCCT_ESSENTIALS_ROOT" in os.environ: + initialize_occt_libraries( + occt_essentials_path=os.environ["OCCT_ESSENTIALS_ROOT"] + ) diff --git a/src/Tesselator/ShapeTesselator.cpp b/src/Tesselator/ShapeTesselator.cpp index 5795e7925..df06360a6 100644 --- a/src/Tesselator/ShapeTesselator.cpp +++ b/src/Tesselator/ShapeTesselator.cpp @@ -302,7 +302,7 @@ void ShapeTesselator::EnsureMeshIsComputed() printf("The mesh is not computed. Currently computing with default parameters ..."); Compute(true, 1.0, false); printf("done\n"); - printf("Call explicitely the Compute method to set the parameters value."); + printf("Call explicitely the Compute method to set the parameters value.\n"); } }