diff --git a/CHANGELOG.md b/CHANGELOG.md index 11d09b27..92e0430f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ This project aims to adhere to [Semantic Versioning](https://semver.org/spec/v2. ### Changed +- Move example apps from `src/apps` to `examples`. Remove `PMP_BUILD_APPS` CMake option. - Rename `Simplification` to `Decimation` - Rename `Factory` to `Shapes` - Drop `Surface` prefix from algorithms diff --git a/CMakeLists.txt b/CMakeLists.txt index 18e514ef..d43591ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ project( cmake_minimum_required(VERSION 3.16.3) cmake_policy(SET CMP0072 NEW) -option(PMP_BUILD_APPS "Build the PMP applications" ON) option(PMP_BUILD_EXAMPLES "Build the PMP examples" ON) option(PMP_BUILD_TESTS "Build the PMP test programs" ON) option(PMP_BUILD_DOCS "Build the PMP documentation" ON) @@ -180,14 +179,11 @@ include(clang-tidy) # which directories to process if(EMSCRIPTEN) add_subdirectory(src/pmp) - if(PMP_BUILD_APPS) - add_subdirectory(src/apps) + if(PMP_BUILD_EXAMPLES) + add_subdirectory(examples) endif() else() add_subdirectory(src/pmp) - if(PMP_BUILD_APPS) - add_subdirectory(src/apps) - endif() if(PMP_BUILD_DOCS) add_subdirectory(docs) endif() @@ -200,13 +196,6 @@ else() endif() endif() -set(CPACK_PACKAGE_VERSION ${PMP_VERSION}) -set(CPACK_SOURCE_PACKAGE_FILE_NAME - "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}") -set(CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") -set(CPACK_SOURCE_GENERATOR "ZIP") -include(CPack) - if(NOT EMSCRIPTEN AND PMP_INSTALL) # Generate package configuration files diff --git a/README.md b/README.md index f5ea1901..8c315ecf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Introduction [![build](https://github.com/pmp-library/pmp-library/workflows/build/badge.svg)](https://github.com/pmp-library/pmp-library/actions?query=workflow%3Abuild) -[![Coverage Status](https://coveralls.io/repos/github/pmp-library/pmp-library/badge.svg?branch=master)](https://coveralls.io/github/pmp-library/pmp-library?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/pmp-library/pmp-library/badge.svg?branch=master)](https://coveralls.io/github/pmp-library/pmp-library?branch=main) [![Latest Release](https://img.shields.io/github/v/release/pmp-library/pmp-library?sort=semver)](https://github.com/pmp-library/pmp-library/releases/latest) The Polygon Mesh Processing Library is a modern C++ open-source library for processing and visualizing polygon surface meshes. Its main features are: diff --git a/cmake/clang-format.cmake b/cmake/clang-format.cmake index 5e981ec9..dd459c4f 100644 --- a/cmake/clang-format.cmake +++ b/cmake/clang-format.cmake @@ -12,7 +12,15 @@ if(CLANG_FORMAT_EXE) message(STATUS "clang-format found: ${CLANG_FORMAT_EXE}") # get all sources - file(GLOB_RECURSE ALL_SOURCES "src/*.cpp" "src/*.h" "tests/*.cpp" "tests/*.h") + file( + GLOB_RECURSE + ALL_SOURCES + "src/*.cpp" + "src/*.h" + "tests/*.cpp" + "tests/*.h" + "examples/*.cpp" + "examples/*.h") add_custom_target(clang-format COMMAND ${CLANG_FORMAT_EXE} -style=file -i ${ALL_SOURCES}) diff --git a/docs/news.md b/docs/news.md index 870ac8aa..a668eab4 100644 --- a/docs/news.md +++ b/docs/news.md @@ -1,5 +1,6 @@ # News {#news} +- @subpage version-2-0-1-released-2022-08-26 - Aug 26, 2022 - @subpage version-2-0-released-2022-08-14 - Aug 14, 2022 - @subpage version-1-2-1-released-2020-05-10 - May 10, 2020 - @subpage version-1-2-released-2020-03-15 - March 15, 2020 diff --git a/docs/posts/2022-08-26-version-2.0.1-released.md b/docs/posts/2022-08-26-version-2.0.1-released.md new file mode 100644 index 00000000..3a21ee4a --- /dev/null +++ b/docs/posts/2022-08-26-version-2.0.1-released.md @@ -0,0 +1,42 @@ +# Version 2.0.1 Released {#version-2-0-1-released-2022-08-26} + +_Aug 26, 2022_ + +We just released version 2.0.1 of the Polygon Mesh Processing Library! This is a minor bug fix release fixing the following issues: + +- Fix shared library version +- Fix compilation with `PMP_SCALAR_TYPE=64` +- Use correct C++ standard (C++14) in public target compile options +- Fix crash in smoothing demo app + +See the [changelog](https://github.com/pmp-library/pmp-library/blob/master/CHANGELOG.md) for a full summary of changes. + +## Obtaining the pmp-library + +Get your own copy by cloning: + +```sh +git clone --recursive https://github.com/pmp-library/pmp-library.git +``` + +Checkout the 2.0.1 release tag: + +```sh +cd pmp-library && git checkout 2.0.1 +``` + +Configure and build: + +```sh +mkdir build && cd build && cmake .. && make +``` + +Run the mesh processing app + +```sh +./mpview ../external/pmp-data/off/bunny.off +``` + +## Reporting Bugs or Problems + +If you encounter any glitches or problems please [report the issue](https://github.com/pmp-library/pmp-library/issues) on GitHub. diff --git a/docs/tutorial.md b/docs/tutorial.md index c21dbe74..301f2d39 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -36,14 +36,11 @@ number of vertices, edges, and faces is printed to standard output. // instantiate a SurfaceMesh object SurfaceMesh mesh; -// instantiate 4 vertex handles -Vertex v0,v1,v2,v3; - // add 4 vertices -v0 = mesh.add_vertex(Point(0,0,0)); -v1 = mesh.add_vertex(Point(1,0,0)); -v2 = mesh.add_vertex(Point(0,1,0)); -v3 = mesh.add_vertex(Point(0,0,1)); +const auto v0 = mesh.add_vertex(Point(0,0,0)); +const auto v1 = mesh.add_vertex(Point(1,0,0)); +const auto v2 = mesh.add_vertex(Point(0,1,0)); +const auto v3 = mesh.add_vertex(Point(0,0,1)); // add 4 triangular faces mesh.add_triangle(v0,v1,v3); diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 45fc0efe..998dd34a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,24 +1,147 @@ -if(WITH_EXAMPLES) +add_executable(basics basics.cpp) +target_link_libraries(basics pmp) - add_executable(SurfaceMeshBasics SurfaceMeshBasics.cpp) - target_link_libraries(SurfaceMeshBasics pmp) +add_executable(io io.cpp) +target_link_libraries(io pmp) - add_executable(SurfaceMeshIO SurfaceMeshIO.cpp) - target_link_libraries(SurfaceMeshIO pmp) +add_executable(iterators iterators.cpp) +target_link_libraries(iterators pmp) - add_executable(SurfaceMeshIterators SurfaceMeshIterators.cpp) - target_link_libraries(SurfaceMeshIterators pmp) +add_executable(barycenter barycenter.cpp) +target_link_libraries(barycenter pmp) - add_executable(SurfaceMeshBarycenter SurfaceMeshBarycenter.cpp) - target_link_libraries(SurfaceMeshBarycenter pmp) +add_custom_target( + examples + COMMAND + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "") - add_custom_target( - examples - COMMAND - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" - COMMENT "") +add_dependencies(examples basics io iterators barycenter) - add_dependencies(examples SurfaceMeshBasics SurfaceMeshIO - SurfaceMeshIterators SurfaceMeshBarycenter) +# example apps +if(EMSCRIPTEN AND PMP_BUILD_VIS) -endif(WITH_EXAMPLES) + add_executable(mview mview.cpp data/shell.html) + target_link_libraries(mview pmp_vis) + set_target_properties( + mview PROPERTIES LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html") + + add_executable(curvature curvature.cpp data/shell.html) + target_link_libraries(curvature pmp_vis) + set_target_properties( + curvature + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" + ) + + add_executable(smoothing smoothing.cpp data/shell.html) + target_link_libraries(smoothing pmp_vis) + set_target_properties( + smoothing + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/fandisk.off@input.off" + ) + + add_executable(fairing fairing.cpp data/shell.html) + target_link_libraries(fairing pmp_vis) + set_target_properties( + fairing + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/hemisphere.off@input.off" + ) + + add_executable(mpview mpview.cpp MeshProcessingViewer.cpp + MeshProcessingViewer.h data/shell.html) + target_link_libraries(mpview pmp_vis) + set_target_properties( + mpview + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" + ) + + add_executable(subdivision subdivision.cpp data/shell.html) + target_link_libraries(subdivision pmp_vis) + set_target_properties( + subdivision + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/obj/suzanne.obj@input.obj" + ) + + add_executable(remeshing remeshing.cpp data/shell.html) + target_link_libraries(remeshing pmp_vis) + set_target_properties( + remeshing + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" + ) + + add_executable(decimation decimation.cpp data/shell.html) + target_link_libraries(decimation pmp_vis) + set_target_properties( + decimation + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/fandisk.off@input.off" + ) + + add_executable(parameterization parameterization.cpp data/shell.html) + target_link_libraries(parameterization pmp_vis) + set_target_properties( + parameterization + PROPERTIES + LINK_FLAGS + "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/hemisphere.off@input.off" + ) + +else() + + find_package(OpenGL) + + # build mconvert only on unix / OS-X + if(NOT WIN32) + add_executable(mconvert mconvert.cpp) + target_link_libraries(mconvert pmp) + endif() + + if(OpenGL_FOUND AND PMP_BUILD_VIS) + add_executable(mview mview.cpp) + target_link_libraries(mview pmp_vis) + + add_executable(curvature curvature.cpp) + target_link_libraries(curvature pmp_vis) + + add_executable(subdivision subdivision.cpp) + target_link_libraries(subdivision pmp_vis) + + add_executable(smoothing smoothing.cpp) + target_link_libraries(smoothing pmp_vis) + + add_executable(fairing fairing.cpp) + target_link_libraries(fairing pmp_vis) + + add_executable(parameterization parameterization.cpp) + target_link_libraries(parameterization pmp_vis) + + add_executable(decimation decimation.cpp) + target_link_libraries(decimation pmp_vis) + + add_executable(remeshing remeshing.cpp) + target_link_libraries(remeshing pmp_vis) + + add_executable(mpview mpview.cpp MeshProcessingViewer.cpp + MeshProcessingViewer.h) + target_link_libraries(mpview pmp_vis) + + add_executable(deformation_transfer deformation_transfer.cpp) + target_link_libraries(deformation_transfer pmp_vis) + + endif() + +endif() diff --git a/src/apps/MeshProcessingViewer.cpp b/examples/MeshProcessingViewer.cpp similarity index 100% rename from src/apps/MeshProcessingViewer.cpp rename to examples/MeshProcessingViewer.cpp diff --git a/src/apps/MeshProcessingViewer.h b/examples/MeshProcessingViewer.h similarity index 100% rename from src/apps/MeshProcessingViewer.h rename to examples/MeshProcessingViewer.h diff --git a/examples/SurfaceMeshBarycenter.cpp b/examples/barycenter.cpp similarity index 100% rename from examples/SurfaceMeshBarycenter.cpp rename to examples/barycenter.cpp diff --git a/examples/SurfaceMeshBasics.cpp b/examples/basics.cpp similarity index 73% rename from examples/SurfaceMeshBasics.cpp rename to examples/basics.cpp index 22b51ee7..9a057e7b 100644 --- a/examples/SurfaceMeshBasics.cpp +++ b/examples/basics.cpp @@ -5,21 +5,18 @@ using namespace pmp; -int main(void) +int main() { //! [basics] // instantiate a SurfaceMesh object SurfaceMesh mesh; - // instantiate 4 vertex handles - Vertex v0, v1, v2, v3; - // add 4 vertices - v0 = mesh.add_vertex(Point(0, 0, 0)); - v1 = mesh.add_vertex(Point(1, 0, 0)); - v2 = mesh.add_vertex(Point(0, 1, 0)); - v3 = mesh.add_vertex(Point(0, 0, 1)); + const auto v0 = mesh.add_vertex(Point(0, 0, 0)); + const auto v1 = mesh.add_vertex(Point(1, 0, 0)); + const auto v2 = mesh.add_vertex(Point(0, 1, 0)); + const auto v3 = mesh.add_vertex(Point(0, 0, 1)); // add 4 triangular faces mesh.add_triangle(v0, v1, v3); diff --git a/src/apps/curview.cpp b/examples/curvature.cpp similarity index 100% rename from src/apps/curview.cpp rename to examples/curvature.cpp diff --git a/src/apps/data/shell.html b/examples/data/shell.html similarity index 100% rename from src/apps/data/shell.html rename to examples/data/shell.html diff --git a/src/apps/decimation.cpp b/examples/decimation.cpp similarity index 100% rename from src/apps/decimation.cpp rename to examples/decimation.cpp diff --git a/src/apps/deftrans.cpp b/examples/deformation_transfer.cpp similarity index 100% rename from src/apps/deftrans.cpp rename to examples/deformation_transfer.cpp diff --git a/src/apps/fairing.cpp b/examples/fairing.cpp similarity index 100% rename from src/apps/fairing.cpp rename to examples/fairing.cpp diff --git a/examples/SurfaceMeshIO.cpp b/examples/io.cpp similarity index 100% rename from examples/SurfaceMeshIO.cpp rename to examples/io.cpp diff --git a/examples/SurfaceMeshIterators.cpp b/examples/iterators.cpp similarity index 100% rename from examples/SurfaceMeshIterators.cpp rename to examples/iterators.cpp diff --git a/src/apps/mconvert.cpp b/examples/mconvert.cpp similarity index 100% rename from src/apps/mconvert.cpp rename to examples/mconvert.cpp diff --git a/src/apps/mpview.cpp b/examples/mpview.cpp similarity index 100% rename from src/apps/mpview.cpp rename to examples/mpview.cpp diff --git a/src/apps/mview.cpp b/examples/mview.cpp similarity index 100% rename from src/apps/mview.cpp rename to examples/mview.cpp diff --git a/src/apps/parameterization.cpp b/examples/parameterization.cpp similarity index 100% rename from src/apps/parameterization.cpp rename to examples/parameterization.cpp diff --git a/src/apps/remeshing.cpp b/examples/remeshing.cpp similarity index 100% rename from src/apps/remeshing.cpp rename to examples/remeshing.cpp diff --git a/src/apps/smoothing.cpp b/examples/smoothing.cpp similarity index 100% rename from src/apps/smoothing.cpp rename to examples/smoothing.cpp diff --git a/src/apps/subdiv.cpp b/examples/subdivision.cpp similarity index 93% rename from src/apps/subdiv.cpp rename to examples/subdivision.cpp index a43f1337..3aa5cfe4 100644 --- a/src/apps/subdiv.cpp +++ b/examples/subdivision.cpp @@ -55,12 +55,6 @@ void Viewer::process_imgui() update_mesh(); } - if (ImGui::Button("Quad-Tri Subdivision")) - { - Subdivision(mesh_).quad_tri(); - update_mesh(); - } - if (ImGui::Button("Catmull-Clark Subdivision")) { Subdivision(mesh_).catmull_clark(); diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt deleted file mode 100644 index 35f9eb52..00000000 --- a/src/apps/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -if(EMSCRIPTEN AND PMP_BUILD_VIS) - - add_executable(mview mview.cpp data/shell.html) - target_link_libraries(mview pmp_vis) - set_target_properties( - mview PROPERTIES LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html") - - add_executable(curview curview.cpp data/shell.html) - target_link_libraries(curview pmp_vis) - set_target_properties( - curview - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" - ) - - add_executable(smoothing smoothing.cpp data/shell.html) - target_link_libraries(smoothing pmp_vis) - set_target_properties( - smoothing - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/fandisk.off@input.off" - ) - - add_executable(fairing fairing.cpp data/shell.html) - target_link_libraries(fairing pmp_vis) - set_target_properties( - fairing - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/hemisphere.off@input.off" - ) - - add_executable(mpview mpview.cpp MeshProcessingViewer.cpp - MeshProcessingViewer.h data/shell.html) - target_link_libraries(mpview pmp_vis) - set_target_properties( - mpview - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" - ) - - add_executable(subdiv subdiv.cpp data/shell.html) - target_link_libraries(subdiv pmp_vis) - set_target_properties( - subdiv - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/obj/suzanne.obj@input.obj" - ) - - add_executable(remeshing remeshing.cpp data/shell.html) - target_link_libraries(remeshing pmp_vis) - set_target_properties( - remeshing - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/bunny.off@input.off" - ) - - add_executable(decimation decimation.cpp data/shell.html) - target_link_libraries(decimation pmp_vis) - set_target_properties( - decimation - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/fandisk.off@input.off" - ) - - add_executable(parameterization parameterization.cpp data/shell.html) - target_link_libraries(parameterization pmp_vis) - set_target_properties( - parameterization - PROPERTIES - LINK_FLAGS - "--shell-file ${CMAKE_CURRENT_SOURCE_DIR}/data/shell.html --preload-file ${PROJECT_SOURCE_DIR}/external/pmp-data/off/hemisphere.off@input.off" - ) - -else() - - find_package(OpenGL) - - # build mconvert only on unix / OS-X - if(NOT WIN32) - add_executable(mconvert mconvert.cpp) - target_link_libraries(mconvert pmp) - endif() - - if(OpenGL_FOUND AND PMP_BUILD_VIS) - add_executable(mview mview.cpp) - target_link_libraries(mview pmp_vis) - - add_executable(curview curview.cpp) - target_link_libraries(curview pmp_vis) - - add_executable(subdiv subdiv.cpp) - target_link_libraries(subdiv pmp_vis) - - add_executable(smoothing smoothing.cpp) - target_link_libraries(smoothing pmp_vis) - - add_executable(fairing fairing.cpp) - target_link_libraries(fairing pmp_vis) - - add_executable(parameterization parameterization.cpp) - target_link_libraries(parameterization pmp_vis) - - add_executable(decimation decimation.cpp) - target_link_libraries(decimation pmp_vis) - - add_executable(remeshing remeshing.cpp) - target_link_libraries(remeshing pmp_vis) - - add_executable(mpview mpview.cpp MeshProcessingViewer.cpp - MeshProcessingViewer.h) - target_link_libraries(mpview pmp_vis) - - add_executable(deftrans deftrans.cpp) - target_link_libraries(deftrans pmp_vis) - - endif() - -endif() diff --git a/src/pmp/SurfaceMesh.cpp b/src/pmp/SurfaceMesh.cpp index 4c96a1df..9fb00718 100644 --- a/src/pmp/SurfaceMesh.cpp +++ b/src/pmp/SurfaceMesh.cpp @@ -775,7 +775,7 @@ void SurfaceMesh::flip(Edge e) set_halfedge(vb0, b1); } -bool SurfaceMesh::is_collapse_ok(Halfedge v0v1) +bool SurfaceMesh::is_collapse_ok(Halfedge v0v1) const { Halfedge v1v0(opposite_halfedge(v0v1)); Vertex v0(to_vertex(v1v0)); @@ -826,7 +826,7 @@ bool SurfaceMesh::is_collapse_ok(Halfedge v0v1) return true; } -bool SurfaceMesh::is_removal_ok(Edge e) +bool SurfaceMesh::is_removal_ok(Edge e) const { Halfedge h0 = halfedge(e, 0); Halfedge h1 = halfedge(e, 1); diff --git a/src/pmp/SurfaceMesh.h b/src/pmp/SurfaceMesh.h index 922b9044..119922b2 100644 --- a/src/pmp/SurfaceMesh.h +++ b/src/pmp/SurfaceMesh.h @@ -1830,7 +1830,7 @@ class SurfaceMesh //! \return whether collapsing the halfedge \p v0v1 is topologically legal. //! \attention This function is only valid for triangle meshes. - bool is_collapse_ok(Halfedge v0v1); + bool is_collapse_ok(Halfedge v0v1) const; //! Collapse the halfedge \p h by moving its start vertex into its target //! vertex. For non-boundary halfedges this function removes one vertex, three @@ -1844,7 +1844,7 @@ class SurfaceMesh void collapse(Halfedge h); //! \return whether removing the edge \p e is topologically legal. - bool is_removal_ok(Edge e); + bool is_removal_ok(Edge e) const; //! Remove edge and merge its two incident faces into one. //! This operation requires that the edge has two incident faces diff --git a/src/pmp/SurfaceMeshIO.cpp b/src/pmp/SurfaceMeshIO.cpp index ba566af6..e6cdb5e4 100644 --- a/src/pmp/SurfaceMeshIO.cpp +++ b/src/pmp/SurfaceMeshIO.cpp @@ -231,9 +231,8 @@ void SurfaceMeshIO::read_obj(SurfaceMesh& mesh) // add texture coordinates if (with_tex_coord && f.is_valid()) { - SurfaceMesh::HalfedgeAroundFaceCirculator h_fit = - mesh.halfedges(f); - SurfaceMesh::HalfedgeAroundFaceCirculator h_end = h_fit; + auto h_fit = mesh.halfedges(f); + auto h_end = h_fit; unsigned v_idx = 0; do { @@ -643,27 +642,26 @@ void SurfaceMeshIO::write_off(const SurfaceMesh& mesh) // vertices, and optionally normals and texture coordinates VertexProperty points = mesh.get_vertex_property("v:point"); - for (SurfaceMesh::VertexIterator vit = mesh.vertices_begin(); - vit != mesh.vertices_end(); ++vit) + for (auto v : mesh.vertices()) { - const Point& p = points[*vit]; + const Point& p = points[v]; fprintf(out, "%.10f %.10f %.10f", p[0], p[1], p[2]); if (has_normals) { - const Normal& n = normals[*vit]; + const Normal& n = normals[v]; fprintf(out, " %.10f %.10f %.10f", n[0], n[1], n[2]); } if (has_colors) { - const Color& c = colors[*vit]; + const Color& c = colors[v]; fprintf(out, " %.10f %.10f %.10f", c[0], c[1], c[2]); } if (has_texcoords) { - const TexCoord& t = texcoords[*vit]; + const TexCoord& t = texcoords[v]; fprintf(out, " %.10f %.10f", t[0], t[1]); } @@ -671,17 +669,16 @@ void SurfaceMeshIO::write_off(const SurfaceMesh& mesh) } // faces - for (SurfaceMesh::FaceIterator fit = mesh.faces_begin(); - fit != mesh.faces_end(); ++fit) + for (auto f : mesh.faces()) { - int nv = mesh.valence(*fit); - fprintf(out, "%d", nv); - SurfaceMesh::VertexAroundFaceCirculator fvit = mesh.vertices(*fit), - fvend = fvit; + auto nv = mesh.valence(f); + fprintf(out, "%zu", nv); + auto fv = mesh.vertices(f); + auto fvend = fv; do { - fprintf(out, " %d", (*fvit).idx()); - } while (++fvit != fvend); + fprintf(out, " %d", (*fv).idx()); + } while (++fv != fvend); fprintf(out, "\n"); } diff --git a/src/pmp/algorithms/DifferentialGeometry.cpp b/src/pmp/algorithms/DifferentialGeometry.cpp index 66158bb8..39c511c0 100644 --- a/src/pmp/algorithms/DifferentialGeometry.cpp +++ b/src/pmp/algorithms/DifferentialGeometry.cpp @@ -167,7 +167,7 @@ double voronoi_area(const SurfaceMesh& mesh, Vertex v) { Halfedge h0, h1, h2; dvec3 p, q, r, pq, qr, pr; - double dotp, dotq, dotr, triArea; + double dotp, dotq, dotr; double cotq, cotr; for (auto h : mesh.halfedges(v)) @@ -190,8 +190,8 @@ double voronoi_area(const SurfaceMesh& mesh, Vertex v) (pr = r) -= p; // compute and check triangle area - triArea = norm(cross(pq, pr)); - if (triArea <= std::numeric_limits::min()) + const auto triangle_area = norm(cross(pq, pr)); + if (triangle_area <= std::numeric_limits::min()) continue; // dot products for each corner (of its two emanating edge vectors) @@ -202,21 +202,21 @@ double voronoi_area(const SurfaceMesh& mesh, Vertex v) // angle at p is obtuse if (dotp < 0.0) { - area += 0.25 * triArea; + area += 0.25 * triangle_area; } // angle at q or r obtuse else if (dotq < 0.0 || dotr < 0.0) { - area += 0.125 * triArea; + area += 0.125 * triangle_area; } // no obtuse angles else { // cot(angle) = cos(angle)/sin(angle) = dot(A,B)/norm(cross(A,B)) - cotq = dotq / triArea; - cotr = dotr / triArea; + cotq = dotq / triangle_area; + cotr = dotr / triangle_area; // clamp cot(angle) by clamping angle to [3, 177] area += 0.125 * (sqrnorm(pr) * clamp_cot(cotq) + @@ -266,16 +266,16 @@ Point laplace(const SurfaceMesh& mesh, Vertex v) if (!mesh.is_isolated(v)) { - Scalar weight, sumWeights(0.0); + Scalar sum_weights(0.0); for (auto h : mesh.halfedges(v)) { - weight = cotan_weight(mesh, mesh.edge(h)); - sumWeights += weight; + const auto weight = cotan_weight(mesh, mesh.edge(h)); + sum_weights += weight; laplace += weight * mesh.position(mesh.to_vertex(h)); } - laplace -= sumWeights * mesh.position(v); + laplace -= sum_weights * mesh.position(v); laplace /= Scalar(2.0) * voronoi_area(mesh, v); } diff --git a/src/pmp/algorithms/Subdivision.cpp b/src/pmp/algorithms/Subdivision.cpp index 13793f07..35be5381 100644 --- a/src/pmp/algorithms/Subdivision.cpp +++ b/src/pmp/algorithms/Subdivision.cpp @@ -410,11 +410,13 @@ void Subdivision::quad_tri() else { // count the number of faces and quads surrounding the vertex - int n_faces = 0, n_quads = 0; + int n_faces = 0; + int n_quads = 0; for (auto f : mesh_.faces(v)) { n_faces++; - n_quads += mesh_.valence(f) == 4; + if (mesh_.valence(f) == 4) + n_quads++; } if (n_quads == 0) diff --git a/tests/SmoothingTest.cpp b/tests/SmoothingTest.cpp index d152b791..4349c5b5 100644 --- a/tests/SmoothingTest.cpp +++ b/tests/SmoothingTest.cpp @@ -19,6 +19,15 @@ TEST(SmoothingTest, implicit_smoothing) EXPECT_LT(area_after, area_before); } +TEST(SmoothingTest, implicit_smoothing_with_rescale) +{ + auto mesh = open_cone(); + auto area_before = surface_area(mesh); + Smoothing(mesh).implicit_smoothing(0.01, false, true); + auto area_after = surface_area(mesh); + EXPECT_FLOAT_EQ(area_after, area_before); +} + TEST(SmoothingTest, explicit_smoothing) { auto mesh = open_cone(); diff --git a/tests/SubdivisionTest.cpp b/tests/SubdivisionTest.cpp index ba43d73a..f7207d51 100644 --- a/tests/SubdivisionTest.cpp +++ b/tests/SubdivisionTest.cpp @@ -47,6 +47,13 @@ TEST(SubdivisionTest, catmull_clark_with_features) EXPECT_EQ(mesh.n_faces(), size_t(24)); } +TEST(SubdivisionTest, catmull_clark_with_boundary) +{ + auto mesh = Shapes::plane(1); + Subdivision(mesh).catmull_clark(); + EXPECT_EQ(mesh.n_faces(), size_t(4)); +} + TEST(SubdivisionTest, quad_tri_on_quads) { auto mesh = Shapes::hexahedron(); @@ -60,3 +67,10 @@ TEST(SubdivisionTest, quad_tri_on_triangles) Subdivision(mesh).quad_tri(); EXPECT_EQ(mesh.n_faces(), size_t(16)); } + +TEST(SubdivisionTest, quad_tri_on_mixed) +{ + auto mesh = Shapes::cone(4); // pyramid + Subdivision(mesh).quad_tri(); + EXPECT_EQ(mesh.n_faces(), size_t(20)); +}