Merge remote-tracking branch 'origin/master' into e57

# Conflicts:
#	.github/workflows/CreateRelease.yml
#	.github/workflows/MacOS.yml
#	scripts/Linux/2_deploy.sh
#	scripts/macOS/2_deploy.sh
#	src/external/external.cmake
#	src/external/u3d.cmake
This commit is contained in:
alemuntoni 2021-06-08 17:36:34 +02:00
commit e82fd1d6f8
1497 changed files with 153566 additions and 38834 deletions

7
.github/stale.yml vendored
View File

@ -34,9 +34,10 @@ staleLabel: wontfix
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. The resources of the VCLab team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the last release of MeshLab, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >

View File

@ -8,10 +8,6 @@ on:
description: 'New MeshLab Version'
required: true
default: 'YYYY.MM'
release_candidate:
description: 'Is release candidate'
required: true
default: 'false'
jobs:
@ -40,7 +36,7 @@ jobs:
linux_build:
needs: [update_ml_version]
name: Build MeshLab (Linux)
runs-on: ubuntu-16.04 #in order to deploy, need to use oldest supported version
runs-on: ubuntu-18.04 #in order to deploy, need to use oldest supported version
strategy:
matrix:
precision: [single_precision, double_precision]
@ -54,7 +50,7 @@ jobs:
uses: jurplel/install-qt-action@v2
- name: Install dependencies
run: |
sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libgmp-dev
sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libgmp-dev libcgal-dev libboost-all-dev
#needed by qt 5.15 on linux
sudo apt-get install libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-render-util0-dev libxcb-xinerama0-dev
- name: Setup env variables
@ -66,15 +62,10 @@ jobs:
else
echo ::set-output name=artifact_suffix::""
fi
if [ "${{ github.event.inputs.release_candidate }}" == "true" ]; then
echo ::set-output name=rc_option::"-rc"
else
echo ::set-output name=rc_option::""
fi
- name: Configure and Build
shell: bash
run: |
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }} ${{steps.envs.outputs.rc_option}}
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }}
- name: Deploy
shell: bash
run: |
@ -109,7 +100,7 @@ jobs:
submodules: true
- name: Install dependencies
run: |
brew install libomp xerces-c
brew install libomp cgal xerces-c
npm install -g appdmg
- name: Install Qt
uses: jurplel/install-qt-action@v2
@ -122,19 +113,32 @@ jobs:
else
echo ::set-output name=artifact_suffix::""
fi
if [ "${{ github.event.inputs.release_candidate }}" == "true" ]; then
echo ::set-output name=rc_option::"-rc"
else
echo ::set-output name=rc_option::""
fi
- name: Configure and Build
shell: bash
run: |
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }} ${{steps.envs.outputs.rc_option}}
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }}
- name: Deploy
shell: bash
run: |
bash scripts/${{ runner.os }}/2_deploy.sh
- name: Import Cert and Key
uses: apple-actions/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }}
p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
- name: Sign
run: |
codesign --options "runtime" --timestamp --force --deep --sign ${{ secrets.MACOS_CERT_ID }} src/install/meshlab.app
- name: Notarize
uses: devbotsxyz/xcode-notarize@v1
with:
product-path: "src/install/meshlab.app"
appstore-connect-username: ${{ secrets.MACOS_NOTARIZATION_USER }}
appstore-connect-password: ${{ secrets.MACOS_NOTARIZATION_PSSW }}
- name: "Staple Release"
uses: devbotsxyz/xcode-staple@v1
with:
product-path: "src/install/meshlab.app"
- name: Create MeshLab DMG
shell: bash
run: |
@ -176,16 +180,26 @@ jobs:
else
echo ::set-output name=artifact_suffix::""
fi
if [ "${{ github.event.inputs.release_candidate }}" == "true" ]; then
echo ::set-output name=rc_option::"-rc"
else
echo ::set-output name=rc_option::""
fi
echo "VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC" >> $GITHUB_ENV
- name: Expand PATH for wget
run: |
echo "C:\msys64\usr\bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Set Certificate
run: |
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_CERTIFICATE }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
- name: Download external libraries
shell: bash
run: |
bash scripts/${{ runner.os }}/0_download_ext.sh
- name: Configure and Build
shell: bash
run: |
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }} ${{steps.envs.outputs.rc_option}}
bash scripts/${{ runner.os }}/1_build.sh --${{ matrix.precision }}
- name: Sign Portable content
run: |
.\scripts\Windows\resources\windows_sign_dlls.ps1 -pssw '${{ secrets.WIN_CERTIFICATE_PWD }}' -path 'src\install\'
- name: Deploy
shell: bash
run: |
@ -201,7 +215,11 @@ jobs:
- name: Move Installer
shell: bash
run: |
mv src/install/MeshLab*-windows.exe src/
mkdir src/installer
mv src/install/MeshLab*-windows.exe src/installer
- name: Sign Installer
run: |
.\scripts\Windows\resources\windows_sign_dlls.ps1 -pssw '${{ secrets.WIN_CERTIFICATE_PWD }}' -path 'src\installer\'
- name: Uploading MeshLab Portable
uses: actions/upload-artifact@v2
with:
@ -211,7 +229,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: meshlab_windows_installer${{steps.envs.outputs.artifact_suffix}}
path: src/MeshLab*-windows.exe
path: src/installer/MeshLab*-windows.exe
#after building MeshLab for the three platforms, we create a release in github
create_release:
@ -259,10 +277,11 @@ jobs:
chmod +x meshlab_linux_portable_double/AppRun
- name: Create MeshLab Portable Linux Archive
run: |
mv meshlab_linux_portable MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}
tar -cvzf MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-linux.tar.gz MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}/
mv meshlab_linux_portable_double MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}
tar -cvzf MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-linux.tar.gz MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}/
cd meshlab_linux_portable
tar -cvzf ../MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-linux.tar.gz *
cd ../meshlab_linux_portable_double
tar -cvzf ../MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-linux.tar.gz *
cd ..
#Download MacOS Package
- name: Download MacOS DMG
@ -285,13 +304,17 @@ jobs:
with:
name: meshlab_macos_portable_double
path: meshlab_macos_portable_double
- name: Change Permissions
run: |
chmod +x meshlab_macos_portable/MeshLab*.app/Contents/MacOS/meshlab
chmod +x meshlab_macos_portable_double/MeshLab*.app/Contents/MacOS/meshlab
- name: Create MeshLab Portable MacOS
run: |
mv meshlab_macos_portable MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}.app
zip -r MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.zip MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}.app/
rm -r MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}.app
mv meshlab_macos_portable_double MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}.app
zip -r MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.zip MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}.app/
cd meshlab_macos_portable
tar -cvzf ../MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.tar.gz *
cd ../meshlab_macos_portable_double
tar -cvzf ../MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.tar.gz *
cd ..
#Download Windows Packages
- name: Download Windows ZIP
@ -316,10 +339,11 @@ jobs:
path: meshlab_windows_installer_double
- name: Create MeshLab Portable Windows Archive
run: |
mv meshlab_windows_portable MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}
zip -r MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-windows.zip MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}/
mv meshlab_windows_portable_double MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}
zip -r MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-windows.zip MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}/
cd meshlab_windows_portable
zip -r ../MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-windows.zip *
cd ../meshlab_windows_portable_double
zip -r ../MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-windows.zip *
cd ..
#Create release and upload
@ -402,8 +426,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.zip
asset_name: MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.zip
asset_path: MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.tar.gz
asset_name: MeshLab${{ github.event.inputs.version }}${{steps.envs.outputs.rc_suffix}}-macos.tar.gz
asset_content_type: MeshLab Portable for MacOS
- name: Upload ReleaseMacOSPortable-d
id: upload-release-macos-portable-d
@ -412,8 +436,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.zip
asset_name: MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.zip
asset_path: MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.tar.gz
asset_name: MeshLab${{ github.event.inputs.version }}d${{steps.envs.outputs.rc_suffix}}-macos.tar.gz
asset_content_type: MeshLab Portable for MacOS
#Windows
- name: Upload ReleaseWindowsPortable

View File

@ -6,7 +6,7 @@ on:
jobs:
linux_build:
name: Build MeshLab (Linux)
runs-on: ubuntu-16.04 #in order to deploy, need to use oldest supported version
runs-on: ubuntu-18.04 #in order to deploy, need to use oldest supported version
strategy:
matrix:
precision: [single_precision, double_precision]
@ -19,7 +19,7 @@ jobs:
uses: jurplel/install-qt-action@v2
- name: Install dependencies
run: |
sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libgmp-dev
sudo apt-get install -y mesa-common-dev libglu1-mesa-dev libgmp-dev libcgal-dev libboost-all-dev
#needed by qt 5.15 on linux
sudo apt-get install libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-render-util0-dev libxcb-xinerama0-dev
- name: Setup env variables

View File

@ -17,7 +17,7 @@ jobs:
submodules: true
- name: Install dependencies
run: |
brew install libomp xerces-c
brew install libomp cgal xerces-c
npm install -g appdmg
- name: Install Qt
uses: jurplel/install-qt-action@v2

View File

@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
ubuntu_build:
name: Build MeshLab (Ubuntu - QMake)
runs-on: ubuntu-16.04 #in order to deploy, need to use oldest supported version
runs-on: ubuntu-18.04 #in order to deploy, need to use oldest supported version
steps:
- uses: actions/checkout@v2

View File

@ -28,6 +28,13 @@ jobs:
echo ::set-output name=artifact_suffix::""
fi
echo "VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC" >> $GITHUB_ENV
- name: Expand PATH for wget
run: |
echo "C:\msys64\usr\bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Download external libraries
shell: bash
run: |
bash scripts/${{ runner.os }}/0_download_ext.sh
- name: Configure and Build
shell: bash
run: |
@ -47,7 +54,8 @@ jobs:
- name: Move Installer
shell: bash
run: |
mv src/install/MeshLab*-windows.exe src/
mkdir src/installer
mv src/install/MeshLab*-windows.exe src/installer/
- name: Uploading MeshLab Portable
uses: actions/upload-artifact@v2
with:
@ -57,4 +65,4 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: meshlab_windows_installer${{steps.envs.outputs.artifact_suffix}}
path: src/MeshLab*-windows.exe
path: src/installer/MeshLab*-windows.exe

2
.gitignore vendored
View File

@ -20,6 +20,8 @@
distrib*
src/build/*
src/install/*
src/external/boost_1_75_0
src/external/CGAL-5.2.1
install/macos/resources/meshlab_dmg_final.json
install/windows/resources/meshlab_final.nsi
install/windows/resources/MeshLab*.exe

View File

@ -1 +1 @@
2020.12
2021.05

View File

@ -19,7 +19,6 @@ INSTALL_PATH=$SOURCE_PATH/install/usr/
CORES="-j4"
DOUBLE_PRECISION_OPTION=""
NIGHTLY_OPTION=""
RC_OPTION=""
#check parameters
for i in "$@"
@ -45,10 +44,6 @@ case $i in
NIGHTLY_OPTION="-DMESHLAB_IS_NIGHTLY_VERSION=ON"
shift # past argument=value
;;
-rc|--release_candidate)
RC_OPTION="-DMESHLAB_IS_RELEASE_CANDIDATE_VERSION=ON"
shift # past argument=value
;;
*)
# unknown option
;;
@ -71,6 +66,6 @@ BUILD_PATH=$(realpath $BUILD_PATH)
INSTALL_PATH=$(realpath $INSTALL_PATH)
cd $BUILD_PATH
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $RC_OPTION $SOURCE_PATH
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $SOURCE_PATH
make $CORES
make install

View File

@ -35,6 +35,7 @@ $SCRIPTS_PATH/resources/linuxdeployqt $INSTALL_PATH/usr/share/applications/meshl
-executable=$INSTALL_PATH/usr/lib/meshlab/plugins/libfilter_sketchfab.so \
-executable=$INSTALL_PATH/usr/lib/meshlab/plugins/libio_3ds.so \
-executable=$INSTALL_PATH/usr/lib/meshlab/plugins/libio_ctm.so \
-executable=$INSTALL_PATH/usr/lib/meshlab/plugins/libfilter_mesh_booleans.so \
-executable=$INSTALL_PATH/usr/lib/meshlab/plugins/libio_e57.so

View File

@ -25,16 +25,14 @@ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INSTALL_PATH
#check if we have an exec in distrib
if ! [ -f $INSTALL_PATH/usr/bin/meshlab ]
then
echo "ERROR: meshlab bin not found inside $INSTALL_PATH/usr/bin/"
exit 1
echo "ERROR: meshlab bin not found inside $INSTALL_PATH/usr/bin/"
exit 1
fi
mkdir -p $INSTALL_PATH/usr/share/doc/meshlab
mkdir -p $INSTALL_PATH/usr/share/icons/hicolor/512x512/apps/
mkdir -p $INSTALL_PATH/usr/share/icons/Yaru/512x512/apps/
cp $SCRIPTS_PATH/resources/meshlab_appimage.desktop $INSTALL_PATH/usr/share/applications/meshlab.desktop
cp $DISTRIB_PATH/meshlab.png $INSTALL_PATH/usr/share/icons/hicolor/512x512/apps/meshlab.png
cp $DISTRIB_PATH/meshlab.png $INSTALL_PATH/usr/share/icons/Yaru/512x512/apps/meshlab.png
cp $DISTRIB_PATH/LICENSE.txt $INSTALL_PATH/usr/share/doc/meshlab/
cp $DISTRIB_PATH/privacy.txt $INSTALL_PATH/usr/share/doc/meshlab/

View File

@ -7,7 +7,7 @@ GenericName[en_GB]=Mesh processing
Comment=View and process meshes
Type=Application
Exec=meshlab %F
Icon=/usr/share/pixmaps/meshlab.png
Icon=meshlab
Terminal=false
MimeType=model/mesh;application/x-3ds;image/x-3ds;model/x-ply;application/sla;model/x-quad-object;model/x-geomview-off;application/x-cyclone-ptx;application/x-vmi;application/x-bre;model/vnd.collada+xml;model/openctm;application/x-expe-binary;application/x-expe-ascii;application/x-xyz;application/x-gts;chemical/x-pdb;application/x-tri;application/x-asc;model/x3d+xml;model/x3d+vrml;model/vrml;model/u3d;model/idtf;
Categories=Graphics;3DGraphics;Viewer;Qt;

View File

@ -18,9 +18,14 @@ apps:
meshlab:
command: AppRun
extensions: [kde-neon]
plugs: [home, opengl, removable-media]
desktop: usr/share/applications/meshlab.desktop
environment:
DISABLE_WAYLAND: 1
plugs:
- home
- opengl
- removable-media
- mount-observe
parts:
meshlab:
@ -43,6 +48,8 @@ parts:
- patchelf
- rsync
- libqt5opengl5-dev
- libcgal-dev
- libboost-all-dev
stage-packages:
- lib3ds-1-3
- libgomp1

View File

@ -0,0 +1,19 @@
#!/bin/bash
#default paths wrt the script folder
SCRIPTS_PATH="$(dirname "$(realpath "$0")")"
EXTERNAL_PATH=$SCRIPTS_PATH/../../src/external
cd $EXTERNAL_PATH
wget https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.zip
unzip boost_1_75_0.zip
rm boost_1_75_0.zip
wget https://github.com/CGAL/cgal/releases/download/v5.2.1/CGAL-5.2.1.zip
unzip CGAL-5.2.1.zip
rm CGAL-5.2.1.zip
wget https://github.com/CGAL/cgal/releases/download/v5.2.1/CGAL-5.2.1-win64-auxiliary-libraries-gmp-mpfr.zip
unzip -o CGAL-5.2.1-win64-auxiliary-libraries-gmp-mpfr.zip -d CGAL-5.2.1/
rm CGAL-5.2.1-win64-auxiliary-libraries-gmp-mpfr.zip

View File

@ -18,7 +18,6 @@ BUILD_PATH=$SOURCE_PATH/build
INSTALL_PATH=$SOURCE_PATH/install
DOUBLE_PRECISION_OPTION=""
NIGHTLY_OPTION=""
RC_OPTION=""
#check parameters
for i in "$@"
@ -40,10 +39,6 @@ case $i in
NIGHTLY_OPTION="-DMESHLAB_IS_NIGHTLY_VERSION=ON"
shift # past argument=value
;;
-rc|--release_candidate)
RC_OPTION="-DMESHLAB_IS_RELEASE_CANDIDATE_VERSION=ON"
shift # past argument=value
;;
*)
# unknown option
;;
@ -70,6 +65,6 @@ echo "INSTALL PATH: "$INSTALL_PATH
echo "SCRIPTS PATH: "$SCRIPTS_PATH
cd $BUILD_PATH
cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $RC_OPTION $SOURCE_PATH
cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $SOURCE_PATH
ninja
ninja install

View File

@ -0,0 +1,12 @@
param($pssw, $path, $cert_path="")
if ([string]::IsNullOrEmpty($cert_path)) {
$cert_path = Join-Path $PSScriptRoot ..\..\..\certificate\certificate.pfx
}
$files = Get-ChildItem $path -include ('*.exe', '*.dll') -Recurse
for ($i=0; $i -lt $files.Count; $i++) {
$file = $files[$i].FullName
signtool.exe sign /f $cert_path /p $pssw /t http://timestamp.comodoca.com/authenticode $file
}

View File

@ -24,7 +24,6 @@ INSTALL_PATH=$SOURCE_PATH/install
CORES="-j4"
DOUBLE_PRECISION_OPTION=""
NIGHTLY_OPTION=""
RC_OPTION=""
#check parameters
for i in "$@"
@ -50,10 +49,6 @@ case $i in
NIGHTLY_OPTION="-DMESHLAB_IS_NIGHTLY_VERSION=ON"
shift # past argument=value
;;
-rc|--release_candidate)
RC_OPTION="-DMESHLAB_IS_RELEASE_CANDIDATE_VERSION=ON"
shift # past argument=value
;;
*)
# unknown option
;;
@ -73,6 +68,6 @@ then
fi
cd $BUILD_PATH
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $RC_OPTION $SOURCE_PATH
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH $DOUBLE_PRECISION_OPTION $NIGHTLY_OPTION $SOURCE_PATH
make $CORES
make install

View File

@ -47,4 +47,11 @@ else
MACDEPLOYQT_EXE=macdeployqt
fi
${MACDEPLOYQT_EXE} $INSTALL_PATH/$APPNAME -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libedit_align.so -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_csg.so -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_isoparametrization.so -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_screened_poisson.so -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_sketchfab.so -executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libio_e57.so
${MACDEPLOYQT_EXE} $INSTALL_PATH/$APPNAME \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libedit_align.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_csg.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_isoparametrization.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_mesh_booleans.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_screened_poisson.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libfilter_sketchfab.so \
-executable=$INSTALL_PATH/$APPNAME/Contents/PlugIns/libio_e57.so

View File

@ -1,7 +1,7 @@
# Known to build in Ubuntu 18.04, 20.04
name: meshlab
base: core18
version: '2020.12'
version: '2021.05'
summary: MeshLab
description: |
The open source system for processing and editing 3D triangular meshes.
@ -18,9 +18,14 @@ apps:
meshlab:
command: AppRun
extensions: [kde-neon]
plugs: [home, opengl, removable-media]
desktop: usr/share/applications/meshlab.desktop
environment:
DISABLE_WAYLAND: 1
plugs:
- home
- opengl
- removable-media
- mount-observe
parts:
meshlab:

View File

@ -2,24 +2,18 @@
# Copyright 2019, 2021, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.10)
project(MeshLab)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
### Build options
option(ALLOW_BUNDLED_EXTERNAL_MESHLAB_LIBRARIES "Allow to build bundled external libraries sources" ON)
option(BUILD_MINI "Build only a minimal set of plugins" OFF)
option(BUILD_SERVER "Build a command-line server application" OFF)
option(BUILD_STRICT "Strictly enforce resolution of all symbols" ON)
option(BUILD_WITH_DOUBLE_SCALAR "Use double type instead of float type for scalars" OFF)
option(BUILD_ONLY_MESHLAB_LIBRARIES "Build only meshlab-common and plugins" OFF)
option(USE_DEFAULT_BUILD_AND_INSTALL_DIRS "If set to OFF, it expects that you set manually the binary and install directories" ON)
option(MESHLAB_IS_RELEASE_CANDIDATE_VERSION "" OFF)
option(MESHLAB_IS_NIGHTLY_VERSION "" OFF)
option(MESHLAB_IS_NIGHTLY_VERSION "Nightly version of meshlab will be used instead of ML_VERSION" OFF)
### Dependencies
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@ -112,18 +106,12 @@ endif()
# External
set(EXTERNAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
include(${EXTERNAL_DIR}/external_common.cmake)
if((NOT BUILD_MINI) AND (ALLOW_BUNDLED_EXTERNAL_MESHLAB_LIBRARIES))
add_subdirectory(${EXTERNAL_DIR})
endif()
add_subdirectory(${EXTERNAL_DIR})
add_subdirectory(common)
if (NOT BUILD_ONLY_MESHLAB_LIBRARIES)
add_subdirectory(meshlab)
if(BUILD_SERVER)
add_subdirectory(meshlabserver)
endif()
if(WIN32 AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/use_cpu_opengl")
add_subdirectory(use_cpu_opengl)
endif()
@ -172,7 +160,6 @@ if(NOT DEFINED MESHLAB_PLUGINS) # it may be already defined in parent directory
meshlabplugins/filter_color_projection
meshlabplugins/filter_colorproc
meshlabplugins/filter_create
meshlabplugins/filter_csg
meshlabplugins/filter_dirt
meshlabplugins/filter_fractal
meshlabplugins/filter_func
@ -180,6 +167,7 @@ if(NOT DEFINED MESHLAB_PLUGINS) # it may be already defined in parent directory
meshlabplugins/filter_isoparametrization
meshlabplugins/filter_layer
meshlabplugins/filter_measure
meshlabplugins/filter_mesh_booleans
meshlabplugins/filter_meshing
meshlabplugins/filter_mls
meshlabplugins/filter_mutualglobal
@ -194,6 +182,7 @@ if(NOT DEFINED MESHLAB_PLUGINS) # it may be already defined in parent directory
meshlabplugins/filter_sketchfab
meshlabplugins/filter_ssynth
meshlabplugins/filter_texture
meshlabplugins/filter_texture_defragmentation
meshlabplugins/filter_trioptimize
meshlabplugins/filter_unsharp
meshlabplugins/filter_voronoi
@ -279,7 +268,7 @@ if (NOT BUILD_ONLY_MESHLAB_LIBRARIES)
if(NOT WIN32 AND NOT APPLE)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/Linux/resources/meshlab.desktop" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/meshlab.png" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../scripts/meshlab.png" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps)
endif()
endif()

View File

@ -8,7 +8,6 @@ The source code of MeshLab is structured in the following directories:
* [external](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/external): it contains a series of external libraries needed by several plugins. Some of these libraries are compiled before the compilation of meshlab, if a corresponding system library is not found and then linked; other are header-only libraries that are just included;
* [common](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/common): a series of utility classes and functions used by MeshLab and its plugins;
* [meshlab](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/meshlab): GUI and core of MeshLab;
* [meshlabserver](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/meshlabserver): a tool that allows to compute mesh operations through command line;
* [meshlabplugins](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/meshlabplugins): all the plugins that can be added to MeshLab;
* [use_cpu_opengl](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/use_cpu_opengl): a tool compiled only under windows that allows to use non-GPU accelerated OpenGL calls;
* [vcglib](https://github.com/cnr-isti-vclab/meshlab/tree/master/src/vcglib): submodule containing the vcglib.

View File

@ -2,14 +2,15 @@
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
# Prefer GLVND
# Prefer OpenGL GLVND
if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
endif()
### Build settings
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version" FORCE)

View File

@ -1,15 +1,13 @@
#version management
string(TIMESTAMP MESHLAB_VERSION "%Y.%m")
if (MESHLAB_IS_RELEASE_CANDIDATE_VERSION AND MESHLAB_IS_NIGHTLY_VERSION)
message(FATAL_ERROR "Both nightly and release candidate options are set to ON. Choose one.")
endif()
if (MESHLAB_IS_NIGHTLY_VERSION)
# nightly version is in the form:
# YYYY.mm[d]_nightly_GIT_SHA1
# YYYY and mm are computed by cmake and not read from file
find_package(Git)
execute_process(COMMAND
"${GIT_EXECUTABLE}" describe --match=NeVeRmAtCh --always --abbrev=6
"${GIT_EXECUTABLE}" describe --match=NeVeRmAtCh --always --abbrev=7
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_SHA1
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
@ -23,13 +21,9 @@ else()
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/../../ML_VERSION" MESHLAB_VERSION)
endif()
# if double precision version, "d" is appended
# if release candidate, "_rc" is appended
if (BUILD_WITH_DOUBLE_SCALAR)
set(MESHLAB_VERSION "${MESHLAB_VERSION}d")
endif()
if (MESHLAB_IS_RELEASE_CANDIDATE_VERSION)
set(MESHLAB_VERSION "${MESHLAB_VERSION}_rc")
endif()
endif()
message(STATUS "MeshLab version: ${MESHLAB_VERSION}")
@ -82,9 +76,6 @@ set(HEADERS
GLExtensionsManager.h
GLLogStream.h
filterscript.h
mainwindow_interface.h
meshlabdocumentbundler.h
meshlabdocumentxml.h
ml_selection_buffers.h
ml_thread_safe_memory_info.h
mlapplication.h
@ -125,13 +116,12 @@ set(SOURCES
GLExtensionsManager.cpp
GLLogStream.cpp
filterscript.cpp
meshlabdocumentbundler.cpp
meshlabdocumentxml.cpp
ml_selection_buffers.cpp
ml_thread_safe_memory_info.cpp
mlapplication.cpp
searcher.cpp
${EXTERNAL_DIR}/easyexif/exif.cpp)
searcher.cpp)
set(RESOURCES meshlab-common.qrc)
set(TARGET_TYPE SHARED)
if(WIN32)
@ -145,8 +135,6 @@ target_compile_definitions(meshlab-common
MESHLAB_SCALAR=${MESHLAB_SCALAR})
target_include_directories(meshlab-common
PRIVATE
${EXTERNAL_DIR}/easyexif/
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..)
@ -160,6 +148,7 @@ target_link_libraries(
Qt5::Network
vcglib
external-glew
external-exif
)
set_property(TARGET meshlab-common PROPERTY FOLDER Core)

View File

@ -61,7 +61,7 @@ void GLExtensionsManager::initializeGLextensions()
if (!glewInitialized) {
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (err != GLEW_OK && err != GLEW_ERROR_NO_GLX_DISPLAY) {
if (err != GLEW_OK) {
throw MLException(QString("GLEW initialization failed: %1\n")
.arg((const char *)glewGetErrorString(err)));
}

View File

@ -75,12 +75,10 @@ HEADERS += \
GLExtensionsManager.h \
filterscript.h \
GLLogStream.h \
mainwindow_interface.h \
mlexception.h \
mlapplication.h \
meshlabdocumentxml.h \
ml_selection_buffers.h \
meshlabdocumentxml.h
ml_selection_buffers.h
SOURCES += \
globals.cpp \
@ -118,11 +116,12 @@ SOURCES += \
GLLogStream.cpp \
mlapplication.cpp \
searcher.cpp \
meshlabdocumentxml.cpp \
meshlabdocumentbundler.cpp \
ml_selection_buffers.cpp \
$$MESHLAB_EXTERNAL_DIRECTORY/easyexif/exif.cpp
RESOURCES += \
meshlab-common.qrc
macx:QMAKE_POST_LINK = "\
if [ -d $$MESHLAB_DISTRIB_DIRECTORY/meshlab.app/Contents/Frameworks/ ]; \
then \

BIN
src/common/img/dummy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>img/dummy.png</file>
</qresource>
</RCC>

View File

@ -1,98 +0,0 @@
#include <QString>
#include <QtGlobal>
#include <QString>
#include <QFileInfo>
#include <QFileDialog>
#include <QMessageBox>
#include <QtXml>
#include "ml_document/mesh_document.h"
#include<QImageReader>
#include "meshlabdocumentbundler.h"
#include <wrap/qt/shot_qt.h>
#include <wrap/io_trimesh/import_out.h>
#include <wrap/io_trimesh/import_nvm.h>
bool MeshDocumentFromBundler(MeshDocument &md, QString filename_out,QString image_list_filename, QString model_filename)
{
md.addNewMesh(model_filename,QString("model"));
std::vector<Shotm> shots;
const QString path = QFileInfo(filename_out).absolutePath();
const QString path_im = QFileInfo(image_list_filename).absolutePath()+QString("/");
std::vector<std::string> image_filenames;
vcg::tri::io::ImporterOUT<CMeshO>::Open(md.mm()->cm,shots,image_filenames, qUtf8Printable(filename_out), qUtf8Printable(image_list_filename));
md.mm()->updateDataMask(MeshModel::MM_VERTCOLOR);
QString curr_path = QDir::currentPath();
QFileInfo imi(image_list_filename);
//
QStringList image_filenames_q;
for(unsigned int i = 0; i < image_filenames.size(); ++i)
{
QImageReader sizeImg(QString::fromStdString(image_filenames[i]));
if(sizeImg.size()==QSize(-1,-1))
image_filenames_q.push_back(path_im+QString::fromStdString(image_filenames[i]));
else
image_filenames_q.push_back(QString::fromStdString(image_filenames[i]));
}
QDir::setCurrent(imi.absoluteDir().absolutePath());
for(size_t i=0 ; i<shots.size() ; i++)
{
md.addNewRaster();
const QString fullpath_image_filename = image_filenames_q[int(i)];
md.rm()->addPlane(new RasterPlane(fullpath_image_filename,RasterPlane::RGBA));
int count=fullpath_image_filename.count('\\');
if (count==0)
{
count=fullpath_image_filename.count('/');
md.rm()->setLabel(fullpath_image_filename.section('/',count,1));
}
else
md.rm()->setLabel(fullpath_image_filename.section('\\',count,1));
md.rm()->shot = shots[i];
}
QDir::setCurrent(curr_path);
return true;
}
bool MeshDocumentFromNvm(MeshDocument &md, QString filename_nvm, QString model_filename)
{
md.addNewMesh(model_filename,QString("model"));
std::vector<Shotm> shots;
const QString path = QFileInfo(filename_nvm).absolutePath();
//const QString path_im = QFileInfo(image_list_filename).absolutePath()+QString("/");
std::vector<std::string> image_filenames;
vcg::tri::io::ImporterNVM<CMeshO>::Open(md.mm()->cm,shots,image_filenames, qUtf8Printable(filename_nvm));
md.mm()->updateDataMask(MeshModel::MM_VERTCOLOR);
QString curr_path = QDir::currentPath();
//QFileInfo imi(image_list_filename);
//QDir::setCurrent(imi.absoluteDir().absolutePath());
QStringList image_filenames_q;
for(size_t i = 0; i < image_filenames.size(); ++i)
image_filenames_q.push_back(QString::fromStdString(image_filenames[int(i)]));
for(size_t i=0 ; i<shots.size() ; i++){
md.addNewRaster();
const QString fullpath_image_filename = image_filenames_q[int(i)];
md.rm()->addPlane(new RasterPlane(fullpath_image_filename,RasterPlane::RGBA));
md.rm()->setLabel(image_filenames_q[int(i)].section('/',1,2));
md.rm()->shot = shots[int(i)];
/*md.rm()->shot.Intrinsics.ViewportPx[0]=md.rm()->currentPlane->image.width();
md.rm()->shot.Intrinsics.ViewportPx[1]=md.rm()->currentPlane->image.height();
md.rm()->shot.Intrinsics.CenterPx[0]=(int)((double)md.rm()->shot.Intrinsics.ViewportPx[0]/2.0f);
md.rm()->shot.Intrinsics.CenterPx[1]=(int)((double)md.rm()->shot.Intrinsics.ViewportPx[1]/2.0f);*/
}
QDir::setCurrent(curr_path);
return true;
}

