diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 29b8464a925773f55b4a17a074e99f1902a58e66..eb6e2d5541e228a54a7f3a0b60f18729f6f2daf1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,15 +1,15 @@ -image: kitware/paraview-ci-plugin:vtk-v9.1.0-stdthread-python-mpi stages: - build - test -build-plugin: +build-vtkmodule: + image: kitware/paraview-ci-plugin:vtk-v9.1.0-stdthread-python-mpi stage: build script: - apt-get install -y libcgal-dev libeigen3-dev - mkdir -p build - cd build - - cmake -DVTK_DIR=/vtk/build/ -D BUILD_TESTING=ON .. + - cmake -DVTK_DIR=/vtk/build/ -DBUILD_TESTING=ON -DBUILD_PYTHON_WRAPPERS=ON -DVESPA_BUILD_MODE=VTK .. - cmake --build . --config Release --parallel 2 tags: - build @@ -22,9 +22,10 @@ build-plugin: paths: - build/ -test-plugin: +test-vtkmodule: + image: kitware/paraview-ci-plugin:vtk-v9.1.0-stdthread-python-mpi stage: test - needs: ['build-plugin'] + needs: ['build-vtkmodule'] script: - cd build - ctest -VV @@ -34,4 +35,29 @@ test-plugin: - linux - vtk-cgal dependencies: - - build-plugin + - build-vtkmodule + +build-pvplugin: + image: kitware/paraview-for-ci:latest + stage: build + script: + # This is needed because the build of ParaView uses some absolute path + - ln -s /paraview/gitlab-kitware-sciviz-ci/ /builds/gitlab-kitware-sciviz-ci + - git submodule update --init --recursive + - apt update + - apt-get install -y libcgal-dev libeigen3-dev + - mkdir -p build + - cd build + - cmake -DCMAKE_PREFIX_PATH=/opt/paraview/install/ -DBUILD_TESTING=OFF -DBUILD_PYTHON_WRAPPERS=OFF -DVESPA_BUILD_MODE=PARAVIEW .. + - cmake --build . --config Release --parallel 2 + tags: + - build + - docker + - linux + - vtk-cgal + - paraview + artifacts: + expire_in: 1h + when: always + paths: + - build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bc549d90e0dbb888c65e8428a1785be181cc54d..ffa4cfccb3911e6fb1612206714d2da9bcde790b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.8) -project (vespa) +project(vespa) ## Config @@ -11,25 +11,13 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") option(BUILD_SHARED_LIBS "Build shared library" ON) +set(VESPA_BUILD_MODE "NONE" CACHE STRING "Build VESPA VTK module or ParaView plugin") +set_property(CACHE VESPA_BUILD_MODE PROPERTY STRINGS NONE VTK PARAVIEW) include(CTest) ## Deps -find_package(VTK - COMPONENTS - CommonCore - CommonDataModel - CommonExecutionModel - FiltersCore - FiltersExtraction - FiltersGeometry - Python - OPTIONAL_COMPONENTS - CommonSystem - IOXML - TestingCore) - find_package(CGAL REQUIRED) find_package(Eigen3 REQUIRED 3.2.0) @@ -40,45 +28,86 @@ else() include_directories(${EIGEN3_INCLUDE_DIR}) endif() -## VTK Module -option(FORCE_STATIC_MODULES "Build VTK modules statically" OFF) -mark_as_advanced(FORCE_STATIC_MODULES) -if (FORCE_STATIC_MODULES) - set(FORCE_STATIC_MODULES_STRING FORCE_STATIC) -else () - set(FORCE_STATIC_MODULES_STRING) -endif() - -vtk_module_find_modules(vtkcgal_module_files "${CMAKE_CURRENT_SOURCE_DIR}/vespa") +if (VESPA_BUILD_MODE MATCHES "PARAVIEW") + ## ParaView plugin -vtk_module_scan( - MODULE_FILES ${vtkcgal_module_files} - PROVIDES_MODULES vtkcgal_provided_modules - WANT_BY_DEFAULT ON - ENABLE_TESTS ON) + find_package(ParaView REQUIRED) -vtk_module_python_default_destination(python_destination) + set("_paraview_plugin_default_${CMAKE_PROJECT_NAME}" ON) + paraview_plugin_scan( + PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/ParaViewPlugin/paraview.plugin" + ENABLE_BY_DEFAULT ON + PROVIDES_PLUGINS vtkcgal_provided_modules + REQUIRES_MODULES pv_required_modules) -vtk_module_build( - MODULES ${vtkcgal_provided_modules} - INSTALL_EXPORT vespa - INSTALL_HEADERS ON - CMAKE_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vespa" - HEADERS_DESTINATION "include") + foreach (module IN LISTS pv_required_modules) + if (NOT TARGET "${module}") + message("${CMAKE_PROJECT_NAME}: missing required module ${module}") + return () + endif () + endforeach () + paraview_plugin_build( + RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}" + PLUGINS ${vtkcgal_provided_modules}) + +elseif (VESPA_BUILD_MODE MATCHES "VTK") + ## VTK Module + + find_package(VTK + COMPONENTS + CommonCore + CommonDataModel + CommonExecutionModel + FiltersCore + FiltersExtraction + FiltersGeometry + Python + OPTIONAL_COMPONENTS + CommonSystem + IOXML + TestingCore) + + option(FORCE_STATIC_MODULES "Build VTK modules statically" OFF) + mark_as_advanced(FORCE_STATIC_MODULES) + if (FORCE_STATIC_MODULES) + set(FORCE_STATIC_MODULES_STRING FORCE_STATIC) + else () + set(FORCE_STATIC_MODULES_STRING) + endif() + + vtk_module_find_modules(vtkcgal_module_files "${CMAKE_CURRENT_SOURCE_DIR}/vespa") + + vtk_module_scan( + MODULE_FILES ${vtkcgal_module_files} + PROVIDES_MODULES vtkcgal_provided_modules + WANT_BY_DEFAULT ON + ENABLE_TESTS ON) + + vtk_module_python_default_destination(python_destination) + + vtk_module_build( + MODULES ${vtkcgal_provided_modules} + INSTALL_EXPORT vespa + INSTALL_HEADERS ON + CMAKE_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vespa" + HEADERS_DESTINATION "include") -## Install + ## Install + set(vespaExport ${vtkcgal_provided_modules}) + export( + TARGETS ${vespaExport} + NAMESPACE VTK:: + FILE "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/vespa/vespa-targets.cmake") + install( + EXPORT vespa + NAMESPACE VTK:: + FILE vespa-targets.cmake + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vespa") -set(vespaExport ${vtkcgal_provided_modules}) -export( - TARGETS ${vespaExport} - NAMESPACE VTK:: - FILE "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/vespa/vespa-targets.cmake") -install( - EXPORT vespa - NAMESPACE VTK:: - FILE vespa-targets.cmake - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vespa") +endif() ## Python wrapping @@ -126,4 +155,3 @@ if(BUILD_PYTHON_WRAPPERS) DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vespaPython") endif() - diff --git a/ParaViewPlugin/CMakeLists.txt b/ParaViewPlugin/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6c31ec353ed97117e52fe8431d49956822e5b52 --- /dev/null +++ b/ParaViewPlugin/CMakeLists.txt @@ -0,0 +1,17 @@ +paraview_add_plugin(VESPAPlugin + VERSION "1.0" + REQUIRED_ON_CLIENT + REQUIRED_ON_SERVER + SERVER_MANAGER_XML VESPAFilters.xml + MODULES + vtkCGALDelaunay + vtkCGALPMP + MODULE_FILES + "${CMAKE_CURRENT_SOURCE_DIR}/../vespa/Delaunay/vtk.module" + "${CMAKE_CURRENT_SOURCE_DIR}/../vespa/PolygonMeshProcessing/vtk.module" +) + +target_link_libraries(VESPAPlugin + PRIVATE + vtkCGALDelaunay + vtkCGALPMP) diff --git a/ParaViewPlugin/VESPAFilters.xml b/ParaViewPlugin/VESPAFilters.xml new file mode 100644 index 0000000000000000000000000000000000000000..8bd948d3775824626a6c7340f605f5c2b1fe2322 --- /dev/null +++ b/ParaViewPlugin/VESPAFilters.xml @@ -0,0 +1,460 @@ + + + + + + + This filter creates planar Delaunay meshes from a set of planar points. + Edge and polygon constraints can be specified as vtkPolyData lines and polygons. + The input mesh needs to be planar along the x, y or z axis. + Constraints should not overlap each other. + + + + + + + + + + + + + + + + + + + + + This filter performs boolean operations between two closed polygonal meshes. These + operations include union, intersection, and difference. The resulting mesh is closed. + + + + + + + + + + + + + + + + + + + + + + Second dataset. + + + + + + + + + + + Type of boolean operation. + + + + + + + + + + + + This filter remeshes a triangulated vtkPolyData using the CGAL + isotropic_remesh method. Feature edges are protected. + + + + + + + + + + + + + + + Target length for edges. + + + + + + + Number of iterations for the remeshing algorithm. + + + + + + + Angle threshold for feature edges to protect (in degrees). + + + + + + + + + + + + This filter deforms a surface mesh by moving control points to target positions. + Neighboring points contained in a Region of Interest (ROI) may be moved to obtain + a smooth deformation. + + The filter can take three inputs: + - the vtkPolyData mesh to deform with unique IDs for the points + - a vtkPointSet with the target positions of the control points, identified by their IDs + - a vtkSelection corresponding to the ROI (optional) + + If a ROI is not specified, it is defined with the control points. + In this case, the control points will simply be moved to their destinations without + modifying the rest of the mesh. + + + + + + + + + + + + + + + + + + + + + + + Point set describing the control points and their target positions. + + + + + + + + + + + + + Selection containing the region of interest (points that can be moved). + + + + + + + + + + + Input array describing global point IDs. + + + + + + + + + + Number of iterations used in the deformation process. + + + + + + + Tolerance of the energy convergence used in the deformation process. + If 0 is specified, no energy criterion is used. + + + + + + + + + + + + This filter performs a surface mesh subdivision by creating new points to + refine and smoothen a polygonal mesh. Several subdivision methods are available: + - Catmull-Clark based on the PQQ pattern + - Loop based on the PTQ pattern + - Doo-Sabin based on the DQQ pattern + - Sqrt3 based on the Sqrt3 pattern + + + + + + + + + + + + + + + + + + + + + Type of subdivision. + + + + + + + Number of subdivisions. + + + + + + + + + + + + This filter fills a selected hole (or patch) in a triangulated vtkPolyData using meshing, + refining and fairing. Note that if a patch is selected (even without an existing hole), the + the selected triangles will be removed first. + + + + + + + + + + + + + + + + + + + + + + Input that provides the selection specifying the patch or hole to fill. + + + + + + + + + + Value for the tangential continuity of the resulting surface patch. + Possible values are 0, 1 and 2, referring to C0, C1 and C2 continuity. + Use 0 for planar filling. + + + + + + + + + + + + This filter fairs (smoothes) a selected region of a triangulated vtkPolyData + by moving vertices. + + + + + + + + + + + + + + + + + + + + + + Input that provides the selection specifying the region to fair. + + + + + + + + + + + + + + + This filter smoothes the overall shape of a triangulated vtkPolyData + using the mean curvature. The degree of smoothing can be controlled using + the number of iterations as well as the time step. + + + + + + + + + + + + + + + + Number of iterations for the smoothing algorithm. + + + + + + + Time step indicating the smoothing speed. + A higher value leads to a faster distortion of the shape. + Standard values lie between 1e-6 and 1. + + + + + + + + + + + + diff --git a/ParaViewPlugin/paraview.plugin b/ParaViewPlugin/paraview.plugin new file mode 100644 index 0000000000000000000000000000000000000000..4aa87f369af66e8517673a84495797e2a1d6929d --- /dev/null +++ b/ParaViewPlugin/paraview.plugin @@ -0,0 +1,4 @@ +NAME + VESPAPlugin +DESCRIPTION + ParaView plugin based on the VESPA VTK module diff --git a/README.md b/README.md index bbe3d17b0ad2a8a979c9aa4e5b2c31d0ba78a366..9d79b5f3f25c88453153a3f9ed4bc146369a33b7 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,19 @@ # Brief -This project contains VTK filters that uses CGAL for mesh processing. +This project contains VTK filters that use CGAL for mesh processing. +The filters can be used either as part of a VTK module or ParaView plugin. This project is distributed under a BSD-3 License, but as it is linked to CGAL, any binary generated with it retains the GPLv3 license. # How to install -The VESPA project requires the [CMake](https://cmake.org/) build system, the [VTK library](https://vtk.org/) -and the [CGAL library](https://www.cgal.org/) on your system. +The VESPA project requires on your system: + +* the [CMake](https://cmake.org/) build system, +* the [VTK library](https://vtk.org/) for the module or [ParaView software](https://www.paraview.org/) for the plugin, +* the [CGAL library](https://www.cgal.org/). ### VTK @@ -20,6 +24,13 @@ We need VTK >= 9.0. It can be installed: * using the package manager of your system (including brew on OSX, or vcpkg on Windows), * manually using [CMake instructions](https://vtk.org/Wiki/VTK/Configure_and_Build). +### ParaView + +We need ParaView >= 5.10.0. It can be installed: +* using the package manager of your system (including brew on OSX, or vcpkg on Windows), +* by downloading the software [on the official website](https://www.paraview.org/download/), +* manually using [CMake instructions](https://gitlab.kitware.com/paraview/paraview/-/blob/master/Documentation/dev/build.md). + ### CGAL We need CGAL >= 5.3. It can be installed: @@ -32,7 +43,8 @@ Then, we can install this project using the standard CMake procedure: 1. Create a build folder 1. Launch CMake with this repository as source folder -1. Configure the project. It will need VTK and CGAL. +1. Configure the project. It will need CGAL, as well as VTK or ParaView depending on whether the VTK module or ParaView plugin should be built. +To specify which one to build, set the CMake variable `VESPA_BUILD_MODE` to `VTK` or `PARAVIEW`, respectively. - If you have installed a library in a custom folder, you can find it in CMake by giving the folder: **install_dir**/lib/cmake/**project-version**. For example, for VTK: **install_dir**/lib/cmake/vtk-9.1. diff --git a/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.cxx b/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.cxx index ece4bf2dba4f3f1251488bd9eefe25ad9bba7b5d..8af35e75be3c3fbd7de935e186de41084e4f7872 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.cxx +++ b/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.cxx @@ -50,6 +50,18 @@ int vtkCGALMeshDeformation::FillInputPortInformation(int port, vtkInformation* i return 1; } +//------------------------------------------------------------------------------ +void vtkCGALMeshDeformation::SetSourceConnection(vtkAlgorithmOutput* algOutput) +{ + this->SetInputConnection(1, algOutput); +} + +//------------------------------------------------------------------------------ +void vtkCGALMeshDeformation::SetSelectionConnection(vtkAlgorithmOutput* algOutput) +{ + this->SetInputConnection(2, algOutput); +} + //------------------------------------------------------------------------------ int vtkCGALMeshDeformation::RequestData( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) diff --git a/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.h b/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.h index 522e45115209839a25abac5d4f95f252937ea306..c276cbfa3f63b2214a226391bf3bc013ec86b333 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.h +++ b/vespa/PolygonMeshProcessing/vtkCGALMeshDeformation.h @@ -30,6 +30,16 @@ public: vtkTypeMacro(vtkCGALMeshDeformation, vtkCGALPolyDataAlgorithm); void PrintSelf(ostream& os, vtkIndent indent) override; + /** + * Set input connection for the second input (vtkPointSet). + **/ + void SetSourceConnection(vtkAlgorithmOutput* algOutput); + + /** + * Set input connection for the third input (vtkSelection). + **/ + void SetSelectionConnection(vtkAlgorithmOutput* algOutput); + ///@{ /** * Get/set the number of iterations used in the deformation process. diff --git a/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.cxx b/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.cxx index 473cd0e384e7cedf67ace661eae32eaa752b3dd3..d78a44d8872621e4c7a5cd2f8376e5cc457a7289 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.cxx +++ b/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.cxx @@ -54,6 +54,12 @@ int vtkCGALPatchFilling::FillInputPortInformation(int port, vtkInformation* info return 1; } +//------------------------------------------------------------------------------ +void vtkCGALPatchFilling::SetSourceConnection(vtkAlgorithmOutput* algOutput) +{ + this->SetInputConnection(1, algOutput); +} + //------------------------------------------------------------------------------ int vtkCGALPatchFilling::RequestData( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) diff --git a/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.h b/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.h index b2dad0d01c61d9c0ddf10d4a1115b2bbde7691c9..528fbfaea8e2aac493bc7e09dbf729f22e0bcea4 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.h +++ b/vespa/PolygonMeshProcessing/vtkCGALPatchFilling.h @@ -27,6 +27,11 @@ public: void SetUpdateAttributes(bool update) override; + /** + * Specify the selection describing the hole or patch to fill. + */ + void SetSourceConnection(vtkAlgorithmOutput* algOutput); + ///@{ /** * Drive the boundary tagencial continuity parameter diff --git a/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.cxx b/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.cxx index 455d74895e18ee625e26c2dcd103fe88d0a63e93..4254cb1a682c83de3bf548fc792ddd4300d909c6 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.cxx +++ b/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.cxx @@ -43,6 +43,12 @@ int vtkCGALRegionFairing::FillInputPortInformation(int port, vtkInformation* inf return 1; } +//------------------------------------------------------------------------------ +void vtkCGALRegionFairing::SetSourceConnection(vtkAlgorithmOutput* algOutput) +{ + this->SetInputConnection(1, algOutput); +} + //------------------------------------------------------------------------------ int vtkCGALRegionFairing::RequestData( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) diff --git a/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.h b/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.h index 149daced3577c8d2826560824e65d62637aaf3fd..f2ddf7659e24e8984f7c984cd0a6c887012da0e9 100644 --- a/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.h +++ b/vespa/PolygonMeshProcessing/vtkCGALRegionFairing.h @@ -20,6 +20,11 @@ public: vtkTypeMacro(vtkCGALRegionFairing, vtkCGALPolyDataAlgorithm); void PrintSelf(ostream& os, vtkIndent indent) override; + /** + * Specify the selection describing the region to fair. + */ + void SetSourceConnection(vtkAlgorithmOutput* algOutput); + protected: vtkCGALRegionFairing(); ~vtkCGALRegionFairing() override = default;