Merge branch 'master' into Draft_addgroup

This commit is contained in:
Yorik van Havre
2021-09-06 12:02:36 +02:00
committed by GitHub
6308 changed files with 1352377 additions and 676426 deletions
+1 -1
View File
@@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: FreeCAD
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://www.patreon.com/yorikvanhavre', 'https://www.patreon.com/kkremitzki', 'https://www.patreon.com/thundereal']
custom: ["https://wiki.freecadweb.org/Donate"]
+9 -6
View File
@@ -1,11 +1,14 @@
Thank you for creating a pull request to contribute to FreeCAD! To ease integration, please confirm the following:
Thank you for creating a pull request to contribute to FreeCAD! To ease integration, we ask you to conform to the following items. Pull requests which don't satisfy all the items below might be rejected. If you are in doubt with any of the items below, don't hesitate to ask for help in the [FreeCAD forum](https://forum.freecadweb.org/viewforum.php?f=10)!
- [ ] Branch rebased on latest master `git pull --rebase upstream master`
- [ ] Unit tests confirmed to pass by running `./bin/FreeCAD --run-test 0`
- [ ] Commit message is [well-written](https://chris.beams.io/posts/git-commit/)
- [ ] Commit message includes `issue #<id>` or `fixes #<id>` where `<id>` is the [associated MantisBT](https://freecadweb.org/wiki/tracker#GitHub_and_MantisBT) issue id if one exists
- [ ] Your pull request is confined strictly to a single module. That is, all the files changed by your pull request are either in `App`, `Base`, `Gui` or one of the `Mod` subfolders. If you need to make changes in several locations, make several pull requests and wait for the first one to be merged before submitting the next ones
- [ ] In case your pull request does more than just fixing small bugs, make sure you discussed your ideas with other developers on the FreeCAD forum
- [ ] Your branch is [rebased](https://git-scm.com/docs/git-rebase) on latest master `git pull --rebase upstream master`
- [ ] All FreeCAD unit tests are confirmed to pass by running `./bin/FreeCAD --run-test 0`
- [ ] All commit messages are [well-written](https://chris.beams.io/posts/git-commit/) ex: `Fixes typo in Draft Move command text`
- [ ] Your pull request is well written and has a good description, and its title starts with the module name, ex: `Draft: Fixed typos`
- [ ] Commit messages include `issue #<id>` or `fixes #<id>` where `<id>` is the [FreeCAD bug tracker issue number](https://freecadweb.org/wiki/tracker#GitHub_and_MantisBT) in case a particular commit solves or is related to an existing issue on the tracker. Ex: `Draft: fix typos - fixes #0004805`
And please remember to update the Wiki with the features added or changed once this PR is merged.
**Note**: If you don't have wiki access, then please mention your contribution on the [0.19 Changelog Forum Thread](https://forum.freecadweb.org/viewtopic.php?f=10&t=34586).
**Note**: If you don't have wiki access, then please mention your contribution on the [0.20 Changelog Forum Thread](https://forum.freecadweb.org/viewtopic.php?f=10&t=56135).
---
+1 -1
View File
@@ -1,5 +1,6 @@
# file types to ignore
*.DS_Store
*.pyc
*.obj
*.lib
@@ -33,7 +34,6 @@ install_manifest.txt
/src/Tools/offlinedoc/localwiki/
/src/Tools/offlinedoc/*.txt
OpenSCAD_rc.py
.subuser-dev
/\.idea/
.tags
tags
-1
View File
@@ -1 +0,0 @@
{"image-sources-dir": "./subuser"}
+98 -67
View File
@@ -1,4 +1,5 @@
####
######
#
# Travis-CI configuration file for FreeCAD.
#
# This build configuration will build and test FreeCAD on both Linux
@@ -16,7 +17,7 @@
#
# DEPLOY: Repo setting to deploy (defaults to no deploy to reduce
# Travis build times. Set DEPLOY=1 to enable in repo settings.
##
######
env:
global:
- GENERATOR="Unix Makefiles"
@@ -48,7 +49,8 @@ jobs:
# - python: 3.7
fast_finish: true # https://blog.travis-ci.com/2013-11-27-fast-finishing-builds
include:
- os: linux
- if: type != pull_request
os: linux
dist: bionic
language: cpp
compiler: clang
@@ -57,53 +59,54 @@ jobs:
apt:
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
packages:
- clang-9
- clang-10
env:
- CC=clang-9
- CXX=clang++-9
- CMAKE_ARGS="-DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_FEM_NETGEN=ON -DBUILD_QT5=ON"
- CC=clang-10
- CXX=clang++-10
- CMAKE_ARGS="-DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_FEM_NETGEN=ON"
- CACHE_NAME=JOB1
- os: linux
dist: bionic
language: cpp
compiler: gcc-9
compiler: gcc-10
cache: ccache
addons:
apt:
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages:
- gcc-9
- g++-9
- gcc-10
- g++-10
env:
- CC=gcc-9
- CXX=g++-9
- CC_FOR_BUILD=gcc-9
- CXX_FOR_BUILD=g++-9
- CMAKE_ARGS="-DCMAKE_CXX_COMPILER=/usr/bin/c++ -DCMAKE_C_COMPILER=/usr/bin/cc -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_FEM_NETGEN=ON -DBUILD_QT5=ON"
- CC=gcc-10
- CXX=g++-10
- CC_FOR_BUILD=gcc-10
- CXX_FOR_BUILD=g++-10
- CMAKE_ARGS="-DCMAKE_CXX_COMPILER=/usr/bin/c++ -DCMAKE_C_COMPILER=/usr/bin/cc -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_FEM_NETGEN=ON"
- CACHE_NAME=JOB2
- os: linux
dist: bionic
language: cpp
compiler: gcc-7
cache: ccache
env:
- CC=gcc-7
- CXX=g++-7
- CC_FOR_BUILD=gcc-7
- CXX_FOR_BUILD=g++-7
- CMAKE_ARGS="-DCMAKE_CXX_COMPILER=/usr/bin/c++ -DCMAKE_C_COMPILER=/usr/bin/cc"
- CACHE_NAME=JOB3
# - os: osx
# osx_image: xcode11.6
# language: cpp
# cache:
# - ccache: true
# - directories:
# - $HOME/.ccache
# - $HOME/Library/Caches/Homebrew
# - /usr/local/Homebrew
# env:
# - CMAKE_OPTS="-DBUILD_QT5=ON -DBUILD_ENABLE_CXX_STD='C++17' -DUSE_PYTHON3=1 -DCMAKE_CXX_FLAGS='-Wno-deprecated-declarations' -DBUILD_FEM_NETGEN=1 -DBUILD_FEM=1 -DBUILD_TECHDRAW=0 -DCMAKE_PREFIX_PATH='/usr/local/opt/qt/lib/cmake;/usr/local/opt/nglib/Contents/Resources' -DBUILD_FEM_NETGEN:BOOL=ON -DFREECAD_USE_EXTERNAL_KDL=ON -DCMAKE_BUILD_TYPE=Release"
# - PATH=/usr/local/bin:$PATH
# - CACHE_NAME=OSX1
- os: windows
language: cpp
env:
- CMAKE_OPTS="-DBUILD_FEM_NETGEN=ON -DFREECAD_RELEASE_PDB=OFF -DFREECAD_RELEASE_SEH=OFF"
- CMAKE_OPTS="-DBUILD_FEM_NETGEN=OFF -DFREECAD_RELEASE_PDB=OFF -DFREECAD_RELEASE_SEH=OFF"
- GENERATOR="Visual Studio 15 2017 Win64"
- PYTHON_MAJOR_VERSION=3
- MSBUILD_PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin"
@@ -119,7 +122,7 @@ jobs:
cache:
directories:
- $HOME/clcache
# - language: python
# python: 3.7
# dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069)
@@ -128,6 +131,9 @@ jobs:
# # fail the build if there are Python syntax errors or undefined names
# script: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
before_cache:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi
before_install:
# - eval "$(curl -fsSL "https://raw.githubusercontent.com/${OSX_PORTS_CACHE}/v${FREECAD_RELEASE}/travis-helpers.sh")"
@@ -188,6 +194,11 @@ before_install:
# Runtime deps
sudo apt-get install -y --no-install-recommends freecad-daily-python3 python-pivy python3-pivy python-ply python3-ply
# Use newer Eigen to suppress warnings
# https://github.com/FreeCAD/FreeCAD/pull/3485
wget http://mirrors.kernel.org/ubuntu/pool/universe/e/eigen3/libeigen3-dev_3.3.7-2_all.deb
sudo dpkg -i libeigen3-dev_3.3.7-2_all.deb
export DISPLAY=:99.0
sh -e /etc/init.d/xvfb start
@@ -196,40 +207,55 @@ before_install:
;;
"osx")
#xcodebuild -version -sdk
#brew --config
#if [ "${OSX_PORTS_CACHE}X" != "X" ]; then
# brew install jq
# cacheContext=$(create_helper_context repo=${OSX_PORTS_CACHE} auth_token=${GH_TOKEN} release=${FREECAD_RELEASE})
# travis_wait prime_local_ports_cache $cacheContext
#fi
#brew update >/dev/null
#brew --config
#brew tap FreeCAD/freecad
#brew install --verbose --only-dependencies freecad --with-packaging-utils
#pip install six
## Qt5: Set Qt5 build flag and CMAKE_PREFIX
#QT5_CMAKE_PREFIX=$(ls -d $(brew --cellar)/qt/*/lib/cmake)
#QT5_WEBKIT_CMAKE_PREFIX=$(ls -d $(brew --cellar)/qtwebkit/*/lib/cmake)
#CMAKE_OPTS="${CMAKE_OPTS} -DBUILD_QT5=ON -DCMAKE_PREFIX_PATH=${QT5_CMAKE_PREFIX};${QT5_WEBKIT_CMAKE_PREFIX}"
xcodebuild -version -sdk
brew --config
brew install ccache
brew install coreutils
brew update >/dev/null
brew --config
brew update
brew upgrade
brew install [email protected]
brew unlink [email protected]
brew link --overwrite --force [email protected]
rm /usr/local/bin/python
ln -s /usr/local/bin/python3 /usr/local/bin/python
pip3 install six
pip3 install pyyaml
pip3 install ply
export PATH=/usr/local/bin:$PATH
brew reinstall [email protected]
brew link --force [email protected]
which python
python --version
brew install boost
brew install boost-python3
brew tap FreeCAD/freecad
brew install freecad/freecad/coin
brew install freecad/freecad/nglib
brew install freecad/freecad/med-file
brew install freecad/freecad/opencamlib
brew install freecad/freecad/shiboken2
brew install freecad/freecad/pyside2
brew install freecad/freecad/pyside2-tools
brew install freecad/freecad/pivy
brew install freecad/freecad/matplotlib
##Install the 3DConnexion frameworks
#if [ "${DEPLOY}" == "1" ]; then
# if [ ! -d /Library/Frameworks/3DconnexionClient.framework ]; then
# curl -o /tmp/3dFW.dmg -L 'http://www.3dconnexion.com/index.php?eID=sdl&ext=tx_iccsoftware&oid=a273bdbc-c289-e10d-816b-567043331c9e&filename=3DxWareMac_v10-4-1_r2428.dmg'
# hdiutil attach -readonly /tmp/3dFW.dmg
# sudo installer -package /Volumes/3Dconnexion\ Software/Install\ 3Dconnexion\ software.pkg -target /
# diskutil eject /Volumes/3Dconnexion\ Software
# fi
# export CMAKE_OPTS="${CMAKE_OPTS} -DFREECAD_CREATE_MAC_APP=ON"
# export INSTALLED_APP_PATH="/usr/local/FreeCAD.app/Contents/MacOS/FreeCAD"
#else
# export INSTALLED_APP_PATH="/usr/local/MacOS/FreeCAD"
#fi
if [ ! -d /Library/Frameworks/3DconnexionClient.framework ]; then
curl -o /tmp/3dFW.dmg -L 'https://download.3dconnexion.com/drivers/mac/10-6-6_360DF97D-ED08-4ccf-A55E-0BF905E58476/3DxWareMac_v10-6-6_r3234.dmg'
hdiutil attach -readonly /tmp/3dFW.dmg
sudo installer -package /Volumes/3Dconnexion\ Software/Install\ 3Dconnexion\ software.pkg -target /
diskutil eject /Volumes/3Dconnexion\ Software
fi
export CMAKE_OPTS="${CMAKE_OPTS} -DFREECAD_CREATE_MAC_APP=OFF"
export INSTALLED_APP_PATH="/usr/local/MacOS/FreeCAD"
#export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_USE_EXTERNAL_KDL=ON"
export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_USE_EXTERNAL_KDL=ON"
brew link --overwrite matplotlib
if [ -f "/usr/local/Cellar/opencascade/7.4.0_1/include/opencascade/Standard_Macro.hxx" ]; then
sed '1,$s/\[\[nodiscard\]\]//' /usr/local/Cellar/opencascade/7.4.0_1/include/opencascade/Standard_Macro.hxx > /tmp/Standard_Macro.hxx && cp /tmp/Standard_Macro.hxx /usr/local/Cellar/opencascade/7.4.0_1/include/opencascade/Standard_Macro.hxx ;
fi
;;
"windows")
@@ -245,12 +271,12 @@ before_install:
# clcache stats before compilation
cmd.exe //C 'C:\Users\travis\build\FreeCAD\FreeCAD\clcache.exe -s'
curl -L https://github.com/FreeCAD/FreeCAD/releases/download/0.19_pre/FreeCADLibs_12.1.4_x64_VC15.7z --output FreeCADLibs.7z
curl -L https://github.com/FreeCAD/FreeCAD/releases/download/0.19.1/FreeCADLibs_12.5.3_x64_VC17.7z --output FreeCADLibs.7z
7z x FreeCADLibs.7z -oFreeCADLibs > /dev/null
rm -f FreeCADLibs.7z
export FREECAD_LIBPACK_DIR="$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.1.4_x64_VC15"
export FREECAD_LIBPACK_DIR="$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.5.3_x64_VC17"
export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_LIBPACK_DIR=$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.1.4_x64_VC15 -DPYTHON_EXECUTABLE=$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.1.4_x64_VC15\bin\python.exe \
export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_LIBPACK_DIR=$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.5.3_x64_VC17 -DPYTHON_EXECUTABLE=$TRAVIS_BUILD_DIR\FreeCADLibs\FreeCADLibs_12.5.3_x64_VC17\bin\python.exe \
-DBUILD_QT5=TRUE"
export PATH=$MSBUILD_PATH:$PATH
;;
@@ -265,7 +291,9 @@ install:
####
# Build FreeCAD with cmake options set above for each platform
##
- mkdir build && cd build && cmake -G"${GENERATOR}" ${CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ../
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export PATH="/usr/local/bin:/usr/local/opt/ccache/libexec:$PATH"; fi
- echo ${CMAKE_ARGS}
- mkdir build && cd build && cmake -Wno-dev -G"${GENERATOR}" ${CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ../
script:
####
@@ -280,7 +308,7 @@ script:
cmd.exe //C 'C:\Users\travis\build\FreeCAD\FreeCAD\.travis\build.bat'
# ls -lahR
mkdir bin/
mv ../FreeCADLibs/FreeCADLibs_12.1.4_x64_VC15/bin/* bin/
mv ../FreeCADLibs/FreeCADLibs_12.5.3_x64_VC17/bin/* bin/
du -hs bin/
# show clcache hit stats
cmd.exe //C 'C:\Users\travis\build\FreeCAD\FreeCAD\clcache.exe -s'
@@ -294,9 +322,12 @@ script:
# Stop compiling (GCC) after 2 hrs 50 min (3 hrs limit).
# Preserves created ccache for the next build job.
# if [ "${TRAVIS_OS_NAME}" == "linux" ]; then sudo timeout -k 175m 170m make -j2 install || true; fi
# if [ "${TRAVIS_OS_NAME}" == "osx" ]; then sudo make -j2 install; fi
# if [ "${TRAVIS_OS_NAME}" == "osx" ]; then sudo gtimeout -s KILL make -j2 install; fi
cat $HOME/.ccache/ccache.conf
ccache -z -s
df -h
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then export PATH="/usr/local/opt/ccacche/libexec:$PATH"; sudo gtimeout -s KILL 7200 make -j2; [ $? == 124 ] && { ccache -s; return 0; } fi
if [ "${TRAVIS_OS_NAME}" == "linux" ]; then sudo timeout -k 175m 170m make -j2 install || true; fi
sudo make -j2 install
ccache -s
${INSTALLED_APP_PATH} --console --run-test 0 || travis_terminate 1
+38
View File
@@ -0,0 +1,38 @@
# Building FreeCAD on Mac OS 10.15.x -- Catalina #
General notes on how the tooling works:
This setup uses [conda](https://docs.conda.io) for dependency management.
Conda is able to pull the deps from a repository called conda-forge and
setup an isolated build environment. Not quite as isolated as docker, but
it is a good option for Mac and its what the FreeCAD CI system uses.
Once the dependencies are installed into a conda environment, then the
build uses the standard `cmake` configuration process to configure the build
and `ninja` to invoke the actual compilation against whatever host compiler
(gcc, clang, etc.) was installed by conda's `cxx-compiler` package for
that architecture.
All of this, and some sanity checks, are in a unified shell script. See below.
# Directions #
## Install XCode Command line tools ##
Run `xcode-select --install` and click through.
## Install Conda ##
Refer to [MiniConda Docs](https://docs.conda.io/en/latest/miniconda.html).
## Run the shell script ##
Run the `./build_unix_dev_conda.sh` and go get coffee. Builds take
an hour+ on a 2012 Retina MacBook.
Output binaries will be in the `./build/bin/FreeCAD` *and*
`${CONDA_PREFIX}/bin/FreeCAD` directories.
You can code/build/test using the cmake configuration folder `./build` in
the standard way *from within the freecad_dev conda environment*.
+19 -21
View File
@@ -1,21 +1,12 @@
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
# March 2021, the oldest we have to support : Ununtu 18.04 LTS
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
if(POLICY CMP0020)
cmake_policy(SET CMP0020 NEW)
endif(POLICY CMP0020)
# added in cmake 3.0
if(POLICY CMP0050)
cmake_policy(SET CMP0050 NEW)
endif(POLICY CMP0050)
if (POLICY CMP0045)
cmake_policy(SET CMP0045 NEW)
endif(POLICY CMP0045)
if (POLICY CMP0072)
cmake_policy(SET CMP0072 OLD)
endif(POLICY CMP0072)
endif(COMMAND cmake_policy)
# policy CMP0072 was introduced with CMake 3.11
# relates to FindOpenGL module
# and cache variables OPENGL_gl_LIBRARY, OPENGL_glu_LIBRARY
if (POLICY CMP0072)
cmake_policy(SET CMP0072 OLD)
endif(POLICY CMP0072)
find_program(CCACHE_PROGRAM ccache) #This check should occur before project()
if(CCACHE_PROGRAM)
@@ -26,8 +17,8 @@ project(FreeCAD)
set(PACKAGE_VERSION_NAME "Vulcan")
set(PACKAGE_VERSION_MAJOR "0")
set(PACKAGE_VERSION_MINOR "19")
set(PACKAGE_VERSION_PATCH "16100")
set(PACKAGE_VERSION_MINOR "20")
set(PACKAGE_VERSION_PATCH "0")
set(PACKAGE_VERSION_SUFFIX "dev") # either "dev" for development snapshot or "" (empty string)
set(FREECAD_VERSION_PATCH "0") # number of patch release (e.g. "4" for the 0.18.4 release)
@@ -36,6 +27,7 @@ set(PACKAGE_VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE
set(PACKAGE_STRING "${PROJECT_NAME} ${PACKAGE_VERSION}")
# include local modules
include(CheckCXXCompilerFlag)
include(AddFileDependencies)
include(cMake/FreeCadMacros.cmake)
# include helper functions/macros
@@ -48,16 +40,23 @@ ConfigureCMakeVariables()
InitializeFreeCADBuildOptions()
CheckInterModuleDependencies()
FreeCADLibpackChecks()
SetupDoxygen()
if(NOT FREECAD_LIBPACK_USE OR FREECAD_LIBPACK_CHECKFILE_CLBUNDLER)
SetupPython()
SetupPCL()
SetupPybind11()
SetupBoost()
SetupXercesC()
find_package(ZLIB REQUIRED)
find_package(PyCXX REQUIRED)
SetupOpenCasCade()
if(BUILD_GUI)
# Do this before the check for SMESH because it depends on vtk
# that may have its own OpenGL check but possibly fails and leaves
# OPENGL_gl_LIBRARY empty that results into linker errors
SetupOpenGL()
endif(BUILD_GUI)
SetupSalomeSMESH()
SetupBoost()
if (BUILD_FEM_NETGEN)
find_package(NETGEN)
endif(BUILD_FEM_NETGEN)
@@ -71,7 +70,6 @@ if(NOT FREECAD_LIBPACK_USE OR FREECAD_LIBPACK_CHECKFILE_CLBUNDLER)
SetupFreetype()
if(BUILD_GUI)
SetupOpenGL()
SetupCoin3D()
SetupSpaceball()
SetupShibokenAndPyside()
+40
View File
@@ -9,5 +9,45 @@
# include <${OCC_INCLUDE_DIR}/Standard_Version.hxx>
#endif
/* No need for Boost (version info is always included in the source) */
/* No need for Coin (version info is always included in the source) */
/* No need for Python (version info is always included in the source) */
/* No need for Qt (version info is always included in the source) */
/* No need for zlib (version info is always included in the source) */
// No CMake version info for SMESH, libarea, Zipios, or KDL
// Eigen3
constexpr char * FC_EIGEN3_VERSION = "${EIGEN3_VERSION}";
// FreeType
constexpr char * FC_FREETYPE_VERSION = "${FREETYPE_VERSION_STRING}";
// pcl
constexpr char * FC_PCL_VERSION = "${PCL_VERSION}";
// PyCXX
constexpr char * FC_PYCXX_VERSION = "${PYCXX_VERSION}";
// PySide
constexpr char * FC_PYSIDE_VERSION = "${PySide2_VERSION}";
// PyBind
constexpr char * FC_PYBIND11_VERSION = "${pybind11_VERSION}";
// Shiboken
constexpr char * FC_SHIBOKEN_VERSION = "${Shiboken2_VERSION}";
// vtk
constexpr char * FC_VTK_VERSION = "${VTK_VERSION}";
// Xerces-C
constexpr char * FC_XERCESC_VERSION = "${XercesC_VERSION}";
// Pivy
constexpr char * FC_PIVY_VERSION = "${PIVY_VERSION}";
#endif // LIBRARY_VERSIONS_H
+58 -40
View File
@@ -3,21 +3,15 @@
### Your own 3D parametric modeler
[Website](https://www.freecadweb.org) •
[Documentation](https://www.freecadweb.org/wiki/) •
[Documentation](https://wiki.freecadweb.org) •
[Forum](https://forum.freecadweb.org/) •
[Bug tracker](https://www.freecadweb.org/tracker/) •
[Git repository](https://github.com/FreeCAD/FreeCAD)
[![Release](https://img.shields.io/github/release/freecad/freecad.svg)](https://github.com/freecad/freecad/releases/latest) [![Master][freecad-master-status]][travis-branches] [![Crowdin](https://d322cqt584bo4o.cloudfront.net/freecad/localized.svg)](https://crowdin.com/project/freecad) [![Gitter](https://img.shields.io/gitter/room/freecad/freecad.svg)](https://gitter.im/freecad/freecad?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/FreeCAD/FreeCAD.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/FreeCAD/FreeCAD/context:python)
[![Release](https://img.shields.io/github/release/freecad/freecad.svg)](https://github.com/freecad/freecad/releases/latest) [![Master][freecad-master-status]][travis-branches] [![Crowdin](https://d322cqt584bo4o.cloudfront.net/freecad/localized.svg)](https://crowdin.com/project/freecad) [![Gitter](https://img.shields.io/gitter/room/freecad/freecad.svg)](https://gitter.im/freecad/freecad?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/FreeCAD/FreeCAD.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/FreeCAD/FreeCAD/context:python) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/FreeCAD/FreeCAD.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/FreeCAD/FreeCAD/context:cpp) [![Liberapay](https://img.shields.io/liberapay/receives/FreeCAD.svg?logo=liberapay)](https://liberapay.com/FreeCAD)
<p>
<a href="https://www.digitalocean.com/?utm_medium=opensource&utm_source=FreeCAD">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/PoweredByDO/DO_Powered_by_Badge_blue.svg" width="201px">
</a>
</p>
![screenshot](http://www.freecadweb.org/wiki/images/thumb/7/72/Freecad016_screenshot1.jpg/800px-Freecad016_screenshot1.jpg)
![screenshot](https://wiki.freecadweb.org/images/thumb/7/72/Freecad016_screenshot1.jpg/800px-Freecad016_screenshot1.jpg)
Overview
--------
@@ -25,46 +19,45 @@ Overview
* **Freedom to build what you want** FreeCAD is an open-source parametric 3D
modeler made primarily to design real-life objects of any size.
Parametric modeling allows you to easily modify your design by going back into
your model history and changing its parameters.
your model history to change its parameters.
* **Create 3D from 2D & back** FreeCAD allows you to sketch geometry constrained
* **Create 3D from 2D and back** FreeCAD lets you to sketch geometry constrained
2D shapes and use them as a base to build other objects.
It contains many components to adjust dimensions or extract design details from
3D models to create high quality production ready drawings.
3D models to create high quality production-ready drawings.
* **Designed for your needs** FreeCAD is designed to fit a wide range of uses
including product design, mechanical engineering and architecture.
Whether you are a hobbyist, a programmer, an experienced CAD user,
a student or a teacher, you will feel right at home with FreeCAD.
including product design, mechanical engineering and architecture,
whether you are a hobbyist, programmer, experienced CAD user, student or teacher.
* **Cross platform** FreeCAD runs on Windows, Mac and Linux
* **Cross platform** FreeCAD runs on Windows, macOS and Linux operating systems.
* **Underlying technology**
* **OpenCASCADE** A powerful geometry kernel, the most important component of FreeCAD
* **Coin3D library** Open Inventor-compliant 3D scene representation model
* **Python** FreeCAD offers a broad Python API
* **Qt** Graphical User Interface built with Qt
* **Qt** Graphical user interface built with Qt
Installing
----------
Precompiled (installable) packages are available for Windows and Mac on the
Precompiled (installable) packages are available for Windows and macOS on the
[Releases page](https://github.com/FreeCAD/FreeCAD/releases).
On most Linux distributions, FreeCAD is directly installable from the
software center application.
Other options are described at the [wiki Download page](http://www.freecadweb.org/wiki/Download).
Other options are described at the [wiki Download page](https://wiki.freecadweb.org/Download).
Build Status <img src="https://blog.travis-ci.com/images/travis-mascot-200px.png" height="30"/>
Build Status
------------
| Master | 0.18 | Translation |
| Master | 0.19 | Translation |
|:------:|:----:|:-----------:|
|[![Master][freecad-master-status]][travis-branches]|[![0.18][freecad-0.18-status]][travis-branches]|[![Crowdin](https://d322cqt584bo4o.cloudfront.net/freecad/localized.svg)](https://crowdin.com/project/freecad)|
|[![Master][freecad-master-status]][travis-branches]|[![0.19][freecad-0.19-status]][travis-branches]|[![Crowdin](https://d322cqt584bo4o.cloudfront.net/freecad/localized.svg)](https://crowdin.com/project/freecad)|
[freecad-0.18-status]: https://travis-ci.org/FreeCAD/FreeCAD.svg?branch=releases/FreeCAD-0-18
[freecad-0.19-status]: https://travis-ci.org/FreeCAD/FreeCAD.svg?branch=releases/FreeCAD-0-19
[freecad-master-status]: https://travis-ci.org/FreeCAD/FreeCAD.svg?branch=master
[travis-branches]: https://travis-ci.org/FreeCAD/FreeCAD/branches
[travis-builds]: https://travis-ci.org/FreeCAD/FreeCAD/builds
@@ -73,20 +66,38 @@ Compiling
---------
Compiling FreeCAD requires installation of several libraries and their
development files such as OpenCASCADe, Coin and Qt, listed in the
pages below. Once this is done, FreeCAD can be simply compiled with
cMake. On Windows, these libraries are bundled and offered by the
development files such as OCCT (Open Cascade), Coin and Qt, listed in the
pages below. Once this is done, FreeCAD can be compiled with
CMake. On Windows, these libraries are bundled and offered by the
FreeCAD team in a convenient package. On Linux, they are usually found
in your distribution's repositories, and on Mac OSX and other platforms
you will usually need to compile them yourself.
in your distribution's repositories, and on macOS and other platforms,
you will usually have to compile them yourself.
The pages below contain up-to-date build instructions:
- [Linux](http://www.freecadweb.org/wiki/CompileOnUnix)
- [Windows](http://www.freecadweb.org/wiki/CompileOnWindows)
- [Mac OSX](http://www.freecadweb.org/wiki/CompileOnMac)
- [Cygwin](http://www.freecadweb.org/wiki/CompileOnCygwin)
- [MinGW](http://www.freecadweb.org/wiki/CompileOnMinGW)
- [Linux](https://wiki.freecadweb.org/Compile_on_Linux)
- [Windows](https://wiki.freecadweb.org/Compile_on_Windows)
- [macOS](https://wiki.freecadweb.org/Compile_on_MacOS)
- [Cygwin](https://wiki.freecadweb.org/Compile_on_Cygwin)
- [MinGW](https://wiki.freecadweb.org/Compile_on_MinGW)
Reporting Issues
---------
To report an issue please:
- First post to forum to verify the issue;
- Link forum thread to bug tracker ticket and vice-a-versa;
- Use the most updated stable or development versions of FreeCAD;
- Post version info from eg. `Help > About FreeCAD > Copy to clipboard`;
- Post a Step-By-Step explanation on how to recreate the issue;
- Upload an example file to demonstrate problem.
For more detail see:
- [Wiki Page about the Bug Tracker](https://wiki.freecadweb.org/Tracker)
- [Bug Tracker](https://tracker.freecadweb.org)
- [Help Forum](http://forum.freecadweb.org/viewforum.php?f=3)
Usage & Getting help
--------------------
@@ -95,13 +106,20 @@ The FreeCAD wiki contains documentation on
general FreeCAD usage, Python scripting, and development. These
pages might help you get started:
- [Getting started](http://www.freecadweb.org/wiki/Getting_started)
- [Features list](http://www.freecadweb.org/wiki/Feature_list)
- [Frequent questions](http://www.freecadweb.org/wiki/FAQ)
- [Workbenches](http://www.freecadweb.org/wiki/Workbench_Concept)
- [Scripting](http://www.freecadweb.org/wiki/Power_users_hub)
- [Development](http://www.freecadweb.org/wiki/Developer_hub)
- [Getting started](https://wiki.freecadweb.org/Getting_started)
- [Features list](https://wiki.freecadweb.org/Feature_list)
- [Frequent questions](https://wiki.freecadweb.org/FAQ/en)
- [Workbenches](https://wiki.freecadweb.org/Workbenches)
- [Scripting](https://wiki.freecadweb.org/Power_users_hub)
- [Development](https://wiki.freecadweb.org/Developer_hub)
The [FreeCAD forum](http://forum.freecadweb.org) is also a great place
The [FreeCAD forum](https://forum.freecadweb.org) is also a great place
to find help and solve specific problems you might encounter when
learning to use FreeCAD.
<p>This project receives generous infrastructure support from
<a href="https://www.digitalocean.com/">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="91px">
</a> and <a href="https://www.kipro-pcb.com/">KiCad Services Corp.</a>
</p>
+91
View File
@@ -0,0 +1,91 @@
##!/usr/bin/env bash
#
# MacOS Build Script for FreeCAD using Conda.
# This is intended for developer use.
#
# Copyright (c) 2020 by Jeffrey Zampieron. All rights reserved.
#
# License: LGPLv2.1
#
# References:
# - Conda: https://conda.io/projects/conda/en/latest/user-guide/install/index.html
# - Conda Build: https://docs.conda.io/projects/conda-build/en/latest/install-conda-build.html
###########################################################################
# Script wide setup.
###########################################################################
# The Conda environment name
FCENV=freecad_dev
# The cmake build directory
HOST=$(uname)
###########################################################################
# Env Checks
###########################################################################
if [[ ${HOST} =~ "Linux" ]]; then
# Linux specific checks here
echo "Linux specific checks..."
elif [[ ${HOST} =~ "Darwin" ]]; then
# OSX specific checks here.
echo "OS X specific checks..."
which xcrun
if [ $? != 0 ]; then
echo "xcrun not found... install XCode command line tools..."
echo "using: xcode-select --install"
exit 1
fi
else
echo "unknown host env... probably won't work. Aborting build."
exit 1
fi
###########################################################################
# Conda Setup
###########################################################################
which conda
if [ $? != 0 ]; then
echo "Failed to find conda executable. Please install."
exit 1
fi
if [[ "${CONDA_DEFAULT_ENV}" =~ "${FCENV}" ]]; then
echo "Already in env"
elif [[ -z "${CONDA_DEFAULT_ENV}" ]]; then
echo "Not in conda env... activating"
eval "$(conda shell.bash hook)"
conda activate ${FCENV}
else
# Assume we are in some other env.
echo "In ${CONDA_DEFAULT_ENV}, attempting switch to ${FCENV}"
eval "$(conda shell.bash hook)"
conda deactivate
conda activate ${FCENV}
fi
if [ $? != 0 ]; then
echo "Failed to activate conda env: ${FCENV} ... creating"
if [[ ${HOST} =~ "Linux" ]]; then
echo "Linux"
conda env create -f environment-linux.yml
elif [[ ${HOST} =~ "Darwin" ]]; then
echo "OS X"
conda env create -f environment-osx.yml
else
echo "Unknown Host: ${HOST}"
exit 1
fi
conda activate ${FCENV}
if [ $? != 0 ]; then
echo "Failed to create conda environment and activate it."
exit 1
fi
fi
if [ -z "${CONDA_PREFIX}" ]; then
echo "Failed to find CONDA_PREFIX variable."
exit 1
fi
PREFIX="${CONDA_PREFIX}" ./conda/build.sh
+16
View File
@@ -105,5 +105,21 @@ ENDIF (WIN32)
IF(COIN3D_LIBRARIES)
SET( COIN3D_FOUND "YES" )
message(STATUS "Coin3D libraries found")
IF(NOT COIN3D_VERSION)
file(READ "${COIN3D_INCLUDE_DIRS}/Inventor/C/basic.h" _coin3d_basic_h)
string(REGEX MATCH "define[ \t]+COIN_MAJOR_VERSION[ \t]+([0-9?])" _coin3d_major_version_match "${_coin3d_basic_h}")
set(COIN3D_MAJOR_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+COIN_MINOR_VERSION[ \t]+([0-9?])" _coin3d_minor_version_match "${_coin3d_basic_h}")
set(COIN3D_MINOR_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+COIN_MICRO_VERSION[ \t]+([0-9?])" _coin3d_micro_version_match "${_coin3d_basic_h}")
set(COIN3D_MICRO_VERSION "${CMAKE_MATCH_1}")
set(COIN3D_VERSION "${COIN3D_MAJOR_VERSION}.${COIN3D_MINOR_VERSION}.${COIN3D_MICRO_VERSION}")
ENDIF()
IF(NOT PIVY_VERSION)
execute_process (COMMAND ${Python3_EXECUTABLE} -c "import pivy as p; print(p.__version__,end='')" OUTPUT_VARIABLE PIVY_VERSION)
ENDIF()
ENDIF(COIN3D_LIBRARIES)
+7 -5
View File
@@ -23,18 +23,19 @@ IF (COIN3D_FOUND)
find_path(COIN3D_DOC_PATH index.html
/usr/share/doc/libcoin80-doc/html
/usr/share/doc/coin/html
/usr/share/doc/Coin/html
)
IF( EXISTS ${COIN3D_DOC_PATH})
message(STATUS "Coin3D doc is installed")
find_file(COIN3D_DOC_TAGFILE coin.tag Coin.tag
${COIN3D_DOC_PATH}
find_file(COIN3D_DOC_TAGFILE NAMES coin.tag Coin.tag
PATHS ${COIN3D_DOC_PATH}
)
IF( EXISTS ${COIN3D_DOC_TAGFILE})
SET( COIN3D_DOC_FOUND "YES"
)
ELSE( EXISTS ${COIN3D_DOC_TAGFILE})
find_file(COIN3D_DOC_TAGFILE_GZ coin.tag.gz Coin.tag.gz
${COIN3D_DOC_PATH}
find_file(COIN3D_DOC_TAGFILE_GZ NAMES coin.tag.gz Coin.tag.gz
PATHS ${COIN3D_DOC_PATH}
)
IF( EXISTS ${COIN3D_DOC_TAGFILE_GZ})
message(STATUS " Found ${COIN3D_DOC_TAGFILE_GZ}")
@@ -85,4 +86,5 @@ if(COIN3D_DOC_FOUND)
message(STATUS " Location: ${COIN3D_DOC_PATH}")
endif(COIN3D_DOC_FOUND)
# export for others
SET( COIN3D_DOC_FOUND "${COIN3D_DOC_FOUND}" CACHE BOOL "Coin3d documentation available")
+12
View File
@@ -5,6 +5,7 @@
# MEDFILE_LIBRARIES
# MEDFILE_C_LIBRARIES
# MEDFILE_F_LIBRARIES
# MEDFILE_VERSION
#
# The CMake (or environment) variable MEDFILE_ROOT_DIR can be set to
# guide the detection and indicate a root directory to look into.
@@ -56,3 +57,14 @@ ENDIF(MEDFILE_F_LIBRARIES)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MEDFile REQUIRED_VARS MEDFILE_INCLUDE_DIRS MEDFILE_LIBRARIES)
IF(meddotH)
FILE(READ "${meddotH}" _med_h)
STRING(REGEX MATCH "define[ \t]+MED_MAJOR_NUM[ \t]+([0-9?])" _med_major_version_match "${_med_h}")
SET(MED_MAJOR_VERSION "${CMAKE_MATCH_1}")
STRING(REGEX MATCH "define[ \t]+MED_MINOR_NUM[ \t]+([0-9?])" _med_minor_version_match "${_med_h}")
SET(MED_MINOR_VERSION "${CMAKE_MATCH_1}")
STRING(REGEX MATCH "define[ \t]+MED_RELEASE_NUM[ \t]+([0-9?])" _med_release_version_match "${_med_h}")
SET(MED_RELEASE_VERSION "${CMAKE_MATCH_1}")
SET(MEDFILE_VERSION "${MED_MAJOR_VERSION}.${MED_MINOR_VERSION}.${MED_RELEASE_VERSION}")
ENDIF()
+1 -1
View File
@@ -9,7 +9,7 @@
# MATPLOTLIB_VERSION_PATCH - the patch version number of matplotlib
# MATPLOTLIB_PATH_DIRS - path to the matplotlib include files
IF(PYTHONINTERP_FOUND)
IF(Python3_Interpreter_FOUND)
# Try to import matplotlib into Python interpreter. Python
# interpreter was found previously as required package, so
# don't take care about this.
+19 -15
View File
@@ -108,7 +108,7 @@ else(Netgen_FOUND)
IF(NOT NGLIB_INCLUDE_DIR AND NOT NETGEN_DIR_include)
MESSAGE(STATUS "Cannot find NETGEN header files.")
ELSE()
ELSEIF(NOT NETGEN_VERSION)
file(STRINGS ${NETGEN_DIR_include}/mydefs.hpp NETGEN_VERSION
REGEX "#define PACKAGE_VERSION.*"
)
@@ -129,23 +129,27 @@ endif(Netgen_FOUND)
# Package-provided cMake file is not enough
IF(Netgen_FOUND)
IF(NETGEN_VERSION)
string(REGEX MATCHALL "[0-9]+" NETGEN_VERSION_expr ${NETGEN_VERSION})
list(LENGTH NETGEN_VERSION_expr NETGEN_VERSION_COUNT)
list(GET NETGEN_VERSION_expr 0 NETGEN_VERSION_MAJOR)
IF(NETGEN_VERSION_COUNT GREATER 1)
list(GET NETGEN_VERSION_expr 1 NETGEN_VERSION_MINOR)
ELSE()
set(NETGEN_VERSION_MINOR 0)
ENDIF()
ELSE() # workaround for netgen 6.2 and newer. currently there is no easy way to detect the version
# better use "find_package(netgen CONFIG REQUIRED)"
set(NETGEN_VERSION_MAJOR 6)
set(NETGEN_VERSION_MINOR 2)
IF(NOT NETGEN_VERSION_MAJOR)
IF(NETGEN_VERSION)
string(REGEX MATCHALL "[0-9]+" NETGEN_VERSION_expr ${NETGEN_VERSION})
list(LENGTH NETGEN_VERSION_expr NETGEN_VERSION_COUNT)
list(GET NETGEN_VERSION_expr 0 NETGEN_VERSION_MAJOR)
IF(NETGEN_VERSION_COUNT GREATER 1)
list(GET NETGEN_VERSION_expr 1 NETGEN_VERSION_MINOR)
ELSE()
set(NETGEN_VERSION_MINOR 0)
ENDIF()
ELSE() # workaround for netgen 6.2 and newer. currently there is no easy way to detect the version
# better use "find_package(netgen CONFIG REQUIRED)"
set(NETGEN_VERSION_MAJOR 6)
set(NETGEN_VERSION_MINOR 2)
ENDIF()
set(NETGEN_VERSION_PATCH 0)
ENDIF()
MATH(EXPR NETGEN_VERSION_C "(${NETGEN_VERSION_MAJOR} << 16) + (${NETGEN_VERSION_MINOR} << 8)")
MATH(EXPR NETGEN_VERSION_C "(${NETGEN_VERSION_MAJOR} << 16) + (${NETGEN_VERSION_MINOR} << 8) + (${NETGEN_VERSION_PATCH})")
MATH(EXPR NETGEN_VERSION_62 "(6 << 16) + (2 << 8)")
MATH(EXPR NETGEN_VERSION_62_2004 "(6 << 16) + (2 << 8) + (2004)")
IF(NOT NETGEN_VERSION_C LESS NETGEN_VERSION_62) # Version >= 6.2
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang sometimes fails to include <cstdio>
+16 -3
View File
@@ -37,6 +37,12 @@ else(OCE_FOUND) #look for OpenCASCADE
# we first try to find opencascade directly:
if(NOT OCCT_CMAKE_FALLBACK)
find_package(OpenCASCADE CONFIG QUIET)
if(NOT (CMAKE_VERSION VERSION_LESS 3.6.0))
get_property(flags DIRECTORY PROPERTY COMPILE_DEFINITIONS)
# OCCT 7.5 adds this define that causes hundreds of compiler warnings with Qt5.x, so remove it again
list(FILTER flags EXCLUDE REGEX [[GL_GLEXT_LEGACY]])
set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS ${flags})
endif()
endif(NOT OCCT_CMAKE_FALLBACK)
if(OpenCASCADE_FOUND)
set(OCC_FOUND ${OpenCASCADE_FOUND})
@@ -125,32 +131,39 @@ if(OCC_FOUND)
TKSTL
TKShHealing
TKXSBase
TKBin
TKBool
TKBO
TKCDF
TKBRep
TKTopAlgo
TKGeomAlgo
TKGeomBase
TKOffset
TKPrim
TKSTEP
TKSTEPBase
TKSTEPAttr
TKSTEP209
TKSTEP
TKHLR
TKFeat
)
set(OCC_OCAF_LIBRARIES
TKBin
TKBinL
TKCAF
TKXCAF
TKLCAF
TKVCAF
TKCDF
TKXDESTEP
TKXDEIGES
TKMeshVS
TKService
TKV3d
)
if(OCC_VERSION_STRING VERSION_LESS 6.7.3)
list(APPEND OCC_OCAF_LIBRARIES TKAdvTools)
elseif(NOT OCC_VERSION_STRING VERSION_LESS 7.5.0)
list(APPEND OCC_OCAF_LIBRARIES TKRWMesh)
endif(OCC_VERSION_STRING VERSION_LESS 6.7.3)
message(STATUS "-- Found OCE/OpenCASCADE version: ${OCC_VERSION_STRING}")
message(STATUS "-- OCE/OpenCASCADE include directory: ${OCC_INCLUDE_DIR}")
+1
View File
@@ -5,6 +5,7 @@
# PYCXX_SOURCE_DIR
# PYCXX_FOUND
# PYCXX_SOURCES
# PYCXX_VERSION
#
# The PYCXX_*_DIR variables can be set to tell this module where
# the files are.
+7 -7
View File
@@ -27,15 +27,15 @@ FIND_PACKAGE(Qt5Core)
IF(Qt5Core_VERSION VERSION_LESS 5.14)
# Legacy (< 5.14)
FIND_PROGRAM(PYSIDE2UICBINARY NAMES python2-pyside2-uic pyside2-uic pyside2-uic-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} HINTS ${PYSIDE_BIN_DIR})
FIND_PROGRAM(PYSIDE2RCCBINARY NAMES pyside2-rcc pyside2-rcc-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} HINTS ${PYSIDE_BIN_DIR})
FIND_PROGRAM(PYSIDE2UICBINARY NAMES python2-pyside2-uic pyside2-uic pyside2-uic-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} pyuic5 HINTS ${PYSIDE_BIN_DIR})
FIND_PROGRAM(PYSIDE2RCCBINARY NAMES pyside2-rcc pyside2-rcc-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} pyrcc5 HINTS ${PYSIDE_BIN_DIR})
set(UICOPTIONS "")
set(RCCOPTIONS "")
ELSE(Qt5Core_VERSION VERSION_LESS 5.14)
# New (>= 5.14)
FIND_PROGRAM(PYSIDE2UICBINARY NAMES uic-qt5 uic)
FIND_PROGRAM(PYSIDE2UICBINARY NAMES uic-qt5 uic pyside2-uic)
set(UICOPTIONS "--generator=python")
FIND_PROGRAM(PYSIDE2RCCBINARY NAMES rcc-qt5 rcc)
FIND_PROGRAM(PYSIDE2RCCBINARY NAMES rcc-qt5 rcc pyside2-rcc)
set(RCCOPTIONS "--generator=python" "--compress-algo=zlib" "--compress=1")
ENDIF(Qt5Core_VERSION VERSION_LESS 5.14)
@@ -55,10 +55,10 @@ MACRO(PYSIDE_WRAP_UI outfiles)
else()
# Especially on Open Build Service we don't want changing date like
# pyside2-uic generates in comments at beginning., which is why
# we follow the tool command with in-place sed.
# we follow the tool command with a POSIX-friendly sed.
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND "${PYSIDE2UICBINARY}" ${UICOPTIONS} "${infile}" -o "${outfile}"
COMMAND sed -i "/^# /d" "${outfile}"
COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
MAIN_DEPENDENCY "${infile}"
)
endif()
@@ -85,7 +85,7 @@ MACRO(PYSIDE_WRAP_RC outfiles)
# we follow the tool command with in-place sed.
ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
COMMAND "${PYSIDE2RCCBINARY}" ${RCCOPTIONS} "${infile}" ${PY_ATTRIBUTE} -o "${outfile}"
COMMAND sed -i "/^# /d" "${outfile}"
COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
MAIN_DEPENDENCY "${infile}"
)
endif()
-101
View File
@@ -1,101 +0,0 @@
# Try to find PySide utilities, PYSIDEUIC4 and PYSIDERCC4:
# PYSIDEUIC4BINARY - Location of PYSIDEUIC4 executable
# PYSIDERCC4BINARY - Location of PYSIDERCC4 executable
# PYSIDE_TOOLS_FOUND - PySide utilities found.
# Also provides macro similar to FindQt4.cmake's WRAP_UI and WRAP_RC,
# for the automatic generation of Python code from Qt4's user interface
# ('.ui') and resource ('.qrc') files. These macros are called:
# - PYSIDE_WRAP_UI
# - PYSIDE_WRAP_RC
IF(PYSIDEUIC4BINARY AND PYSIDERCC4BINARY)
# Already in cache, be silent
set(PYSIDE_TOOLS_FOUND_QUIETLY TRUE)
ENDIF(PYSIDEUIC4BINARY AND PYSIDERCC4BINARY)
if(WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
#pyside tools are often in same location as python interpreter
get_filename_component(PYTHON_BIN_DIR ${PYTHON_EXECUTABLE} PATH)
set(PYSIDE_BIN_DIR ${PYTHON_BIN_DIR})
endif(WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
FIND_PROGRAM(PYSIDEUIC4BINARY NAMES python2-pyside-uic pyside-uic pyside-uic-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} HINTS ${PYSIDE_BIN_DIR})
FIND_PROGRAM(PYSIDERCC4BINARY NAMES pyside-rcc pyside-rcc-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} HINTS ${PYSIDE_BIN_DIR})
MACRO(PYSIDE_WRAP_UI outfiles)
FOREACH(it ${ARGN})
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py)
#ADD_CUSTOM_TARGET(${it} ALL
# DEPENDS ${outfile}
#)
if(WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${PYSIDEUIC4BINARY} ${infile} -o ${outfile}
MAIN_DEPENDENCY ${infile}
)
else(WIN32)
# Especially on Open Build Service we don't want changing date like
# pyside-uic generates in comments at beginning, which is why
# we follow the tool command with in-place sed.
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND "${PYSIDEUIC4BINARY}" "${infile}" -o "${outfile}"
COMMAND sed -i "/^# /d" "${outfile}"
MAIN_DEPENDENCY "${infile}"
)
endif(WIN32)
list(APPEND ${outfiles} ${outfile})
ENDFOREACH(it)
ENDMACRO (PYSIDE_WRAP_UI)
MACRO(PYSIDE_WRAP_RC outfiles)
FOREACH(it ${ARGN})
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
SET(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py")
#ADD_CUSTOM_TARGET(${it} ALL
# DEPENDS ${outfile}
#)
if (${PYTHON_VERSION_MAJOR} LESS 3)
SET(PY_ATTRIBUTE "")
else (${PYTHON_VERSION_MAJOR} LESS 3)
SET(PY_ATTRIBUTE "-py3")
endif (${PYTHON_VERSION_MAJOR} LESS 3)
if(WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${PYSIDERCC4BINARY} ${infile} ${PY_ATTRIBUTE} -o ${outfile}
MAIN_DEPENDENCY ${infile}
)
else(WIN32)
# Especially on Open Build Service we don't want changing date like
# pyside-rcc generates in comments at beginning, which is why
# we follow the tool command with in-place sed.
ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
COMMAND "${PYSIDERCC4BINARY}" "${infile}" ${PY_ATTRIBUTE} -o "${outfile}"
COMMAND sed -i "/^# /d" "${outfile}"
MAIN_DEPENDENCY "${infile}"
)
endif(WIN32)
list(APPEND ${outfiles} ${outfile})
ENDFOREACH(it)
ENDMACRO (PYSIDE_WRAP_RC)
IF(EXISTS ${PYSIDEUIC4BINARY} AND EXISTS ${PYSIDERCC4BINARY})
set(PYSIDE_TOOLS_FOUND TRUE)
ENDIF(EXISTS ${PYSIDEUIC4BINARY} AND EXISTS ${PYSIDERCC4BINARY})
if(PYSIDERCC4BINARY AND PYSIDEUIC4BINARY)
if (NOT PySideTools_FIND_QUIETLY)
message(STATUS "Found PySide Tools: ${PYSIDEUIC4BINARY}, ${PYSIDERCC4BINARY}")
endif (NOT PySideTools_FIND_QUIETLY)
else(PYSIDERCC4BINARY AND PYSIDEUIC4BINARY)
if(PySideTools_FIND_REQUIRED)
message(FATAL_ERROR "PySideTools could not be found, but are required.")
else(PySideTools_FIND_REQUIRED)
if (NOT PySideTools_FIND_QUIETLY)
message(STATUS "PySideTools: not found.")
endif (NOT PySideTools_FIND_QUIETLY)
endif(PySideTools_FIND_REQUIRED)
endif(PYSIDERCC4BINARY AND PYSIDEUIC4BINARY)
-164
View File
@@ -1,164 +0,0 @@
# - Try to find Windows Installer XML
# See http://wix.sourceforge.net
#
# The following variables are optionally searched for defaults
# WIX_ROOT_DIR: Base directory of WIX2 tree to use.
#
# The following are set after configuration is done:
# WIX_FOUND
# WIX_ROOT_DIR
# WIX_CANDLE
# WIX_LIGHT
#
# 2009/02 Petr Pytelka (pyta at lightcomp.cz)
#
MACRO(DBG_MSG _MSG)
# MESSAGE(STATUS "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}):\n ${_MSG}")
ENDMACRO(DBG_MSG)
# typical root dirs of installations, exactly one of them is used
SET (WIX_POSSIBLE_ROOT_DIRS
"${WIX_ROOT_DIR}"
"$ENV{WIX_ROOT_DIR}"
"$ENV{ProgramFiles}/Windows Installer XML"
)
#DBG_MSG("DBG (WIX_POSSIBLE_ROOT_DIRS=${WIX_POSSIBLE_ROOT_DIRS}")
#
# select exactly ONE WIX base directory/tree
# to avoid mixing different version headers and libs
#
FIND_PATH(WIX_ROOT_DIR
NAMES
bin/candle.exe
bin/light.exe
PATHS ${WIX_POSSIBLE_ROOT_DIRS})
DBG_MSG("WIX_ROOT_DIR=${WIX_ROOT_DIR}")
#
# Logic selecting required libs and headers
#
SET(WIX_FOUND OFF)
IF(WIX_ROOT_DIR)
SET(WIX_FOUND ON)
ENDIF(WIX_ROOT_DIR)
# display help message
IF(NOT WIX_FOUND)
# make FIND_PACKAGE friendly
IF(NOT WIX_FIND_QUIETLY)
IF(WIX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR
"Windows Installer XML required but some files not found. Please specify it's location with WIX_ROOT_DIR env. variable.")
ELSE(WIX_FIND_REQUIRED)
MESSAGE(STATUS
"ERROR: Windows Installer XML was not found.")
ENDIF(WIX_FIND_REQUIRED)
ENDIF(NOT WIX_FIND_QUIETLY)
ELSE(NOT WIX_FOUND)
SET(WIX_CANDLE ${WIX_ROOT_DIR}/bin/candle.exe)
SET(WIX_LIGHT ${WIX_ROOT_DIR}/bin/light.exe)
# MESSAGE(STATUS "Windows Installer XML found.")
ENDIF(NOT WIX_FOUND)
MARK_AS_ADVANCED(
WIX_ROOT_DIR
WIX_CANDLE
WIX_LIGHT
)
#
# Call wix compiler
#
# Parameters:
# _sources - name of list with sources
# _obj - name of list for target objects
#
MACRO(WIX_COMPILE _sources _objs _extra_dep)
DBG_MSG("WIX compile: ${${_sources}}")
FOREACH (_current_FILE ${${_sources}})
GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
SET (SOURCE_WIX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_current_FILE} )
DBG_MSG("WIX source file: ${SOURCE_WIX_FILE}")
# Check whether source exists
IF(EXISTS ${SOURCE_WIX_FILE})
ELSE(EXISTS ${SOURCE_WIX_FILE})
MESSAGE(FATAL_ERROR "Path not exists: ${SOURCE_WIX_FILE}")
ENDIF(EXISTS ${SOURCE_WIX_FILE})
SET (OUTPUT_WIXOBJ ${_basename}.wixobj )
DBG_MSG("WIX output: ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_WIXOBJ}")
DBG_MSG("WIX command: ${WIX_CANDLE}")
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_WIXOBJ}
COMMAND ${WIX_CANDLE}
ARGS ${WIX_CANDLE_FLAGS} ${SOURCE_WIX_FILE}
DEPENDS ${SOURCE_WIX_FILE} ${${_extra_dep}}
COMMENT "Compiling ${SOURCE_WIX_FILE} -> ${OUTPUT_WIXOBJ}"
)
SET(${_objs} ${${_objs}} ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_WIXOBJ} )
DBG_MSG("WIX compile output: ${${_objs}}")
ENDFOREACH (_current_FILE)
ENDMACRO(WIX_COMPILE)
#
# Call wix compiler
#
# Parameters:
# _sources - name of list with sources
# _obj - name of list for target objects
#
MACRO(WIX_COMPILE_ALL _target _sources _extra_dep)
DBG_MSG("WIX compile all: ${${_sources}}, dependencies: ${${_extra_dep}}")
ADD_CUSTOM_COMMAND(
OUTPUT ${_target}
COMMAND ${WIX_CANDLE}
ARGS ${WIX_CANDLE_FLAGS} -out "${_target}" ${${_sources}}
DEPENDS ${${_sources}} ${${_extra_dep}}
COMMENT "Compiling ${${_sources}} -> ${_target}"
)
ENDMACRO(WIX_COMPILE_ALL)
#
# Link MSI file
#
# Parameters
# _target - Name of target file
# _sources - Name of list with sources
#
MACRO(WIX_LINK _target _sources _loc_files)
DBG_MSG("WIX command: ${WIX_LIGHT}\n WIX target: ${_target} objs: ${${_sources}}")
SET( WIX_LINK_FLAGS_A "" )
# Add localization
FOREACH (_current_FILE ${${_loc_files}})
SET( WIX_LINK_FLAGS_A ${WIX_LINK_FLAGS_A} -loc "${_current_FILE}" )
DBG_MSG("WIX link localization: ${_current_FILE}")
ENDFOREACH (_current_FILE)
DBG_MSG("WIX link flags: ${WIX_LINK_FLAGS_A}")
ADD_CUSTOM_COMMAND(
OUTPUT ${_target}
COMMAND ${WIX_LIGHT}
ARGS ${WIX_LINK_FLAGS_A} -out "${_target}" ${${_sources}}
DEPENDS ${${_sources}}
COMMENT "Linking ${${_sources}} -> ${_target}"
)
ENDMACRO(WIX_LINK)
-51
View File
@@ -1,51 +0,0 @@
# Locate Xerces-C include paths and libraries
# Xerces-C can be found at http://xml.apache.org/xerces-c/
# Written by Frederic Heem, frederic.heem _at_ telsey.it
# Modified by Jos van den Oever
# This module defines
# XercesC_INCLUDE_DIRS, where to find ptlib.h, etc.
# XercesC_LIBRARIES, the libraries to link against to use pwlib.
# XercesC_FOUND, If false, don't try to use pwlib.
FIND_PATH(XercesC_INCLUDE_DIRS xercesc/dom/DOM.hpp
${CMAKE_INCLUDE_PATH}
"[HKEY_CURRENT_USER\\software\\xerces-c\\src]"
"[HKEY_CURRENT_USER\\xerces-c\\src]"
$ENV{XERCESCROOT}/src/
/usr/local/include
/usr/include
)
FIND_LIBRARY(XercesC_LIBRARIES
NAMES
xerces-c
xerces-c_3
PATHS
${CMAKE_LIBRARY_PATH}
"[HKEY_CURRENT_USER\\software\\xerces-c\\lib]"
"[HKEY_CURRENT_USER\\xerces-c\\lib]"
$ENV{XERCESCROOT}/${LIB_DESTINATION}
/usr/local/${LIB_DESTINATION}
/usr/${LIB_DESTINATION}
)
# if the include a the library are found then we have it
IF(XercesC_INCLUDE_DIRS AND XercesC_LIBRARIES)
SET(XercesC_FOUND "YES" )
IF(NOT XERCESC__FIND_QUIETLY)
MESSAGE(STATUS "Found Xerces-C: ${XercesC_LIBRARIES}")
ENDIF(NOT XERCESC__FIND_QUIETLY)
ELSE(XercesC_INCLUDE_DIRS AND XercesC_LIBRARIES)
IF(XERCESC_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Xerces-C was not found.")
ENDIF(XERCESC_FIND_REQUIRED)
IF(NOT XERCESC__FIND_QUIETLY)
MESSAGE(STATUS "Xerces-C was not found.")
ENDIF(NOT XERCESC__FIND_QUIETLY)
ENDIF(XercesC_INCLUDE_DIRS AND XercesC_LIBRARIES)
#MARK_AS_ADVANCED(
# XercesC_INCLUDE_DIRS
# XercesC_LIBRARIES
#)
@@ -6,11 +6,12 @@ macro(CheckInterModuleDependencies)
# modules. Warns if any of the prerequisite modules are disabled.
function(REQUIRES_MODS dependent)
if(${dependent})
foreach(prerequisite ${ARGN})
foreach(prerequisite IN LISTS ARGN)
if(NOT ${prerequisite})
message(WARNING
"${dependent} requires ${ARGN} each be ON, but "
"${prerequisite} is \"${${prerequisite}}\"")
message(STATUS "${dependent} requires ${prerequisite} to be ON, but it"
" is \"${${prerequisite}}\"")
set(${dependent} OFF PARENT_SCOPE)
break()
endif(NOT ${prerequisite})
endforeach()
endif(${dependent})
@@ -28,12 +29,11 @@ macro(CheckInterModuleDependencies)
REQUIRES_MODS(BUILD_FLAT_MESH BUILD_MESH_PART)
REQUIRES_MODS(BUILD_OPENSCAD BUILD_MESH_PART BUILD_DRAFT)
REQUIRES_MODS(BUILD_PART_DESIGN BUILD_SKETCHER)
REQUIRES_MODS(BUILD_PATH BUILD_PART BUILD_ROBOT)
REQUIRES_MODS(BUILD_PATH BUILD_PART BUILD_MESH BUILD_ROBOT)
REQUIRES_MODS(BUILD_RAYTRACING BUILD_PART)
REQUIRES_MODS(BUILD_REVERSEENGINEERING BUILD_PART BUILD_MESH)
REQUIRES_MODS(BUILD_ROBOT BUILD_PART)
REQUIRES_MODS(BUILD_SANDBOX BUILD_PART BUILD_MESH)
REQUIRES_MODS(BUILD_SHIP BUILD_PART BUILD_PLOT BUILD_IMAGE)
REQUIRES_MODS(BUILD_SKETCHER BUILD_PART)
REQUIRES_MODS(BUILD_SPREADSHEET BUILD_DRAFT)
REQUIRES_MODS(BUILD_START BUILD_WEB)
@@ -1,3 +1,7 @@
# Some resources
# https://github.com/dev-cafe/cmake-cookbook
# https://cmake.org/cmake/help/v3.8/manual/cmake-compile-features.7.html
macro(CompilerChecksAndSetups)
if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANGXX TRUE)
@@ -13,9 +17,9 @@ macro(CompilerChecksAndSetups)
add_definitions(-DHAVE_SNPRINTF)
endif()
# Allow developers to use Boost < 1.48
# Allow developers to use Boost < 1.55
if (NOT BOOST_MIN_VERSION)
set(BOOST_MIN_VERSION 1.48)
set(BOOST_MIN_VERSION 1.55)
endif()
# For older cmake versions the variable 'CMAKE_CXX_COMPILER_VERSION' is missing
@@ -24,22 +28,29 @@ macro(CompilerChecksAndSetups)
OUTPUT_VARIABLE CMAKE_CXX_COMPILER_VERSION)
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_COMPILER_VERSION)
# Enabled C++11 for Freecad 0.17 and later
if (FREECAD_VERSION VERSION_GREATER 0.16)
set(BUILD_ENABLE_CXX_STD "C++11" CACHE STRING "Enable C++ standard")
# Enabled C++17 for Freecad 0.20 and later
set(BUILD_ENABLE_CXX_STD "C++17" CACHE STRING "Enable C++ standard")
set_property(CACHE BUILD_ENABLE_CXX_STD PROPERTY STRINGS
"C++11"
"C++14"
"C++17"
"C++20"
)
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
message(FATAL_ERROR "FreeCAD 0.17 and later requires C++11. G++ must be 4.7 or later, the used version is ${CMAKE_CXX_COMPILER_VERSION}")
elseif(CMAKE_COMPILER_IS_CLANGXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3)
message(FATAL_ERROR "FreeCAD 0.17 and later requires C++11. Clang must be 3.3 or later, the used version is ${CMAKE_CXX_COMPILER_VERSION}")
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3)
message(FATAL_ERROR "FreeCAD 0.20 and later requires C++17. G++ must be 7.3 or later, the used version is ${CMAKE_CXX_COMPILER_VERSION}")
elseif(CMAKE_COMPILER_IS_CLANGXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
message(FATAL_ERROR "FreeCAD 0.20 and later requires C++17. Clang must be 6.0 or later, the used version is ${CMAKE_CXX_COMPILER_VERSION}")
endif()
endif(FREECAD_VERSION VERSION_GREATER 0.16)
# Escape the two plus chars as otherwise cmake complains about invalid regex
if(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+20")
set(CMAKE_CXX_STANDARD 20)
elseif(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+17")
set(CMAKE_CXX_STANDARD 17)
elseif(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+14")
set(CMAKE_CXX_STANDARD 14)
elseif (${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+11")
set(CMAKE_CXX_STANDARD 11)
endif()
# Log the compiler and version
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER_ID}, version: ${CMAKE_CXX_COMPILER_VERSION}")
@@ -49,17 +60,6 @@ macro(CompilerChecksAndSetups)
configure_file(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
add_definitions(-DHAVE_CONFIG_H)
# Escape the two plus chars as otherwise cmake complains about invalid regex
if(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+20")
set(CMAKE_CXX_STANDARD 20)
elseif(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+17")
set(CMAKE_CXX_STANDARD 17)
elseif(${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+14")
set(CMAKE_CXX_STANDARD 14)
elseif (${BUILD_ENABLE_CXX_STD} MATCHES "C\\+\\+11")
set(CMAKE_CXX_STANDARD 11)
endif()
# For now only set pedantic option for clang
if(CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic -Wno-write-strings ${CMAKE_CXX_FLAGS}")
@@ -91,6 +91,7 @@ macro(CompilerChecksAndSetups)
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-undefined-var-template")
endif()
add_definitions(-DGL_SILENCE_DEPRECATION)
elseif (UNIX)
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-undefined-var-template")
@@ -31,18 +31,8 @@ macro(InitializeFreeCADBuildOptions)
if (DEFINED ENV{FREECAD_LIBPACK_DIR})
set(FREECAD_LIBPACK_DIR $ENV{FREECAD_LIBPACK_DIR} CACHE PATH "Directory of the FreeCAD LibPack")
message(STATUS "Found libpack env variable: ${FREECAD_LIBPACK_DIR}")
if (EXISTS ${FREECAD_LIBPACK_DIR}/lib/Qt5Core.lib)
option(BUILD_QT5 "Build with Qt5." ON)
else()
option(BUILD_QT5 "Build with Qt5." OFF)
endif()
else()
set(FREECAD_LIBPACK_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Directory of the FreeCAD LibPack")
if (EXISTS ${FREECAD_LIBPACK_DIR}/lib/Qt5Core.lib)
option(BUILD_QT5 "Build with Qt5." ON)
else()
option(BUILD_QT5 "Build with Qt5." OFF)
endif()
endif()
set(LIBPACK_FOUND OFF )
@@ -68,10 +58,10 @@ macro(InitializeFreeCADBuildOptions)
message(STATUS "Visit: https://github.com/apeltauer/FreeCAD/releases/ for Windows libpack downloads.")
endif()
else(MSVC)
option(BUILD_QT5 "Build with Qt5." OFF)
option(FREECAD_LIBPACK_USE "Use the LibPack to Build FreeCAD (only Win32 so far)." OFF)
set(FREECAD_LIBPACK_DIR "" CACHE PATH "Directory of the FreeCAD LibPack")
endif(MSVC)
option(BUILD_QT5 "Build with Qt5." ON)
# https://blog.kitware.com/constraining-values-with-comboboxes-in-cmake-cmake-gui/
set(FREECAD_USE_OCC_VARIANT "Community Edition" CACHE STRING "Official OpenCASCADE version or community edition")
@@ -124,7 +114,7 @@ macro(InitializeFreeCADBuildOptions)
option(BUILD_ADDONMGR "Build the FreeCAD addon manager module" ON)
option(BUILD_ARCH "Build the FreeCAD Architecture module" ON)
option(BUILD_ASSEMBLY "Build the FreeCAD Assembly module" OFF)
option(BUILD_COMPLETE "Build the FreeCAD complete module" ON)
option(BUILD_COMPLETE "Build the FreeCAD complete module" OFF)
option(BUILD_DRAFT "Build the FreeCAD draft module" ON)
option(BUILD_DRAWING "Build the FreeCAD drawing module" ON)
option(BUILD_IDF "Build the FreeCAD idf module" ON)
@@ -140,12 +130,11 @@ macro(InitializeFreeCADBuildOptions)
option(BUILD_PART "Build the FreeCAD part module" ON)
option(BUILD_PART_DESIGN "Build the FreeCAD part design module" ON)
option(BUILD_PATH "Build the FreeCAD path module" ON)
option(BUILD_PLOT "Build the FreeCAD plot module" OFF)
option(BUILD_PLOT "Build the FreeCAD plot module" ON)
option(BUILD_POINTS "Build the FreeCAD points module" ON)
option(BUILD_RAYTRACING "Build the FreeCAD ray tracing module" ON)
option(BUILD_REVERSEENGINEERING "Build the FreeCAD reverse engineering module" ON)
option(BUILD_ROBOT "Build the FreeCAD robot module" ON)
option(BUILD_SHIP "Build the FreeCAD ship module" OFF)
option(BUILD_SHOW "Build the FreeCAD Show module (helper module for visibility automation)" ON)
option(BUILD_SKETCHER "Build the FreeCAD sketcher module" ON)
option(BUILD_SPREADSHEET "Build the FreeCAD spreadsheet module" ON)
@@ -160,7 +149,7 @@ macro(InitializeFreeCADBuildOptions)
if(MSVC)
option(BUILD_FEM_NETGEN "Build the FreeCAD FEM module with the NETGEN mesher" ON)
option(FREECAD_USE_PCL "Build the features that use PCL libs" ON)
option(FREECAD_USE_PCL "Build the features that use PCL libs" OFF) # 3/5/2021 current LibPack uses non-C++17 FLANN
option(FREECAD_USE_3DCONNEXION "Use the 3D connexion SDK to support 3d mouse." ON)
elseif(APPLE)
find_library(3DCONNEXIONCLIENT_FRAMEWORK 3DconnexionClient)
+77 -88
View File
@@ -13,7 +13,7 @@ macro(PrintFinalReport)
message(STATUS "Standard: Requires C++${CMAKE_CXX_STANDARD}")
# Qt5 needs/sets PYTHON_CONFIG_SUFFIX regarding Shiboken
message(STATUS "Python: [${PYTHON_EXECUTABLE}] [${PYTHON_CONFIG_SUFFIX}]")
message(STATUS "Python: ${PYTHON_VERSION_STRING} [${PYTHON_EXECUTABLE}] [${PYTHON_CONFIG_SUFFIX}]")
if(DEFINED PCL_FOUND)
message(STATUS "PCL: ${PCL_VERSION}")
@@ -27,22 +27,22 @@ macro(PrintFinalReport)
message(STATUS "pybind11: not enabled")
endif(DEFINED pybind11_FOUND)
message(STATUS "Boost: ${Boost_VERSION}")
message(STATUS "Boost: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} (${Boost_VERSION})")
message(STATUS "XercesC: [${XercesC_LIBRARIES}] [${XercesC_INCLUDE_DIRS}]")
message(STATUS "XercesC: ${XercesC_VERSION} [${XercesC_LIBRARIES}] [${XercesC_INCLUDE_DIRS}]")
message(STATUS "ZLIB: ${ZLIB_VERSION_STRING}")
message(STATUS "PyCXX: [${PYCXX_INCLUDE_DIR}]")
message(STATUS "PyCXX: ${PYCXX_VERSION} [${PYCXX_INCLUDE_DIR}]")
message(STATUS "OCC: ${OCC_VERSION_STRING} [${OCC_LIBRARIES}]")
message(STATUS "OCC: ${OCC_VERSION_STRING} [${OCC_LIBRARIES}] [${OCC_LIBRARY_DIR}] [${OCC_INCLUDE_DIR}]")
if(BUILD_SMESH)
if(FREECAD_USE_EXTERNAL_SMESH)
message(STATUS "SMESH: ${SMESH_VERSION_MAJOR}.${SMESH_VERSION_MINOR}.${SMESH_VERSION_PATCH}.${SMESH_VERSION_TWEAK}")
else(FREECAD_USE_EXTERNAL_SMESH)
message(STATUS "SMESH: build internal")
message(STATUS " MEDFile: [${MEDFILE_LIBRARIES}] [${MEDFILE_INCLUDE_DIRS}]")
message(STATUS " MEDFile: ${MEDFILE_VERSION} [${MEDFILE_LIBRARIES}] [${MEDFILE_INCLUDE_DIRS}]")
message(STATUS " HDF5: ${HDF5_VERSION}")
message(STATUS " VTK: ${VTK_VERSION}")
endif(FREECAD_USE_EXTERNAL_SMESH)
@@ -51,7 +51,7 @@ macro(PrintFinalReport)
endif(BUILD_SMESH)
if(DEFINED NETGEN_FOUND)
message(STATUS "NETGEN: ${NETGEN_VERSION} [${NETGEN_DEFINITIONS}] [${NETGEN_CXX_FLAGS}] [${NGLIB_INCLUDE_DIR}] [${NGLIB_LIBRARIES}] [${NETGEN_INCLUDE_DIRS}]")
message(STATUS "NETGEN: ${NETGEN_VERSION_MAJOR}.${NETGEN_VERSION_MINOR}.${NETGEN_VERSION_PATCH} (${NETGEN_VERSION}) [${NETGEN_DEFINITIONS}] [${NETGEN_CXX_FLAGS}] [${NGLIB_INCLUDE_DIR}] [${NGLIB_LIBRARIES}] [${NETGEN_INCLUDE_DIRS}]")
else(DEFINED NETGEN_FOUND)
message(STATUS "NETGEN: not enabled")
endif(DEFINED NETGEN_FOUND)
@@ -70,88 +70,76 @@ macro(PrintFinalReport)
message(STATUS "Eigen3: not found")
endif(DEFINED EIGEN3_FOUND)
if(NOT BUILD_QT5)
message(STATUS "Qt4: ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}")
if(QT_QTWEBKIT_FOUND)
message(STATUS "QtWebKit: found")
else(QT_QTWEBKIT_FOUND)
message(STATUS "QtWebKit: not found")
endif(QT_QTWEBKIT_FOUND)
message(STATUS "Shiboken: ${Shiboken_VERSION} [${SHIBOKEN_INCLUDE_DIR}]")
message(STATUS "PySide: ${PySide_VERSION} [${PYSIDE_INCLUDE_DIR}]")
message(STATUS "PySideTools: [${PYSIDEUIC4BINARY}] [${PYSIDERCC4BINARY}]")
else(NOT BUILD_QT5)
message(STATUS "Qt5Core: ${Qt5Core_VERSION}")
message(STATUS "Qt5Network: ${Qt5Network_VERSION}")
message(STATUS "Qt5Xml: ${Qt5Xml_VERSION}")
message(STATUS "Qt5XmlPatterns: ${Qt5XmlPatterns_VERSION}")
if (BUILD_GUI)
message(STATUS "Qt5Widgets: ${Qt5Widgets_VERSION}")
message(STATUS "Qt5PrintSupport: ${Qt5PrintSupport_VERSION}")
message(STATUS "Qt5OpenGL: ${Qt5OpenGL_VERSION}")
message(STATUS "Qt5Svg: ${Qt5Svg_VERSION}")
message(STATUS "Qt5UiTools: ${Qt5UiTools_VERSION}")
message(STATUS "Qt5Concurrent: ${Qt5Concurrent_VERSION}")
if(BUILD_WEB)
if (Qt5WebKitWidgets_FOUND)
message(STATUS "Qt5WebKitWidgets: ${Qt5WebKitWidgets_VERSION}")
endif()
if (Qt5WebEngineWidgets_FOUND)
message(STATUS "Qt5WebEngineWidgets: ${Qt5WebEngineWidgets_VERSION}")
endif()
else(BUILD_WEB)
message(STATUS "Qt5WebKitWidgets: not needed (BUILD_WEB)")
message(STATUS "Qt5WebEngineWidgets: not needed (BUILD_WEB)")
endif(BUILD_WEB)
if(${Qt5WinExtras_FOUND})
message(STATUS "Qt5WinExtras: ${Qt5WinExtras_VERSION}")
message(STATUS "Qt5Core: ${Qt5Core_VERSION}")
message(STATUS "Qt5Network: ${Qt5Network_VERSION}")
message(STATUS "Qt5Xml: ${Qt5Xml_VERSION}")
message(STATUS "Qt5XmlPatterns: ${Qt5XmlPatterns_VERSION}")
if (BUILD_GUI)
message(STATUS "Qt5Widgets: ${Qt5Widgets_VERSION}")
message(STATUS "Qt5PrintSupport: ${Qt5PrintSupport_VERSION}")
message(STATUS "Qt5OpenGL: ${Qt5OpenGL_VERSION}")
message(STATUS "Qt5Svg: ${Qt5Svg_VERSION}")
message(STATUS "Qt5UiTools: ${Qt5UiTools_VERSION}")
message(STATUS "Qt5Concurrent: ${Qt5Concurrent_VERSION}")
if(BUILD_WEB)
if (Qt5WebKitWidgets_FOUND)
message(STATUS "Qt5WebKitWidgets: ${Qt5WebKitWidgets_VERSION}")
endif()
if (Qt5WebEngineWidgets_FOUND)
message(STATUS "Qt5WebEngineWidgets: ${Qt5WebEngineWidgets_VERSION}")
endif()
else(BUILD_WEB)
message(STATUS "Qt5WebKitWidgets: not needed (BUILD_WEB)")
message(STATUS "Qt5WebEngineWidgets: not needed (BUILD_WEB)")
endif(BUILD_WEB)
if(${Qt5WinExtras_FOUND})
message(STATUS "Qt5WinExtras: ${Qt5WinExtras_VERSION}")
endif()
else(BUILD_GUI)
message(STATUS "Qt5Widgets: not needed")
message(STATUS "Qt5PrintSupport: not needed")
message(STATUS "Qt5OpenGL: not needed")
message(STATUS "Qt5Svg: not needed")
message(STATUS "Qt5UiTools: not needed")
message(STATUS "Qt5Concurrent: not needed")
message(STATUS "Qt5WebKitWidgets: not needed")
endif(BUILD_GUI)
else(BUILD_GUI)
message(STATUS "Qt5Widgets: not needed")
message(STATUS "Qt5PrintSupport: not needed")
message(STATUS "Qt5OpenGL: not needed")
message(STATUS "Qt5Svg: not needed")
message(STATUS "Qt5UiTools: not needed")
message(STATUS "Qt5Concurrent: not needed")
message(STATUS "Qt5WebKitWidgets: not needed")
endif(BUILD_GUI)
if(DEFINED MACPORTS_PREFIX)
if(DEFINED Shiboken_FOUND)
message(STATUS "Shiboken: ${Shiboken_VERSION} [${SHIBOKEN_INCLUDE_DIR}]")
else(DEFINED Shiboken_FOUND)
message(STATUS "Shiboken: not found (only searched if MACPORTS_PREFIX is defined)")
endif(DEFINED Shiboken_FOUND)
if(DEFINED PySide_FOUND)
message(STATUS "PySide: ${PySide_VERSION} [${PYSIDE_INCLUDE_DIR}]")
if(NOT PYSIDE_INCLUDE_DIR)
message(STATUS " IncludeDir: Unable to find, python version mismatch?")
endif(NOT PYSIDE_INCLUDE_DIR)
else(DEFINED PySide_FOUND)
message(STATUS "PySide: not found (only searched if MACPORTS_PREFIX is defined)")
endif(DEFINED PySide_FOUND)
endif(DEFINED MACPORTS_PREFIX)
if(DEFINED Shiboken2_FOUND)
message(STATUS "Shiboken2: ${Shiboken2_VERSION} [${Shiboken2_DIR}] [${SHIBOKEN_INCLUDE_DIR}]")
else(DEFINED Shiboken2_FOUND)
message(STATUS "Shiboken2: not found")
endif(DEFINED Shiboken2_FOUND)
if(DEFINED PySide2_FOUND)
message(STATUS "PySide2: ${PySide2_VERSION} [${PYSIDE_INCLUDE_DIR}]")
if(DEFINED MACPORTS_PREFIX)
if(DEFINED Shiboken_FOUND)
message(STATUS "Shiboken: ${Shiboken_VERSION} [${SHIBOKEN_INCLUDE_DIR}]")
else(DEFINED Shiboken_FOUND)
message(STATUS "Shiboken: not found (only searched if MACPORTS_PREFIX is defined)")
endif(DEFINED Shiboken_FOUND)
if(DEFINED PySide_FOUND)
message(STATUS "PySide: ${PySide_VERSION} [${PYSIDE_INCLUDE_DIR}]")
if(NOT PYSIDE_INCLUDE_DIR)
message(STATUS " IncludeDir: Unable to find, python version mismatch?")
endif(NOT PYSIDE_INCLUDE_DIR)
else(DEFINED PySide2_FOUND)
message(STATUS "PySide2: not found")
endif(DEFINED PySide2_FOUND)
if(DEFINED PYSIDE2_TOOLS_FOUND)
message(STATUS "PySide2Tools: [${PYSIDE2UICBINARY}] [${PYSIDE2RCCBINARY}]")
else(DEFINED PYSIDE2_TOOLS_FOUND)
message(STATUS "PySide2Tools: not found")
endif(DEFINED PYSIDE2_TOOLS_FOUND)
endif(NOT BUILD_QT5)
else(DEFINED PySide_FOUND)
message(STATUS "PySide: not found (only searched if MACPORTS_PREFIX is defined)")
endif(DEFINED PySide_FOUND)
endif(DEFINED MACPORTS_PREFIX)
if(DEFINED Shiboken2_FOUND)
message(STATUS "Shiboken2: ${Shiboken2_VERSION} [${Shiboken2_DIR}] [${SHIBOKEN_INCLUDE_DIR}]")
else(DEFINED Shiboken2_FOUND)
message(STATUS "Shiboken2: not found")
endif(DEFINED Shiboken2_FOUND)
if(DEFINED PySide2_FOUND)
message(STATUS "PySide2: ${PySide2_VERSION} [${PYSIDE_INCLUDE_DIR}]")
if(NOT PYSIDE_INCLUDE_DIR)
message(STATUS " IncludeDir: Unable to find, python version mismatch?")
endif(NOT PYSIDE_INCLUDE_DIR)
else(DEFINED PySide2_FOUND)
message(STATUS "PySide2: not found")
endif(DEFINED PySide2_FOUND)
if(DEFINED PYSIDE2_TOOLS_FOUND)
message(STATUS "PySide2Tools: [${PYSIDE2UICBINARY}] [${PYSIDE2RCCBINARY}]")
else(DEFINED PYSIDE2_TOOLS_FOUND)
message(STATUS "PySide2Tools: not found")
endif(DEFINED PYSIDE2_TOOLS_FOUND)
if(FREECAD_USE_FREETYPE)
if(DEFINED FREETYPE_FOUND)
@@ -163,9 +151,11 @@ macro(PrintFinalReport)
message(STATUS "Freetype: disabled")
endif(FREECAD_USE_FREETYPE)
message(STATUS "OpenGLU: ${OPENGL_glu_LIBRARY} [${OPENGL_glu_LIBRARY}][${OPENGL_INCLUDE_DIR}]")
message(STATUS "OpenGL: ${OPENGL_gl_LIBRARY}")
message(STATUS "OpenGLU: [${OPENGL_glu_LIBRARY}][${OPENGL_INCLUDE_DIR}]")
message(STATUS "Coin3D: [${COIN3D_LIBRARIES}] [${COIN3D_INCLUDE_DIRS}]")
message(STATUS "Coin3D: ${COIN3D_VERSION} [${COIN3D_LIBRARIES}] [${COIN3D_INCLUDE_DIRS}]")
message(STATUS "Pivy: ${PIVY_VERSION}")
if (WIN32)
@@ -223,8 +213,7 @@ macro(PrintFinalReport)
file(COPY ${FREECAD_LIBPACK_DIR}/plugins/styles DESTINATION ${CMAKE_BINARY_DIR}/bin)
file(COPY ${FREECAD_LIBPACK_DIR}/plugins/printsupport DESTINATION ${CMAKE_BINARY_DIR}/bin)
file(COPY ${FREECAD_LIBPACK_DIR}/resources DESTINATION ${CMAKE_BINARY_DIR})
file(COPY ${FREECAD_LIBPACK_DIR}/bin/Lib/site-packages/PySide2/translations/qtwebengine_locales
DESTINATION ${CMAKE_BINARY_DIR}/bin)
file(COPY ${FREECAD_LIBPACK_DIR}/translations/qtwebengine_locales DESTINATION ${CMAKE_BINARY_DIR}/translations)
message(STATUS "... end copying.\n=======================================\n")
endif(FREECAD_COPY_DEPEND_DIRS_TO_BUILD)
@@ -258,7 +247,7 @@ macro(PrintFinalReport)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/plugins/sqldrivers DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/plugins/styles DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/plugins/printsupport DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/bin/Lib/site-packages/PySide2/translations/qtwebengine_locales DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/translations/qtwebengine_locales DESTINATION ${CMAKE_INSTALL_PREFIX}/translations)
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/resources DESTINATION ${CMAKE_INSTALL_PREFIX})
install(DIRECTORY ${FREECAD_LIBPACK_DIR}/bin DESTINATION ${CMAKE_INSTALL_PREFIX})
message(STATUS "Created install commands for INSTALL target.\n")
+12
View File
@@ -0,0 +1,12 @@
macro(SetupDoxygen)
# -------------------------------- Doxygen ----------------------------------
find_package(Doxygen)
if (NOT DOXYGEN_FOUND)
message("=====================================================\n"
"Doxygen not found, will not build documentation. \n"
"=====================================================\n")
endif(NOT DOXYGEN_FOUND)
endmacro(SetupDoxygen)
+9
View File
@@ -17,4 +17,13 @@ macro(SetupEigen)
set (BUILD_FLAT_MESH OFF)
endif()
# Older versions raise the warning -Wdeprecated-copy with clang10/gcc10
if (${EIGEN3_VERSION} VERSION_LESS "3.3.8")
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-deprecated-copy" _flag_found)
if (_flag_found)
set (EIGEN3_NO_DEPRECATED_COPY "-Wno-deprecated-copy")
endif ()
endif()
endmacro(SetupEigen)
+2 -2
View File
@@ -3,10 +3,10 @@ macro(SetupMatplotlib)
find_package(Matplotlib)
if (MATPLOTLIB_FOUND)
message(STATUS "-- matplotlib-${MATPLOTLIB_VERSION} has been found.")
message(STATUS "Found Matplotlib: ${MATPLOTLIB_PATH_DIRS} (found version \"${MATPLOTLIB_VERSION}\")")
else(MATPLOTLIB_FOUND)
message("=====================================================\n"
"matplotlib not found, Plot module won't be available.\n"
"Matplotlib not found, Plot module won't be available.\n"
"=====================================================\n")
endif(MATPLOTLIB_FOUND)
+43 -30
View File
@@ -1,10 +1,6 @@
macro(SetupPython)
# -------------------------------- Python --------------------------------
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677598
# Acceptable versions of Python
set(Python_ADDITIONAL_VERSIONS "2.7")
# For building on OS X
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT BUILD_WITH_CONDA)
@@ -118,32 +114,49 @@ macro(SetupPython)
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT BUILD_WITH_CONDA)
find_package(PythonInterp REQUIRED)
# Issue in cmake prevents finding pythonlibs 3.x when python 2.7 is present
# setting NOTFOUND here resolves the issue
set(PYTHON_INCLUDE_DIR "NOTFOUND")
set(PYTHON_LIBRARY "NOTFOUND")
set(Python_ADDITIONAL_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
if (NOT DEFINED PYTHON_VERSION_STRING)
find_package(PythonLibs REQUIRED)
else (NOT DEFINED PYTHON_VERSION_STRING)
find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT)
endif(NOT DEFINED PYTHON_VERSION_STRING)
if(${CMAKE_VERSION} VERSION_LESS "3.12")
set(Python_ADDITIONAL_VERSIONS ${Python_ADDITIONAL_VERSIONS} "3.10" "3.9" "3.8" "3.7" "3.6")
find_package(PythonInterp REQUIRED)
set(Python_ADDITIONAL_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
if (NOT DEFINED PYTHON_VERSION_STRING)
find_package(PythonLibs REQUIRED)
else (NOT DEFINED PYTHON_VERSION_STRING)
find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT)
endif(NOT DEFINED PYTHON_VERSION_STRING)
if(NOT PYTHONLIBS_FOUND)
message(FATAL_ERROR "=================================\n"
"Python not found, install Python!\n"
"=================================\n")
endif()
# For forward compatibility with new CMake scripts
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
set(Python3_LIBRARIES ${PYTHON_LIBRARIES})
set(Python3_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
set(Python3_LIBRARY_DIRS ${PYTHON_LIBRARY_DIRS})
set(Python3_VERSION ${PYTHON_VERSION_STRING})
set(Python3_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
set(Python3_VERSION_MINOR ${PYTHON_VERSION_MINOR})
set(Python3_VERSION_PATCH ${PYTHON_VERSION_PATCH})
set(Python3_Interpreter_FOUND ${PYTHONINTERP_FOUND})
else()
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
if(NOT PYTHONLIBS_FOUND)
message(FATAL_ERROR "=================================\n"
"Python not found, install Python!\n"
"=================================\n")
else(NOT PYTHONLIBS_FOUND)
# prevent python3 lower than 3.3 (not enough utf8<->unicode tools)
if(PYTHON_VERSION_MAJOR EQUAL 3)
if(PYTHON_VERSION_MINOR LESS 4)
message(FATAL_ERROR "To build FreeCAD with Python3, you need at least version 3.4\n")
endif(PYTHON_VERSION_MINOR LESS 4)
endif(PYTHON_VERSION_MAJOR EQUAL 3)
endif(NOT PYTHONLIBS_FOUND)
# For backwards compatibility with old CMake scripts
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
set(PYTHON_LIBRARIES ${Python3_LIBRARIES})
set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS})
set(PYTHON_LIBRARY_DIRS ${Python3_LIBRARY_DIRS})
set(PYTHON_VERSION_STRING ${Python3_VERSION})
set(PYTHON_VERSION_MAJOR ${Python3_VERSION_MAJOR})
set(PYTHON_VERSION_MINOR ${Python3_VERSION_MINOR})
set(PYTHON_VERSION_PATCH ${Python3_VERSION_PATCH})
set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND})
endif()
# prevent python3 lower than 3.6
if (${PYTHON_VERSION_STRING} VERSION_LESS "3.6")
message(FATAL_ERROR "To build FreeCAD you need at least Python 3.6\n")
endif()
endmacro(SetupPython)
+29 -111
View File
@@ -1,117 +1,35 @@
# -------------------------------- Qt --------------------------------
if (NOT BUILD_QT5)
# If using MacPorts, help the Qt4 finder.
if(MACPORTS_PREFIX)
if(NOT QT_QMAKE_EXECUTABLE)
set(QT_QMAKE_EXECUTABLE ${MACPORTS_PREFIX}/libexec/qt4/bin/qmake)
endif()
endif()
find_package(Qt5Core REQUIRED)
set(CMAKE_AUTOMOC TRUE)
set(QT_MIN_VERSION 4.5.0)
set(QT_USE_QTNETWORK TRUE)
set(QT_USE_QTXML TRUE)
if(BUILD_GUI)
set(QT_USE_QTOPENGL TRUE)
set(QT_USE_QTSVG TRUE)
set(QT_USE_QTUITOOLS TRUE)
set(QT_USE_QTWEBKIT TRUE)
endif(BUILD_GUI)
find_package(Qt4)# REQUIRED
include(${QT_USE_FILE})
if(NOT QT4_FOUND)
message(FATAL_ERROR "========================\n"
"Qt4 libraries not found.\n"
"========================\n")
endif(NOT QT4_FOUND)
if(NOT QT_QTWEBKIT_FOUND)
message("========================================================\n"
"Qt Webkit not found, will not build browser integration.\n"
"========================================================\n")
endif(NOT QT_QTWEBKIT_FOUND)
# This is a special version of the built in macro qt4_wrap_cpp
# It is required since moc'ed files are now included instead of being added to projects directly
# It adds a reverse dependency to solve this
# This has the unfortunate side effect that some files are always rebuilt
# There is probably a cleaner solution than this
macro(fc_wrap_cpp outfiles)
# get include dirs
QT4_GET_MOC_FLAGS(moc_flags)
QT4_EXTRACT_OPTIONS(moc_files moc_options moc_target ${ARGN})
# fixes bug 0000585: bug with boost 1.48
set(moc_options ${moc_options} -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
foreach(it ${moc_files})
get_filename_component(it ${it} ABSOLUTE)
QT4_MAKE_OUTPUT_FILE(${it} moc_ cpp outfile)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_options} ${it} -o ${outfile}
MAIN_DEPENDENCY ${it}
)
set(${outfiles} ${${outfiles}} ${outfile})
add_file_dependencies(${it} ${outfile})
endforeach(it)
endmacro(fc_wrap_cpp)
elseif (BUILD_QT5)
find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5XmlPatterns REQUIRED)
if(BUILD_GUI)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5Svg REQUIRED)
find_package(Qt5UiTools REQUIRED)
find_package(Qt5Concurrent REQUIRED)
if (BUILD_WEB)
if (${FREECAD_USE_QTWEBMODULE} MATCHES "Qt Webkit")
find_package(Qt5WebKitWidgets REQUIRED)
elseif(${FREECAD_USE_QTWEBMODULE} MATCHES "Qt WebEngine")
# For FreeCAD 0.20, pegged to Ubutu 18.04 LTS:
if(${Qt5Core_VERSION} VERSION_LESS "5.9")
message (FATAL_ERROR "FreeCAD v0.20 requires Qt5 5.9 or later")
endif()
find_package(Qt5Network REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5XmlPatterns REQUIRED)
find_package(Qt5Concurrent REQUIRED)
if(BUILD_GUI)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5Svg REQUIRED)
find_package(Qt5UiTools REQUIRED)
if (BUILD_WEB)
if (${FREECAD_USE_QTWEBMODULE} MATCHES "Qt Webkit")
find_package(Qt5WebKitWidgets REQUIRED)
elseif(${FREECAD_USE_QTWEBMODULE} MATCHES "Qt WebEngine")
find_package(Qt5WebEngineWidgets REQUIRED)
else() # Automatic
find_package(Qt5WebKitWidgets QUIET)
if(NOT Qt5WebKitWidgets_FOUND)
find_package(Qt5WebEngineWidgets REQUIRED)
if (Qt5WebEngineWidgets_VERSION VERSION_LESS 5.7.0)
message(FATAL_ERROR "** Minimum supported Qt5WebEngine version is 5.7.0!\n")
endif()
else() # Automatic
find_package(Qt5WebKitWidgets QUIET)
if(NOT Qt5WebKitWidgets_FOUND)
find_package(Qt5WebEngineWidgets REQUIRED)
if (Qt5WebEngineWidgets_VERSION VERSION_LESS 5.7.0)
message(FATAL_ERROR "** Minimum supported Qt5WebEngine version is 5.7.0!\n")
endif()
endif()
endif()
endif()
if(MSVC AND ${Qt5Core_VERSION} VERSION_GREATER "5.2.0")
find_package(Qt5WinExtras QUIET)
endif()
endif(BUILD_GUI)
# This is a special version of the built in macro qt5_wrap_cpp
# It is required since moc'ed files are now included instead of being added to projects directly
# It adds a reverse dependency to solve this
# This has the unfortunate side effect that some files are always rebuilt
# There is probably a cleaner solution than this
macro(fc_wrap_cpp outfiles )
# get include dirs
qt5_get_moc_flags(moc_flags)
set(moc_files ${ARGN})
# fixes bug 0000585: bug with boost 1.48
set(moc_options ${moc_options} -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
foreach(it ${moc_files})
get_filename_component(it ${it} ABSOLUTE)
qt5_make_output_file(${it} moc_ cpp outfile)
qt5_create_moc_command(${it} ${outfile} "${moc_flags}" "${moc_options}" "${moc_target}" "${moc_depends}")
set(${outfiles} ${${outfiles}} ${outfile})
add_file_dependencies(${it} ${outfile})
endforeach(it)
endmacro(fc_wrap_cpp)
endif (NOT BUILD_QT5)
endif()
if(MSVC)
find_package(Qt5WinExtras QUIET)
endif()
endif(BUILD_GUI)
+20 -10
View File
@@ -27,13 +27,24 @@ macro(SetupSalomeSMESH)
# check which modules are available
if(UNIX OR WIN32)
find_package(VTK COMPONENTS vtkCommonCore REQUIRED NO_MODULE)
list(APPEND VTK_COMPONENTS vtkIOMPIParallel vtkParallelMPI vtkhdf5 vtkFiltersParallelDIY2 vtkRenderingCore vtkInteractionStyle vtkRenderingFreeType vtkRenderingOpenGL2)
foreach(_module ${VTK_COMPONENTS})
list (FIND VTK_MODULES_ENABLED ${_module} _index)
if (${_index} GREATER -1)
list(APPEND AVAILABLE_VTK_COMPONENTS ${_module})
endif()
endforeach()
if(${VTK_MAJOR_VERSION} LESS 9)
list(APPEND VTK_COMPONENTS vtkIOMPIParallel vtkParallelMPI vtkhdf5 vtkFiltersParallelDIY2 vtkRenderingCore vtkInteractionStyle vtkRenderingFreeType vtkRenderingOpenGL2)
foreach(_module ${VTK_COMPONENTS})
list (FIND VTK_MODULES_ENABLED ${_module} _index)
if(${_index} GREATER -1)
list(APPEND AVAILABLE_VTK_COMPONENTS ${_module})
endif()
endforeach()
else()
set(VTK_COMPONENTS "CommonCore;CommonDataModel;FiltersVerdict;IOXML;FiltersCore;FiltersGeneral;IOLegacy;FiltersExtraction;FiltersSources;FiltersGeometry")
list(APPEND VTK_COMPONENTS "IOMPIParallel;ParallelMPI;hdf5;FiltersParallelDIY2;RenderingCore;InteractionStyle;RenderingFreeType;RenderingOpenGL2")
foreach(_module ${VTK_COMPONENTS})
list (FIND VTK_AVAILABLE_COMPONENTS ${_module} _index)
if(${_index} GREATER -1)
list(APPEND AVAILABLE_VTK_COMPONENTS ${_module})
endif()
endforeach()
endif()
endif()
# don't check VERSION 6 as this would exclude VERSION 7
@@ -100,9 +111,8 @@ macro(SetupSalomeSMESH)
add_compile_options(${OPENMPI_CFLAGS})
link_directories(${OPENMPI_LIBRARY_DIRS})
link_libraries(${OPENMPI_LIBRARIES})
find_file(MpidotH mpi.h PATHS ${OPENMPI_INCLUDE_DIRS} NO_DEFAULT_PATH)
if(NOT MpidotH)
message( WARNING "mpi.h was not found. Check for error above.")
if(NOT OPENMPI_FOUND)
message( WARNING "ompi-cxx was not found. Check for error above.")
endif()
endif()
set(SMESH_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/3rdParty/salomesmesh/inc)
+121 -127
View File
@@ -1,139 +1,133 @@
macro(SetupShibokenAndPyside)
# -------------------------------- Shiboken/PySide ------------------------
if(BUILD_QT5)
# set(PYTHON_SUFFIX -python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
# Below are two variables that can be left empty for standard python 3 version,
# but must be set by the user for different python versions such as 2.7, 3.5 ...
if (PYTHON_VERSION_MAJOR LESS 3)
set(PYTHON_CONFIG_SUFFIX -python2.7 CACHE STRING "Shiboken cmake file suffix. If left empty, system default will be used: <ShibokenConfigPYTHON_CONFIG_SUFFIX.cmake>")
set(PYTHON_BASENAME -python2.7 CACHE STRING "Same as PYTHON_SUFFIX but for PySide. If left empty, PYTHON_SUFFIX will be used: <PySideConfigPYTHON_BASENAME.cmake>")
else()
#set(PYTHON_CONFIG_SUFFIX "" CACHE STRING "Shiboken cmake file suffix. If left empty, system default will be used: <ShibokenConfigPYTHON_CONFIG_SUFFIX.cmake>")
#set(PYTHON_BASENAME "" CACHE STRING "Same as PYTHON_SUFFIX but for PySide. If left empty, PYTHON_SUFFIX will be used: <PySideConfigPYTHON_BASENAME.cmake>")
if(DEFINED MACPORTS_PREFIX)
find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
endif(DEFINED MACPORTS_PREFIX)
# Shiboken2Config.cmake may explicitly set CMAKE_BUILD_TYPE to Release which causes
# CMake to fail to create Makefiles for a debug build.
# So as a workaround we save and restore the value after checking for Shiboken2.
set (SAVE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
find_package(Shiboken2 QUIET)# REQUIRED
set (CMAKE_BUILD_TYPE ${SAVE_BUILD_TYPE})
if (Shiboken2_FOUND)
# Shiboken2 config file was found but it may use the wrong Python version
# Try to get the matching config suffix and repeat finding the package
set(SHIBOKEN_PATTERN .cpython-${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR})
file(GLOB SHIBOKEN_CONFIG "${Shiboken2_DIR}/Shiboken2Config${SHIBOKEN_PATTERN}*.cmake")
if (SHIBOKEN_CONFIG)
get_filename_component(SHIBOKEN_CONFIG_SUFFIX ${SHIBOKEN_CONFIG} NAME)
string(SUBSTRING ${SHIBOKEN_CONFIG_SUFFIX} 15 -1 SHIBOKEN_CONFIG_SUFFIX)
string(REPLACE ".cmake" "" PYTHON_CONFIG_SUFFIX ${SHIBOKEN_CONFIG_SUFFIX})
message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
find_package(Shiboken2 QUIET)
endif()
endif()
if(DEFINED MACPORTS_PREFIX)
find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
endif(DEFINED MACPORTS_PREFIX)
# pyside2 changed its cmake files, this is the dance we have
# to dance to be compatible with the old (<5.12) and the new versions (>=5.12)
if(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken2::libshiboken)
get_property(SHIBOKEN_INCLUDE_DIR TARGET Shiboken2::libshiboken PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
endif(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken2::libshiboken)
# Shiboken2Config.cmake may explicitly set CMAKE_BUILD_TYPE to Release which causes
# CMake to fail to create Makefiles for a debug build.
# So as a workaround we save and restore the value after checking for Shiboken2.
set (SAVE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
find_package(Shiboken2 QUIET)# REQUIRED
set (CMAKE_BUILD_TYPE ${SAVE_BUILD_TYPE})
if (Shiboken2_FOUND)
# Shiboken2 config file was found but it may use the wrong Python version
# Try to get the matching config suffix and repeat finding the package
if (PYTHON_VERSION_MAJOR LESS 3)
set(SHIBOKEN_PATTERN -python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
else()
set(SHIBOKEN_PATTERN .cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR})
endif()
if(NOT SHIBOKEN_INCLUDE_DIR)
message("====================\n"
"shiboken2 not found.\n"
"====================\n")
endif(NOT SHIBOKEN_INCLUDE_DIR)
file(GLOB SHIBOKEN_CONFIG "${Shiboken2_DIR}/Shiboken2Config${SHIBOKEN_PATTERN}*.cmake")
if (SHIBOKEN_CONFIG)
get_filename_component(SHIBOKEN_CONFIG_SUFFIX ${SHIBOKEN_CONFIG} NAME)
string(SUBSTRING ${SHIBOKEN_CONFIG_SUFFIX} 15 -1 SHIBOKEN_CONFIG_SUFFIX)
string(REPLACE ".cmake" "" PYTHON_CONFIG_SUFFIX ${SHIBOKEN_CONFIG_SUFFIX})
message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
find_package(Shiboken2 QUIET)
endif()
find_package(PySide2 QUIET)# REQUIRED
if(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide2::pyside2)
get_property(PYSIDE_INCLUDE_DIR TARGET PySide2::pyside2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
endif(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide2::pyside2)
if(NOT PYSIDE_INCLUDE_DIR)
message("==================\n"
"PySide2 not found.\n"
"==================\n")
endif(NOT PYSIDE_INCLUDE_DIR)
find_package(PySide2Tools QUIET) #REQUIRED # PySide2 utilities (pyside2-uic & pyside2-rcc)
if(NOT PYSIDE2_TOOLS_FOUND)
message("=======================\n"
"PySide2Tools not found.\n"
"=======================\n")
endif(NOT PYSIDE2_TOOLS_FOUND)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Ext/PySide)
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/__init__.py "# PySide wrapper\n"
"from PySide2 import __version__\n"
"from PySide2 import __version_info__\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtCore.py "from PySide2.QtCore import *\n\n"
"#QCoreApplication.CodecForTr=0\n"
"#QCoreApplication.UnicodeUTF8=1\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtGui.py "from PySide2.QtGui import *\n"
"from PySide2.QtWidgets import *\n"
"QHeaderView.setResizeMode = QHeaderView.setSectionResizeMode\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvg.py "from PySide2.QtSvg import *\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtUiTools.py "from PySide2.QtUiTools import *\n")
if(APPLE AND NOT BUILD_WITH_CONDA)
install(
DIRECTORY
${CMAKE_BINARY_DIR}/Ext/PySide
DESTINATION
MacOS
)
else()
install(
DIRECTORY
${CMAKE_BINARY_DIR}/Ext/PySide
DESTINATION
Ext
)
endif()
# If shiboken cannot be found the build option will be set to OFF
if(SHIBOKEN_INCLUDE_DIR)
option(FREECAD_USE_SHIBOKEN "Links to the shiboken library at build time. If OFF its Python module is imported at runtime" ON)
else()
option(FREECAD_USE_SHIBOKEN "Links to the shiboken library at build time. If OFF its Python module is imported at runtime" OFF)
# Now try to import the shiboken Python module and print a warning if it can't be loaded
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import shiboken2"
RESULT_VARIABLE FAILURE
OUTPUT_VARIABLE PRINT_OUTPUT
)
if(FAILURE)
message("=================================\n"
"shiboken Python module not found.\n"
"=================================\n")
endif()
endif()
# pyside2 changed it's cmake files, this is the dance we have
# to dance to be compatible with the old (<5.12) and the new versions (>=5.12)
if(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken2::libshiboken)
get_property(SHIBOKEN_INCLUDE_DIR TARGET Shiboken2::libshiboken PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
endif(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken2::libshiboken)
# If PySide cannot be found the build option will be set to OFF
if(PYSIDE_INCLUDE_DIR)
option(FREECAD_USE_PYSIDE "Links to the PySide libraries at build time." ON)
else()
option(FREECAD_USE_PYSIDE "Links to the PySide libraries at build time." OFF)
endif()
if(NOT SHIBOKEN_INCLUDE_DIR)
message("====================\n"
"shiboken2 not found.\n"
"====================\n")
endif(NOT SHIBOKEN_INCLUDE_DIR)
find_package(PySide2 QUIET)# REQUIRED
if(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide2::pyside2)
get_property(PYSIDE_INCLUDE_DIR TARGET PySide2::pyside2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
endif(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide2::pyside2)
if(NOT PYSIDE_INCLUDE_DIR)
message("==================\n"
"PySide2 not found.\n"
"==================\n")
endif(NOT PYSIDE_INCLUDE_DIR)
find_package(PySide2Tools QUIET) #REQUIRED # PySide2 utilities (pyside2-uic & pyside2-rcc)
if(NOT PYSIDE2_TOOLS_FOUND)
message("=======================\n"
"PySide2Tools not found.\n"
"=======================\n")
endif(NOT PYSIDE2_TOOLS_FOUND)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Ext/PySide)
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/__init__.py "# PySide wrapper\n"
"from PySide2 import __version__\n"
"from PySide2 import __version_info__\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtCore.py "from PySide2.QtCore import *\n\n"
"#QCoreApplication.CodecForTr=0\n"
"#QCoreApplication.UnicodeUTF8=1\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtGui.py "from PySide2.QtGui import *\n"
"from PySide2.QtWidgets import *\n"
"QHeaderView.setResizeMode = QHeaderView.setSectionResizeMode\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvg.py "from PySide2.QtSvg import *\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtUiTools.py "from PySide2.QtUiTools import *\n")
if(APPLE AND NOT BUILD_WITH_CONDA)
install(
DIRECTORY
${CMAKE_BINARY_DIR}/Ext/PySide
DESTINATION
MacOS
)
else()
install(
DIRECTORY
${CMAKE_BINARY_DIR}/Ext/PySide
DESTINATION
Ext
)
endif()
else(BUILD_QT5)
# set(PYTHON_SUFFIX -python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
# Below are two variables that can be left empty for standard python 3 version,
# but must be set by the user for different python versions such as 2.7, 3.5 ...
if (PYTHON_VERSION_MAJOR LESS 3)
set(PYTHON_CONFIG_SUFFIX -python2.7 CACHE STRING "Shiboken cmake file suffix. If left empty, system default will be used: <ShibokenConfigPYTHON_CONFIG_SUFFIX.cmake>")
set(PYTHON_BASENAME -python2.7 CACHE STRING "Same as PYTHON_SUFFIX but for PySide. If left empty, PYTHON_SUFFIX will be used: <PySideConfigPYTHON_BASENAME.cmake>")
else()
set(PYTHON_CONFIG_SUFFIX "" CACHE STRING "Shiboken cmake file suffix. If left empty, system default will be used: <ShibokenConfigPYTHON_CONFIG_SUFFIX.cmake>")
set(PYTHON_BASENAME "" CACHE STRING "Same as PYTHON_SUFFIX but for PySide. If left empty, PYTHON_SUFFIX will be used: <PySideConfigPYTHON_BASENAME.cmake>")
endif()
if(DEFINED MACPORTS_PREFIX)
find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
endif(DEFINED MACPORTS_PREFIX)
find_package(Shiboken)# REQUIRED
if(NOT SHIBOKEN_INCLUDE_DIR)
message(FATAL_ERROR "===================\n"
"shiboken not found.\n"
"===================\n")
endif(NOT SHIBOKEN_INCLUDE_DIR)
find_package(PySide)# REQUIRED
if(NOT PYSIDE_INCLUDE_DIR)
message(FATAL_ERROR "=================\n"
"PySide not found.\n"
"=================\n")
endif(NOT PYSIDE_INCLUDE_DIR)
find_package(PySideTools REQUIRED) # PySide utilities (pyside-uic & pyside-rcc)
endif(BUILD_QT5)
# Independent of the build option PySide modules must be loaded at runtime. Print a warning if it fails.
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import PySide2;import os;print(os.path.dirname(PySide2.__file__), end='')"
RESULT_VARIABLE FAILURE
OUTPUT_VARIABLE PRINT_OUTPUT
)
if(FAILURE)
message("================================\n"
"PySide2 Python module not found.\n"
"================================\n")
else()
message(STATUS "===============================================\n"
"PySide2 Python module found at ${PRINT_OUTPUT}.\n"
"===============================================\n")
endif()
endmacro(SetupShibokenAndPyside)
+53
View File
@@ -0,0 +1,53 @@
mkdir build
cd build
if "%FEATURE_DEBUG%"=="1" (
set BUILD_TYPE="Debug"
echo "#! building debug package !#") else (
set BUILD_TYPE="Release")
set "CFLAGS= "
set "CXXFLAGS= "
set "LDFLAGS_SHARED= ucrt.lib"
cmake -G "Ninja" ^
-D BUID_WITH_CONDA:BOOL=ON ^
-D CMAKE_BUILD_TYPE=%BUILD_TYPE% ^
-D FREECAD_LIBPACK_USE:BOOL=OFF ^
-D CMAKE_INSTALL_PREFIX:FILEPATH=%LIBRARY_PREFIX% ^
-D CMAKE_PREFIX_PATH:FILEPATH=%LIBRARY_PREFIX% ^
-D CMAKE_INCLUDE_PATH:FILEPATH=%LIBRARY_PREFIX%/include ^
-D CMAKE_LIBRARY_PATH:FILEPATH=%LIBRARY_PREFIX%/lib ^
-D CMAKE_INSTALL_LIBDIR:FILEPATH=%LIBRARY_PREFIX%/lib ^
-D BUILD_QT5:BOOL=ON ^
-D NETGENDATA:FILEPATH=%LIBRARY_PREFIX%/include/netgen ^
-D NGLIB_INCLUDE_DIR:FILEPATH=%LIBRARY_PREFIX%/include/netgen ^
-D BUILD_FEM_NETGEN:BOOL=ON ^
-D OCC_INCLUDE_DIR:FILEPATH=%LIBRARY_PREFIX%/include/opencascade ^
-D OCC_LIBRARY_DIR:FILEPATH=%LIBRARY_PREFIX%/lib ^
-D OCC_LIBRARIES:FILEPATH=%LIBRARY_PREFIX%/lib ^
-D FREECAD_USE_OCC_VARIANT="Official Version" ^
-D OCC_OCAF_LIBRARIES:FILEPATH=%LIBRARY_PREFIX%/lib ^
-D BUILD_REVERSEENGINEERING:BOOL=ON ^
-D USE_BOOST_PYTHON:BOOL=OFF ^
-D FREECAD_USE_PYBIND11:BOOL=ON ^
-D SMESH_INCLUDE_DIR:FILEPATH=%LIBRARY_PREFIX%/include/smesh ^
-D FREECAD_USE_EXTERNAL_SMESH:BOOL=ON ^
-D BUILD_FLAT_MESH:BOOL=ON ^
-D OCCT_CMAKE_FALLBACK:BOOL=ON ^
-D PYTHON_EXECUTABLE:FILEPATH=%PREFIX%/python ^
-D BUILD_DYNAMIC_LINK_PYTHON:BOOL=ON ^
-D Boost_NO_BOOST_CMAKE:BOOL=ON ^
-D FREECAD_USE_PCH:BOOL=OFF ^
-D FREECAD_USE_PCL:BOOL=ON ^
-D INSTALL_TO_SITEPACKAGES:BOOL=ON ^
..
if errorlevel 1 exit 1
ninja install
if errorlevel 1 exit 1
rmdir /s /q "%LIBRARY_PREFIX%\doc"
ren %LIBRARY_PREFIX%\bin\FreeCAD.exe freecad.exe
ren %LIBRARY_PREFIX%\bin\FreeCADCmd.exe freecadcmd.exe
Executable
+84
View File
@@ -0,0 +1,84 @@
HOST=$(uname)
mkdir -p build
cd build
if [[ ${FEATURE_DEBUG} = 1 ]]; then
BUILD_TYPE="Debug"
else
BUILD_TYPE="Release"
fi
declare -a CMAKE_PLATFORM_FLAGS
if [[ ${HOST} =~ "Linux" ]]; then
echo "adding hacks for linux"
# temporary workaround for vtk-cmake setup
# should be applied @vtk-feedstock
sed -i 's#/home/conda/feedstock_root/build_artifacts/vtk_.*_build_env/x86_64-conda_cos6-linux-gnu/sysroot/usr/lib.*;##g' ${PREFIX}/lib/cmake/vtk-8.2/Modules/vtkhdf5.cmake
# temporary workaround for qt-cmake:
sed -i 's|_qt5gui_find_extra_libs(EGL.*)|_qt5gui_find_extra_libs(EGL "EGL" "" "")|g' $PREFIX/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake
sed -i 's|_qt5gui_find_extra_libs(OPENGL.*)|_qt5gui_find_extra_libs(OPENGL "GL" "" "")|g' $PREFIX/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake
CMAKE_PLATFORM_FLAGS+=(-DCMAKE_TOOLCHAIN_FILE="${RECIPE_DIR}/cross-linux.cmake")
fi
if [[ ${HOST} =~ "Darwin" ]]; then
# add hacks for osx here!
echo "adding hacks for osx"
#ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
# install space-mouse
if [ ! -d "/Library/Frameworks/3DconnexionClient.framework" ]; then
echo "Installing 3D connexion space mouse drivers."
curl -o /tmp/3dFW.dmg -L 'https://download.3dconnexion.com/drivers/mac/10-6-6_360DF97D-ED08-4ccf-A55E-0BF905E58476/3DxWareMac_v10-6-6_r3234.dmg'
hdiutil attach -readonly /tmp/3dFW.dmg
sudo installer -package /Volumes/3Dconnexion\ Software/Install\ 3Dconnexion\ software.pkg -target /
diskutil eject /Volumes/3Dconnexion\ Software
fi
CMAKE_PLATFORM_FLAGS+=(-DFREECAD_USE_3DCONNEXION:BOOL=ON)
CMAKE_PLATFORM_FLAGS+=(-D3DCONNEXIONCLIENT_FRAMEWORK:FILEPATH="/Library/Frameworks/3DconnexionClient.framework")
fi
cmake \
-G "Ninja" \
-D BUID_WITH_CONDA:BOOL=ON \
-D CMAKE_BUILD_TYPE=${BUILD_TYPE} \
-D CMAKE_INSTALL_PREFIX:FILEPATH=$PREFIX \
-D CMAKE_PREFIX_PATH:FILEPATH=$PREFIX \
-D CMAKE_LIBRARY_PATH:FILEPATH=$PREFIX/lib \
-D CMAKE_INSTALL_LIBDIR:FILEPATH=$PREFIX/lib \
-D CMAKE_INCLUDE_PATH:FILEPATH=$PREFIX/include \
-D BUILD_QT5:BOOL=ON \
-D FREECAD_USE_OCC_VARIANT="Official Version" \
-D OCC_INCLUDE_DIR:FILEPATH=$PREFIX/include \
-D USE_BOOST_PYTHON:BOOL=OFF \
-D FREECAD_USE_PYBIND11:BOOL=ON \
-D BUILD_ENABLE_CXX11:BOOL=ON \
-D SMESH_INCLUDE_DIR:FILEPATH=$PREFIX/include/smesh \
-D FREECAD_USE_EXTERNAL_SMESH=ON \
-D BUILD_FLAT_MESH:BOOL=ON \
-D BUILD_WITH_CONDA:BOOL=ON \
-D PYTHON_EXECUTABLE:FILEPATH=$PREFIX/bin/python \
-D BUILD_FEM_NETGEN:BOOL=ON \
-D OCCT_CMAKE_FALLBACK:BOOL=OFF \
-D FREECAD_USE_QT_DIALOG:BOOL=ON \
-D BUILD_DYNAMIC_LINK_PYTHON:BOOL=OFF \
-D Boost_NO_BOOST_CMAKE:BOOL=ON \
-D FREECAD_USE_PCL:BOOL=ON \
-D INSTALL_TO_SITEPACKAGES:BOOL=ON \
${CMAKE_PLATFORM_FLAGS[@]} \
..
if [ $? != 0 ]; then
echo "CMake failed to configure."
exit 1
fi
echo "FREECAD_USE_3DCONNEXION=${FREECAD_USE_3DCONNEXION}"
ninja install
rm -r ${PREFIX}/share/doc/FreeCAD # smaller size of package!
mv ${PREFIX}/bin/FreeCAD ${PREFIX}/bin/freecad
mv ${PREFIX}/bin/FreeCADCmd ${PREFIX}/bin/freecadcmd
+6
View File
@@ -0,0 +1,6 @@
channel_sources:
- conda-forge,defaults
channel_targets:
- freecad dev
MACOSX_DEPLOYMENT_TARGET: # [osx]
- '10.12' # [osx]
+16
View File
@@ -0,0 +1,16 @@
# this one is important
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_PLATFORM Linux)
# specify the cross compiler
set(CMAKE_C_COMPILER $ENV{CC})
set(CMAKE_CXX_COMPILER $ENV{CXX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH $ENV{PREFIX} $ENV{BUILD_PREFIX}/$ENV{HOST}/sysroot)
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+118
View File
@@ -0,0 +1,118 @@
{% set name = "freecad" %}
{% set version = "0.19.pre" %}
{% set build_number = 142 %}
{% set build_number = build_number + 500 %} # [FEATURE_DEBUG]
package:
name: {{ name }}
version: {{ version }}
source:
# JZ - For local building this is the setup.
path: ../
#git_url: https://github.com/FreeCAD/FreeCAD
#git_tag: master
patches:
- windows_python_interface.patch
build:
number: {{ build_number }}
skip: true # [py < 38]
requirements:
build:
- {{ compiler("cxx") }}
- {{ cdt('mesa-libgl-devel') }} # [linux]
- {{ cdt('mesa-dri-drivers') }} # [linux]
- {{ cdt('mesa-libegl-devel') }} # [linux]
- {{ cdt('libselinux') }} # [linux]
- {{ cdt('libxdamage') }} # [linux]
- {{ cdt('libxfixes') }} # [linux]
- {{ cdt('libxxf86vm') }} # [linux]
- {{ cdt('libxcb') }} # [linux]
- {{ cdt('libxext') }} # [linux]
- {{ cdt('xorg-x11-server-xvfb') }} # [linux]
- {{ cdt('libxau') }} # [linux]
- {{ cdt('libxi-devel') }} # [linux]
- cmake
- ninja
- git
host:
- boost-cpp
- python
- qt
- occt
- xerces-c
- zlib
- vtk
- swig
- eigen
- pybind11
- coin3d
- pivy
- pyside2
- smesh
- netgen 6.2.1808*
- doxygen
- hdf5
- xorg-libxt # [linux]
- freetype
- libspnav # [linux]
- pcl
- six
- ply
- tbb-devel
run:
- {{ pin_compatible("pyside2") }}
- vtk
- occt
- qt
- xerces-c
- zlib
- boost-cpp
- hdf5
- python
- coin3d
- pivy
- smesh
- netgen 6.2.1808*
- xorg-libxt # [linux]
- freetype
- numpy
- six
- pyyaml
- libspnav # [linux]
- pcl
- ply
run_constrained:
- __osx >={{ MACOSX_DEPLOYMENT_TARGET|default("10.9") }} # [osx]
#test:
# commands:
# - FreeCADCmd -t 0
about:
home: https://www.freecadweb.org/
license: LGPL2.1
license_family: LGPL
license_file: LICENSE
summary: 'FreeCAD is a parametric 3D modeler made primarily to design real-life objects of any size. '
description: |
FreeCAD is a general purpose feature-based, parametric 3D modeler for
CAD, MCAD, CAx, CAE and PLM, aimed directly at mechanical engineering
and product design but also fits a wider range of uses in engineering,
such as architecture or other engineering specialities. It is 100% Open
Source (LGPL2+ license) and extremely modular, allowing for very
advanced extension and customization.
FreeCAD is based on OpenCASCADE, a powerful geometry kernel, features an
Open Inventor-compliant 3D scene representation model provided by the
Coin 3D library, and a broad Python API. The interface is built with Qt.
FreeCAD runs exactly the same way on Windows, Mac OSX, BSD and Linux
platforms.
doc_url: https://www.freecadweb.org/wiki/Main_Page
dev_url: https://github.com/FreeCAD/FreeCAD
extra:
recipe-maintainers:
- looooo
+31
View File
@@ -0,0 +1,31 @@
diff --git a/src/Ext/freecad/CMakeLists.txt b/src/Ext/freecad/CMakeLists.txt
index e03b5527e..d9004275b 100644
--- a/src/Ext/freecad/CMakeLists.txt
+++ b/src/Ext/freecad/CMakeLists.txt
@@ -5,7 +5,9 @@ SET(PYTHON_MAIN_DIR ${python_libs})
set(NAMESPACE_INIT "${CMAKE_BINARY_DIR}/Ext/freecad/__init__.py")
if (WIN32)
- set(FREECAD_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_BINDIR})
+ get_filename_component(FREECAD_LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}"
+ REALPATH BASE_DIR "${CMAKE_INSTALL_PREFIX}")
+ set( ${CMAKE_INSTALL_BINDIR})
else()
set(FREECAD_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
endif()
diff --git a/src/Ext/freecad/__init__.py.template b/src/Ext/freecad/__init__.py.template
index 68ca151a5..d5360b252 100644
--- a/src/Ext/freecad/__init__.py.template
+++ b/src/Ext/freecad/__init__.py.template
@@ -12,9 +12,9 @@ except ModuleNotFoundError:
except KeyError:
# 2. we use the default freecad defined for this package
- _path_to_freecad_libdir = "${CMAKE_INSTALL_LIBDIR}"
+ _path_to_freecad_libdir = "${FREECAD_LIBRARY_INSTALL_DIR}"
print("PATH_TO_FREECAD_LIBDIR not specified, using default \
-FreeCAD version in {}".format( "${FREECAD_LIBRARY_INSTALL_DIR}"))
+FreeCAD version in {}".format("${FREECAD_LIBRARY_INSTALL_DIR}"))
_sys.path.append(_path_to_freecad_libdir) # this is the default version
import FreeCAD as app
+6
View File
@@ -0,0 +1,6 @@
mesa-libGL
mesa-dri-drivers
libselinux
libXdamage
libXxf86vm
libXext-devel
+49
View File
@@ -0,0 +1,49 @@
name: freecad_dev
channels:
- conda-forge
- defaults
dependencies:
- cxx-compiler
- cmake
- ninja
- git
- doxygen
- python
- qt
- boost-cpp
- xerces-c
- zlib
- vtk
- swig
- eigen
- occt
- pybind11
- coin3d
- pivy
- smesh
- netgen=6.2.1808*
- hdf5
- freetype
- pcl
- six
- ply
- tbb-devel
- pyside2
- numpy
- six
- pyyaml
- libspnav
- libxcb
- xorg-libxt
# Linux ONLY items
- mesa-libgl-devel # [linux]
- mesa-dri-drivers # [linux]
- mesa-libegl-devel # [linux]
- libselinux # [linux]
- libxdamage # [linux]
- libxfixes # [linux]
- libxxf86vm # [linux]
- libxext # [linux]
- xorg-x11-server-xvfb # [linux]
- libxau # [linux]
- libxi-devel # [linux]
+49
View File
@@ -0,0 +1,49 @@
name: freecad_dev
channels:
- conda-forge
- defaults
dependencies:
- cxx-compiler
- cmake
- ninja
- git
- doxygen
- python
- qt
- boost-cpp
- xerces-c
- zlib
- vtk
- swig
- eigen
- occt
- pybind11
- coin3d
- pivy
- smesh
- netgen=6.2.1808*
- hdf5
- freetype
- pcl
- six
- ply
- tbb-devel
- pyside2
- numpy
- six
- pyyaml
- libspnav
- libxcb
- xorg-libxt
# Linux ONLY items
# - mesa-libgl-devel # [linux]
# - mesa-dri-drivers # [linux]
# - mesa-libegl-devel # [linux]
# - libselinux # [linux]
# - libxdamage # [linux]
# - libxfixes # [linux]
# - libxxf86vm # [linux]
# - libxext # [linux]
# - xorg-x11-server-xvfb # [linux]
# - libxau # [linux]
# - libxi-devel # [linux]
+67
View File
@@ -5,8 +5,75 @@ path_classifiers:
- "src/Mod/Import/App/config_control_design.py"
- "src/Mod/Import/App/ifc2x3.py"
- "src/Mod/Import/App/ifc4.py"
library:
- "src/zipios++/"
- "src/3rdParty/"
- "src/Mod/Import/App/SCL"
- "src/CXX/"
template:
- "src/Tools/examplePy2wiki.py"
- "src/Mode/TemplatePyMod/"
unmaintained:
- "src/Mod/Robot/"
- "src/Mod/Ship/"
legacy:
- "src/Mod/Assembly/"
- "src/Mod/Drawing/"
- "src/Mod/Raytracing/"
- "src/Mod/Spreadsheet/App/Spreadsheet_legacy.py"
- "src/Mod/OpenSCAD/prototype.py"
extraction:
javascript:
index:
filters:
exclude: "**/translations/*.ts"
cpp:
prepare:
packages:
- "cmake"
- "cmake-gui"
- "libboost-date-time-dev"
- "libboost-dev"
- "libboost-filesystem-dev"
- "libboost-graph-dev"
- "libboost-iostreams-dev"
- "libboost-program-options-dev"
- "libboost-python-dev"
- "libboost-regex-dev"
- "libboost-serialization-dev"
- "libboost-thread-dev"
- "libcoin-dev"
- "libeigen3-dev"
- "libgts-bin"
- "libgts-dev"
- "libkdtree++-dev"
- "libmedc-dev"
- "libocct-data-exchange-dev"
- "libocct-ocaf-dev"
- "libocct-visualization-dev"
- "libopencv-dev"
- "libproj-dev"
- "libpyside2-dev"
- "libshiboken2-dev"
- "libspnav-dev"
- "libvtk7-dev"
- "libx11-dev"
- "libxerces-c-dev"
- "libzipios++-dev"
- "occt-draw"
- "pyside2-tools"
- "python3-dev"
- "python3-matplotlib"
- "python3-pivy"
- "python3-ply"
- "python3-pyside2.qtcore"
- "python3-pyside2uic"
- "qtbase5-dev"
- "qttools5-dev"
- "swig"
configure:
command: "cmake ./ -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GUI=OFF -DBUILD_ARCH=OFF\
\ -DBUILD_DRAWING=OFF -DBUILD_IMAGE=OFF -DBUILD_INSPECTION=OFF -DBUILD_OPENSCAD=OFF\
\ -DBUILD_RAYTRACING=OFF -DBUILD_REVERSEENGINEERING=OFF -DBUILD_SURFACE=OFF -DBUILD_START=OFF\
\ -DBUILD_ROBOT=OFF -DBUILD_PATH=OFF -DBUILD_FEM=OFF"
+24 -9
View File
@@ -1,6 +1,6 @@
# This package depends on automagic byte compilation
# https://fedoraproject.org/wiki/Changes/No_more_automagic_Python_bytecompilation_phase_2
%global _python_bytecompile_extra 1
# https://fedoraproject.org/wiki/Changes/No_more_automagic_Python_bytecompilation_phase_3
%global py_bytecompile 1
# Setup python target for shiboken so the right cmake file is imported.
%global py_suffix %(%{__python3} -c "import sysconfig; print(sysconfig.get_config_var('SOABI'))")
@@ -17,6 +17,9 @@
# rpmbuild --without=bundled_smesh: don't use bundled version of Salome's Mesh
%global bundled_smesh %{?_without_bundled_smesh: 0} %{?!_without_bundled_smesh: 1}
# Prevent RPM from doing its magical 'build' directory for now
%global __cmake_in_source_build 0
# See FreeCAD-master/src/3rdParty/salomesmesh/CMakeLists.txt to find this out.
%global bundled_smesh_version 7.7.1.0
@@ -28,8 +31,8 @@
Name: %{name}
Epoch: 1
Version: 0.19
Release: pre_{{{ git_commit_no }}}
Version: 0.20
Release: pre_{{{git_commit_no}}}%{?dist}
Summary: A general purpose 3D CAD modeler
Group: Applications/Engineering
@@ -46,8 +49,10 @@ BuildRequires: git
# Development Libraries
BuildRequires: Coin3-devel
BuildRequires: Coin4-devel
%if 0%{?fedora} < 35
BuildRequires: Inventor-devel
%endif
BuildRequires: opencascade-devel
BuildRequires: boost-devel
BuildRequires: boost-python3-devel
@@ -70,6 +75,7 @@ BuildRequires: netgen-mesher-devel
BuildRequires: netgen-mesher-devel-private
BuildRequires: python3-pivy
BuildRequires: mesa-libEGL-devel
BuildRequires: openmpi-devel
BuildRequires: pcl-devel
BuildRequires: pyside2-tools
BuildRequires: python3
@@ -80,8 +86,10 @@ BuildRequires: python3-pycxx-devel
%endif
BuildRequires: python3-pyside2-devel
BuildRequires: python3-shiboken2-devel
BuildRequires: qt5-devel
BuildRequires: qt5-qtwebkit-devel
BuildRequires: qt5-qtsvg-devel
BuildRequires: qt5-qttools-static
BuildRequires: qt5-qtxmlpatterns-devel
%if ! %{bundled_smesh}
BuildRequires: smesh-devel
%endif
@@ -195,8 +203,8 @@ LDFLAGS='-Wl,--as-needed -Wl,--no-undefined'; export LDFLAGS
-DPYTHON_EXECUTABLE:FILEPATH=/usr/bin/python3 \
-DMEDFILE_INCLUDE_DIRS=%{MEDFILE_INCLUDE_DIRS} \
-DOpenGL_GL_PREFERENCE=GLVND \
-DCOIN3D_INCLUDE_DIR=%{_includedir}/Coin3 \
-DCOIN3D_DOC_PATH=%{_datadir}/Coin3/Coin \
-DCOIN3D_INCLUDE_DIR=%{_includedir}/Coin4 \
-DCOIN3D_DOC_PATH=%{_datadir}/Coin4/Coin \
-DFREECAD_USE_EXTERNAL_PIVY=TRUE \
-DUSE_OCC=TRUE \
%if ! %{bundled_smesh}
@@ -239,6 +247,9 @@ mv %{buildroot}%{_libdir}/%{name}/share/metainfo/* %{buildroot}%{_metainfodir}/
mkdir %{buildroot}%{_datadir}/applications/
mv %{buildroot}%{_libdir}/%{name}/share/applications/* %{buildroot}%{_datadir}/applications/
mkdir -p %{buildroot}%{_datadir}/thumbnailers/
mv %{buildroot}%{_libdir}/%{name}/share/thumbnailers/* %{buildroot}%{_datadir}/thumbnailers/
mkdir -p %{buildroot}%{_datadir}/icons/hicolor/scalable/
mv %{buildroot}%{_libdir}/%{name}/share/icons/hicolor/scalable/* %{buildroot}%{_datadir}/icons/hicolor/scalable/
@@ -258,7 +269,8 @@ popd
# Remove obsolete Start_Page.html
rm -f %{buildroot}%{_docdir}/%{name}/Start_Page.html
# Belongs in %%license not %%doc
rm -f %{buildroot}%{_docdir}/freecad/ThirdPartyLibraries.html
#No longer present?
#rm -f %{buildroot}%{_docdir}/freecad/ThirdPartyLibraries.html
# Bug maintainers to keep %%{plugins} macro up to date.
#
@@ -324,7 +336,10 @@ fi
%{_datadir}/icons/hicolor/scalable/*
%{_datadir}/pixmaps/*
%{_datadir}/mime/packages/*
%{_datadir}/thumbnailers/*
%files data
%{_datadir}/%{name}/
%{_docdir}/%{name}/%{name}.q*
%{_docdir}/%{name}/CONTRIBUTORS
%{_docdir}/%{name}/LICENSE.html
+1 -1
View File
@@ -1,4 +1,4 @@
function git_commit_no {
commits=$(curl -s 'https://api.github.com/repos/FreeCAD/FreeCAD/compare/120ca87015...master' | grep "ahead_by" | sed -s 's/ //g' | sed -s 's/"ahead_by"://' | sed -s 's/,//')
echo $((commits + 1))
echo -n $((commits + 1))
}
+2 -1
View File
@@ -3,4 +3,5 @@ matplotlib==3.0.2; python_version >= '3.0'
PySide==1.2.4
# PySide2==5.12.0
Shiboken==1.2.2
six==1.12.0
six==1.12.0
Markdown==3.2.2
+48 -5
View File
@@ -1,20 +1,60 @@
# SGEOM cmake build file
#PROJECT(SMESH Fortran CXX)
set(CMAKE_AUTOMOC FALSE)
SET(SMESH_VERSION_MAJOR 7) # see main CMakeLists.txt of FreeCAD
SET(SMESH_VERSION_MINOR 7)
SET(SMESH_VERSION_PATCH 1)
SET(SMESH_VERSION_TWEAK 0)
# Suppress gcc warnings
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wno-sign-compare -Wno-reorder -Wno-switch -Wno-unused-variable -Wno-unused-but-set-variable -Wno-comment -Wno-unused-parameter -Wno-empty-body -Wno-pedantic")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable -Wno-unused-but-set-variable")
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-unused-result" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-result")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result")
endif ()
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-maybe-uninitialized" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
endif ()
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-missing-field-initializers" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers")
endif ()
# Suppress clang warnings
elseif(CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wno-sign-compare -Wno-reorder -Wno-switch -Wno-unused-variable -Wno-unused-private-field -Wno-unused-function -Wno-sometimes-uninitialized -Wno-overloaded-virtual -Wno-dynamic-class-memaccess -Wno-comment -Wno-unused-parameter -Wno-extra-semi")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wno-self-assign -Wno-sign-compare -Wno-logical-op-parentheses -Wno-reorder -Wno-switch -Wno-switch-enum -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-private-field")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wno-unused-function -Wno-sometimes-uninitialized -Wno-overloaded-virtual -Wno-dynamic-class-memaccess -Wno-comment -Wno-unused-parameter -Wno-extra-semi")
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-deprecated-copy" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-copy")
endif ()
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-missing-field-initializers" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers")
endif ()
unset(_flag_found CACHE)
check_cxx_compiler_flag("-Wno-c++17-extensions" _flag_found)
if (_flag_found)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++17-extensions")
endif ()
endif()
if(CMAKE_COMPILER_IS_CLANGXX)
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wno-self-assign -Wno-reorder -Wno-switch-enum -Wno-unknown-pragmas -Wno-logical-op-parentheses -Wno-unused-variable -Wno-unused-function -Wno-overloaded-virtual")
endif()
if (VTK_OPTIONS)
add_definitions(${VTK_OPTIONS})
@@ -386,7 +426,10 @@ if(WIN32)
else()
set_target_properties(NETGENPlugin PROPERTIES COMPILE_FLAGS "${NETGEN_CXX_FLAGS}")
endif(WIN32)
IF(NOT NETGEN_VERSION_C LESS NETGEN_VERSION_62) # Version >= 6.2
IF(NOT NETGEN_VERSION_C LESS NETGEN_VERSION_62_2004) # Version >= 6.2.2004
set_target_properties(NETGENPlugin PROPERTIES CXX_STANDARD_REQUIRED ON)
set_target_properties(NETGENPlugin PROPERTIES CXX_STANDARD 17) # Standard std=c++1y could work aswell
ELSEIF(NOT NETGEN_VERSION_C LESS NETGEN_VERSION_62) # Version >= 6.2
set_target_properties(NETGENPlugin PROPERTIES CXX_STANDARD_REQUIRED ON)
set_target_properties(NETGENPlugin PROPERTIES CXX_STANDARD 14) # Standard std=c++1y could work aswell
ENDIF()
+3
View File
@@ -32,6 +32,9 @@
#ifndef WIN32
#include <sys/time.h>
#else
// avoid name collision with std::byte in C++17
#define NOCRYPT
#define NOGDI
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"winmm.lib")
+4 -1
View File
@@ -106,8 +106,11 @@ namespace GEOMUtils
* \brief Sort shapes in the list by their coordinates.
* \param SL The list of shapes to sort.
*/
struct CompareShapes : public std::binary_function<TopoDS_Shape, TopoDS_Shape, bool>
struct CompareShapes
{
typedef TopoDS_Shape first_argument_type;
typedef TopoDS_Shape second_argument_type;
typedef bool result_type;
CompareShapes (bool isOldSorting)
: myIsOldSorting(isOldSorting) {}
+3 -3
View File
@@ -36,7 +36,7 @@
#include <SMESH_Algo.hxx>
#include <SMESH_ProxyMesh.hxx>
#define NETGEN_VERSION_STRING(a,b) (a << 16) + (b << 8)
#define NETGEN_VERSION_STRING(a,b,c) (a << 16) + (b << 8) + (c)
namespace nglib {
#include <nglib.h>
@@ -85,7 +85,7 @@ struct NETGENPlugin_ngMeshInfo
struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper
{
bool _isComputeOk;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
nglib::Ng_Mesh * _ngMesh;
#else
std::shared_ptr<nglib::Ng_Mesh> _ngMesh;
@@ -204,7 +204,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
bool _optimize;
int _fineness;
bool _isViscousLayers2D;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
netgen::Mesh* _ngMesh;
#else
std::shared_ptr<netgen::Mesh> _ngMesh;
+7 -2
View File
@@ -40,11 +40,16 @@
#include <vtkType.h>
#include <vtkCellType.h>
#include <vtkCellArray.h>
//typedef unsigned short UShortType;
typedef short ShortType;
typedef int LongType;
#ifdef VTK_CELL_ARRAY_V2
typedef const vtkIdType* vtkIdTypePtr;
#else
typedef vtkIdType* vtkIdTypePtr;
#endif
class SMDS_MeshNode;
class SMDS_MeshEdge;
class SMDS_MeshFace;
@@ -192,7 +197,7 @@ protected:
//! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells
int myID;
//! index in vtkUnstructuredGrid
int myVtkID;
vtkIdType myVtkID;
//! SMDS_Mesh identification in SMESH
ShortType myMeshId;
//! SubShape and SubMesh identification in SMESHDS
@@ -95,7 +95,11 @@ public:
std::map<int, std::map<long,int> >& nodeQuadDomains);
vtkCellLinks* GetLinks()
{
#ifdef VTK_CELL_ARRAY_V2
return static_cast<vtkCellLinks*>(GetCellLinks());
#else
return Links;
#endif
}
SMDS_Downward* getDownArray(unsigned char vtkType)
{
+1 -1
View File
@@ -53,7 +53,7 @@ namespace SMESH{
class SMESHCONTROLS_EXPORT Functor
{
public:
~Functor(){}
virtual ~Functor(){}
virtual void SetMesh( const SMDS_Mesh* theMesh ) = 0;
virtual SMDSAbs_ElementType GetType() const = 0;
};
+5 -4
View File
@@ -51,13 +51,14 @@ class SMESH_EXPORT Unexpect { //save / retrieve unexpected exceptions treatment
PVF old;
public :
#ifndef WNT
// std::set_unexpected has been removed in C++17
Unexpect( PVF f )
{ old = std::set_unexpected(f); }
~Unexpect() { std::set_unexpected(old); }
{ /*old = std::set_unexpected(f);*/old = f; }
~Unexpect() { /*std::set_unexpected(old);*/ }
#else
Unexpect( PVF f )
{ old = std::set_unexpected(f); }
~Unexpect() { std::set_unexpected(old); }
{ old = ::set_unexpected(f); }
~Unexpect() { ::set_unexpected(old); }
#endif
};
+3 -2
View File
@@ -39,9 +39,10 @@ class UTILS_EXPORT Unexpect { //save / retrieve unexpected exceptions treatment
PVF old;
public :
#ifndef WIN32
// std::set_unexpected has been removed in C++17
Unexpect( PVF f )
{ old = std::set_unexpected(f); }
~Unexpect() { std::set_unexpected(old); }
{ /*old = std::set_unexpected(f);*/old = f; }
~Unexpect() { /*std::set_unexpected(old);*/ }
#else
Unexpect( PVF f )
{ old = ::set_unexpected(f); }
@@ -87,6 +87,10 @@ namespace nglib {
#undef NETGEN_PYTHON
#endif
#ifndef WIN32
#undef DLL_HEADER
#endif
#include <occgeom.hpp>
#include <meshing.hpp>
//#include <ngexception.hpp>
@@ -96,11 +100,14 @@ namespace nglib {
#endif
namespace netgen {
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,2004)
typedef Refinement OCCRefinementSurfaces;
DLL_HEADER extern int OCCGenerateMesh(OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&, int, int);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, MeshingParameters&, int, int);
#else
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
@@ -181,7 +188,7 @@ NETGENPlugin_Mesher::~NETGENPlugin_Mesher()
if ( _ptrToMe )
*_ptrToMe = NULL;
_ptrToMe = 0;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
_ngMesh = NULL;
#endif
}
@@ -2475,7 +2482,7 @@ bool NETGENPlugin_Mesher::Compute()
// -------------------------
// Generate the mesh
// -------------------------
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
_ngMesh = NULL;
#endif
NETGENPlugin_ngMeshInfo initState; // it remembers size of ng mesh equal to size of Smesh
@@ -2513,10 +2520,10 @@ bool NETGENPlugin_Mesher::Compute()
occgeo.face_maxh = mparams.maxh;
// Let netgen create _ngMesh and calculate element size on not meshed shapes
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0,0)
char *optstr = 0;
#endif
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
int startWith = netgen::MESHCONST_ANALYSE;
int endWith = netgen::MESHCONST_ANALYSE;
#else
@@ -2525,9 +2532,9 @@ bool NETGENPlugin_Mesher::Compute()
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, startWith, endWith, optstr);
@@ -2544,7 +2551,7 @@ bool NETGENPlugin_Mesher::Compute()
err = 0; //- MESHCONST_ANALYSE isn't so important step
if ( !_ngMesh )
return false;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
ngLib.setMesh(( Ng_Mesh*) _ngMesh);
#else
ngLib.setMesh(( Ng_Mesh*) _ngMesh.get() );
@@ -2612,7 +2619,7 @@ bool NETGENPlugin_Mesher::Compute()
intOccgeo.shape = occgeo.shape;
intOccgeo.face_maxh.SetSize(intOccgeo.fmap.Extent());
intOccgeo.face_maxh = netgen::mparam.maxh;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
netgen::Mesh *tmpNgMesh = NULL;
#else
std::shared_ptr<netgen::Mesh> tmpNgMesh; // = std::make_shared<netgen::Mesh>();
@@ -2625,9 +2632,9 @@ bool NETGENPlugin_Mesher::Compute()
// let netgen create a temporary mesh
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, mparams, startWith, endWith);
#else
netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, startWith, endWith, optstr);
@@ -2636,22 +2643,22 @@ bool NETGENPlugin_Mesher::Compute()
return false;
// copy LocalH from the main to temporary mesh
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState.transferLocalH( _ngMesh, tmpNgMesh );
#else
initState.transferLocalH( _ngMesh.get(), tmpNgMesh.get() );
#endif
// compute mesh on internal edges
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
startWith = endWith = netgen::MESHCONST_MESHEDGES;
#else
mparams.perfstepsstart = mparams.perfstepsend = netgen::MESHCONST_MESHEDGES;
#endif
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, startWith, endWith, optstr);
@@ -2663,7 +2670,7 @@ bool NETGENPlugin_Mesher::Compute()
comment << text(ex);
err = 1;
}
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState.restoreLocalH( tmpNgMesh );
#else
initState.restoreLocalH( tmpNgMesh.get() );
@@ -2674,7 +2681,7 @@ bool NETGENPlugin_Mesher::Compute()
FillSMesh( intOccgeo, *tmpNgMesh, initState, *_mesh, tmpNodeVec, comment );
err = ( err || !comment.empty() );
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)tmpNgMesh);
#else
tmpNgMesh.reset();
@@ -2687,7 +2694,7 @@ bool NETGENPlugin_Mesher::Compute()
err = ! ( FillNgMesh(occgeo, *_ngMesh, nodeVec, meshedSM[ MeshDim_0D ]) &&
FillNgMesh(occgeo, *_ngMesh, nodeVec, meshedSM[ MeshDim_1D ], &quadHelper));
}
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
@@ -2696,7 +2703,7 @@ bool NETGENPlugin_Mesher::Compute()
// Compute 1d mesh
if (!err)
{
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
startWith = endWith = netgen::MESHCONST_MESHEDGES;
#else
mparams.perfstepsstart = mparams.perfstepsend = netgen::MESHCONST_MESHEDGES;
@@ -2704,9 +2711,9 @@ bool NETGENPlugin_Mesher::Compute()
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, startWith, endWith, optstr);
@@ -2773,7 +2780,7 @@ bool NETGENPlugin_Mesher::Compute()
FillSMesh( occgeo, *_ngMesh, initState, *_mesh, nodeVec, comment );
// add segments to faces with internal vertices
AddIntVerticesInFaces( occgeo, *_ngMesh, nodeVec, internals );
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
@@ -2785,7 +2792,7 @@ bool NETGENPlugin_Mesher::Compute()
{
if ( !internals.hasInternalVertexInFace() ) {
FillSMesh( occgeo, *_ngMesh, initState, *_mesh, nodeVec, comment );
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
@@ -2815,7 +2822,7 @@ bool NETGENPlugin_Mesher::Compute()
if ( !error ) error = SMESH_ComputeError::New();
}
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
@@ -2823,7 +2830,7 @@ bool NETGENPlugin_Mesher::Compute()
}
// Let netgen compute 2D mesh
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
startWith = netgen::MESHCONST_MESHSURFACE;
endWith = _optimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE;
#else
@@ -2833,9 +2840,9 @@ bool NETGENPlugin_Mesher::Compute()
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, startWith, endWith, optstr);
@@ -2894,7 +2901,7 @@ bool NETGENPlugin_Mesher::Compute()
// fill _ngMesh with faces of sub-meshes
err = ! ( FillNgMesh(occgeo, *_ngMesh, nodeVec, meshedSM[ MeshDim_2D ], &quadHelper));
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
@@ -2919,7 +2926,7 @@ bool NETGENPlugin_Mesher::Compute()
_ngMesh->SetGlobalH (mparams.maxh);
mparams.grading = 0.4;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0,0)
_ngMesh->CalcLocalH();
#else
_ngMesh->CalcLocalH(mparams.grading);
@@ -2935,14 +2942,14 @@ bool NETGENPlugin_Mesher::Compute()
AddIntVerticesInSolids( occgeo, *_ngMesh, nodeVec, internals );
// duplicate mesh faces on internal faces
FixIntFaces( occgeo, *_ngMesh, internals );
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
#else
initState = NETGENPlugin_ngMeshInfo(_ngMesh.get());
#endif
}
// Let netgen compute 3D mesh
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
startWith = endWith = netgen::MESHCONST_MESHVOLUME;
#else
mparams.perfstepsstart = mparams.perfstepsend = netgen::MESHCONST_MESHVOLUME;
@@ -2950,9 +2957,9 @@ bool NETGENPlugin_Mesher::Compute()
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, startWith, endWith, optstr);
@@ -2980,7 +2987,7 @@ bool NETGENPlugin_Mesher::Compute()
// Let netgen optimize 3D mesh
if ( !err && _optimize )
{
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
startWith = endWith = netgen::MESHCONST_OPTVOLUME;
#else
mparams.perfstepsstart = mparams.perfstepsend = netgen::MESHCONST_OPTVOLUME;
@@ -2988,9 +2995,9 @@ bool NETGENPlugin_Mesher::Compute()
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, mparams, startWith, endWith);
#else
err = netgen::OCCGenerateMesh(occgeo, _ngMesh, startWith, endWith, optstr);
@@ -3202,15 +3209,15 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
// let netgen create _ngMesh and calculate element size on not meshed shapes
NETGENPlugin_NetgenLibWrapper ngLib;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
netgen::Mesh *ngMesh = NULL;
#else
std::shared_ptr<netgen::Mesh> ngMesh; // = std::make_shared<netgen::Mesh>();
#endif
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0,0)
char *optstr = 0;
#endif
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
int startWith = netgen::MESHCONST_ANALYSE;
int endWith = netgen::MESHCONST_MESHEDGES;
#else
@@ -3218,9 +3225,9 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
mparams.perfstepsend = netgen::MESHCONST_MESHEDGES;
#endif
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
int err = netgen::OCCGenerateMesh(occgeo, ngMesh, mparams);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
int err = netgen::OCCGenerateMesh(occgeo, ngMesh, mparams, startWith, endWith);
#else
int err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
@@ -3228,7 +3235,7 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
if(netgen::multithread.terminate)
return false;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
ngLib.setMesh(( Ng_Mesh*) ngMesh);
#else
ngLib.setMesh(( Ng_Mesh*) ngMesh.get());
@@ -3693,7 +3700,7 @@ void NETGENPlugin_ngMeshInfo::transferLocalH( netgen::Mesh* fromMesh,
{
if ( !fromMesh->LocalHFunctionGenerated() ) return;
if ( !toMesh->LocalHFunctionGenerated() )
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0,0)
toMesh->CalcLocalH();
#else
toMesh->CalcLocalH(netgen::mparam.grading);
@@ -4090,7 +4097,7 @@ NETGENPlugin_NetgenLibWrapper::NETGENPlugin_NetgenLibWrapper()
std::cout.rdbuf( netgen::mycout->rdbuf() );
#endif
}
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
_ngMesh = Ng_NewMesh();
#else
_ngMesh = std::make_shared<Ng_Mesh>();
@@ -4105,7 +4112,7 @@ NETGENPlugin_NetgenLibWrapper::NETGENPlugin_NetgenLibWrapper()
NETGENPlugin_NetgenLibWrapper::~NETGENPlugin_NetgenLibWrapper()
{
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
Ng_DeleteMesh( _ngMesh );
#else
_ngMesh.reset();
@@ -4129,7 +4136,7 @@ NETGENPlugin_NetgenLibWrapper::~NETGENPlugin_NetgenLibWrapper()
void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh )
{
if ( _ngMesh )
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
Ng_DeleteMesh( _ngMesh );
_ngMesh = mesh;
#else
@@ -55,6 +55,10 @@ namespace nglib {
#undef NETGEN_PYTHON
#endif
#ifndef WIN32
#undef DLL_HEADER
#endif
#include <meshing.hpp>
#if defined(__clang__)
@@ -54,6 +54,10 @@ namespace nglib {
#undef NETGEN_PYTHON
#endif
#ifndef WIN32
#undef DLL_HEADER
#endif
#include <meshing.hpp>
#if defined(__clang__)
@@ -72,6 +72,10 @@ namespace nglib {
#undef NETGEN_PYTHON
#endif
#ifndef WIN32
#undef DLL_HEADER
#endif
#include <occgeom.hpp>
#include <meshing.hpp>
//#include <meshing/meshtype.hpp>
@@ -81,17 +85,32 @@ namespace nglib {
#endif
namespace netgen {
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,2004)
// https://github.com/NGSolve/netgen/commit/bee097b153b43d9346819789534536cd1b773428
int OCCGenerateMesh(OCCGeometry& geo, shared_ptr<Mesh>& mesh, MeshingParameters& mparams)
{
//geo.SetOCCParameters(occparam);
int perfstepsend = mparams.perfstepsend;
if (perfstepsend == netgen::MESHCONST_OPTSURFACE) {
mparams.perfstepsend = netgen::MESHCONST_MESHSURFACE;
}
auto result = geo.GenerateMesh(mesh, mparams);
mparams.perfstepsend = perfstepsend;
return result;
}
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
DLL_HEADER extern int OCCGenerateMesh(OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&, int, int);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, MeshingParameters&, int, int);
#else
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
#endif
DLL_HEADER extern MeshingParameters mparam;
#if NETGEN_VERSION <= NETGEN_VERSION_STRING(6,2,1808)
DLL_HEADER extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh);
#endif
}
using namespace std;
@@ -262,7 +281,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
ngLib._isComputeOk = false;
netgen::Mesh ngMeshNoLocSize;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize };
#else
netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh.get(), & ngMeshNoLocSize };
@@ -310,15 +329,29 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
}
// set local size depending on curvature and NOT closeness of EDGEs
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,2004)
// https://github.com/NGSolve/netgen/commit/073e215bb6bc97d8712990cba9cc6e9e1e4d8b2a
netgen::mparam.closeedgefac = std::nullopt;
#else
netgen::occparam.resthcloseedgeenable = false;
#endif
//netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading;
occgeoComm.face_maxh = netgen::mparam.maxh;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,2004)
// https://github.com/NGSolve/netgen/commit/bee097b153b43d9346819789534536cd1b773428
occgeoComm.Analyse(*ngMeshes[0], netgen::mparam);
#else
netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] );
#endif
occgeoComm.emap.Clear();
occgeoComm.vmap.Clear();
// set local size according to size of existing segments
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,2004)
const double factor = netgen::mparam.closeedgefac.value();
#else
const double factor = netgen::occparam.resthcloseedgefac;
#endif
TopTools_IndexedMapOfShape edgeMap;
TopExp::MapShapes( aMesh.GetShapeToMesh(), TopAbs_EDGE, edgeMap );
for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
@@ -489,7 +522,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
// -------------------------
// Generate surface mesh
// -------------------------
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
const int startWith = MESHCONST_MESHSURFACE;
const int endWith = toOptimize ? MESHCONST_OPTSURFACE : MESHCONST_MESHSURFACE;
#else
@@ -499,14 +532,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
SMESH_Comment str;
try {
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0,0)
std::shared_ptr<netgen::Mesh> mesh_ptr(ngMesh, [](netgen::Mesh*){});
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeom, mesh_ptr, netgen::mparam);
#else
err = netgen::OCCGenerateMesh(occgeom, mesh_ptr, netgen::mparam, startWith, endWith);
#endif
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
err = netgen::OCCGenerateMesh(occgeom, ngMesh, netgen::mparam, startWith, endWith);
#else
char *optstr = 0;
@@ -81,6 +81,10 @@
#undef NETGEN_PYTHON
#endif
#ifndef WIN32
#undef DLL_HEADER
#endif
#include <occgeom.hpp>
#if defined(__clang__)
@@ -91,11 +95,11 @@ namespace nglib {
#include <nglib.h>
}
namespace netgen {
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, shared_ptr<Mesh>&, MeshingParameters&, int, int);
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, MeshingParameters&, int, int);
#else
DLL_HEADER extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
@@ -228,7 +232,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
int Netgen_triangle[3];
NETGENPlugin_NetgenLibWrapper ngLib;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
#else
Ng_Mesh * Netgen_mesh = ngLib._ngMesh.get();
@@ -452,11 +456,11 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
netgen::Mesh* ngMesh = (netgen::Mesh*)Netgen_mesh;
int Netgen_NbOfNodes = Ng_GetNP(Netgen_mesh);
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(5,0,0)
char *optstr = 0;
#endif
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
int startWith = netgen::MESHCONST_MESHVOLUME;
int endWith = netgen::MESHCONST_OPTVOLUME;
#else
@@ -472,7 +476,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
{
aMesher.SetParameters( _hypParameters );
if ( !_hypParameters->GetOptimize() )
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,2,0)
endWith = netgen::MESHCONST_MESHVOLUME;
#else
netgen::mparam.perfstepsend = netgen::MESHCONST_MESHVOLUME;
@@ -503,14 +507,14 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
try
{
OCC_CATCH_SIGNALS;
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,0,0)
std::shared_ptr<netgen::Mesh> mesh_ptr(ngMesh, [](netgen::Mesh*){});
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2)
#if NETGEN_VERSION >= NETGEN_VERSION_STRING(6,2,0)
err = netgen::OCCGenerateMesh(occgeo, mesh_ptr, netgen::mparam);
#else
err = netgen::OCCGenerateMesh(occgeo, mesh_ptr, netgen::mparam, startWith, endWith);
#endif
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0)
#elif NETGEN_VERSION >= NETGEN_VERSION_STRING(5,0,0)
ngMesh->CalcLocalH(netgen::mparam.grading);
err = netgen::OCCGenerateMesh(occgeo, ngMesh, netgen::mparam, startWith, endWith);
#else
@@ -635,7 +639,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
int Netgen_tetrahedron[4];
NETGENPlugin_NetgenLibWrapper ngLib;
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0)
#if NETGEN_VERSION < NETGEN_VERSION_STRING(6,0,0)
Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
#else
Ng_Mesh * Netgen_mesh = ngLib._ngMesh.get();
+8 -1
View File
@@ -67,10 +67,16 @@ void SMDS_BallElement::SetDiameter(double diameter)
bool SMDS_BallElement::ChangeNode (const SMDS_MeshNode * node)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
cellPoints->SetId(0, node->getVtkId());
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
pts[0] = node->getVtkId();
#endif
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
return true;
}
@@ -83,7 +89,8 @@ void SMDS_BallElement::Print (std::ostream & OS) const
const SMDS_MeshNode* SMDS_BallElement::GetNode (const int ind) const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( myVtkID, npts, pts );
return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ 0 ]);
}
+22 -22
View File
@@ -303,7 +303,7 @@ int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
void SMDS_Down1D::setNodes(int cellId, int vtkId)
{
vtkIdType npts = 0;
vtkIdType *pts; // will refer to the point id's of the face
vtkIdTypePtr pts; // will refer to the point id's of the face
_grid->GetCellPoints(vtkId, npts, pts);
// MESSAGE(vtkId << " " << npts << " " << _nbDownCells);
//ASSERT(npts == _nbDownCells);
@@ -357,7 +357,7 @@ int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
{
vtkIdType point = pts[i];
int numCells = _grid->GetLinks()->GetNcells(point);
vtkIdType *cells = _grid->GetLinks()->GetCells(point);
vtkIdTypePtr cells = _grid->GetLinks()->GetCells(point);
for (int j = 0; j < numCells; j++)
{
int vtkCellId = cells[j];
@@ -532,7 +532,7 @@ int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
// --- find point id's of the face
vtkIdType npts = 0;
vtkIdType *pts; // will refer to the point id's of the face
vtkIdTypePtr pts; // will refer to the point id's of the face
_grid->GetCellPoints(cellId, npts, pts);
vector<int> nodes;
for (int i = 0; i < npts; i++)
@@ -577,7 +577,7 @@ int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
vtkIdType point = pts[i];
int numCells = _grid->GetLinks()->GetNcells(point);
//MESSAGE("cells pour " << i << " " << numCells);
vtkIdType *cells = _grid->GetLinks()->GetCells(point);
vtkIdTypePtr cells = _grid->GetLinks()->GetCells(point);
for (int j = 0; j < numCells; j++)
{
int vtkCellId = cells[j];
@@ -627,7 +627,7 @@ int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
{
vtkIdType npts = 0;
vtkIdType *pts; // will refer to the point id's of the face
vtkIdTypePtr pts; // will refer to the point id's of the face
_grid->GetCellPoints(vtkId, npts, pts);
// MESSAGE(vtkId << " " << npts << " " << _nbNodes);
//ASSERT(npts == _nbNodes);
@@ -795,7 +795,7 @@ void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
{
int vtkId = this->_vtkCellIds[cellId];
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(vtkId, npts, nodes);
for (int i = 0; i < npts; i++)
nodeSet.insert(nodes[i]);
@@ -1126,7 +1126,7 @@ void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& o
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1178,7 +1178,7 @@ void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& face
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1234,7 +1234,7 @@ void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1288,7 +1288,7 @@ void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType&
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1357,7 +1357,7 @@ void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>&
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1435,7 +1435,7 @@ void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& fa
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1500,7 +1500,7 @@ void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdTy
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1580,7 +1580,7 @@ void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1660,7 +1660,7 @@ void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& o
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1744,7 +1744,7 @@ void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& face
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1810,7 +1810,7 @@ void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -1896,7 +1896,7 @@ void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType&
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -1981,7 +1981,7 @@ void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& or
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -2036,7 +2036,7 @@ void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& faces
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
@@ -2112,7 +2112,7 @@ void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>
//MESSAGE("cellId = " << cellId);
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
set<int> tofind;
@@ -2167,7 +2167,7 @@ void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& f
// --- find point id's of the volume
vtkIdType npts = 0;
vtkIdType *nodes; // will refer to the point id's of the volume
vtkIdTypePtr nodes; // will refer to the point id's of the volume
_grid->GetCellPoints(cellId, npts, nodes);
// --- create all the ordered list of node id's for each face
+5 -1
View File
@@ -4768,7 +4768,11 @@ void SMDS_Mesh::dumpGrid(string ficdump)
ficcon << endl;
}
ficcon << "-------------------------------- connectivity " << nbPoints << endl;
vtkCellLinks *links = myGrid->GetCellLinks();
#ifdef VTK_CELL_ARRAY_V2
vtkCellLinks *links = static_cast<vtkCellLinks*>(myGrid->GetCellLinks());
#else
vtkCellLinks *links = myGrid->GetCellLinks();
#endif
for (int i=0; i<nbPoints; i++)
{
int ncells = links->GetNcells(i);
@@ -146,6 +146,17 @@ bool SMDS_Mesh0DElement::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbN
if ( nbNodes == 1 )
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
if (nbNodes != cellPoints->GetNumberOfIds())
{
MESSAGE("ChangeNodes problem: not the same number of nodes " << cellPoints->GetNumberOfIds() << " -> " << nbNodes);
return false;
}
myNode = nodes[0];
cellPoints->SetId(0, myNode->getVtkId());
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
@@ -156,6 +167,7 @@ bool SMDS_Mesh0DElement::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbN
}
myNode = nodes[0];
pts[0] = myNode->getVtkId();
#endif
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
return true;
+5 -5
View File
@@ -191,7 +191,7 @@ public:
SMDS_ElemIteratorPtr SMDS_MeshNode::
GetInverseElementIterator(SMDSAbs_ElementType type) const
{
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks())->GetLink(myVtkID);
//MESSAGE("myID " << myID << " ncells " << l.ncells);
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
}
@@ -251,7 +251,7 @@ elementsIterator(SMDSAbs_ElementType type) const
return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
else
{
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks())->GetLink(myVtkID);
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
}
}
@@ -350,7 +350,7 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
const SMDS_MeshCell *cell = dynamic_cast<const SMDS_MeshCell*> (ME);
assert(cell);
SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkCellLinks *Links = grid->GetCellLinks();
vtkCellLinks *Links = static_cast<vtkCellLinks*>(grid->GetCellLinks());
Links->ResizeCellList(myVtkID, 1);
Links->AddCellReference(cell->getVtkId(), myVtkID);
}
@@ -366,7 +366,7 @@ void SMDS_MeshNode::ClearInverseElements()
bool SMDS_MeshNode::emptyInverseElements()
{
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks())->GetLink(myVtkID);
return (l.ncells == 0);
}
@@ -378,7 +378,7 @@ bool SMDS_MeshNode::emptyInverseElements()
int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
{
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks())->GetLink(myVtkID);
if ( type == SMDSAbs_All )
return l.ncells;
+32 -3
View File
@@ -139,8 +139,8 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p
for (; it != setOfNodes.end(); ++it)
{
//MESSAGE("reverse link for node " << *it << " cell " << cellid);
this->Links->ResizeCellList(*it, 1);
this->Links->AddCellReference(cellid, *it);
this->GetLinks()->ResizeCellList(*it, 1);
this->GetLinks()->AddCellReference(cellid, *it);
}
return cellid;
@@ -332,9 +332,13 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
{
newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId
#ifdef VTK_CELL_ARRAY_V2
vtkIdType oldLoc = this->GetCellLocationsArray()->GetValue(j);
#else
vtkIdType oldLoc = this->Locations->GetValue(j);
#endif
vtkIdType nbpts;
vtkIdType *oldPtsCell = 0;
vtkIdTypePtr oldPtsCell = 0;
this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
assert(nbpts < NBMAXNODESINCELL);
//MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
@@ -952,6 +956,21 @@ void SMDS_UnstructuredGrid::GetNodeIds(std::set<int>& nodeSet, int downId, unsig
*/
void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds)
{
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
this->GetCellPoints(vtkVolId, cellPoints.GetPointer());
for (vtkIdType i = 0; i < cellPoints->GetNumberOfIds(); i++)
{
if (localClonedNodeIds.count(cellPoints->GetId(i)))
{
vtkIdType oldpt = cellPoints->GetId(i);
cellPoints->SetId(i, localClonedNodeIds[oldpt]);
//MESSAGE(oldpt << " --> " << pts[i]);
//this->RemoveReferenceToCell(oldpt, vtkVolId);
//this->AddReferenceToCell(pts[i], vtkVolId);
}
}
#else
vtkIdType npts = 0;
vtkIdType *pts; // will refer to the point id's of the face
this->GetCellPoints(vtkVolId, npts, pts);
@@ -966,6 +985,7 @@ void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> loc
//this->AddReferenceToCell(pts[i], vtkVolId);
}
}
#endif
}
/*! reorder the nodes of a face
@@ -995,11 +1015,20 @@ void SMDS_UnstructuredGrid::BuildLinks()
this->Links->UnRegister(this);
}
#ifdef VTK_CELL_ARRAY_V2
this->Links = SMDS_CellLinks::New();
GetLinks()->Allocate(this->GetNumberOfPoints());
GetLinks()->Register(this);
//FIXME: vtk9
GetLinks()->BuildLinks(this);
GetLinks()->Delete();
#else
this->Links = SMDS_CellLinks::New();
this->Links->Allocate(this->GetNumberOfPoints());
this->Links->Register(this);
this->Links->BuildLinks(this, this->Connectivity);
this->Links->Delete();
#endif
}
/*! Create a volume (prism or hexahedron) by duplication of a face.
+4 -3
View File
@@ -33,7 +33,8 @@ SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSA
}
else
{
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( _cellId, npts, pts );
_vtkIdList->SetNumberOfIds( _nbNodes = npts );
for (int i = 0; i < _nbNodes; i++)
@@ -67,7 +68,7 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
//MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type);
_vtkIdList = vtkIdList::New();
vtkIdType* pts;
vtkIdTypePtr pts;
vtkIdType npts;
vtkUnstructuredGrid* grid = _mesh->getGrid();
grid->GetCellPoints((vtkIdType)_cellId, npts, pts);
@@ -182,7 +183,7 @@ SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCel
{
//MESSAGE("SMDS_VtkCellIterator Polyhedra");
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(_cellId, nFaces, ptIds);
int id = 0;
_nbNodesInFaces = 0;
+17 -2
View File
@@ -67,6 +67,19 @@ bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode
bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
if (nbNodes != cellPoints->GetNumberOfIds())
{
MESSAGE("ChangeNodes problem: not the same number of nodes " << cellPoints->GetNumberOfIds() << " -> " << nbNodes);
return false;
}
for (int i = 0; i < nbNodes; i++)
{
cellPoints->SetId(i, nodes[i]->getVtkId());
}
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
@@ -79,6 +92,7 @@ bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{
pts[i] = nodes[i]->getVtkId();
}
#endif
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
return true;
}
@@ -87,7 +101,7 @@ bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType npts = 0;
vtkIdType* pts = 0;
vtkIdTypePtr pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
//MESSAGE("IsMediumNode " << npts << " " << (node->getVtkId() == pts[npts-1]));
return ((npts == 3) && (node->getVtkId() == pts[2]));
@@ -137,7 +151,8 @@ const SMDS_MeshNode*
SMDS_VtkEdge::GetNode(const int ind) const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( this->myVtkID, npts, pts );
return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
}
+26 -3
View File
@@ -101,6 +101,19 @@ void SMDS_VtkFace::initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh
bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
if (nbNodes != cellPoints->GetNumberOfIds())
{
MESSAGE("ChangeNodes problem: not the same number of nodes " << cellPoints->GetNumberOfIds() << " -> " << nbNodes);
return false;
}
for (int i = 0; i < nbNodes; i++)
{
cellPoints->SetId(i, nodes[i]->getVtkId());
}
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
@@ -113,6 +126,7 @@ bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{
pts[i] = nodes[i]->getVtkId();
}
#endif
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
return true;
}
@@ -173,7 +187,8 @@ const SMDS_MeshNode*
SMDS_VtkFace::GetNode(const int ind) const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( this->myVtkID, npts, pts );
return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
}
@@ -186,7 +201,8 @@ SMDS_VtkFace::GetNode(const int ind) const
int SMDS_VtkFace::GetNodeIndex( const SMDS_MeshNode* node ) const
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( this->myVtkID, npts, pts );
for ( vtkIdType i = 0; i < npts; ++i )
if ( pts[i] == node->getVtkId() )
@@ -251,7 +267,7 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
return false;
}
vtkIdType npts = 0;
vtkIdType* pts = 0;
vtkIdTypePtr pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
vtkIdType nodeId = node->getVtkId();
for (int rank = 0; rank < npts; rank++)
@@ -356,11 +372,18 @@ SMDS_NodeIteratorPtr SMDS_VtkFace::interlacedNodesIterator() const
void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
grid->RemoveReferenceToCell(cellPoints->GetId(0), myVtkID);
cellPoints->SetId(0, node->getVtkId());
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
grid->RemoveReferenceToCell(pts[0], myVtkID);
pts[0] = node->getVtkId();
#endif
node->AddInverseElement(this),
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
}
+27 -11
View File
@@ -133,6 +133,19 @@ void SMDS_VtkVolume::initPoly(const std::vector<vtkIdType>& nodeIds,
bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
{
vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
#ifdef VTK_CELL_ARRAY_V2
vtkNew<vtkIdList> cellPoints;
grid->GetCellPoints(myVtkID, cellPoints.GetPointer());
if (nbNodes != cellPoints->GetNumberOfIds())
{
MESSAGE("ChangeNodes problem: not the same number of nodes " << cellPoints->GetNumberOfIds() << " -> " << nbNodes);
return false;
}
for (int i = 0; i < nbNodes; i++)
{
cellPoints->SetId(i, nodes[i]->getVtkId());
}
#else
vtkIdType npts = 0;
vtkIdType* pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
@@ -145,6 +158,7 @@ bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes
{
pts[i] = nodes[i]->getVtkId();
}
#endif
SMDS_Mesh::_meshList[myMeshId]->setMyModified();
return true;
}
@@ -207,7 +221,7 @@ int SMDS_VtkVolume::NbFaces() const
case VTK_POLYHEDRON:
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
nbFaces = nFaces;
break;
@@ -236,7 +250,7 @@ int SMDS_VtkVolume::NbNodes() const
else
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0;
for (int i = 0; i < nFaces; i++)
@@ -276,7 +290,7 @@ int SMDS_VtkVolume::NbEdges() const
case VTK_POLYHEDRON:
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
nbEdges = 0;
int id = 0;
@@ -312,7 +326,7 @@ int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const
if (aVtkType == VTK_POLYHEDRON)
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0;
for (int i = 0; i < nFaces; i++)
@@ -342,7 +356,7 @@ const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int n
if (aVtkType == VTK_POLYHEDRON)
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0;
for (int i = 0; i < nFaces; i++)
@@ -372,7 +386,7 @@ std::vector<int> SMDS_VtkVolume::GetQuantities() const
if (aVtkType == VTK_POLYHEDRON)
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0;
for (int i = 0; i < nFaces; i++)
@@ -430,7 +444,7 @@ const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
if ( aVtkType == VTK_POLYHEDRON)
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0, nbPoints = 0;
for (int i = 0; i < nFaces; i++)
@@ -443,7 +457,8 @@ const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
}
return 0;
}
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( this->myVtkID, npts, pts );
const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType ));
return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] );
@@ -460,7 +475,7 @@ int SMDS_VtkVolume::GetNodeIndex( const SMDS_MeshNode* node ) const
if ( aVtkType == VTK_POLYHEDRON)
{
vtkIdType nFaces = 0;
vtkIdType* ptIds = 0;
vtkIdTypePtr ptIds = 0;
grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
int id = 0;
for (int iF = 0; iF < nFaces; iF++)
@@ -473,7 +488,8 @@ int SMDS_VtkVolume::GetNodeIndex( const SMDS_MeshNode* node ) const
}
return -1;
}
vtkIdType npts, *pts;
vtkIdType npts;
vtkIdTypePtr pts;
grid->GetCellPoints( this->myVtkID, npts, pts );
for ( vtkIdType i = 0; i < npts; ++i )
if ( pts[i] == node->getVtkId() )
@@ -534,7 +550,7 @@ bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const
return false;
}
vtkIdType npts = 0;
vtkIdType* pts = 0;
vtkIdTypePtr pts = 0;
grid->GetCellPoints(myVtkID, npts, pts);
vtkIdType nodeId = node->getVtkId();
for (int rank = 0; rank < npts; rank++)
+7 -1
View File
@@ -20,6 +20,12 @@
// See http://www.salome-platform.org/ or email : [email protected]
//
// Suppress warning due to use of #import an macOS inside Aspect_RenderingContext.hxx
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wimport-preprocessor-directive-pedantic"
#endif
#include <Standard_Stream.hxx>
#include <GEOMUtils.hxx>
@@ -643,7 +649,7 @@ TopoDS_Shape GEOMUtils::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
}
}
return std::move(aCompound);
return TopoDS_Shape(std::move(aCompound));
}
//=======================================================================
+8 -2
View File
@@ -20,6 +20,12 @@
// See http://www.salome-platform.org/ or email : [email protected]
//
// Suppress warning due to use of #import an macOS inside Aspect_RenderingContext.hxx
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wimport-preprocessor-directive-pedantic"
#endif
// File : SMESH_Mesh.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
@@ -76,10 +82,10 @@
#ifndef WIN32
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#else
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
//#include <pthread.h>
#endif
+5 -5
View File
@@ -4168,7 +4168,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems,
// if ( posType != SMDS_TOP_3DSPACE )
// dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
// if ( dist2 < dist1 )
uv = newUV;
uv = newUV;
}
}
// store UV in the map
@@ -11348,7 +11348,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
{
int oldId = *itn;
//MESSAGE(" node " << oldId);
vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(grid->GetCellLinks())->GetLink(oldId);
for (int i=0; i<l.ncells; i++)
{
int vtkId = l.cells[i];
@@ -11527,7 +11527,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
//MESSAGE(" domain " << idom << " volume " << elem->GetID());
double values[3];
vtkIdType npts = 0;
vtkIdType* pts = 0;
vtkIdTypePtr pts = 0;
grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
SMDS_VtkVolume::gravityCenter(grid, pts, npts, values);
if (id ==0)
@@ -11708,7 +11708,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
{
int oldId = itnod->first;
//MESSAGE(" node " << oldId);
vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
vtkCellLinks::Link l = static_cast<vtkCellLinks*>(grid->GetCellLinks())->GetLink(oldId);
for (int i = 0; i < l.ncells; i++)
{
int vtkId = l.cells[i];
@@ -12165,7 +12165,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
MESSAGE("volume to check, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
bool volInside = false;
vtkIdType npts = 0;
vtkIdType* pts = 0;
vtkIdTypePtr pts = 0;
grid->GetCellPoints(vtkId, npts, pts);
for (int i=0; i<npts; i++)
{
+1 -1
View File
@@ -2100,7 +2100,7 @@ TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
}
}
return std::move(aCompound);
return TopoDS_Compound(std::move(aCompound));
}
//=======================================================================
@@ -22,6 +22,13 @@
// File : StdMeshers_Cartesian_3D.cxx
// Module : SMESH
//
// Suppress warning due to use of #import an macOS inside Aspect_RenderingContext.hxx
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wimport-preprocessor-directive-pedantic"
#endif
#include "StdMeshers_Cartesian_3D.hxx"
#include "SMDS_MeshNode.hxx"
+275 -216
View File
@@ -30,6 +30,7 @@
# include <sstream>
# include <exception>
# include <ios>
# include <functional>
# if defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
# include <unistd.h>
# include <pwd.h>
@@ -41,10 +42,12 @@
# include <ctime>
# include <csignal>
# include <boost/program_options.hpp>
# include <boost/filesystem.hpp>
#endif
#ifdef FC_OS_WIN32
# include <Shlobj.h>
# include <codecvt>
#endif
#if defined(FC_OS_BSD)
@@ -114,6 +117,12 @@
#include <Base/GeometryPyCXX.h>
#include "Link.h"
#include "DocumentPy.h"
#include "DocumentObjectGroupPy.h"
#include "LinkBaseExtensionPy.h"
#include "OriginGroupExtensionPy.h"
#include "PartPy.h"
// If you stumble here, run the target "BuildExtractRevision" on Windows systems
// or the Python script "SubWCRev.py" on Linux based systems which builds
// src/Build/Version.h. Or create your own from src/Build/Version.h.in!
@@ -122,15 +131,15 @@
#include <boost/tokenizer.hpp>
#include <boost/token_functions.hpp>
#include <boost/bind.hpp>
#include <boost/version.hpp>
#include <QDir>
#include <QFileInfo>
#include <QProcessEnvironment>
using namespace App;
using namespace std;
using namespace boost;
using namespace boost::program_options;
namespace sp = std::placeholders;
// scriptings (scripts are built-in but can be overridden by command line option)
@@ -191,7 +200,6 @@ PyDoc_STRVAR(Base_doc,
"like vector, matrix, bounding box, placement, rotation, axis, ...\n"
);
#if PY_MAJOR_VERSION >= 3
// This is called via the PyImport_AppendInittab mechanism called
// during initialization, to make the built-in __FreeCADBase__
// module known to Python.
@@ -220,7 +228,6 @@ init_freecad_module(void)
};
return PyModule_Create(&FreeCADModuleDef);
}
#endif
Application::Application(std::map<std::string,std::string> &mConfig)
: _mConfig(mConfig), _pActiveDoc(0), _isRestoring(false),_allowPartial(false)
@@ -234,7 +241,6 @@ Application::Application(std::map<std::string,std::string> &mConfig)
// setting up Python binding
Base::PyGILStateLocker lock;
#if PY_MAJOR_VERSION >= 3
PyObject* modules = PyImport_GetModuleDict();
__AppMethods = Application::Methods;
@@ -244,12 +250,8 @@ Application::Application(std::map<std::string,std::string> &mConfig)
pAppModule = init_freecad_module();
PyDict_SetItemString(modules, "FreeCAD", pAppModule);
}
#else
PyObject* pAppModule = Py_InitModule3("FreeCAD", Application::Methods, FreeCAD_doc);
#endif
Py::Module(pAppModule).setAttr(std::string("ActiveDocument"),Py::None());
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef ConsoleModuleDef = {
PyModuleDef_HEAD_INIT,
"__FreeCADConsole__", Console_doc, -1,
@@ -257,9 +259,6 @@ Application::Application(std::map<std::string,std::string> &mConfig)
NULL, NULL, NULL, NULL
};
PyObject* pConsoleModule = PyModule_Create(&ConsoleModuleDef);
#else
PyObject* pConsoleModule = Py_InitModule3("__FreeCADConsole__", ConsoleSingleton::Methods, Console_doc);
#endif
// introducing additional classes
@@ -277,16 +276,13 @@ Application::Application(std::map<std::string,std::string> &mConfig)
// binding classes from the base module. At a later stage we should
// remove these types from the FreeCAD module.
#if PY_MAJOR_VERSION >= 3
PyObject* pBaseModule = PyImport_ImportModule ("__FreeCADBase__");
if (!pBaseModule) {
PyErr_Clear();
pBaseModule = init_freecad_base_module();
PyDict_SetItemString(modules, "__FreeCADBase__", pBaseModule);
}
#else
PyObject* pBaseModule = Py_InitModule3("__FreeCADBase__", NULL, Base_doc);
#endif
Base::BaseExceptionFreeCADError = PyErr_NewException("Base.FreeCADError", PyExc_RuntimeError, NULL);
Py_INCREF(Base::BaseExceptionFreeCADError);
PyModule_AddObject(pBaseModule, "FreeCADError", Base::BaseExceptionFreeCADError);
@@ -307,6 +303,23 @@ Application::Application(std::map<std::string,std::string> &mConfig)
Base::Interpreter().addType(&App::MaterialPy::Type, pAppModule, "Material");
// Add document types
Base::Interpreter().addType(&App::PropertyContainerPy::Type, pAppModule, "PropertyContainer");
Base::Interpreter().addType(&App::ExtensionContainerPy::Type, pAppModule, "ExtensionContainer");
Base::Interpreter().addType(&App::DocumentPy::Type, pAppModule, "Document");
Base::Interpreter().addType(&App::DocumentObjectPy::Type, pAppModule, "DocumentObject");
Base::Interpreter().addType(&App::DocumentObjectGroupPy::Type, pAppModule, "DocumentObjectGroup");
Base::Interpreter().addType(&App::GeoFeaturePy::Type, pAppModule, "GeoFeature");
Base::Interpreter().addType(&App::PartPy::Type, pAppModule, "Part");
// Add extension types
Base::Interpreter().addType(&App::ExtensionPy::Type, pAppModule, "Extension");
Base::Interpreter().addType(&App::DocumentObjectExtensionPy::Type, pAppModule, "DocumentObjectExtension");
Base::Interpreter().addType(&App::GroupExtensionPy::Type, pAppModule, "GroupExtension");
Base::Interpreter().addType(&App::GeoFeatureGroupExtensionPy::Type, pAppModule, "GeoFeatureGroupExtension");
Base::Interpreter().addType(&App::OriginGroupExtensionPy::Type, pAppModule, "OriginGroupExtension");
Base::Interpreter().addType(&App::LinkBaseExtensionPy::Type, pAppModule, "LinkBaseExtension");
//insert Base and Console
Py_INCREF(pBaseModule);
PyModule_AddObject(pAppModule, "Base", pBaseModule);
@@ -319,7 +332,6 @@ Application::Application(std::map<std::string,std::string> &mConfig)
PyModule_AddObject(pAppModule, "Qt", pTranslateModule);
//insert Units module
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef UnitsModuleDef = {
PyModuleDef_HEAD_INIT,
"Units", "The Unit API", -1,
@@ -327,14 +339,8 @@ Application::Application(std::map<std::string,std::string> &mConfig)
NULL, NULL, NULL, NULL
};
PyObject* pUnitsModule = PyModule_Create(&UnitsModuleDef);
#else
PyObject* pUnitsModule = Py_InitModule3("Units", Base::UnitsApi::Methods,"The Unit API");
#endif
Base::Interpreter().addType(&Base::QuantityPy ::Type,pUnitsModule,"Quantity");
// make sure to set the 'nb_true_divide' slot
#if PY_MAJOR_VERSION < 3
Base::QuantityPy::Type.tp_as_number->nb_true_divide = Base::QuantityPy::Type.tp_as_number->nb_divide;
#endif
Base::Interpreter().addType(&Base::UnitPy ::Type,pUnitsModule,"Unit");
Py_INCREF(pUnitsModule);
@@ -380,12 +386,19 @@ void Application::renameDocument(const char *OldName, const char *NewName)
#endif
}
Document* Application::newDocument(const char * Name, const char * UserName, bool createView)
Document* Application::newDocument(const char * Name, const char * UserName, bool createView, bool tempDoc)
{
// get a valid name anyway!
if (!Name || Name[0] == '\0')
Name = "Unnamed";
string name = getUniqueDocumentName(Name);
string name = getUniqueDocumentName(Name, tempDoc);
// return the temporary document if it exists
if (tempDoc) {
auto it = DocMap.find(name);
if (it != DocMap.end() && it->second->testStatus(Document::TempDoc))
return it->second;
}
std::string userName;
if (UserName && UserName[0] != '\0') {
@@ -406,33 +419,37 @@ Document* Application::newDocument(const char * Name, const char * UserName, boo
// create the FreeCAD document
std::unique_ptr<Document> newDoc(new Document(name.c_str()));
if (tempDoc)
newDoc->setStatus(Document::TempDoc, true);
auto oldActiveDoc = _pActiveDoc;
auto doc = newDoc.get();
// add the document to the internal list
DocMap[name] = newDoc.release(); // now owned by the Application
_pActiveDoc = DocMap[name];
// connect the signals to the application for the new document
_pActiveDoc->signalBeforeChange.connect(boost::bind(&App::Application::slotBeforeChangeDocument, this, _1, _2));
_pActiveDoc->signalChanged.connect(boost::bind(&App::Application::slotChangedDocument, this, _1, _2));
_pActiveDoc->signalNewObject.connect(boost::bind(&App::Application::slotNewObject, this, _1));
_pActiveDoc->signalDeletedObject.connect(boost::bind(&App::Application::slotDeletedObject, this, _1));
_pActiveDoc->signalBeforeChangeObject.connect(boost::bind(&App::Application::slotBeforeChangeObject, this, _1, _2));
_pActiveDoc->signalChangedObject.connect(boost::bind(&App::Application::slotChangedObject, this, _1, _2));
_pActiveDoc->signalRelabelObject.connect(boost::bind(&App::Application::slotRelabelObject, this, _1));
_pActiveDoc->signalActivatedObject.connect(boost::bind(&App::Application::slotActivatedObject, this, _1));
_pActiveDoc->signalUndo.connect(boost::bind(&App::Application::slotUndoDocument, this, _1));
_pActiveDoc->signalRedo.connect(boost::bind(&App::Application::slotRedoDocument, this, _1));
_pActiveDoc->signalRecomputedObject.connect(boost::bind(&App::Application::slotRecomputedObject, this, _1));
_pActiveDoc->signalRecomputed.connect(boost::bind(&App::Application::slotRecomputed, this, _1));
_pActiveDoc->signalBeforeRecompute.connect(boost::bind(&App::Application::slotBeforeRecompute, this, _1));
_pActiveDoc->signalOpenTransaction.connect(boost::bind(&App::Application::slotOpenTransaction, this, _1, _2));
_pActiveDoc->signalCommitTransaction.connect(boost::bind(&App::Application::slotCommitTransaction, this, _1));
_pActiveDoc->signalAbortTransaction.connect(boost::bind(&App::Application::slotAbortTransaction, this, _1));
_pActiveDoc->signalStartSave.connect(boost::bind(&App::Application::slotStartSaveDocument, this, _1, _2));
_pActiveDoc->signalFinishSave.connect(boost::bind(&App::Application::slotFinishSaveDocument, this, _1, _2));
_pActiveDoc->signalBeforeChange.connect(std::bind(&App::Application::slotBeforeChangeDocument, this, sp::_1, sp::_2));
_pActiveDoc->signalChanged.connect(std::bind(&App::Application::slotChangedDocument, this, sp::_1, sp::_2));
_pActiveDoc->signalNewObject.connect(std::bind(&App::Application::slotNewObject, this, sp::_1));
_pActiveDoc->signalDeletedObject.connect(std::bind(&App::Application::slotDeletedObject, this, sp::_1));
_pActiveDoc->signalBeforeChangeObject.connect(std::bind(&App::Application::slotBeforeChangeObject, this, sp::_1, sp::_2));
_pActiveDoc->signalChangedObject.connect(std::bind(&App::Application::slotChangedObject, this, sp::_1, sp::_2));
_pActiveDoc->signalRelabelObject.connect(std::bind(&App::Application::slotRelabelObject, this, sp::_1));
_pActiveDoc->signalActivatedObject.connect(std::bind(&App::Application::slotActivatedObject, this, sp::_1));
_pActiveDoc->signalUndo.connect(std::bind(&App::Application::slotUndoDocument, this, sp::_1));
_pActiveDoc->signalRedo.connect(std::bind(&App::Application::slotRedoDocument, this, sp::_1));
_pActiveDoc->signalRecomputedObject.connect(std::bind(&App::Application::slotRecomputedObject, this, sp::_1));
_pActiveDoc->signalRecomputed.connect(std::bind(&App::Application::slotRecomputed, this, sp::_1));
_pActiveDoc->signalBeforeRecompute.connect(std::bind(&App::Application::slotBeforeRecompute, this, sp::_1));
_pActiveDoc->signalOpenTransaction.connect(std::bind(&App::Application::slotOpenTransaction, this, sp::_1, sp::_2));
_pActiveDoc->signalCommitTransaction.connect(std::bind(&App::Application::slotCommitTransaction, this, sp::_1));
_pActiveDoc->signalAbortTransaction.connect(std::bind(&App::Application::slotAbortTransaction, this, sp::_1));
_pActiveDoc->signalStartSave.connect(std::bind(&App::Application::slotStartSaveDocument, this, sp::_1, sp::_2));
_pActiveDoc->signalFinishSave.connect(std::bind(&App::Application::slotFinishSaveDocument, this, sp::_1, sp::_2));
_pActiveDoc->signalChangePropertyEditor.connect(
boost::bind(&App::Application::slotChangePropertyEditor, this, _1, _2));
std::bind(&App::Application::slotChangePropertyEditor, this, sp::_1, sp::_2));
// make sure that the active document is set in case no GUI is up
{
@@ -441,12 +458,16 @@ Document* Application::newDocument(const char * Name, const char * UserName, boo
Py::Module("FreeCAD").setAttr(std::string("ActiveDocument"),active);
}
signalNewDocument(*_pActiveDoc,createView);
signalNewDocument(*_pActiveDoc, createView);
// set the UserName after notifying all observers
_pActiveDoc->Label.setValue(userName);
return _pActiveDoc;
// set the old document active again if the new is temporary
if (tempDoc && oldActiveDoc)
setActiveDocument(oldActiveDoc);
return doc;
}
bool Application::closeDocument(const char* name)
@@ -512,7 +533,7 @@ std::vector<App::Document*> Application::getDocuments() const
return docs;
}
std::string Application::getUniqueDocumentName(const char *Name) const
std::string Application::getUniqueDocumentName(const char *Name, bool tempDoc) const
{
if (!Name || *Name == '\0')
return std::string();
@@ -522,7 +543,7 @@ std::string Application::getUniqueDocumentName(const char *Name) const
std::map<string,Document*>::const_iterator pos;
pos = DocMap.find(CleanName);
if (pos == DocMap.end()) {
if (pos == DocMap.end() || (tempDoc && pos->second->testStatus(Document::TempDoc))) {
// if not, name is OK
return CleanName;
}
@@ -530,7 +551,8 @@ std::string Application::getUniqueDocumentName(const char *Name) const
std::vector<std::string> names;
names.reserve(DocMap.size());
for (pos = DocMap.begin();pos != DocMap.end();++pos) {
names.push_back(pos->first);
if (!tempDoc || !pos->second->testStatus(Document::TempDoc))
names.push_back(pos->first);
}
return Base::Tools::getUniqueName(CleanName, names);
}
@@ -582,7 +604,13 @@ public:
~DocOpenGuard() {
if(flag) {
flag = false;
signal();
try {
signal();
}
catch (const boost::exception&) {
// reported by code analyzers
Base::Console().Warning("~DocOpenGuard: Unexpected boost exception\n");
}
}
}
};
@@ -755,9 +783,9 @@ std::vector<Document*> Application::openDocuments(const std::vector<std::string>
return res;
}
Document* Application::openDocumentPrivate(const char * FileName,
Document* Application::openDocumentPrivate(const char * FileName,
const char *propFileName, const char *label,
bool isMainDoc, bool createView,
bool isMainDoc, bool createView,
const std::set<std::string> &objNames)
{
FileInfo File(FileName);
@@ -770,17 +798,26 @@ Document* Application::openDocumentPrivate(const char * FileName,
// Before creating a new document we check whether the document is already open
std::string filepath = File.filePath();
QString canonicalPath = QFileInfo(QString::fromUtf8(FileName)).canonicalFilePath();
for (std::map<std::string,Document*>::iterator it = DocMap.begin(); it != DocMap.end(); ++it) {
// get unique path separators
std::string fi = FileInfo(it->second->FileName.getValue()).filePath();
if (filepath != fi)
if (filepath != fi) {
if (canonicalPath == QFileInfo(QString::fromUtf8(fi.c_str())).canonicalFilePath()) {
bool samePath = (canonicalPath == QString::fromUtf8(FileName));
FC_WARN("Identical physical path '" << canonicalPath.toUtf8().constData() << "'\n"
<< (samePath?"":" for file '") << (samePath?"":FileName) << (samePath?"":"'\n")
<< " with existing document '" << it->second->Label.getValue()
<< "' in path: '" << it->second->FileName.getValue() << "'");
}
continue;
if(it->second->testStatus(App::Document::PartialDoc)
}
if(it->second->testStatus(App::Document::PartialDoc)
|| it->second->testStatus(App::Document::PartialRestore)) {
// Here means a document is already partially loaded, but the document
// is requested again, either partial or not. We must check if the
// is requested again, either partial or not. We must check if the
// document contains the required object
if(isMainDoc) {
// Main document must be open fully, so close and reopen
closeDocument(it->first.c_str());
@@ -909,7 +946,13 @@ Application::TransactionSignaller::TransactionSignaller(bool abort, bool signal)
Application::TransactionSignaller::~TransactionSignaller() {
if(--_TransSignalCount == 0 && _TransSignalled) {
_TransSignalled = false;
GetApplication().signalCloseTransaction(abort);
try {
GetApplication().signalCloseTransaction(abort);
}
catch (const boost::exception&) {
// reported by code analyzers
Base::Console().Warning("~TransactionSignaller: Unexpected boost exception\n");
}
}
}
@@ -977,7 +1020,7 @@ std::string Application::getHelpDir()
int Application::checkLinkDepth(int depth, bool no_throw) {
if(_objCount<0) {
_objCount = 0;
for(auto &v : DocMap)
for(auto &v : DocMap)
_objCount += v.second->countObjects();
}
if(depth > _objCount+2) {
@@ -1437,6 +1480,23 @@ int Application::_argc;
char ** Application::_argv;
void Application::cleanupUnits()
{
try {
Base::PyGILStateLocker lock;
Py::Module mod (Py::Module("FreeCAD").getAttr("Units").ptr());
Py::List attr(mod.dir());
for (Py::List::iterator it = attr.begin(); it != attr.end(); ++it) {
mod.delAttr(Py::String(*it));
}
}
catch (Py::Exception& e) {
Base::PyGILStateLocker lock;
e.clear();
}
}
void Application::destruct(void)
{
// saving system parameter
@@ -1467,6 +1527,11 @@ void Application::destruct(void)
_pcSysParamMngr = 0;
_pcUserParamMngr = 0;
#ifdef FC_DEBUG
// Do this only in debug mode for memory leak checkers
cleanupUnits();
#endif
// not initialized or double destruct!
assert(_pcSingleton);
delete _pcSingleton;
@@ -1566,7 +1631,11 @@ void segmentation_fault_handler(int sig)
(void)sig;
std::cerr << "Program received signal SIGSEGV, Segmentation fault.\n";
printBacktrace(2);
#if defined(FC_DEBUG)
abort();
#else
exit(1);
#endif
#else
switch (sig) {
case SIGSEGV:
@@ -1642,7 +1711,7 @@ void Application::init(int argc, char ** argv)
std::signal(SIGSEGV,segmentation_fault_handler);
std::signal(SIGABRT,segmentation_fault_handler);
std::set_terminate(unhandled_exception_handler);
std::set_unexpected(unexpection_error_handler);
::set_unexpected(unexpection_error_handler);
#elif defined(FC_OS_LINUX)
std::signal(SIGSEGV,segmentation_fault_handler);
#endif
@@ -1651,10 +1720,6 @@ void Application::init(int argc, char ** argv)
#endif
initTypes();
#if (BOOST_VERSION < 104600) || (BOOST_FILESYSTEM_VERSION == 2)
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
#endif
initConfig(argc,argv);
initApplication();
}
@@ -1700,6 +1765,7 @@ void Application::initTypes(void)
App ::PropertyAcceleration ::init();
App ::PropertyForce ::init();
App ::PropertyPressure ::init();
App ::PropertyVacuumPermittivity::init();
App ::PropertyInteger ::init();
App ::PropertyIntegerConstraint ::init();
App ::PropertyPercent ::init();
@@ -1888,7 +1954,7 @@ void Application::initConfig(int argc, char ** argv)
Branding brand;
QString binDir = QString::fromUtf8((mConfig["AppHomePath"] + "bin").c_str());
QFileInfo fi(binDir, QString::fromLatin1("branding.xml"));
if (brand.readFile(fi.absoluteFilePath())) {
if (fi.exists() && brand.readFile(fi.absoluteFilePath())) {
Branding::XmlConfig cfg = brand.getUserDefines();
for (Branding::XmlConfig::iterator it = cfg.begin(); it != cfg.end(); ++it) {
App::Application::Config()[it.key()] = it.value();
@@ -1905,10 +1971,8 @@ void Application::initConfig(int argc, char ** argv)
# endif
// init python
#if PY_MAJOR_VERSION >= 3
PyImport_AppendInittab ("FreeCAD", init_freecad_module);
PyImport_AppendInittab ("__FreeCADBase__", init_freecad_base_module);
#endif
const char* pythonpath = Interpreter().init(argc,argv);
if (pythonpath)
mConfig["PythonSearchPath"] = pythonpath;
@@ -1920,9 +1984,13 @@ void Application::initConfig(int argc, char ** argv)
// Init console ===========================================================
Base::PyGILStateLocker lock;
if (mConfig["LoggingConsole"] == "1") {
_pConsoleObserverStd = new ConsoleObserverStd();
Console().AttachObserver(_pConsoleObserverStd);
_pConsoleObserverStd = new ConsoleObserverStd();
Console().AttachObserver(_pConsoleObserverStd);
if (mConfig["LoggingConsole"] != "1") {
_pConsoleObserverStd->bMsg = false;
_pConsoleObserverStd->bLog = false;
_pConsoleObserverStd->bWrn = false;
_pConsoleObserverStd->bErr = false;
}
if (mConfig["Verbose"] == "Strict")
Console().UnsetConsoleMode(ConsoleSingleton::Verbose);
@@ -1988,8 +2056,7 @@ void Application::initConfig(int argc, char ** argv)
#endif
}
// Set application tmp. directory
mConfig["AppTempPath"] = Base::FileInfo::getTempPath();
// Change application tmp. directory
std::string tmpPath = _pcUserParamMngr->GetGroup("BaseApp/Preferences/General")->GetASCII("TempPath");
Base::FileInfo di(tmpPath);
if (di.exists() && di.isDir()) {
@@ -2065,6 +2132,9 @@ void Application::initApplication(void)
catch (const Base::Exception& e) {
e.ReportException();
}
// seed randomizer
srand(time(0));
}
std::list<std::string> Application::getCmdLineFiles()
@@ -2309,23 +2379,10 @@ void Application::LoadParameters(void)
// fix weird error while linking boost (all versions of VC)
// VS2010: https://forum.freecadweb.org/viewtopic.php?f=4&t=1886&p=12553&hilit=boost%3A%3Afilesystem%3A%3Aget#p12553
namespace boost { namespace program_options { std::string arg="arg"; } }
#if (defined (BOOST_VERSION) && (BOOST_VERSION >= 104100))
namespace boost { namespace program_options {
const unsigned options_description::m_default_line_length = 80;
} }
#endif
#endif
#if 0 // it seems that SUSE has fixed the broken boost package
// reported for SUSE in issue #0000208
#if defined(__GNUC__)
#if BOOST_VERSION == 104400
namespace boost { namespace filesystem {
bool no_check( const std::string & ) { return true; }
} }
#endif
#endif
#endif
pair<string, string> customSyntax(const string& s)
{
@@ -2666,67 +2723,98 @@ void Application::ExtractUserPath()
mConfig["BinPath"] = mConfig["AppHomePath"] + "bin" + PATHSEP;
mConfig["DocPath"] = mConfig["AppHomePath"] + "doc" + PATHSEP;
// Set application tmp. directory
mConfig["AppTempPath"] = Base::FileInfo::getTempPath();
// this is to support a portable version of FreeCAD
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
QString userHome = env.value(QString::fromLatin1("FREECAD_USER_HOME"));
QString userData = env.value(QString::fromLatin1("FREECAD_USER_DATA"));
QString userTemp = env.value(QString::fromLatin1("FREECAD_USER_TEMP"));
// verify env. variables
if (!userHome.isEmpty()) {
QDir dir(userHome);
if (dir.exists())
userHome = QDir::toNativeSeparators(dir.canonicalPath());
else
userHome.clear();
}
if (!userData.isEmpty()) {
QDir dir(userData);
if (dir.exists())
userData = QDir::toNativeSeparators(dir.canonicalPath());
else
userData.clear();
}
else if (!userHome.isEmpty()) {
// if FREECAD_USER_HOME is set but not FREECAD_USER_DATA
userData = userHome;
}
// override temp directory if set by env. variable
if (!userTemp.isEmpty()) {
QDir dir(userTemp);
if (dir.exists()) {
userTemp = dir.canonicalPath();
userTemp += QDir::separator();
userTemp = QDir::toNativeSeparators(userTemp);
mConfig["AppTempPath"] = userTemp.toUtf8().data();
}
}
else if (!userHome.isEmpty()) {
// if FREECAD_USER_HOME is set but not FREECAD_USER_TEMP
QDir dir(userHome);
dir.mkdir(QString::fromLatin1("temp"));
QFileInfo fi(dir, QString::fromLatin1("temp"));
QString tmp(fi.absoluteFilePath());
tmp += QDir::separator();
tmp = QDir::toNativeSeparators(tmp);
mConfig["AppTempPath"] = tmp.toUtf8().data();
}
#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_BSD)
// Default paths for the user specific stuff
struct passwd *pwd = getpwuid(getuid());
if (pwd == NULL)
throw Base::RuntimeError("Getting HOME path from system failed!");
mConfig["UserHomePath"] = pwd->pw_dir;
char *path = pwd->pw_dir;
char *fc_user_data;
if ((fc_user_data = getenv("FREECAD_USER_DATA"))) {
QString env = QString::fromUtf8(fc_user_data);
QDir dir(env);
if (!env.isEmpty() && dir.exists())
path = fc_user_data;
if (!userHome.isEmpty()) {
mConfig["UserHomePath"] = userHome.toUtf8().data();
}
std::string appData(path);
Base::FileInfo fi(appData.c_str());
if (!fi.exists()) {
boost::filesystem::path appData(pwd->pw_dir);
if (!userData.isEmpty())
appData = userData.toUtf8().data();
if (!boost::filesystem::exists(appData)) {
// This should never ever happen
std::stringstream str;
str << "Application data directory " << appData << " does not exist!";
throw Base::FileSystemError(str.str());
throw Base::FileSystemError("Application data directory " + appData.string() + " does not exist!");
}
// In order to write into our data path, we must create some directories, first.
// If 'AppDataSkipVendor' is defined, the value of 'ExeVendor' must not be part of
// the path.
appData += PATHSEP;
appData += ".";
if (mConfig.find("AppDataSkipVendor") == mConfig.end()) {
appData += mConfig["ExeVendor"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
}
appData += PATHSEP;
}
appData += mConfig["ExeName"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
appData /= "." + mConfig["ExeVendor"];
appData /= mConfig["ExeName"];
} else {
appData /= "." + mConfig["ExeName"];
}
// Actually the name of the directory where the parameters are stored should be the name of
// the application due to branding reasons.
appData += PATHSEP;
mConfig["UserAppData"] = appData;
// In order to write to our data path, we must create some directories, first.
if (!boost::filesystem::exists(appData) && !Py_IsInitialized()) {
try {
boost::filesystem::create_directories(appData);
} catch (const boost::filesystem::filesystem_error& e) {
throw Base::FileSystemError("Could not create app data directories. Failed with: " + e.code().message());
}
}
mConfig["UserAppData"] = appData.string() + PATHSEP;
#elif defined(FC_OS_MACOSX)
// Default paths for the user specific stuff on the platform
@@ -2734,130 +2822,101 @@ void Application::ExtractUserPath()
if (pwd == NULL)
throw Base::RuntimeError("Getting HOME path from system failed!");
mConfig["UserHomePath"] = pwd->pw_dir;
std::string appData = pwd->pw_dir;
appData += PATHSEP;
appData += "Library";
appData += PATHSEP;
appData += "Preferences";
Base::FileInfo fi(appData.c_str());
if (!fi.exists()) {
if (!userHome.isEmpty()) {
mConfig["UserHomePath"] = userHome.toUtf8().data();
}
boost::filesystem::path appData(pwd->pw_dir);
if (!userData.isEmpty())
appData = userData.toUtf8().data();
appData = appData / "Library" / "Preferences";
if (!boost::filesystem::exists(appData)) {
// This should never ever happen
std::stringstream str;
str << "Application data directory " << appData << " does not exist!";
throw Base::FileSystemError(str.str());
throw Base::FileSystemError("Application data directory " + appData.string() + " does not exist!");
}
// In order to write to our data path, we must create some directories, first.
// If 'AppDataSkipVendor' is defined the value of 'ExeVendor' must not be part of
// If 'AppDataSkipVendor' is defined, the value of 'ExeVendor' must not be part of
// the path.
appData += PATHSEP;
if (mConfig.find("AppDataSkipVendor") == mConfig.end()) {
appData += mConfig["ExeVendor"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
}
appData += PATHSEP;
appData /= mConfig["ExeVendor"];
}
appData /= mConfig["ExeName"];
appData += mConfig["ExeName"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
}
// Actually the name of the directory where the parameters are stored should be the name of
// the application due to branding reasons.
appData += PATHSEP;
mConfig["UserAppData"] = appData;
// In order to write to our data path, we must create some directories, first.
if (!boost::filesystem::exists(appData) && !Py_IsInitialized()) {
try {
boost::filesystem::create_directories(appData);
} catch (const boost::filesystem::filesystem_error& e) {
throw Base::FileSystemError("Could not create app data directories. Failed with: " + e.code().message());
}
}
mConfig["UserAppData"] = appData.string() + PATHSEP;
#elif defined(FC_OS_WIN32)
WCHAR szPath[MAX_PATH];
char dest[MAX_PATH*3];
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
// Get the default path where we can save our documents. It seems that
// 'CSIDL_MYDOCUMENTS' doesn't work on all machines, so we use 'CSIDL_PERSONAL'
// which does the same.
if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, szPath))) {
WideCharToMultiByte(CP_UTF8, 0, szPath, -1,dest, 256, NULL, NULL);
mConfig["UserHomePath"] = dest;
mConfig["UserHomePath"] = converter.to_bytes(szPath);
}
else
else {
mConfig["UserHomePath"] = mConfig["AppHomePath"];
}
if (!userHome.isEmpty()) {
mConfig["UserHomePath"] = userHome.toUtf8().data();
}
// In the second step we want the directory where user settings of the application can be
// kept. There we create a directory with name of the vendor and a sub-directory with name
// of the application.
if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, szPath))) {
// convert to UTF8
WideCharToMultiByte(CP_UTF8, 0, szPath, -1,dest, 256, NULL, NULL);
boost::filesystem::path appData(szPath);
if (!userData.isEmpty())
appData = userData.toStdWString();
std::string appData = dest;
Base::FileInfo fi(appData.c_str());
if (!fi.exists()) {
if (!boost::filesystem::exists(appData)) {
// This should never ever happen
std::stringstream str;
str << "Application data directory " << appData << " does not exist!";
throw Base::FileSystemError(str.str());
throw Base::FileSystemError("Application data directory " + appData.string() + " does not exist!");
}
// In order to write to our data path we must create some directories first.
// If 'AppDataSkipVendor' is defined the value of 'ExeVendor' must not be part of
// If 'AppDataSkipVendor' is defined, the value of 'ExeVendor' must not be part of
// the path.
if (mConfig.find("AppDataSkipVendor") == mConfig.end()) {
appData += PATHSEP;
appData += mConfig["ExeVendor"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
}
}
appData += PATHSEP;
appData += mConfig["ExeName"];
fi.setFile(appData.c_str());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
std::string error = "Cannot create directory ";
error += appData;
// Want more details on console
std::cerr << error << std::endl;
throw Base::FileSystemError(error);
}
appData /= mConfig["ExeVendor"];
}
appData /= mConfig["ExeName"];
// Actually the name of the directory where the parameters are stored should be the name of
// the application due to branding reasons.
appData += PATHSEP;
mConfig["UserAppData"] = appData;
// In order to write to our data path, we must create some directories, first.
if (!boost::filesystem::exists(appData) && !Py_IsInitialized()) {
try {
boost::filesystem::create_directories(appData);
} catch (const boost::filesystem::filesystem_error& e) {
throw Base::FileSystemError("Could not create app data directories. Failed with: " + e.code().message());
}
}
mConfig["UserAppData"] = converter.to_bytes(appData.wstring()) + PATHSEP;
// Create the default macro directory
fi.setFile(getUserMacroDir());
if (!fi.exists() && !Py_IsInitialized()) {
if (!fi.createDirectory()) {
// If the creation fails only write an error but do not raise an
// exception because it doesn't prevent FreeCAD from working
std::string error = "Cannot create directory ";
error += fi.fileName();
// Want more details on console
std::cerr << error << std::endl;
boost::filesystem::path macroDir = converter.from_bytes(getUserMacroDir());
if (!boost::filesystem::exists(macroDir) && !Py_IsInitialized()) {
try {
boost::filesystem::create_directories(macroDir);
} catch (const boost::filesystem::filesystem_error& e) {
throw Base::FileSystemError("Could not create macro directory. Failed with: " + e.code().message());
}
}
}
+15 -12
View File
@@ -24,7 +24,7 @@
#ifndef APP_APPLICATION_H
#define APP_APPLICATION_H
#include <boost/signals2.hpp>
#include <boost_signals2.hpp>
#include <vector>
#include <deque>
@@ -72,7 +72,7 @@ class AppExport Application
public:
//---------------------------------------------------------------------
// exported functions goes here +++++++++++++++++++++++++++++++++++++++
// exported functions go here +++++++++++++++++++++++++++++++++++++++++
//---------------------------------------------------------------------
/** @name methods for document handling */
@@ -86,11 +86,12 @@ public:
* The second name is a UTF8 name of any kind. It's that name normally shown to
* the user and stored in the App::Document::Name property.
*/
App::Document* newDocument(const char * Name=0l, const char * UserName=0l, bool createView=true);
App::Document* newDocument(const char * Name=0l, const char * UserName=0l,
bool createView=true, bool tempDoc=false);
/// Closes the document \a name and removes it from the application.
bool closeDocument(const char* name);
/// find a unique document name
std::string getUniqueDocumentName(const char *Name) const;
std::string getUniqueDocumentName(const char *Name, bool tempDoc=false) const;
/// Open an existing document from a file
App::Document* openDocument(const char * FileName=0l, bool createView=true);
/** Open multiple documents
@@ -110,7 +111,7 @@ public:
*
* This function will also open any external referenced files.
*/
std::vector<Document*> openDocuments(const std::vector<std::string> &filenames,
std::vector<Document*> openDocuments(const std::vector<std::string> &filenames,
const std::vector<std::string> *paths=0,
const std::vector<std::string> *labels=0,
std::vector<std::string> *errs=0,
@@ -135,7 +136,7 @@ public:
/// Indicate the application is closing all document
bool isClosingAll() const;
//@}
/** @name Application-wide trandaction setting */
//@{
/** Setup a pending application-wide active transaction
@@ -262,9 +263,9 @@ public:
/// signal on about changing the editor mode of a property
boost::signals2::signal<void (const App::Document&, const App::Property&)> signalChangePropertyEditor;
//@}
/** @name Signals of extension changes
* These signals are emitted on dynamic extension addition. Dynamic extensions are the ones added by python (c++ ones are part
* These signals are emitted on dynamic extension addition. Dynamic extensions are the ones added by python (c++ ones are part
* of the class definition, hence not dynamic)
* The extension in question is provided as parameter.
*/
@@ -381,7 +382,7 @@ public:
/** @name Link handling */
//@{
/** Check for link recursion depth
*
* @param depth: current depth
@@ -397,7 +398,7 @@ public:
/** Return the links to a given object
*
* @param obj: the linked object. If NULL, then all links are returned.
* @param option: @sa App::GetLinkOptions
* @param option: @sa App::GetLinkOption
* @param maxCount: limit the number of links returned, 0 means no limit
*/
std::set<DocumentObject*> getLinksTo(
@@ -457,6 +458,8 @@ private:
/// Destructor
virtual ~Application();
static void cleanupUnits();
/** @name member for parameter */
//@{
static ParameterManager *_pcSysParamMngr;
@@ -512,7 +515,7 @@ private:
static PyObject *sGetActiveTransaction (PyObject *self,PyObject *args);
static PyObject *sCloseActiveTransaction(PyObject *self,PyObject *args);
static PyObject *sCheckAbort(PyObject *self,PyObject *args);
static PyMethodDef Methods[];
static PyMethodDef Methods[];
friend class ApplicationObserver;
@@ -525,7 +528,7 @@ private:
static Application *_pcSingleton;
/// argument helper function
static void ParseOptions(int argc, char ** argv);
/// checks if the environment is allreight
/// checks if the environment is alright
//static void CheckEnv(void);
/// Search for the FreeCAD home path based on argv[0]
/*!
+23 -36
View File
@@ -104,11 +104,11 @@ PyMethodDef Application::Methods[] = {
"loadFile(string=filename,[string=module]) -> None\n\n"
"Loads an arbitrary file by delegating to the given Python module:\n"
"* If no module is given it will be determined by the file extension.\n"
"* If more than one module can load a file the first one one will be taken.\n"
"* If more than one module can load a file the first one will be taken.\n"
"* If no module exists to load the file an exception will be raised."},
{"open", (PyCFunction) Application::sOpenDocument, METH_VARARGS|METH_KEYWORDS,
{"open", reinterpret_cast<PyCFunction>(reinterpret_cast<void (*) (void)>( Application::sOpenDocument )), METH_VARARGS|METH_KEYWORDS,
"See openDocument(string)"},
{"openDocument", (PyCFunction) Application::sOpenDocument, METH_VARARGS|METH_KEYWORDS,
{"openDocument", reinterpret_cast<PyCFunction>(reinterpret_cast<void (*) (void)>( Application::sOpenDocument )), METH_VARARGS|METH_KEYWORDS,
"openDocument(filepath,hidden=False) -> object\n"
"Create a document and load the project file into the document.\n\n"
"filepath: file path to an existing file. If the file doesn't exist\n"
@@ -118,12 +118,13 @@ PyMethodDef Application::Methods[] = {
// {"saveDocument", (PyCFunction) Application::sSaveDocument, METH_VARARGS,
// "saveDocument(string) -- Save the document to a file."},
// {"saveDocumentAs", (PyCFunction) Application::sSaveDocumentAs, METH_VARARGS},
{"newDocument", (PyCFunction) Application::sNewDocument, METH_VARARGS|METH_KEYWORDS,
"newDocument(name, label=None, hidden=False) -> object\n"
{"newDocument", reinterpret_cast<PyCFunction>(reinterpret_cast<void (*) (void)>( Application::sNewDocument )), METH_VARARGS|METH_KEYWORDS,
"newDocument(name, label=None, hidden=False, temp=False) -> object\n"
"Create a new document with a given name.\n\n"
"name: unique document name which is checked automatically.\n"
"label: optional user changeable label for the document.\n"
"hidden: whether to hide document 3D view."},
"hidden: whether to hide document 3D view.\n"
"temp: mark the document as temporary so that it will not be saved"},
{"closeDocument", (PyCFunction) Application::sCloseDocument, METH_VARARGS,
"closeDocument(string) -> None\n\n"
"Close the document with a given name."},
@@ -173,9 +174,9 @@ PyMethodDef Application::Methods[] = {
"active transaction causes any document changes to open a transaction with\n"
"the given name and ID."},
{"getActiveTransaction", (PyCFunction) Application::sGetActiveTransaction, METH_VARARGS,
"getActiveTransaction() -> (name,id) return the current active transaction name and ID"},
"getActiveTransaction() -> (name,id) return the current active transaction name and ID"},
{"closeActiveTransaction", (PyCFunction) Application::sCloseActiveTransaction, METH_VARARGS,
"closeActiveTransaction(abort=False) -- commit or abort current active transaction"},
"closeActiveTransaction(abort=False) -- commit or abort current active transaction"},
{"isRestoring", (PyCFunction) Application::sIsRestoring, METH_VARARGS,
"isRestoring() -> Bool -- Test if the application is opening some document"},
{"checkAbort", (PyCFunction) Application::sCheckAbort, METH_VARARGS,
@@ -269,13 +270,16 @@ PyObject* Application::sNewDocument(PyObject * /*self*/, PyObject *args, PyObjec
char *docName = 0;
char *usrName = 0;
PyObject *hidden = Py_False;
static char *kwlist[] = {"name","label","hidden",0};
if (!PyArg_ParseTupleAndKeywords(args, kwd, "|etetO", kwlist,
"utf-8", &docName, "utf-8", &usrName, &hidden))
PyObject *temp = Py_False;
static char *kwlist[] = {"name","label","hidden","temp",0};
if (!PyArg_ParseTupleAndKeywords(args, kwd, "|etetOO", kwlist,
"utf-8", &docName, "utf-8", &usrName, &hidden, &temp))
return NULL;
PY_TRY {
App::Document* doc = GetApplication().newDocument(docName, usrName,!PyObject_IsTrue(hidden));
App::Document* doc = GetApplication().newDocument(docName, usrName,
!PyObject_IsTrue(hidden),
PyObject_IsTrue(temp));
PyMem_Free(docName);
PyMem_Free(usrName);
return doc->getPyObject();
@@ -445,11 +449,7 @@ PyObject* Application::sGetConfig(PyObject * /*self*/, PyObject *args)
}
else {
// do not set an error because this may break existing python code
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromString("");
#else
return PyString_FromString("");
#endif
}
}
@@ -461,11 +461,7 @@ PyObject* Application::sDumpConfig(PyObject * /*self*/, PyObject *args)
PyObject *dict = PyDict_New();
for (std::map<std::string,std::string>::iterator It= GetApplication()._mConfig.begin();
It!=GetApplication()._mConfig.end();++It) {
#if PY_MAJOR_VERSION >= 3
PyDict_SetItemString(dict,It->first.c_str(), PyUnicode_FromString(It->second.c_str()));
#else
PyDict_SetItemString(dict,It->first.c_str(), PyString_FromString(It->second.c_str()));
#endif
}
return dict;
}
@@ -714,11 +710,7 @@ PyObject* Application::sListDocuments(PyObject * /*self*/, PyObject *args)
docs = Document::getDependentDocuments(docs,true);
for (auto doc : docs) {
#if PY_MAJOR_VERSION >= 3
pKey = PyUnicode_FromString(doc->getName());
#else
pKey = PyString_FromString(doc->getName());
#endif
// GetPyObject() increments
pValue = static_cast<Base::PyObjectBase*>(doc->getPyObject());
PyDict_SetItem(pDict, pKey, pValue);
@@ -760,13 +752,8 @@ PyObject *Application::sSetLogLevel(PyObject * /*self*/, PyObject *args)
return NULL;
PY_TRY{
int l;
#if PY_MAJOR_VERSION < 3
if (PyString_Check(pcObj)) {
const char *pstr = PyString_AsString(pcObj);
#else
if (PyUnicode_Check(pcObj)) {
const char *pstr = PyUnicode_AsUTF8(pcObj);
#endif
if(strcmp(pstr,"Log") == 0)
l = FC_LOGLEVEL_LOG;
else if(strcmp(pstr,"Warning") == 0)
@@ -873,7 +860,7 @@ PyObject *Application::sGetLinksTo(PyObject * /*self*/, PyObject *args)
auto links = GetApplication().getLinksTo(obj,options,count);
Py::Tuple ret(links.size());
int i=0;
for(auto o : links)
for(auto o : links)
ret.setItem(i++,Py::Object(o->getPyObject(),true));
return Py::new_reference_to(ret);
}PY_CATCH;
@@ -889,7 +876,7 @@ PyObject *Application::sGetDependentObjects(PyObject * /*self*/, PyObject *args)
std::vector<App::DocumentObject*> objs;
if(PySequence_Check(obj)) {
Py::Sequence seq(obj);
for(size_t i=0;i<seq.size();++i) {
for(Py_ssize_t i=0;i<seq.size();++i) {
if(!PyObject_TypeCheck(seq[i].ptr(),&DocumentObjectPy::Type)) {
PyErr_SetString(PyExc_TypeError, "Expect element in sequence to be of type document object");
return 0;
@@ -897,7 +884,7 @@ PyObject *Application::sGetDependentObjects(PyObject * /*self*/, PyObject *args)
objs.push_back(static_cast<DocumentObjectPy*>(seq[i].ptr())->getDocumentObjectPtr());
}
}else if(!PyObject_TypeCheck(obj,&DocumentObjectPy::Type)) {
PyErr_SetString(PyExc_TypeError,
PyErr_SetString(PyExc_TypeError,
"Expect first argument to be either a document object or sequence of document objects");
return 0;
}else
@@ -907,7 +894,7 @@ PyObject *Application::sGetDependentObjects(PyObject * /*self*/, PyObject *args)
auto ret = App::Document::getDependencyList(objs,options);
Py::Tuple tuple(ret.size());
for(size_t i=0;i<ret.size();++i)
for(size_t i=0;i<ret.size();++i)
tuple.setItem(i,Py::Object(ret[i]->getPyObject(),true));
return Py::new_reference_to(tuple);
} PY_CATCH;
@@ -920,7 +907,7 @@ PyObject *Application::sSetActiveTransaction(PyObject * /*self*/, PyObject *args
PyObject *persist = Py_False;
if (!PyArg_ParseTuple(args, "s|O", &name,&persist))
return 0;
PY_TRY {
Py::Int ret(GetApplication().setActiveTransaction(name,PyObject_IsTrue(persist)));
return Py::new_reference_to(ret);
@@ -931,7 +918,7 @@ PyObject *Application::sGetActiveTransaction(PyObject * /*self*/, PyObject *args
{
if (!PyArg_ParseTuple(args, ""))
return 0;
PY_TRY {
int id = 0;
const char *name = GetApplication().getActiveTransaction(&id);
@@ -950,7 +937,7 @@ PyObject *Application::sCloseActiveTransaction(PyObject * /*self*/, PyObject *ar
int id = 0;
if (!PyArg_ParseTuple(args, "|Oi", &abort,&id))
return 0;
PY_TRY {
GetApplication().closeActiveTransaction(PyObject_IsTrue(abort),id);
Py_Return;
+2 -2
View File
@@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
* Copyright (c) 2019 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@@ -50,7 +50,7 @@ AutoTransaction::AutoTransaction(const char *name, bool tmpName) {
// We use negative transaction guard to disable auto transaction from here
// and any stack below. This is to support user setting active transaction
// before having any existing AutoTransaction on stack, or 'persist'
// transaction that can out live AutoTransaction.
// transaction that can out live AutoTransaction.
if(app._activeTransactionGuard<0)
--app._activeTransactionGuard;
else if(tid || app._activeTransactionGuard>0)
+3 -3
View File
@@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
* Copyright (c) 2019 Zheng Lei (realthunder) <realthunder.dev@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@@ -70,10 +70,10 @@ public:
*
* Once disabled, any empty temporary named transaction is closed. If there
* are non-empty or non-temporary named active transaction, it will not be
* auto closed.
* auto closed.
*
* This function may be used in, for example, Gui::Document::setEdit() to
* allow a transaction live past any command scope.
* allow a transaction live past any command scope.
*/
static void setEnable(bool enable);
-2
View File
@@ -16,8 +16,6 @@ IF(DOCDIR)
add_definitions(-DDOCDIR="${DOCDIR}")
ENDIF(DOCDIR)
add_definitions(-DBOOST_${Boost_VERSION})
#if you want to use the old DAG structure uncomment this line
#add_definitions(-DUSE_OLD_DAG)
+12 -12
View File
@@ -197,7 +197,7 @@ public:
ColorField (void);
ColorField (const ColorField &rclCF);
ColorField (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt);
virtual ~ColorField ();
virtual ~ColorField ();
ColorField& operator = (const ColorField &rclCF);
@@ -212,7 +212,7 @@ public:
void setDirect (unsigned short usInd, Color clCol) { _aclField[usInd] = clCol; }
float getMinValue (void) const { return _fMin; }
float getMaxValue (void) const { return _fMax; }
Color getColor (unsigned short usIndex) const { return _aclField[usIndex]; }
inline Color getColor (float fVal) const;
inline unsigned short getColorIndex (float fVal) const;
@@ -281,7 +281,7 @@ public:
ColorGradient& operator = (const ColorGradient &rclCR);
void set (float fMin, float fMax, unsigned short usCt, TStyle tS, bool bOG);
void set (float fMin, float fMax, unsigned short usCt, TStyle tS, bool bOG);
void setRange (float fMin, float fMax) { set(fMin, fMax, _usCtColors, _tStyle, _bOutsideGrayed); }
void getRange (float &rfMin, float &rfMax) const { rfMin = _fMin; rfMax = _fMax; }
unsigned short getCountColors (void) const { return _usCtColors; }
@@ -305,9 +305,9 @@ protected:
TColorModel _tColorModel;
TStyle _tStyle;
float _fMin, _fMax;
unsigned short _usCtColors;
unsigned short _usCtColors;
bool _bOutsideGrayed;
ColorModel _clTotal, _clTop, _clBottom;
ColorModel _clTotal, _clTop, _clBottom;
void rebuild (void);
void setColorModel (void);
@@ -330,7 +330,7 @@ public:
bool addMax (const std::string &rclName);
bool remove (unsigned long ulPos);
void removeFirst (void);
void removeLast (void);
void removeLast (void);
Color getColor (unsigned long ulPos) const;
uint32_t getPackedColor (unsigned long ulPos) const;
@@ -426,10 +426,10 @@ inline Color ColorGradient::getColor (float fVal) const
else
return _clColFld2.getColor(fVal);
}
else
else
return _clColFld1.getColor(fVal);
}
default:
case FLOW:
{
@@ -451,10 +451,10 @@ inline unsigned short ColorGradient::getColorIndex (float fVal) const
else
return (unsigned short)(_clColFld1.getCountColors() + _clColFld2.getColorIndex(fVal));
}
else
else
return _clColFld1.getColorIndex(fVal);
}
default:
case FLOW:
{
@@ -464,7 +464,7 @@ inline unsigned short ColorGradient::getColorIndex (float fVal) const
}
inline const ColorModel& ColorGradient::getColorModel (void) const
{
{
if ( _tStyle == ZERO_BASED )
{
if ( _fMax <= 0.0f )
@@ -482,4 +482,4 @@ inline const ColorModel& ColorGradient::getColorModel (void) const
} // namespace App
#endif // APP_COLORMODEL_H
#endif // APP_COLORMODEL_H
+4 -4
View File
@@ -58,7 +58,7 @@ public:
class AppExport ComplexGeoData: public Base::Persistence, public Base::Handled
{
TYPESYSTEM_HEADER();
public:
struct Line {uint32_t I1; uint32_t I2;};
struct Facet {uint32_t I1; uint32_t I2; uint32_t I3;};
@@ -109,11 +109,11 @@ public:
* using the setTransform() method.
*/
void setPlacement(const Base::Placement& rclPlacement);
/** Return the current transformation as placement using
/** Return the current transformation as placement using
* getTransform().
*/
Base::Placement getPlacement() const;
/** Override the current transformation with the new one.
/** Override the current transformation with the new one.
* This method has to be handled by the child classes.
* the actual placement and matrix is not part of this class.
*/
@@ -201,7 +201,7 @@ protected:
/// from local to inside
inline Base::Vector3f transformToInside(const Base::Vector3d& vec) const
{
Base::Matrix4D tmpM(getTransform());
Base::Matrix4D tmpM(getTransform());
tmpM.inverse();
Base::Vector3d tmp = tmpM * vec;
return Base::Vector3f((float)tmp.x,(float)tmp.y,(float)tmp.z);
+1 -1
View File
@@ -141,5 +141,5 @@ PyObject *ComplexGeoDataPy::getCustomAttributes(const char* /*attr*/) const
int ComplexGeoDataPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
return 0;
}
+173 -80
View File
@@ -26,7 +26,7 @@
\ingroup APP
\brief The Base class of the FreeCAD Document
This is (besides the App::Application class) the most important class in FreeCAD.
This (besides the App::Application class) is the most important class in FreeCAD.
It contains all the data of the opened, saved, or newly created FreeCAD Document.
The App::Document manages the Undo and Redo mechanism and the linking of documents.
@@ -70,7 +70,7 @@ recompute path. Also, it enables more complicated dependencies beyond trees.
#include <boost/algorithm/string.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost_graph_adjacency_list.hpp>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/strong_components.hpp>
@@ -82,7 +82,7 @@ recompute path. Also, it enables more complicated dependencies beyond trees.
#include <boost/graph/visitors.hpp>
#endif //USE_OLD_DAG
#include <boost/bind.hpp>
#include <boost_bind_bind.hpp>
#include <boost/regex.hpp>
#include <unordered_set>
#include <unordered_map>
@@ -178,16 +178,18 @@ struct DocumentP
bool rollback;
bool undoing; ///< document in the middle of undo or redo
bool committing;
bool opentransaction;
std::bitset<32> StatusBits;
int iUndoMode;
unsigned int UndoMemSize;
unsigned int UndoMaxStackSize;
std::string programVersion;
#ifdef USE_OLD_DAG
DependencyList DepList;
std::map<DocumentObject*,Vertex> VertexObjectList;
std::map<Vertex,DocumentObject*> vertexMap;
#endif //USE_OLD_DAG
std::multimap<const App::DocumentObject*,
std::multimap<const App::DocumentObject*,
std::unique_ptr<App::DocumentObjectExecReturn> > _RecomputeLog;
DocumentP() {
@@ -197,13 +199,14 @@ struct DocumentP
// Set some random offset to reduce likelihood of ID collision when
// copying shape from other document. It is probably better to randomize
// on each object ID.
lastObjectId = _RDIST(_RGEN);
lastObjectId = _RDIST(_RGEN);
activeObject = 0;
activeUndoTransaction = 0;
iTransactionMode = 0;
rollback = false;
undoing = false;
committing = false;
opentransaction = false;
StatusBits.set((size_t)Document::Closable, true);
StatusBits.set((size_t)Document::KeepTrailingDigits, true);
StatusBits.set((size_t)Document::Restoring, false);
@@ -626,7 +629,10 @@ void Document::exportGraphviz(std::ostream& out) const
//first build up the coordinate system subgraphs
for (auto objectIt : d->objectArray) {
// do not require an empty inlist (#0003465: Groups breaking dependency graph)
if (objectIt->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()))
// App::Origin now has the GeoFeatureGroupExtension but it should not move its
// group symbol outside its parent
if (!objectIt->isDerivedFrom(Origin::getClassTypeId()) &&
objectIt->hasExtension(GeoFeatureGroupExtension::getExtensionClassTypeId()))
recursiveCSSubgraphs(objectIt, nullptr);
}
}
@@ -804,6 +810,12 @@ void Document::exportGraphviz(std::ostream& out) const
}
}
#if defined(__clang__)
#elif defined (__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
void markCycles() {
bool changed = true;
std::unordered_set<Vertex> in_use;
@@ -869,6 +881,11 @@ void Document::exportGraphviz(std::ostream& out) const
edgeAttrMap[ei->second]["color"] = "red";
}
#if defined(__clang__)
#elif defined (__GNUC__)
# pragma GCC diagnostic pop
#endif
void markOutOfScopeLinks() {
const boost::property_map<Graph, boost::edge_attribute_t>::type& edgeAttrMap = boost::get(boost::edge_attribute, DepList);
@@ -949,6 +966,7 @@ bool Document::undo(int id)
d->activeUndoTransaction = new Transaction(mUndoTransactions.back()->getID());
d->activeUndoTransaction->Name = mUndoTransactions.back()->Name;
{
Base::FlagToggler<bool> flag(d->undoing);
// applying the undo
mUndoTransactions.back()->apply(*this,false);
@@ -962,7 +980,17 @@ bool Document::undo(int id)
delete mUndoTransactions.back();
mUndoTransactions.pop_back();
signalUndo(*this);
}
for(auto & obj:d->objectArray) {
if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) {
obj->onUndoRedoFinished();
obj->setStatus(ObjectStatus::PendingTransactionUpdate,false);
}
}
signalUndo(*this); // now signal the undo
return true;
}
@@ -990,6 +1018,7 @@ bool Document::redo(int id)
d->activeUndoTransaction->Name = mRedoTransactions.back()->Name;
// do the redo
{
Base::FlagToggler<bool> flag(d->undoing);
mRedoTransactions.back()->apply(*this,true);
@@ -1000,6 +1029,14 @@ bool Document::redo(int id)
mRedoMap.erase(mRedoTransactions.back()->getID());
delete mRedoTransactions.back();
mRedoTransactions.pop_back();
}
for(auto & obj:d->objectArray) {
if(obj->testStatus(ObjectStatus::PendingTransactionUpdate)) {
obj->onUndoRedoFinished();
obj->setStatus(ObjectStatus::PendingTransactionUpdate,false);
}
}
signalRedo(*this);
return true;
@@ -1010,7 +1047,7 @@ bool Document::redo(int id)
void Document::addOrRemovePropertyOfObject(TransactionalObject* obj, Property *prop, bool add)
{
if (!prop || !obj || !obj->isAttachedToDocument())
if (!prop || !obj || !obj->isAttachedToDocument())
return;
if(d->iUndoMode && !isPerformingTransaction() && !d->activeUndoTransaction) {
if(!testStatus(Restoring) || testStatus(Importing)) {
@@ -1066,6 +1103,14 @@ int Document::_openTransaction(const char* name, int id)
}
if (d->iUndoMode) {
// Avoid recursive calls that is possible while
// clearing the redo transactions and will cause
// a double deletion of some transaction and thus
// a segmentation fault
if (d->opentransaction)
return 0;
Base::FlagToggler<> flag(d->opentransaction);
if(id && mUndoMap.find(id)!=mUndoMap.end())
throw Base::RuntimeError("invalid transaction id");
if (d->activeUndoTransaction)
@@ -1083,9 +1128,9 @@ int Document::_openTransaction(const char* name, int id)
auto &app = GetApplication();
auto activeDoc = app.getActiveDocument();
if(activeDoc &&
activeDoc!=this &&
!activeDoc->hasPendingTransaction())
if(activeDoc &&
activeDoc!=this &&
!activeDoc->hasPendingTransaction())
{
std::string aname("-> ");
aname += d->activeUndoTransaction->Name;
@@ -1117,18 +1162,14 @@ void Document::_checkTransaction(DocumentObject* pcDelObj, const Property *What,
const char *name = GetApplication().getActiveTransaction(&tid);
if(name && tid>0) {
bool ignore = false;
if(What) {
auto parent = What->getContainer();
auto parentObj = Base::freecad_dynamic_cast<DocumentObject>(parent);
if(!parentObj || What->testStatus(Property::NoModify))
ignore = true;
}
if(What && What->testStatus(Property::NoModify))
ignore = true;
if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
if(What)
FC_LOG((ignore?"ignore":"auto") << " transaction ("
<< line << ") '" << What->getFullName());
if(What)
FC_LOG((ignore?"ignore":"auto") << " transaction ("
<< line << ") '" << What->getFullName());
else
FC_LOG((ignore?"ignore":"auto") <<" transaction ("
FC_LOG((ignore?"ignore":"auto") <<" transaction ("
<< line << ") '" << name << "' in " << getName());
}
if(!ignore)
@@ -1177,11 +1218,16 @@ void Document::commitTransaction() {
void Document::_commitTransaction(bool notify)
{
if(isPerformingTransaction() || d->committing) {
if (isPerformingTransaction()) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Cannot commit transaction while transacting");
return;
}
else if (d->committing) {
// for a recursive call return without printing a warning
return;
}
if (d->activeUndoTransaction) {
Base::FlagToggler<> flag(d->committing);
Application::TransactionSignaller signaller(false,true);
@@ -1196,7 +1242,8 @@ void Document::_commitTransaction(bool notify)
}
signalCommitTransaction(*this);
if(notify)
// closeActiveTransaction() may call again _commitTransaction()
if (notify)
GetApplication().closeActiveTransaction(false,id);
}
}
@@ -1207,7 +1254,7 @@ void Document::abortTransaction() {
FC_WARN("Cannot abort transaction while transacting");
return;
}
if (d->activeUndoTransaction)
if (d->activeUndoTransaction)
GetApplication().closeActiveTransaction(true,d->activeUndoTransaction->getID());
}
@@ -1348,7 +1395,8 @@ int Document::getAvailableUndos(int id) const
return i;
}
auto rit = mUndoTransactions.rbegin();
for(;rit!=mUndoTransactions.rend()&&*rit!=it->second;++rit,++i);
for(;rit!=mUndoTransactions.rend()&&*rit!=it->second;++rit)
++i;
assert(rit!=mUndoTransactions.rend());
return i+1;
}
@@ -1365,7 +1413,8 @@ int Document::getAvailableRedos(int id) const
if(it == mRedoMap.end())
return 0;
int i = 0;
for(auto rit=mRedoTransactions.rbegin();*rit!=it->second;++rit,++i);
for(auto rit=mRedoTransactions.rbegin();*rit!=it->second;++rit)
++i;
assert(i<(int)mRedoTransactions.size());
return i+1;
}
@@ -1571,7 +1620,7 @@ Document::Document(const char *name)
ADD_PROPERTY_TYPE(License,(license.c_str()),0,Prop_None,"License string of the Item");
ADD_PROPERTY_TYPE(LicenseURL,(licenseUrl.c_str()),0,Prop_None,"URL to the license text/contract");
ADD_PROPERTY_TYPE(ShowHidden,(false), 0,PropertyType(Prop_None),
ADD_PROPERTY_TYPE(ShowHidden,(false), 0,PropertyType(Prop_None),
"Whether to show hidden object items in the tree view");
// this creates and sets 'TransientDir' in onChanged()
@@ -1834,7 +1883,7 @@ void Document::writeObjects(const std::vector<App::DocumentObject*>& obj,
for(auto o : obj) {
const auto &outList = o->getOutList(DocumentObject::OutListNoHidden
| DocumentObject::OutListNoXLinked);
writer.Stream() << writer.ind()
writer.Stream() << writer.ind()
<< "<" FC_ELEMENT_OBJECT_DEPS " " FC_ATTR_DEP_OBJ_NAME "=\""
<< o->getNameInDocument() << "\" " FC_ATTR_DEP_COUNT "=\"" << outList.size();
if(outList.empty()) {
@@ -1874,7 +1923,7 @@ void Document::writeObjects(const std::vector<App::DocumentObject*>& obj,
if ((*it)->testStatus(ObjectStatus::Error)) {
writer.Stream() << "Invalid=\"1\" ";
auto desc = getErrorDescription(*it);
if(desc)
if(desc)
writer.Stream() << "Error=\"" << Property::encodeAttribute(desc) << "\" ";
}
writer.Stream() << "/>" << endl;
@@ -1907,9 +1956,9 @@ struct DepInfo {
int canLoadPartial = 0;
};
static void _loadDeps(const std::string &name,
std::unordered_map<std::string,bool> &objs,
const std::unordered_map<std::string,DepInfo> &deps)
static void _loadDeps(const std::string &name,
std::unordered_map<std::string,bool> &objs,
const std::unordered_map<std::string,DepInfo> &deps)
{
auto it = deps.find(name);
if(it == deps.end()) {
@@ -2049,7 +2098,7 @@ Document::readObjects(Base::XMLReader& reader)
}
if (reader.hasAttribute("Invalid")) {
obj->setStatus(ObjectStatus::Error, reader.getAttributeAsInteger("Invalid") != 0);
if(obj->isError() && reader.hasAttribute("Error"))
if(obj->isError() && reader.hasAttribute("Error"))
d->addRecomputeLog(reader.getAttribute("Error"),obj);
}
}
@@ -2092,6 +2141,9 @@ Document::readObjects(Base::XMLReader& reader)
catch (const Base::RuntimeError &e) {
e.ReportException();
}
catch (const Base::XMLAttributeError &e) {
e.ReportException();
}
pObj->setStatus(ObjectStatus::Restore, false);
@@ -2693,8 +2745,11 @@ void Document::restore (const char *filename,
}
catch (const Base::Exception& e) {
Base::Console().Error("Invalid Document.xml: %s\n", e.what());
setStatus(Document::RestoreError, true);
}
d->partialLoadObjects.clear();
d->programVersion = reader.ProgramVersion;
// Special handling for Gui document, the view representations must already
// exist, what is done in Restore().
@@ -2723,7 +2778,7 @@ void Document::afterRestore(bool checkPartial) {
setStatus(Document::Restoring, false);
}
bool Document::afterRestore(const std::vector<DocumentObject *> &objArray, bool checkPartial)
bool Document::afterRestore(const std::vector<DocumentObject *> &objArray, bool checkPartial)
{
checkPartial = checkPartial && testStatus(Document::PartialDoc);
if(checkPartial && d->touchedObjs.size())
@@ -2743,7 +2798,7 @@ bool Document::afterRestore(const std::vector<DocumentObject *> &objArray, bool
try {
prop->afterRestore();
} catch (const Base::Exception& e) {
FC_ERR("Failed to restore " << obj->getFullName()
FC_ERR("Failed to restore " << obj->getFullName()
<< '.' << prop->getName() << ": " << e.what());
}
}
@@ -2810,7 +2865,7 @@ bool Document::afterRestore(const std::vector<DocumentObject *> &objArray, bool
if(checkPartial && d->touchedObjs.size()) {
// partial document touched, signal full reload
return false;
} else if(!d->touchedObjs.count(obj))
} else if(!d->touchedObjs.count(obj))
obj->purgeTouched();
signalFinishRestoreObject(*obj);
@@ -2849,6 +2904,17 @@ std::string Document::getFullName() const {
return myName;
}
const char* Document::getProgramVersion() const
{
return d->programVersion.c_str();
}
const char* Document::getFileName() const
{
return testStatus(TempDoc) ? TransientDir.getValue()
: FileName.getValue();
}
/// Remove all modifications. After this call The document becomes valid again.
void Document::purgeTouched()
{
@@ -2890,11 +2956,11 @@ int Document::countObjects(void) const
return static_cast<int>(d->objectArray.size());
}
void Document::getLinksTo(std::set<DocumentObject*> &links,
void Document::getLinksTo(std::set<DocumentObject*> &links,
const DocumentObject *obj, int options, int maxCount,
const std::vector<DocumentObject*> &objs) const
const std::vector<DocumentObject*> &objs) const
{
std::map<const App::DocumentObject*,App::DocumentObject*> linkMap;
std::map<const App::DocumentObject*, std::vector<App::DocumentObject*> > linkMap;
for(auto o : objs.size()?objs:d->objectArray) {
if(o == obj) continue;
@@ -2903,7 +2969,7 @@ void Document::getLinksTo(std::set<DocumentObject*> &links,
linked = o->getLinkedObject(false);
else {
auto ext = o->getExtensionByType<LinkBaseExtension>(true);
if(ext)
if(ext)
linked = ext->getTrueLinkedObject(false,0,0,true);
else
linked = o->getLinkedObject(false);
@@ -2911,7 +2977,7 @@ void Document::getLinksTo(std::set<DocumentObject*> &links,
if(linked && linked!=o) {
if(options & GetLinkRecursive)
linkMap[linked] = o;
linkMap[linked].push_back(o);
else if(linked == obj || !obj) {
if((options & GetLinkExternal)
&& linked->getDocument()==o->getDocument())
@@ -2934,15 +3000,19 @@ void Document::getLinksTo(std::set<DocumentObject*> &links,
if(!GetApplication().checkLinkDepth(depth,true))
break;
std::vector<const DocumentObject*> next;
for(auto o : current) {
for(const App::DocumentObject *o : current) {
auto iter = linkMap.find(o);
if(iter!=linkMap.end() && links.insert(iter->second).second) {
if(maxCount && maxCount<=(int)links.size())
return;
next.push_back(iter->second);
if(iter==linkMap.end())
continue;
for (App::DocumentObject *link : iter->second) {
if (links.insert(link).second) {
if(maxCount && maxCount<=(int)links.size())
return;
next.push_back(link);
}
}
}
current.swap(next);
current = std::move(next);
}
return;
}
@@ -2983,8 +3053,8 @@ std::vector<App::DocumentObject*> Document::getInList(const DocumentObject* me)
// external object.
//
static void _buildDependencyList(const std::vector<App::DocumentObject*> &objectArray,
int options, std::vector<App::DocumentObject*> *depObjs,
DependencyList *depList, std::map<DocumentObject*,Vertex> *objectMap,
int options, std::vector<App::DocumentObject*> *depObjs,
DependencyList *depList, std::map<DocumentObject*,Vertex> *objectMap,
bool *touchCheck = 0)
{
std::map<DocumentObject*, std::vector<DocumentObject*> > outLists;
@@ -3063,7 +3133,7 @@ std::vector<App::DocumentObject*> Document::getDependencyList(
std::map<int,std::vector<Vertex> > components;
boost::strong_components(depList,boost::make_iterator_property_map(
c.begin(),boost::get(boost::vertex_index,depList),c[0]));
for(size_t i=0;i<c.size();++i)
for(size_t i=0;i<c.size();++i)
components[c[i]].push_back(i);
FC_ERR("Dependency cycles: ");
@@ -3115,7 +3185,7 @@ std::vector<App::Document*> Document::getDependentDocuments(bool sort) {
}
std::vector<App::Document*> Document::getDependentDocuments(
std::vector<App::Document*> pending, bool sort)
std::vector<App::Document*> pending, bool sort)
{
DependencyList depList;
std::map<Document*,Vertex> docMap;
@@ -3340,7 +3410,7 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
#else //ifdef USE_OLD_DAG
int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool force, bool *hasError, int options)
int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool force, bool *hasError, int options)
{
if (d->undoing || d->rollback) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
@@ -3350,7 +3420,7 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
int objectCount = 0;
if (testStatus(Document::PartialDoc)) {
if(mustExecute())
if(mustExecute())
FC_WARN("Please reload partial document '" << Label.getValue() << "' for recomputation.");
return 0;
}
@@ -3376,7 +3446,7 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
#if 0
//////////////////////////////////////////////////////////////////////////
// FIXME Comment by Realthunder:
// FIXME Comment by Realthunder:
// the topologicalSrot() below cannot handle partial recompute, haven't got
// time to figure out the code yet, simply use back boost::topological_sort
// for now, that is, rely on getDependencyList() to do the sorting. The
@@ -3414,7 +3484,7 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
if(canAbort)
seq.reset(new Base::SequencerLauncher("Recompute...", topoSortedObjects.size()));
FC_LOG("Recompute pass " << passes);
for (;idx<topoSortedObjects.size();(seq?seq->next(true):true),++idx) {
for (; idx < topoSortedObjects.size(); ++idx) {
auto obj = topoSortedObjects[idx];
if(!obj->getNameInDocument() || filter.find(obj)!=filter.end())
continue;
@@ -3445,13 +3515,15 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
for (auto inObjIt : obj->getInList())
inObjIt->enforceRecompute();
}
if (seq)
seq->next(true);
}
// check if all objects are recomputed but still thouched
// check if all objects are recomputed but still thouched
for (size_t i=0;i<topoSortedObjects.size();++i) {
auto obj = topoSortedObjects[i];
obj->setStatus(ObjectStatus::Recompute2,false);
if(!filter.count(obj) && obj->isTouched()) {
if(passes>0)
if(passes>0)
FC_ERR(obj->getFullName() << " still touched after recompute");
else{
FC_LOG(obj->getFullName() << " still touched after recompute");
@@ -3483,8 +3555,8 @@ int Document::recompute(const std::vector<App::DocumentObject*> &objs, bool forc
FC_TIME_LOG(t,"Recompute total");
if(d->_RecomputeLog.size())
Base::Console().Error("Recompute failed! Please check report view.\n");
if (d->_RecomputeLog.size())
Base::Console().Log("Recompute failed! Please check report view.\n");
return objectCount;
}
@@ -3679,7 +3751,7 @@ int Document::_recomputeFeature(DocumentObject* Feat)
}
catch(Base::AbortException &e){
e.ReportException();
FC_ERR("Failed to recompute " << Feat->getFullName() << ": " << e.what());
FC_LOG("Failed to recompute " << Feat->getFullName() << ": " << e.what());
d->addRecomputeLog("User abort",Feat);
return -1;
}
@@ -3690,7 +3762,7 @@ int Document::_recomputeFeature(DocumentObject* Feat)
}
catch (Base::Exception &e) {
e.ReportException();
FC_ERR("Failed to recompute " << Feat->getFullName() << ": " << e.what());
FC_LOG("Failed to recompute " << Feat->getFullName() << ": " << e.what());
d->addRecomputeLog(e.what(),Feat);
return 1;
}
@@ -3707,12 +3779,13 @@ int Document::_recomputeFeature(DocumentObject* Feat)
}
#endif
if(returnCode == DocumentObject::StdReturn) {
if (returnCode == DocumentObject::StdReturn) {
Feat->resetError();
}else{
}
else {
returnCode->Which = Feat;
d->addRecomputeLog(returnCode);
FC_ERR("Failed to recompute " << Feat->getFullName() << ": " << returnCode->Why);
FC_LOG("Failed to recompute " << Feat->getFullName() << ": " << returnCode->Why);
return 1;
}
return 0;
@@ -3738,7 +3811,7 @@ bool Document::recomputeFeature(DocumentObject* Feat, bool recursive)
return false;
}
DocumentObject * Document::addObject(const char* sType, const char* pObjectName,
DocumentObject * Document::addObject(const char* sType, const char* pObjectName,
bool isNew, const char* viewType, bool isPartial)
{
Base::BaseClass* base = static_cast<Base::BaseClass*>(Base::Type::createInstanceByName(sType,true));
@@ -4084,6 +4157,11 @@ void Document::removeObject(const char* sName)
TipName.setValue("");
}
// remove the ID before possibly deleting the object
d->objectIdMap.erase(pos->second->_Id);
// Unset the bit to be on the safe side
pos->second->setStatus(ObjectStatus::Remove, false);
// do no transactions if we do a rollback!
std::unique_ptr<DocumentObject> tobedestroyed;
if (!d->rollback) {
@@ -4107,8 +4185,6 @@ void Document::removeObject(const char* sName)
}
}
pos->second->setStatus(ObjectStatus::Remove, false); // Unset the bit to be on the safe side
d->objectIdMap.erase(pos->second->_Id);
d->objectMap.erase(pos);
}
@@ -4196,7 +4272,7 @@ void Document::breakDependency(DocumentObject* pcObject, bool clear)
}
std::vector<DocumentObject*> Document::copyObject(
const std::vector<DocumentObject*> &objs, bool recursive)
const std::vector<DocumentObject*> &objs, bool recursive, bool returnAll)
{
std::vector<DocumentObject*> deps;
if(!recursive)
@@ -4204,10 +4280,11 @@ std::vector<DocumentObject*> Document::copyObject(
else
deps = getDependencyList(objs,DepNoXLinked|DepSort);
if(!isSaved() && PropertyXLink::hasXLink(deps))
if (!testStatus(TempDoc) && !isSaved() && PropertyXLink::hasXLink(deps)) {
throw Base::RuntimeError(
"Document must be saved at least once before link to external objects");
}
MergeDocuments md(this);
// if not copying recursively then suppress possible warnings
md.setVerbose(recursive);
@@ -4246,7 +4323,7 @@ std::vector<DocumentObject*> Document::copyObject(
imported = md.importObjects(istr);
}
if(imported.size()!=deps.size())
if (returnAll || imported.size()!=deps.size())
return imported;
std::unordered_map<App::DocumentObject*,size_t> indices;
@@ -4260,7 +4337,7 @@ std::vector<DocumentObject*> Document::copyObject(
return result;
}
std::vector<App::DocumentObject*>
std::vector<App::DocumentObject*>
Document::importLinks(const std::vector<App::DocumentObject*> &objArray)
{
std::set<App::DocumentObject*> links;
@@ -4324,7 +4401,7 @@ Document::importLinks(const std::vector<App::DocumentObject*> &objArray)
// properties, e.g. a link sub referring to some sub object of an xlink, If
// that sub object is imported with a different name, and xlink is changed
// before this link sub, it will break.
for(auto &v : propMap)
for(auto &v : propMap)
v.first->Paste(*v.second);
return objs;
@@ -4340,7 +4417,7 @@ DocumentObject* Document::moveObject(DocumentObject* obj, bool recursive)
// True object move without copy is only safe when undo is off on both
// documents.
if(!recursive && !d->iUndoMode && !that->d->iUndoMode) {
if(!recursive && !d->iUndoMode && !that->d->iUndoMode && !that->d->rollback) {
// all object of the other document that refer to this object must be nullified
that->breakDependency(obj, false);
std::string objname = getUniqueObjectName(obj->getNameInDocument());
@@ -4351,13 +4428,13 @@ DocumentObject* Document::moveObject(DocumentObject* obj, bool recursive)
}
std::vector<App::DocumentObject*> deps;
if(recursive)
if(recursive)
deps = getDependencyList({obj},DepNoXLinked|DepSort);
else
deps.push_back(obj);
auto objs = copyObject(deps,false);
if(objs.empty())
if(objs.empty())
return 0;
// Some object may delete its children if deleted, so we collect the IDs
// or all depending objects for safety reason.
@@ -4501,15 +4578,31 @@ std::vector< DocumentObject* > Document::getObjectsWithExtension(const Base::Typ
}
std::vector<DocumentObject*> Document::findObjects(const Base::Type& typeId, const char* objname) const
std::vector<DocumentObject*> Document::findObjects(const Base::Type& typeId, const char* objname, const char* label) const
{
boost::regex rx(objname);
boost::cmatch what;
boost::regex rx_name, rx_label;
if (objname)
rx_name.set_expression(objname);
if (label)
rx_label.set_expression(label);
std::vector<DocumentObject*> Objects;
DocumentObject* found = nullptr;
for (std::vector<DocumentObject*>::const_iterator it = d->objectArray.begin(); it != d->objectArray.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(typeId)) {
if (boost::regex_match((*it)->getNameInDocument(), what, rx))
Objects.push_back(*it);
found = *it;
if (!rx_name.empty() && !boost::regex_search((*it)->getNameInDocument(), what, rx_name))
found = nullptr;
if (!rx_label.empty() && !boost::regex_search((*it)->Label.getValue(), what, rx_label))
found = nullptr;
if (found)
Objects.push_back(found);
}
}
return Objects;
+28 -11
View File
@@ -37,7 +37,7 @@
#include <stack>
#include <functional>
#include <boost/signals2.hpp>
#include <boost_signals2.hpp>
namespace Base {
class Writer;
@@ -73,6 +73,8 @@ public:
Importing = 6,
PartialDoc = 7,
AllowPartialRecompute = 8, // allow recomputing editing object if SkipRecompute is set
TempDoc = 9, // Mark as temporary document without prompt for save
RestoreError = 10
};
/** @name Properties */
@@ -178,6 +180,7 @@ public:
boost::signals2::signal<void (const App::DocumentObject&)> signalFinishRestoreObject;
boost::signals2::signal<void (const App::Document&,const App::Property&)> signalChangePropertyEditor;
//@}
boost::signals2::signal<void (std::string)> signalLinkXsetValue;
void clearDocument();
@@ -191,7 +194,7 @@ public:
bool saveAs(const char* file);
bool saveCopy(const char* file) const;
/// Restore the document from the file in Property Path
void restore (const char *filename=0,
void restore (const char *filename=0,
bool delaySignal=false, const std::set<std::string> &objNames={});
void afterRestore(bool checkPartial=false);
bool afterRestore(const std::vector<App::DocumentObject *> &, bool checkPartial=false);
@@ -207,7 +210,7 @@ public:
*
* @param objs: input list of objects. Only objects belonging to this document will
* be checked for external links. And all found external linked object will be imported
* to this document. Link type properties of those input objects will be automatically
* to this document. Link type properties of those input objects will be automatically
* reassigned to the imported objects. Note that the link properties of other objects
* in the document but not included in the input list, will not be affected even if they
* point to some object beining imported. To import all objects, simply pass in all objects
@@ -223,6 +226,15 @@ public:
bool isSaved() const;
/// Get the document name
const char* getName() const;
/// Get program version the project file was created with
const char* getProgramVersion() const;
/** Returned filename
*
* For saved document, this will be the content stored in property
* 'Filename'. For unsaved temporary file, this will be the content of
* property 'TransientDir'.
*/
const char* getFileName() const;
//@}
virtual void Save (Base::Writer &writer) const override;
@@ -241,7 +253,7 @@ public:
* @param viewType override object's view provider name
* @param isPartial indicate if this object is meant to be partially loaded
*/
DocumentObject *addObject(const char* sType, const char* pObjectName=0,
DocumentObject *addObject(const char* sType, const char* pObjectName=0,
bool isNew=true, const char *viewType=0, bool isPartial=false);
/** Add an array of features of the given types and names.
* Unicode names are set through the Label property.
@@ -267,10 +279,15 @@ public:
* @param recursive: if true, then all objects this object depends on are
* copied as well. By default \a recursive is false.
*
* @param returnAll: if true, return all copied objects including those
* auto included by recursive searching. If false, then only return the
* copied object corresponding to the input objects.
*
* @return Returns the list of objects copied.
*/
std::vector<DocumentObject*> copyObject(
const std::vector<DocumentObject*> &objs, bool recursive=false);
const std::vector<DocumentObject*> &objs,
bool recursive=false, bool returnAll=false);
/** Move an object from another document to this document
* If \a recursive is true then all objects this object depends on
* are moved as well. By default \a recursive is false.
@@ -299,7 +316,7 @@ public:
std::vector<DocumentObject*> getObjectsOfType(const Base::Type& typeId) const;
/// Returns all object with given extensions. If derived=true also all objects with extensions derived from the given one
std::vector<DocumentObject*> getObjectsWithExtension(const Base::Type& typeId, bool derived = true) const;
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname) const;
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname, const char* label) const;
/// Returns an array with the correct types already.
template<typename T> inline std::vector<T*> getObjectsOfType() const;
int countObjectsOfType(const Base::Type& typeId) const;
@@ -340,7 +357,7 @@ public:
//@}
/** @name methods for the UNDO REDO and Transaction handling
/** @name methods for the UNDO REDO and Transaction handling
*
* Introduce a new concept of transaction ID. Each transaction must be
* unique inside the document. Multiple transactions from different
@@ -431,13 +448,13 @@ public:
/// Raise exception on cycles
DepNoCycle = 4,
};
/** Get a complete list of all objects the given objects depend on.
/** Get a complete list of all objects the given objects depend on.
*
* This function is defined as static because it accepts objects from
* different documents, and the returned list will contain dependent
* objects from all relevant documents
*
* @param objs: input objects to query for dependency.
* @param objs: input objects to query for dependency.
* @param options: See DependencyOption
*/
static std::vector<App::DocumentObject*> getDependencyList(
@@ -461,12 +478,12 @@ public:
*
* @param links: holds the links found
* @param obj: the linked object. If NULL, then all links are returned.
* @param option: @sa App::GetLinkOptions
* @param option: @sa App::GetLinkOption
* @param maxCount: limit the number of links returned, 0 means no limit
* @param objs: optional objects to search for, if empty, then all objects
* of this document are searched.
*/
void getLinksTo(std::set<DocumentObject*> &links,
void getLinksTo(std::set<DocumentObject*> &links,
const DocumentObject *obj, int options, int maxCount=0,
const std::vector<DocumentObject*> &objs = {}) const;
+30 -6
View File
@@ -42,7 +42,7 @@
#include "DocumentObjectExtension.h"
#include "GeoFeatureGroupExtension.h"
#include <App/DocumentObjectPy.h>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
FC_LOG_LEVEL_INIT("App",true,true)
@@ -108,12 +108,31 @@ App::DocumentObjectExecReturn *DocumentObject::recompute(void)
// set/unset the execution bit
Base::ObjectStatusLocker<ObjectStatus, DocumentObject> exe(App::Recompute, this);
return this->execute();
// mark the object to recompute its extensions
this->setStatus(App::RecomputeExtension, true);
auto ret = this->execute();
if (ret == StdReturn) {
// most feature classes don't call the execute() method of its base class
// so execute the extensions now
if (this->testStatus(App::RecomputeExtension)) {
ret = executeExtensions();
}
}
return ret;
}
DocumentObjectExecReturn *DocumentObject::execute(void)
{
//call all extensions
return executeExtensions();
}
App::DocumentObjectExecReturn* DocumentObject::executeExtensions()
{
//execute extensions but stop on error
this->setStatus(App::RecomputeExtension, false); // reset the flag
auto vector = getExtensionsDerivedFromType<App::DocumentObjectExtension>();
for(auto ext : vector) {
auto ret = ext->extensionExecute();
@@ -663,7 +682,7 @@ bool DocumentObject::removeDynamicProperty(const char* name)
}
for (auto it : removeExpr) {
ExpressionEngine.setValue(it, boost::shared_ptr<Expression>());
ExpressionEngine.setValue(it, std::shared_ptr<Expression>());
}
return TransactionalObject::removeDynamicProperty(name);
@@ -699,7 +718,7 @@ void DocumentObject::onChanged(const Property* prop)
return;
if(!GetApplication().isRestoring() &&
prop && !prop->testStatus(Property::PartialTrigger) &&
!prop->testStatus(Property::PartialTrigger) &&
getDocument() &&
getDocument()->testStatus(Document::PartialDoc))
{
@@ -893,7 +912,7 @@ void DocumentObject::Save (Base::Writer &writer) const
* @param expr Expression tree
*/
void DocumentObject::setExpression(const ObjectIdentifier &path, boost::shared_ptr<Expression> expr)
void DocumentObject::setExpression(const ObjectIdentifier &path, std::shared_ptr<Expression> expr)
{
ExpressionEngine.setValue(path, expr);
}
@@ -936,6 +955,11 @@ void DocumentObject::onDocumentRestored()
Visibility.setStatus(Property::NoModify,true);
}
void DocumentObject::onUndoRedoFinished()
{
}
void DocumentObject::onSettingDocument()
{
//call all extensions
+28 -19
View File
@@ -36,7 +36,7 @@
#include <unordered_map>
#include <bitset>
#include <boost/signals2.hpp>
#include <boost_signals2.hpp>
namespace App
{
@@ -64,6 +64,8 @@ enum ObjectStatus {
GeoExcluded = 15, // mark as a member but not claimed by GeoFeatureGroup
Expand = 16, // indicate the object's tree item expansion status
NoAutoExpand = 17, // disable tree item auto expand on selection for this object
PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished.
RecomputeExtension = 19, // mark the object to recompute its extensions
};
/** Return object for feature execution
@@ -182,14 +184,14 @@ public:
*/
//@{
/** Set sub-element visibility
*
*
* For performance reason, \c element must not contain any further
* sub-elements, i.e. there should be no '.' inside \c element.
*
* @return -1 if element visibility is not supported, 0 if element is not
* found, 1 if success
*/
virtual int setElementVisible(const char *element, bool visible);
virtual int setElementVisible(const char *element, bool visible);
/** Get sub-element visibility
*
@@ -245,7 +247,7 @@ public:
* @param inList [in, out]: optional pointer to a vector holding the output
* objects, with the furthest linking object ordered last.
*/
void getInListEx(std::set<App::DocumentObject*> &inSet,
void getInListEx(std::set<App::DocumentObject*> &inSet,
bool recursive, std::vector<App::DocumentObject*> *inList=0) const;
/** Return a set of all objects linking to this object, including possible external parent objects
* @param recursive [in]: whether to obtain recursive in list
@@ -333,10 +335,10 @@ public:
* include the transformation applied by the final object reference in \c
* subname. For Part::Feature, the transformation is applied to the
* TopoShape inside \c pyObj before returning.
*
*
* @param transform: if false, then it will not apply the object's own
* transformation to \c mat, which lets you override the object's placement
* (and possibly scale).
* (and possibly scale).
*
* @param depth: depth limitation as hint for cyclic link detection
*
@@ -344,7 +346,7 @@ public:
* then it shall return itself. If subname is invalid, then it shall return
* zero.
*/
virtual DocumentObject *getSubObject(const char *subname, PyObject **pyObj=0,
virtual DocumentObject *getSubObject(const char *subname, PyObject **pyObj=0,
Base::Matrix4D *mat=0, bool transform=true, int depth=0) const;
/// Return a list of objects referenced by a given subname including this object
@@ -379,13 +381,13 @@ public:
std::vector<std::pair<App::DocumentObject*,std::string> > getParents(int depth=0) const;
/** Return the linked object with optional transformation
*
*
* @param recurse: If false, return the immediate linked object, or else
* recursively call this function to return the final linked object.
*
* @param mat: If non zero, it is used as the current transformation matrix
* on input. And output as the accumulated transformation till the final
* linked object.
* linked object.
*
* @param transform: if false, then it will not accumulate the object's own
* placement into \c mat, which lets you override the object's placement.
@@ -393,7 +395,7 @@ public:
* @return Return the linked object. This function must return itself if the
* it is not a link or the link is invalid.
*/
virtual DocumentObject *getLinkedObject(bool recurse=true,
virtual DocumentObject *getLinkedObject(bool recurse=true,
Base::Matrix4D *mat=0, bool transform=false, int depth=0) const;
/* Return true to cause PropertyView to show linked object's property */
@@ -406,7 +408,7 @@ public:
*
* @param newLabel: input as the new label, which can be modified by object itself
*
* This function is is called before onBeforeChange()
* This function is called before onBeforeChange()
*/
virtual void onBeforeChangeLabel(std::string &newLabel) {(void)newLabel;}
@@ -420,7 +422,7 @@ public:
/* Expression support */
virtual void setExpression(const ObjectIdentifier & path, boost::shared_ptr<App::Expression> expr);
virtual void setExpression(const ObjectIdentifier & path, std::shared_ptr<App::Expression> expr);
virtual const PropertyExpressionEngine::ExpressionInfo getExpression(const ObjectIdentifier &path) const;
@@ -440,10 +442,10 @@ public:
short attr=0, bool ro=false, bool hidden=false) override;
/** Resolve the last document object referenced in the subname
*
*
* @param subname: dot separated subname
* @param parent: return the direct parent of the object
* @param childName: return child name to be passed to is/setElementVisible()
* @param childName: return child name to be passed to is/setElementVisible()
* @param subElement: return non-object sub-element name if found. The
* pointer is guaranteed to be within the buffer pointed to by 'subname'
*
@@ -451,7 +453,7 @@ public:
* @return Returns the last referenced document object in the subname. If no
* such object in subname, return pObject.
*/
App::DocumentObject *resolve(const char *subname, App::DocumentObject **parent=0,
App::DocumentObject *resolve(const char *subname, App::DocumentObject **parent=0,
std::string *childName=0, const char **subElement=0,
PyObject **pyObj=0, Base::Matrix4D *mat=0, bool transform=true, int depth=0) const;
@@ -499,7 +501,7 @@ public:
*
* The common parent 'Group' is removed.
*/
App::DocumentObject *resolveRelativeLink(std::string &subname,
App::DocumentObject *resolveRelativeLink(std::string &subname,
App::DocumentObject *&link, std::string &linkSub) const;
/** Called to adjust link properties to avoid cyclic links
@@ -532,7 +534,7 @@ public:
/** Allow object to redirect a subname path
*
* @param ss: input as the current subname path from \a topParent leading
* just before this object, i.e. ends at the parent of this object. This
* just before this object, i.e. ends at the parent of this object. This
* function should append its own name to this path, or redirect the
* subname to other place.
* @param topParent: top parent of this subname path
@@ -540,7 +542,7 @@ public:
*
* This function is called by tree view to generate a subname path when an
* item is selected in the tree. Document object can use this function to
* redirect the selection to some other objects.
* redirect the selection to some other objects.
*/
virtual bool redirectSubName(std::ostringstream &ss,
DocumentObject *topParent, DocumentObject *child) const;
@@ -566,6 +568,11 @@ protected:
*/
virtual App::DocumentObjectExecReturn *execute(void);
/**
* Executes the extensions of a document object.
*/
App::DocumentObjectExecReturn *executeExtensions();
/** Status bits of the document object
* The first 8 bits are used for the base system the rest can be used in
* descendent classes to mark special statuses on the objects.
@@ -592,6 +599,8 @@ protected:
virtual void onChanged(const Property* prop) override;
/// get called after a document has been fully restored
virtual void onDocumentRestored();
/// get called after an undo/redo transaction is finished
virtual void onUndoRedoFinished();
/// get called after setting the document
virtual void onSettingDocument();
/// get called after a brand new object was created
@@ -620,7 +629,7 @@ private:
// unique identifier (among a document) of this object.
long _Id;
private:
// Back pointer to all the fathers in a DAG of the document
// this is used by the document (via friend) to have a effective DAG handling
+8 -8
View File
@@ -35,7 +35,7 @@ using namespace App;
EXTENSION_PROPERTY_SOURCE(App::DocumentObjectExtension, App::Extension)
DocumentObjectExtension::DocumentObjectExtension()
DocumentObjectExtension::DocumentObjectExtension()
{
initExtensionType(App::DocumentObjectExtension::getExtensionClassTypeId());
}
@@ -46,7 +46,7 @@ DocumentObjectExtension::~DocumentObjectExtension()
}
short int DocumentObjectExtension::extensionMustExecute(void) {
return 0;
}
@@ -64,15 +64,15 @@ void DocumentObjectExtension::onExtendedDocumentRestored() {
}
void DocumentObjectExtension::onExtendedSetupObject() {
}
void DocumentObjectExtension::onExtendedUnsetupObject() {
}
PyObject* DocumentObjectExtension::getExtensionPyObject(void) {
if (ExtensionPythonObject.is(Py::_None())){
// ref counter is set to 1
ExtensionPythonObject = Py::Object(new DocumentObjectExtensionPy(this),true);
@@ -82,17 +82,17 @@ PyObject* DocumentObjectExtension::getExtensionPyObject(void) {
const DocumentObject* DocumentObjectExtension::getExtendedObject() const {
assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId()));
assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId()));
return static_cast<const DocumentObject*>(getExtendedContainer());
}
DocumentObject* DocumentObjectExtension::getExtendedObject() {
assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId()));
assert(getExtendedContainer()->isDerivedFrom(DocumentObject::getClassTypeId()));
return static_cast<DocumentObject*>(getExtendedContainer());
}
bool DocumentObjectExtension::extensionGetSubObject(DocumentObject *&,
bool DocumentObjectExtension::extensionGetSubObject(DocumentObject *&,
const char *, PyObject **, Base::Matrix4D *, bool, int) const
{
return false;
+8 -8
View File
@@ -28,10 +28,10 @@
#include "DocumentObject.h"
namespace App {
/**
* @brief Extension with special document object calls
*
*
*/
class AppExport DocumentObjectExtension : public App::Extension
{
@@ -47,12 +47,12 @@ public:
App::DocumentObject* getExtendedObject();
const App::DocumentObject* getExtendedObject() const;
//override if execution is necessary
virtual short extensionMustExecute(void);
virtual App::DocumentObjectExecReturn *extensionExecute(void);
/// get called after setting the document
virtual void onExtendedSettingDocument();
/// get called after a document has been fully restored
@@ -63,8 +63,8 @@ public:
virtual void onExtendedUnsetupObject();
virtual PyObject* getExtensionPyObject(void) override;
/// returns the type name of the ViewProviderExtension which is automatically attached
/// returns the type name of the ViewProviderExtension which is automatically attached
/// to the viewprovider object when it is initiated
virtual const char* getViewProviderExtensionName(void) const {return "";}
@@ -73,7 +73,7 @@ public:
*
* @return Return turn if handled, the sub object is returned in \c ret
*/
virtual bool extensionGetSubObject( DocumentObject *&ret, const char *subname,
virtual bool extensionGetSubObject( DocumentObject *&ret, const char *subname,
PyObject **pyObj, Base::Matrix4D *mat, bool transform, int depth) const;
/** Get name references of all sub objects
+1 -1
View File
@@ -34,7 +34,7 @@ using namespace App;
PROPERTY_SOURCE(App::DocumentObjectFileIncluded, App::DocumentObject)
DocumentObjectFileIncluded::DocumentObjectFileIncluded()
DocumentObjectFileIncluded::DocumentObjectFileIncluded()
{
ADD_PROPERTY_TYPE(File,(0),"",(App::PropertyType)(Prop_None),"File to include into Project File");
}
+2 -2
View File
@@ -41,12 +41,12 @@ public:
DocumentObjectFileIncluded(void);
virtual ~DocumentObjectFileIncluded();
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
return "Gui::ViewProviderDocumentObject";
}
/// Properties
PropertyFileIncluded File;
+1 -1
View File
@@ -58,7 +58,7 @@ PyObject *DocumentObjectGroup::getPyObject()
// Python feature ---------------------------------------------------------
namespace App {
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(App::DocumentObjectGroupPython, App::DocumentObjectGroup)
template<> const char* App::DocumentObjectGroupPython::getViewProviderName(void) const {
+5 -5
View File
@@ -33,21 +33,21 @@
namespace App
{
class AppExport DocumentObjectGroup : public DocumentObject, public GroupExtension {
PROPERTY_HEADER_WITH_EXTENSIONS(App::DocumentObjectGroup);
public:
/// Constructor
DocumentObjectGroup(void);
virtual ~DocumentObjectGroup();
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const override{
return "Gui::ViewProviderDocumentObjectGroup";
}
virtual PyObject *getPyObject(void) override;
};
+15 -1
View File
@@ -65,6 +65,20 @@
<UserDocu>recompute(recursive=False): Recomputes this object</UserDocu>
</Documentation>
</Methode>
<Methode Name="getStatusString" const="True">
<Documentation>
<UserDocu>Returns the status of the object as string.
If the object is invalid its error description will be returned.
If the object is valid but touched then &apos;Touched&apos; will be returned,
&apos;Valid&apos; otherwise.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="isValid" const="True">
<Documentation>
<UserDocu>Returns True if the object is valid, False otherwise</UserDocu>
</Documentation>
</Methode>
<Methode Name="getSubObject" Keyword="true">
<Documentation>
<UserDocu>
@@ -86,7 +100,7 @@ referencing subobject.
DocAndPyObject: return a tuple (object, matrix, pyobj) for each subname
Placement: return a trasformed placement of the sub-object
Placement: return a transformed placement of the sub-object
* matrix: the initial transformation to be applied to the sub object.
+32 -44
View File
@@ -329,39 +329,17 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args)
App::ObjectIdentifier p(ObjectIdentifier::parse(getDocumentObjectPtr(), path));
if (Py::Object(expr).isNone())
getDocumentObjectPtr()->setExpression(p, boost::shared_ptr<Expression>());
#if PY_MAJOR_VERSION >= 3
getDocumentObjectPtr()->setExpression(p, std::shared_ptr<Expression>());
else if (PyUnicode_Check(expr)) {
const char * exprStr = PyUnicode_AsUTF8(expr);
#else
else if (PyString_Check(expr)) {
const char * exprStr = PyString_AsString(expr);
#endif
boost::shared_ptr<Expression> shared_expr(Expression::parse(getDocumentObjectPtr(), exprStr));
std::shared_ptr<Expression> shared_expr(Expression::parse(getDocumentObjectPtr(), exprStr));
if(shared_expr && comment)
shared_expr->comment = comment;
getDocumentObjectPtr()->setExpression(p, shared_expr);
}
else if (PyUnicode_Check(expr)) {
#if PY_MAJOR_VERSION >= 3
std::string exprStr = PyUnicode_AsUTF8(expr);
#else
PyObject* unicode = PyUnicode_AsEncodedString(expr, "utf-8", 0);
if (unicode) {
std::string exprStr = PyString_AsString(unicode);
Py_DECREF(unicode);
boost::shared_ptr<Expression> shared_expr(ExpressionParser::parse(getDocumentObjectPtr(), exprStr.c_str()));
if(shared_expr && comment)
shared_expr->comment = comment;
getDocumentObjectPtr()->setExpression(p, shared_expr);
}
else {
// utf-8 encoding failed
return 0;
}
#endif
}
else
throw Py::TypeError("String or None expected.");
@@ -375,7 +353,7 @@ PyObject* DocumentObjectPy::evalExpression(PyObject * args)
return NULL; // NULL triggers exception
PY_TRY {
boost::shared_ptr<Expression> shared_expr(Expression::parse(getDocumentObjectPtr(), expr));
std::shared_ptr<Expression> shared_expr(Expression::parse(getDocumentObjectPtr(), expr));
if(shared_expr)
return Py::new_reference_to(shared_expr->getPyValue());
Py_Return;
@@ -397,6 +375,34 @@ PyObject* DocumentObjectPy::recompute(PyObject *args)
}
}
PyObject* DocumentObjectPy::isValid(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
try {
bool ok = getDocumentObjectPtr()->isValid();
return Py_BuildValue("O", (ok ? Py_True : Py_False));
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
}
PyObject* DocumentObjectPy::getStatusString(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
try {
Py::String text(getDocumentObjectPtr()->getStatusString());
return Py::new_reference_to(text);
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
}
PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds)
{
PyObject *obj;
@@ -417,32 +423,14 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds)
std::vector<std::string> subs;
bool single=true;
if (PyUnicode_Check(obj)) {
#if PY_MAJOR_VERSION >= 3
subs.push_back(PyUnicode_AsUTF8(obj));
#else
PyObject* unicode = PyUnicode_AsUTF8String(obj);
subs.push_back(PyString_AsString(unicode));
Py_DECREF(unicode);
}
else if (PyString_Check(obj)) {
subs.push_back(PyString_AsString(obj));
#endif
} else if (PySequence_Check(obj)) {
single=false;
Py::Sequence shapeSeq(obj);
for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyUnicode_Check(item)) {
#if PY_MAJOR_VERSION >= 3
subs.push_back(PyUnicode_AsUTF8(item));
#else
PyObject* unicode = PyUnicode_AsUTF8String(item);
subs.push_back(PyString_AsString(unicode));
Py_DECREF(unicode);
}
else if (PyString_Check(item)) {
subs.push_back(PyString_AsString(item));
#endif
}else{
PyErr_SetString(PyExc_TypeError, "non-string object in sequence");
return 0;
@@ -460,7 +448,7 @@ PyObject* DocumentObjectPy::getSubObject(PyObject *args, PyObject *keywds)
Py::Object obj;
Py::Object pyObj;
Base::Matrix4D mat;
SubInfo(const Base::Matrix4D &mat):mat(mat){}
SubInfo(const Base::Matrix4D &mat) : sobj(nullptr), mat(mat){}
};
Base::Matrix4D mat;
+129 -33
View File
@@ -24,11 +24,10 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <functional>
# include <sstream>
#endif
#include <boost/bind.hpp>
#include <Base/Tools.h>
#include "Application.h"
#include "Document.h"
@@ -38,6 +37,7 @@
#include "GeoFeature.h"
using namespace App;
namespace sp = std::placeholders;
DocumentT::DocumentT()
@@ -54,6 +54,11 @@ DocumentT::DocumentT(const std::string& name)
document = name;
}
DocumentT::DocumentT(const DocumentT& doc)
{
document = doc.document;
}
DocumentT::~DocumentT()
{
}
@@ -243,10 +248,8 @@ const std::string &DocumentObjectT::getPropertyName() const {
std::string DocumentObjectT::getPropertyPython() const
{
std::stringstream str;
str << "FreeCAD.getDocument('" << document
<< "').getObject('" << object
<< "')";
if(property.size())
str << getObjectPython();
if (property.size())
str << '.' << property;
return str.str();
}
@@ -358,7 +361,7 @@ std::string SubObjectT::getOldElementName(int *index) const {
if(!obj)
return std::string();
GeoFeature::resolveElement(obj,subname.c_str(),element);
if(!index)
if(!index)
return std::move(element.second);
std::size_t pos = element.second.find_first_of("0123456789");
if(pos == std::string::npos)
@@ -395,12 +398,105 @@ std::vector<App::DocumentObject*> SubObjectT::getSubObjectList() const {
// -----------------------------------------------------------------------------
PropertyLinkT::PropertyLinkT()
: toPython("None")
{
}
PropertyLinkT::PropertyLinkT(DocumentObject *obj)
: PropertyLinkT()
{
if (obj) {
std::ostringstream str;
DocumentObjectT objT(obj);
str << objT.getObjectPython();
toPython = str.str();
}
}
PropertyLinkT::PropertyLinkT(DocumentObject *obj, const std::vector<std::string>& subNames)
: PropertyLinkT()
{
if (obj) {
std::ostringstream str;
DocumentObjectT objT(obj);
str << "(" << objT.getObjectPython() << ",[";
for(const auto& it : subNames)
str << "'" << it << "',";
str << "])";
toPython = str.str();
}
}
PropertyLinkT::PropertyLinkT(const std::vector<DocumentObject*>& objs)
: PropertyLinkT()
{
if (!objs.empty()) {
std::stringstream str;
str << "[";
for (std::size_t i = 0; i < objs.size(); i++) {
if (i > 0)
str << ", ";
App::DocumentObject* obj = objs[i];
if (obj) {
DocumentObjectT objT(obj);
str << objT.getObjectPython();
}
else {
str << "None";
}
}
str << "]";
}
}
PropertyLinkT::PropertyLinkT(const std::vector<DocumentObject*>& objs, const std::vector<std::string>& subNames)
: PropertyLinkT()
{
if (!objs.empty() && objs.size() == subNames.size()) {
std::stringstream str;
str << "[";
for (std::size_t i = 0; i < subNames.size(); i++) {
if (i>0)
str << ",(";
else
str << "(";
App::DocumentObject* obj = objs[i];
if (obj) {
DocumentObjectT objT(obj);
str << objT.getObjectPython();
}
else {
str << "None";
}
str << ",";
str << "'" << subNames[i] << "'";
str << ")";
}
str << "]";
}
}
std::string PropertyLinkT::getPropertyPython() const
{
return toPython;
}
// -----------------------------------------------------------------------------
class DocumentWeakPtrT::Private {
public:
Private(App::Document* doc) : _document(doc) {
if (doc) {
connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
(&Private::deletedDocument, this, _1));
connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind
(&Private::deletedDocument, this, sp::_1));
}
}
@@ -477,13 +573,13 @@ public:
object = obj;
if (obj) {
indocument = true;
connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
(&Private::deletedDocument, this, _1));
connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind
(&Private::deletedDocument, this, sp::_1));
App::Document* doc = obj->getDocument();
connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind
(&Private::createdObject, this, _1));
connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind
(&Private::deletedObject, this, _1));
connectDocumentCreatedObject = doc->signalNewObject.connect(std::bind
(&Private::createdObject, this, sp::_1));
connectDocumentDeletedObject = doc->signalDeletedObject.connect(std::bind
(&Private::deletedObject, this, sp::_1));
}
}
App::DocumentObject* get() const noexcept {
@@ -549,19 +645,19 @@ bool DocumentObjectWeakPtrT::operator!= (const DocumentObjectWeakPtrT& p) const
DocumentObserver::DocumentObserver() : _document(nullptr)
{
this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind
(&DocumentObserver::slotCreatedDocument, this, _1));
this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
(&DocumentObserver::slotDeletedDocument, this, _1));
this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(std::bind
(&DocumentObserver::slotCreatedDocument, this, sp::_1));
this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind
(&DocumentObserver::slotDeletedDocument, this, sp::_1));
}
DocumentObserver::DocumentObserver(Document* doc) : _document(nullptr)
{
// Connect to application and given document
this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind
(&DocumentObserver::slotCreatedDocument, this, _1));
this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind
(&DocumentObserver::slotDeletedDocument, this, _1));
this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(std::bind
(&DocumentObserver::slotCreatedDocument, this, sp::_1));
this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(std::bind
(&DocumentObserver::slotDeletedDocument, this, sp::_1));
attachDocument(doc);
}
@@ -584,16 +680,16 @@ void DocumentObserver::attachDocument(Document* doc)
detachDocument();
_document = doc;
this->connectDocumentCreatedObject = _document->signalNewObject.connect(boost::bind
(&DocumentObserver::slotCreatedObject, this, _1));
this->connectDocumentDeletedObject = _document->signalDeletedObject.connect(boost::bind
(&DocumentObserver::slotDeletedObject, this, _1));
this->connectDocumentChangedObject = _document->signalChangedObject.connect(boost::bind
(&DocumentObserver::slotChangedObject, this, _1, _2));
this->connectDocumentRecomputedObject = _document->signalRecomputedObject.connect(boost::bind
(&DocumentObserver::slotRecomputedObject, this, _1));
this->connectDocumentRecomputed = _document->signalRecomputed.connect(boost::bind
(&DocumentObserver::slotRecomputedDocument, this, _1));
this->connectDocumentCreatedObject = _document->signalNewObject.connect(std::bind
(&DocumentObserver::slotCreatedObject, this, sp::_1));
this->connectDocumentDeletedObject = _document->signalDeletedObject.connect(std::bind
(&DocumentObserver::slotDeletedObject, this, sp::_1));
this->connectDocumentChangedObject = _document->signalChangedObject.connect(std::bind
(&DocumentObserver::slotChangedObject, this, sp::_1, sp::_2));
this->connectDocumentRecomputedObject = _document->signalRecomputedObject.connect(std::bind
(&DocumentObserver::slotRecomputedObject, this, sp::_1));
this->connectDocumentRecomputed = _document->signalRecomputed.connect(std::bind
(&DocumentObserver::slotRecomputedDocument, this, sp::_1));
}
}
+31 -1
View File
@@ -25,7 +25,7 @@
#define APP_DOCUMENTOBSERVER_H
#include <Base/BaseClass.h>
#include <boost/signals2.hpp>
#include <boost_signals2.hpp>
#include <set>
#include <memory>
@@ -51,6 +51,8 @@ public:
DocumentT(Document*);
/*! Constructor */
DocumentT(const std::string&);
/*! Constructor */
DocumentT(const DocumentT&);
/*! Destructor */
~DocumentT();
/*! Assignment operator */
@@ -209,6 +211,34 @@ private:
std::string subname;
};
/**
* The PropertyLinkT class is a helper class to create Python statements for proprty links.
*/
class AppExport PropertyLinkT
{
public:
/*! Constructor */
PropertyLinkT();
/*! Constructor */
PropertyLinkT(DocumentObject *obj);
/*! Constructor */
PropertyLinkT(DocumentObject *obj, const std::vector<std::string>& subNames);
/*! Constructor */
PropertyLinkT(const std::vector<DocumentObject*>& objs);
/*! Constructor */
PropertyLinkT(const std::vector<DocumentObject*>& objs, const std::vector<std::string>& subNames);
/*! Get the property as Python command. */
std::string getPropertyPython() const;
private:
std::string toPython;
};
/**
* @brief The DocumentWeakPtrT class
*/
+4 -2
View File
@@ -24,6 +24,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <boost_bind_bind.hpp>
#endif
#include "Application.h"
@@ -34,6 +35,7 @@
#include <Base/Console.h>
using namespace App;
namespace bp = boost::placeholders;
std::vector<DocumentObserverPython*> DocumentObserverPython::_instances;
@@ -72,7 +74,7 @@ DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj
FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\
if (!py##_name1.py.isNone())\
py##_name1.slot = App::GetApplication().signal##_name2.connect(\
boost::bind(&DocumentObserverPython::slot##_name1, this, _1));\
boost::bind(&DocumentObserverPython::slot##_name1, this, bp::_1));\
}\
while(0);
@@ -80,7 +82,7 @@ DocumentObserverPython::DocumentObserverPython(const Py::Object& obj) : inst(obj
FC_PY_GetCallable(obj.ptr(), "slot" #_name1, py##_name1.py);\
if (!py##_name1.py.isNone())\
py##_name1.slot = App::GetApplication().signal##_name2.connect(\
boost::bind(&DocumentObserverPython::slot##_name1, this, _1, _2));\
boost::bind(&DocumentObserverPython::slot##_name1, this, bp::_1, bp::_2));\
}\
while(0);
+4 -4
View File
@@ -26,8 +26,8 @@
#include <CXX/Objects.hxx>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>
#include <boost_signals2.hpp>
#include <boost/bind/bind.hpp>
#include <string>
@@ -111,13 +111,13 @@ private:
void slotBeforeAddingDynamicExtension(const App::ExtensionContainer&, std::string extension);
/** Called when an object gets a dynamic extension added*/
void slotAddedDynamicExtension(const App::ExtensionContainer&, std::string extension);
private:
Py::Object inst;
static std::vector<DocumentObserverPython*> _instances;
typedef struct {
typedef struct PythonObject {
boost::signals2::scoped_connection slot;
Py::Object py;
PyObject* ptr() {
+13 -5
View File
@@ -94,11 +94,13 @@ viewType (String): override the view provider type directly, only effective when
<Methode Name="copyObject">
<Documentation>
<UserDocu>
copyObject(object, with_dependencies=False)
copyObject(object, with_dependencies=False, return_all=False)
Copy an object or objects from another document to this document.
object: can either a single object or sequence of objects
with_dependencies: if True, all internal dependent objects are copied too.
return_all: if True, return all copied objects, or else return only the copied
object corresponding to the input objects.
</UserDocu>
</Documentation>
</Methode>
@@ -158,11 +160,11 @@ object of this document.
NOTE: It's possible that several objects have the same label name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="findObjects">
<Methode Name="findObjects" Keyword="true">
<Documentation>
<UserDocu>findObjects([string (type)], [string (name)]) -&gt; list
Return a list of objects that match the specified type and name.
Both parameters are optional.</UserDocu>
<UserDocu>findObjects([Type=string], [Name=string], [Label=string]) -&gt; list
Return a list of objects that match the specified type, name or label.
Name and label support regular expressions. All parameters are optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getLinksTo">
@@ -328,6 +330,12 @@ sort: whether to topologically sort the return list
</Documentation>
<Parameter Name="OldLabel" Type="String"/>
</Attribute>
<Attribute Name="Temporary" ReadOnly="true" >
<Documentation>
<UserDocu>Check if this is a temporary document</UserDocu>
</Documentation>
<Parameter Name="Temporary" Type="Boolean"/>
</Attribute>
<CustomAttributes />
</PythonExport>
</GenerateModel>

Some files were not shown because too many files have changed in this diff Show More