View File

@ -1,9 +0,0 @@
#ifndef __MESHLABDOC_BUNDLER_H
#define __MESHLABDOC_BUNDLER_H
#include "ml_document/mesh_model.h"
bool MeshDocumentFromBundler(MeshDocument &md, QString filename_out, QString image_list_filename, QString model_filename);
bool MeshDocumentFromNvm(MeshDocument &md, QString filename_nvm, QString model_filename);
#endif // __MESHLABDOC_BUNDLER_H

View File

@ -1,297 +0,0 @@
#include <QString>
#include <QtGlobal>
#include <QFileInfo>
#include <QtXml>
#include "meshlabdocumentxml.h"
#include <wrap/qt/shot_qt.h>
bool MeshDocumentToXMLFile(MeshDocument &md, QString filename, bool onlyVisibleLayers, bool saveViewState, bool binary, const std::map<int, MLRenderingData>& rendOpt)
{
md.setFileName(filename);
QFileInfo fi(filename);
QDir tmpDir = QDir::current();
QDir::setCurrent(fi.absoluteDir().absolutePath());
QDomDocument doc = MeshDocumentToXML(md, onlyVisibleLayers, saveViewState, binary, rendOpt);
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream qstream(&file);
doc.save(qstream, 1);
file.close();
QDir::setCurrent(tmpDir.absolutePath());
return true;
}
QDomElement Matrix44mToXML(Matrix44m &m, QDomDocument &doc)
{
QDomElement matrixElem = doc.createElement("MLMatrix44");
QString Row[4];
for (int i = 0; i < 4; ++i)
Row[i] = QString("%1 %2 %3 %4 \n").arg(m[i][0]).arg(m[i][1]).arg(m[i][2]).arg(m[i][3]);
QDomText nd = doc.createTextNode("\n" + Row[0] + Row[1] + Row[2] + Row[3]);
matrixElem.appendChild(nd);
return matrixElem;
}
QDomElement Matrix44mToBinaryXML(Matrix44m &m, QDomDocument &doc)
{
QDomElement matrixElem = doc.createElement("MLMatrix44");
QByteArray value = QByteArray::fromRawData((char *)m.V(), sizeof(Matrix44m::ScalarType) * 16).toBase64();
QDomText nd = doc.createTextNode(QString(value));
matrixElem.appendChild(nd);
return matrixElem;
}
bool MeshDocumentFromXML(MeshDocument &md, QString filename, bool binary, std::map<int, MLRenderingData>& rendOpt)
{
QFile qf(filename);
QFileInfo qfInfo(filename);
QDir tmpDir = QDir::current();
QDir::setCurrent(qfInfo.absoluteDir().absolutePath());
if (!qf.open(QIODevice::ReadOnly))
return false;
QString project_path = qfInfo.absoluteFilePath();
QDomDocument doc("MeshLabDocument"); //It represents the XML document
if (!doc.setContent(&qf))
return false;
QDomElement root = doc.documentElement();
QDomNode node;
node = root.firstChild();
//Devices
while (!node.isNull()) {
if (QString::compare(node.nodeName(), "MeshGroup") == 0)
{
QDomNode mesh; QString filen, label;
mesh = node.firstChild();
while (!mesh.isNull()) {
//return true;
filen = mesh.attributes().namedItem("filename").nodeValue();
label = mesh.attributes().namedItem("label").nodeValue();
bool visible = true;
if (mesh.attributes().contains("visible"))
visible = (mesh.attributes().namedItem("visible").nodeValue().toInt() == 1);
MeshModel* mm = md.addNewMesh(filen, label);
mm->visible = visible;
if (mesh.attributes().contains("idInFile"))
mm->setIdInFile(mesh.attributes().namedItem("idInFile").nodeValue().toInt());
QDomNode tr = mesh.firstChildElement("MLMatrix44");
if (!tr.isNull())
{
vcg::Matrix44f trm;
if (tr.childNodes().size() == 1)
{
if (!binary)
{
QStringList rows = tr.firstChild().nodeValue().split("\n", QString::SkipEmptyParts);
int i = 0;
for (const QString& row : qAsConst(rows)){
if (rows.size() > 0) {
QStringList values = row.split(" ", QString::SkipEmptyParts);
int j = 0;
for (const QString& value : qAsConst(values)) {
if (i < 4 && j < 4) {
md.mm()->cm.Tr[i][j] = value.toFloat();
j++;
}
}
i++;
}
}
}
else
{
QString str = tr.firstChild().nodeValue();
QByteArray value = QByteArray::fromBase64(str.toLocal8Bit());
memcpy(md.mm()->cm.Tr.V(), value.data(), sizeof(Matrix44m::ScalarType) * 16);
}
}
}
QDomNode renderingOpt = mesh.firstChildElement("RenderingOption");
if (!renderingOpt.isNull())
{
QString value = renderingOpt.firstChild().nodeValue();
MLRenderingData::GLOptionsType opt;
if (renderingOpt.attributes().contains("pointSize"))
opt._perpoint_pointsize = renderingOpt.attributes().namedItem("pointSize").nodeValue().toFloat();
if (renderingOpt.attributes().contains("wireWidth"))
opt._perwire_wirewidth = renderingOpt.attributes().namedItem("wireWidth").nodeValue().toFloat();
if (renderingOpt.attributes().contains("boxColor"))
{
QStringList values = renderingOpt.attributes().namedItem("boxColor").nodeValue().split(" ", QString::SkipEmptyParts);
opt._perbbox_fixed_color = vcg::Color4b(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3].toInt());
}
if (renderingOpt.attributes().contains("pointColor"))
{
QStringList values = renderingOpt.attributes().namedItem("pointColor").nodeValue().split(" ", QString::SkipEmptyParts);
opt._perpoint_fixed_color = vcg::Color4b(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3].toInt());
}
if (renderingOpt.attributes().contains("wireColor"))
{
QStringList values = renderingOpt.attributes().namedItem("wireColor").nodeValue().split(" ", QString::SkipEmptyParts);
opt._perwire_fixed_color = vcg::Color4b(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3].toInt());
}
if (renderingOpt.attributes().contains("solidColor"))
{
QStringList values = renderingOpt.attributes().namedItem("solidColor").nodeValue().split(" ", QString::SkipEmptyParts);
opt._persolid_fixed_color = vcg::Color4b(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3].toInt());
}
MLRenderingData data;
data.set(opt);
if (data.deserialize(value.toStdString()))
rendOpt.insert(std::pair<int, MLRenderingData>(mm->id(), data));
}
mesh = mesh.nextSibling();
}
}
// READ IN POINT CORRESPONDECES INCOMPLETO!!
else if (QString::compare(node.nodeName(), "RasterGroup") == 0)
{
QDomNode raster; QString filen, label;
raster = node.firstChild();
while (!raster.isNull())
{
//return true;
md.addNewRaster();
QString labelRaster = raster.attributes().namedItem("label").nodeValue();
md.rm()->setLabel(labelRaster);
QDomNode sh = raster.firstChild();
ReadShotFromQDomNode(md.rm()->shot, sh);
QDomElement el = raster.firstChildElement("Plane");
while (!el.isNull())
{
QString filen = el.attribute("fileName");
QFileInfo fi(filen);
QString sem = el.attribute("semantic");
QString nm = fi.absoluteFilePath();
md.rm()->addPlane(new RasterPlane(fi.absoluteFilePath(), RasterPlane::RGBA));
el = node.nextSiblingElement("Plane");
}
raster = raster.nextSibling();
}
}
node = node.nextSibling();
}
QDir::setCurrent(tmpDir.absolutePath());
qf.close();
return true;
}
QDomElement MeshModelToXML(MeshModel *mp, QDomDocument &doc, bool binary, bool saveViewState, const MLRenderingData& rendOpt = MLRenderingData())
{
QDomElement meshElem = doc.createElement("MLMesh");
meshElem.setAttribute("label", mp->label());
meshElem.setAttribute("filename", mp->relativePathName());
meshElem.setAttribute("visible", saveViewState?mp->isVisible():true);
meshElem.setAttribute("idInFile", mp->idInFile());
if (binary)
meshElem.appendChild(Matrix44mToBinaryXML(mp->cm.Tr, doc));
else
meshElem.appendChild(Matrix44mToXML(mp->cm.Tr, doc));
if (saveViewState)
{
QDomElement renderingElem = doc.createElement("RenderingOption");
std::string text;
rendOpt.serialize(text);
QDomText nd = doc.createTextNode(QString(text.c_str()));
renderingElem.appendChild(nd);
MLRenderingData::GLOptionsType opt;
if (rendOpt.get(opt))
{
renderingElem.setAttribute("boxColor", QString("%1 %2 %3 %4").arg(opt._perbbox_fixed_color[0]).arg(opt._perbbox_fixed_color[1]).arg(opt._perbbox_fixed_color[2]).arg(opt._perbbox_fixed_color[3]));
renderingElem.setAttribute("pointColor", QString("%1 %2 %3 %4").arg(opt._perpoint_fixed_color[0]).arg(opt._perpoint_fixed_color[1]).arg(opt._perpoint_fixed_color[2]).arg(opt._perpoint_fixed_color[3]));
renderingElem.setAttribute("wireColor", QString("%1 %2 %3 %4").arg(opt._perwire_fixed_color[0]).arg(opt._perwire_fixed_color[1]).arg(opt._perwire_fixed_color[2]).arg(opt._perwire_fixed_color[3]));
renderingElem.setAttribute("solidColor", QString("%1 %2 %3 %4").arg(opt._persolid_fixed_color[0]).arg(opt._persolid_fixed_color[1]).arg(opt._persolid_fixed_color[2]).arg(opt._persolid_fixed_color[3]));
renderingElem.setAttribute("pointSize", opt._perpoint_pointsize);
renderingElem.setAttribute("wireWidth", opt._perwire_wirewidth);
}
meshElem.appendChild(renderingElem);
}
return meshElem;
}
QDomElement RasterModelToXML(RasterModel *mp, QDomDocument &doc, bool binary)
{
QDomElement rasterElem = doc.createElement("MLRaster");
rasterElem.setAttribute("label", mp->label());
if (binary)
rasterElem.appendChild(WriteShotToQDomNodeBinary(mp->shot, doc));
else
rasterElem.appendChild(WriteShotToQDomNode(mp->shot, doc));
for (int ii = 0; ii < mp->planeList.size(); ++ii)
rasterElem.appendChild(PlaneToXML(mp->planeList[ii], mp->par->pathName(), doc));
return rasterElem;
}
QDomElement PlaneToXML(RasterPlane* pl, const QString& basePath, QDomDocument& doc)
{
QDomElement planeElem = doc.createElement("Plane");
QDir dir(basePath);
planeElem.setAttribute("fileName", dir.relativeFilePath(pl->fullPathFileName));
planeElem.setAttribute("semantic", pl->semantic);
return planeElem;
}
QDomDocument MeshDocumentToXML(MeshDocument &md, bool onlyVisibleLayers, bool saveViewState, bool binary, const std::map<int, MLRenderingData>& rendOpt)
{
QDomDocument ddoc("MeshLabDocument");
QDomElement root = ddoc.createElement("MeshLabProject");
ddoc.appendChild(root);
QDomElement mgroot = ddoc.createElement("MeshGroup");
for(MeshModel *mmp : md.meshList)
{
if ((!onlyVisibleLayers) || (mmp->visible))
{
QDomElement meshElem;
if (rendOpt.find(mmp->id()) != rendOpt.end())
meshElem = MeshModelToXML(mmp, ddoc, binary, saveViewState, rendOpt.at(mmp->id()));
else
meshElem = MeshModelToXML(mmp, ddoc, binary, saveViewState);
mgroot.appendChild(meshElem);
}
}
root.appendChild(mgroot);
QDomElement rgroot = ddoc.createElement("RasterGroup");
foreach(RasterModel *rmp, md.rasterList)
{
QDomElement rasterElem = RasterModelToXML(rmp, ddoc, binary);
rgroot.appendChild(rasterElem);
}
root.appendChild(rgroot);
// tag.setAttribute(QString("name"),(*ii).first);
// RichParameterSet &par=(*ii).second;
// QList<RichParameter*>::iterator jj;
// RichParameterXMLVisitor v(doc);
// for(jj=par.paramList.begin();jj!=par.paramList.end();++jj)
// {
// (*jj)->accept(v);
// tag.appendChild(v.parElem);
// }
// root.appendChild(tag);
// }
//
return ddoc;
}

View File

@ -1,16 +0,0 @@
#ifndef __MESHLABDOC_XML_H
#define __MESHLABDOC_XML_H
#include <QDomDocument>
#include "ml_shared_data_context/ml_shared_data_context.h"
#include "ml_document/mesh_document.h"
#include<map>
QDomDocument MeshDocumentToXML(MeshDocument &md, bool onlyVisibleLayers, bool saveViewState, bool binary, const std::map<int, MLRenderingData>& rendOpt = std::map<int, MLRenderingData>());
bool MeshDocumentToXMLFile(MeshDocument &md, QString filename, bool onlyVisibleLayers, bool saveViewState, bool binary, const std::map<int, MLRenderingData>& rendOpt = std::map<int, MLRenderingData>());
bool MeshDocumentFromXML(MeshDocument &md, QString filename, bool binary, std::map<int, MLRenderingData>& rendOpt);
QDomElement RasterModelToXML(RasterModel *mp,QDomDocument &doc, bool binary);
QDomElement PlaneToXML(RasterPlane* pl,const QString& basePath,QDomDocument& doc);
#endif // __MESHLABDOC_XML_H

View File

@ -35,18 +35,22 @@ CMeshO::CMeshO(const CMeshO& oth) :
{
enableOCFComponentsFromOtherMesh(oth);
vcg::tri::Append<vcgTriMesh, vcgTriMesh>::MeshAppendConst(*this, oth);
textures = oth.textures;
normalmaps = oth.normalmaps;
}
/// TODO: make a proper implementation of a move constructor.
/// Even if almost never used, this is very inefficient.
CMeshO::CMeshO(CMeshO&& oth):
vcgTriMesh(), sfn(oth.sfn), svn(oth.svn),
vcgTriMesh(), sfn(oth.sfn), svn(oth.svn),
pvn(oth.pvn), pfn(oth.pfn), Tr(oth.Tr)
{
enableOCFComponentsFromOtherMesh(oth);
//I could take everything from oth and place it in
//this mesh
vcg::tri::Append<vcgTriMesh, vcgTriMesh>::Mesh(*this, oth);
textures = oth.textures;
normalmaps = oth.normalmaps;
}
/// TODO: change this and use the copy&swap idiom
@ -60,6 +64,8 @@ CMeshO& CMeshO::operator=(const CMeshO& oth)
pvn = oth.pvn;
pfn = oth.pfn;
Tr = oth.Tr;
textures = oth.textures;
normalmaps = oth.normalmaps;
return *this;
}

View File

@ -16,9 +16,7 @@ MeshDocumentStateData::~MeshDocumentStateData()
void MeshDocumentStateData::create(MeshDocument& md)
{
QWriteLocker locker(&_lock);
for (int ii = 0; ii < md.meshList.size(); ++ii)
{
MeshModel* mm = md.meshList[ii];
for (MeshModel* mm : md.meshIterator()) {
if (mm != NULL)
insert(mm->id(), MeshModelStateData(mm->dataMask(), mm->cm.VN(), mm->cm.FN(), mm->cm.EN()));
}

View File

@ -2,7 +2,7 @@
* MeshLab o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2020 \/)\/ *
* Copyright(C) 2004-2021 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
@ -24,11 +24,11 @@
#include "mesh_document.h"
template <class LayerElement>
QString NameDisambiguator(QList<LayerElement*> &elemList, QString meshLabel )
QString nameDisambiguator(std::list<LayerElement*> &elemList, QString meshLabel)
{
QString newName=std::move(meshLabel);
typename QList<LayerElement*>::iterator mmi;
typename std::list<LayerElement*>::iterator mmi;
for(mmi=elemList.begin(); mmi!=elemList.end(); ++mmi)
{
if((*mmi)->label() == newName) // if duplicated name found
@ -37,38 +37,36 @@ QString NameDisambiguator(QList<LayerElement*> &elemList, QString meshLabel )
QString baseName = fi.baseName(); // all characters in the file up to the first '.' Eg "/tmp/archive.tar.gz" -> "archive"
QString suffix = fi.suffix();
bool ok;
// if name ends with a number between parenthesis (XXX),
// it was himself a duplicated name, and we need to
// just increase the number between parenthesis
int numDisamb;
int startDisamb;
int endDisamb;
startDisamb = baseName.lastIndexOf("(");
endDisamb = baseName.lastIndexOf(")");
if((startDisamb!=-1)&&(endDisamb!=-1))
numDisamb = (baseName.mid((startDisamb+1),(endDisamb-startDisamb-1))).toInt(&ok);
numDisamb = baseName.midRef((startDisamb+1),(endDisamb-startDisamb-1)).toInt(&ok);
else
numDisamb = 0;
if(startDisamb!=-1)
newName = baseName.left(startDisamb)+ "(" + QString::number(numDisamb+1) + ")";
else
newName = baseName + "(" + QString::number(numDisamb+1) + ")";
if (suffix != QString(""))
newName = newName + "." + suffix;
// now recurse to see if the new name is free
newName = NameDisambiguator(elemList, newName);
newName = nameDisambiguator(elemList, newName);
}
}
return newName;
}
MeshDocument::MeshDocument()
{
meshIdCounter=0;
@ -92,11 +90,11 @@ void MeshDocument::clear()
for(MeshModel *mmp : meshList)
delete mmp;
meshList.clear();
for(RasterModel* rmp :rasterList)
delete rmp;
rasterList.clear();
meshIdCounter=0;
rasterIdCounter=0;
currentMesh = nullptr;
@ -108,7 +106,7 @@ void MeshDocument::clear()
meshDocStateData().clear();
}
const MeshModel* MeshDocument::getMesh(int id) const
const MeshModel* MeshDocument::getMesh(unsigned int id) const
{
for (const MeshModel* m : meshList)
if (m->id() == id)
@ -117,7 +115,7 @@ const MeshModel* MeshDocument::getMesh(int id) const
}
//returns the mesh ata given position in the list
MeshModel* MeshDocument::getMesh(int id)
MeshModel* MeshDocument::getMesh(unsigned int id)
{
for (MeshModel* m : meshList)
if (m->id() == id)
@ -127,8 +125,7 @@ MeshModel* MeshDocument::getMesh(int id)
void MeshDocument::setCurrentMesh(int new_curr_id)
{
if(new_curr_id<0)
{
if(new_curr_id<0) {
currentMesh=0;
return;
}
@ -137,30 +134,31 @@ void MeshDocument::setCurrentMesh(int new_curr_id)
assert(currentMesh);
}
void MeshDocument::setVisible(int meshId, bool val)
{
getMesh(meshId)->visible=val;
emit meshSetChanged();
}
//returns the raster at a given position in the list
RasterModel *MeshDocument::getRaster(int i)
{
foreach(RasterModel *rmp, rasterList)
{
for(RasterModel *rmp : rasterList) {
if(rmp->id() == i) return rmp;
}
//assert(0);
return 0;
}
//if i is <0 it means that no currentRaster is set
void MeshDocument::setCurrentRaster( int new_curr_id)
void MeshDocument::setCurrentRaster(int new_curr_id)
{
if(new_curr_id<0)
{
if(new_curr_id<0) {
currentRaster=0;
return;
}
foreach(RasterModel *rmp, rasterList)
{
if(rmp->id() == new_curr_id)
{
for(RasterModel *rmp : rasterList) {
if(rmp->id() == new_curr_id) {
currentRaster = rmp;
return;
}
@ -183,7 +181,7 @@ MeshModel* MeshDocument::nextVisibleMesh(MeshModel* _m)
MeshModel *newM = nextMesh(_m);
if(newM==0)
return newM;
if(newM->isVisible())
return newM;
else
@ -193,26 +191,31 @@ MeshModel* MeshDocument::nextVisibleMesh(MeshModel* _m)
MeshModel* MeshDocument::nextMesh(MeshModel* _m)
{
if(_m==0 && meshList.size()>0)
return meshList.at(0);
for (int i = 0; i < meshList.size(); ++i) {
if (meshList.at(i) == _m) {
if(i+1 < meshList.size())
return meshList.at(i+1);
return meshList.front();
for (auto it = meshList.begin(); it != meshList.end(); ++it) {
if (*it == _m) {
auto next = it;
next++;
if(next != meshList.end())
return *next;
}
}
return 0;
return nullptr;
}
RasterModel* MeshDocument::nextRaster(RasterModel* _rm)
{
for (int i = 0; i < rasterList.size(); ++i) {
if (rasterList.at(i) == _rm)
{
if(i+1 < rasterList.size())
return rasterList.at(i+1);
if(_rm==0 && rasterList.size()>0)
return rasterList.front();
for (auto it = rasterList.begin(); it != rasterList.end(); ++it) {
if (*it == _rm) {
auto next = it;
next++;
if(next != rasterList.end())
return *next;
}
}
return 0;
return nullptr;
}
MeshModel* MeshDocument::mm()
@ -230,18 +233,13 @@ RasterModel* MeshDocument::rm()
return currentRaster;
}
unsigned int MeshDocument::newMeshId()
const RasterModel* MeshDocument::rm() const
{
return meshIdCounter++;
}
unsigned int MeshDocument::newRasterId()
{
return rasterIdCounter++;
return currentRaster;
}
void MeshDocument::requestUpdatingPerMeshDecorators(int mesh_id)
{
{
emit updateDecorators(mesh_id);
}
@ -271,12 +269,12 @@ void MeshDocument::setFileName(const QString& newFileName)
fullPathFilename = newFileName;
}
int MeshDocument::size() const
unsigned int MeshDocument::meshNumber() const
{
return meshList.size();
}
int MeshDocument::sizeRasters() const
unsigned int MeshDocument::rasterNumber() const
{
return rasterList.size();
}
@ -295,36 +293,46 @@ void MeshDocument::setBusy(bool _busy)
* @brief Adds a new mesh to the MeshDocument. The added mesh is a COPY of the mesh
* passed as parameter.
*/
MeshModel* MeshDocument::addNewMesh(const CMeshO& mesh, QString label, bool setAsCurrent)
MeshModel* MeshDocument::addNewMesh(
const CMeshO& mesh,
const QString& label,
bool setAsCurrent)
{
MeshModel* m = addNewMesh("", label, setAsCurrent);
m->cm = mesh;
m->UpdateBoxAndNormals();
m->updateBoxAndNormals();
m->updateDataMask();
return m;
}
MeshModel * MeshDocument::addNewMesh(QString fullPath, QString label, bool setAsCurrent)
MeshModel * MeshDocument::addNewMesh(
QString fullPath,
const QString& label,
bool setAsCurrent)
{
QString newlabel = NameDisambiguator(this->meshList,std::move(label));
QString newlabel = nameDisambiguator(this->meshList, label);
if(!fullPath.isEmpty())
{
QFileInfo fi(fullPath);
fullPath = fi.absoluteFilePath();
}
MeshModel *newMesh = new MeshModel(this, newMeshId(), fullPath,newlabel);
MeshModel *newMesh = new MeshModel(newMeshId(), fullPath,newlabel);
meshList.push_back(newMesh);
if(setAsCurrent)
this->setCurrentMesh(newMesh->id());
emit meshSetChanged();
emit meshAdded(newMesh->id());
return newMesh;
}
MeshModel * MeshDocument::addOrGetMesh(QString fullPath, const QString& label, bool setAsCurrent)
MeshModel * MeshDocument::addOrGetMesh(
const QString& fullPath,
const QString& label,
bool setAsCurrent)
{
MeshModel *newMesh = nullptr;
for (MeshModel* m : meshList)
@ -335,7 +343,7 @@ MeshModel * MeshDocument::addOrGetMesh(QString fullPath, const QString& label, b
this->setCurrentMesh(newMesh->id());
return newMesh;
}
return addNewMesh(std::move(fullPath),label,setAsCurrent);
return addNewMesh(fullPath,label,setAsCurrent);
}
/**
@ -361,16 +369,19 @@ std::list<MeshModel*> MeshDocument::getMeshesLoadedFromSameFile(MeshModel* mm)
bool MeshDocument::delMesh(MeshModel *mmToDel)
{
if(!meshList.removeOne(mmToDel))
auto pos = std::find(meshList.begin(), meshList.end(), mmToDel);
if (pos == meshList.end())
return false;
meshList.erase(pos);
if((currentMesh == mmToDel) && (!meshList.empty()))
setCurrentMesh(this->meshList.at(0)->id());
setCurrentMesh(this->meshList.front()->id());
else if (meshList.empty())
setCurrentMesh(-1);
int index = mmToDel->id();
delete mmToDel;
emit meshSetChanged();
emit meshRemoved(index);
return true;
@ -380,45 +391,35 @@ RasterModel * MeshDocument::addNewRaster(/*QString fullPathFilename*/)
{
QFileInfo info(fullPathFilename);
QString newLabel=info.fileName();
QString newName = NameDisambiguator(this->rasterList, newLabel);
RasterModel *newRaster=new RasterModel(this, newRasterId(), newLabel);
rasterList.push_back(newRaster);
//Add new plane
//Plane *plane = new Plane(newRaster, fullPathFilename, QString());
//newRaster->addPlane(plane);
this->setCurrentRaster(newRaster->id());
emit rasterSetChanged();
return newRaster;
}
bool MeshDocument::delRaster(RasterModel *rasterToDel)
{
QMutableListIterator<RasterModel *> i(rasterList);
while (i.hasNext())
{
RasterModel *r = i.next();
if (r==rasterToDel)
{
i.remove();
delete rasterToDel;
}
}
if(currentRaster == rasterToDel)
{
if (!rasterList.empty())
setCurrentRaster(rasterList.at(0)->id());
else
setCurrentRaster(-1);
}
auto pos = std::find(rasterList.begin(), rasterList.end(), rasterToDel);
if (pos == rasterList.end())
return false;
rasterList.erase(pos);
if((currentRaster == rasterToDel) && (!rasterList.empty()))
setCurrentRaster(this->rasterList.front()->id());
else if (rasterList.empty())
setCurrentRaster(-1);
delete rasterToDel;
emit rasterSetChanged();
return true;
}
@ -438,7 +439,7 @@ int MeshDocument::fn()
return tot;
}
Box3m MeshDocument::bbox()
Box3m MeshDocument::bbox() const
{
Box3m FullBBox;
for(MeshModel * mp : meshList)
@ -453,8 +454,72 @@ bool MeshDocument::hasBeenModified()
return false;
}
MeshDocument::MeshRangeIterator MeshDocument::meshIterator()
MeshDocument::MeshIterator MeshDocument::meshBegin()
{
return MeshRangeIterator(this);
return meshList.begin();
}
MeshDocument::MeshIterator MeshDocument::meshEnd()
{
return meshList.end();
}
MeshDocument::RasterIterator MeshDocument::rasterBegin()
{
return rasterList.begin();
}
MeshDocument::RasterIterator MeshDocument::rasterEnd()
{
return rasterList.end();
}
MeshDocument::ConstMeshIterator MeshDocument::meshBegin() const
{
return (reinterpret_cast<const std::list<const MeshModel*>* >(&meshList))->begin();
}
MeshDocument::ConstMeshIterator MeshDocument::meshEnd() const
{
return (reinterpret_cast<const std::list<const MeshModel*>* >(&meshList))->end();
}
MeshDocument::ConstRasterIterator MeshDocument::rasterBegin() const
{
return (reinterpret_cast<const std::list<const RasterModel*>* >(&rasterList))->begin();
}
MeshDocument::ConstRasterIterator MeshDocument::rasterEnd() const
{
return (reinterpret_cast<const std::list<const RasterModel*>* >(&rasterList))->end();
}
MeshDocument::MeshRangeIterator MeshDocument::meshIterator()
{
return MeshRangeIterator(*this);
}
MeshDocument::ConstMeshRangeIterator MeshDocument::meshIterator() const
{
return ConstMeshRangeIterator(*this);
}
MeshDocument::RasterRangeIterator MeshDocument::rasterIterator()
{
return RasterRangeIterator(*this);
}
MeshDocument::ConstRasterRangeIterator MeshDocument::rasterIterator() const
{
return ConstRasterRangeIterator(*this);
}
unsigned int MeshDocument::newMeshId()
{
return meshIdCounter++;
}
unsigned int MeshDocument::newRasterId()
{
return rasterIdCounter++;
}

View File

@ -2,7 +2,7 @@
* MeshLab o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2020 \/)\/ *
* Copyright(C) 2004-2021 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
@ -32,150 +32,203 @@
class MeshDocument : public QObject
{
Q_OBJECT
public:
// Iterators
typedef std::list<MeshModel*>::iterator MeshIterator;
typedef std::list<const MeshModel*>::const_iterator ConstMeshIterator;
typedef std::list<RasterModel*>::iterator RasterIterator;
typedef std::list<const RasterModel*>::const_iterator ConstRasterIterator;
class MeshRangeIterator
{
friend class MeshDocument;
public:
MeshIterator begin() {return md.meshBegin();}
MeshIterator end() {return md.meshEnd();}
private:
MeshRangeIterator(MeshDocument& md) : md(md){}
MeshDocument& md;
};
class ConstMeshRangeIterator
{
friend class MeshDocument;
public:
ConstMeshIterator begin() {return md.meshBegin();}
ConstMeshIterator end() {return md.meshEnd();}
private:
ConstMeshRangeIterator(const MeshDocument& md) : md(md){}
const MeshDocument& md;
};
class RasterRangeIterator
{
friend class MeshDocument;
public:
RasterIterator begin() {return md.rasterBegin();}
RasterIterator end() {return md.rasterEnd();}
private:
RasterRangeIterator(MeshDocument& md) : md(md){}
MeshDocument& md;
};
class ConstRasterRangeIterator
{
friend class MeshDocument;
public:
ConstRasterIterator begin() {return md.rasterBegin();}
ConstRasterIterator end() {return md.rasterEnd();}
private:
ConstRasterRangeIterator(const MeshDocument& md) : md(md){}
const MeshDocument& md;
};
MeshDocument();
//deletes each meshModel
~MeshDocument();
void clear();
///returns the mesh with the given unique id
const MeshModel* getMesh(int id) const;
MeshModel* getMesh(int id);
const MeshModel* getMesh(unsigned int id) const;
MeshModel* getMesh(unsigned int id);
//set the current mesh to be the one with the given ID
void setCurrentMesh( int new_curr_id );
void setVisible(int meshId, bool val);
/// returns the raster with the given unique id
RasterModel *getRaster(int i);
//set the current raster to be the one with the given ID
void setCurrentRaster( int new_curr_id );
void setCurrent(MeshModel *newCur);
void setCurrent(RasterModel *newCur);
/// methods to access the set of Meshes in a ordered fashion.
MeshModel *nextVisibleMesh(MeshModel *_m = nullptr);
MeshModel *nextMesh(MeshModel *_m = nullptr);
/// methods to access the set of Meshes in a ordered fashion.
RasterModel *nextRaster(RasterModel *_rm = nullptr);
MeshModel* mm();
const MeshModel* mm() const;
//Could return 0 if no raster has been selected
RasterModel *rm();
const RasterModel* rm() const;
void requestUpdatingPerMeshDecorators(int mesh_id);
MeshDocumentStateData& meshDocStateData();
void setDocLabel(const QString& docLb);
QString docLabel() const;
QString pathName() const;
void setFileName(const QString& newFileName);
int size() const;
int sizeRasters() const;
unsigned int meshNumber() const;
unsigned int rasterNumber() const;
bool isBusy(); // used in processing. To disable access to the mesh by the rendering thread
void setBusy(bool _busy);
///add a new mesh with the given name
MeshModel* addNewMesh(const CMeshO& mesh, QString Label, bool setAsCurrent=true);
MeshModel *addNewMesh(QString fullPath, QString Label, bool setAsCurrent=true);
MeshModel *addOrGetMesh(QString fullPath, const QString& Label, bool setAsCurrent=true);
MeshModel* addNewMesh(const CMeshO& mesh, const QString& Label, bool setAsCurrent=true);
MeshModel *addNewMesh(QString fullPath, const QString& Label, bool setAsCurrent=true);
MeshModel *addOrGetMesh(const QString& fullPath, const QString& Label, bool setAsCurrent=true);
std::list<MeshModel*> getMeshesLoadedFromSameFile(MeshModel* mm);
///remove the mesh from the list and delete it from memory
bool delMesh(MeshModel *mmToDel);
///add a new raster model
RasterModel *addNewRaster(/*QString rasterName*/);
///remove the raster from the list and delete it from memory
bool delRaster(RasterModel *rasterToDel);
int vn(); /// Sum of all the vertices of all the meshes
int fn();
Box3m bbox();
Box3m bbox() const;
bool hasBeenModified();
class MeshRangeIterator
{
friend class MeshDocument;
public:
QList<MeshModel*>::iterator begin() {return md->meshList.begin();}
QList<MeshModel*>::iterator end() {return md->meshList.end();}
private:
MeshRangeIterator(MeshDocument* md) : md(md){}
MeshDocument* md;
};
//iterator member functions
MeshIterator meshBegin();
MeshIterator meshEnd();
RasterIterator rasterBegin();
RasterIterator rasterEnd();
ConstMeshIterator meshBegin() const;
ConstMeshIterator meshEnd() const;
ConstRasterIterator rasterBegin() const;
ConstRasterIterator rasterEnd() const;
MeshRangeIterator meshIterator();
ConstMeshRangeIterator meshIterator() const;
RasterRangeIterator rasterIterator();
ConstRasterRangeIterator rasterIterator() const;
GLLogStream Log;
FilterScript filterHistory;
private:
/// The very important member:
/// The list of MeshModels.
QList<MeshModel *> meshList;
std::list<MeshModel *> meshList;
/// The list of the raster models of the project
QList<RasterModel *> rasterList;
private:
std::list<RasterModel *> rasterList;
int meshIdCounter;
int rasterIdCounter;
/**
All the files referred in a document are relative to the folder containing the project file.
this is the full path to the document.
*/
QString fullPathFilename;
//it is the label of the document. it should only be something like Project_n (a temporary name for a new empty document) or the fullPathFilename.
QString documentLabel;
MeshDocumentStateData mdstate;
bool busy;
MeshModel *currentMesh;
//the current raster model
RasterModel* currentRaster;
unsigned int newMeshId();
unsigned int newRasterId();
signals:
///whenever the current mesh is changed (e.g. the user click on a different mesh)
// this signal will send out with the index of the newest mesh
void currentMeshChanged(int index);
/// whenever the document (or even a single mesh) is modified by a filter
void meshDocumentModified();
///whenever the meshList is changed
void meshSetChanged();
void meshAdded(int index);
void meshRemoved(int index);
///whenever the rasterList is changed
void rasterSetChanged();
//this signal is emitted when a filter request to update the mesh in the renderingState
void documentUpdated();
void updateDecorators(int mesh_id);
};// end class MeshDocument

View File

@ -2,7 +2,7 @@
* MeshLab o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2020 \/)\/ *
* Copyright(C) 2004-2021 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
@ -21,13 +21,12 @@
* *
****************************************************************************/
#include <QString>
#include <QtGlobal>
#include <QFileInfo>
#include "mesh_model.h"
#include "mesh_document.h"
#include "../utilities/load_save.h"
#include <wrap/gl/math.h>
@ -36,178 +35,309 @@
using namespace vcg;
MeshModel::MeshModel(MeshDocument *_parent, unsigned int id, const QString& fullFileName, const QString& labelName) :
MeshModel::MeshModel(unsigned int id, const QString& fullFileName, const QString& labelName) :
idInsideFile(-1)
{
/*glw.m = &(cm);*/
Clear();
parent=_parent;
clear();
_id=id;
if(!fullFileName.isEmpty()) this->fullPathFileName=fullFileName;
if(!labelName.isEmpty()) this->_label=labelName;
if(!labelName.isEmpty()) this->_label=labelName;
}
void MeshModel::Clear()
void MeshModel::clear()
{
setMeshModified(false);
// These data are always active on the mesh
currentDataMask = MM_NONE;
currentDataMask |= MM_VERTCOORD | MM_VERTNORMAL | MM_VERTFLAG ;
currentDataMask |= MM_FACEVERT | MM_FACENORMAL | MM_FACEFLAG ;
// These data are always active on the mesh
currentDataMask = MM_NONE;
currentDataMask |= MM_VERTCOORD | MM_VERTNORMAL | MM_VERTFLAG ;
currentDataMask |= MM_FACEVERT | MM_FACENORMAL | MM_FACEFLAG ;
visible=true;
cm.Tr.SetIdentity();
cm.sfn=0;
cm.svn=0;
visible=true;
cm.Tr.SetIdentity();
cm.sfn=0;
cm.svn=0;
}
void MeshModel::UpdateBoxAndNormals()
void MeshModel::updateBoxAndNormals()
{
tri::UpdateBounding<CMeshO>::Box(cm);
if(cm.fn>0) {
tri::UpdateNormal<CMeshO>::PerFaceNormalized(cm);
tri::UpdateNormal<CMeshO>::PerVertexAngleWeighted(cm);
}
tri::UpdateBounding<CMeshO>::Box(cm);
if(cm.fn>0) {
tri::UpdateNormal<CMeshO>::PerFaceNormalized(cm);
tri::UpdateNormal<CMeshO>::PerVertexAngleWeighted(cm);
}
}
QString MeshModel::relativePathName() const
QString MeshModel::relativePathName(const QString& path) const
{
QDir documentDir (documentPathName());
QString relPath=documentDir.relativeFilePath(this->fullPathFileName);
QDir documentDir (path);
QString relPath=documentDir.relativeFilePath(this->fullPathFileName);
if(relPath.size()>1 && relPath[0]=='.' && relPath[1]=='.')
qDebug("Error we have a mesh that is not in the same folder of the project: %s ", qUtf8Printable(relPath));
//if(relPath.size()>1 && relPath[0]=='.' && relPath[1]=='.')
// qDebug("Error we have a mesh that is not in the same folder of the project: %s ", qUtf8Printable(relPath));
return relPath;
return relPath;
}
QString MeshModel::documentPathName() const
/**
* @brief Starting from the (still unloaded) textures contained in the contained
* CMeshO, loads the textures in the map of QImages contained in the MeshModel.
*
* The contained CMeshO will have a list of texture names like ":filename.png",
* and these names will be mapped with the actual loaded image in the map
* "textures".
*
* When a texture is not found, a dummy texture will be used (":dummy.png").
*
* Returns the list of non-loaded textures that have been modified with
* ":dummy.png" in the contained mesh.
*/
std::list<std::string> MeshModel::loadTextures(
GLLogStream* log,
vcg::CallBackPos* cb)
{
return parent->pathName();
std::list<std::string> unloadedTextures;
for (std::string& textName : cm.textures){
if (textures.find(textName) == textures.end()){
QImage img(":/img/dummy.png");
QFileInfo finfo(QString::fromStdString(textName));
try {
img = meshlab::loadImage(finfo.absoluteFilePath(), log, cb);
textName = finfo.fileName().toStdString();
} catch (const MLException& e) {
try { //could be relative to the meshmodel
QFileInfo mfi(fullName());
QString fn2 = mfi.absolutePath() + "/" + finfo.fileName();
img = meshlab::loadImage(fn2, log, cb);
textName = finfo.fileName().toStdString();
} catch (const MLException& e) {
if (log){
log->log(
GLLogStream::WARNING, "Failed loading " + textName +
"; using a dummy texture");
}
else {
std::cerr <<
"Failed loading " + textName + "; using a dummy texture\n";
}
unloadedTextures.push_back(textName);
textName = "dummy.png";
}
}
textures[textName] = img;
}
}
return unloadedTextures;
}
void MeshModel::saveTextures(
const QString& basePath,
int quality,
GLLogStream* log,
CallBackPos* cb)
{
for (const std::string& tname : cm.textures){
meshlab::saveImage(
basePath + "/" + QString::fromStdString(tname),
textures.at(tname), quality, log, cb);
}
}
QImage MeshModel::getTexture(const std::string& tn) const
{
auto it = textures.find(tn);
if (it != textures.end())
return it->second;
else
return QImage();
}
void MeshModel::clearTextures()
{
textures.clear();
cm.textures.clear();
}
void MeshModel::addTexture(std::string name, const QImage& txt)
{
cm.textures.push_back(name);
textures[name]=txt;
}
void MeshModel::setTexture(std::string name, const QImage& txt)
{
auto it = textures.find(name);
if (it != textures.end())
it->second = txt;
}
void MeshModel::changeTextureName(
const std::string& oldName,
std::string newName)
{
auto mit = textures.find(oldName);
auto tit = std::find(cm.textures.begin(), cm.textures.end(), oldName);
if (mit != textures.end() && tit != cm.textures.end()){
*tit = newName;
textures[newName] = mit->second;
textures.erase(mit);
}
}
int MeshModel::io2mm(int single_iobit)
{
switch(single_iobit)
{
case tri::io::Mask::IOM_NONE : return MM_NONE;
case tri::io::Mask::IOM_VERTCOORD : return MM_VERTCOORD;
case tri::io::Mask::IOM_VERTCOLOR : return MM_VERTCOLOR;
case tri::io::Mask::IOM_VERTFLAGS : return MM_VERTFLAG;
case tri::io::Mask::IOM_VERTQUALITY : return MM_VERTQUALITY;
case tri::io::Mask::IOM_VERTNORMAL : return MM_VERTNORMAL;
case tri::io::Mask::IOM_VERTTEXCOORD : return MM_VERTTEXCOORD;
case tri::io::Mask::IOM_VERTRADIUS : return MM_VERTRADIUS;
switch(single_iobit)
{
case tri::io::Mask::IOM_NONE : return MM_NONE;
case tri::io::Mask::IOM_VERTCOORD : return MM_VERTCOORD;
case tri::io::Mask::IOM_VERTCOLOR : return MM_VERTCOLOR;
case tri::io::Mask::IOM_VERTFLAGS : return MM_VERTFLAG;
case tri::io::Mask::IOM_VERTQUALITY : return MM_VERTQUALITY;
case tri::io::Mask::IOM_VERTNORMAL : return MM_VERTNORMAL;
case tri::io::Mask::IOM_VERTTEXCOORD : return MM_VERTTEXCOORD;
case tri::io::Mask::IOM_VERTRADIUS : return MM_VERTRADIUS;
case tri::io::Mask::IOM_FACEINDEX : return MM_FACEVERT ;
case tri::io::Mask::IOM_FACEFLAGS : return MM_FACEFLAG ;
case tri::io::Mask::IOM_FACECOLOR : return MM_FACECOLOR ;
case tri::io::Mask::IOM_FACEQUALITY : return MM_FACEQUALITY;
case tri::io::Mask::IOM_FACENORMAL : return MM_FACENORMAL ;
case tri::io::Mask::IOM_FACEINDEX : return MM_FACEVERT ;
case tri::io::Mask::IOM_FACEFLAGS : return MM_FACEFLAG ;
case tri::io::Mask::IOM_FACECOLOR : return MM_FACECOLOR ;
case tri::io::Mask::IOM_FACEQUALITY : return MM_FACEQUALITY;
case tri::io::Mask::IOM_FACENORMAL : return MM_FACENORMAL ;
case tri::io::Mask::IOM_WEDGTEXCOORD : return MM_WEDGTEXCOORD;
case tri::io::Mask::IOM_WEDGCOLOR : return MM_WEDGCOLOR;
case tri::io::Mask::IOM_WEDGNORMAL : return MM_WEDGNORMAL ;
case tri::io::Mask::IOM_WEDGTEXCOORD : return MM_WEDGTEXCOORD;
case tri::io::Mask::IOM_WEDGCOLOR : return MM_WEDGCOLOR;
case tri::io::Mask::IOM_WEDGNORMAL : return MM_WEDGNORMAL ;
case tri::io::Mask::IOM_BITPOLYGONAL : return MM_POLYGONAL ;
case tri::io::Mask::IOM_BITPOLYGONAL : return MM_POLYGONAL ;
default:
assert(0);
return MM_NONE; // FIXME: Returning this is not the best solution (!)
break;
} ;
default:
assert(0);
return MM_NONE; // FIXME: Returning this is not the best solution (!)
break;
} ;
}
/**** DATAMASK STUFF ****/
void MeshDocument::setVisible(int meshId, bool val)
{
getMesh(meshId)->visible=val;
emit meshSetChanged();
}
bool MeshModel::hasDataMask(const int maskToBeTested) const
{
return ((currentDataMask & maskToBeTested)!= 0);
return ((currentDataMask & maskToBeTested)!= 0);
}
void MeshModel::updateDataMask(MeshModel *m)
void MeshModel::updateDataMask()
{
updateDataMask(m->currentDataMask);
currentDataMask = MM_NONE;
currentDataMask |=
MM_VERTCOORD | MM_VERTNORMAL | MM_VERTFLAG |
MM_VERTQUALITY | MM_VERTCOLOR;
currentDataMask |=
MM_FACEVERT | MM_FACENORMAL | MM_FACEFLAG ;
if (cm.vert.IsVFAdjacencyEnabled())
currentDataMask |= MM_VERTFACETOPO;
if (cm.vert.IsMarkEnabled())
currentDataMask |= MM_VERTMARK;
if (cm.vert.IsTexCoordEnabled())
currentDataMask |= MM_VERTTEXCOORD;
if (cm.vert.IsCurvatureEnabled())
currentDataMask |= MM_VERTCURV;
if (cm.vert.IsCurvatureDirEnabled())
currentDataMask |= MM_VERTCURVDIR;
if (cm.vert.IsRadiusEnabled())
currentDataMask |= MM_VERTRADIUS;
if (cm.face.IsQualityEnabled())
currentDataMask |= MM_FACEQUALITY;
if (cm.face.IsMarkEnabled())
currentDataMask |= MM_FACEMARK;
if (cm.face.IsColorEnabled())
currentDataMask |= MM_FACECOLOR;
if (cm.face.IsFFAdjacencyEnabled())
currentDataMask |= MM_FACEFACETOPO;
if (cm.face.IsVFAdjacencyEnabled())
currentDataMask |= MM_VERTFACETOPO;
if (cm.face.IsCurvatureDirEnabled())
currentDataMask |= MM_FACECURVDIR;
if (cm.face.IsWedgeTexCoordEnabled())
currentDataMask |= MM_WEDGTEXCOORD;
}
void MeshModel::updateDataMask(const MeshModel *m)
{
updateDataMask(m->currentDataMask);
}
void MeshModel::updateDataMask(int neededDataMask)
{
if((neededDataMask & MM_FACEFACETOPO)!=0)
{
cm.face.EnableFFAdjacency();
tri::UpdateTopology<CMeshO>::FaceFace(cm);
}
if((neededDataMask & MM_VERTFACETOPO)!=0)
{
cm.vert.EnableVFAdjacency();
cm.face.EnableVFAdjacency();
tri::UpdateTopology<CMeshO>::VertexFace(cm);
}
if((neededDataMask & MM_FACEFACETOPO)!=0)
{
cm.face.EnableFFAdjacency();
tri::UpdateTopology<CMeshO>::FaceFace(cm);
}
if((neededDataMask & MM_VERTFACETOPO)!=0)
{
cm.vert.EnableVFAdjacency();
cm.face.EnableVFAdjacency();
tri::UpdateTopology<CMeshO>::VertexFace(cm);
}
if((neededDataMask & MM_WEDGTEXCOORD)!=0)
cm.face.EnableWedgeTexCoord();
if((neededDataMask & MM_FACECOLOR)!=0)
cm.face.EnableColor();
if((neededDataMask & MM_FACEQUALITY)!=0)
cm.face.EnableQuality();
if((neededDataMask & MM_FACECURVDIR)!=0)
cm.face.EnableCurvatureDir();
if((neededDataMask & MM_FACEMARK)!=0)
cm.face.EnableMark();
if((neededDataMask & MM_VERTMARK)!=0)
cm.vert.EnableMark();
if((neededDataMask & MM_VERTCURV)!=0)
cm.vert.EnableCurvature();
if((neededDataMask & MM_VERTCURVDIR)!=0)
cm.vert.EnableCurvatureDir();
if((neededDataMask & MM_VERTRADIUS)!=0)
cm.vert.EnableRadius();
if((neededDataMask & MM_VERTTEXCOORD)!=0)
cm.vert.EnableTexCoord();
if((neededDataMask & MM_WEDGTEXCOORD)!=0)
cm.face.EnableWedgeTexCoord();
if((neededDataMask & MM_FACECOLOR)!=0)
cm.face.EnableColor();
if((neededDataMask & MM_FACEQUALITY)!=0)
cm.face.EnableQuality();
if((neededDataMask & MM_FACECURVDIR)!=0)
cm.face.EnableCurvatureDir();
if((neededDataMask & MM_FACEMARK)!=0)
cm.face.EnableMark();
if((neededDataMask & MM_VERTMARK)!=0)
cm.vert.EnableMark();
if((neededDataMask & MM_VERTCURV)!=0)
cm.vert.EnableCurvature();
if((neededDataMask & MM_VERTCURVDIR)!=0)
cm.vert.EnableCurvatureDir();
if((neededDataMask & MM_VERTRADIUS)!=0)
cm.vert.EnableRadius();
if((neededDataMask & MM_VERTTEXCOORD)!=0)
cm.vert.EnableTexCoord();
currentDataMask |= neededDataMask;
currentDataMask |= neededDataMask;
}
void MeshModel::clearDataMask(int unneededDataMask)
{
if( ( (unneededDataMask & MM_VERTFACETOPO)!=0) && hasDataMask(MM_VERTFACETOPO)) {cm.face.DisableVFAdjacency();
cm.vert.DisableVFAdjacency(); }
if( ( (unneededDataMask & MM_FACEFACETOPO)!=0) && hasDataMask(MM_FACEFACETOPO)) cm.face.DisableFFAdjacency();
if( ( (unneededDataMask & MM_VERTFACETOPO)!=0) && hasDataMask(MM_VERTFACETOPO)) {cm.face.DisableVFAdjacency();
cm.vert.DisableVFAdjacency(); }
if( ( (unneededDataMask & MM_FACEFACETOPO)!=0) && hasDataMask(MM_FACEFACETOPO)) cm.face.DisableFFAdjacency();
if( ( (unneededDataMask & MM_WEDGTEXCOORD)!=0) && hasDataMask(MM_WEDGTEXCOORD)) cm.face.DisableWedgeTexCoord();
if( ( (unneededDataMask & MM_FACECOLOR)!=0) && hasDataMask(MM_FACECOLOR)) cm.face.DisableColor();
if( ( (unneededDataMask & MM_FACEQUALITY)!=0) && hasDataMask(MM_FACEQUALITY)) cm.face.DisableQuality();
if( ( (unneededDataMask & MM_FACEMARK)!=0) && hasDataMask(MM_FACEMARK)) cm.face.DisableMark();
if( ( (unneededDataMask & MM_VERTMARK)!=0) && hasDataMask(MM_VERTMARK)) cm.vert.DisableMark();
if( ( (unneededDataMask & MM_VERTCURV)!=0) && hasDataMask(MM_VERTCURV)) cm.vert.DisableCurvature();
if( ( (unneededDataMask & MM_VERTCURVDIR)!=0) && hasDataMask(MM_VERTCURVDIR)) cm.vert.DisableCurvatureDir();
if( ( (unneededDataMask & MM_VERTRADIUS)!=0) && hasDataMask(MM_VERTRADIUS)) cm.vert.DisableRadius();
if( ( (unneededDataMask & MM_VERTTEXCOORD)!=0) && hasDataMask(MM_VERTTEXCOORD)) cm.vert.DisableTexCoord();
if( ( (unneededDataMask & MM_WEDGTEXCOORD)!=0) && hasDataMask(MM_WEDGTEXCOORD)) cm.face.DisableWedgeTexCoord();
if( ( (unneededDataMask & MM_FACECOLOR)!=0) && hasDataMask(MM_FACECOLOR)) cm.face.DisableColor();
if( ( (unneededDataMask & MM_FACEQUALITY)!=0) && hasDataMask(MM_FACEQUALITY)) cm.face.DisableQuality();
if( ( (unneededDataMask & MM_FACEMARK)!=0) && hasDataMask(MM_FACEMARK)) cm.face.DisableMark();
if( ( (unneededDataMask & MM_VERTMARK)!=0) && hasDataMask(MM_VERTMARK)) cm.vert.DisableMark();
if( ( (unneededDataMask & MM_VERTCURV)!=0) && hasDataMask(MM_VERTCURV)) cm.vert.DisableCurvature();
if( ( (unneededDataMask & MM_VERTCURVDIR)!=0) && hasDataMask(MM_VERTCURVDIR)) cm.vert.DisableCurvatureDir();
if( ( (unneededDataMask & MM_VERTRADIUS)!=0) && hasDataMask(MM_VERTRADIUS)) cm.vert.DisableRadius();
if( ( (unneededDataMask & MM_VERTTEXCOORD)!=0) && hasDataMask(MM_VERTTEXCOORD)) cm.vert.DisableTexCoord();
currentDataMask = currentDataMask & (~unneededDataMask);
currentDataMask = currentDataMask & (~unneededDataMask);
}
void MeshModel::Enable(int openingFileMask)
void MeshModel::enable(int openingFileMask)
{
if( openingFileMask & tri::io::Mask::IOM_VERTTEXCOORD )
updateDataMask(MM_VERTTEXCOORD);
if( openingFileMask & tri::io::Mask::IOM_WEDGTEXCOORD )
updateDataMask(MM_WEDGTEXCOORD);
if( openingFileMask & tri::io::Mask::IOM_VERTCOLOR )
updateDataMask(MM_VERTCOLOR);
if( openingFileMask & tri::io::Mask::IOM_FACECOLOR )
updateDataMask(MM_FACECOLOR);
if( openingFileMask & tri::io::Mask::IOM_VERTRADIUS ) updateDataMask(MM_VERTRADIUS);
if( openingFileMask & tri::io::Mask::IOM_CAMERA ) updateDataMask(MM_CAMERA);
if( openingFileMask & tri::io::Mask::IOM_VERTQUALITY ) updateDataMask(MM_VERTQUALITY);
if( openingFileMask & tri::io::Mask::IOM_FACEQUALITY ) updateDataMask(MM_FACEQUALITY);
if( openingFileMask & tri::io::Mask::IOM_BITPOLYGONAL ) updateDataMask(MM_POLYGONAL);
if( openingFileMask & tri::io::Mask::IOM_VERTTEXCOORD )
updateDataMask(MM_VERTTEXCOORD);
if( openingFileMask & tri::io::Mask::IOM_WEDGTEXCOORD )
updateDataMask(MM_WEDGTEXCOORD);
if( openingFileMask & tri::io::Mask::IOM_VERTCOLOR )
updateDataMask(MM_VERTCOLOR);
if( openingFileMask & tri::io::Mask::IOM_FACECOLOR )
updateDataMask(MM_FACECOLOR);
if( openingFileMask & tri::io::Mask::IOM_VERTRADIUS ) updateDataMask(MM_VERTRADIUS);
if( openingFileMask & tri::io::Mask::IOM_CAMERA ) updateDataMask(MM_CAMERA);
if( openingFileMask & tri::io::Mask::IOM_VERTQUALITY ) updateDataMask(MM_VERTQUALITY);
if( openingFileMask & tri::io::Mask::IOM_FACEQUALITY ) updateDataMask(MM_FACEQUALITY);
if( openingFileMask & tri::io::Mask::IOM_BITPOLYGONAL ) updateDataMask(MM_POLYGONAL);
}
bool MeshModel::meshModified() const
@ -222,5 +352,5 @@ void MeshModel::setMeshModified(bool b)
int MeshModel::dataMask() const
{
return currentDataMask;
return currentDataMask;
}

View File

@ -2,7 +2,7 @@
* MeshLab o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2020 \/)\/ *
* Copyright(C) 2004-2021 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
@ -21,8 +21,8 @@
* *
****************************************************************************/
#ifndef MESHMODEL_H
#define MESHMODEL_H
#ifndef MESH_MODEL_H
#define MESH_MODEL_H
#include <GL/glew.h>
#include <stdio.h>
@ -30,6 +30,9 @@
#include <map>
#include "cmesh.h"
#include "../GLLogStream.h"
#include "../filterscript.h"
#include "../ml_shared_data_context/ml_plugin_gl_context.h"
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/color.h>
@ -40,11 +43,6 @@
#include <vcg/complex/algorithms/update/selection.h>
#include <vcg/complex/algorithms/update/topology.h>
//#include <wrap/gl/trimesh.h>
#include <wrap/callback.h>
#include <wrap/io_trimesh/io_mask.h>
#include <wrap/io_trimesh/additionalinfo.h>
@ -56,10 +54,6 @@
#include <QReadWriteLock>
#include <QImage>
#include <QAction>
#include "../GLLogStream.h"
#include "../filterscript.h"
#include "../ml_shared_data_context/ml_plugin_gl_context.h"
/*
MeshModel Class
The base class for representing a single mesh.
@ -71,169 +65,149 @@ class MeshDocument;
class MeshModel
{
public:
/*
This enum specify the various simplex components
It is used in various parts of the framework:
- to know what elements are currently active and therefore can be saved on a file
- to know what elements are required by a filter and therefore should be made ready before starting the filter (e.g. if a
- to know what elements are changed by a filter and therefore should be saved/restored in case of dynamic filters with a preview
*/
enum MeshElement{
MM_NONE = 0x00000000,
MM_VERTCOORD = 0x00000001,
MM_VERTNORMAL = 0x00000002,
MM_VERTFLAG = 0x00000004,
MM_VERTCOLOR = 0x00000008,
MM_VERTQUALITY = 0x00000010,
MM_VERTMARK = 0x00000020,
MM_VERTFACETOPO = 0x00000040,
MM_VERTCURV = 0x00000080,
MM_VERTCURVDIR = 0x00000100,
MM_VERTRADIUS = 0x00000200,
MM_VERTTEXCOORD = 0x00000400,
MM_VERTNUMBER = 0x00000800,
/*
This enum specify the various simplex components
It is used in various parts of the framework:
- to know what elements are currently active and therefore can be saved on a file
- to know what elements are required by a filter and therefore should be made ready before starting the filter (e.g. if a
- to know what elements are changed by a filter and therefore should be saved/restored in case of dynamic filters with a preview
*/
enum MeshElement{
MM_NONE = 0x00000000,
MM_VERTCOORD = 0x00000001,
MM_VERTNORMAL = 0x00000002,
MM_VERTFLAG = 0x00000004,
MM_VERTCOLOR = 0x00000008,
MM_VERTQUALITY = 0x00000010,
MM_VERTMARK = 0x00000020,
MM_VERTFACETOPO = 0x00000040,
MM_VERTCURV = 0x00000080,
MM_VERTCURVDIR = 0x00000100,
MM_VERTRADIUS = 0x00000200,
MM_VERTTEXCOORD = 0x00000400,
MM_VERTNUMBER = 0x00000800,
MM_FACEVERT = 0x00001000,
MM_FACENORMAL = 0x00002000,
MM_FACEFLAG = 0x00004000,
MM_FACECOLOR = 0x00008000,
MM_FACEQUALITY = 0x00010000,
MM_FACEMARK = 0x00020000,
MM_FACEFACETOPO = 0x00040000,
MM_FACENUMBER = 0x00080000,
MM_FACECURVDIR = 0x00100000,
MM_FACEVERT = 0x00001000,
MM_FACENORMAL = 0x00002000,
MM_FACEFLAG = 0x00004000,
MM_FACECOLOR = 0x00008000,
MM_FACEQUALITY = 0x00010000,
MM_FACEMARK = 0x00020000,
MM_FACEFACETOPO = 0x00040000,
MM_FACENUMBER = 0x00080000,
MM_FACECURVDIR = 0x00100000,
MM_WEDGTEXCOORD = 0x00200000,
MM_WEDGNORMAL = 0x00400000,
MM_WEDGCOLOR = 0x00800000,
MM_WEDGTEXCOORD = 0x00200000,
MM_WEDGNORMAL = 0x00400000,
MM_WEDGCOLOR = 0x00800000,
// Selection
MM_VERTFLAGSELECT = 0x01000000,
MM_FACEFLAGSELECT = 0x02000000,
// Selection
MM_VERTFLAGSELECT = 0x01000000,
MM_FACEFLAGSELECT = 0x02000000,
// Per Mesh Stuff....
MM_CAMERA = 0x08000000,
MM_TRANSFMATRIX = 0x10000000,
MM_COLOR = 0x20000000,
MM_POLYGONAL = 0x40000000,
// Per Mesh Stuff....
MM_CAMERA = 0x08000000,
MM_TRANSFMATRIX = 0x10000000,
MM_COLOR = 0x20000000,
MM_POLYGONAL = 0x40000000,
// unknown - will raise exceptions, to be avoided, here just for compatibility
MM_UNKNOWN = 0x80000000,
MM_UNKNOWN = 0x80000000,
// geometry change (for filters that remove stuff or modify geometry or topology, but not touch face/vertex color or face/vertex quality)
MM_GEOMETRY_AND_TOPOLOGY_CHANGE = 0x431e7be7,
MM_GEOMETRY_AND_TOPOLOGY_CHANGE = 0x431e7be7,
// everything - dangerous, will add unwanted data to layer (e.g. if you use MM_ALL it could means that it could add even color or quality)
MM_ALL = 0xffffffff
};
MM_ALL = 0xffffffff
};
MeshModel(MeshDocument *parent, unsigned int id, const QString& fullFileName, const QString& labelName);
~MeshModel()
{
}
MeshModel(unsigned int id, const QString& fullFileName, const QString& labelName);
~MeshModel()
{
}
MeshDocument *parent;
void clear();
void updateBoxAndNormals(); // This is the STANDARD method that you should call after changing coords.
inline unsigned int id() const {return _id;}
CMeshO cm;
int idInFile() const {return idInsideFile;}
void setIdInFile(int id) {idInsideFile = id;}
// Some notes about the files and naming.
// Each mesh when shown in the layer dialog has a label.
// By default the label is just the name of the file, but the
// in a future the path should be moved outside the meshmodel into the meshdocument (and assume that all the meshes resides in a common subtree)
// currently we just fix the interface and make the pathname private for avoiding future hassles.
QString label() const { if(_label.isEmpty()) return shortName(); else return _label;}
/// The whole full path name of the mesh
QString fullName() const {return fullPathFileName;}
/// just the name of the file
QString shortName() const { return QFileInfo(fullPathFileName).fileName(); }
/// the full path without the name of the file (e.g. the dir where the mesh and often its textures are)
QString pathName() const {QFileInfo fi(fullName()); return fi.absolutePath();}
/// just the extension.
QString suffixName() const {QFileInfo fi(fullName()); return fi.suffix();}
/// the relative path with respect to the current project
QString relativePathName(const QString& path) const;
void setFileName(QString newFileName) {
QFileInfo fi(newFileName);
if(!fi.isAbsolute()) qWarning("Someone is trying to put a non relative filename");
fullPathFileName = fi.absoluteFilePath();
}
void setLabel(QString newName) {_label=newName;}
bool visible; // used in rendering; Needed for toggling on and off the meshes
bool isVisible() const { return visible; }
std::list<std::string> loadTextures(GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr);
void saveTextures(const QString& basePath, int quality = 66, GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr);
QImage getTexture(const std::string& tn) const;
void clearTextures();
void addTexture(std::string name, const QImage& txt);
void setTexture(std::string name, const QImage& txt);
void changeTextureName(const std::string& oldName, std::string newName);
// This function is roughly equivalent to the updateDataMask,
// but it takes in input a mask coming from a filetype instead of a filter requirement (like topology etc)
void enable(int openingFileMask);
bool hasDataMask(const int maskToBeTested) const;
void updateDataMask();
void updateDataMask(const MeshModel* m);
void updateDataMask(int neededDataMask);
void clearDataMask(int unneededDataMask);
int dataMask() const;
bool meshModified() const;
void setMeshModified(bool b = true);
static int io2mm(int single_iobit);
/*vcg::GlTrimesh<CMeshO> glw;*/
/*
Bitmask denoting what fields are currently used in the mesh
it is composed by MeshElement enums.
it should be changed by only mean the following functions:
updateDataMask(neededStuff)
clearDataMask(no_needed_stuff)
hasDataMask(stuff)
Note that if an element is active means that is also allocated
Some unactive elements (vertex color) are usually already allocated
other elements (FFAdj or curvature data) not necessarily.
*/
CMeshO cm;
private:
int currentDataMask;
QString fullPathFileName;
QString _label;
unsigned int _id;
bool modified;
int currentDataMask;
QString fullPathFileName;
QString _label;
unsigned int _id;
bool modified;
//this is an id used for meshes that are loaded from files
//that can store more than one mesh. For meshes loaded from
//files containing just this mesh, this id will be -1.
int idInsideFile;
public:
void Clear();
void UpdateBoxAndNormals(); // This is the STANDARD method that you should call after changing coords.
inline int id() const {return _id;}
int idInFile() const {return idInsideFile;}
void setIdInFile(int id) {idInsideFile = id;}
// Some notes about the files and naming.
// Each mesh when shown in the layer dialog has a label.
// By default the label is just the name of the file, but the
// in a future the path should be moved outside the meshmodel into the meshdocument (and assume that all the meshes resides in a common subtree)
// currently we just fix the interface and make the pathname private for avoiding future hassles.
QString label() const { if(_label.isEmpty()) return shortName(); else return _label;}
/// The whole full path name of the mesh
QString fullName() const {return fullPathFileName;}
/// just the name of the file
QString shortName() const { return QFileInfo(fullPathFileName).fileName(); }
/// the full path without the name of the file (e.g. the dir where the mesh and often its textures are)
QString pathName() const {QFileInfo fi(fullName()); return fi.absolutePath();}
/// just the extension.
QString suffixName() const {QFileInfo fi(fullName()); return fi.suffix();}
/// the relative path with respect to the current project
QString relativePathName() const;
/// the absolute path of the current project
QString documentPathName() const;
void setFileName(QString newFileName) {
QFileInfo fi(newFileName);
if(!fi.isAbsolute()) qWarning("Someone is trying to put a non relative filename");
fullPathFileName = fi.absoluteFilePath();
}
void setLabel(QString newName) {_label=newName;}
bool visible; // used in rendering; Needed for toggling on and off the meshes
bool isVisible() const { return visible; }
// This function is roughly equivalent to the updateDataMask,
// but it takes in input a mask coming from a filetype instead of a filter requirement (like topology etc)
void Enable(int openingFileMask);
bool hasDataMask(const int maskToBeTested) const;
void updateDataMask(MeshModel *m);
void updateDataMask(int neededDataMask);
void clearDataMask(int unneededDataMask);
int dataMask() const;
bool meshModified() const;
void setMeshModified(bool b = true);
static int io2mm(int single_iobit);
//textures associated to mesh
std::map<std::string, QImage> textures;
};// end class MeshModel
#endif

View File

@ -38,6 +38,16 @@ RasterPlane::RasterPlane(const QString& pathName, const int _semantic)
image = QImage(pathName);
}
RasterPlane::RasterPlane(
const QImage& img,
const QString& pathName,
const int _semantic)
{
semantic =_semantic;
fullPathFileName = pathName;
image = img;
}
MeshLabRenderRaster::MeshLabRenderRaster()
{

View File

@ -58,7 +58,6 @@ public:
int semantic;
QString fullPathFileName;
QImage image;
QImage thumb;
float *buf;
bool IsInCore() { return !image.isNull(); }
@ -72,6 +71,7 @@ public:
RasterPlane(const RasterPlane& pl);
RasterPlane(const QString& pathName, const int _semantic);
RasterPlane(const QImage& image, const QString& pathName, const int _semantic);
}; //end class Plane

View File

@ -134,11 +134,15 @@ void MLPoliciesStandAloneFunctions::maskMeaninglessAttributesPerPrimitiveModalit
}
}
void MLPoliciesStandAloneFunctions::updatedRendAttsAccordingToPriorities(const MLRenderingData::PRIMITIVE_MODALITY pm,const MLRenderingData::RendAtts& updated,const MLRenderingData::RendAtts& current,MLRenderingData::RendAtts& result)
void MLPoliciesStandAloneFunctions::updatedRendAttsAccordingToPriorities(
const MLRenderingData::PRIMITIVE_MODALITY pm,
const MLRenderingData::RendAtts& updated, //from the result of the filter
const MLRenderingData::RendAtts& current, //from the current model
MLRenderingData::RendAtts& result) //returned final result
{
MLRenderingData::RendAtts filteredupdated = updated;
MLRenderingData::RendAtts tmp = current;
tmp[MLRenderingData::ATT_NAMES::ATT_VERTPOSITION] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTPOSITION];
MLRenderingData::RendAtts filteredupdated = updated;
MLRenderingData::RendAtts tmp = current; // tmp will be then saved in returned
tmp[MLRenderingData::ATT_NAMES::ATT_VERTPOSITION] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTPOSITION];
if ((pm == MLRenderingData::PR_WIREFRAME_TRIANGLES) || (pm == MLRenderingData::PR_WIREFRAME_EDGES))
{
tmp[MLRenderingData::ATT_NAMES::ATT_VERTNORMAL] = false;
@ -146,15 +150,17 @@ void MLPoliciesStandAloneFunctions::updatedRendAttsAccordingToPriorities(const M
}
else
{
//vert normal shading if in current or in updated
tmp[MLRenderingData::ATT_NAMES::ATT_VERTNORMAL] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTNORMAL];
tmp[MLRenderingData::ATT_NAMES::ATT_FACENORMAL] = (tmp[MLRenderingData::ATT_NAMES::ATT_FACENORMAL] || filteredupdated[MLRenderingData::ATT_NAMES::ATT_FACENORMAL]) && !(filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTNORMAL]);
//face normal shading if in current or in updated
tmp[MLRenderingData::ATT_NAMES::ATT_FACENORMAL] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_FACENORMAL];
}
tmp[MLRenderingData::ATT_NAMES::ATT_VERTCOLOR] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTCOLOR];
tmp[MLRenderingData::ATT_NAMES::ATT_FACECOLOR] = (tmp[MLRenderingData::ATT_NAMES::ATT_FACECOLOR] || filteredupdated[MLRenderingData::ATT_NAMES::ATT_FACECOLOR]) && !(filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTCOLOR]);
tmp[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE];
tmp[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE] = (tmp[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE] || filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE]) && !(filteredupdated[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE]);
result = tmp;
tmp[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE] |= filteredupdated[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE];
tmp[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE] = (tmp[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE] || filteredupdated[MLRenderingData::ATT_NAMES::ATT_VERTTEXTURE]) && !(filteredupdated[MLRenderingData::ATT_NAMES::ATT_WEDGETEXTURE]);
result = tmp;
}
void MLPoliciesStandAloneFunctions::suggestedDefaultPerViewRenderingData(MeshModel* meshmodel,MLRenderingData& dtout, size_t minpolnumpersmoothshading)

View File

@ -73,6 +73,11 @@ const QString& RichParameter::toolTip() const
return tooltip;
}
void RichParameter::setName(const QString& newName)
{
pName = newName;
}
void RichParameter::setValue(const Value& ov)
{
assert(val->typeName() == ov.typeName());
@ -572,39 +577,17 @@ bool RichSaveFile::operator==( const RichParameter& rb )
RichMesh::RichMesh(
const QString& nm,
MeshModel* defval,
MeshDocument* doc,
unsigned int meshind,
const MeshDocument* doc,
const QString& desc,
const QString& tltip ):
RichParameter(nm, MeshValue(defval), desc, tltip), meshdoc(doc)
RichParameter(nm,MeshValue(meshind), desc, tltip), meshdoc(doc)
{
meshindex = -1;
if (meshdoc != nullptr)
meshindex = meshdoc->meshList.indexOf(defval);
assert((meshindex != -1) || (meshdoc == nullptr));
}
RichMesh::RichMesh(
const QString& nm,
int meshind,
MeshDocument* doc,
const QString& desc,
const QString& tltip ):
RichParameter(nm,MeshValue(doc, meshind), desc, tltip), meshdoc(doc)
RichMesh::RichMesh(const QString& nm, unsigned int meshind, const QString& desc, const QString& tltip):
RichParameter(nm, MeshValue(meshind), desc, tltip), meshdoc(nullptr)
{
assert(meshind < meshdoc->size() && meshind >= 0);
meshindex = meshind;
if (meshdoc != nullptr)
val = new MeshValue(meshdoc->meshList.at(meshindex));
else
val = nullptr;
}
RichMesh::RichMesh(const QString& nm, int meshind, const QString& desc, const QString& tltip):
RichParameter(nm, MeshValue(nullptr), desc, tltip)
{
meshdoc = nullptr;
meshindex = meshind;
}
RichMesh::~RichMesh()
@ -619,7 +602,7 @@ QString RichMesh::stringType() const
QDomElement RichMesh::fillToXMLDocument(QDomDocument& doc, bool saveDescriptionAndTooltip) const
{
QDomElement parElem = RichParameter::fillToXMLDocument(doc, saveDescriptionAndTooltip);
parElem.setAttribute("value", QString::number(meshindex));
parElem.setAttribute("value", QString::number(val->getMeshId()));
return parElem;
}
@ -630,7 +613,7 @@ RichMesh* RichMesh::clone() const
bool RichMesh::operator==( const RichParameter& rb )
{
return (rb.value().isMesh() &&(pName == rb.name()) && (value().getMesh() == rb.value().getMesh()));
return (rb.value().isMesh() &&(pName == rb.name()) && (value().getMeshId() == rb.value().getMeshId()));
}
/**** RichParameterAdapter Class ****/

View File

@ -59,6 +59,7 @@ public:
virtual QString stringType() const = 0;
void setName(const QString& newName);
void setValue(const Value& ov);
virtual QDomElement fillToXMLDocument(QDomDocument& doc, bool saveDescriptionAndTooltip = true) const;
@ -251,10 +252,9 @@ public:
class RichMesh : public RichParameter
{
public:
RichMesh(const QString& nm, MeshModel* defval, MeshDocument* doc, const QString& desc = QString(), const QString& tltip = QString());
RichMesh(const QString& nm, int meshindex, MeshDocument* doc, const QString& desc = QString(), const QString& tltip = QString());
RichMesh(const QString& nm, unsigned int meshindex, const MeshDocument* doc, const QString& desc = QString(), const QString& tltip = QString());
//WARNING: IT SHOULD BE USED ONLY BY MESHLABSERVER!!!!!!!
RichMesh(const QString& nm, int meshind, const QString& desc = QString(), const QString& tltip = QString());
RichMesh(const QString& nm, unsigned int meshind, const QString& desc = QString(), const QString& tltip = QString());
~RichMesh();
QString stringType() const;
@ -262,8 +262,7 @@ public:
RichMesh* clone() const;
bool operator==(const RichParameter& rb);
MeshDocument* meshdoc;
int meshindex;
const MeshDocument* meshdoc;
};
class RichParameterAdapter

View File

@ -24,6 +24,7 @@
#include "rich_parameter_list.h"
#include "../mlexception.h"
#include "../ml_document/mesh_document.h"
#include <vcg/math/matrix44.h>
#include <wrap/qt/col_qt_convert.h>
@ -194,9 +195,9 @@ int RichParameterList::getEnum(const QString& name) const
* @return the mesh of the RichParameter having the given name.
* @throws an MLException if the name is not found in the list
*/
MeshModel * RichParameterList::getMesh(const QString& name) const
unsigned int RichParameterList::getMeshId(const QString& name) const
{
return getParameterByName(name).value().getMesh();
return getParameterByName(name).value().getMeshId();
}
/**

View File

@ -108,7 +108,7 @@ public:
vcg::Color4b getColor4b(const QString& name) const;
Scalarm getAbsPerc(const QString& name) const;
int getEnum(const QString& name) const;
MeshModel* getMesh(const QString& name) const;
unsigned int getMeshId(const QString& name) const;
Scalarm getDynamicFloat(const QString& name) const;
QString getOpenFileName(const QString& name) const;
QString getSaveFileName(const QString& name) const;

View File

@ -31,14 +31,6 @@ void BoolValue::fillToXMLElement(QDomElement& element) const
element.setAttribute("value", v);
}
MeshValue::MeshValue(MeshDocument* doc, int meshind)
{
if (doc != nullptr)
pval = doc->meshList.at(meshind);
else
pval = nullptr;
}
void IntValue::fillToXMLElement(QDomElement& element) const
{
element.setAttribute("value", QString::number(pval));

View File

@ -53,7 +53,7 @@ public:
virtual QColor getColor() const { assert(0); return QColor(); }
virtual Scalarm getAbsPerc() const { assert(0); return Scalarm(); }
virtual int getEnum() const { assert(0); return int(); }
virtual MeshModel* getMesh() const { assert(0); return NULL; }
virtual unsigned int getMeshId() const { assert(0); return 0; }
virtual Scalarm getDynamicFloat() const { assert(0); return Scalarm(); }
virtual QString getFileName() const { assert(0); return QString(); }
@ -275,19 +275,18 @@ private:
class MeshValue : public Value
{
public:
MeshValue(MeshModel* mesh) : pval(mesh) {}
MeshValue(MeshDocument* doc, int meshind);
MeshValue(unsigned int meshind) : pval(meshind) {};
~MeshValue() {}
inline MeshModel* getMesh() const { return pval; }
inline unsigned int getMeshId() const { return pval; }
inline bool isMesh() const { return true; }
inline QString typeName() const { return QString("Mesh"); }
inline void set(const Value& p) { pval = p.getMesh(); }
inline void set(const Value& p) { pval = p.getMeshId(); }
inline MeshValue* clone() const {return new MeshValue(*this);}
void fillToXMLElement(QDomElement& element) const;
private:
MeshModel* pval;
unsigned int pval;
};
#endif //MESHLAB_VALUE_H

View File

@ -35,9 +35,6 @@ void DecoratePluginContainer::clear()
void DecoratePluginContainer::pushDecoratePlugin(DecoratePlugin* iDecorate)
{
decoratePlugins.push_back(iDecorate);
for(QAction *decoratorAction : iDecorate->actions()) {
iDecorate->initGlobalParameterList(decoratorAction, meshlab::defaultGlobalParameterList());
}
}
void DecoratePluginContainer::eraseDecoratePlugin(DecoratePlugin* iDecorate)

View File

@ -14,7 +14,7 @@ void IOPluginContainer::clear()
ioPlugins.clear();
inputMeshFormatToPluginMap.clear();
outputMeshFormatToPluginMap.clear();
inputRasterFormatToPluginMap.clear();
inputImageFormatToPluginMap.clear();
}
void IOPluginContainer::pushIOPlugin(IOPlugin* iIO)
@ -39,11 +39,38 @@ void IOPluginContainer::pushIOPlugin(IOPlugin* iIO)
}
}
//add input raster formats to inputFormatMap
for (const FileFormat& ff : iIO->importRasterFormats()){
//add input image formats to inputFormatMap
for (const FileFormat& ff : iIO->importImageFormats()){
for (const QString& currentExtension : ff.extensions) {
if (! inputRasterFormatToPluginMap.contains(currentExtension.toLower())) {
inputRasterFormatToPluginMap.insert(currentExtension.toLower(), iIO);
if (! inputImageFormatToPluginMap.contains(currentExtension.toLower())) {
inputImageFormatToPluginMap.insert(currentExtension.toLower(), iIO);
}
}
}
//add output image formats to inputFormatMap
for (const FileFormat& ff : iIO->exportImageFormats()){
for (const QString& currentExtension : ff.extensions) {
if (! outputImageFormatToPluginMap.contains(currentExtension.toLower())) {
outputImageFormatToPluginMap.insert(currentExtension.toLower(), iIO);
}
}
}
//add input project formats to inputFormatMap
for (const FileFormat& ff : iIO->importProjectFormats()){
for (const QString& currentExtension : ff.extensions) {
if (! inputProjectFormatToPluginMap.contains(currentExtension.toLower())) {
inputProjectFormatToPluginMap.insert(currentExtension.toLower(), iIO);
}
}
}
//add output project formats to inputFormatMap
for (const FileFormat& ff : iIO->exportProjectFormats()){
for (const QString& currentExtension : ff.extensions) {
if (! outputProjectFormatToPluginMap.contains(currentExtension.toLower())) {
outputProjectFormatToPluginMap.insert(currentExtension.toLower(), iIO);
}
}
}
@ -62,9 +89,9 @@ void IOPluginContainer::eraseIOPlugin(IOPlugin* iIO)
outputMeshFormatToPluginMap.remove(currentExtension.toLower());
}
}
for (const FileFormat& ff : iIO->importRasterFormats()){
for (const FileFormat& ff : iIO->importImageFormats()){
for (const QString& currentExtension : ff.extensions) {
inputRasterFormatToPluginMap.remove(currentExtension.toLower());
inputImageFormatToPluginMap.remove(currentExtension.toLower());
}
}
}
@ -79,9 +106,24 @@ bool IOPluginContainer::isOutputMeshFormatSupported(const QString& outputFormat)
return outputMeshFormatToPluginMap.find(outputFormat.toLower()) != outputMeshFormatToPluginMap.end();
}
bool IOPluginContainer::isInputRasterFormatSupported(const QString& inputFormat) const
bool IOPluginContainer::isInputImageFormatSupported(const QString& inputFormat) const
{
return inputRasterFormatToPluginMap.find(inputFormat.toLower()) != inputRasterFormatToPluginMap.end();
return inputImageFormatToPluginMap.find(inputFormat.toLower()) != inputImageFormatToPluginMap.end();
}
bool IOPluginContainer::isOutputImageFormatSupported(const QString& outputFormat) const
{
return outputImageFormatToPluginMap.find(outputFormat.toLower()) != outputImageFormatToPluginMap.end();
}
bool IOPluginContainer::isInputProjectFormatSupported(const QString& inputFormat) const
{
return inputProjectFormatToPluginMap.find(inputFormat.toLower()) != inputProjectFormatToPluginMap.end();
}
bool IOPluginContainer::isOutputProjectFormatSupported(const QString& outputFormat) const
{
return outputImageFormatToPluginMap.find(outputFormat.toLower()) != outputProjectFormatToPluginMap.end();
}
IOPlugin* IOPluginContainer::inputMeshPlugin(const QString& inputFormat) const
@ -100,10 +142,34 @@ IOPlugin* IOPluginContainer::outputMeshPlugin(const QString& outputFormat) const
return nullptr;
}
IOPlugin* IOPluginContainer::inputRasterPlugin(const QString& inputFormat) const
IOPlugin* IOPluginContainer::inputImagePlugin(const QString& inputFormat) const
{
auto it = inputRasterFormatToPluginMap.find(inputFormat.toLower());
if (it != inputRasterFormatToPluginMap.end())
auto it = inputImageFormatToPluginMap.find(inputFormat.toLower());
if (it != inputImageFormatToPluginMap.end())
return *it;
return nullptr;
}
IOPlugin* IOPluginContainer::outputImagePlugin(const QString& outputFormat) const
{
auto it = outputImageFormatToPluginMap.find(outputFormat.toLower());
if (it != outputImageFormatToPluginMap.end())
return *it;
return nullptr;
}
IOPlugin* IOPluginContainer::inputProjectPlugin(const QString& inputFormat) const
{
auto it = inputProjectFormatToPluginMap.find(inputFormat.toLower());
if (it != inputProjectFormatToPluginMap.end())
return *it;
return nullptr;
}
IOPlugin* IOPluginContainer::outputProjectPlugin(const QString& outputFormat) const
{
auto it = outputProjectFormatToPluginMap.find(outputFormat.toLower());
if (it != outputProjectFormatToPluginMap.end())
return *it;
return nullptr;
}
@ -118,9 +184,24 @@ QStringList IOPluginContainer::outputMeshFormatList() const
return outputMeshFormatToPluginMap.keys();
}
QStringList IOPluginContainer::inputRasterFormatList() const
QStringList IOPluginContainer::inputImageFormatList() const
{
return inputRasterFormatToPluginMap.keys();
return inputImageFormatToPluginMap.keys();
}
QStringList IOPluginContainer::outputImageFormatList() const
{
return outputImageFormatToPluginMap.keys();
}
QStringList IOPluginContainer::inputProjectFormatList() const
{
return inputProjectFormatToPluginMap.keys();
}
QStringList IOPluginContainer::outputProjectFormatList() const
{
return outputProjectFormatToPluginMap.keys();
}
IOPluginContainer::IOPluginRangeIterator IOPluginContainer::ioPluginIterator(bool iterateAlsoDisabledPlugins) const

View File

@ -47,14 +47,24 @@ public:
bool isInputMeshFormatSupported(const QString& inputFormat) const;
bool isOutputMeshFormatSupported(const QString& outputFormat) const;
bool isInputRasterFormatSupported(const QString& inputFormat) const;
bool isInputImageFormatSupported(const QString& inputFormat) const;
bool isOutputImageFormatSupported(const QString& outputFormat) const;
bool isInputProjectFormatSupported(const QString& inputFormat) const;
bool isOutputProjectFormatSupported(const QString& outputFormat) const;
IOPlugin* inputMeshPlugin(const QString& inputFormat) const;
IOPlugin* outputMeshPlugin(const QString& outputFormat) const;
IOPlugin* inputRasterPlugin(const QString& inputFormat) const;
IOPlugin* inputImagePlugin(const QString& inputFormat) const;
IOPlugin* outputImagePlugin(const QString& outputFormat) const;
IOPlugin* inputProjectPlugin(const QString& inputFormat) const;
IOPlugin* outputProjectPlugin(const QString& outputFormat) const;
QStringList inputMeshFormatList() const;
QStringList outputMeshFormatList() const;
QStringList inputRasterFormatList() const;
QStringList inputImageFormatList() const;
QStringList outputImageFormatList() const;
QStringList inputProjectFormatList() const;
QStringList outputProjectFormatList() const;
IOPluginRangeIterator ioPluginIterator(bool iterateAlsoDisabledPlugins = false) const;
@ -62,7 +72,10 @@ private:
std::vector<IOPlugin*> ioPlugins;
QMap<QString,IOPlugin*> inputMeshFormatToPluginMap;
QMap<QString,IOPlugin*> outputMeshFormatToPluginMap;
QMap<QString,IOPlugin*> inputRasterFormatToPluginMap;
QMap<QString,IOPlugin*> inputImageFormatToPluginMap;
QMap<QString,IOPlugin*> outputImageFormatToPluginMap;
QMap<QString,IOPlugin*> inputProjectFormatToPluginMap;
QMap<QString,IOPlugin*> outputProjectFormatToPluginMap;
};
class IOPluginContainer::IOPluginRangeIterator

View File

@ -98,7 +98,8 @@ public:
* This string is printed in the top of the parameter window
* so it should be at least one or two paragraphs long. The more the better.
* you can use simple html formatting tags (like "<br>" "<b>" and "<i>") to improve readability.
* This string is used in the 'About plugin' dialog and by meshlabserver to create the filter list wiki page and the doxygen documentation of the filters.
* This string is used in the 'About plugin' dialog and by pymeshlab to create
* the filter list documentation page of the filters.
* Here is the place where you should put you bibliographic references in a form like this:
* <br>
* See: <br />
@ -128,7 +129,7 @@ public:
* to MeshModel::updateDataMask(...)
*/
virtual int getRequirements(const QAction*) { return MeshModel::MM_NONE; }
/**
* @brief This function should require true if the glContext is used by the
* filter. Without this, the glContext will remain set to nullptr on non-GUI
@ -156,6 +157,23 @@ public:
*/
virtual int postCondition(const QAction*) const { return MeshModel::MM_ALL; }
/**
* @brief This function is called to initialized the list of parameters.
* If a filter does not need parameters, do not implement this function and
* the framework will not create a dialog (unless for previewing).
* You can implement the one which takes the MeshModel or the one that
* takes the MeshDocument, depending of your needings, but do not re-implement
* both the functions.
*/
virtual RichParameterList initParameterList(const QAction*, const MeshModel &/*m*/)
{
return RichParameterList();
}
virtual RichParameterList initParameterList(const QAction* filter, const MeshDocument &md)
{
return initParameterList(filter, *(md.mm()));
}
/**
* @brief applies the selected filter with the already stabilished parameters
* This function is called by the framework after getting values for the parameters specified in the \ref initParameterList
@ -198,17 +216,6 @@ public:
*/
virtual FilterArity filterArity(const QAction *act) const = 0;
/**
* @brief This function is called to initialized the list of parameters.
* it is always called. If a filter does not need parameter it leave it empty and the framework
* will not create a dialog (unless for previewing)
*/
virtual void initParameterList(const QAction*, MeshModel &/*m*/, RichParameterList & /*par*/) {}
virtual void initParameterList(const QAction* filter, MeshDocument &md, RichParameterList &par)
{
initParameterList(filter, *(md.mm()), par);
}
virtual QString filterInfo(const QAction* a) const { return this->filterInfo(ID(a)); }
virtual QString filterName(const QAction* a) const { return this->filterName(ID(a)); }
virtual QString pythonFilterName(const QAction* a) const {return this->pythonFilterName(ID(a)); }

View File

@ -3,21 +3,12 @@
unsigned int IOPlugin::numberMeshesContainedInFile(
const QString&,
const QString&) const
const QString&,
const RichParameterList&) const
{
return 1;
}
void IOPlugin::initOpenParameter(const QString& format, const std::list<MeshModel*>& ml, RichParameterList& params)
{
initOpenParameter(format, *ml.front(), params);
}
void IOPlugin::applyOpenParameter(const QString& format, const std::list<MeshModel*>& ml, const RichParameterList& params)
{
applyOpenParameter(format, *ml.front(), params);
}
void IOPlugin::open(
const QString& format,
const QString& fileName,

View File

@ -31,8 +31,27 @@
#include "../../utilities/file_format.h"
#include "../../ml_document/raster_model.h"
class MLRenderingData;
/**
* @brief The IOPlugin is the base class for all the single mesh loading plugins.
* @brief The IOPlugin is the base class for meshes, images and projects loading
* and saving.
*
* Provides the base functions to open:
* - a mesh file (open);
* - a project file (openProject);
* - an image file (openImage);
*
* and the base functions to save:
* - a mesh file (save);
* - a project file (saveProject);
* - an image file (saveImage);
*
* You can tell which formats your plugin will be able to open or save by
* re-implementing the following functions
* - import<type>Formats()
* - export<type>Formats()
* where <type> can be [todo] Mesh, Image or Project.
*/
class IOPlugin : virtual public MeshLabPlugin, virtual public MeshLabPluginLogger
{
@ -40,6 +59,10 @@ public:
IOPlugin() : MeshLabPluginLogger() { }
virtual ~IOPlugin() { }
/***********************
* Open Mesh Functions *
***********************/
/**
* @brief The importFormats function returns a list of all the
* input file formats supported by the plugin.
@ -49,28 +72,9 @@ public:
*/
virtual std::list<FileFormat> importFormats() const = 0;
/**
* @brief The exportFormats function returns a list of all the
* output file formats supported by the plugin.
* This function must be implemented on any IO plugin.
* If yout plugin does not export any mesh format, just return an
* empty list.
*/
virtual std::list<FileFormat> exportFormats() const = 0;
/**
* @brief If yout plugin supports loading also raster formats, re-implement
* this function, returning the list of raster formats supported by
* your openRaster function.
*/
virtual std::list<FileFormat> importRasterFormats() const
{
return std::list<FileFormat>();
}
/**
* @brief The initPreOpenParameter function is called to initialize the list
* of additional parameters that a OPENING filter could require. It is
* of additional parameters that opening a mesh format could require. It is
* called by the framework BEFORE the actual mesh loading to determine how
* to parse the input file. The instanced parameters are then passed to the
* open at the loading time.
@ -78,78 +82,12 @@ public:
* load. If you do not need any additional processing simply do not override
* this and ignore the parameterList in the open member function
*/
virtual void initPreOpenParameter(
const QString& /*format*/,
RichParameterList& /*parameters*/)
virtual RichParameterList initPreOpenParameter(
const QString& /*format*/) const
{
return RichParameterList();
}
virtual void initOpenParameter(
const QString& /*format*/,
const std::list<MeshModel*>& /*m*/,
RichParameterList& /*parameters*/);
/**
* @brief The initOpenParameter function is called to initialize the list
* of additional parameters that a OPENING filter could require.
* It is called by the framework AFTER the mesh is already loaded to
* perform more or less standard processing on the mesh.
* typical example: unifying vertices in stl models.
* If you do not need any additional processing do nothing.
*/
virtual void initOpenParameter(
const QString& /*format*/,
MeshModel& /*m*/,
RichParameterList& /*parameters*/)
{
}
virtual void applyOpenParameter(
const QString& /*format*/,
const std::list<MeshModel*>& /*m*/,
const RichParameterList& /*parameters*/);
/**
* @brief The applyOpenParameter function is the corrispondent function to
* the initOpenParameter. It is called after the mesh is loaded,
* and it should apply the given parameters to the loaded mesh.
* If you haven't implemented the initOpenParameter member function,
* you do not need to implement this.
*/
virtual void applyOpenParameter(
const QString& /*format*/,
MeshModel& /*m*/,
const RichParameterList& /*parameters*/)
{
}
/**
* @brief The initSaveParameter function is called to initialize the list
* of additional parameters that a SAVING filter could require. It is called
* by the framework after the output format is selected by the user.
* typical example: ascii or binary format for ply or stl
* If you do not need any additional parameters, simply do not implement
* this function.
*/
virtual void initSaveParameter(
const QString& /*format*/,
const MeshModel& /*m*/,
RichParameterList& /*par*/)
{
}
/**
* @brief The exportMaskCapability function tells to the framework which
* export capabilities are supported by the given format (e.g. if the format
* supports saving face colors, vertex quality...).
* It also tells to the framework which of these export capabilities are
* set by default.
*/
virtual void exportMaskCapability(
const QString &format,
int& capability,
int& defaultBits) const = 0;
/**
* @brief this function returns the number of meshes that the open function
* is going to load from the file given as parameter. Default value is 1.
@ -171,7 +109,8 @@ public:
*/
virtual unsigned int numberMeshesContainedInFile(
const QString& format,
const QString& fileName) const;
const QString& fileName,
const RichParameterList& preParams) const;
/**
* @brief The open function is called by the framework everytime a mesh is
@ -195,12 +134,12 @@ public:
* @param cb: standard callback for reporting progress in the loading
*/
virtual void open(
const QString &format,
const QString &fileName,
const std::list<MeshModel*>& meshModelList,
std::list<int>& maskList,
const RichParameterList & par,
vcg::CallBackPos *cb = nullptr);
const QString &format,
const QString &fileName,
const std::list<MeshModel*>& meshModelList,
std::list<int>& maskList,
const RichParameterList & par,
vcg::CallBackPos *cb = nullptr);
/**
* @brief The open function is called by the framework everytime a mesh is
@ -218,12 +157,52 @@ public:
* @param cb: standard callback for reporting progress in the loading
*/
virtual void open(
const QString &format,
const QString &fileName,
MeshModel &m,
int &mask,
const RichParameterList & par,
vcg::CallBackPos *cb = nullptr) = 0;
const QString &format,
const QString &fileName,
MeshModel &m,
int &mask,
const RichParameterList & par,
vcg::CallBackPos *cb = nullptr) = 0;
/***********************
* Save Mesh Functions *
***********************/
/**
* @brief The exportFormats function returns a list of all the
* output file formats supported by the plugin.
* This function must be implemented on any IO plugin.
* If yout plugin does not export any mesh format, just return an
* empty list.
*/
virtual std::list<FileFormat> exportFormats() const = 0;
/**
* @brief The exportMaskCapability function tells to the framework which
* export capabilities are supported by the given format (e.g. if the format
* supports saving face colors, vertex quality...).
* It also tells to the framework which of these export capabilities are
* set by default.
*/
virtual void exportMaskCapability(
const QString &format,
int& capability,
int& defaultBits) const = 0;
/**
* @brief The initSaveParameter function is called to initialize the list
* of additional parameters that saving a mesh could require. It is called
* by the framework after the output format is selected by the user.
* typical example: ascii or binary format for ply or stl
* If you do not need any additional parameters, simply do not implement
* this function.
*/
virtual RichParameterList initSaveParameter(
const QString& /*format*/,
const MeshModel& /*m*/) const
{
return RichParameterList();
}
/**
* @brief The save function is called by the framework everytime a mesh is
@ -239,27 +218,188 @@ public:
* @param cb: standard callback for reporting progress in the saving
*/
virtual void save(
const QString &format,
const QString &fileName,
MeshModel &m, /** NOTE: this is going to be const MeshModel&: try to use only const functions!! **/
const int mask,
const RichParameterList & par,
vcg::CallBackPos *cb) = 0;
const QString &format,
const QString &fileName,
MeshModel &m, /** NOTE: this is going to be const MeshModel&: try to use only const functions!! **/
const int mask,
const RichParameterList & par,
vcg::CallBackPos* cb = nullptr) = 0;
/************************
* Open Image Functions *
************************/
/**
* @brief If your plugin supports raster formats, re-implement this
* function.
* @param format: the extension of the format e.g. "JPG"
* @param filename: the name of the file to be opened (including its path)
* @param rm: the raster model on which save the loaded raster
* @param cb: standard callback for reporting progress while opening
* @brief If your plugin supports loading also images, re-implement
* this function, returning the list of image formats supported by
* your openImage function.
*/
virtual void openRaster(
const QString& /*format*/,
virtual std::list<FileFormat> importImageFormats() const
{
return std::list<FileFormat>();
}
/**
* @brief The openImage function is called by the framework everytime an image
* needs to be loaded. Could be called when loading textures or rasters.
* @param format: the extension of the format, e.g. "PNG"
* @param fileName: the name of the file from which load the image (including its path)
* @param cb: standard callback for reporting progresso in the loading
* @return the loaded QImage
*/
virtual QImage openImage(
const QString& format,
const QString& /*fileName*/,
RasterModel& /*rm*/,
vcg::CallBackPos* /*cb*/ = nullptr)
{};
{
wrongOpenFormat(format);
return QImage();
};
/************************
* Save Image Functions *
************************/
/**
* @brief If your plugin supports saving also images, re-implement
* this function, returning the list of image formats supported by
* your saveImage function.
*/
virtual std::list<FileFormat> exportImageFormats() const
{
return std::list<FileFormat>();
}
/**
* @brief The saveImage function is called by the framework everytime an image
* needs to be saved (e.g. when saving a texture).
* @param format: the extension of the format, e.g. "PNG"
* @param fileName: the name of the file on which save the image (including its path)
* @param image: the image to save in the given fileName
* @param cb: standard callback for reporting progresso in the loading
*/
virtual void saveImage(
const QString& format,
const QString& /*fileName*/,
const QImage& /*image*/,
int /*quality*/ = 66,
vcg::CallBackPos* /*cb*/ = nullptr)
{
wrongSaveFormat(format);
}
/**************************
* Open Project Functions *
**************************/
/**
* @brief If your plugin supports loading also projects, re-implement
* this function, returning the list of project formats supported by
* your openProject function.
*/
virtual std::list<FileFormat> importProjectFormats() const
{
return std::list<FileFormat>();
}
/**
* @brief some project file formats require the load of more than one file
* (e.g. bundler.out requires also a txt containing raster infos).
*
* If this is your case, you should implement this returning a list of
* *FileFormats* for each additional file that should be loaded.
* Then, the framework will ask the user to select the additional required
* files. Leaving the returned list empty means that the format of the
* project does not need additional files to be loaded.
*
* The list of files will then passed to the user in the openProject.
*
* @return
*/
virtual std::list<FileFormat> projectFileRequiresAdditionalFiles(
const QString& /*format*/,
const QString& /*filename*/)
{
return std::list<FileFormat>();
};
/**
* @brief The openProject function is called by the framework everytime a
* project needs to be loaded.
*
* The function takes an list of filenames because some project files
* are composed by more than one file. In this specific case, you should
* re-implement the function projectFileRequiresAdditionalFiles.
* The number of filenames contained in the input list will be
* 1 + number of elements in the list returned by the function
* projectFileRequiresAdditionalFiles (default: 0).
*
* If the meshes contained in the project are saved in separate files and not
* into the project, you should use the functions provided into the file
* "common/utilities/load_save.h". These functions will take care to load
* a mesh with any of the formats supported by meshlab.
*
* @param format: the extension of the format, e.g. "MLP"
* @param fileName: the name of the file from which load the project (including its path)
* @param md: MeshDocument on which store the content of the loaded project
* note: the document could not be empty!
* @param rendOpt: rendering options that may be loaded from the project file,
* if it supports them. They are not required. If you can support
* rendering options, the rendOpt vector must have the same size of
* the MeshModel vector returned by the openProject function.
* @param cb: standard callback for reporting progresso in the loading
* @return the list of MeshModel that have been loaded from the given project
*/
virtual std::vector<MeshModel*> openProject(
const QString& format,
const QStringList& /*filenames*/,
MeshDocument& /*md*/,
std::vector<MLRenderingData>& /*rendOpt*/,
vcg::CallBackPos* /*cb*/ = nullptr)
{
wrongOpenFormat(format);
return std::vector<MeshModel*>();
}
/**************************
* Save Project Functions *
**************************/
/**
* @brief If your plugin supports saving also projects, re-implement
* this function, returning the list of project formats supported by
* your saveProject function.
*/
virtual std::list<FileFormat> exportProjectFormats() const
{
return std::list<FileFormat>();
}
/**
* @brief The saveProject function is called by the framework everytime a
* project is saved.
* @param format: the extension of the format e.g. "MLP"
* @param fileName: the name of the file on which save the project md
* (including its path)
* @param md: the MeshDocument to be saved in the file
* @param onlyVisibleMesh: if this parameter is set to true, only the meshes
* marked visible should be saved into the project
* @param cb: standard callback for reporting progress in the saving
*/
virtual void saveProject(
const QString& format,
const QString& /*fileName*/,
const MeshDocument& /*md*/,
bool /*onlyVisibleMeshes*/,
const std::vector<MLRenderingData>& /*rendOpt*/,
vcg::CallBackPos* /*cb*/ = nullptr)
{
wrongSaveFormat(format);
}
/***************************
* Other utility Functions *
***************************/
/**
* @brief The reportWarning function should be used everytime that a
@ -287,14 +427,13 @@ public:
/**
* @brief The warningMessageString is invoked by the framework after the
* execution of load/save function. It returns the warning string containing
* execution of load/save functions. It returns the warning string containing
* all the warinings produced by the function, and it clears the string.
*/
QString warningMessageString() const;
private:
mutable QString warnString;
};
#define IO_PLUGIN_IID "vcg.meshlab.IOPlugin/1.0"

View File

@ -29,7 +29,6 @@
#include <vcg/complex/algorithms/create/platonic.h>
#include "meshlab_plugin_type.h"
#include "../mlexception.h"
#include "../globals.h"
@ -68,7 +67,7 @@ PluginManager::~PluginManager()
*
* Throws a MLException if the file is not a valid MeshLab plugin.
*/
void PluginManager::checkPlugin(const QString& filename)
MeshLabPluginType PluginManager::checkPlugin(const QString& filename)
{
QFileInfo fin(filename);
if (!fin.exists()){
@ -126,6 +125,7 @@ void PluginManager::checkPlugin(const QString& filename)
}
loader.unload();
return type;
}
/**
@ -184,7 +184,7 @@ void PluginManager::loadPlugins(QDir pluginsDirectory)
*
* Throws a MLException if the load of the plugin fails.
*/
void PluginManager::loadPlugin(const QString& fileName)
MeshLabPlugin* PluginManager::loadPlugin(const QString& fileName)
{
QFileInfo fin(fileName);
if (pluginFiles.find(fin.absoluteFilePath()) != pluginFiles.end())
@ -220,6 +220,7 @@ void PluginManager::loadPlugin(const QString& fileName)
allPlugins.push_back(ifp);
allPluginLoaders.push_back(loader);
pluginFiles.insert(fin.absoluteFilePath());
return ifp;
}
void PluginManager::unloadPlugin(MeshLabPlugin* ifp)
@ -300,9 +301,24 @@ IOPlugin* PluginManager::outputMeshPlugin(const QString& outputFormat) const
return ioPlugins.outputMeshPlugin(outputFormat);
}
IOPlugin* PluginManager::inputRasterPlugin(const QString inputFormat) const
IOPlugin* PluginManager::inputImagePlugin(const QString inputFormat) const
{
return ioPlugins.inputRasterPlugin(inputFormat);
return ioPlugins.inputImagePlugin(inputFormat);
}
IOPlugin* PluginManager::outputImagePlugin(const QString& outputFormat) const
{
return ioPlugins.outputImagePlugin(outputFormat);
}
IOPlugin* PluginManager::inputProjectPlugin(const QString& inputFormat) const
{
return ioPlugins.inputProjectPlugin(inputFormat);
}
IOPlugin* PluginManager::outputProjectPlugin(const QString& outputFormat) const
{
return ioPlugins.outputProjectPlugin(outputFormat);
}
bool PluginManager::isInputMeshFormatSupported(const QString inputFormat) const
@ -315,9 +331,24 @@ bool PluginManager::isOutputMeshFormatSupported(const QString outputFormat) cons
return ioPlugins.isOutputMeshFormatSupported(outputFormat);
}
bool PluginManager::isInputRasterFormatSupported(const QString inputFormat) const
bool PluginManager::isInputImageFormatSupported(const QString inputFormat) const
{
return ioPlugins.isInputRasterFormatSupported(inputFormat);
return ioPlugins.isInputImageFormatSupported(inputFormat);
}
bool PluginManager::isOutputImageFormatSupported(const QString outputFormat) const
{
return ioPlugins.isOutputImageFormatSupported(outputFormat);
}
bool PluginManager::isInputProjectFormatSupported(const QString inputFormat) const
{
return ioPlugins.isInputProjectFormatSupported(inputFormat);
}
bool PluginManager::isOutputProjectFormatSupported(const QString outputFormat) const
{
return ioPlugins.isOutputProjectFormatSupported(outputFormat);
}
QStringList PluginManager::inputMeshFormatList() const
@ -330,9 +361,24 @@ QStringList PluginManager::outputMeshFormatList() const
return ioPlugins.outputMeshFormatList();
}
QStringList PluginManager::inputRasterFormatList() const
QStringList PluginManager::inputImageFormatList() const
{
return ioPlugins.inputRasterFormatList();
return ioPlugins.inputImageFormatList();
}
QStringList PluginManager::outputImageFormatList() const
{
return ioPlugins.outputImageFormatList();
}
QStringList PluginManager::inputProjectFormatList() const
{
return ioPlugins.inputProjectFormatList();
}
QStringList PluginManager::outputProjectFormatList() const
{
return ioPlugins.outputProjectFormatList();
}
QStringList PluginManager::inputMeshFormatListDialog() const
@ -345,9 +391,19 @@ QStringList PluginManager::outputMeshFormatListDialog() const
return outputFormatListDialog(ioPluginIterator());
}
QStringList PluginManager::inputRasterFormatListDialog() const
QStringList PluginManager::inputImageFormatListDialog() const
{
return inputRasterFormatListDialog(ioPluginIterator());
return inputImageFormatListDialog(ioPluginIterator());
}
QStringList PluginManager::inputProjectFormatListDialog() const
{
return inputProjectFormatListDialog(ioPluginIterator());
}
QStringList PluginManager::outputProjectFormatListDialog() const
{
return outputProjectFormatListDialog(ioPluginIterator());
}
MeshLabPlugin* PluginManager::operator[](unsigned int i) const
@ -410,7 +466,7 @@ template<typename RangeIterator>
QStringList PluginManager::inputFormatListDialog(RangeIterator iterator)
{
QString allKnownFormats = QObject::tr("All known formats (");
QStringList inputRasterFormatsDialogStringList;
QStringList inputFormatsDialogStringList;
for (auto io : iterator){
QString allKnownFormatsFilter;
for (const FileFormat& currentFormat : io->importFormats()){
@ -423,19 +479,19 @@ QStringList PluginManager::inputFormatListDialog(RangeIterator iterator)
currentFilterEntry.append(currentExtension);
}
currentFilterEntry.append(')');
inputRasterFormatsDialogStringList.append(currentFilterEntry);
inputFormatsDialogStringList.append(currentFilterEntry);
}
allKnownFormats += allKnownFormatsFilter;
}
allKnownFormats.append(')');
inputRasterFormatsDialogStringList.push_front(allKnownFormats);
return inputRasterFormatsDialogStringList;
inputFormatsDialogStringList.push_front(allKnownFormats);
return inputFormatsDialogStringList;
}
template<typename RangeIterator>
QStringList PluginManager::outputFormatListDialog(RangeIterator iterator)
{
QStringList inputRasterFormatsDialogStringList;
QStringList outputFormatsDialogStringList;
for (auto io : iterator){
for (const FileFormat& currentFormat : io->exportFormats()){
QString currentFilterEntry = currentFormat.description + " (";
@ -445,20 +501,20 @@ QStringList PluginManager::outputFormatListDialog(RangeIterator iterator)
currentFilterEntry.append(currentExtension);
}
currentFilterEntry.append(')');
inputRasterFormatsDialogStringList.append(currentFilterEntry);
outputFormatsDialogStringList.append(currentFilterEntry);
}
}
return inputRasterFormatsDialogStringList;
return outputFormatsDialogStringList;
}
template<typename RangeIterator>
QStringList PluginManager::inputRasterFormatListDialog(RangeIterator iterator)
QStringList PluginManager::inputImageFormatListDialog(RangeIterator iterator)
{
QString allKnownFormats = QObject::tr("All known formats (");
QStringList inputRasterFormatsDialogStringList;
QStringList inputImageFormatsDialogStringList;
for (auto io : iterator){
QString allKnownFormatsFilter;
for (const FileFormat& currentFormat : io->importRasterFormats()){
for (const FileFormat& currentFormat : io->importImageFormats()){
QString currentFilterEntry = currentFormat.description + " (";
for (QString currentExtension : currentFormat.extensions) {
currentExtension = currentExtension.toLower();
@ -468,13 +524,58 @@ QStringList PluginManager::inputRasterFormatListDialog(RangeIterator iterator)
currentFilterEntry.append(currentExtension);
}
currentFilterEntry.append(')');
inputRasterFormatsDialogStringList.append(currentFilterEntry);
inputImageFormatsDialogStringList.append(currentFilterEntry);
}
allKnownFormats += allKnownFormatsFilter;
}
allKnownFormats.append(')');
inputRasterFormatsDialogStringList.push_front(allKnownFormats);
return inputRasterFormatsDialogStringList;
inputImageFormatsDialogStringList.push_front(allKnownFormats);
return inputImageFormatsDialogStringList;
}
template<typename RangeIterator>
QStringList PluginManager::inputProjectFormatListDialog(RangeIterator iterator)
{
QString allKnownFormats = QObject::tr("All known formats (");
QStringList inputProjectFormatsDialogStringList;
for (auto io : iterator){
QString allKnownFormatsFilter;
for (const FileFormat& currentFormat : io->importProjectFormats()){
QString currentFilterEntry = currentFormat.description + " (";
for (QString currentExtension : currentFormat.extensions) {
currentExtension = currentExtension.toLower();
allKnownFormatsFilter.append(QObject::tr(" *."));
allKnownFormatsFilter.append(currentExtension);
currentFilterEntry.append(QObject::tr(" *."));
currentFilterEntry.append(currentExtension);
}
currentFilterEntry.append(')');
inputProjectFormatsDialogStringList.append(currentFilterEntry);
}
allKnownFormats += allKnownFormatsFilter;
}
allKnownFormats.append(')');
inputProjectFormatsDialogStringList.push_front(allKnownFormats);
return inputProjectFormatsDialogStringList;
}
template<typename RangeIterator>
QStringList PluginManager::outputProjectFormatListDialog(RangeIterator iterator)
{
QStringList outputProjectFormatsDialogStringList;
for (auto io : iterator){
for (const FileFormat& currentFormat : io->exportProjectFormats()){
QString currentFilterEntry = currentFormat.description + " (";
for (QString currentExtension : currentFormat.extensions) {
currentExtension = currentExtension.toLower();
currentFilterEntry.append(QObject::tr(" *."));
currentFilterEntry.append(currentExtension);
}
currentFilterEntry.append(')');
outputProjectFormatsDialogStringList.append(currentFilterEntry);
}
}
return outputProjectFormatsDialogStringList;
}
ConstPluginIterator<MeshLabPlugin> PluginManager::PluginRangeIterator::begin()

View File

@ -29,6 +29,7 @@
#include "containers/filter_plugin_container.h"
#include "containers/io_plugin_container.h"
#include "containers/render_plugin_container.h"
#include "meshlab_plugin_type.h"
#include <QPluginLoader>
#include <QObject>
@ -45,11 +46,11 @@ public:
class PluginRangeIterator;
/** Member functions **/
static void checkPlugin(const QString& filename);
static MeshLabPluginType checkPlugin(const QString& filename);
void loadPlugins();
void loadPlugins(QDir pluginsDirectory);
void loadPlugin(const QString& filename);
MeshLabPlugin* loadPlugin(const QString& filename);
void unloadPlugin(MeshLabPlugin* ifp);
void enablePlugin(MeshLabPlugin* ifp);
@ -64,16 +65,27 @@ public:
IOPlugin* inputMeshPlugin(const QString& inputFormat) const;
IOPlugin* outputMeshPlugin(const QString& outputFormat) const;
IOPlugin* inputRasterPlugin(const QString inputFormat) const;
IOPlugin* inputImagePlugin(const QString inputFormat) const;
IOPlugin* outputImagePlugin(const QString& outputFormat) const;
IOPlugin* inputProjectPlugin(const QString& inputFormat) const;
IOPlugin* outputProjectPlugin(const QString& outputFormat) const;
bool isInputMeshFormatSupported(const QString inputFormat) const;
bool isOutputMeshFormatSupported(const QString outputFormat) const;
bool isInputRasterFormatSupported(const QString inputFormat) const;
bool isInputImageFormatSupported(const QString inputFormat) const;
bool isOutputImageFormatSupported(const QString outputFormat) const;
bool isInputProjectFormatSupported(const QString inputFormat) const;
bool isOutputProjectFormatSupported(const QString outputFormat) const;
QStringList inputMeshFormatList() const;
QStringList outputMeshFormatList() const;
QStringList inputRasterFormatList() const;
QStringList inputImageFormatList() const;
QStringList outputImageFormatList() const;
QStringList inputProjectFormatList() const;
QStringList outputProjectFormatList() const;
QStringList inputMeshFormatListDialog() const;
QStringList outputMeshFormatListDialog() const;
QStringList inputRasterFormatListDialog() const;
QStringList inputImageFormatListDialog() const;
QStringList inputProjectFormatListDialog() const;
QStringList outputProjectFormatListDialog() const;
MeshLabPlugin* operator [](unsigned int i) const;
@ -108,7 +120,13 @@ private:
static QStringList outputFormatListDialog(RangeIterator iterator);
template <typename RangeIterator>
static QStringList inputRasterFormatListDialog(RangeIterator iterator);
static QStringList inputImageFormatListDialog(RangeIterator iterator);
template <typename RangeIterator>
static QStringList inputProjectFormatListDialog(RangeIterator iterator);
template <typename RangeIterator>
static QStringList outputProjectFormatListDialog(RangeIterator iterator);
};
class PluginManager::PluginRangeIterator

View File

@ -160,7 +160,7 @@ void pymeshlab::FunctionParameter::printDefaultValue(std::ostream& o) const
}
if (parameter->value().isMesh()){
const RichMesh* rm = dynamic_cast<const RichMesh*>(parameter);
o << rm->meshindex;
o << rm->value().getMeshId();
return;
}
if (parameter->value().isFileName()){

View File

@ -36,94 +36,98 @@ pymeshlab::FunctionSet::FunctionSet(const PluginManager& pm)
{
//dummy MeshDocument use to compute default value parameters
//the mesh used is a 1x1x1 cube (with extremes [-0.5; 0.5])
MeshDocument dummyMeshDocument;
Box3m b(Point3m(-0.5,-0.5,-0.5),Point3m(0.5,0.5,0.5));
CMeshO dummyMesh;
vcg::tri::Box<CMeshO>(dummyMesh,b);
dummyMeshDocument.addNewMesh(dummyMesh, "cube");
int mask = 0;
mask |= vcg::tri::io::Mask::IOM_VERTQUALITY;
mask |= vcg::tri::io::Mask::IOM_FACEQUALITY;
dummyMeshDocument.mm()->Enable(mask);
initDummyMeshDocument();
for (auto inputFormat : pm.inputMeshFormatList()){
QString originalFilterName = inputFormat;
QString pythonFilterName = inputFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Load " + inputFormat + " format.");
IOPlugin* plugin = pm.inputMeshPlugin(inputFormat);
RichParameterList rps;
plugin->initPreOpenParameter(inputFormat, rps);
plugin->initOpenParameter(inputFormat, *dummyMeshDocument.mm(), rps);
//filename parameter
QString sv = "file_name." + inputFormat;
QStringList sl(inputFormat);
RichOpenFile of("file_name", sv, sl, "File Name", "The name of the file to load");
FunctionParameter par(of);
f.addParameter(par);
for (const RichParameter& rp : rps){
FunctionParameter par(rp);
f.addParameter(par);
}
loadMeshSet.insert(f);
}
for (auto outputFormat : pm.outputMeshFormatList()){
QString originalFilterName = outputFormat;
QString pythonFilterName = outputFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Save " + outputFormat + " format.");
IOPlugin* plugin = pm.outputMeshPlugin(outputFormat);
RichParameterList rps;
plugin->initSaveParameter(outputFormat, *dummyMeshDocument.mm(), rps);
//filename parameter
QString sv = "file_name." + outputFormat;
RichSaveFile of("file_name", sv, outputFormat, "File Name", "The name of the file to save");
FunctionParameter par(of);
f.addParameter(par);
for (const RichParameter& rp : rps){
FunctionParameter par(rp);
f.addParameter(par);
}
//data to save
updateSaveParameters(plugin, outputFormat, f);
saveMeshSet.insert(f);
}
for (auto inputRasterFormat : pm.inputRasterFormatList()){
QString originalFilterName = inputRasterFormat;
QString pythonFilterName = inputRasterFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Load " + inputRasterFormat + " format.");
//filename parameter
QString sv = "file_name." + inputRasterFormat;
QStringList sl(inputRasterFormat);
RichOpenFile of("file_name", sv, sl, "File Name", "The name of the file to load");
FunctionParameter par(of);
f.addParameter(par);
loadRasterSet.insert(f);
for (IOPlugin* iop : pm.ioPluginIterator()){
loadIOPlugin(iop);
}
for (FilterPlugin* fp : pm.filterPluginIterator()){
for (QAction* act : fp->actions()) {
QString originalFilterName = fp->filterName(act);
QString description = fp->filterInfo(act);
QString pythonFilterName = fp->pythonFilterName(act);
Function f(pythonFilterName, originalFilterName, description);
loadFilterPlugin(fp);
}
}
RichParameterList rps;
fp->initParameterList(act, dummyMeshDocument, rps);
void pymeshlab::FunctionSet::loadFilterPlugin(FilterPlugin* fp)
{
for (QAction* act : fp->actions()) {
QString originalFilterName = fp->filterName(act);
QString description = fp->filterInfo(act);
QString pythonFilterName = fp->pythonFilterName(act);
Function f(pythonFilterName, originalFilterName, description);
RichParameterList rps = fp->initParameterList(act, dummyMeshDocument);
for (const RichParameter& rp : rps){
FunctionParameter par(rp);
f.addParameter(par);
}
filterSet.insert(f);
}
}
void pymeshlab::FunctionSet::loadIOPlugin(IOPlugin* iop)
{
for (const FileFormat& ff : iop->importFormats()){
for (const QString& inputFormat : ff.extensions){
QString originalFilterName = inputFormat.toLower();
QString pythonFilterName = inputFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Load " + inputFormat + " format.");
RichParameterList rps = iop->initPreOpenParameter(inputFormat);
//filename parameter
QString sv = "file_name." + inputFormat;
QStringList sl(inputFormat);
RichOpenFile of("file_name", sv, sl, "File Name", "The name of the file to load");
FunctionParameter par(of);
f.addParameter(par);
for (const RichParameter& rp : rps){
FunctionParameter par(rp);
f.addParameter(par);
}
filterSet.insert(f);
loadMeshSet.insert(f);
}
}
for (const FileFormat& ff : iop->exportFormats()){
for (const QString& outputFormat : ff.extensions){
QString originalFilterName = outputFormat.toLower();
QString pythonFilterName = outputFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Save " + outputFormat + " format.");
RichParameterList rps = iop->initSaveParameter(outputFormat, *dummyMeshDocument.mm());
//filename parameter
QString sv = "file_name." + outputFormat;
RichSaveFile of("file_name", sv, outputFormat, "File Name", "The name of the file to save");
FunctionParameter par(of);
f.addParameter(par);
for (const RichParameter& rp : rps){
FunctionParameter par(rp);
f.addParameter(par);
}
//data to save
updateSaveParameters(iop, outputFormat, f);
saveMeshSet.insert(f);
}
}
for (const FileFormat& ff : iop->importImageFormats()){
for (const QString& inputImageFormat : ff.extensions){
QString originalFilterName = inputImageFormat;
QString pythonFilterName = inputImageFormat.toLower();
Function f(pythonFilterName, originalFilterName, "Load " + inputImageFormat + " format.");
//filename parameter
QString sv = "file_name." + inputImageFormat;
QStringList sl(inputImageFormat);
RichOpenFile of("file_name", sv, sl, "File Name", "The name of the file to load");
FunctionParameter par(of);
f.addParameter(par);
loadImageSet.insert(f);
}
}
}
@ -178,15 +182,15 @@ bool pymeshlab::FunctionSet::containsSaveMeshFunction(const QString& pythonFunct
const pymeshlab::Function& pymeshlab::FunctionSet::loadRasterFunction(const QString& pythonFunctionName) const
{
auto it = loadRasterSet.find(Function(pythonFunctionName, "", ""));
if (it == loadRasterSet.end())
auto it = loadImageSet.find(Function(pythonFunctionName, "", ""));
if (it == loadImageSet.end())
throw MLException(pythonFunctionName + " format for loading raster not found.");
return *it;
}
bool pymeshlab::FunctionSet::containsLoadRasterFunction(const QString& pythonFunctionName) const
{
return loadRasterSet.find(Function(pythonFunctionName, "", "")) != loadRasterSet.end();
return loadImageSet.find(Function(pythonFunctionName, "", "")) != loadImageSet.end();
}
pymeshlab::FunctionSet::FunctionRangeIterator pymeshlab::FunctionSet::filterFunctionIterator() const
@ -206,7 +210,7 @@ pymeshlab::FunctionSet::FunctionRangeIterator pymeshlab::FunctionSet::saveMeshFu
pymeshlab::FunctionSet::FunctionRangeIterator pymeshlab::FunctionSet::loadRasterFunctionIterator() const
{
return FunctionRangeIterator(loadRasterSet);
return FunctionRangeIterator(loadImageSet);
}
void pymeshlab::FunctionSet::updateSaveParameters(IOPlugin* plugin,
@ -230,3 +234,16 @@ void pymeshlab::FunctionSet::updateSaveParameters(IOPlugin* plugin,
}
void pymeshlab::FunctionSet::initDummyMeshDocument()
{
dummyMeshDocument.clear();
Box3m b(Point3m(-0.5,-0.5,-0.5),Point3m(0.5,0.5,0.5));
CMeshO dummyMesh;
vcg::tri::Box<CMeshO>(dummyMesh,b);
dummyMeshDocument.addNewMesh(dummyMesh, "cube");
int mask = 0;
mask |= vcg::tri::io::Mask::IOM_VERTQUALITY;
mask |= vcg::tri::io::Mask::IOM_FACEQUALITY;
dummyMeshDocument.mm()->enable(mask);
}

View File

@ -50,6 +50,10 @@ public:
FunctionSet();
FunctionSet(const PluginManager& pm);
//load plugins
void loadFilterPlugin(FilterPlugin* fp);
void loadIOPlugin(IOPlugin* iop);
std::list<std::string> pythonFilterFunctionNames() const;
const Function& filterFunction(const QString& pythonFunctionName) const;
@ -87,10 +91,14 @@ private:
const QString& outputFormat,
Function& f);
void initDummyMeshDocument();
MeshDocument dummyMeshDocument;
std::set<Function> filterSet;
std::set<Function> loadMeshSet;
std::set<Function> saveMeshSet;
std::set<Function> loadRasterSet;
std::set<Function> loadImageSet;
};
}

View File

@ -29,10 +29,38 @@
#include "../globals.h"
#include "../plugins/plugin_manager.h"
#include <exif.h>
namespace meshlab {
void loadMesh(const QString& fileName, IOPlugin* ioPlugin, const RichParameterList& prePar, const std::list<MeshModel*>& meshList, std::list<int>& maskList, vcg::CallBackPos *cb)
/**
* @brief This function assumes that you already have the followind data:
* - the plugin that is needed to load the mesh
* - the number of meshes that will be loaded from the file
* - the list of MeshModel(s) that will contain the loaded mesh(es)
* - the open parameters that will be used to load the mesh(es)
*
* The function will take care to loat the mesh, load textures if needed
* and make all the clean operations after loading the meshes.
* If load fails, throws a MLException.
*
* @param[i] fileName: the filename
* @param[i] ioPlugin: the plugin that supports the file format to load
* @param[i] prePar: the pre open parameters
* @param[i/o] meshList: the list of meshes that will be loaded from the file
* @param[o] maskList: masks of loaded components for each loaded mesh
* @param cb: callback
* @return the list of texture names that could not be loaded
*/
std::list<std::string> loadMesh(
const QString& fileName,
IOPlugin* ioPlugin,
const RichParameterList& prePar,
const std::list<MeshModel*>& meshList,
std::list<int>& maskList,
vcg::CallBackPos *cb)
{
std::list<std::string> unloadedTextures;
QFileInfo fi(fileName);
QString extension = fi.suffix();
@ -46,7 +74,7 @@ void loadMesh(const QString& fileName, IOPlugin* ioPlugin, const RichParameterLi
QString fileNameSansDir = fi.fileName();
try {
ioPlugin->open(extension, fileNameSansDir, meshList ,maskList, prePar, cb);
ioPlugin->open(extension, fileNameSansDir, meshList, maskList, prePar, cb);
}
catch(const MLException& e) {
QDir::setCurrent(origDir); // undo the change of directory before leaving
@ -59,6 +87,9 @@ void loadMesh(const QString& fileName, IOPlugin* ioPlugin, const RichParameterLi
MeshModel* mm = *itmesh;
int mask = *itmask;
std::list<std::string> tmp = mm->loadTextures(nullptr, cb);
unloadedTextures.insert(unloadedTextures.end(), tmp.begin(), tmp.end());
// In case of polygonal meshes the normal should be updated accordingly
if( mask & vcg::tri::io::Mask::IOM_BITPOLYGONAL) {
mm->updateDataMask(MeshModel::MM_POLYGONAL); // just to be sure. Hopefully it should be done in the plugin...
@ -98,28 +129,56 @@ void loadMesh(const QString& fileName, IOPlugin* ioPlugin, const RichParameterLi
++itmask;
}
QDir::setCurrent(origDir); // undo the change of directory before leaving
return unloadedTextures;
}
void loadMeshWithStandardParameters(const QString& filename, MeshDocument& md, vcg::CallBackPos *cb)
/**
* @brief loads the given filename and puts the loaded mesh(es) into the
* given MeshDocument. Returns the list of loaded meshes.
*
* If you already know the open parameters that could be used to load the mesh,
* you can pass a RichParameterList containing them.
* Note: only parameters of your RPL that are actually required by the plugin
* will be given as input to the load function.
* If you don't know any parameter, leave the RichParameterList parameter empty.
*
* The function takes care to:
* - find the plugin that loads the format of the file
* - create the required MeshModels into the MeshDocument
* - load the meshes and their textures, with standard parameters
*
* if an error occurs, an exception will be thrown, and MeshDocument won't
* contain new meshes.
*/
std::list<MeshModel*> loadMeshWithStandardParameters(
const QString& filename,
MeshDocument& md,
vcg::CallBackPos *cb,
RichParameterList prePar)
{
QFileInfo fi(filename);
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.inputMeshPlugin(extension);
IOPlugin* ioPlugin = pm.inputMeshPlugin(extension);
if (ioPlugin == nullptr)
throw MLException(
"Mesh " + filename + " cannot be opened. Your MeshLab version "
"has not plugin to read " + extension + " file format");
ioPlugin->setLog(&md.Log);
RichParameterList openParams =ioPlugin->initPreOpenParameter(extension);
RichParameterList prePar;
ioPlugin->initPreOpenParameter(extension, prePar);
for (RichParameter& rp : prePar){
auto it = openParams.findParameter(rp.name());
if (it != openParams.end()){
it->setValue(rp.value());
}
}
prePar.join(meshlab::defaultGlobalParameterList());
unsigned int nMeshes = ioPlugin->numberMeshesContainedInFile(extension, filename);
unsigned int nMeshes = ioPlugin->numberMeshesContainedInFile(extension, filename, prePar);
std::list<MeshModel*> meshList;
for (unsigned int i = 0; i < nMeshes; i++) {
MeshModel *mm = md.addNewMesh(filename, fi.fileName());
@ -135,28 +194,27 @@ void loadMeshWithStandardParameters(const QString& filename, MeshDocument& md, v
try{
loadMesh(fi.fileName(), ioPlugin, prePar, meshList, masks, cb);
RichParameterList par;
ioPlugin->initOpenParameter(extension, meshList, par);
ioPlugin->applyOpenParameter(extension, meshList, par);
}
catch(const MLException& e){
for (MeshModel* mm : meshList)
md.delMesh(mm);
throw e;
}
return meshList;
}
void reloadMesh(
const QString& filename,
const std::list<MeshModel*>& meshList,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(filename);
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.inputMeshPlugin(extension);
IOPlugin* ioPlugin = pm.inputMeshPlugin(extension);
if (ioPlugin == nullptr) {
throw MLException(
@ -165,11 +223,12 @@ void reloadMesh(
" file format");
}
RichParameterList prePar;
ioPlugin->initPreOpenParameter(extension, prePar);
ioPlugin->setLog(log);
RichParameterList prePar = ioPlugin->initPreOpenParameter(extension);
prePar.join(meshlab::defaultGlobalParameterList());
unsigned int nMeshes = ioPlugin->numberMeshesContainedInFile(extension, filename);
unsigned int nMeshes = ioPlugin->numberMeshesContainedInFile(extension, filename, prePar);
if (meshList.size() != nMeshes){
throw MLException(
@ -179,35 +238,254 @@ void reloadMesh(
std::list<int> masks;
for (MeshModel* mm : meshList){
mm->Clear();
mm->clear();
}
loadMesh(filename, ioPlugin, prePar, meshList, masks, cb);
RichParameterList par;
ioPlugin->initOpenParameter(extension, meshList, par);
ioPlugin->applyOpenParameter(extension, meshList, par);
}
void loadRaster(const QString& filename, MeshDocument& md, vcg::CallBackPos* cb)
void saveMeshWithStandardParameters(
const QString& fileName,
MeshModel& m,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(fileName);
QString extension = fi.suffix().toLower();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin* ioPlugin = pm.outputMeshPlugin(extension);
if (ioPlugin == nullptr) {
throw MLException(
"Mesh " + fileName + " cannot be saved. Your MeshLab "
"version has not plugin to save " + extension +
" file format");
}
ioPlugin->setLog(log);
int capability=0,defaultBits=0;
ioPlugin->exportMaskCapability(extension, capability, defaultBits);
RichParameterList saveParams = ioPlugin->initSaveParameter(extension, m);
ioPlugin->save(extension, fileName, m ,capability, saveParams, cb);
m.setFileName(fileName);
m.saveTextures(fi.absolutePath(), 66, log, cb);
}
void saveAllMeshes(
const QString& basePath,
MeshDocument& md,
bool onlyVisible,
GLLogStream* log,
vcg::CallBackPos* cb)
{
PluginManager& pm = meshlab::pluginManagerInstance();
for (MeshModel* m : md.meshIterator()){
if (m->isVisible() || !onlyVisible) {
QString filename, extension;
if (m->fullName().isEmpty()){
if (m->label().contains('.')){
extension = QFileInfo(m->label()).suffix();
filename = QFileInfo(m->label()).baseName();
}
else {
extension = "ply";
filename = m->label();
}
}
else {
QFileInfo fi(m->fullName());
extension = fi.suffix();
filename = fi.baseName();
}
filename.replace(QRegExp("[" + QRegExp::escape( "\\/:*?\"<>|" ) + "]"),QString("_"));
IOPlugin* ioPlugin = pm.outputMeshPlugin(extension);
if (ioPlugin == nullptr){
std::cerr << "Warning: extension " + extension.toStdString() +
" not supported. Saving " + filename.toStdString() + ".ply.";
filename += ".ply";
}
else {
filename += ("." + extension.toLower());
}
filename = basePath + "/" + filename;
saveMeshWithStandardParameters(filename, *m, log, cb);
}
}
}
QImage loadImage(
const QString& filename,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(filename);
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.inputRasterPlugin(extension);
IOPlugin *ioPlugin = pm.inputImagePlugin(extension);
if (ioPlugin == nullptr)
throw MLException(
"Raster " + filename + " cannot be opened. Your MeshLab version "
"Image " + filename + " cannot be opened. Your MeshLab version "
"has not plugin to read " + extension + " file format.");
RasterModel *rm = md.addNewRaster();
try {
ioPlugin->openRaster(extension, filename, *rm, cb);
ioPlugin->setLog(log);
return ioPlugin->openImage(extension, filename, cb);
}
void saveImage(
const QString& filename,
const QImage& image,
int quality,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(filename);
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.outputImagePlugin(extension);
if (ioPlugin == nullptr)
throw MLException(
"Image " + filename + " cannot be saved. Your MeshLab version "
"has not plugin to save " + extension + " file format.");
ioPlugin->setLog(log);
ioPlugin->saveImage(extension, filename, image, quality, cb);
}
void loadRaster(const QString& filename, RasterModel& rm, GLLogStream* log, vcg::CallBackPos* cb)
{
QImage loadedImage = loadImage(filename, log, cb);
rm.setLabel(filename);
rm.addPlane(new RasterPlane(loadedImage, filename, RasterPlane::RGBA));
// Read the file into a buffer
FILE *fp = fopen(qUtf8Printable(filename), "rb");
if (!fp) {
QString errorMsgFormat = "Exif Parsing: Unable to open file:\n\"%1\"\n\nError details: file %1 is not readable.";
throw MLException(errorMsgFormat.arg(filename));
}
catch(const MLException& e){
md.delRaster(rm);
throw e;
fseek(fp, 0, SEEK_END);
unsigned long fsize = ftell(fp);
rewind(fp);
unsigned char *buf = new unsigned char[fsize];
if (fread(buf, 1, fsize, fp) != fsize) {
QString errorMsgFormat = "Exif Parsing: Unable to read the content of the opened file:\n\"%1\"\n\nError details: file %1 is not readable.";
delete[] buf;
fclose(fp);
throw MLException(errorMsgFormat.arg(filename));
}
fclose(fp);
// Parse EXIF
easyexif::EXIFInfo ImageInfo;
int code = ImageInfo.parseFrom(buf, fsize);
delete[] buf;
if (!code) {
log->log(GLLogStream::FILTER, "Warning: unable to parse exif for file " + filename);
}
if (code && ImageInfo.FocalLengthIn35mm==0.0f)
{
rm.shot.Intrinsics.ViewportPx = vcg::Point2i(rm.currentPlane->image.width(), rm.currentPlane->image.height());
rm.shot.Intrinsics.CenterPx = Point2m(float(rm.currentPlane->image.width()/2.0), float(rm.currentPlane->image.width()/2.0));
rm.shot.Intrinsics.PixelSizeMm[0]=36.0f/(float)rm.currentPlane->image.width();
rm.shot.Intrinsics.PixelSizeMm[1]=rm.shot.Intrinsics.PixelSizeMm[0];
rm.shot.Intrinsics.FocalMm = 50.0f;
}
else
{
rm.shot.Intrinsics.ViewportPx = vcg::Point2i(ImageInfo.ImageWidth, ImageInfo.ImageHeight);
rm.shot.Intrinsics.CenterPx = Point2m(float(ImageInfo.ImageWidth/2.0), float(ImageInfo.ImageHeight/2.0));
float ratioFocal=ImageInfo.FocalLength/ImageInfo.FocalLengthIn35mm;
rm.shot.Intrinsics.PixelSizeMm[0]=(36.0f*ratioFocal)/(float)ImageInfo.ImageWidth;
rm.shot.Intrinsics.PixelSizeMm[1]=(24.0f*ratioFocal)/(float)ImageInfo.ImageHeight;
rm.shot.Intrinsics.FocalMm = ImageInfo.FocalLength;
}
// End of EXIF reading
}
std::vector<MeshModel*> loadProject(
const QStringList& filenames,
IOPlugin* ioPlugin,
MeshDocument& md,
std::vector<MLRenderingData>& rendOpt,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(filenames.first());
QString extension = fi.suffix();
ioPlugin->setLog(log);
return ioPlugin->openProject(extension, filenames, md, rendOpt, cb);
}
std::vector<MeshModel*> loadProject(
const QStringList& filenames,
MeshDocument& md,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QFileInfo fi(filenames.first());
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.inputProjectPlugin(extension);
if (ioPlugin == nullptr)
throw MLException(
"Project " + filenames.first() + " cannot be loaded. Your MeshLab version "
"has not plugin to load " + extension + " file format.");
std::list<FileFormat> additionalFiles =
ioPlugin->projectFileRequiresAdditionalFiles(extension, filenames.first());
if (additionalFiles.size() +1 != (unsigned int)filenames.size()){
throw MLException(
"The number of input files given (" + QString::number(filenames.size()) +
") is different from the expected one (" +
QString::number(additionalFiles.size() +1));
}
std::vector<MLRenderingData> rendOpt;
return loadProject(filenames, ioPlugin, md, rendOpt, log, cb);
}
std::vector<MeshModel*> loadProject(
const QString& filename,
MeshDocument& md,
GLLogStream* log,
vcg::CallBackPos* cb)
{
QStringList fnms;
fnms.push_back(filename);
return loadProject(fnms, md, log, cb);
}
void saveProject(
const QString& filename,
const MeshDocument& md,
bool onlyVisibleMeshes,
std::vector<MLRenderingData> renderData)
{
QFileInfo fi(filename);
QString extension = fi.suffix();
PluginManager& pm = meshlab::pluginManagerInstance();
IOPlugin *ioPlugin = pm.outputProjectPlugin(extension);
if (ioPlugin == nullptr)
throw MLException(
"Project " + filename + " cannot be loaded. Your MeshLab version "
"has not plugin to load " + extension + " file format.");
if (renderData.size() != 0 && md.meshNumber() != renderData.size()){
std::cerr << "Warning: renderData vector has different size from "
"MeshDocument number meshes. Ignoring render data when saving " +
filename.toStdString() << " project.";
renderData.clear();
}
RichParameterList rpl;
ioPlugin->saveProject(extension, filename, md, onlyVisibleMeshes, renderData);
}
}

View File

@ -34,7 +34,7 @@
namespace meshlab {
void loadMesh(
std::list<std::string> loadMesh(
const QString& fileName,
IOPlugin* ioPlugin,
const RichParameterList& prePar,
@ -42,20 +42,75 @@ void loadMesh(
std::list<int>& maskList,
vcg::CallBackPos *cb);
void loadMeshWithStandardParameters(
std::list<MeshModel*> loadMeshWithStandardParameters(
const QString& filename,
MeshDocument& md,
vcg::CallBackPos *cb);
vcg::CallBackPos *cb = nullptr,
RichParameterList prePar = RichParameterList());
void reloadMesh(
const QString& filename,
const std::list<MeshModel*>& meshList,
vcg::CallBackPos* cb);
GLLogStream* log = nullptr,
vcg::CallBackPos* cb = nullptr);
void saveMeshWithStandardParameters(
const QString& fileName,
MeshModel& m,
GLLogStream* log = nullptr,
vcg::CallBackPos* cb = nullptr);
void saveAllMeshes(
const QString& basePath,
MeshDocument& md,
bool onlyVisible = false,
GLLogStream* log = nullptr,
vcg::CallBackPos* cb = nullptr);
QImage loadImage(
const QString& filename,
GLLogStream* log = nullptr,
vcg::CallBackPos *cb = nullptr);
void saveImage(
const QString& filename,
const QImage& image,
int quality = 66,
GLLogStream* log = nullptr,
vcg::CallBackPos* cb = nullptr);
void loadRaster(
const QString& filename,
RasterModel& rm,
GLLogStream* log = nullptr,
vcg::CallBackPos *cb = nullptr);
std::vector<MeshModel*> loadProject(
const QStringList& filenames,
IOPlugin* ioPlugin,
MeshDocument& md,
vcg::CallBackPos *cb);
std::vector<MLRenderingData>& rendOpt,
GLLogStream* log = nullptr,
vcg::CallBackPos *cb = nullptr);
std::vector<MeshModel*> loadProject(
const QStringList& filenames,
MeshDocument& md,
GLLogStream* log = nullptr,
vcg::CallBackPos *cb = nullptr);
std::vector<MeshModel*> loadProject(
const QString& filename,
MeshDocument& md,
GLLogStream* log = nullptr,
vcg::CallBackPos *cb = nullptr);
void saveProject(
const QString& filename,
const MeshDocument& md,
bool onlyVisibleMeshes,
std::vector<MLRenderingData> renderData = std::vector<MLRenderingData>());
}
#endif // MESHLAB_LOAD_SAVE_H

View File

@ -2,5 +2,77 @@
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
message(STATUS "Searching for optional components")
include(${EXTERNAL_DIR}/external.cmake)
option(
ALLOW_OPTIONAL_EXTERNAL_MESHLAB_LIBRARIES
"Allow to use/build optional external libraries"
ON)
option(
BUILD_BUNDLED_SOURCES_WITHOUT_WARNINGS
"Should warnings be disabled on bundled source code?"
ON)
add_library(external-disable-warnings INTERFACE)
if(BUILD_BUNDLED_SOURCES_WITHOUT_WARNINGS)
if(MSVC)
# TODO
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
target_compile_options(external-disable-warnings INTERFACE -w)
endif()
endif()
## REQUIRED EXTERNAL LIBS ##
# GLEW - required
include(${CMAKE_CURRENT_SOURCE_DIR}/glew.cmake)
# EasyExif - required
include(${CMAKE_CURRENT_SOURCE_DIR}/easyexif.cmake)
## OPTIONAL EXTERNAL LIBS ##
if ((NOT BUILD_MINI) AND ALLOW_OPTIONAL_EXTERNAL_MESHLAB_LIBRARIES)
message(STATUS "Searching for optional components")
# boost - optional for filter_mesh_booleans
include(${CMAKE_CURRENT_SOURCE_DIR}/boost.cmake)
# cgal - optional for filter_mesh_booleans
include(${CMAKE_CURRENT_SOURCE_DIR}/cgal.cmake)
# levmar - optional, for several plugins
include(${CMAKE_CURRENT_SOURCE_DIR}/levmar.cmake)
# lib3ds - optional, for io_3ds
include(${CMAKE_CURRENT_SOURCE_DIR}/lib3ds.cmake)
# libigl - optional for filter_mesh_booleans
include(${CMAKE_CURRENT_SOURCE_DIR}/libigl.cmake)
# muparser - optional, for filter_func
include(${CMAKE_CURRENT_SOURCE_DIR}/muparser.cmake)
# newuoa - optional and header-only, for several plugins including all that use levmar
include(${CMAKE_CURRENT_SOURCE_DIR}/newuoa.cmake)
# OpenCTM - optional, for io_ctm
include(${CMAKE_CURRENT_SOURCE_DIR}/openctm.cmake)
# qhull - optional, for filter_qhull
include(${CMAKE_CURRENT_SOURCE_DIR}/qhull.cmake)
# structure-synth - optional, for filter_ssynth
include(${CMAKE_CURRENT_SOURCE_DIR}/ssynth.cmake)
# u3d - optional, for io_u3d
include(${CMAKE_CURRENT_SOURCE_DIR}/u3d.cmake)
# xerces library - optional, needed by libe57
include(${CMAKE_CURRENT_SOURCE_DIR}/xerces.cmake)
# libe57Format - optional, for io_e57
include(${CMAKE_CURRENT_SOURCE_DIR}/e57.cmake)
endif()

14
src/external/README.md vendored Normal file
View File

@ -0,0 +1,14 @@
# External libraries for MeshLab
Notes about external libraries:
## Required libraries
- GLEW
- easyexif
Without these two libraries (or their relative system provided libraries), MeshLab cannot be compiled.
## Optional libraries
Boost and CGAL directories contain only a portion of the libraries, that is the code necessary to build the `mesh_booleans` plugin.

22
src/external/boost.cmake vendored Normal file
View File

@ -0,0 +1,22 @@
# Copyright 2019, 2021, Collabora, Ltd.
# Copyright 2019, 2021, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
option(ALLOW_BUNDLED_BOOST "Allow use of bundled boost source" ON)
option(ALLOW_SYSTEM_BOOST "Allow use of system-provided boost" ON)
find_package(Boost COMPONENTS thread)
set(BOOST_DIR ${CMAKE_CURRENT_LIST_DIR}/boost_1_75_0)
if(ALLOW_SYSTEM_BOOST AND TARGET Boost::boost)
message(STATUS "- Boost - using system-provided library")
add_library(external-boost INTERFACE)
target_link_libraries(external-boost INTERFACE Boost::boost)
if (TARGET Boost::thread)
target_link_libraries(external-boost INTERFACE Boost::thread)
endif()
elseif(ALLOW_BUNDLED_BOOST AND EXISTS "${BOOST_DIR}/boost/version.hpp")
message(STATUS "- Boost - using bundled source")
add_library(external-boost INTERFACE)
target_include_directories(external-boost INTERFACE "${BOOST_DIR}")
endif()

57
src/external/cgal.cmake vendored Normal file
View File

@ -0,0 +1,57 @@
# Copyright 2019, 2021, Collabora, Ltd.
# Copyright 2019, 2021, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
option(ALLOW_BUNDLED_CGAL "Allow use of bundled CGAL source" ON)
option(ALLOW_SYSTEM_CGAL "Allow use of system-provided CGAL" ON)
find_package(Threads REQUIRED)
find_package(CGAL)
set(CGAL_DIR "${CMAKE_CURRENT_LIST_DIR}/CGAL-5.2.1")
if(ALLOW_SYSTEM_CGAL AND TARGET CGAL::CGAL)
message(STATUS "- CGAL - using system-provided library")
add_library(external-cgal INTERFACE)
target_link_libraries(external-cgal INTERFACE CGAL::CGAL Threads::Threads)
elseif(ALLOW_BUNDLED_CGAL AND EXISTS "${CGAL_DIR}/include/CGAL/version.h")
message(STATUS "- CGAL - using bundled source")
add_library(external-cgal INTERFACE)
target_include_directories(external-cgal INTERFACE "${CGAL_DIR}/include/")
if (WIN32)
add_library(mpfr SHARED IMPORTED GLOBAL)
set_property(TARGET mpfr PROPERTY IMPORTED_IMPLIB "${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.lib")
set_property(TARGET mpfr PROPERTY IMPORTED_LOCATION "${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.dll")
target_include_directories(mpfr INTERFACE "${CGAL_DIR}/auxiliary/gmp/include")
add_library(gmp SHARED IMPORTED GLOBAL)
set_property(TARGET gmp PROPERTY IMPORTED_IMPLIB "${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.lib")
set_property(TARGET gmp PROPERTY IMPORTED_LOCATION "${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.dll")
endif()
target_link_libraries(external-cgal INTERFACE mpfr gmp Threads::Threads)
if (WIN32)
if (DEFINED MESHLAB_BUILD_DISTRIB_DIR)
file(
COPY
${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.lib
${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.dll
${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.lib
${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.dll
DESTINATION
${MESHLAB_BUILD_DISTRIB_DIR})
endif()
if (DEFINED MESHLAB_LIB_INSTALL_DIR)
install(
FILES
${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.lib
${CGAL_DIR}/auxiliary/gmp/lib/libmpfr-4.dll
${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.lib
${CGAL_DIR}/auxiliary/gmp/lib/libgmp-10.dll
DESTINATION
${MESHLAB_LIB_INSTALL_DIR})
endif()
endif()
else()
message(STATUS "- CGAL - skipping CGAL library")
endif()

17
src/external/easyexif.cmake vendored Normal file
View File

@ -0,0 +1,17 @@
# Copyright 2019, 2020, Collabora, Ltd.
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
option(ALLOW_BUNDLED_EXIF "Allow use of bundled EasyExif source" ON)
set(EXIF_DIR ${CMAKE_CURRENT_LIST_DIR}/easyexif)
if(ALLOW_BUNDLED_EXIF AND EXISTS "${EXIF_DIR}/exif.h")
message(STATUS "- exif - using bundled source")
add_library(external-exif STATIC ${EXIF_DIR}/exif.h ${EXIF_DIR}/exif.cpp)
target_include_directories(external-exif PUBLIC ${EXIF_DIR})
else()
message(
FATAL_ERROR
"Exif is required - ALLOW_BUNDLED_EXIF must be enabled and found.")
endif()

View File

@ -1,36 +0,0 @@
# Copyright 2019, 2020, Collabora, Ltd.
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
# newuoa - optional and header-only, for several plugins including all that use levmar
include(${EXTERNAL_DIR}/newuoa.cmake)
# levmar - optional, for several plugins
include(${EXTERNAL_DIR}/levmar.cmake)
# lib3ds - optional, for io_3ds
include(${EXTERNAL_DIR}/lib3ds.cmake)
# gmp or mpir - optional, for filter_csg
include(${EXTERNAL_DIR}/gmp-mpir.cmake)
# muparser - optional, for filter_func
include(${EXTERNAL_DIR}/muparser.cmake)
# OpenCTM - optional, for io_ctm
include(${EXTERNAL_DIR}/openctm.cmake)
# structure-synth - optional, for filter_ssynth
include(${EXTERNAL_DIR}/ssynth.cmake)
# qhull - optional, for filter_qhull
include(${EXTERNAL_DIR}/qhull.cmake)
# u3d - optional, for io_u3d
include(${EXTERNAL_DIR}/u3d.cmake)
# xerces library - optional, needed by libe57
include(${EXTERNAL_DIR}/xerces.cmake)
# libe57Format - optional, for io_e57
include(${EXTERNAL_DIR}/e57.cmake)

View File

@ -1,16 +0,0 @@
# Copyright 2019, 2020, Collabora, Ltd.
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
option(BUILD_BUNDLED_SOURCES_WITHOUT_WARNINGS "Should warnings be disabled on bundled source code?" ON)
add_library(external-disable-warnings INTERFACE)
if(BUILD_BUNDLED_SOURCES_WITHOUT_WARNINGS)
if(MSVC)
# TODO
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
target_compile_options(external-disable-warnings INTERFACE -w)
endif()
endif()
# GLEW - required
include(${EXTERNAL_DIR}/glew.cmake)

View File

@ -5,7 +5,7 @@
option(ALLOW_BUNDLED_GLEW "Allow use of bundled GLEW source" ON)
option(ALLOW_SYSTEM_GLEW "Allow use of system-provided GLEW" ON)
set(GLEW_DIR ${EXTERNAL_DIR}/glew-2.1.0)
set(GLEW_DIR ${CMAKE_CURRENT_LIST_DIR}/glew-2.1.0)
unset(HAVE_SYSTEM_GLEW)
if(DEFINED GLEW_VERSION)

View File

@ -1,44 +0,0 @@
# Copyright 2019, 2020, Collabora, Ltd.
# Copyright 2019, 2020, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
option(ALLOW_SYSTEM_GMP "Allow use of system-provided GMP" ON)
option(ALLOW_BUNDLED_MPIR "Allow use of bundled MPIR binaries" ON)
find_package(GMP)
set(MPIR_DIR ${EXTERNAL_DIR}/mpir)
unset(HAVE_BUNDLED_MPIR)
if (APPLE AND EXISTS "${MPIR_DIR}/macx64/libmpir.a" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
# We have mac binaries for x64
# TODO check target processor architecture, not just pointer size
set(HAVE_BUNDLED_MPIR APPLE-x64)
elseif(WIN32 AND MSVC AND EXISTS "${MPIR_DIR}/win32-msvc/mpir.lib" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
# We have windows binaries for x64
# TODO check target processor architecture, not just pointer size
set(HAVE_BUNDLED_MPIR WIN-x64)
endif()
# gmp or mpir - optional, for filter_csg
if(ALLOW_SYSTEM_GMP AND GMP_FOUND)
message(STATUS "- GMP/MPIR - using system-provided GMP library")
add_library(external-gmp INTERFACE)
target_include_directories(external-gmp SYSTEM INTERFACE ${GMP_INCLUDE_DIRS})
target_link_libraries(external-gmp INTERFACE ${GMP_LIBRARIES})
elseif(ALLOW_BUNDLED_MPIR AND HAVE_BUNDLED_MPIR)
message(STATUS "- GMP/MPIR - using already built MPIR library")
add_library(mpir STATIC IMPORTED GLOBAL)
add_library(mpirxx STATIC IMPORTED GLOBAL)
if (HAVE_BUNDLED_MPIR STREQUAL "WIN-x64")
set_property(TARGET mpir PROPERTY IMPORTED_LOCATION "${MPIR_DIR}/win32-msvc/mpir.lib")
set_property(TARGET mpirxx PROPERTY IMPORTED_LOCATION "${MPIR_DIR}/win32-msvc/mpirxx.lib")
target_include_directories(mpir INTERFACE ${EXTERNAL_DIR}/inc/win32-msvc/mpir-2.2.1_x64)
elseif(HAVE_BUNDLED_MPIR STREQUAL "APPLE-x64")
set_property(TARGET mpir PROPERTY IMPORTED_LOCATION "${MPIR_DIR}/macx64/libmpir.a")
set_property(TARGET mpirxx PROPERTY IMPORTED_LOCATION "${MPIR_DIR}/macx64/libmpirxx.a")
target_include_directories(mpir INTERFACE ${EXTERNAL_DIR}/inc/macx64/mpir-2.4.0)
endif()
add_library(external-mpir INTERFACE)
target_link_libraries(external-mpir INTERFACE mpir mpirxx)
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,519 +0,0 @@
/* Templates for defines setup by configure.
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/* Define one (and only one) of these for the CPU host.
Only hosts that are going to be tested for need to be in this list,
not everything that can possibly be selected.
*/
#undef HAVE_HOST_CPU_alpha
#undef HAVE_HOST_CPU_alphaev5
#undef HAVE_HOST_CPU_alphaev6
#undef HAVE_HOST_CPU_alphaev67
#undef HAVE_HOST_CPU_m68k
#undef HAVE_HOST_CPU_m68000
#undef HAVE_HOST_CPU_m68010
#undef HAVE_HOST_CPU_m68020
#undef HAVE_HOST_CPU_m68030
#undef HAVE_HOST_CPU_m68040
#undef HAVE_HOST_CPU_m68060
#undef HAVE_HOST_CPU_m68302
#undef HAVE_HOST_CPU_m68360
#undef HAVE_HOST_CPU_powerpc604
#undef HAVE_HOST_CPU_powerpc604e
#undef HAVE_HOST_CPU_powerpc750
#undef HAVE_HOST_CPU_powerpc7400
#undef HAVE_HOST_CPU_sparc
#undef HAVE_HOST_CPU_sparcv8
#undef HAVE_HOST_CPU_supersparc
#undef HAVE_HOST_CPU_sparclite
#undef HAVE_HOST_CPU_microsparc
#undef HAVE_HOST_CPU_ultrasparc1
#undef HAVE_HOST_CPU_ultrasparc2
#undef HAVE_HOST_CPU_sparc64
#undef HAVE_HOST_CPU_hppa1_0
#undef HAVE_HOST_CPU_hppa1_1
#undef HAVE_HOST_CPU_hppa2_0n
#undef HAVE_HOST_CPU_hppa2_0w
#undef HAVE_HOST_CPU_i386
#undef HAVE_HOST_CPU_i486
#undef HAVE_HOST_CPU_i586
#undef HAVE_HOST_CPU_i686
#undef HAVE_HOST_CPU_pentium
#undef HAVE_HOST_CPU_pentiummmx
#undef HAVE_HOST_CPU_pentiumpro
#undef HAVE_HOST_CPU_pentium2
#undef HAVE_HOST_CPU_pentium3
#undef HAVE_HOST_CPU_k5
#undef HAVE_HOST_CPU_k6
#undef HAVE_HOST_CPU_k62
#undef HAVE_HOST_CPU_k63
#undef HAVE_HOST_CPU_athlon
/* a dummy to make autoheader happy */
#undef HAVE_HOST_CPU_
/* Define one (and only one) of these for the CPU host family.
Only hosts that are going to be tested for need to be in this list,
not everything that can possibly be selected.
*/
#undef HAVE_HOST_CPU_FAMILY_power
#undef HAVE_HOST_CPU_FAMILY_powerpc
#define HAVE_HOST_CPU_FAMILY_x86 1
/* Define if we have native implementation of function.
(use just one of the three following defines)
*/
#undef HAVE_NATIVE_mpn_add
#undef HAVE_NATIVE_mpn_add_1
#undef HAVE_NATIVE_mpn_addmul_2
#undef HAVE_NATIVE_mpn_addmul_3
#undef HAVE_NATIVE_mpn_addmul_4
#undef HAVE_NATIVE_mpn_addsub_n
#undef HAVE_NATIVE_mpn_addsub_nc
#undef HAVE_NATIVE_mpn_and_n
#undef HAVE_NATIVE_mpn_andn_n
#undef HAVE_NATIVE_mpn_bdivmod
#undef HAVE_NATIVE_mpn_cmp
#undef HAVE_NATIVE_mpn_com_n
#undef HAVE_NATIVE_mpn_divrem
#undef HAVE_NATIVE_mpn_divrem_2
#undef HAVE_NATIVE_mpn_divrem_newton
#undef HAVE_NATIVE_mpn_divrem_classic
#undef HAVE_NATIVE_mpn_dump
#undef HAVE_NATIVE_mpn_gcd
#undef HAVE_NATIVE_mpn_gcd_1
#undef HAVE_NATIVE_mpn_gcd_finda
#undef HAVE_NATIVE_mpn_gcdext
#undef HAVE_NATIVE_mpn_get_str
#undef HAVE_NATIVE_mpn_invert_limb
#undef HAVE_NATIVE_mpn_ior_n
#undef HAVE_NATIVE_mpn_iorn_n
#undef HAVE_NATIVE_mpn_mul
#undef HAVE_NATIVE_mpn_mul_2
#undef HAVE_NATIVE_mpn_mul_3
#undef HAVE_NATIVE_mpn_mul_4
#undef HAVE_NATIVE_mpn_mul_n
#undef HAVE_NATIVE_mpn_nand_n
#undef HAVE_NATIVE_mpn_nior_n
#undef HAVE_NATIVE_mpn_perfect_square_p
#undef HAVE_NATIVE_mpn_preinv_mod_1
#undef HAVE_NATIVE_mpn_random2
#undef HAVE_NATIVE_mpn_random
#undef HAVE_NATIVE_mpn_rawrandom
#undef HAVE_NATIVE_mpn_scan0
#undef HAVE_NATIVE_mpn_scan1
#undef HAVE_NATIVE_mpn_set_str
#undef HAVE_NATIVE_mpn_sqrtrem
#undef HAVE_NATIVE_mpn_sqr_diagonal
#undef HAVE_NATIVE_mpn_sub
#undef HAVE_NATIVE_mpn_sub_1
#undef HAVE_NATIVE_mpn_udiv_w_sdiv
#undef HAVE_NATIVE_mpn_xor_n
#undef HAVE_NATIVE_mpn_xnor_n
#undef HAVE_NATIVE_mpn_add_n
#undef HAVE_NATIVE_mpn_add_nc
#undef HAVE_NATIVE_mpn_sub_n
#undef HAVE_NATIVE_mpn_sub_nc
#undef HAVE_NATIVE_mpn_addmul_1
#undef HAVE_NATIVE_mpn_addmul_1c
#undef HAVE_NATIVE_mpn_submul_1
#undef HAVE_NATIVE_mpn_submul_1c
#undef HAVE_NATIVE_mpn_copyd
#undef HAVE_NATIVE_mpn_copyi
#undef HAVE_NATIVE_mpn_divexact_1
#undef HAVE_NATIVE_mpn_divexact_by3c
#undef HAVE_NATIVE_mpn_divrem_1
#undef HAVE_NATIVE_mpn_divrem_1c
#undef HAVE_NATIVE_mpn_hamdist
#undef HAVE_NATIVE_mpn_popcount
#undef HAVE_NATIVE_mpn_lshift
#undef HAVE_NATIVE_mpn_rshift
#undef HAVE_NATIVE_mpn_mod_1
#undef HAVE_NATIVE_mpn_mod_1c
#undef HAVE_NATIVE_mpn_modexact_1_odd
#undef HAVE_NATIVE_mpn_modexact_1c_odd
#undef HAVE_NATIVE_mpn_mul_1
#undef HAVE_NATIVE_mpn_mul_1c
#undef HAVE_NATIVE_mpn_mul_basecase
#undef HAVE_NATIVE_mpn_sqr_basecase
#undef HAVE_NATIVE_mpn_umul_ppmm
#undef HAVE_NATIVE_mpn_udiv_qrnnd
/* For the generic C code */
#define HAVE_NATIVE_mpn_add_n 1
#define HAVE_NATIVE_mpn_sub_n 1
/* a dummy to make autoheader happy */
#undef HAVE_NATIVE_
/* The gmp-mparam.h to update when tuning. */
#undef GMP_MPARAM_H_SUGGEST
/* Define if you have the `alarm' function. */
#undef HAVE_ALARM
/* Define if alloca() works (via gmp-impl.h). */
#define HAVE_ALLOCA 1
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if the compiler accepts gcc style __attribute__ ((const)) */
#undef HAVE_ATTRIBUTE_CONST
/* Define if the compiler accepts gcc style __attribute__ ((malloc)) */
#undef HAVE_ATTRIBUTE_MALLOC
/* Define if the compiler accepts gcc style __attribute__ ((mode (XX))) */
#undef HAVE_ATTRIBUTE_MODE
/* Define if the compiler accepts gcc style __attribute__ ((noreturn)) */
#undef HAVE_ATTRIBUTE_NORETURN
/* Define if tests/libtests has calling conventions checking for the CPU */
#undef HAVE_CALLING_CONVENTIONS
/* Define if you have the `clock' function. */
#define HAVE_CLOCK 1
/* Define if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define if you have the `cputime' function. */
#undef HAVE_CPUTIME
/* Define to 1 if you have the declaration of `fgetc', and to 0 if you don't.
*/
#define HAVE_DECL_FGETC 1
/* Define to 1 if you have the declaration of `fscanf', and to 0 if you don't.
*/
#define HAVE_DECL_FSCANF 1
/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
*/
#define HAVE_DECL_OPTARG 0
/* Define to 1 if you have the declaration of `ungetc', and to 0 if you don't.
*/
#define HAVE_DECL_UNGETC 1
/* Define to 1 if you have the declaration of `vfprintf', and to 0 if you
don't. */
#define HAVE_DECL_VFPRINTF 1
/* Define if denormalized floats work. */
#define HAVE_DENORMS 1
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define one (and only one) of the following for the format of a `double'.
If your format is not among these choices, or you don't know what it is,
then leave all of them undefined.
"IEEE_LITTLE_SWAPPED" means little endian, but with the two 4-byte halves
swapped, as used by ARM CPUs in little endian mode. */
#undef HAVE_DOUBLE_IEEE_BIG_ENDIAN
#define HAVE_DOUBLE_IEEE_LITTLE_ENDIAN 1
#undef HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
#undef HAVE_DOUBLE_VAX_D
#undef HAVE_DOUBLE_VAX_G
#undef HAVE_DOUBLE_CRAY_CFP
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <fpu_control.h> header file. */
#undef HAVE_FPU_CONTROL_H
/* Define if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the `getrusage' function. */
#undef HAVE_GETRUSAGE
/* Define if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define if 0/0, 1/0, -1/0 and sqrt(-1) work to generate NaN/infinities. */
#define HAVE_INFS 1
/* Define if the system has the type `intmax_t'. */
#undef HAVE_INTMAX_T
/* Define if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define one (just one) of the following for the endiannes of `mp_limb_t'.
If the endianness is not a simple big or little, or you don't know what
it is, then leave both of these undefined. */
#undef HAVE_LIMB_BIG_ENDIAN
#define HAVE_LIMB_LITTLE_ENDIAN 1
#define HAVE_STD__LOCALE 1
/* Define if you have the `localeconv' function. */
#define HAVE_LOCALECONV 1
/* Define if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define if the system has the type `long double'. */
#define HAVE_LONG_DOUBLE 1
/* Define if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define if you have the `lrand48' function. */
#undef HAVE_LRAND48
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define if you have the `mprotect' function. */
#undef HAVE_MPROTECT
/* Define if you have the `obstack_vprintf' function. */
#undef HAVE_OBSTACK_VPRINTF
/* Define if you have the `popen' function. */
#undef HAVE_POPEN
/* Define if you have the `processor_info' function. */
#undef HAVE_PROCESSOR_INFO
/* Define if the system has the type `ptrdiff_t'. */
#define HAVE_PTRDIFF_T 1
/* Define if the system has the type `quad_t'. */
#undef HAVE_QUAD_T
#define HAVE_RAISE 1
/* Define if you have the `read_real_time' function. */
#undef HAVE_READ_REAL_TIME
/* Define if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define if you have the `sigaltstack' function. */
#undef HAVE_SIGALTSTACK
/* Define if you have the `sigstack' function. */
#undef HAVE_SIGSTACK
/* Tune directory speed_cyclecounter, undef=none, 1=32bits, 2=64bits) */
#define HAVE_SPEED_CYCLECOUNTER 2
/* Define if the system has the type `stack_t'. */
#undef HAVE_STACK_T
/* Define if <stdarg.h> exists and works */
#define HAVE_STDARG 1
/* Define if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define if cpp supports the ANSI # stringizing operator. */
#define HAVE_STRINGIZE 1
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
/* Define if you have the `sysconf' function. */
#undef HAVE_SYSCONF
/* Define if you have the `sysctl' function. */
#undef HAVE_SYSCTL
/* Define if you have the `sysctlbyname' function. */
#undef HAVE_SYSCTLBYNAME
/* Define if you have the `syssgi' function. */
#undef HAVE_SYSSGI
/* Define if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/processor.h> header file. */
#undef HAVE_SYS_PROCESSOR_H
/* Define if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define if you have the <sys/syssgi.h> header file. */
#undef HAVE_SYS_SYSSGI_H
/* Define if you have the <sys/systemcfg.h> header file. */
#undef HAVE_SYS_SYSTEMCFG_H
/* Define if you have the <sys/times.h> header file. */
#undef HAVE_SYS_TIMES_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the `times' function. */
#undef HAVE_TIMES
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have vsnprintf and it works properly. */
#undef HAVE_VSNPRINTF
/* Assembler local label prefix */
#undef LSYM_PREFIX
/* Define if you have the `fesetround' function via the <fenv.h> header file.
*/
#undef MPFR_HAVE_FESETROUND
#define HAVE_SSTREAM 1
/* Name of package */
#define PACKAGE "mpir"
/* Define if compiler has function prototypes */
#define PROTOTYPES 1
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* The size of a `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG 4
/* Define if sscanf requires writable inputs */
#undef SSCANF_WRITABLE_INPUT
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Maximum size the tune program can test for KARATSUBA_SQR_THRESHOLD */
#define TUNE_KARATSUBA_SQR_MAX 67
/* ./configure --enable-assert option, to enable some ASSERT()s */
#undef WANT_ASSERT
/* ./configure --enable-fft option, to enable FFTs for multiplication */
#define WANT_FFT 1
/* Define to 1 if --enable-profiling=gprof */
#undef WANT_PROFILING_GPROF
/* Define to 1 if --enable-profiling=prof */
#undef WANT_PROFILING_PROF
/* --enable-alloca=yes */
#define WANT_TMP_ALLOCA 1
/* --enable-alloca=debug */
#undef WANT_TMP_DEBUG
/* --enable-alloca=malloc-notreentrant */
#undef WANT_TMP_NOTREENTRANT
/* --enable-alloca=malloc-reentrant */
#undef WANT_TMP_REENTRANT
/* Define if your processor stores words with the most significant byte first
(like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define if `lex' declares `yytext' as a `char *' by default, not a `char[]'.
*/
#undef YYTEXT_POINTER
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#ifndef __cplusplus
#define inline __inline
#endif
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
#undef volatile
#ifdef _MSC_VER
#define access _access
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define alloca _alloca
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define va_copy(d, s) (d) = (s)
#endif

View File

@ -1,24 +0,0 @@
/* Generic C gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* Values for BITS_PER_MP_LIMB etc will be determined by ./configure and put
in config.h. */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
option(ALLOW_BUNDLED_LEVMAR "Allow use of bundled levmar source" ON)
set(LEVMAR_DIR ${EXTERNAL_DIR}/levmar-2.3)
set(LEVMAR_DIR ${CMAKE_CURRENT_LIST_DIR}/levmar-2.3)
if(ALLOW_BUNDLED_LEVMAR AND EXISTS "${LEVMAR_DIR}/lm.h")
message(STATUS "- levmar - using bundled source")

View File

@ -7,7 +7,7 @@ option(ALLOW_BUNDLED_LIB3DS "Allow use of bundled lib3ds source" ON)
option(ALLOW_SYSTEM_LIB3DS "Allow use of system-provided lib3ds" ON)
find_package(Lib3ds)
set(LIB3DS_DIR ${EXTERNAL_DIR}/lib3ds-1.3.0)
set(LIB3DS_DIR ${CMAKE_CURRENT_LIST_DIR}/lib3ds-1.3.0)
if(ALLOW_SYSTEM_LIB3DS AND TARGET Lib3ds::Lib3ds)
message(STATUS "- lib3ds - using system-provided library")

View File

@ -0,0 +1,18 @@
---
name: 🐛 Bug Report
about: If something isn't working as expected
title: ''
labels: bug, pending verification
assignees: ''
---
#### Describe the bug
<!-- A clear and concise description of what the bug is. -->
#### Platform
<!-- Check all that apply (change to `[x]`) -->
- [ ] Windows
- [ ] macOS
- [ ] Linux

View File

@ -0,0 +1,25 @@
---
name: 😱 Compilation issue
about: Report a problem when compiling the code
title: ''
labels: 'compilation'
assignees: ''
---
#### Describe your issue
<!-- Be sure to include any log file that may help use diagnose the issue -->
#### Checklist
<!-- Check all that apply (change to `[x]`) -->
- [ ] I have read the [bug report](https://libigl.github.io/bug-report/)
- [ ] CMake issue: I have tried with a fresh clone/empty build directory
#### Platform
<!-- Check all that apply (change to `[x]`) -->
- [ ] Windows
- [ ] macOS
- [ ] Linux

View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 🚀 Feature Request
url: https://github.com/libigl/libigl/discussions/new?category_id=32617689
about: Share ideas for new features
- name: ❓ Ask a Question
url: https://github.com/libigl/libigl/discussions/new?category_id=32617688
about: Ask the community for help

View File

@ -0,0 +1,12 @@
Fixes # .
<!-- Describe your changes and what you've already done to test it. -->
#### Checklist
<!-- Check all that apply (change to `[x]`) -->
- [ ] All changes meet [libigl style-guidelines](https://libigl.github.io/style-guidelines/).
- [ ] Adds new .cpp file.
- [ ] Adds corresponding unit test.
- [ ] This is a minor change.

View File

@ -0,0 +1,153 @@
name: Build
on:
push:
branches:
- master
- stable
pull_request:
branches:
- master
- stable
env:
CTEST_OUTPUT_ON_FAILURE: ON
CTEST_PARALLEL_LEVEL: 2
jobs:
####################
# Linux / macOS
####################
Unix:
name: ${{ matrix.name }} (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-latest]
config: [Release]
static: [ON, OFF]
include:
- os: macos-latest
name: macOS
- os: ubuntu-20.04
name: Linux
env:
LIBIGL_NUM_THREADS: 1 # See https://github.com/libigl/libigl/pull/996
steps:
- name: Checkout repository
uses: actions/checkout@v1
with:
fetch-depth: 10
- name: Dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install \
libblas-dev \
libboost-filesystem-dev \
libboost-system-dev \
libboost-thread-dev \
libglu1-mesa-dev \
liblapack-dev \
libmpfr-dev \
xorg-dev \
ccache
- name: Dependencies (macOS)
if: runner.os == 'macOS'
run: brew install boost gmp mpfr ccache
- name: Cache Build
id: cache-build
uses: actions/cache@v1
with:
path: ~/.ccache
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.static }}-cache
- name: Prepare ccache
run: |
ccache --max-size=1.0G
ccache -V && ccache --show-stats && ccache --zero-stats
- name: Configure
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=${{ matrix.config }} \
-DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} \
-DLIBIGL_WITH_CGAL=ON \
-DLIBIGL_WITH_COMISO=ON
- name: Build
run: cd build; make -j2; ccache --show-stats
- name: Tests
run: cd build; ctest --verbose
####################
# Windows
####################
Windows:
name: Windows (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
runs-on: windows-2019
env:
CC: cl.exe
CXX: cl.exe
strategy:
fail-fast: false
matrix:
config: [Release]
static: [ON, OFF]
steps:
- name: Checkout repository
uses: actions/checkout@v1
with:
fetch-depth: 10
- uses: seanmiddleditch/gha-setup-ninja@master
- name: Set env
run: |
echo "BOOST_ROOT=$env:BOOST_ROOT_1_72_0" >> ${env:GITHUB_ENV}
echo "appdata=$env:LOCALAPPDATA" >> ${env:GITHUB_ENV}
- name: Cache build
id: cache-build
uses: actions/cache@v1
with:
path: ${{ env.appdata }}\Mozilla\sccache
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.static }}-cache
- name: Prepare sccache
run: |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop install sccache --global
# Scoop modifies the PATH so we make it available for the next steps of the job
echo "${env:PATH}" >> ${env:GITHUB_PATH}
# We run configure + build in the same step, since they both need to call VsDevCmd
# Also, cmd uses ^ to break commands into multiple lines (in powershell this is `)
- name: Configure and build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x64
cmake -G Ninja ^
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^
-DCMAKE_BUILD_TYPE=${{ matrix.config }} ^
-DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} ^
-DLIBIGL_WITH_CGAL=ON ^
-DLIBIGL_WITH_COMISO=OFF ^
-DCMAKE_JOB_POOLS=pool-linking=1;pool-compilation=2 ^
-DCMAKE_JOB_POOL_COMPILE:STRING=pool-compilation ^
-DCMAKE_JOB_POOL_LINK:STRING=pool-linking ^
-B build ^
-S .
cmake --build build
- name: Tests
run: cd build; ctest --verbose

View File

@ -0,0 +1,190 @@
name: Nightly
on:
schedule:
- cron: '0 4 * * *'
env:
CTEST_OUTPUT_ON_FAILURE: ON
CTEST_PARALLEL_LEVEL: 2
jobs:
####################
# Linux / macOS
####################
# Part of this file is inspired from
# https://github.com/onqtam/doctest/blob/dev/.github/workflows/main.yml
Unix:
name: ${{ matrix.name }} (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name: [
ubuntu-20.04-gcc-8,
ubuntu-20.04-gcc-9,
ubuntu-20.04-gcc-10,
ubuntu-20.04-clang-8,
ubuntu-20.04-clang-9,
ubuntu-20.04-clang-10,
macOS-latest,
]
config: [Debug, Release]
static: [ON, OFF]
include:
- name: ubuntu-20.04-gcc-8
os: ubuntu-20.04
compiler: gcc
version: "8"
- name: ubuntu-20.04-gcc-9
os: ubuntu-20.04
compiler: gcc
version: "9"
- name: ubuntu-20.04-gcc-10
os: ubuntu-20.04
compiler: gcc
version: "10"
- name: ubuntu-20.04-clang-8
os: ubuntu-20.04
compiler: clang
version: "8"
- name: ubuntu-20.04-clang-9
os: ubuntu-20.04
compiler: clang
version: "9"
- name: ubuntu-20.04-clang-10
os: ubuntu-20.04
compiler: clang
version: "10"
- name: macOS-latest
os: macOS-latest
# Build tutorials for most configurations
- tutorials: ON
# Except with Debug mode
- config: Debug
tutorials: OFF
env:
LIBIGL_NUM_THREADS: 1 # See https://github.com/libigl/libigl/pull/996
steps:
- name: Checkout repository
uses: actions/checkout@v1
with:
fetch-depth: 10
- name: Dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
if [ "${{ matrix.compiler }}" = "gcc" ]; then
sudo apt-get install -y g++-${{ matrix.version }}
echo "CC=gcc-${{ matrix.version }}" >> $GITHUB_ENV
echo "CXX=g++-${{ matrix.version }}" >> $GITHUB_ENV
else
sudo apt-get install -y clang-${{ matrix.version }}
echo "CC=clang-${{ matrix.version }}" >> $GITHUB_ENV
echo "CXX=clang++-${{ matrix.version }}" >> $GITHUB_ENV
fi
sudo apt-get install \
libblas-dev \
libboost-filesystem-dev \
libboost-system-dev \
libboost-thread-dev \
libglu1-mesa-dev \
liblapack-dev \
libmpfr-dev \
xorg-dev
- name: Dependencies (macOS)
if: runner.os == 'macOS'
run: brew install boost gmp mpfr
- name: Configure
run: |
mkdir -p build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=${{ matrix.config }} \
-DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} \
-DLIBIGL_BUILD_TUTORIALS=${{ matrix.tutorials }} \
-DLIBIGL_WITH_CGAL=ON \
-DLIBIGL_WITH_COMISO=ON
- name: Free Disk Space
if: runner.os == 'Linux'
run: |
sudo swapoff -a
sudo apt clean
sudo rm -rf /swapfile /usr/share/dotnet /usr/local/lib/android /opt/ghc
df -h
- name: Build
run: cd build; make -j1
- name: Tests
run: cd build; ctest --verbose
####################
# Windows
####################
Windows:
name: Windows (${{ matrix.config }}, ${{ fromJSON('["Static", "HeaderOnly"]')[matrix.static == 'ON'] }})
runs-on: windows-2019
env:
CC: cl.exe
CXX: cl.exe
strategy:
fail-fast: false
matrix:
config: [Debug, Release]
static: [ON, OFF]
include:
- config: Debug
tutorials: OFF
- config: Release
tutorials: ON
steps:
- name: Checkout repository
uses: actions/checkout@v1
with:
fetch-depth: 10
- uses: seanmiddleditch/gha-setup-ninja@master
- name: Set env
run: |
echo "BOOST_ROOT=$env:BOOST_ROOT_1_72_0" >> ${env:GITHUB_ENV}
# We run configure + build in the same step, since they both need to call VsDevCmd
# Also, cmd uses ^ to break commands into multiple lines (in powershell this is `)
- name: Configure and build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x64
cmake -G Ninja ^
-DCMAKE_BUILD_TYPE=${{ matrix.config }} ^
-DLIBIGL_USE_STATIC_LIBRARY=${{ matrix.static }} ^
-DLIBIGL_BUILD_TUTORIALS=${{ matrix.tutorials }} ^
-DLIBIGL_WITH_CGAL=ON ^
-DLIBIGL_WITH_COMISO=OFF ^
-DCMAKE_JOB_POOLS=job-pool=1 ^
-DCMAKE_JOB_POOL_COMPILE:STRING=job-pool ^
-DCMAKE_JOB_POOL_LINK:STRING=job-pool ^
-B build ^
-S .
cd build
ninja -j 1 -k 10
- name: Tests
run: cd build; ctest --verbose

100
src/external/libigl-2.3.0/.gitignore vendored Normal file
View File

@ -0,0 +1,100 @@
# use glob syntax.
*.a
*.dylib
*.egg-info/
*.exe
*.ilk
*.log
*.o
*.opensdf
*.orig
*.pdb
*.psess
*.pyc
*.sdf
*.so
*.so.[0123456789]
*.so.[0123456789].[0123456789]
*.suo
*.swo
*.swp
*.tlog
*.user
*.vsp
*CMakeFiles*
*buildXcode*
*tags
*~
.DS_Store
.idea/
.vs/
.vscode/
/external
Debug/
README.html
Release/
Untitled.ipynb
build
doc.html
documentation/*.aux
documentation/*.log
documentation/*.out
example
example1
example_header_only
example_static
examples/*/*.mexmaci64
examples/*/*.rbr
examples/bbw/bbw_demo
examples/bbw/bbw_demo_selfcontained.zip
examples/bbw/bbw_demo_selfcontained/*
examples/bbw/examples/*-volume.dmat
examples/bbw/examples/*-volume.mesh
examples/principal_curvature/curvature
examples/quicklook-mesh/Mesh.qlgenerator/*
examples/upright/upright
external/MeshFix/meshfix
external/embree/build/*
external/glew/build
external/glfw/build
external/libpng/build
external/medit/rebar.rbr
external/tetgen/tetgen
external/tinyxml2/build
external/tinyxml2/test
external/tinyxml2/tinyxml2.pc
external/yimg/showpng
iglhelpers.pyc
lib
libigl.zip
optional/build
python/.idea
python/.ipynb_checkpoints
python/__pycache__
python/build
python/build2
python/build3
python/build4
python/builddebug
python/buildstatic
python/py_igl/todo
python/py_igl/todo
python/scripts/generated
scripts/change_name.sh
site/
syntax: glob
tests/bin
tests/build
tests/data
tutorial/*/*.mexmaci64
tutorial/*/Makefile
tutorial/*/build/*
tutorial/.idea
tutorial/XXX_test/CMakeLists.txt
tutorial/XXX_test/main.cpp
tutorial/build
tutorial/cmake-build-debug
tutorial/data
tutorial/readme.html
untitled
scripts

19
src/external/libigl-2.3.0/.mailmap vendored Normal file
View File

@ -0,0 +1,19 @@
#
# This list is used by git-shortlog to fix a few botched name translations
# in the libigl archive, either because the author's full name was messed up
# and/or not always written the same way, making contributions from the
# same person appearing not to be so.
#
Alec Jacobson <alecjacobson@gmail.com> Alec Jacobson (jalec <Alec Jacobson (jalec@inf.ethz.ch)>
Alec Jacobson <alecjacobson@gmail.com> jalec <devnull@localhost>
Alec Jacobson <alecjacobson@gmail.com> Alec Jacobson <ajx@Luftmatratze.local>
Alec Jacobson <alecjacobson@gmail.com> ajx <devnull@localhost>
Alec Jacobson <alecjacobson@gmail.com> mangledorf <alecjacobson@gmail.com>
Daniele Panozzo <panozzo@inf.ethz.ch> Daniele Panozzo <daniele.panozzo@gmail.com>
Daniele Panozzo <panozzo@inf.ethz.ch> dpanozzo <devnull@localhost>
Wenzel Jakob <wenzel@inf.ethz.ch> Wenzel Jakob <wenzel@cs.cornell.edu>
Olga Diamanti <olga.diamanti@inf.ethz.ch> dolga <devnull@localhost>
schuellc <schuellchr@gmail.com> schuellc <devnull@localhost>
Kenshi Takayama <kenshi84@gmail.com> Kenshi Takayama (kenshi <Kenshi Takayama (kenshi@gmail.com)>
Kenshi Takayama <kenshi84@gmail.com> kenshi <kenshi@jackal.ethz.ch>
Kenshi Takayama <kenshi84@gmail.com> kenshi84 <kenshi84@gmail.com>

View File

@ -0,0 +1,74 @@
cmake_minimum_required(VERSION 3.1)
# Toggles the use of the hunter package manager
option(HUNTER_ENABLED "Enable Hunter package manager support" OFF)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.23.171.tar.gz"
SHA1 "5d68bcca78eee347239ca5f4d34f4b6c12683154"
)
project(libigl)
# Detects whether this is a top-level project
get_directory_property(LIBIGL_PARENT_DIR PARENT_DIRECTORY)
if(NOT LIBIGL_PARENT_DIR)
set(LIBIGL_TOPLEVEL_PROJECT ON)
else()
set(LIBIGL_TOPLEVEL_PROJECT OFF)
endif()
# Build tests and tutorials
option(LIBIGL_BUILD_TESTS "Build libigl unit test" ${LIBIGL_TOPLEVEL_PROJECT})
option(LIBIGL_BUILD_TUTORIALS "Build libigl tutorial" ${LIBIGL_TOPLEVEL_PROJECT})
option(LIBIGL_EXPORT_TARGETS "Export libigl CMake targets" ${LIBIGL_TOPLEVEL_PROJECT})
# USE_STATIC_LIBRARY speeds up the generation of multiple binaries,
# at the cost of a longer initial compilation time
# (by default, static build is off since libigl is a header-only library)
option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" ON)
# All dependencies that are downloaded as cmake projects and tested on the auto-builds are ON
# (by default, all build options are off)
option(LIBIGL_WITH_COMISO "Use CoMiso" ON)
option(LIBIGL_WITH_EMBREE "Use Embree" ON)
option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
option(LIBIGL_WITH_PNG "Use PNG" ON)
option(LIBIGL_WITH_TETGEN "Use Tetgen" ON)
option(LIBIGL_WITH_TRIANGLE "Use Triangle" ON)
option(LIBIGL_WITH_PREDICATES "Use exact predicates" ON)
option(LIBIGL_WITH_XML "Use XML" ON)
option(LIBIGL_WITH_PYTHON "Use Python" OFF)
### End
if(${LIBIGL_WITH_PYTHON})
message(FATAL_ERROR "Python binding are in the process of being redone. Please use the master branch or refer to https://github.com/geometryprocessing/libigl-python-bindings for the developement version or https://anaconda.org/conda-forge/igl for the stable version.")
endif()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
### conditionally compile certain modules depending on libraries found on the system
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
### Adding libIGL: choose the path to your local copy libIGL
include(libigl)
if(LIBIGL_BUILD_TUTORIALS)
add_subdirectory(tutorial)
endif()
if(LIBIGL_BUILD_TESTS)
include(CTest)
enable_testing()
add_subdirectory(tests)
endif()
if(LIBIGL_TOPLEVEL_PROJECT)
# Set folders for Visual Studio/Xcode
igl_set_folders()
endif()

674
src/external/libigl-2.3.0/LICENSE.GPL vendored Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

373
src/external/libigl-2.3.0/LICENSE.MPL2 vendored Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

8
src/external/libigl-2.3.0/README.md vendored Normal file
View File

@ -0,0 +1,8 @@
# libigl - A simple C++ geometry processing library
[![](https://github.com/libigl/libigl/workflows/Build/badge.svg?event=push)](https://github.com/libigl/libigl/actions?query=workflow%3ABuild+branch%3Amaster+event%3Apush)
[![](https://github.com/libigl/libigl/workflows/Nightly/badge.svg)](https://github.com/libigl/libigl/actions?query=workflow%3ANightly+branch%3Amaster+event%3Aschedule)
[![](https://anaconda.org/conda-forge/igl/badges/installer/conda.svg)](https://anaconda.org/conda-forge/igl)
![](https://libigl.github.io/libigl-teaser.png)
Documentation, tutorial, and instructions at <https://libigl.github.io>.

View File

@ -0,0 +1,85 @@
################################################################################
if(NOT (${CMAKE_VERSION} VERSION_LESS "3.8.0"))
# For CMake 3.8 and above, we can use meta features directly provided by CMake itself
set(CXX11_FEATURES cxx_std_11)
set(CXX14_FEATURES cxx_std_14)
set(CXX17_FEATURES cxx_std_17)
return()
endif()
################################################################################
set(CXX11_FEATURES
cxx_auto_type
cxx_constexpr
)
set(CXX14_FEATURES
cxx_generic_lambdas
)
set(CXX17_FEATURES
)
################################################################################
# https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
# cxx_aggregate_default_initializers Aggregate default initializers, as defined in N3605.
# cxx_alias_templates Template aliases, as defined in N2258.
# cxx_alignas Alignment control alignas, as defined in N2341.
# cxx_alignof Alignment control alignof, as defined in N2341.
# cxx_attributes Generic attributes, as defined in N2761.
# cxx_attribute_deprecated deprecated]] attribute, as defined in N3760.
# cxx_auto_type Automatic type deduction, as defined in N1984.
# cxx_binary_literals Binary literals, as defined in N3472.
# cxx_constexpr Constant expressions, as defined in N2235.
# cxx_contextual_conversions Contextual conversions, as defined in N3323.
# cxx_decltype_incomplete_return_types Decltype on incomplete return types, as defined in N3276.
# cxx_decltype Decltype, as defined in N2343.
# cxx_decltype_auto decltype(auto) semantics, as defined in N3638.
# cxx_default_function_template_args Default template arguments for function templates, as defined in DR226
# cxx_defaulted_functions Defaulted functions, as defined in N2346.
# cxx_defaulted_move_initializers Defaulted move initializers, as defined in N3053.
# cxx_delegating_constructors Delegating constructors, as defined in N1986.
# cxx_deleted_functions Deleted functions, as defined in N2346.
# cxx_digit_separators Digit separators, as defined in N3781.
# cxx_enum_forward_declarations Enum forward declarations, as defined in N2764.
# cxx_explicit_conversions Explicit conversion operators, as defined in N2437.
# cxx_extended_friend_declarations Extended friend declarations, as defined in N1791.
# cxx_extern_templates Extern templates, as defined in N1987.
# cxx_final Override control final keyword, as defined in N2928, N3206 and N3272.
# cxx_func_identifier Predefined __func__ identifier, as defined in N2340.
# cxx_generalized_initializers Initializer lists, as defined in N2672.
# cxx_generic_lambdas Generic lambdas, as defined in N3649.
# cxx_inheriting_constructors Inheriting constructors, as defined in N2540.
# cxx_inline_namespaces Inline namespaces, as defined in N2535.
# cxx_lambdas Lambda functions, as defined in N2927.
# cxx_lambda_init_captures Initialized lambda captures, as defined in N3648.
# cxx_local_type_template_args Local and unnamed types as template arguments, as defined in N2657.
# cxx_long_long_type long long type, as defined in N1811.
# cxx_noexcept Exception specifications, as defined in N3050.
# cxx_nonstatic_member_init Non-static data member initialization, as defined in N2756.
# cxx_nullptr Null pointer, as defined in N2431.
# cxx_override Override control override keyword, as defined in N2928, N3206 and N3272.
# cxx_range_for Range-based for, as defined in N2930.
# cxx_raw_string_literals Raw string literals, as defined in N2442.
# cxx_reference_qualified_functions Reference qualified functions, as defined in N2439.
# cxx_relaxed_constexpr Relaxed constexpr, as defined in N3652.
# cxx_return_type_deduction Return type deduction on normal functions, as defined in N3386.
# cxx_right_angle_brackets Right angle bracket parsing, as defined in N1757.
# cxx_rvalue_references R-value references, as defined in N2118.
# cxx_sizeof_member Size of non-static data members, as defined in N2253.
# cxx_static_assert Static assert, as defined in N1720.
# cxx_strong_enums Strongly typed enums, as defined in N2347.
# cxx_thread_local Thread-local variables, as defined in N2659.
# cxx_trailing_return_types Automatic function return type, as defined in N2541.
# cxx_unicode_literals Unicode string literals, as defined in N2442.
# cxx_uniform_initialization Uniform initialization, as defined in N2640.
# cxx_unrestricted_unions Unrestricted unions, as defined in N2544.
# cxx_user_literals User-defined literals, as defined in N2765.
# cxx_variable_templates Variable templates, as defined in N3651.
# cxx_variadic_macros Variadic macros, as defined in N1653.
# cxx_variadic_templates Variadic templates, as defined in N2242.
# cxx_template_template_parameters Template template parameters, as defined in ISO/IEC 14882:1998.

View File

@ -0,0 +1,17 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
cmake_minimum_required(VERSION 3.1)
project(${DL_ARGS_PROJ}-download NONE)
include(ExternalProject)
ExternalProject_Add(${DL_ARGS_PROJ}-download
${DL_ARGS_UNPARSED_ARGUMENTS}
SOURCE_DIR "${DL_ARGS_SOURCE_DIR}"
BINARY_DIR "${DL_ARGS_BINARY_DIR}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

View File

@ -0,0 +1,182 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
#
# MODULE: DownloadProject
#
# PROVIDES:
# download_project( PROJ projectName
# [PREFIX prefixDir]
# [DOWNLOAD_DIR downloadDir]
# [SOURCE_DIR srcDir]
# [BINARY_DIR binDir]
# [QUIET]
# ...
# )
#
# Provides the ability to download and unpack a tarball, zip file, git repository,
# etc. at configure time (i.e. when the cmake command is run). How the downloaded
# and unpacked contents are used is up to the caller, but the motivating case is
# to download source code which can then be included directly in the build with
# add_subdirectory() after the call to download_project(). Source and build
# directories are set up with this in mind.
#
# The PROJ argument is required. The projectName value will be used to construct
# the following variables upon exit (obviously replace projectName with its actual
# value):
#
# projectName_SOURCE_DIR
# projectName_BINARY_DIR
#
# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically
# need to be provided. They can be specified if you want the downloaded source
# and build directories to be located in a specific place. The contents of
# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the
# locations used whether you provide SOURCE_DIR/BINARY_DIR or not.
#
# The DOWNLOAD_DIR argument does not normally need to be set. It controls the
# location of the temporary CMake build used to perform the download.
#
# The PREFIX argument can be provided to change the base location of the default
# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments
# are provided, then PREFIX will have no effect. The default value for PREFIX is
# CMAKE_BINARY_DIR.
#
# The QUIET option can be given if you do not want to show the output associated
# with downloading the specified project.
#
# In addition to the above, any other options are passed through unmodified to
# ExternalProject_Add() to perform the actual download, patch and update steps.
# The following ExternalProject_Add() options are explicitly prohibited (they
# are reserved for use by the download_project() command):
#
# CONFIGURE_COMMAND
# BUILD_COMMAND
# INSTALL_COMMAND
# TEST_COMMAND
#
# Only those ExternalProject_Add() arguments which relate to downloading, patching
# and updating of the project sources are intended to be used. Also note that at
# least one set of download-related arguments are required.
#
# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to
# prevent a check at the remote end for changes every time CMake is run
# after the first successful download. See the documentation of the ExternalProject
# module for more information. It is likely you will want to use this option if it
# is available to you. Note, however, that the ExternalProject implementation contains
# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when
# using the URL download method or when specifying a SOURCE_DIR with no download
# method. Fixes for these have been created, the last of which is scheduled for
# inclusion in CMake 3.8.0. Details can be found here:
#
# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c
# https://gitlab.kitware.com/cmake/cmake/issues/16428
#
# If you experience build errors related to the update step, consider avoiding
# the use of UPDATE_DISCONNECTED.
#
# EXAMPLE USAGE:
#
# include(DownloadProject)
# download_project(PROJ googletest
# GIT_REPOSITORY https://github.com/google/googletest.git
# GIT_TAG master
# UPDATE_DISCONNECTED 1
# QUIET
# )
#
# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
#
#========================================================================================
set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}")
include(CMakeParseArguments)
function(download_project)
set(options QUIET)
set(oneValueArgs
PROJ
PREFIX
DOWNLOAD_DIR
SOURCE_DIR
BINARY_DIR
# Prevent the following from being passed through
CONFIGURE_COMMAND
BUILD_COMMAND
INSTALL_COMMAND
TEST_COMMAND
)
set(multiValueArgs "")
cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Hide output if requested
if (DL_ARGS_QUIET)
set(OUTPUT_QUIET "OUTPUT_QUIET")
else()
unset(OUTPUT_QUIET)
message(STATUS "Downloading/updating ${DL_ARGS_PROJ}")
endif()
# Set up where we will put our temporary CMakeLists.txt file and also
# the base point below which the default source and binary dirs will be.
# The prefix must always be an absolute path.
if (NOT DL_ARGS_PREFIX)
set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}")
else()
get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if (NOT DL_ARGS_DOWNLOAD_DIR)
set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download")
endif()
# Ensure the caller can know where to find the source and build directories
if (NOT DL_ARGS_SOURCE_DIR)
set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src")
endif()
if (NOT DL_ARGS_BINARY_DIR)
set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build")
endif()
set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE)
set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE)
# The way that CLion manages multiple configurations, it causes a copy of
# the CMakeCache.txt to be copied across due to it not expecting there to
# be a project within a project. This causes the hard-coded paths in the
# cache to be copied and builds to fail. To mitigate this, we simply
# remove the cache if it exists before we configure the new project. It
# is safe to do so because it will be re-generated. Since this is only
# executed at the configure step, it should not cause additional builds or
# downloads.
file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt")
# Create and build a separate CMake project to carry out the download.
# If we've already previously done these steps, they will not cause
# anything to be updated, so extra rebuilds of the project won't occur.
# Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
# has this set to something not findable on the PATH.
configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in"
"${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
-D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}"
.
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
endfunction()

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