hesuicong 2 months ago
parent
commit
5dc49dc874
  1. 62
      build.sh
  2. 2
      libs/MVS/CMakeLists.txt
  3. 320
      vcglib/CMakeLists.txt
  4. 674
      vcglib/LICENSE.txt
  5. 35
      vcglib/README.md
  6. 8
      vcglib/apps/CMakeLists.txt
  7. 256
      vcglib/apps/QT/img_filters/img_filters.cpp
  8. 34
      vcglib/apps/QT/img_filters/img_filters.pro
  9. 200
      vcglib/apps/QT/trimesh_QT/glarea.cpp
  10. 106
      vcglib/apps/QT/trimesh_QT/glarea.h
  11. 48
      vcglib/apps/QT/trimesh_QT/main.cpp
  12. 68
      vcglib/apps/QT/trimesh_QT/mainwindow.cpp
  13. 47
      vcglib/apps/QT/trimesh_QT/mainwindow.h
  14. 197
      vcglib/apps/QT/trimesh_QT/mainwindow.ui
  15. 46
      vcglib/apps/QT/trimesh_QT/trimesh_qt.pro
  16. 232
      vcglib/apps/QT/trimesh_QT_shared/glarea.cpp
  17. 103
      vcglib/apps/QT/trimesh_QT_shared/glarea.h
  18. 48
      vcglib/apps/QT/trimesh_QT_shared/main.cpp
  19. 243
      vcglib/apps/QT/trimesh_QT_shared/mainwindow.cpp
  20. 83
      vcglib/apps/QT/trimesh_QT_shared/mainwindow.h
  21. 82
      vcglib/apps/QT/trimesh_QT_shared/mainwindow.ui
  22. 28
      vcglib/apps/QT/trimesh_QT_shared/mesh.h
  23. 51
      vcglib/apps/QT/trimesh_QT_shared/trimesh_qt.pro
  24. 334
      vcglib/apps/QT/trimesh_ant_freeglut/main.cpp
  25. 40
      vcglib/apps/QT/trimesh_ant_freeglut/trimesh_ant_freeglut.pro
  26. 215
      vcglib/apps/QT/trimesh_ant_qt/glwidget.cpp
  27. 101
      vcglib/apps/QT/trimesh_ant_qt/glwidget.h
  28. 57
      vcglib/apps/QT/trimesh_ant_qt/main.cpp
  29. 40
      vcglib/apps/QT/trimesh_ant_qt/trimesh_ant_qt.pro
  30. 280
      vcglib/apps/QT/trimesh_pos_demo/glwidget.cpp
  31. 103
      vcglib/apps/QT/trimesh_pos_demo/glwidget.h
  32. 11
      vcglib/apps/QT/trimesh_pos_demo/main.cpp
  33. 58
      vcglib/apps/QT/trimesh_pos_demo/mesh_type.h
  34. 56
      vcglib/apps/QT/trimesh_pos_demo/trimesh_pos_demo.cpp
  35. 19
      vcglib/apps/QT/trimesh_pos_demo/trimesh_pos_demo.pro
  36. 39
      vcglib/apps/QT/trimesh_pos_demo/trimesh_vfiter_demo.cpp
  37. 75
      vcglib/apps/QT/trimesh_pos_demo/window.cpp
  38. 54
      vcglib/apps/QT/trimesh_pos_demo/window.h
  39. 18
      vcglib/apps/embree/CMakeLists.txt
  40. 151
      vcglib/apps/embree/embree_sample.cpp
  41. 50
      vcglib/apps/imguiViewer/CMakeLists.txt
  42. 1160
      vcglib/apps/imguiViewer/FileBrowser/Dirent/dirent.h
  43. 1255
      vcglib/apps/imguiViewer/FileBrowser/ImGuiFileBrowser.cpp
  44. 122
      vcglib/apps/imguiViewer/FileBrowser/ImGuiFileBrowser.h
  45. 363
      vcglib/apps/imguiViewer/main.cpp
  46. 48
      vcglib/apps/imguiViewer/triangle_mesh_type.h
  47. 18
      vcglib/apps/meshes/Tetraascii.ply
  48. 55729
      vcglib/apps/meshes/abominevole.off
  49. BIN
      vcglib/apps/meshes/bunny10k_textured.ply
  50. 9667
      vcglib/apps/meshes/conrod.off
  51. 6710
      vcglib/apps/meshes/fertility_quad.off
  52. 14996
      vcglib/apps/meshes/fertility_tri.off
  53. 16
      vcglib/apps/meshes/quad.ply
  54. 19
      vcglib/apps/meshes/quad4.ply
  55. 22
      vcglib/apps/meshes/quad5.ply
  56. 866
      vcglib/apps/meshes/torus.off
  57. 17
      vcglib/apps/metro/CMakeLists.txt
  58. 37
      vcglib/apps/metro/history.txt
  59. 318
      vcglib/apps/metro/metro.cpp
  60. 10
      vcglib/apps/metro/metro.pro
  61. 96
      vcglib/apps/metro/readme.txt
  62. BIN
      vcglib/apps/metro/sample/knot_max_simplified.STL
  63. BIN
      vcglib/apps/metro/sample/knot_orig.ply
  64. BIN
      vcglib/apps/metro/sample/knot_orig_metro.ply
  65. BIN
      vcglib/apps/metro/sample/knot_subsampled.ply
  66. BIN
      vcglib/apps/metro/sample/knot_subsampled_metro.ply
  67. BIN
      vcglib/apps/metro/sample/knot_vcg_simplified.ply
  68. BIN
      vcglib/apps/metro/sample/knot_vcg_simplified_metro.ply
  69. 7
      vcglib/apps/metro/sample/readme.txt
  70. 603
      vcglib/apps/metro/sampling.h
  71. 15
      vcglib/apps/minimal_project/CMakeLists.txt
  72. 74
      vcglib/apps/minimal_project/simple_main.cpp
  73. 10
      vcglib/apps/plymc/plymc.pro
  74. 223
      vcglib/apps/plymc/plymc_main.cpp
  75. 206
      vcglib/apps/plymc/simplemeshprovider.h
  76. 65
      vcglib/apps/sample/CMakeLists.txt
  77. 14
      vcglib/apps/sample/aabb_binary_tree/CMakeLists.txt
  78. 148
      vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.cpp
  79. 3
      vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.pro
  80. 14
      vcglib/apps/sample/colorspace/CMakeLists.txt
  81. 142
      vcglib/apps/sample/colorspace/colorspace.cpp
  82. 3
      vcglib/apps/sample/colorspace/colorspace.pro
  83. 23
      vcglib/apps/sample/common.pri
  84. 94
      vcglib/apps/sample/edgemesh_sampling/edgemesh_sampling.cpp
  85. 3
      vcglib/apps/sample/edgemesh_sampling/edgemesh_sampling.pro
  86. 17
      vcglib/apps/sample/polygonmesh_base/CMakeLists.txt
  87. 204
      vcglib/apps/sample/polygonmesh_base/polygonmesh.cpp
  88. 3
      vcglib/apps/sample/polygonmesh_base/polygonmesh_base.pro
  89. 17
      vcglib/apps/sample/polygonmesh_dual/CMakeLists.txt
  90. 122
      vcglib/apps/sample/polygonmesh_dual/polygonmesh_dual.cpp
  91. 3
      vcglib/apps/sample/polygonmesh_dual/polygonmesh_dual.pro
  92. 17
      vcglib/apps/sample/polygonmesh_optimize/CMakeLists.txt
  93. 180
      vcglib/apps/sample/polygonmesh_optimize/polygonmesh_optimize.cpp
  94. 3
      vcglib/apps/sample/polygonmesh_optimize/polygonmesh_optimize.pro
  95. 17
      vcglib/apps/sample/polygonmesh_polychord_collapse/CMakeLists.txt
  96. 106
      vcglib/apps/sample/polygonmesh_polychord_collapse/polygonmesh_polychord_collapse.cpp
  97. 3
      vcglib/apps/sample/polygonmesh_polychord_collapse/polygonmesh_polychord_collapse.pro
  98. 459
      vcglib/apps/sample/polygonmesh_quadsimpl/polygonmesh_quadsimpl.cpp
  99. 3
      vcglib/apps/sample/polygonmesh_quadsimpl/polygonmesh_quadsimpl.pro
  100. 17
      vcglib/apps/sample/polygonmesh_smooth/CMakeLists.txt
  101. Some files were not shown because too many files have changed in this diff Show More

62
build.sh

@ -0,0 +1,62 @@
#!/bin/bash
set -e
USER=`whoami`
SUDO=
function sudo_auth(){
echo "验证 sudo 权限..."
sudo -v >/dev/null 2>&1 || {
echo "❌ sudo 密码错误,退出脚本"
exit 1
}
}
function install_openmvs(){
cmake -S . -B make -DCMAKE_BUILD_TYPE=Release -DVCG_ROOT=./vcglib -DCGAL_DATA_DIR=/usr/share/cgal
cd make && make -j$(nproc)
make install
}
if [ "$USER" == "root" ]; then
SUDO=""
else
SUDO="sudo "
sudo_auth
fi
$SUDO apt update
install_if_missing() {
for pkg in "$@"; do
if dpkg -s "$pkg" >/dev/null 2>&1; then
echo "$pkg 已安装"
else
echo "📦 正在安装 $pkg ..."
$SUDO apt install -y "$pkg" || {
echo "❌ 安装 $pkg 失败"
exit 1
}
fi
done
}
install_if_missing build-essential cmake git pkg-config
#EIGEN3
install_if_missing libeigen3-dev
#opencv
install_if_missing libopencv-dev
#ceres solver
install_if_missing libceres-dev libceres2
#cgal
install_if_missing libcgal-dev libcgal-demo
#BOOST
install_if_missing libboost-all-dev
#GLFW
install_if_missing libglfw3-dev
install_openmvs

2
libs/MVS/CMakeLists.txt

@ -108,7 +108,7 @@ endif()
# Install # Install
SET_TARGET_PROPERTIES(MVS PROPERTIES SET_TARGET_PROPERTIES(MVS PROPERTIES
PUBLIC_HEADER "${LIBRARY_FILES_H}") PUBLIC_HEADER "${LIBRARY_FILES_H}")
INSTALL(TARGETS MVS INSTALL(TARGETS MVS MeshTextureCUDA
EXPORT OpenMVSTargets EXPORT OpenMVSTargets
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" LIBRARY DESTINATION "${INSTALL_LIB_DIR}"
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"

320
vcglib/CMakeLists.txt

@ -0,0 +1,320 @@
# Copyright 2019, 2020, Collabora, Ltd.
# Copyright 2019, 2021, Visual Computing Lab, ISTI - Italian National Research Council
# SPDX-License-Identifier: BSL-1.0
cmake_minimum_required(VERSION 3.10)
project(VCGLib)
# Eigen options
option(VCG_ALLOW_BUNDLED_EIGEN "Allow use of bundled Eigen source" ON)
option(VCG_ALLOW_SYSTEM_EIGEN "Allow use of system-provided Eigen" ON)
# VCG options
option(VCG_HEADER_ONLY "Use VCG library in header only mode" ON)
option(VCG_BUILD_EXAMPLES "Build a set of examples of the library" OFF)
option(VCG_USE_OPENMP "Allow VCG to find and link OpenMP if detected" ON)
set (VCG_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR})
set (VCG_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE)
### Build settings
set(CMAKE_CXX_STANDARD 11)
### OpenMP
if (VCG_USE_OPENMP)
find_package(OpenMP)
if (APPLE AND OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
endif()
### Eigen
set(VCG_EIGEN_DIR ${CMAKE_CURRENT_LIST_DIR}/eigenlib)
if(VCG_ALLOW_SYSTEM_EIGEN AND EIGEN3_INCLUDE_DIR)
message(STATUS "- Eigen - using system-provided library")
set(EIGEN_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR})
elseif(VCG_ALLOW_BUNDLED_EIGEN AND EXISTS "${VCG_EIGEN_DIR}/Eigen/Eigen")
message(STATUS "- Eigen - using bundled source")
set(EIGEN_INCLUDE_DIRS ${VCG_EIGEN_DIR})
else()
message(
FATAL_ERROR
"Eigen is required - at least one of VCG_ALLOW_SYSTEM_EIGEN or VCG_ALLOW_BUNDLED_EIGEN must be enabled and found.")
endif()
### VCGLib headers and sources
set(VCG_HEADERS
vcg/complex/append.h
vcg/complex/all_types.h
vcg/complex/complex.h
vcg/complex/allocate.h
vcg/complex/exception.h
vcg/complex/algorithms/overlap_estimation.h
vcg/complex/algorithms/dual_meshing.h
vcg/complex/algorithms/intersection.h
vcg/complex/algorithms/clip.h
vcg/complex/algorithms/geodesic.h
vcg/complex/algorithms/parametrization/poisson_solver.h
vcg/complex/algorithms/parametrization/uv_utils.h
vcg/complex/algorithms/parametrization/distortion.h
vcg/complex/algorithms/parametrization/tangent_field_operators.h
vcg/complex/algorithms/parametrization/voronoi_atlas.h
vcg/complex/algorithms/edge_collapse.h
vcg/complex/algorithms/hole.h
vcg/complex/algorithms/align_pair.h
vcg/complex/algorithms/closest.h
vcg/complex/algorithms/tetra_implicit_smooth.h
vcg/complex/algorithms/bitquad_support.h
vcg/complex/algorithms/skeleton.h
vcg/complex/algorithms/symmetry.h
vcg/complex/algorithms/voronoi_volume_sampling.h
vcg/complex/algorithms/polygon_polychord_collapse.h
vcg/complex/algorithms/inside.h
vcg/complex/algorithms/local_optimization/tri_edge_flip.h
vcg/complex/algorithms/local_optimization/quad_diag_collapse.h
vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric.h
vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric_tex.h
vcg/complex/algorithms/local_optimization/tri_edge_collapse.h
vcg/complex/algorithms/local_optimization/tetra_edge_collapse.h
vcg/complex/algorithms/polygonal_algorithms.h
vcg/complex/algorithms/inertia.h
vcg/complex/algorithms/mesh_assert.h
vcg/complex/algorithms/occupancy_grid.h
vcg/complex/algorithms/meshtree.h
vcg/complex/algorithms/align_global.h
vcg/complex/algorithms/cut_tree.h
vcg/complex/algorithms/nring.h
vcg/complex/algorithms/tetra/tetfuse_collapse.h
vcg/complex/algorithms/stat.h
vcg/complex/algorithms/ransac_matching.h
vcg/complex/algorithms/refine.h
vcg/complex/algorithms/outline_support.h
vcg/complex/algorithms/convex_hull.h
vcg/complex/algorithms/clean.h
vcg/complex/algorithms/mesh_to_matrix.h
vcg/complex/algorithms/quadrangulator.h
vcg/complex/algorithms/isotropic_remeshing.h
vcg/complex/algorithms/smooth.h
vcg/complex/algorithms/autoalign_4pcs.h
vcg/complex/algorithms/local_optimization.h
vcg/complex/algorithms/curve_on_manifold.h
vcg/complex/algorithms/clustering.h
vcg/complex/algorithms/refine_loop.h
vcg/complex/algorithms/cylinder_clipping.h
vcg/complex/algorithms/pointcloud_normal.h
vcg/complex/algorithms/bitquad_creation.h
vcg/complex/algorithms/crease_cut.h
vcg/complex/algorithms/implicit_smooth.h
vcg/complex/algorithms/voronoi_remesher.h
vcg/complex/algorithms/polygon_support.h
vcg/complex/algorithms/point_sampling.h
vcg/complex/algorithms/create/mc_lookup_table.h
vcg/complex/algorithms/create/mc_trivial_walker.h
vcg/complex/algorithms/create/extrude.h
vcg/complex/algorithms/create/resampler.h
vcg/complex/algorithms/create/ball_pivoting.h
vcg/complex/algorithms/create/readme.txt
vcg/complex/algorithms/create/zonohedron.h
vcg/complex/algorithms/create/platonic.h
vcg/complex/algorithms/create/marching_cubes.h
vcg/complex/algorithms/create/plymc/voxel.h
vcg/complex/algorithms/create/plymc/simplemeshprovider.h
vcg/complex/algorithms/create/plymc/tri_edge_collapse_mc.h
vcg/complex/algorithms/create/plymc/volume.h
vcg/complex/algorithms/create/plymc/plymc.h
vcg/complex/algorithms/create/plymc/svoxel.h
vcg/complex/algorithms/create/tetramesh_support.h
vcg/complex/algorithms/create/advancing_front.h
vcg/complex/algorithms/textcoord_optimization.h
vcg/complex/algorithms/bitquad_optimization.h
vcg/complex/algorithms/halfedge_quad_clean.h
vcg/complex/algorithms/voronoi_processing.h
vcg/complex/algorithms/update/quality.h
vcg/complex/algorithms/update/selection.h
vcg/complex/algorithms/update/fitmaps.h
vcg/complex/algorithms/update/component_ep.h
vcg/complex/algorithms/update/texture.h
vcg/complex/algorithms/update/curvature_fitting.h
vcg/complex/algorithms/update/normal.h
vcg/complex/algorithms/update/position.h
vcg/complex/algorithms/update/halfedge_topology.h
vcg/complex/algorithms/update/topology.h
vcg/complex/algorithms/update/flag.h
vcg/complex/algorithms/update/bounding.h
vcg/complex/algorithms/update/halfedge_indexed.h
vcg/complex/algorithms/update/color.h
vcg/complex/algorithms/update/curvature.h
vcg/complex/algorithms/point_outlier.h
vcg/complex/algorithms/harmonic.h
vcg/complex/algorithms/point_matching_scale.h
vcg/complex/algorithms/attribute_seam.h
vcg/complex/foreach.h
vcg/complex/base.h
vcg/complex/used_types.h
vcg/container/entries_allocation_table.h
vcg/container/container_allocation_table.h
vcg/container/derivation_chain.h
vcg/container/vector_occ.h
vcg/container/simple_temporary_data.h
vcg/space/segment2.h
vcg/space/fitting3.h
vcg/space/tetra3.h
vcg/space/triangle2.h
vcg/space/ray2.h
vcg/space/point2.h
vcg/space/point4.h
vcg/space/box2.h
vcg/space/ray3.h
vcg/space/planar_polygon_tessellation.h
vcg/space/texcoord2.h
vcg/space/point3.h
vcg/space/intersection/triangle_triangle3.h
vcg/space/distance2.h
vcg/space/point3.h
vcg/space/point.h
vcg/space/space.h
vcg/space/point.h
vcg/space/colorspace.h
vcg/space/rect_packer.h
vcg/space/triangle3.h
vcg/space/obox3.h
vcg/space/point2.h
vcg/space/smallest_enclosing.h
vcg/space/color4.h
vcg/space/polygon3.h
vcg/space/line3.h
vcg/space/index/octree.h
vcg/space/index/grid_util2d.h
vcg/space/index/grid_closest.h
vcg/space/index/grid_static_ptr.h
vcg/space/index/grid_util.h
vcg/space/index/spatial_hashing.h
vcg/space/index/closest2d.h
vcg/space/index/grid_static_obj.h
vcg/space/index/kdtree/kdtree.h
vcg/space/index/kdtree/priorityqueue.h
vcg/space/index/kdtree/kdtree_face.h
vcg/space/index/kdtree/mlsutils.h
vcg/space/index/octree_template.h
vcg/space/index/aabb_binary_tree/kclosest.h
vcg/space/index/aabb_binary_tree/closest.h
vcg/space/index/aabb_binary_tree/ray.h
vcg/space/index/aabb_binary_tree/frustum_cull.h
vcg/space/index/aabb_binary_tree/aabb_binary_tree.h
vcg/space/index/aabb_binary_tree/base.h
vcg/space/index/grid_closest2d.h
vcg/space/index/spatial_hashing2d.h
vcg/space/index/space_iterators.h
vcg/space/index/grid_static_ptr2d.h
vcg/space/index/base2d.h
vcg/space/index/base.h
vcg/space/index/perfect_spatial_hashing.h
vcg/space/index/space_iterators2d.h
vcg/space/line2.h
vcg/space/point_matching.h
vcg/space/intersection3.h
vcg/space/point4.h
vcg/space/rasterized_outline2_packer.h
vcg/space/box.h
vcg/space/plane3.h
vcg/space/outline2_packer.h
vcg/space/segment3.h
vcg/space/intersection2.h
vcg/space/sphere3.h
vcg/space/box3.h
vcg/space/distance3.h
vcg/math/quadric5.h
vcg/math/factorial.h
vcg/math/eigen_matrix_addons.h
vcg/math/quadric.h
vcg/math/perlin_noise.h
vcg/math/shot.h
vcg/math/shot.ipp
vcg/math/spherical_harmonics.h
vcg/math/eigen_matrixbase_addons.h
vcg/math/quaternion.h
vcg/math/similarity.h
vcg/math/disjoint_set.h
vcg/math/random_generator.h
vcg/math/camera.h
vcg/math/camera.ipp
vcg/math/linear.h
vcg/math/matrix44.h
vcg/math/eigen.h
vcg/math/similarity2.h
vcg/math/gen_normal.h
vcg/math/polar_decomposition.h
vcg/math/base.h
vcg/math/histogram.h
vcg/math/legendre.h
vcg/math/matrix33.h
vcg/simplex/edge/distance.h
vcg/simplex/edge/topology.h
vcg/simplex/edge/pos.h
vcg/simplex/edge/component.h
vcg/simplex/edge/base.h
vcg/simplex/tetrahedron/tetrahedron.h
vcg/simplex/tetrahedron/topology.h
vcg/simplex/tetrahedron/pos.h
vcg/simplex/tetrahedron/component.h
vcg/simplex/tetrahedron/base.h
vcg/simplex/face/component_occ.h
vcg/simplex/face/component_ep.h
vcg/simplex/face/jumping_pos.h
vcg/simplex/face/distance.h
vcg/simplex/face/component_polygon.h
vcg/simplex/face/topology.h
vcg/simplex/face/pos.h
vcg/simplex/face/component.h
vcg/simplex/face/component_ocf.h
vcg/simplex/face/base.h
vcg/simplex/vertex/component_occ.h
vcg/simplex/vertex/component_sph.h
vcg/simplex/vertex/distance.h
vcg/simplex/vertex/component.h
vcg/simplex/vertex/component_ocf.h
vcg/simplex/vertex/base.h
vcg/connectors/halfedge_pos.h
vcg/connectors/hedge.h
vcg/connectors/hedge_component.h
#wrap
wrap/callback.h
)
set(SOURCES
)
if (VCG_HEADER_ONLY)
if (NOT TARGET vcglib) # to be sure that vcglib target is created just one time
add_library(vcglib INTERFACE)
target_include_directories(
vcglib INTERFACE
${CMAKE_CURRENT_LIST_DIR}
${EIGEN_INCLUDE_DIRS})
if(OPENMP_FOUND)
target_link_libraries(vcglib INTERFACE OpenMP::OpenMP_CXX)
endif()
if (MSVC)
target_compile_options(vcglib INTERFACE "/bigobj")
endif()
#just to show headers in ide
add_custom_target(vcglib_ide SOURCES ${VCG_HEADERS})
else()
message(STATUS "- VCGLib - jumped - already included")
endif()
else()
#TODO make vcglib that includes all the wrap sources, checking everytime
# if the the required targets (e.g. qt, gl, glew...) exists
endif()
if(VCG_BUILD_EXAMPLES)
#TODO make the list of samples to build
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/apps)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/wrap)
endif()

674
vcglib/LICENSE.txt

@ -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:
{project} Copyright (C) {year} {fullname}
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>.

35
vcglib/README.md

@ -0,0 +1,35 @@
The **_Visualization and Computer Graphics Library_** (VCGlib for short) is an open source, portable, and templated library written in C++, with no external dependencies, for manipulation, processing, cleaning, and simplifying triangle meshes.
[![BuildExamples](https://github.com/cnr-isti-vclab/vcglib/actions/workflows/BuildExamples.yml/badge.svg)](https://github.com/cnr-isti-vclab/vcglib/actions/workflows/BuildExamples.yml)
The library, composed by more than 100k lines of code, is released under the GPL license, and it is the base of most of the software tools of the [Visual Computing Lab](http://vcg.isti.cnr.it) of the Italian National Research Council Institute - ISTI, like [MeshLab](http://www.meshlab.net/), [Metro](http://vcg.isti.cnr.it/vcglib/metro.html) and many others.
The VCG library is tailored to mostly manage triangular meshes: The library is fairly large and offers many state-of-the-art capabilities for processing meshes, such as:
- high quality quadric-error edge-collapse based simplfication
- efficient spatial query structures (uniform grids, hashed grids, kdtree, etc)
- advanced smoothing and fairing algorithms
- computation of curvature
- optimization of texture coordinates
- Hausdorff distance computation
- geodesic paths
- mesh repairing capabilities
- isosurface extraction and advancing front meshing algorithms
- Poisson Disk sampling and other tools to sample point distributions over meshes
- subdivision surfaces
## Notable Applications
A number of applications have been developed using the VCGlib:
- MeshLab: the renowed open source mesh processing software
- Metro, the tool for measuring differences between meshes
- The first high quality out-of-core mesh simplifier that was used by the Stanford Digital Michelangelo project to process their huge 3D scanned models.
## Contacts
For any info about licensing (portions of) the library please contact us:
Paolo Cignoni (p.cignoni@isti.cnr.it)
Visual Computing Lab of the Italian National Research Council - ISTI
In case of bugs please report them [here](https://github.com/cnr-isti-vclab/vcglib/issues).

8
vcglib/apps/CMakeLists.txt

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.13)
project(VCGApps)
add_subdirectory(sample)
add_subdirectory(metro)
add_subdirectory(tridecimator)
add_subdirectory(embree)

256
vcglib/apps/QT/img_filters/img_filters.cpp

@ -0,0 +1,256 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2009 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <QtCore>
#include "wrap/qt/img_qt.h"
void sample001_open_save_color(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
img::saveQtRGB(image, output_file);
}
void sample002_open_save_grayscale(QString input_file, QString output_file)
{
img::Image<1> image;
img::openQtY(input_file, image);
img::saveQtY(image, output_file);
}
void sample003_normalize(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
img::saveQtRGB(img::getNormalized(image), output_file);
}
void sample004_boxfilter(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
int radius=3;
img::saveQtRGB(img::getBoxFiltered(image,radius), output_file);
}
void sample005_gaussiansmooth(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
int radius=4;
img::saveQtRGB(img::getGaussianSmoothed(image,radius), output_file);
}
void sample006_medianfilter(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
int radius=5;
img::saveQtRGB(img::getMedianFiltered(image,radius), output_file);
}
void sample007_unsharpmask(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
int radius=4;
double factor=0.6;
img::saveQtRGB(img::getUnsharpMasked(image,radius,factor), output_file);
}
void sample008_laplacianfilter(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
img::Image<> laplacianfiltered;
img::LaplacianFilter(image,laplacianfiltered);
img::saveQtRGB(img::getNormalized(laplacianfiltered), output_file);
}
void sample009_logfilter(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
int radius=5;
img::Image<> logfiltered;
img::LoGFilter(image,logfiltered,radius);
img::saveQtRGB(img::getNormalized(logfiltered), output_file);
}
void sample010_dogfilter(QString input_file, QString output_file)
{
img::Image<> image;
img::openQtRGB(input_file, image);
// must be radius1 < radius2
int radius1=2;
int radius2=4;
img::Image<> dogfiltered;
img::DoGFilter(image,dogfiltered,radius1,radius2);
img::saveQtRGB(img::getNormalized(dogfiltered), output_file);
}
void sample011_general_convolutions(QString input_file, QString output_dir,QString output_suffix)
{
img::Image<> image;
img::openQtRGB(input_file, image);
QVector< QPair< double*, QPair< QPair< int, int > , QString> > > mm;
double *f;
f=new double[9];
f[0]= 0.0f; f[1]= 0.0f; f[2]= 0.0f;
f[3]=-1.0f; f[4]= 1.0f; f[5]= 0.0f;
f[6]= 0.0f, f[7]= 0.0f; f[8]= 0.0f;
mm.push_back(qMakePair(f,qMakePair(qMakePair(3,3),QString("edge_enhance"))));
f=new double[9];
f[0]= 2.0f; f[1]= 0.0f; f[2]= 0.0f;
f[3]= 0.0f; f[4]=-1.0f; f[5]= 0.0f;
f[6]= 0.0f, f[7]= 0.0f; f[8]=-1.0f;
mm.push_back(qMakePair(f,qMakePair(qMakePair(3,3),QString("embross"))));
f=new double[15];
f[0] = 1.0f; f[1] = 2.0f; f[2] = 0.0f; f[3] = 2.0f; f[4] = 1.0f;
f[5] = 1.0f; f[6] = 2.0f; f[7] =-18.0f; f[8] = 2.0f; f[9] = 1.0f;
f[10]= 1.0f; f[11]= 2.0f; f[12]= 0.0f; f[13]= 2.0f; f[14]= 1.0f;
mm.push_back(qMakePair(f,qMakePair(qMakePair(5,3),QString("my_vert_edges"))));
f=new double[15];
f[0] = 1.0f; f[1] = 1.0f; f[2] = 1.0f;
f[3] = 2.0f; f[4] = 2.0f; f[5] = 2.0f;
f[6] = 0.0f; f[7] =-18.0f; f[8] = 0.0f;
f[9] = 2.0f; f[10]= 2.0f; f[11]= 2.0f;
f[12]= 1.0f; f[13]= 1.0f; f[14]= 1.0f;
mm.push_back(qMakePair(f,qMakePair(qMakePair(3,5),QString("my_horiz_edges"))));
QPair< double*, QPair< QPair< int, int > , QString> > m;
foreach(m,mm){
double* matrix=m.first;
int matrix_width=((m.second).first).first;
int matrix_height=((m.second).first).second;
QString matrix_name=(m.second).second;
img::Image<> convolved;
img::convolution(image,convolved,matrix,matrix_width,matrix_height);
delete [] matrix;
bool normalize=(img::minValue(convolved)<0.0f)||(img::maxValue(convolved)>=255.0f);
QString output_file(output_dir+"/011_general_convolution_"+matrix_name+
"_"+(normalize?" normalized_":"")+output_suffix);
if(normalize)
img::saveQtRGB(img::getNormalized(convolved),output_file);
else
img::saveQtRGB(convolved,output_file);
}
}
void img_filters(QString input_dir,QString image,QString output_dir)
{
QString input_file(input_dir+"/"+image);
sample001_open_save_color(input_file, output_dir+"/001-open_save_color_"+image);
sample002_open_save_grayscale(input_file, output_dir+"/002-open_save_grayscale_"+image);
sample003_normalize(input_file, output_dir+"/003_normalize_"+image);
sample004_boxfilter(input_file, output_dir+"/004_boxfilter_"+image);
sample005_gaussiansmooth(input_file, output_dir+"/005_gaussiansmooth_"+image);
sample006_medianfilter(input_file, output_dir+"/006_medianfilter_"+image);
sample007_unsharpmask(input_file, output_dir+"/007_unsharpmask_"+image);
sample008_laplacianfilter(input_file, output_dir+"/008_laplacianfilter_normalized_"+image);
sample009_logfilter(input_file, output_dir+"/009_logfilter_normalized_"+image);
sample010_dogfilter(input_file, output_dir+"/010_dogfilter_normalized_"+image);
sample011_general_convolutions(input_file, output_dir,image);
}
bool clean_dir(QDir dir); // utility, unrelated with the sample
int main(int argc,char ** argv)
{
if(argc<3)
{
printf("Usage: img_filters <input_dir> <output_dir>\n");
return 1;
}
printf("Executing img_filters over all images in \"%s\", ouput is in \"%s\"\n", argv[1], argv[2]);
QString input_dir(argv[1]);
QString output_dir(argv[2]);
QStringList readable_image_extensions = QStringList()
<< "*.bmp" << "*.gif" << "*.jpg" << "*.jpeg"
<< "*.png" << "*.pbm" << "*.pgm" << "*.ppm"
<< "*.tiff" << "*.xbm" << "*.xpm";
QStringList image_list = QDir(input_dir).entryList(readable_image_extensions,QDir::Files|QDir::Readable,QDir::Name);
assert(clean_dir(QDir(output_dir)));
try {
foreach(QString image, image_list)
img_filters(input_dir,image,output_dir);
} catch (img::ImageException& e) {
qDebug() << "caught ImageException, message:" << e.message;
}
return 0;
}
bool clean_dir(QDir dir){ // utility, unrelated with the sample
if(!dir.exists()){
qDebug() << QString("dir \"%1\" does not exists\n").arg(dir.path());
return false;
}
foreach(QString e,dir.entryList(QDir::NoDotAndDotDot|QDir::Dirs|QDir::Files)){
QFileInfo i(QString("%1/%2").arg(dir.path(),e));
if(i.isDir()){
if(!clean_dir(QDir(QString("%1/%2").arg(dir.path(),e)))){
qDebug() << QString("cannot clean \"%1/%2\"\n").arg(dir.path(),e);
return false;
}
if(!dir.rmdir(e)){
qDebug() << QString("cannot remove \"%1/%2\"\n").arg(dir.path(),e);
return false;
}
}else{
if(!dir.remove(e)){
qDebug() << QString("cannot remove \"%1/%2\"\n").arg(dir.path(),e);
return false;
}
}
}
return true;
}

34
vcglib/apps/QT/img_filters/img_filters.pro

@ -0,0 +1,34 @@
# debugging
CONFIG += debug
# Base options
TEMPLATE = app
LANGUAGE = C++
# Executable name
TARGET = img_filters
# STL support is enabled
CONFIG += stl
# enable console
CONFIG += console
# Awful..
win32{
DEFINES += NOMINMAX
}
# The following define is needed in gcc to remove the asserts
win32-g++:DEFINES += NDEBUG
CONFIG(debug, debug|release) {
win32-g++:release:DEFINES -= NDEBUG
}
#include current path
INCLUDEPATH += .
#include lib path
INCLUDEPATH += ../../..
SOURCES += img_filters.cpp

200
vcglib/apps/QT/trimesh_QT/glarea.cpp

@ -0,0 +1,200 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2007/10/18 08:52:06 benedetti
Initial release.
****************************************************************************/
#include "glarea.h"
#include <QMessageBox>
#include <QKeyEvent>
#include <QKeyEvent>
#include <QWheelEvent>
#include <wrap/qt/trackball.h>
GLArea::GLArea (QWidget * parent)
:QGLWidget (parent)
{
drawmode= SMOOTH;
GLArea::loadTetrahedron();
}
void GLArea::selectDrawMode(int mode){
drawmode=DrawMode(mode);
updateGL();
}
void GLArea::loadMesh(QString fileName)
{
int err=vcg::tri::io::ImporterPLY<CMesh>::Open(mesh,(fileName.toStdString()).c_str());
if(err!=0){
const char* errmsg=vcg::tri::io::ImporterPLY<CMesh>::ErrorMsg(err);
QMessageBox::warning(this,tr("Error Loading Mesh"),QString(errmsg));
}
initMesh("Loaded \""+fileName+"\".");
}
void GLArea::loadTetrahedron(){
vcg::tri::Tetrahedron(mesh);
initMesh(tr("Tethraedron [builtin]"));
}
void GLArea::loadDodecahedron(){
vcg::tri::Dodecahedron(mesh);
initMesh(tr("Dodecahedron [builtin]"));
}
void GLArea::initMesh(QString message)
{
// update bounding box
vcg::tri::UpdateBounding<CMesh>::Box(mesh);
// update Normals
vcg::tri::UpdateNormal<CMesh>::PerVertexNormalizedPerFace(mesh);
vcg::tri::UpdateNormal<CMesh>::PerFaceNormalized(mesh);
// Initialize the opengl wrapper
glWrap.m = &mesh;
glWrap.Update();
updateGL();
emit setStatusBar(message);
}
void GLArea::initializeGL ()
{
glClearColor(0, 0, 0, 0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}
void GLArea::resizeGL (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
initializeGL();
}
void GLArea::paintGL ()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(25, GLArea::width()/(float)GLArea::height(), 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
track.center=vcg::Point3f(0, 0, 0);
track.radius= 1;
track.GetView();
track.Apply();
glPushMatrix();
float d=2.0f/mesh.bbox.Diag();
vcg::glScale(d);
glTranslate(-glWrap.m->bbox.Center());
// the trimesh drawing calls
switch(drawmode)
{
case SMOOTH:
glWrap.Draw<vcg::GLW::DMSmooth, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case POINTS:
glWrap.Draw<vcg::GLW::DMPoints, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case WIRE:
glWrap.Draw<vcg::GLW::DMWire, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case FLATWIRE:
glWrap.Draw<vcg::GLW::DMFlatWire, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case HIDDEN:
glWrap.Draw<vcg::GLW::DMHidden, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case FLAT:
glWrap.Draw<vcg::GLW::DMFlat, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
default:
break;
}
glPopMatrix();
track.DrawPostApply();
}
void GLArea::keyReleaseEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier));
updateGL ();
}
void GLArea::keyPressEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier));
updateGL ();
}
void GLArea::mousePressEvent (QMouseEvent * e)
{
e->accept ();
setFocus ();
track.MouseDown (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ()));
updateGL ();
}
void GLArea::mouseMoveEvent (QMouseEvent * e)
{
if (e->buttons ()) {
track.MouseMove (QT2VCG_X(this,e), QT2VCG_Y(this,e));
updateGL ();
}
}
void GLArea::mouseReleaseEvent (QMouseEvent * e)
{
track.MouseUp (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ()));
updateGL ();
}
void GLArea::wheelEvent (QWheelEvent * e)
{
const int WHEEL_STEP = 120;
track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
updateGL ();
}

106
vcglib/apps/QT/trimesh_QT/glarea.h

@ -0,0 +1,106 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2007/10/18 08:52:06 benedetti
Initial release.
****************************************************************************/
#ifndef GLAREA_H_
#define GLAREA_H_
/// Opengl related imports
#include <GL/glew.h>
#include <QGLWidget>
/// vcg imports
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/create/platonic.h>
/// wrapper imports
#include <wrap/io_trimesh/import.h>
#include <wrap/gl/trimesh.h>
#include <wrap/gui/trackball.h>
/// declaring edge and face type
using namespace vcg;
class CFace;
class CVertex;
struct MyUsedTypes : public UsedTypes< Use<CVertex> ::AsVertexType,
Use<CFace> ::AsFaceType>{};
/// compositing wanted proprieties
class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {};
class CMesh : public vcg::tri::TriMesh< std::vector<CVertex>, std::vector<CFace> > {};
class GLArea:public QGLWidget
{
Q_OBJECT
public:
GLArea (QWidget * parent = 0);
/// we chose a subset of the available drawing modes
enum DrawMode{SMOOTH=0,POINTS,WIRE,FLATWIRE,HIDDEN,FLAT};
public slots:
/// widget-based user interaction slots
void selectDrawMode(int mode);
void loadMesh(QString filename);
void loadTetrahedron();
void loadDodecahedron();
signals:
/// signal for setting the statusbar message
void setStatusBar(QString message);
protected:
/// opengl initialization and drawing calls
void initializeGL ();
void resizeGL (int w, int h);
void paintGL ();
/// keyboard and mouse event callbacks
void keyReleaseEvent(QKeyEvent * e);
void keyPressEvent(QKeyEvent * e);
void mousePressEvent(QMouseEvent*e);
void mouseMoveEvent(QMouseEvent*e);
void mouseReleaseEvent(QMouseEvent*e);
void wheelEvent(QWheelEvent*e);
private:
/// the active mesh instance
CMesh mesh;
/// the active mesh opengl wrapper
vcg::GlTrimesh<CMesh> glWrap;
/// the active manipulator
vcg::Trackball track;
/// the current drawmode
DrawMode drawmode;
/// mesh data structure initializer
void initMesh(QString message);
};
#endif /*GLAREA_H_ */

48
vcglib/apps/QT/trimesh_QT/main.cpp

@ -0,0 +1,48 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
/**
* Minimal QT trimesh viewer
*
* This sample shows how to use togheter:
* - the Opengl module in QT using the designer
* - the trimesh loading and initialization
* - basic usage of the default manipulators (the "Trackball")
*/
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow *mw = new MainWindow;
mw->show();
return app.exec();
}

68
vcglib/apps/QT/trimesh_QT/mainwindow.cpp

@ -0,0 +1,68 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#include "mainwindow.h"
#include <QFileDialog>
MainWindow::MainWindow (QWidget * parent):QMainWindow (parent)
{
ui.setupUi (this);
//connections
//from toolFrame to glArea
connect (ui.drawModeComboBox, SIGNAL (currentIndexChanged(int)),
ui.glArea, SLOT (selectDrawMode(int)));
connect (ui.loadTetrahedronPushButton, SIGNAL (clicked()),
ui.glArea, SLOT (loadTetrahedron()));
connect (ui.loadDodecahedronPushButton, SIGNAL (clicked()),
ui.glArea, SLOT (loadDodecahedron()));
//from toolFrame to glArea through mainwindow
connect (ui.loadMeshPushButton, SIGNAL (clicked()),
this, SLOT (chooseMesh()));
connect (this, SIGNAL (loadMesh(QString)),
ui.glArea, SLOT(loadMesh(QString)));
//from glArea to statusbar
connect (ui.glArea, SIGNAL (setStatusBar(QString)),
ui.statusbar, SLOT (showMessage(QString)));
}
// mesh chooser file dialog
void MainWindow::chooseMesh()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Mesh"), QDir::currentPath(),
tr("Poly Model (*.ply)"));
if(!fileName.isEmpty())
emit loadMesh(fileName);
}

47
vcglib/apps/QT/trimesh_QT/mainwindow.h

@ -0,0 +1,47 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include "ui_mainwindow.h"
class MainWindow:public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget * parent = 0);
public slots:
void chooseMesh();
signals:
void loadMesh(QString newMesh);
private:
Ui::mainWindow ui;
};
#endif /*MAINWINDOW_H_ */

197
vcglib/apps/QT/trimesh_QT/mainwindow.ui

@ -0,0 +1,197 @@
<ui version="4.0" >
<class>mainWindow</class>
<widget class="QMainWindow" name="mainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>715</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle" >
<string>Trimesh QT</string>
</property>
<widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QFrame" name="toolsFrame" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="drawModeLabel" >
<property name="text" >
<string>Draw &amp;Mode :</string>
</property>
<property name="buddy" >
<cstring>drawModeComboBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="drawModeComboBox" >
<item>
<property name="text" >
<string>Smooth</string>
</property>
</item>
<item>
<property name="text" >
<string>Points</string>
</property>
</item>
<item>
<property name="text" >
<string>Wire</string>
</property>
</item>
<item>
<property name="text" >
<string>Flat Wire</string>
</property>
</item>
<item>
<property name="text" >
<string>Hidden</string>
</property>
</item>
<item>
<property name="text" >
<string>Flat</string>
</property>
</item>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="loadMeshPushButton" >
<property name="text" >
<string>Load &amp;Mesh</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadTetrahedronPushButton" >
<property name="text" >
<string>Load &amp;Tetrahedron</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loadDodecahedronPushButton" >
<property name="text" >
<string>Load &amp;Dodecahedron</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="glFrame" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="GLArea" native="1" name="glArea" >
<property name="minimumSize" >
<size>
<width>320</width>
<height>240</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>715</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar" />
</widget>
<customwidgets>
<customwidget>
<class>GLArea</class>
<extends>QWidget</extends>
<header>glarea.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>drawModeComboBox</tabstop>
<tabstop>loadMeshPushButton</tabstop>
<tabstop>loadTetrahedronPushButton</tabstop>
<tabstop>loadDodecahedronPushButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

46
vcglib/apps/QT/trimesh_QT/trimesh_qt.pro

@ -0,0 +1,46 @@
# Base options
TEMPLATE = app
LANGUAGE = C++
# QT modules
QT += opengl
# Executable name
TARGET = trimesh_qt
# Directories
DESTDIR = .
UI_DIR = build/ui
MOC_DIR = build/moc
OBJECTS_DIR = build/obj
# Lib headers
INCLUDEPATH += .
INCLUDEPATH += ../../..
INCLUDEPATH += ../../../eigenlib
# Lib sources
SOURCES += ../../../wrap/ply/plylib.cpp
SOURCES += ../../../wrap/gui/trackball.cpp
SOURCES += ../../../wrap/gui/trackmode.cpp
# Compile glew
DEFINES += GLEW_STATIC
INCLUDEPATH += ../../../../code/lib/glew/include
SOURCES += ../../../../code/lib/glew/src/glew.c
# Awful problem with windows..
win32{
DEFINES += NOMINMAX
}
# Input
HEADERS += mainwindow.h
HEADERS += glarea.h
SOURCES += main.cpp
SOURCES += mainwindow.cpp
SOURCES += glarea.cpp
FORMS += mainwindow.ui

232
vcglib/apps/QT/trimesh_QT_shared/glarea.cpp

@ -0,0 +1,232 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2007/10/18 08:52:06 benedetti
Initial release.
****************************************************************************/
#include "glarea.h"
#include <QKeyEvent>
#include <QKeyEvent>
#include <QWheelEvent>
#include <wrap/qt/trackball.h>
#include <cassert>
#include <wrap/gl/trimesh.h>
#include "mainwindow.h"
GLArea::GLArea (SharedDataOpenGLContext* sharedcontext,MainWindow* parent)
:QGLWidget(NULL,sharedcontext),parwin(parent)
{
}
GLArea::~GLArea()
{
}
void GLArea::initializeGL()
{
makeCurrent();
glewExperimental=GL_TRUE;
glewInit();
glClearColor(0, 0, 0, 0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
GLenum err = glGetError();
assert(err == GL_NO_ERROR);
doneCurrent();
}
void GLArea::resizeGL (int w, int h)
{
makeCurrent();
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
doneCurrent();
//initializeGL();
}
void GLArea::paintGL ()
{
if (parwin == NULL)
return;
SharedDataOpenGLContext::MultiViewManager* man = parwin->getMultiviewerManager();
if (man == NULL)
return;
CMeshO& mesh = parwin->currentMesh();
//glt.m = &mesh;
makeCurrent();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(25, GLArea::width()/(float)GLArea::height(), 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
track.center=vcg::Point3f(0, 0, 0);
track.radius= 1;
track.GetView();
track.Apply();
glPushMatrix();
if (mesh.VN() > 0)
{
float d=2.0f/mesh.bbox.Diag();
vcg::glScale(d);
glTranslate(-mesh.bbox.Center());
man->draw(context());
}
glPopMatrix();
track.DrawPostApply();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
GLenum err = glGetError();
assert(err == GL_NO_ERROR);
}
void GLArea::keyReleaseEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier));
makeCurrent();
updateGL ();
doneCurrent();
}
void GLArea::keyPressEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt)
track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier));
makeCurrent();
updateGL ();
doneCurrent();
}
void GLArea::mousePressEvent (QMouseEvent * e)
{
e->accept ();
setFocus ();
track.MouseDown (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ()));
makeCurrent();
updateGL ();
doneCurrent();
}
void GLArea::mouseMoveEvent (QMouseEvent * e)
{
if (e->buttons ()) {
track.MouseMove (QT2VCG_X(this,e), QT2VCG_Y(this,e));
makeCurrent();
updateGL ();
doneCurrent();
}
}
void GLArea::mouseReleaseEvent (QMouseEvent * e)
{
track.MouseUp (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ()));
makeCurrent();
updateGL ();
doneCurrent();
}
void GLArea::wheelEvent (QWheelEvent * e)
{
const int WHEEL_STEP = 120;
track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
makeCurrent();
updateGL ();
doneCurrent();
}
void GLArea::resetTrackBall()
{
track.Reset();
makeCurrent();
updateGL();
doneCurrent();
}
SharedDataOpenGLContext::SharedDataOpenGLContext(CMeshO& mesh,vcg::QtThreadSafeMemoryInfo& mi,QWidget* parent)
:QGLWidget(parent),manager(mesh,mi,100000)
{
}
SharedDataOpenGLContext::~SharedDataOpenGLContext()
{
}
void SharedDataOpenGLContext::myInitGL()
{
makeCurrent();
glewInit();
doneCurrent();
}
void SharedDataOpenGLContext::deAllocateBO()
{
makeCurrent();
manager.removeAllViewsAndDeallocateBO();
doneCurrent();
}
void SharedDataOpenGLContext::setPerViewRendAtts( QGLContext* viewid,vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK mm,vcg::GLMeshAttributesInfo::RendAtts& atts )
{
manager.setPerViewInfo(viewid,mm,atts);
}
void SharedDataOpenGLContext::manageBuffers()
{
makeCurrent();
manager.manageBuffers();
doneCurrent();
}

103
vcglib/apps/QT/trimesh_QT_shared/glarea.h

@ -0,0 +1,103 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2007/10/18 08:52:06 benedetti
Initial release.
****************************************************************************/
#ifndef GLAREA_H_
#define GLAREA_H_
/// Opengl related imports
#include <GL/glew.h>
#include <QGLWidget>
/// wrapper imports
#include <wrap/gui/trackball.h>
#include <wrap/qt/qt_thread_safe_memory_info.h>
#include <wrap/qt/qt_thread_safe_mesh_attributes_multi_viewer_bo_manager.h>
#include <wrap/gl/trimesh.h>
#include "mesh.h"
class MainWindow;
class SharedDataOpenGLContext : public QGLWidget
{
Q_OBJECT
public:
typedef vcg::QtThreadSafeGLMeshAttributesMultiViewerBOManager<CMeshO,QGLContext*> MultiViewManager;
SharedDataOpenGLContext(CMeshO& mesh,vcg::QtThreadSafeMemoryInfo& mi,QWidget* parent = 0);
~SharedDataOpenGLContext();
void myInitGL();
void deAllocateBO();
void setPerViewRendAtts(QGLContext* view,vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK mm,vcg::GLMeshAttributesInfo::RendAtts& atts);
void manageBuffers();
MultiViewManager manager;
};
class GLArea:public QGLWidget
{
Q_OBJECT
public:
GLArea (SharedDataOpenGLContext* sharedcontext,MainWindow* parent);
~GLArea();
void resetTrackBall();
//unsigned int getId() const {return areaid;}
/// we chose a subset of the available drawing modes
signals:
/// signal for setting the statusbar message
void setStatusBar(QString message);
void updateRenderModalityRequested(int);
protected:
/// opengl initialization and drawing calls
void initializeGL ();
void resizeGL (int w, int h);
void paintGL ();
/// keyboard and mouse event callbacks
void keyReleaseEvent(QKeyEvent * e);
void keyPressEvent(QKeyEvent * e);
void mousePressEvent(QMouseEvent*e);
void mouseMoveEvent(QMouseEvent*e);
void mouseReleaseEvent(QMouseEvent*e);
void wheelEvent(QWheelEvent*e);
private:
MainWindow* parwin;
/// the active manipulator
vcg::Trackball track;
/// mesh data structure initializer
void initMesh(QString message);
//unsigned int areaid;
//vcg::GlTrimesh<CMeshO> glt;
};
#endif /*GLAREA_H_ */

48
vcglib/apps/QT/trimesh_QT_shared/main.cpp

@ -0,0 +1,48 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
/**
* Minimal QT trimesh viewer
*
* This sample shows how to use togheter:
* - the Opengl module in QT using the designer
* - the trimesh loading and initialization
* - basic usage of the default manipulators (the "Trackball")
*/
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mw;
mw.show();
return app.exec();
}

243
vcglib/apps/QT/trimesh_QT_shared/mainwindow.cpp

@ -0,0 +1,243 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#include "mainwindow.h"
#include "glarea.h"
#include <QGridLayout>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QTime>
QProgressBar *MainWindow::qb;
QStatusBar* MainWindow::sb;
MainWindow::MainWindow (QWidget * parent)
:QMainWindow (parent),mi(2000000000),mesh()
{
ui.setupUi (this);
initTable();
QGridLayout* grid = new QGridLayout();
//parent is set to NULL in order to avoid QT bug on MAC (business as usual...).
//The QGLWidget are destroyed by hand in the MainWindow destructor...
shared = new SharedDataOpenGLContext(mesh,mi,NULL);
shared->setHidden(true);
shared->myInitGL();
for(unsigned int ii = 0;ii < 2;++ii)
{
rendbox[ii] = new QComboBox(this);
for(QMap<MyDrawMode,QString>::iterator it = stringrendtable.begin();it != stringrendtable.end();++it)
rendbox[ii]->addItem(it.value());
rendbox[ii]->setCurrentIndex((int) MDM_SMOOTH);
glar[ii] = new GLArea(shared,this);
connect(rendbox[ii],SIGNAL(activated(int)),glar[ii],SIGNAL(updateRenderModalityRequested(int)));
connect(glar[ii],SIGNAL(updateRenderModalityRequested(int)),this,SLOT(updateRenderModality(int)));
//connect(shared,SIGNAL(dataReadyToBeRead(MyDrawMode,vcg::GLFeederInfo::ReqAtts&)),glar[ii], SLOT(updateRequested(MyDrawMode,vcg::GLFeederInfo::ReqAtts&)));
grid->addWidget(rendbox[ii],0,ii,1,1,Qt::AlignRight);
grid->addWidget(glar[ii],1,ii,1,1);
}
ui.glbox->setLayout(grid);
connect(ui.actionLoad_Mesh,SIGNAL(triggered()),this,SLOT(chooseMesh()));
connect (ui.actionLoad_Tetrahedron, SIGNAL (triggered()),this, SLOT (loadTetrahedron()));
connect (ui.actionLoad_Dodecahedron, SIGNAL (triggered()),this, SLOT (loadDodecahedron()));
sb = statusBar();
qb=new QProgressBar(this);
qb->setMaximum(100);
qb->setMinimum(0);
qb->reset();
statusBar()->addPermanentWidget(qb,0);
}
// mesh chooser file dialog
void MainWindow::chooseMesh()
{
mesh.Clear();
QString plyext("ply");
QString objext("obj");
QString extoptions = QString("Poly Model (*.") + plyext + ");;OBJ Model (*." + objext + ")";
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Mesh"), QDir::currentPath(),
extoptions);
QFileInfo fi(fileName);
QTime loadingtime;
loadingtime.start();
int err=0;
if (fi.suffix() == plyext)
err=vcg::tri::io::ImporterPLY<CMeshO>::Open(mesh,(fileName.toStdString()).c_str(),qCallBack);
else
if (fi.suffix() == objext)
{
int loadmask;
err=vcg::tri::io::ImporterOBJ<CMeshO>::Open(mesh,(fileName.toStdString()).c_str(),loadmask,qCallBack);
}
int msec = loadingtime.elapsed();
if(err!=0)
{
const char* errmsg=vcg::tri::io::ImporterPLY<CMeshO>::ErrorMsg(err);
QMessageBox::warning(this,tr("Error Loading Mesh"),QString(errmsg));
}
QString msg = fileName + " vtx: " + QString::number(mesh.VN()) + " fcs: " + QString::number(mesh.FN()) + " loading time: " + QString::number(msec) + " msec";
initMesh(msg);
}
void MainWindow::loadTetrahedron()
{
mesh.Clear();
vcg::tri::Tetrahedron(mesh);
initMesh(tr("Tethraedron [builtin]"));
}
void MainWindow::loadDodecahedron()
{
mesh.Clear();
vcg::tri::Dodecahedron(mesh);
initMesh(tr("Dodecahedron [builtin]"));
}
void MainWindow::initMesh(QString& message)
{
if (shared != NULL)
shared->deAllocateBO();
// update bounding box
vcg::tri::UpdateBounding<CMeshO>::Box(mesh);
// update Normals
vcg::tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFaceNormalized(mesh);
QTime rdsetuptime;
rdsetuptime.start();
for(unsigned int ii = 0;ii < 2;++ii)
if ((glar[ii] != NULL) && (rendbox[ii] != NULL))
{
glar[ii]->resetTrackBall();
MyDrawMode mdm = (MyDrawMode) rendbox[ii]->currentIndex();
QMap<MyDrawMode,QPair<vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK, vcg::GLMeshAttributesInfo::RendAtts> >::iterator it = rendtable.find(mdm);
if (it == rendtable.end())
return;
shared->setPerViewRendAtts(glar[ii]->context(),it.value().first,it.value().second);
}
shared->manageBuffers();
for(unsigned int ii = 0;ii < 2;++ii)
glar[ii]->updateGL();
qb->reset();
int msec = rdsetuptime.elapsed();
message += " bo creation: " + QString::number(msec) + " msec";
statusBar()->showMessage(message);
}
void MainWindow::updateRenderModality(int clickedindex)
{
GLArea* glasender = qobject_cast<GLArea*>(sender());
if (glasender == NULL)
return;
updateRenderModality(glasender,clickedindex);
}
void MainWindow::updateRenderModality( GLArea* area,int clickedindex )
{
if ((shared == NULL) || (area == NULL))
return;
MyDrawMode mdm = (MyDrawMode) clickedindex;
QMap<MyDrawMode,QPair<vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK, vcg::GLMeshAttributesInfo::RendAtts> >::iterator it = rendtable.find(mdm);
if (it == rendtable.end())
return;
shared->setPerViewRendAtts(area->context(),it.value().first,it.value().second);
shared->manageBuffers();
for(unsigned int ii = 0;ii < 2;++ii)
glar[ii]->updateGL();
}
MainWindow::~MainWindow()
{
for(int ii = 0;ii < 2;++ii)
delete glar[ii];
delete shared;
}
void MainWindow::initTable()
{
stringrendtable[MDM_SMOOTH] = QString("Solid Smooth");
stringrendtable[MDM_FLAT] = QString("Solid Flat");
stringrendtable[MDM_WIRE] = QString("Wire");
stringrendtable[MDM_POINTS] = QString("Points");
stringrendtable[MDM_QUAD_WIRE] = QString("Wire Quad");
stringrendtable[MDM_QUAD_SMOOTH_WIRE] = QString("Wire Solid Smooth Quad");
vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK mmask = vcg::GLMeshAttributesInfo::PR_SOLID;
vcg::GLMeshAttributesInfo::RendAtts ratts;
ratts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTPOSITION] = true;
ratts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTNORMAL] = true;
rendtable[MDM_SMOOTH] = qMakePair(mmask,ratts);
ratts.reset(true);
ratts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_FACENORMAL] = true;
rendtable[MDM_FLAT] = qMakePair(mmask,ratts);
ratts.reset(true);
mmask = vcg::GLMeshAttributesInfo::PR_WIREFRAME_TRIANGLES;
rendtable[MDM_WIRE] = qMakePair(mmask,ratts);
ratts.reset(true);
mmask = vcg::GLMeshAttributesInfo::PR_POINTS;
ratts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTNORMAL] = true;
rendtable[MDM_POINTS] = qMakePair(mmask,ratts);
ratts.reset(true);
mmask = vcg::GLMeshAttributesInfo::PR_WIREFRAME_EDGES;
rendtable[MDM_QUAD_WIRE] = qMakePair(mmask,ratts);
ratts.reset(true);
mmask = vcg::GLMeshAttributesInfo::PR_WIREFRAME_EDGES | vcg::GLMeshAttributesInfo::PR_SOLID;
ratts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTNORMAL] = true;
rendtable[MDM_QUAD_SMOOTH_WIRE] = qMakePair(mmask,ratts);
}
bool MainWindow::qCallBack(const int pos, const char * str)
{
int static lastPos=-1;
if(pos==lastPos) return true;
lastPos=pos;
static QTime currTime = QTime::currentTime();
if(currTime.elapsed()< 100) return true;
currTime.start();
sb->showMessage(str,5000);
qb->show();
qb->setEnabled(true);
qb->setValue(pos);
sb->update();
qApp->processEvents();
return true;
}
SharedDataOpenGLContext::MultiViewManager* MainWindow::getMultiviewerManager()
{
if (shared == NULL)
return NULL;
return &(shared->manager);
}

83
vcglib/apps/QT/trimesh_QT_shared/mainwindow.h

@ -0,0 +1,83 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include <GL/glew.h>
#include <QGLContext>
#include "ui_mainwindow.h"
#include "mesh.h"
#include <wrap/gl/gl_mesh_attributes_info.h>
#include <wrap/qt/qt_thread_safe_mesh_attributes_multi_viewer_bo_manager.h>
#include <wrap/qt/qt_thread_safe_memory_info.h>
#include <QProgressBar>
#include <QStatusBar>
#include <QComboBox>
#include "glarea.h"
enum MyDrawMode{MDM_SMOOTH=0,MDM_POINTS,MDM_WIRE,MDM_FLAT,MDM_QUAD_WIRE,MDM_QUAD_SMOOTH_WIRE};
class MainWindow:public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget * parent = 0);
~MainWindow();
CMeshO& currentMesh() {return mesh;}
SharedDataOpenGLContext::MultiViewManager* getMultiviewerManager();
void updateRenderModality(GLArea* area,int clickedindex);
static bool qCallBack(const int pos, const char * str);
public slots:
void chooseMesh();
void loadTetrahedron();
void loadDodecahedron();
void initMesh(QString& message);
void updateRenderModality(int clickedindex);
signals:
void loadMesh(QString newMesh);
void updateRenderModalityRequested(int);
private:
void initTable();
Ui::mainWindow ui;
GLArea* glar[2];
SharedDataOpenGLContext* shared;
vcg::QtThreadSafeMemoryInfo mi;
QComboBox* rendbox[2];
/// the active mesh instance
CMeshO mesh;
QMap<MyDrawMode,QString> stringrendtable;
QMap<MyDrawMode,QPair<vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK,vcg::GLMeshAttributesInfo::RendAtts> > rendtable;
static QProgressBar* qb;
static QStatusBar* sb;
};
#endif /*MAINWINDOW_H_ */

82
vcglib/apps/QT/trimesh_QT_shared/mainwindow.ui

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mainWindow</class>
<widget class="QMainWindow" name="mainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>715</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle">
<string>Trimesh QT</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QWidget" name="glbox" native="true"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>715</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionLoad_Mesh"/>
<addaction name="actionLoad_Tetrahedron"/>
<addaction name="actionLoad_Dodecahedron"/>
<addaction name="separator"/>
<addaction name="actionClose"/>
</widget>
<addaction name="menuFile"/>
</widget>
<action name="actionLoad_Mesh">
<property name="text">
<string>Load Mesh</string>
</property>
</action>
<action name="actionLoad_Tetrahedron">
<property name="text">
<string>Load Tetrahedron</string>
</property>
</action>
<action name="actionLoad_Dodecahedron">
<property name="text">
<string>Load Dodecahedron</string>
</property>
</action>
<action name="actionClose">
<property name="text">
<string>Close</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

28
vcglib/apps/QT/trimesh_QT_shared/mesh.h

@ -0,0 +1,28 @@
#ifndef MESH_H
#define MESH_H
/// vcg imports
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <wrap/io_trimesh/import.h>
using namespace vcg;
class CFaceO;
class CVertexO;
class CEdgeO;
struct MyUsedTypes : public UsedTypes<Use<CVertexO> ::AsVertexType, vcg::Use<CEdgeO >::AsEdgeType,
Use<CFaceO> ::AsFaceType>{};
/// compositing wanted proprieties
class CVertexO : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
class CFaceO : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {};
class CEdgeO : public vcg::Edge<MyUsedTypes,vcg::edge::BitFlags,vcg::edge::EVAdj,vcg::edge::EEAdj>{};
class CMeshO : public vcg::tri::TriMesh< std::vector<CVertexO>, std::vector<CFaceO>,std::vector<CEdgeO> >
{
};
#endif

51
vcglib/apps/QT/trimesh_QT_shared/trimesh_qt.pro

@ -0,0 +1,51 @@
# Base options
TEMPLATE = app
LANGUAGE = C++
# QT modules
QT += opengl
# Executable name
TARGET = trimesh_qt
# Directories
DESTDIR = .
UI_DIR = build/ui
MOC_DIR = build/moc
OBJECTS_DIR = build/obj
# Lib headers
INCLUDEPATH += .
INCLUDEPATH += ../../..
# Lib sources
SOURCES += ../../../wrap/ply/plylib.cpp
SOURCES += ../../../wrap/gui/trackball.cpp
SOURCES += ../../../wrap/gui/trackmode.cpp
# Compile glew
DEFINES += GLEW_STATIC
INCLUDEPATH += ../../../../lib/glew/include
SOURCES += ../../../../lib/glew/src/glew.c
# Awful problem with windows..
win32{
DEFINES += NOMINMAX
}
# Input
HEADERS += mainwindow.h
HEADERS += glarea.h
SOURCES += main.cpp
SOURCES += mainwindow.cpp
SOURCES += glarea.cpp
FORMS += mainwindow.ui
linux-g++:LIBS += -lGLU
linux-g++-32:LIBS += -lGLU
linux-g++-64:LIBS += -lGLU

334
vcglib/apps/QT/trimesh_ant_freeglut/main.cpp

@ -0,0 +1,334 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2007 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/**
* Minimal trimesh viewer made with AntTweakBar and freglut
*
* This sample shows how to use togheter:
* - the trimesh loading and initialization
* - basic usage of the default manipulators (the "Trackball")
*/
#include <AntTweakBar.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
/// vcg imports
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/face/base.h>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/create/platonic.h>
/// wrapper imports
#include <wrap/io_trimesh/import.h>
#include <wrap/gl/trimesh.h>
#include <wrap/gui/trackball.h>
/// declaring edge and face type
using namespace vcg;
class CFace;
class CVertex;
struct MyUsedTypes : public UsedTypes< Use<CVertex> ::AsVertexType,
Use<CFace> ::AsFaceType>{};
/// compositing wanted proprieties
class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {};
class CMesh : public vcg::tri::TriMesh< std::vector<CVertex>, std::vector<CFace> > {};
/// the active mesh instance
CMesh mesh;
/// filename of the mesh to load
char * filename = NULL;
/// the active mesh opengl wrapper
vcg::GlTrimesh<CMesh> glWrap;
/// the active manipulator
vcg::Trackball track;
/// window size
int width,height;
/// we chose a subset of the available drawing modes
enum DrawMode{SMOOTH=0,PERPOINTS,WIRE,FLATWIRE,HIDDEN,FLAT};
/// the current drawmode
DrawMode drawmode;
/// Takes a GLUT MouseButton and returns the equivalent Trackball::Button
static vcg::Trackball::Button GLUT2VCG (int glut_button, int )
{
int vcgbt = vcg::Trackball::BUTTON_NONE;
switch(glut_button){
case GLUT_LEFT_BUTTON: vcgbt |= vcg::Trackball::BUTTON_LEFT; break;
case GLUT_MIDDLE_BUTTON: vcgbt |= vcg::Trackball::BUTTON_RIGHT; break;
case GLUT_RIGHT_BUTTON: vcgbt |= vcg::Trackball::BUTTON_MIDDLE; break;
}
int modifiers = glutGetModifiers();
if (modifiers & GLUT_ACTIVE_SHIFT) vcgbt |= vcg::Trackball::KEY_SHIFT;
if (modifiers & GLUT_ACTIVE_CTRL) vcgbt |= vcg::Trackball::KEY_CTRL;
if (modifiers & GLUT_ACTIVE_ALT) vcgbt |= vcg::Trackball::KEY_ALT;
return vcg::Trackball::Button (vcgbt);
}
void Display(){
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(!mesh.face.empty()){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, width /(float) height , 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
track.center=vcg::Point3f(0, 0, 0);
track.radius= 1;
track.GetView();
track.Apply();
glPushMatrix();
float d=1.0f/mesh.bbox.Diag();
vcg::glScale(d);
glTranslate(-glWrap.m->bbox.Center());
// the trimesh drawing calls
switch(drawmode)
{
case SMOOTH:
glWrap.Draw<vcg::GLW::DMSmooth, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case PERPOINTS:
glWrap.Draw<vcg::GLW::DMPoints, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case WIRE:
glWrap.Draw<vcg::GLW::DMWire, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case FLATWIRE:
glWrap.Draw<vcg::GLW::DMFlatWire, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case HIDDEN:
glWrap.Draw<vcg::GLW::DMHidden, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
case FLAT:
glWrap.Draw<vcg::GLW::DMFlat, vcg::GLW::CMNone,vcg::GLW::TMNone> ();
break;
default:
break;
}
glPopMatrix();
track.DrawPostApply();
}
TwDraw();
// Present frame buffer
glutSwapBuffers();
// Recall Display at next frame
glutPostRedisplay();
}
void Reshape(int _width,int _height){
width = _width ;
height = _height;
TwWindowSize(width, height);
}
void Terminate(){}
void initMesh()
{
// update bounding box
vcg::tri::UpdateBounding<CMesh>::Box(mesh);
// update Normals
vcg::tri::UpdateNormals<CMesh>::PerVertexNormalizedPerFace(mesh);
vcg::tri::UpdateNormals<CMesh>::PerFaceNormalized(mesh);
// Initialize the opengl wrapper
glWrap.m = &mesh;
glWrap.Update();
}
void TW_CALL loadMesh(void *)
{
if(filename==0) return;
int err=vcg::tri::io::ImporterPLY<CMesh>::Open(mesh,(char*)filename);
if(err!=0){
const char* errmsg=vcg::tri::io::ImporterPLY<CMesh>::ErrorMsg(err);
}
else
initMesh();
}
void TW_CALL loadTetrahedron(void *){
vcg::tri::Tetrahedron(mesh);
initMesh();
}
void TW_CALL loadDodecahedron(void * ){
vcg::tri::Dodecahedron(mesh);
initMesh();
}
void keyReleaseEvent (unsigned char k,int x,int y)
{
int modifiers = glutGetModifiers();
if (modifiers & GLUT_ACTIVE_CTRL)
track.ButtonUp (Trackball::Button::KEY_CTRL);
if (modifiers & GLUT_ACTIVE_SHIFT)
track.ButtonUp ( Trackball::Button::KEY_SHIFT);
if (modifiers & GLUT_ACTIVE_ALT)
track.ButtonUp (Trackball::Button::KEY_ALT);
}
void keyPressEvent (unsigned char k,int x,int y)
{
int modifiers = glutGetModifiers();
if (modifiers & GLUT_ACTIVE_CTRL)
track.ButtonDown (Trackball::Button::KEY_CTRL);
if (modifiers & GLUT_ACTIVE_SHIFT)
track.ButtonDown ( Trackball::Button::KEY_SHIFT);
if (modifiers & GLUT_ACTIVE_ALT)
track.ButtonDown (Trackball::Button::KEY_ALT);
TwEventKeyboardGLUT(k,x,y);
}
void mousePressEvent(int bt,int state,int x,int y){
if(state == GLUT_DOWN)
track.MouseDown ( x , height - y , GLUT2VCG (bt,state));
else
track.MouseUp ( x , height - y , GLUT2VCG (bt,state));
TwEventMouseButtonGLUT(bt,state,x,y);
};
void mouseMoveEvent (int x, int y )
{
if(!TwEventMouseMotionGLUT(x,y))
track.MouseMove ( x , height - y );
}
//void mouseReleaseEvent(QMouseEvent*e);
void wheelEvent(int wheel, int direction, int x, int y ){
track.MouseWheel(wheel*direction);
}
void TW_CALL CopyCDStringToClient(char **destPtr, const char *src)
{
size_t srcLen = (src!=NULL) ? strlen(src) : 0;
size_t destLen = (*destPtr!=NULL) ? strlen(*destPtr) : 0;
// Alloc or realloc dest memory block if needed
if( *destPtr==NULL )
*destPtr = (char *)malloc(srcLen+1);
else if( srcLen>destLen )
*destPtr = (char *)realloc(*destPtr, srcLen+1);
// Copy src
if( srcLen>0 )
strncpy(*destPtr, src, srcLen);
(*destPtr)[srcLen] = '\0'; // null-terminated string
}
int main(int argc, char *argv[])
{
TwBar *bar; // Pointer to the tweak bar
// Initialize AntTweakBar
// (note that AntTweakBar could also be intialized after GLUT, no matter)
if( !TwInit(TW_OPENGL, NULL) )
{
// A fatal error occured
fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
return 1;
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("AntTweakBar simple example using GLUT");
glutCreateMenu(NULL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
// Set GLUT callbacks
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
atexit(Terminate); // Called after glutMainLoop ends
// Set GLUT event callbacks
// - Directly redirect GLUT mouse button events to AntTweakBar
glutMouseFunc((GLUTmousebuttonfun)mousePressEvent);
// - Directly redirect GLUT mouse motion events to AntTweakBar
glutMotionFunc((GLUTmousemotionfun)mouseMoveEvent);
// - Directly redirect GLUT mouse "passive" motion events to AntTweakBar (same as MouseMotion)
glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
// - Directly redirect GLUT key events to AntTweakBar
glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT);
// - Directly redirect GLUT special key events to AntTweakBar
glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT);
glutKeyboardFunc(keyPressEvent);
glutKeyboardUpFunc(keyReleaseEvent);
glutMouseWheelFunc(wheelEvent);
bar = TwNewBar("TweakBar");
TwCopyCDStringToClientFunc (CopyCDStringToClient);
TwAddVarRW(bar,"Input",TW_TYPE_CDSTRING,&filename," label='Filepath' group=SetMesh help=` Name of the file to load` ");
TwAddButton(bar,"Load from file",loadMesh,0, " label='Load Mesh' group=SetMesh help=`load the mesh` ");
TwAddButton(bar,"Use tetrahedron",loadTetrahedron,0, " label='Make Tetrahedron' group=SetMesh help=`use tetrahedron.` ");
TwAddButton(bar,"Use dodecahedron",loadDodecahedron,0, " label='Make Dodecahedron' group=SetMesh help=`use dodecahedron.` ");
// ShapeEV associates Shape enum values with labels that will be displayed instead of enum values
TwEnumVal drawmodes[6] = { {SMOOTH, "Smooth"}, {PERPOINTS, "Per Points"}, {WIRE, "Wire"}, {FLATWIRE, "FlatWire"},{HIDDEN, "Hidden"},{FLAT, "Flat"}};
// Create a type for the enum shapeEV
TwType drawMode = TwDefineEnum("DrawMode", drawmodes, 6);
// add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>].
TwAddVarRW(bar, "Draw Mode", drawMode, &drawmode, " keyIncr='<' keyDecr='>' help='Change draw mode.' ");
glutMainLoop();
}

40
vcglib/apps/QT/trimesh_ant_freeglut/trimesh_ant_freeglut.pro

@ -0,0 +1,40 @@
# Base options
TEMPLATE = app
LANGUAGE = C++
# Executable name
TARGET = trimesh_ant_freeglut
# Directories
DESTDIR = .
OBJECTS_DIR = build/obj
# Lib headers
INCLUDEPATH += .
INCLUDEPATH += ../../..
# Lib sources
SOURCES += ../../../wrap/ply/plylib.cpp
SOURCES += ../../../wrap/gui/trackball.cpp
SOURCES += ../../../wrap/gui/trackmode.cpp
# Compile glew
DEFINES += GLEW_STATIC
SOURCES += ../../../../code/lib/glew/src/glew.c
# Awful problem with windows..
win32{
DEFINES += NOMINMAX
INCLUDEPATH += ../../../../code/lib/glew/include
INCLUDEPATH += ../../../../code/lib/AntTweakBar/include
INCLUDEPATH += ../../../../code/lib/freeglut/include
LIBS +=../../../../code/lib/AntTweakBar/lib/AntTweakBar.lib
LIBS +=../../../../code/lib/freeglut/lib/freeglut.lib
}
unix {
LIBS += -lfreeglut
}
# Input
SOURCES += main.cpp

215
vcglib/apps/QT/trimesh_ant_qt/glwidget.cpp

@ -0,0 +1,215 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "glwidget.h"
#include <wrap/qt/trackball.h>
#include <wrap/gl/picking.h>
#include <wrap/qt/anttweakbarMapper.h>
TwBar *bar;
char * filename;/// filename of the mesh to load
CMesh mesh; /// the active mesh instance
vcg::GlTrimesh<CMesh> glWrap; /// the active mesh opengl wrapper
vcg::Trackball track; /// the active manipulator
GLW::DrawMode drawmode=GLW::DMFlatWire; /// the current drawmode
void TW_CALL loadTetrahedron(void *){
vcg::tri::Tetrahedron(mesh);
vcg::tri::UpdateBounding<CMesh>::Box(mesh);
vcg::tri::UpdateNormal<CMesh>::PerVertexNormalizedPerFace(mesh);
vcg::tri::UpdateNormal<CMesh>::PerFaceNormalized(mesh);
glWrap.m = &mesh;
glWrap.Update();
}
void TW_CALL loadMesh(void *)
{
if(filename==0) return;
int err=vcg::tri::io::ImporterPLY<CMesh>::Open(mesh,(char*)filename);
if(err==ply::E_NOERROR)
{
vcg::tri::UpdateBounding<CMesh>::Box(mesh);
vcg::tri::UpdateNormal<CMesh>::PerVertexNormalizedPerFace(mesh);
vcg::tri::UpdateNormal<CMesh>::PerFaceNormalized(mesh);
glWrap.m = &mesh;
glWrap.Update();
}
}
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
filename=0;
hasToPick=false;
setWindowTitle(tr("Hello GL"));
bar = TwNewBar("TweakBar");
TwCopyCDStringToClientFunc (CopyCDStringToClient);
TwAddVarRW(bar,"Input",TW_TYPE_CDSTRING, &filename," label='Filepath' group=SetMesh help=` Name of the file to load` ");
TwAddButton(bar,"Load from file",loadMesh,0, " label='Load Mesh' group=SetMesh help=`load the mesh` ");
TwAddButton(bar,"Use tetrahedron",loadTetrahedron,0, " label='Make Tetrahedron' group=SetMesh help=`use tetrahedron.` ");
// ShapeEV associates Shape enum values with labels that will be displayed instead of enum values
TwEnumVal drawmodes[6] = { {GLW::DMSmooth, "Smooth"}, {GLW::DMPoints, "Per Points"}, {GLW::DMWire, "Wire"}, {GLW::DMFlatWire, "FlatWire"},{GLW::DMHidden, "Hidden"},{GLW::DMFlat, "Flat"}};
// Create a type for the enum shapeEV
TwType drawMode = TwDefineEnum("DrawMode", drawmodes, 6);
// add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>].
TwAddVarRW(bar, "Draw Mode", drawMode, &drawmode, " keyIncr='<' keyDecr='>' help='Change draw mode.' ");
}
void GLWidget::initializeGL ()
{
glewInit();
glClearColor(0, 0, 0, 0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}
void GLWidget::resizeGL (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
TwWindowSize(w, h);
initializeGL();
}
void GLWidget::paintGL ()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, GLWidget::width()/(float)GLWidget::height(), 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,3.5f, 0,0,0, 0,1,0);
track.center=vcg::Point3f(0, 0, 0);
track.radius= 1;
track.GetView();
glPushMatrix();
track.Apply();
glPushMatrix();
if(mesh.vert.size()>0)
{
vcg::glScale(2.0f/mesh.bbox.Diag());
glTranslate(-mesh.bbox.Center());
glWrap.Draw(GLW::DrawMode(drawmode),GLW::CMNone,GLW::TMNone);
}
glPopMatrix();
track.DrawPostApply();
glPopMatrix();
if(hasToPick)
{
hasToPick=false;
Point3f pp;
if(Pick<Point3f>(pointToPick[0],pointToPick[1],pp))
{
track.Translate(-pp);
track.Scale(1.25f);
QCursor::setPos(mapToGlobal(QPoint(width()/2+2,height()/2+2)));
}
}
TwDraw();
}
void GLWidget::keyReleaseEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier));
updateGL ();
}
void GLWidget::keyPressEvent (QKeyEvent * e)
{
e->ignore ();
if (e->key () == Qt::Key_Control) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier));
if (e->key () == Qt::Key_Shift) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier));
if (e->key () == Qt::Key_Alt) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier));
TwKeyPressQt(e);
updateGL ();
}
void GLWidget::mousePressEvent (QMouseEvent * e)
{
if(!TwMousePressQt(e))
{
e->accept ();
setFocus ();
track.MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
}
updateGL ();
}
void GLWidget::mouseMoveEvent (QMouseEvent * e)
{
if (e->buttons ()) {
track.MouseMove (e->x (), height () - e->y ());
updateGL ();
}
TwMouseMotion(e->x (), e->y ());
}
void GLWidget::mouseDoubleClickEvent (QMouseEvent * e)
{
hasToPick=true;
pointToPick=Point2i(e->x(),height()-e->y());
updateGL ();
}
void GLWidget::mouseReleaseEvent (QMouseEvent * e)
{
track.MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ()));
TwMouseReleaseQt(e);
updateGL ();
}
void GLWidget::wheelEvent (QWheelEvent * e)
{
const int WHEEL_STEP = 120;
track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
updateGL ();
}

101
vcglib/apps/QT/trimesh_ant_qt/glwidget.h

@ -0,0 +1,101 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <GL/glew.h>
#include <QGLWidget>
#include <QKeyEvent>
/// vcg imports
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/create/platonic.h>
/// wrapper imports
#include <wrap/io_trimesh/import.h>
#include <wrap/gl/trimesh.h>
#include <wrap/gui/trackball.h>
/// declaring edge and face type
#include <AntTweakBar.h>
using namespace vcg;
class CFace;
class CVertex;
struct MyUsedTypes : public UsedTypes< Use<CVertex> ::AsVertexType,
Use<CFace> ::AsFaceType>{};
/// compositing wanted proprieties
class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {};
class CMesh : public vcg::tri::TriMesh< std::vector<CVertex>, std::vector<CFace> > {};
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
bool hasToPick;
Point2i pointToPick;
~GLWidget() {};
QSize sizeHint() const {
return QSize(800, 600);
};
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseDoubleClickEvent ( QMouseEvent * event );
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
};
#endif

57
vcglib/apps/QT/trimesh_ant_qt/main.cpp

@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QApplication>
#include <QDesktopWidget>
#include "glwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
if( !TwInit(TW_OPENGL, NULL) )
{
fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError());
return 1;
}
GLWidget window;
window.show();
return app.exec();
}

40
vcglib/apps/QT/trimesh_ant_qt/trimesh_ant_qt.pro

@ -0,0 +1,40 @@
VCGLIBDIR = ../../../../vcglib
GLEWDIR = ../../../../code/lib/glew/
ANTDIR = ../../../../code/lib/AntTweakBar1.14/
HEADERS = glwidget.h
SOURCES = glwidget.cpp \
main.cpp
QT += opengl
# Compile glew
DEFINES += GLEW_STATIC
INCLUDEPATH += $$GLEWDIR/include
SOURCES += $$GLEWDIR/src/glew.c
INCLUDEPATH += $$VCGLIBDIR
INCLUDEPATH += $$GLEWDIR/include
INCLUDEPATH += $$ANTDIR/include
SOURCES += $$VCGLIBDIR/wrap/ply/plylib.cpp
SOURCES += $$VCGLIBDIR/wrap/gui/trackball.cpp
SOURCES += $$VCGLIBDIR/wrap/gui/trackmode.cpp
SOURCES += $$VCGLIBDIR/wrap/qt/anttweakbarMapper.cpp
# Awful problem with windows..
win32{
DEFINES += NOMINMAX
LIBS +=$$ANTDIR/lib/AntTweakBar.lib
}
mac{
# Mac specific Config required to avoid to make application bundles
CONFIG -= app_bundle
LIBS +=$$ANTDIR/lib/libAntTweakBar.dylib
QMAKE_POST_LINK ="cp -P ../../../../code/lib/AntTweakBar1.14/lib/libAntTweakBar.dylib . ; install_name_tool -change ../lib/libAntTweakBar.dylib ./libAntTweakBar.dylib $$TARGET"
}
unix:!macx{
LIBS +=$$ANTDIR/lib/libAntTweakBar.so -lGLU
}

280
vcglib/apps/QT/trimesh_pos_demo/glwidget.cpp

@ -0,0 +1,280 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.4 2007/05/17 09:06:44 ganovelli
gestione double click
Revision 1.3 2006/12/10 23:29:57 ganovelli
added VFIterator (Pos is disabled in this version)
Revision 1.2 2006/12/10 22:17:18 ganovelli
cvs problem during frist committ. repeated
*/
#include <QtGui>
#include <GL/glew.h>
#include <QtOpenGL>
#include <math.h>
#include "glwidget.h"
#include <wrap/io_trimesh/import_PLY.h>
#include <wrap/gl/picking.h>
#include <wrap/gl/space.h>
#include <wrap/gl/pos.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/update/topology.h>
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent)
{
object = 0;
trolltechGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
trolltechPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
track.SetPosition(vcg::Point3f(0.0,0.0,0.0));
track.SetIdentity();
track.radius = 0.4;
pos.f=NULL;
vfite.f = NULL;
doPickVfIte = false;
doPickPos = false;
}
GLWidget::~GLWidget()
{
makeCurrent();
glDeleteLists(object, 1);
}
QSize GLWidget::minimumSizeHint() const
{
return QSize(50, 50);
}
QSize GLWidget::sizeHint() const
{
return QSize(400, 400);
}
void GLWidget::LoadTriMesh(QString &namefile)
{
vcg::tri::io::ImporterPLY<MyStraightMesh>::Open(mesh,namefile.toAscii());
vcg::tri::UpdateBounding<MyStraightMesh>::Box(mesh);
vcg::tri::UpdateNormals<MyStraightMesh>::PerFace(mesh);
vcg::tri::UpdateNormals<MyStraightMesh>::PerVertex(mesh);
vcg::tri::UpdateTopology<MyStraightMesh>::FaceFace(mesh);
vcg::tri::UpdateTopology<MyStraightMesh>::VertexFace(mesh);
pos.f=0;
vfite.f=NULL;
}
void GLWidget::OpenFile(){
QStringList filters;
QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),".", filters.join("\n"));
if (fileName.isEmpty()) return;
else
LoadTriMesh( fileName );
}
void GLWidget::flipV( ){
if(pos.f) pos.FlipV();
repaint();
}
void GLWidget::flipE( ){
if(pos.f) pos.FlipE();
repaint();
}
void GLWidget::flipF( ){
if(pos.f) pos.FlipF();
repaint();
}
void GLWidget::nextE( ){
if(pos.f) pos.NextE();
repaint();
}
void GLWidget::nextB( ){
if(pos.f) pos.NextB();
repaint();
}
void GLWidget::nextVfite( ){
if(vfite.F()) ++vfite;
repaint();
}
void GLWidget::initializeGL()
{
qglClearColor(trolltechPurple.dark());
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
template <class VertexType>
void drawVertex(VertexType & v){
glPushAttrib(0xffffffff);
glPointSize(2.0);
glBegin(GL_POINTS);
glVertex(v.P());
glEnd();
glPopAttrib();
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,2, 0,0,0, 0,1,0);
track.GetView();
track.Apply();
glScalef(1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag());
glTranslate(-glWrap.m->bbox.Center());
// to do some picking
MyStraightMesh::FaceType* fp=NULL;
MyStraightMesh::VertexType* vp=NULL;
if(doPickPos)
{
std::vector<MyStraightMesh::FaceType*> res;
int yes = vcg::Pick<MyStraightMesh::FaceContainer>(pic_x,ScreenH-pic_y+1,mesh.face,res,vcg::glTriangle3<MyStraightMesh::FaceType>,1,1);
if(yes)
{fp = res[0];
pos.Set(fp,0,fp->V(0));
}
doPickPos=false;
}else
if(doPickVfIte)
{
std::vector<MyStraightMesh::VertexType*> res;
int yes = vcg::Pick<MyStraightMesh::VertContainer>(pic_x,ScreenH-pic_y+1,mesh.vert,res,drawVertex<MyStraightMesh::VertexType>,3,3);
if(yes)
{vp = res[0];
MyStraightMesh::FaceType* g = vp->VFp();
vfite=vcg::face::VFIterator<MyStraightMesh::FaceType>(vp);
}
doPickVfIte = false;
}
glWrap.Draw<vcg::GLW::DMFlatWire,vcg::GLW::CMNone,vcg::GLW::TMNone> ();
if(pos.f!=NULL) {
glPushAttrib(0xffffffff);
glDisable(GL_LIGHTING);
glColor3f(0.0,1.0,0.0);
glDepthRange(0.0,0.999);
vcg::GlPos<vcg::face::Pos<MyStraightMesh::FaceType> >::Draw(pos);
glPopAttrib();
}
if(vfite.F()!=NULL) {
glPushAttrib(0xffffffff);
glDisable(GL_LIGHTING);
glColor3f(0.0,1.0,0.0);
glDepthRange(0.0,0.99);
vcg::GlVfIterator<vcg::face::VFIterator<MyStraightMesh::FaceType> >::Draw(vfite);
glPopAttrib();
}
}
void GLWidget::mouseMoveEvent(QMouseEvent *e)
{
track.MouseMove(e->x(),ScreenH-e->y()+1);
repaint();
//if (event->buttons() & Qt::LeftButton) {
// setXRotation(xRot + 8 * dy);
//} else if (event->buttons() & Qt::RightButton) {
// setXRotation(xRot + 8 * dy);
//}
// lastPos = event->pos();
}
void GLWidget::keyPressEvent ( QKeyEvent * e ) {
if((keypress == Qt::Key_Control)&&(e->key()==Qt::Key_Control))
keypress = -1;
else
keypress = e->key();
}
void GLWidget::mouseDoubleClickEvent(QMouseEvent *e){
if(e->button() == Qt::RightButton)
doPickPos=true;
}
void GLWidget:: mousePressEvent(QMouseEvent *e)
{
if( (keypress==Qt::Key_Control) && (e->button() == Qt::LeftButton) )
track.MouseDown(e->x(),ScreenH-e->y()+1,vcg::Trackball::KEY_CTRL|vcg::Trackball::BUTTON_LEFT );
else
if(e->button() == Qt::LeftButton )
track.MouseDown(e->x(),ScreenH-e->y()+1,vcg::Trackball::BUTTON_LEFT);
else
if(e->button() == Qt::RightButton)
{
doPickVfIte=true;
pic_x = e->x();
pic_y = e->y();
}
repaint();
}
void GLWidget::mouseReleaseEvent ( QMouseEvent * e ){
if( (keypress==Qt::Key_Control) && (e->button() == Qt::LeftButton) )
track.MouseUp(e->x(),ScreenH-e->y()+1,vcg::Trackball::KEY_CTRL );
else
if(e->button() == Qt::LeftButton )
track.MouseUp(e->x(),ScreenH-e->y()+1,vcg::Trackball::BUTTON_LEFT);
repaint();
}
void GLWidget::resizeGL(int w,int h){
ScreenW=w; ScreenH=h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,ScreenW/(float)ScreenH,0.01,5);
}
void GLWidget::wheelEvent ( QWheelEvent * e ){
int v = e->delta()/(float) 120;
track.MouseWheel(v);
repaint();
}

103
vcglib/apps/QT/trimesh_pos_demo/glwidget.h

@ -0,0 +1,103 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.4 2007/05/17 09:06:44 ganovelli
gestione double click
Revision 1.3 2006/12/10 23:29:57 ganovelli
added VFIterator (Pos is disabled in this version)
Revision 1.2 2006/12/10 22:17:18 ganovelli
cvs problem during frist committ. repeated
*/
#ifndef GLWIDGET_H_POS_DEMO
#define GLWIDGET_H_POS_DEMO
#include <GL/glew.h>
#include <QGLWidget>
#include "mesh_type.h"
#include <wrap/gui/trackball.h>
#include <wrap/gl/trimesh.h>
#include <vcg/simplex/face/pos.h>
#include <vcg/simplex/face/topology.h>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
QSize minimumSizeHint() const;
QSize sizeHint() const;
int xRotation() const { return xRot; }
MyStraightMesh mesh;
vcg::GlTrimesh<MyStraightMesh> glWrap;
vcg::Trackball track;
int ScreenH,ScreenW,pic_x,pic_y,keypress;
bool doPickPos,doPickVfIte;
vcg::face::Pos< MyStraightMesh::FaceType> pos;
vcg::face::VFIterator< MyStraightMesh::FaceType> vfite;
public slots:
void flipV( );
void flipE( );
void flipF( );
void nextE( );
void nextB( );
void nextVfite( );
void LoadTriMesh(QString& namefile);
void OpenFile();
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void wheelEvent ( QWheelEvent * e );
void keyPressEvent ( QKeyEvent * e );
private:
GLuint makeObject();
void quad(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2,
GLdouble x3, GLdouble y3, GLdouble x4, GLdouble y4);
void extrude(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
void normalizeAngle(int *angle);
GLuint object;
int xRot;
QPoint lastPos;
QColor trolltechGreen;
QColor trolltechPurple;
};
#endif

11
vcglib/apps/QT/trimesh_pos_demo/main.cpp

@ -0,0 +1,11 @@
#include <QApplication>
#include "window.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window wdw;
wdw.show();
return app.exec();
}

58
vcglib/apps/QT/trimesh_pos_demo/mesh_type.h

@ -0,0 +1,58 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2006/12/10 19:55:09 ganovelli
first draft. Working but ugly interface. right mouse of the button to place a pos, then prss buttons.
*/
#pragma once
/** the definition of vertex */
#include<vcg/simplex/vertex/base.h>
/** the definition of face */
#include<vcg/simplex/face/base.h>
/** definition of triangle mesh */
#include<vcg/complex/complex.h>
/** allocation vertices and faces of triangle mesh */
#include<wrap/io_trimesh/import_PLY.h>
class DummyEdge;
class StraightFace;
/**************************************************************************************************************************/
/* DEFINITION OF A VERY STRAIGHT MESH. No optional atributes, just normals in the vertices and flags in vertices and faces*/
/** definition of a very simple vertex type. Just coordinates and normal as attributes*/
class StraightVertex: public vcg::VertexSimp2< StraightVertex, DummyEdge, StraightFace, vcg::vert::Coord3f,vcg::vert::VFAdj,vcg::vert::Normal3f,vcg::vert::BitFlags>{};
/** definition of a very simple face type. Just color and reference to vertices as attribute*/
class StraightFace: public vcg::FaceSimp2< StraightVertex, DummyEdge, StraightFace, vcg:: face::VertexRef, vcg:: face::FFAdj, vcg:: face::VFAdj,vcg:: face::Normal3f,vcg::face::BitFlags > {};
/** definition of a very simple mesh*/
class MyStraightMesh: public vcg::tri::TriMesh< std::vector<StraightVertex>,std::vector<StraightFace> >{};
/****************************************************************************************************************************/

56
vcglib/apps/QT/trimesh_pos_demo/trimesh_pos_demo.cpp

@ -0,0 +1,56 @@
#include <vector>
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/vertex/component.h>
#include <vcg/simplex/face/base.h>
#include <vcg/simplex/face/component.h>
#include <vcg/complex/complex.h>
#include<vcg/complex/algorithms/create/platonic.h>
#include<vcg/complex/algorithms/update/topology.h>
#include <vcg/simplex/face/pos.h>
class MyEdge;
class MyFace;
class MyVertex: public vcg::VertexSimp2<MyVertex,MyEdge,MyFace, vcg::vert::Coord3d, vcg::vert::Normal3f>{};
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::FFAdj>{};
class MyMesh: public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
void OneRingNeighborhood( MyFace * f)
{
MyVertex * v = f->V(0);
MyFace* start = f;
vcg::face::Pos<MyFace> p(f,0,v);// constructor that takes face, edge and vertex
do
{
p.FlipF();
p.FlipE();
}while(p.f!=start);
}
#include <vcg/simplex/face/jumping_pos.h> // include the definition of jumping pos
void OneRingNeighborhoodJP( MyFace * f)
{
MyVertex * v = f->V(0);
MyFace* start = f;
vcg::face::JumpingPos<MyFace> p(f,0,v);// constructor that takes face, edge and vertex
do
{
p.NextFE();
}while(p.f!=start);
}
int main()
{
MyMesh m;
vcg::tri::Tetrahedron(m);
vcg::tri::UpdateTopology<MyVCGMesh>::FaceFace(m);
OneRingNeighborhood(&(*m.face.begin()));
OneRingNeighborhoodJP(&(*m.face.begin()));
return 0;
}

19
vcglib/apps/QT/trimesh_pos_demo/trimesh_pos_demo.pro

@ -0,0 +1,19 @@
INCLUDEPATH += . ../../.. ../../../../code/lib ../../../../code/lib/glew/include
HEADERS = glwidget.h \
window.h \
mesh_type.h
SOURCES = glwidget.cpp \
main.cpp \
window.cpp\
../../../../code/lib/glew/src/glew.c \
../../../wrap/ply/plylib.cpp\
../../../wrap/gui/trackmode.cpp\
../../../wrap/gui/trackball.cpp
QT += opengl
# install
target.path = $$./debug
sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trimesh_pos_demo.pro
sources.path = ./
INSTALLS += target sources

39
vcglib/apps/QT/trimesh_pos_demo/trimesh_vfiter_demo.cpp

@ -0,0 +1,39 @@
#include <vector>
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/vertex/component.h>
#include <vcg/simplex/face/base.h>
#include <vcg/simplex/face/component.h>
#include <vcg/complex/complex.h>
#include<vcg/complex/algorithms/create/platonic.h>
#include<vcg/complex/algorithms/update/topology.h>
#include <vcg/simplex/face/pos.h>
class MyEdge;
class MyFace;
class MyVertex: public vcg::VertexSimp2<MyVertex,MyEdge,MyFace, vcg::vert::Coord3d, vcg::vert::Normal3f,vcg::vert::VFAdj>{};
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::VFAdj>{};
class MyMesh: public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
void OneRingNeighborhoodVF( MyVertex * v)
{
vcg::face::VFIterator<MyFace> vfi(v); //initialize the iterator tohe first face
for(;!vfi.End();++vfi)
{
MyFace* f = vfi.F();
// ...do something with face f
}
}
int main()
{
MyMesh m;
vcg::tri::Tetrahedron(m);
vcg::tri::UpdateTopology<MyVCGMesh>::VertexFace(m);
OneRingNeighborhoodVF(&(*m.vert.begin()));
return 0;
}

75
vcglib/apps/QT/trimesh_pos_demo/window.cpp

@ -0,0 +1,75 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.2 2006/12/10 22:17:18 ganovelli
cvs problem during frist committ. repeated
*/
#include <QtGui>
#include "glwidget.h"
#include "window.h"
#include "mesh_type.h"
Window::Window()
{
glWidget = new GLWidget;
fvButton = createButton("FlipV()",SLOT(flipV( )));
feButton = createButton("FlipE()",SLOT(flipE( )));
ffButton = createButton("FlipF()",SLOT(flipF( )));
neButton = createButton("NextE() {FlipE() + FlipF() }",SLOT(nextE( )));
nbButton = createButton("NextB() ",SLOT(nextB( )));
ldButton = createButton("Load TriMesh",SLOT(OpenFile( )));
vfButton = createButton("++()",SLOT(nextVfite()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(glWidget);
mainLayout->addWidget(fvButton);
mainLayout->addWidget(feButton);
mainLayout->addWidget(ffButton);
mainLayout->addWidget(neButton);
mainLayout->addWidget(nbButton);
mainLayout->addWidget(vfButton);
mainLayout->addWidget(ldButton);
setLayout(mainLayout);
glWidget->glWrap.m = &glWidget->mesh;
setWindowTitle(tr("TriMesh Pos Demo"));
}
QPushButton *Window::createButton(const char *text, const char *setterSlot)
{
QPushButton *button = new QPushButton( text,0);
button-> resize ( 50, 20 );
if(!connect(button, SIGNAL(clicked()), glWidget, setterSlot))
exit(0);
return button;
}

54
vcglib/apps/QT/trimesh_pos_demo/window.h

@ -0,0 +1,54 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.2 2006/12/10 22:17:18 ganovelli
cvs problem during frist committ. repeated
*/
#ifndef WINDOW_H_POS_DEMO
#define WINDOW_H_POS_DEMO
#include <QWidget>
#include <QPushButton>
class QSlider;
class GLWidget;
class Window : public QWidget
{
Q_OBJECT
public:
Window();
private:
QPushButton *createButton(const char *changedSignal, const char *setterSlot);
GLWidget *glWidget;
QPushButton * fvButton,*feButton,*ffButton,*neButton,*ldButton,*nbButton,*vfButton;
};
#endif

18
vcglib/apps/embree/CMakeLists.txt

@ -0,0 +1,18 @@
cmake_minimum_required (VERSION 3.13)
project (embree_sample)
set(SOURCES embree_sample.cpp)
FIND_PACKAGE(embree 4.3)
if(embree_FOUND)
add_executable(embree_sample ${SOURCES})
target_link_libraries(
embree_sample
PUBLIC
embree
vcglib)
endif()

151
vcglib/apps/embree/embree_sample.cpp

@ -0,0 +1,151 @@
/*
g++ ./apps/embree/embree_sample.cpp -o ./apps/embree/prova.o -I ./vcg -I ./ -I ./eigenlib -I /usr/local/include/embree4/ -I ./vcglib/ -I ./vcglib/eigenlib/ -I ./vcglib/wrap/ply/ -L /usr/local/lib/ -lembree4 -std=c++17 -fopenmp -O3
./apps/embree/prova.o ./apps/meshes/cube.off 64
or with cmake from embree folder
mkdir build
cd build
cmake ..
make
./embree_sample ../../meshes/bunny.off 64
*/
#include <iostream>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/create/platonic.h>
//import export
#include<wrap/io_trimesh/import.h>
#include<wrap/io_trimesh/export.h>
#include<wrap/io_trimesh/import_ply.h>
#include<wrap/io_trimesh/export_ply.h>
#include <wrap/io_trimesh/export_off.h>
#include <wrap/io_trimesh/import_off.h>
#include <time.h>
#include <vcg/math/gen_normal.h>
#include <vcg/complex/allocate.h>
//vcgLibForEmbree
#include<wrap/embree/EmbreeAdaptor.h>
class MyVertex; class MyEdge; class MyFace;
struct MyUsedTypes : public vcg::UsedTypes<vcg::Use<MyVertex> ::AsVertexType,
vcg::Use<MyEdge> ::AsEdgeType,
vcg::Use<MyFace> ::AsFaceType> {};
class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags, vcg::vertex::VFAdj, vcg::vertex::Qualityf, vcg::vertex::Color4b> {};
class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Color4b, vcg::face::Qualityf> {};
class MyEdge : public vcg::Edge<MyUsedTypes, vcg::edge::VertexRef, vcg::edge::BitFlags> {};
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > {};
using namespace vcg;
using namespace std;
int main( int argc, char **argv )
{
cout << "start" << endl;
MyMesh m;
int ret = tri::io::ImporterOFF<MyMesh>::Open(m, argv[1]);
if(ret!=tri::io::ImporterOFF<MyMesh>::NoError)
{
cout<<"Error reading file \n"<<endl;
exit(0);
}
char *endptr;
int nOfRays = 150; //strtof(argv[2], &endptr);
if (argc > 2) {
nOfRays = std::stoi(argv[2]);
}
MyMesh m2,m3,m4,m5,m6,m7;
vcg::tri::Append<MyMesh,MyMesh>::MeshCopy(m2,m);
vcg::tri::Append<MyMesh,MyMesh>::MeshCopy(m3,m);
vcg::tri::Append<MyMesh,MyMesh>::MeshCopy(m4, m);
vcg::tri::Append<MyMesh, MyMesh>::MeshCopy(m5, m);
vcg::tri::Append<MyMesh,MyMesh>::MeshCopy(m6,m);
vcg::tri::Append<MyMesh,MyMesh>::MeshCopy(m7,m);
EmbreeAdaptor<MyMesh> adaptor = EmbreeAdaptor<MyMesh>(m);
adaptor.computeAmbientOcclusion(m,nOfRays);
tri::UpdateQuality<MyMesh>::VertexFromFace(m);
tri::UpdateColor<MyMesh>::PerVertexQualityGray(m);
tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
tri::io::ExporterOFF<MyMesh>::Save(m,"testAO.off",tri::io::Mask::IOM_VERTCOLOR);
cout << "Done AO" << endl;
std::vector<Point3f> unifDirVec;
std::vector<Point3f> ndir;
GenNormal<float>::Fibonacci(nOfRays,unifDirVec);
Point3f dir(0, 1, 0);
for (int g = 0; g < nOfRays; g++) {
if (unifDirVec.at(g) >= dir) {
ndir.push_back(unifDirVec.at(g));
}
}
adaptor = EmbreeAdaptor<MyMesh>(m2);
adaptor.computeAmbientOcclusion(m2,ndir);
tri::UpdateQuality<MyMesh>::VertexFromFace(m2);
tri::UpdateColor<MyMesh>::PerVertexQualityGray(m2);
tri::io::ExporterOFF<MyMesh>::Save(m2,"testAODir.off",tri::io::Mask::IOM_VERTCOLOR);
cout << "Done AO Directioned" << endl;
EmbreeAdaptor<MyMesh> adaptor2 = EmbreeAdaptor<MyMesh>(m4);
adaptor2.computeSDF(m4,nOfRays,90);
tri::UpdateQuality<MyMesh>::VertexFromFace(m4);
tri::UpdateColor<MyMesh>::PerVertexQualityRamp(m4);
tri::io::ExporterOFF<MyMesh>::Save(m4,"testSDF.off",tri::io::Mask::IOM_VERTCOLOR);
cout << "Done SDF" << endl;
adaptor = EmbreeAdaptor<MyMesh>(m5);
adaptor.computeNormalAnalysis(m5, nOfRays, true);
tri::io::ExporterOFF<MyMesh>::Save(m5, "testNormal.off", tri::io::Mask::IOM_FACENORMAL);
//vector<Point3f> BentNormal = adaptor.AOBentNormal(m5,nOfRays);
cout << "Done NormalAnlysis" << endl;
adaptor = EmbreeAdaptor<MyMesh>(m6);
Point3f p(1, 0, 0);
adaptor.selectVisibleFaces(m6, p, true);
tri::io::ExporterOFF<MyMesh>::Save(m6, "testSelectS.off", tri::io::Mask::IOM_FACECOLOR);
cout << "done face selection" << endl;
std::vector<Point3f> origine;
origine.push_back(Point3f(.0f,10.0f,.0f));
origine.push_back(Point3f(.0f,10.0f,.0f));
origine.push_back(Point3f(.0f,10.0f,.0f));
origine.push_back(Point3f(.0f,10.0f,.0f));
std::vector<Point3f> direction;
direction.push_back(Point3f(.0f,1.0f,.0f));
direction.push_back(Point3f(.0f,1.0f,3.0f));
direction.push_back(Point3f(.0f,1.0f,6.0f));
direction.push_back(Point3f(.0f,1.0f,9.0f));
/*
If you want to test the visualize_ray_shoot add the ply to makefile
MyMesh m8;
adaptor.visualize_ray_shoot(m8, origine[0], direction, true);
int mask = vcg::tri::io::Mask::IOM_VERTCOORD;
mask |= vcg::tri::io::Mask::IOM_EDGEINDEX;
tri::io::ExporterPLY<MyMesh>::Save(m8, "EdgeTest.ply", mask);
*/
cout << "Done All" << endl;
return 0;
}

50
vcglib/apps/imguiViewer/CMakeLists.txt

@ -0,0 +1,50 @@
cmake_minimum_required(VERSION 3.1)
project(imguiViewer)
# Set the C++ standard to C++17
set(CMAKE_CXX_STANDARD 17)
if(WIN32)
message("Windows specific stuff")
elseif(APPLE)
message("Apple specific stuff")
add_compile_definitions(GL_SILENCE_DEPRECATION)
elseif(UNIX)
message("Linux specific stuff")
endif()
find_package(GLFW3 REQUIRED)
find_package(GLEW 2.0 REQUIRED)
find_package(EIGEN3 REQUIRED NO_MODULE)
set(IMGUI_DIR "../../../github/imgui" CACHE INTERNAL "Path to imgui")
set(VCGLIB_DIR "../.." CACHE INTERNAL "Path to vcglib")
set(EIGEN_DIR = "${VCGLIB_DIR}/eigenlib" CACHE INTERNAL "")
add_executable(${PROJECT_NAME} main.cpp
${VCGLIB_DIR}/wrap/gui/trackball.cpp
${VCGLIB_DIR}/wrap/gui/trackmode.cpp
${VCGLIB_DIR}/wrap/ply/plylib.cpp
${IMGUI_DIR}/imgui.cpp
${IMGUI_DIR}/imgui_demo.cpp
${IMGUI_DIR}/imgui_draw.cpp
${IMGUI_DIR}/imgui_tables.cpp
${IMGUI_DIR}/imgui_widgets.cpp
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
${IMGUI_DIR}/backends/imgui_impl_opengl2.cpp
FileBrowser/ImGuiFileBrowser.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE ${IMGUI_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${IMGUI_DIR}/backends)
target_include_directories(${PROJECT_NAME} PRIVATE ${GLEW_INCLUDE_DIRS})
target_include_directories(${PROJECT_NAME} PRIVATE ${VCGLIB_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${EIGEN_DIR})
target_link_directories(${PROJECT_NAME} PRIVATE ${GLEW_LIBRARY_DIRS})
target_link_directories(${PROJECT_NAME} PRIVATE ${GLFW3_LIBRARY_DIRS})
target_link_libraries(${PROJECT_NAME}
GLEW::GLEW
glfw
)

1160
vcglib/apps/imguiViewer/FileBrowser/Dirent/dirent.h

File diff suppressed because it is too large Load Diff

1255
vcglib/apps/imguiViewer/FileBrowser/ImGuiFileBrowser.cpp

File diff suppressed because it is too large Load Diff

122
vcglib/apps/imguiViewer/FileBrowser/ImGuiFileBrowser.h

@ -0,0 +1,122 @@
#ifndef IMGUIFILEBROWSER_H
#define IMGUIFILEBROWSER_H
#include <imgui.h>
#include <string>
#include <vector>
namespace imgui_addons
{
class ImGuiFileBrowser
{
public:
ImGuiFileBrowser();
~ImGuiFileBrowser();
enum class DialogMode
{
SELECT, //Select Directory Mode
OPEN, //Open File mode
SAVE //Save File mode.
};
/* Use this to show an open file dialog. The function takes label for the window,
* the size, a DialogMode enum value defining in which mode the dialog should operate and optionally the extensions that are valid for opening.
* Note that the select directory mode doesn't need any extensions.
*/
bool showFileDialog(const std::string& label, const DialogMode mode, const ImVec2& sz_xy = ImVec2(0,0), const std::string& valid_types = "*.*");
/* Store the opened/saved file name or dir name (incase of selectDirectoryDialog) and the absolute path to the selection
* Should only be accessed when above functions return true else may contain garbage.
*/
std::string selected_fn;
std::string selected_path;
std::string ext; // Store the saved file extension
private:
struct Info
{
Info(std::string name, bool is_hidden) : name(name), is_hidden(is_hidden)
{
}
std::string name;
bool is_hidden;
};
//Enum used as bit flags.
enum FilterMode
{
FilterMode_Files = 0x01,
FilterMode_Dirs = 0x02
};
//Helper Functions
static std::string wStringToString(const wchar_t* wchar_arr);
static bool alphaSortComparator(const Info& a, const Info& b);
ImVec2 getButtonSize(std::string button_text);
/* Helper Functions that render secondary modals
* and help in validating file extensions and for filtering, parsing top navigation bar.
*/
void setValidExtTypes(const std::string& valid_types_string);
bool validateFile();
void showErrorModal();
void showInvalidFileModal();
bool showReplaceFileModal();
void showHelpMarker(std::string desc);
void parsePathTabs(std::string str);
void filterFiles(int filter_mode);
/* Core Functions that render the 4 different regions making up
* a simple file dialog
*/
bool renderNavAndSearchBarRegion();
bool renderFileListRegion();
bool renderInputTextAndExtRegion();
bool renderButtonsAndCheckboxRegion();
bool renderInputComboBox();
void renderExtBox();
/* Core Functions that handle navigation and
* reading directories/files
*/
bool readDIR(std::string path);
bool onNavigationButtonClick(int idx);
bool onDirClick(int idx);
// Functions that reset state and/or clear file list when reading new directory
void clearFileList();
void closeDialog();
#if defined (WIN32) || defined (_WIN32) || defined (__WIN32)
bool loadWindowsDrives(); // Helper Function for Windows to load Drive Letters.
#endif
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
void initCurrentPath(); // Helper function for UNIX based system to load Absolute path using realpath
#endif
ImVec2 min_size, max_size, input_combobox_pos, input_combobox_sz;
DialogMode dialog_mode;
int filter_mode, col_items_limit, selected_idx, selected_ext_idx;
float col_width, ext_box_width;
bool show_hidden, show_inputbar_combobox, is_dir, is_appearing, filter_dirty, validate_file, show_all_valid_files;
char input_fn[256];
std::vector<std::string> valid_exts;
std::vector<std::string> current_dirlist;
std::vector<Info> subdirs;
std::vector<Info> subfiles;
std::string current_path, error_msg, error_title, invfile_modal_id, repfile_modal_id;
ImGuiTextFilter filter;
std::string valid_types;
std::vector<const Info*> filtered_dirs; // Note: We don't need to call delete. It's just for storing filtered items from subdirs and subfiles so we don't use PassFilter every frame.
std::vector<const Info*> filtered_files;
std::vector< std::reference_wrapper<std::string> > inputcb_filter_files;
};
}
#endif // IMGUIFILEBROWSER_H

363
vcglib/apps/imguiViewer/main.cpp

@ -0,0 +1,363 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl2.h"
#include <stdio.h>
#include "FileBrowser/ImGuiFileBrowser.h"
#include "triangle_mesh_type.h"
#include <wrap/gui/trackball.h>
#include <wrap/gl/trimesh.h>
// Interface variables
GLFWwindow* window;
vcg::GlTrimesh<MyTriMesh> glWrap;
vcg::Trackball trackball;
imgui_addons::ImGuiFileBrowser file_dialog;
std::ostringstream oss; // String stream used for the log
// Interface options
ImVec4 clear_color = ImVec4(0.33f, 0.33f, 0.33f, 1.00f);
ImVec4 mesh_color = ImVec4(0.79f, 0.9f, 0.87f, 1.00f);
float line_thick=1.f;
int selected_rend_mode = 5;
bool showMesh=true;
bool showTrackBall=true;
vcg::GLW::DrawMode DMode=vcg::GLW::DMSmooth;
std::string PathMesh="../../meshes/fertility_tri.off";
// Mesh data
MyTriMesh mesh;
void LoadMesh(std::string path)
{
oss<<"Loading "<<path.c_str()<<std::endl;
int ret = vcg::tri::io::Importer<MyTriMesh>::Open(mesh,path.c_str());
vcg::tri::UpdateBounding<MyTriMesh>::Box(mesh);
vcg::tri::UpdateNormal<MyTriMesh>::PerVertexNormalizedPerFaceNormalized(mesh);
if (ret==0)
oss<<"Loaded "<<mesh.fn<<" faces "<<mesh.vn<<" vertices"<<std::endl;
else
oss<<"Mesh not loaded"<<std::endl;
}
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
{
if(ImGui::GetIO().WantCaptureMouse) return;
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
float xscale, yscale;
glfwGetWindowContentScale(window, &xscale, &yscale);
xpos*=xscale;
ypos*=yscale;
ypos=(display_h)-ypos;
trackball.MouseMove((int)xpos,(int)ypos);
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if(ImGui::GetIO().WantCaptureMouse) return;
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
float xscale, yscale;
glfwGetWindowContentScale(window, &xscale, &yscale);
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
xpos*=xscale;
ypos*=yscale;
ypos=(display_h)-ypos;
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
trackball.MouseDown((int)xpos,(int)ypos,vcg::Trackball::BUTTON_LEFT);
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE)
trackball.MouseUp((int)xpos,(int)ypos,vcg::Trackball::BUTTON_LEFT);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
trackball.MouseWheel(yoffset/4);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_LEFT_SHIFT && action == GLFW_PRESS)
trackball.ButtonDown(vcg::Trackball::KEY_SHIFT);
if (key == GLFW_KEY_LEFT_SHIFT && action == GLFW_RELEASE)
trackball.ButtonUp(vcg::Trackball::KEY_SHIFT);
if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_PRESS)
trackball.ButtonDown(vcg::Trackball::KEY_CTRL);
if (key == GLFW_KEY_LEFT_CONTROL && action == GLFW_RELEASE)
trackball.ButtonUp(vcg::Trackball::KEY_CTRL);
if (key == GLFW_KEY_LEFT_ALT && action == GLFW_PRESS)
trackball.ButtonDown(vcg::Trackball::KEY_ALT);
if (key == GLFW_KEY_LEFT_ALT && action == GLFW_RELEASE)
trackball.ButtonUp(vcg::Trackball::KEY_ALT);
}
// Now inside any function
void showMainMenu()
{
bool open = false, save = false;
if(ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Open", NULL))
open = true;
if (ImGui::MenuItem("Quit", NULL))
exit(0);
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
//Remember the name to ImGui::OpenPopup() and showFileDialog() must be same...
if(open)
ImGui::OpenPopup("Open File");
if(file_dialog.showFileDialog("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(700, 310), ".obj,.ply,.off"))
{
LoadMesh(file_dialog.selected_path);
PathMesh= file_dialog.selected_path;
}
}
void InitGLFW_Window()
{
if (!glfwInit())
{
std::cout<<"Error Initializing GLFW"<<std::endl;
exit(0);
}
window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL2 example", NULL, NULL);
if (window == NULL)
{
std::cout<<"Error Initializing GLFW Window"<<std::endl;
exit(0);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync
// Setup window
glfwSetErrorCallback(glfw_error_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetKeyCallback(window, key_callback);
}
void InitIMGui()
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// Setup Dear ImGui style
// ImGui::StyleColorsClassic();
ImGui::StyleColorsDark();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL2_Init();
}
void SetRenderBar()
{
ImGui::Begin("Simple VCG Mesh Visualizer",NULL,ImGuiWindowFlags_AlwaysAutoResize); // Create a window called "Hello, world!" and append into it.
ImGui::Checkbox("Show Mesh", &showMesh);
ImGui::SameLine();
ImGui::Checkbox("Show TBall", &showTrackBall);
ImGui::ColorEdit3("mesh color", (float*)&mesh_color); // Edit 3 floats representing a color
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
const char* items[] = { "Box", "Points", "DMWire",
"Hidden", "Flat", "Smooth",
"FlatWire","Radar"
};
if (ImGui::BeginCombo("Rendering", items[selected_rend_mode]))
{
for (int i = 0; i < IM_ARRAYSIZE(items); i++)
{
bool is_selected = (selected_rend_mode == i);
if (ImGui::Selectable(items[i], is_selected))
{
selected_rend_mode = i;
switch(selected_rend_mode)
{
case 0 : DMode=vcg::GLW::DMBox; break;
case 1 : DMode=vcg::GLW::DMPoints; break;
case 2 : DMode=vcg::GLW::DMWire; break;
case 3 : DMode=vcg::GLW::DMHidden; break;
case 4 : DMode=vcg::GLW::DMFlat; break;
case 5 : DMode=vcg::GLW::DMSmooth; break;
case 6 : DMode=vcg::GLW::DMFlatWire; break;
default : DMode=vcg::GLW::DMFlatWire;
}
}
if (is_selected)
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
ImGui::SliderFloat("thickness", &line_thick, 0.5f, 20.0f);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::End();
}
void SetLogWindow()
{
ImGui::Begin("Log",NULL,ImGuiWindowFlags_AlwaysAutoResize);
std::string LogPrint= oss.str();
ImGui::Text("%s",LogPrint.c_str());
ImGui::End();
}
void SetUserBar()
{
ImGui::Begin("User",NULL,ImGuiWindowFlags_AlwaysAutoResize);
if(ImGui::Button("Reload Mesh"))
{
LoadMesh(PathMesh);
oss<<"Reloaded mesh";
}
if(ImGui::Button("Smooth Mesh"))
{
vcg::tri::Smooth<MyTriMesh>::VertexCoordLaplacian(mesh, 1, false);
vcg::tri::UpdateNormal<MyTriMesh>::PerVertexNormalizedPerFaceNormalized(mesh);
oss<<"Smoothed mesh";
}
ImGui::End();
}
void GLDrawMesh()
{
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, (GLdouble)display_w/(GLdouble)display_h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,4.f, 0,0,0, 0,1,0);
trackball.GetView();
trackball.Apply();
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
// save modelview matrix
glPushMatrix();
vcg::glScale(2.0f/mesh.bbox.Diag());
vcg::glTranslate(-mesh.bbox.Center());
if (showMesh)
{
glColor4f(mesh_color.x * mesh_color.w, mesh_color.y * mesh_color.w, mesh_color.z * mesh_color.w, mesh_color.w);
glPushAttrib(GL_ALL_ATTRIB_BITS);
glLineWidth(line_thick);
glWrap.SetHintParamf(vcg::GLW::HNPPointSize,line_thick);
glWrap.Draw(DMode,vcg::GLW::CMNone,vcg::GLW::TMNone);
glPopAttrib();
}
glPopMatrix();
if (showTrackBall) trackball.DrawPostApply();
}
int main(int, char**)
{
LoadMesh(PathMesh);
glWrap.m=&mesh;
InitGLFW_Window();
InitIMGui();
glewInit();
// Main loop
while (!glfwWindowShouldClose(window))
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
{
SetRenderBar();
SetLogWindow();
SetUserBar();
showMainMenu();
}
// Rendering
ImGui::Render();
GLDrawMesh();
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
glfwMakeContextCurrent(window);
glfwSwapBuffers(window);
}
// Cleanup
ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

48
vcglib/apps/imguiViewer/triangle_mesh_type.h

@ -0,0 +1,48 @@
#ifndef MY_TRI_MESH_TYPE
#define MY_TRI_MESH_TYPE
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/smooth.h>
#include <wrap/io_trimesh/import.h>
#include <wrap/gl/trimesh.h>
class MyTriFace;
class MyTriEdge;
class MyTriVertex;
struct TriUsedTypes : public vcg::UsedTypes<vcg::Use<MyTriVertex>::AsVertexType,
vcg::Use<MyTriEdge>::AsEdgeType,
vcg::Use<MyTriFace>::AsFaceType>
{
};
class MyTriVertex : public vcg::Vertex<TriUsedTypes,
vcg::vertex::Coord3f,
vcg::vertex::Normal3f,
vcg::vertex::BitFlags>
{
};
class MyTriEdge : public vcg::Edge<
TriUsedTypes,
vcg::edge::VertexRef,
vcg::edge::BitFlags>
{
};
class MyTriFace : public vcg::Face<TriUsedTypes,
vcg::face::VertexRef,
vcg::face::BitFlags,
vcg::face::Normal3f>
{
};
class MyTriMesh : public vcg::tri::TriMesh<std::vector<MyTriVertex>,
std::vector<MyTriEdge>,
std::vector<MyTriFace>>
{
};
#endif

18
vcglib/apps/meshes/Tetraascii.ply

@ -0,0 +1,18 @@
ply
format ascii 1.0
comment VCGLIB generated
element vertex 4
property float x
property float y
property float z
element face 4
property list uchar int vertex_indices
end_header
1 1 1
-1 1 -1
-1 -1 1
1 -1 -1
3 0 1 2
3 0 2 3
3 0 3 1
3 3 2 1

55729
vcglib/apps/meshes/abominevole.off

File diff suppressed because it is too large Load Diff

BIN
vcglib/apps/meshes/bunny10k_textured.ply

Binary file not shown.

9667
vcglib/apps/meshes/conrod.off

File diff suppressed because it is too large Load Diff

6710
vcglib/apps/meshes/fertility_quad.off

File diff suppressed because it is too large Load Diff

14996
vcglib/apps/meshes/fertility_tri.off

File diff suppressed because it is too large Load Diff

16
vcglib/apps/meshes/quad.ply

@ -0,0 +1,16 @@
ply
format ascii 1.0
comment VCGLIB generated
element vertex 4
property float x
property float y
property float z
element face 2
property list uchar int vertex_indices
end_header
-1 -1 0
1 -1 0
1 1 0
-1 1 0
3 0 1 2
3 0 2 3

19
vcglib/apps/meshes/quad4.ply

@ -0,0 +1,19 @@
ply
format ascii 1.0
comment VCGLIB generated
element vertex 5
property float x
property float y
property float z
element face 4
property list uchar int vertex_indices
end_header
-1 -1 0
1 -1 0
1 1 0
-1 1 0
0 0 0
3 0 1 4
3 1 2 4
3 2 3 4
3 3 0 4

22
vcglib/apps/meshes/quad5.ply

@ -0,0 +1,22 @@
ply
format ascii 1.0
comment VCGLIB generated
element vertex 6
property float x
property float y
property float z
element face 6
property list uchar int vertex_indices
end_header
-1 -1 0
1 -1 0
1 1 0
-1 1 0
-.1 -.1 0
.1 .1 0
3 0 1 4
3 1 4 5
3 1 2 5
3 2 3 5
3 3 4 5
3 3 0 4

866
vcglib/apps/meshes/torus.off

@ -0,0 +1,866 @@
OFF
288 576 0
4 0 0
3.866025 0 0.5
3.5 0 0.8660254
3 0 1
2.5 0 0.8660254
2.133975 0 0.5000001
2 0 -8.742278e-08
2.133975 0 -0.5000002
2.5 0 -0.8660254
3 0 -1
3.5 0 -0.8660254
3.866025 0 -0.4999998
3.863703 1.035276 0
3.734294 1.000601 0.5
3.38074 0.9058666 0.8660254
2.897778 0.7764571 1
2.414814 0.6470476 0.8660254
2.061261 0.5523133 0.5000001
1.931852 0.5176381 -8.742278e-08
2.061261 0.5523133 -0.5000002
2.414814 0.6470476 -0.8660254
2.897778 0.7764571 -1
3.38074 0.9058666 -0.8660254
3.734294 1.000601 -0.4999998
3.464102 2 0
3.348076 1.933013 0.5
3.031089 1.75 0.8660254
2.598076 1.5 1
2.165063 1.25 0.8660254
1.848076 1.066987 0.5000001
1.732051 1 -8.742278e-08
1.848076 1.066987 -0.5000002
2.165063 1.25 -0.8660254
2.598076 1.5 -1
3.031089 1.75 -0.8660254
3.348076 1.933013 -0.4999998
2.828427 2.828427 0
2.733693 2.733693 0.5
2.474874 2.474874 0.8660254
2.12132 2.12132 1
1.767767 1.767767 0.8660254
1.508948 1.508948 0.5000001
1.414214 1.414214 -8.742278e-08
1.508948 1.508948 -0.5000002
1.767767 1.767767 -0.8660254
2.12132 2.12132 -1
2.474874 2.474874 -0.8660254
2.733693 2.733693 -0.4999998
2 3.464102 0
1.933013 3.348076 0.5
1.75 3.031089 0.8660254
1.5 2.598076 1
1.25 2.165064 0.8660254
1.066987 1.848076 0.5000001
0.9999999 1.732051 -8.742278e-08
1.066987 1.848076 -0.5000002
1.25 2.165064 -0.8660254
1.5 2.598076 -1
1.75 3.031089 -0.8660254
1.933013 3.348076 -0.4999998
1.035276 3.863703 0
1.000601 3.734294 0.5
0.9058667 3.38074 0.8660254
0.7764572 2.897778 1
0.6470477 2.414814 0.8660254
0.5523133 2.061261 0.5000001
0.5176381 1.931852 -8.742278e-08
0.5523134 2.061261 -0.5000002
0.6470477 2.414814 -0.8660254
0.7764572 2.897778 -1
0.9058667 3.38074 -0.8660254
1.000601 3.734294 -0.4999998
-1.748456e-07 4 0
-1.689893e-07 3.866025 0.5
-1.529899e-07 3.5 0.8660254
-1.311342e-07 3 0.9999999
-1.092785e-07 2.5 0.8660253
-9.327899e-08 2.133975 0.5
-8.742278e-08 2 -8.742277e-08
-9.3279e-08 2.133975 -0.5000001
-1.092785e-07 2.5 -0.8660254
-1.311342e-07 3 -0.9999999
-1.529899e-07 3.5 -0.8660254
-1.689893e-07 3.866025 -0.4999997
-1.035277 3.863703 0
-1.000601 3.734294 0.5
-0.9058671 3.38074 0.8660254
-0.7764575 2.897778 0.9999999
-0.6470479 2.414814 0.8660253
-0.5523135 2.061261 0.5
-0.5176383 1.931852 -8.742277e-08
-0.5523136 2.061261 -0.5000001
-0.6470479 2.414814 -0.8660254
-0.7764575 2.897778 -0.9999999
-0.9058671 3.38074 -0.8660254
-1.000601 3.734294 -0.4999997
-2 3.464102 0
-1.933013 3.348076 0.5
-1.75 3.031089 0.8660254
-1.5 2.598076 0.9999999
-1.25 2.165063 0.8660253
-1.066987 1.848076 0.5
-1 1.732051 -8.742277e-08
-1.066988 1.848076 -0.5000001
-1.25 2.165063 -0.8660254
-1.5 2.598076 -0.9999999
-1.75 3.031089 -0.8660254
-1.933013 3.348076 -0.4999997
-2.828427 2.828427 0
-2.733693 2.733693 0.5
-2.474874 2.474874 0.8660254
-2.12132 2.12132 1
-1.767767 1.767767 0.8660254
-1.508948 1.508948 0.5000001
-1.414214 1.414214 -8.742278e-08
-1.508948 1.508948 -0.5000002
-1.767767 1.767767 -0.8660254
-2.12132 2.12132 -1
-2.474874 2.474874 -0.8660254
-2.733693 2.733693 -0.4999998
-3.464102 2 0
-3.348076 1.933013 0.5
-3.031089 1.75 0.8660254
-2.598076 1.5 1
-2.165063 1.25 0.8660254
-1.848076 1.066987 0.5000001
-1.732051 1 -8.742278e-08
-1.848076 1.066988 -0.5000002
-2.165063 1.25 -0.8660254
-2.598076 1.5 -1
-3.031089 1.75 -0.8660254
-3.348076 1.933013 -0.4999998
-3.863703 1.035276 0
-3.734294 1.000601 0.5
-3.380741 0.9058663 0.8660254
-2.897778 0.7764568 1
-2.414815 0.6470473 0.8660254
-2.061261 0.552313 0.5000001
-1.931852 0.5176378 -8.742278e-08
-2.061261 0.5523131 -0.5000002
-2.414815 0.6470473 -0.8660254
-2.897778 0.7764568 -1
-3.380741 0.9058663 -0.8660254
-3.734294 1.000601 -0.4999998
-4 -3.496911e-07 0
-3.866025 -3.379787e-07 0.5
-3.5 -3.059797e-07 0.8660254
-3 -2.622683e-07 1
-2.5 -2.185569e-07 0.8660254
-2.133975 -1.86558e-07 0.5000001
-2 -1.748456e-07 -8.742278e-08
-2.133975 -1.86558e-07 -0.5000002
-2.5 -2.185569e-07 -0.8660254
-3 -2.622683e-07 -1
-3.5 -3.059797e-07 -0.8660254
-3.866025 -3.379787e-07 -0.4999998
-3.863703 -1.035276 0
-3.734294 -1.000601 0.5
-3.38074 -0.9058667 0.8660254
-2.897778 -0.7764572 1
-2.414814 -0.6470477 0.8660254
-2.061261 -0.5523133 0.5000001
-1.931852 -0.5176381 -8.742278e-08
-2.061261 -0.5523134 -0.5000002
-2.414814 -0.6470477 -0.8660254
-2.897778 -0.7764572 -1
-3.38074 -0.9058667 -0.8660254
-3.734294 -1.000601 -0.4999998
-3.464101 -2.000001 0
-3.348076 -1.933013 0.5
-3.031088 -1.750001 0.8660254
-2.598076 -1.5 0.9999999
-2.165063 -1.25 0.8660253
-1.848076 -1.066988 0.5
-1.732051 -1 -8.742277e-08
-1.848076 -1.066988 -0.5000001
-2.165063 -1.25 -0.8660254
-2.598076 -1.5 -0.9999999
-3.031088 -1.750001 -0.8660254
-3.348076 -1.933013 -0.4999997
-2.828427 -2.828428 0
-2.733692 -2.733693 0.5
-2.474873 -2.474874 0.8660254
-2.12132 -2.121321 0.9999999
-1.767767 -1.767767 0.8660253
-1.508948 -1.508948 0.5
-1.414213 -1.414214 -8.742277e-08
-1.508948 -1.508948 -0.5000001
-1.767767 -1.767767 -0.8660254
-2.12132 -2.121321 -0.9999999
-2.474873 -2.474874 -0.8660254
-2.733692 -2.733693 -0.4999997
-2 -3.464102 0
-1.933012 -3.348076 0.5
-1.75 -3.031089 0.8660254
-1.5 -2.598076 1
-1.25 -2.165064 0.8660254
-1.066987 -1.848076 0.5000001
-0.9999998 -1.732051 -8.742278e-08
-1.066987 -1.848076 -0.5000002
-1.25 -2.165064 -0.8660254
-1.5 -2.598076 -1
-1.75 -3.031089 -0.8660254
-1.933012 -3.348076 -0.4999998
-1.035276 -3.863703 0
-1.000601 -3.734294 0.5
-0.9058664 -3.380741 0.8660254
-0.776457 -2.897778 1
-0.6470475 -2.414815 0.8660254
-0.5523131 -2.061261 0.5000001
-0.517638 -1.931852 -8.742278e-08
-0.5523132 -2.061261 -0.5000002
-0.6470475 -2.414815 -0.8660254
-0.776457 -2.897778 -1
-0.9058664 -3.380741 -0.8660254
-1.000601 -3.734294 -0.4999998
4.769952e-08 -4 0
4.610189e-08 -3.866025 0.5
4.173708e-08 -3.5 0.8660254
3.577464e-08 -3 1
2.98122e-08 -2.5 0.8660254
2.544739e-08 -2.133975 0.5000001
2.384976e-08 -2 -8.742278e-08
2.54474e-08 -2.133975 -0.5000002
2.98122e-08 -2.5 -0.8660254
3.577464e-08 -3 -1
4.173708e-08 -3.5 -0.8660254
4.610189e-08 -3.866025 -0.4999998
1.035276 -3.863703 0
1.000601 -3.734294 0.5
0.9058666 -3.38074 0.8660254
0.7764571 -2.897778 1
0.6470475 -2.414814 0.8660254
0.5523132 -2.061261 0.5000001
0.517638 -1.931852 -8.742278e-08
0.5523133 -2.061261 -0.5000002
0.6470475 -2.414814 -0.8660254
0.7764571 -2.897778 -1
0.9058666 -3.38074 -0.8660254
1.000601 -3.734294 -0.4999998
2 -3.464102 0
1.933012 -3.348076 0.5
1.75 -3.031089 0.8660254
1.5 -2.598076 1
1.25 -2.165064 0.8660254
1.066987 -1.848076 0.5000001
0.9999998 -1.732051 -8.742278e-08
1.066987 -1.848076 -0.5000002
1.25 -2.165064 -0.8660254
1.5 -2.598076 -1
1.75 -3.031089 -0.8660254
1.933012 -3.348076 -0.4999998
2.828428 -2.828426 0
2.733694 -2.733692 0.5
2.474874 -2.474873 0.8660254
2.121321 -2.12132 1
1.767768 -1.767766 0.8660254
1.508948 -1.508947 0.5000001
1.414214 -1.414213 -8.742278e-08
1.508949 -1.508947 -0.5000002
1.767768 -1.767766 -0.8660254
2.121321 -2.12132 -1
2.474874 -2.474873 -0.8660254
2.733694 -2.733692 -0.4999998
3.464102 -1.999999 0
3.348077 -1.933012 0.5
3.03109 -1.749999 0.8660254
2.598077 -1.499999 1
2.165064 -1.249999 0.8660254
1.848076 -1.066987 0.5000001
1.732051 -0.9999995 -8.742278e-08
1.848077 -1.066987 -0.5000002
2.165064 -1.249999 -0.8660254
2.598077 -1.499999 -1
3.03109 -1.749999 -0.8660254
3.348077 -1.933012 -0.4999998
3.863703 -1.035275 0
3.734294 -1.0006 0.5
3.380741 -0.9058659 0.8660254
2.897778 -0.7764565 1
2.414815 -0.6470471 0.8660254
2.061261 -0.5523128 0.5000001
1.931852 -0.5176377 -8.742278e-08
2.061261 -0.5523129 -0.5000002
2.414815 -0.6470471 -0.8660254
2.897778 -0.7764565 -1
3.380741 -0.9058659 -0.8660254
3.734294 -1.0006 -0.4999998
3 13 1 0
3 0 12 13
3 14 2 1
3 1 13 14
3 15 3 2
3 2 14 15
3 16 4 3
3 3 15 16
3 17 5 4
3 4 16 17
3 18 6 5
3 5 17 18
3 19 7 6
3 6 18 19
3 20 8 7
3 7 19 20
3 21 9 8
3 8 20 21
3 22 10 9
3 9 21 22
3 23 11 10
3 10 22 23
3 12 0 11
3 11 23 12
3 25 13 12
3 12 24 25
3 26 14 13
3 13 25 26
3 27 15 14
3 14 26 27
3 28 16 15
3 15 27 28
3 29 17 16
3 16 28 29
3 30 18 17
3 17 29 30
3 31 19 18
3 18 30 31
3 32 20 19
3 19 31 32
3 33 21 20
3 20 32 33
3 34 22 21
3 21 33 34
3 35 23 22
3 22 34 35
3 24 12 23
3 23 35 24
3 37 25 24
3 24 36 37
3 38 26 25
3 25 37 38
3 39 27 26
3 26 38 39
3 40 28 27
3 27 39 40
3 41 29 28
3 28 40 41
3 42 30 29
3 29 41 42
3 43 31 30
3 30 42 43
3 44 32 31
3 31 43 44
3 45 33 32
3 32 44 45
3 46 34 33
3 33 45 46
3 47 35 34
3 34 46 47
3 36 24 35
3 35 47 36
3 49 37 36
3 36 48 49
3 50 38 37
3 37 49 50
3 51 39 38
3 38 50 51
3 52 40 39
3 39 51 52
3 53 41 40
3 40 52 53
3 54 42 41
3 41 53 54
3 55 43 42
3 42 54 55
3 56 44 43
3 43 55 56
3 57 45 44
3 44 56 57
3 58 46 45
3 45 57 58
3 59 47 46
3 46 58 59
3 48 36 47
3 47 59 48
3 61 49 48
3 48 60 61
3 62 50 49
3 49 61 62
3 63 51 50
3 50 62 63
3 64 52 51
3 51 63 64
3 65 53 52
3 52 64 65
3 66 54 53
3 53 65 66
3 67 55 54
3 54 66 67
3 68 56 55
3 55 67 68
3 69 57 56
3 56 68 69
3 70 58 57
3 57 69 70
3 71 59 58
3 58 70 71
3 60 48 59
3 59 71 60
3 73 61 60
3 60 72 73
3 74 62 61
3 61 73 74
3 75 63 62
3 62 74 75
3 76 64 63
3 63 75 76
3 77 65 64
3 64 76 77
3 78 66 65
3 65 77 78
3 79 67 66
3 66 78 79
3 80 68 67
3 67 79 80
3 81 69 68
3 68 80 81
3 82 70 69
3 69 81 82
3 83 71 70
3 70 82 83
3 72 60 71
3 71 83 72
3 85 73 72
3 72 84 85
3 86 74 73
3 73 85 86
3 87 75 74
3 74 86 87
3 88 76 75
3 75 87 88
3 89 77 76
3 76 88 89
3 90 78 77
3 77 89 90
3 91 79 78
3 78 90 91
3 92 80 79
3 79 91 92
3 93 81 80
3 80 92 93
3 94 82 81
3 81 93 94
3 95 83 82
3 82 94 95
3 84 72 83
3 83 95 84
3 97 85 84
3 84 96 97
3 98 86 85
3 85 97 98
3 99 87 86
3 86 98 99
3 100 88 87
3 87 99 100
3 101 89 88
3 88 100 101
3 102 90 89
3 89 101 102
3 103 91 90
3 90 102 103
3 104 92 91
3 91 103 104
3 105 93 92
3 92 104 105
3 106 94 93
3 93 105 106
3 107 95 94
3 94 106 107
3 96 84 95
3 95 107 96
3 109 97 96
3 96 108 109
3 110 98 97
3 97 109 110
3 111 99 98
3 98 110 111
3 112 100 99
3 99 111 112
3 113 101 100
3 100 112 113
3 114 102 101
3 101 113 114
3 115 103 102
3 102 114 115
3 116 104 103
3 103 115 116
3 117 105 104
3 104 116 117
3 118 106 105
3 105 117 118
3 119 107 106
3 106 118 119
3 108 96 107
3 107 119 108
3 121 109 108
3 108 120 121
3 122 110 109
3 109 121 122
3 123 111 110
3 110 122 123
3 124 112 111
3 111 123 124
3 125 113 112
3 112 124 125
3 126 114 113
3 113 125 126
3 127 115 114
3 114 126 127
3 128 116 115
3 115 127 128
3 129 117 116
3 116 128 129
3 130 118 117
3 117 129 130
3 131 119 118
3 118 130 131
3 120 108 119
3 119 131 120
3 133 121 120
3 120 132 133
3 134 122 121
3 121 133 134
3 135 123 122
3 122 134 135
3 136 124 123
3 123 135 136
3 137 125 124
3 124 136 137
3 138 126 125
3 125 137 138
3 139 127 126
3 126 138 139
3 140 128 127
3 127 139 140
3 141 129 128
3 128 140 141
3 142 130 129
3 129 141 142
3 143 131 130
3 130 142 143
3 132 120 131
3 131 143 132
3 145 133 132
3 132 144 145
3 146 134 133
3 133 145 146
3 147 135 134
3 134 146 147
3 148 136 135
3 135 147 148
3 149 137 136
3 136 148 149
3 150 138 137
3 137 149 150
3 151 139 138
3 138 150 151
3 152 140 139
3 139 151 152
3 153 141 140
3 140 152 153
3 154 142 141
3 141 153 154
3 155 143 142
3 142 154 155
3 144 132 143
3 143 155 144
3 157 145 144
3 144 156 157
3 158 146 145
3 145 157 158
3 159 147 146
3 146 158 159
3 160 148 147
3 147 159 160
3 161 149 148
3 148 160 161
3 162 150 149
3 149 161 162
3 163 151 150
3 150 162 163
3 164 152 151
3 151 163 164
3 165 153 152
3 152 164 165
3 166 154 153
3 153 165 166
3 167 155 154
3 154 166 167
3 156 144 155
3 155 167 156
3 169 157 156
3 156 168 169
3 170 158 157
3 157 169 170
3 171 159 158
3 158 170 171
3 172 160 159
3 159 171 172
3 173 161 160
3 160 172 173
3 174 162 161
3 161 173 174
3 175 163 162
3 162 174 175
3 176 164 163
3 163 175 176
3 177 165 164
3 164 176 177
3 178 166 165
3 165 177 178
3 179 167 166
3 166 178 179
3 168 156 167
3 167 179 168
3 181 169 168
3 168 180 181
3 182 170 169
3 169 181 182
3 183 171 170
3 170 182 183
3 184 172 171
3 171 183 184
3 185 173 172
3 172 184 185
3 186 174 173
3 173 185 186
3 187 175 174
3 174 186 187
3 188 176 175
3 175 187 188
3 189 177 176
3 176 188 189
3 190 178 177
3 177 189 190
3 191 179 178
3 178 190 191
3 180 168 179
3 179 191 180
3 193 181 180
3 180 192 193
3 194 182 181
3 181 193 194
3 195 183 182
3 182 194 195
3 196 184 183
3 183 195 196
3 197 185 184
3 184 196 197
3 198 186 185
3 185 197 198
3 199 187 186
3 186 198 199
3 200 188 187
3 187 199 200
3 201 189 188
3 188 200 201
3 202 190 189
3 189 201 202
3 203 191 190
3 190 202 203
3 192 180 191
3 191 203 192
3 205 193 192
3 192 204 205
3 206 194 193
3 193 205 206
3 207 195 194
3 194 206 207
3 208 196 195
3 195 207 208
3 209 197 196
3 196 208 209
3 210 198 197
3 197 209 210
3 211 199 198
3 198 210 211
3 212 200 199
3 199 211 212
3 213 201 200
3 200 212 213
3 214 202 201
3 201 213 214
3 215 203 202
3 202 214 215
3 204 192 203
3 203 215 204
3 217 205 204
3 204 216 217
3 218 206 205
3 205 217 218
3 219 207 206
3 206 218 219
3 220 208 207
3 207 219 220
3 221 209 208
3 208 220 221
3 222 210 209
3 209 221 222
3 223 211 210
3 210 222 223
3 224 212 211
3 211 223 224
3 225 213 212
3 212 224 225
3 226 214 213
3 213 225 226
3 227 215 214
3 214 226 227
3 216 204 215
3 215 227 216
3 229 217 216
3 216 228 229
3 230 218 217
3 217 229 230
3 231 219 218
3 218 230 231
3 232 220 219
3 219 231 232
3 233 221 220
3 220 232 233
3 234 222 221
3 221 233 234
3 235 223 222
3 222 234 235
3 236 224 223
3 223 235 236
3 237 225 224
3 224 236 237
3 238 226 225
3 225 237 238
3 239 227 226
3 226 238 239
3 228 216 227
3 227 239 228
3 241 229 228
3 228 240 241
3 242 230 229
3 229 241 242
3 243 231 230
3 230 242 243
3 244 232 231
3 231 243 244
3 245 233 232
3 232 244 245
3 246 234 233
3 233 245 246
3 247 235 234
3 234 246 247
3 248 236 235
3 235 247 248
3 249 237 236
3 236 248 249
3 250 238 237
3 237 249 250
3 251 239 238
3 238 250 251
3 240 228 239
3 239 251 240
3 253 241 240
3 240 252 253
3 254 242 241
3 241 253 254
3 255 243 242
3 242 254 255
3 256 244 243
3 243 255 256
3 257 245 244
3 244 256 257
3 258 246 245
3 245 257 258
3 259 247 246
3 246 258 259
3 260 248 247
3 247 259 260
3 261 249 248
3 248 260 261
3 262 250 249
3 249 261 262
3 263 251 250
3 250 262 263
3 252 240 251
3 251 263 252
3 265 253 252
3 252 264 265
3 266 254 253
3 253 265 266
3 267 255 254
3 254 266 267
3 268 256 255
3 255 267 268
3 269 257 256
3 256 268 269
3 270 258 257
3 257 269 270
3 271 259 258
3 258 270 271
3 272 260 259
3 259 271 272
3 273 261 260
3 260 272 273
3 274 262 261
3 261 273 274
3 275 263 262
3 262 274 275
3 264 252 263
3 263 275 264
3 277 265 264
3 264 276 277
3 278 266 265
3 265 277 278
3 279 267 266
3 266 278 279
3 280 268 267
3 267 279 280
3 281 269 268
3 268 280 281
3 282 270 269
3 269 281 282
3 283 271 270
3 270 282 283
3 284 272 271
3 271 283 284
3 285 273 272
3 272 284 285
3 286 274 273
3 273 285 286
3 287 275 274
3 274 286 287
3 276 264 275
3 275 287 276
3 1 277 276
3 276 0 1
3 2 278 277
3 277 1 2
3 3 279 278
3 278 2 3
3 4 280 279
3 279 3 4
3 5 281 280
3 280 4 5
3 6 282 281
3 281 5 6
3 7 283 282
3 282 6 7
3 8 284 283
3 283 7 8
3 9 285 284
3 284 8 9
3 10 286 285
3 285 9 10
3 11 287 286
3 286 10 11
3 0 276 287
3 287 11 0

17
vcglib/apps/metro/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project (metro)
if (VCG_HEADER_ONLY)
set(SOURCES
metro.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(metro
${SOURCES})
target_link_libraries(
metro
PUBLIC
vcglib
)

37
vcglib/apps/metro/history.txt

@ -0,0 +1,37 @@
VCGLib http://vcg.sf.net o o
Visual and Computer Graphics Library o o
_ O _
Copyright(C) 2005-2006 \/)\/
Visual Computing Lab http://vcg.isti.cnr.it /\/|
ISTI - Italian National Research Council |
\
Metro 4.07 2007/05/11
All rights reserved.
2007/05/11 Release 4.07
Added support for obj files.
Now the Distance comparison can be done exploiting also a (slow) octree.
Removed bug on the display of the area of the mesh.
2005/10/03 Release 4.06
Changed the core for distance computation.
Current version uses the lib flexible search structures.
Now the comparison can be done exploiting a static uniform grid,
a hashed grid or a hierarchy of AA box.
2005/04/04 Release 4.05
Added saving of Error Histogram
2005/01/26 Release 4.04
Gcc compiling issues
Moved to the library core the code for computing min distance froma a point to a mesh using a uniform grid.
Slightly faster.
2005/01/03 Release 4.03
Better ply compatibility, and improved error reporting
2004/11/29 Release 4.02
removed bug in printing Hausdorf distance,
removed bug in command line parsing,
upgraded import mesh library to support off format

318
vcglib/apps/metro/metro.cpp

@ -0,0 +1,318 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
// standard libraries
#include <time.h>
#include <vcg/math/histogram.h>
#include <vcg/complex/complex.h>
#include <wrap/io_trimesh/import.h>
#include <wrap/io_trimesh/export.h>
#include <vcg/simplex/face/component_ep.h>
#include <vcg/complex/algorithms/update/component_ep.h>
#include <vcg/complex/algorithms/update/bounding.h>
#include "sampling.h"
using namespace std;
// project definitions.
// error messages
#define MSG_ERR_MESH_LOAD "error loading the input meshes.\n"
#define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n"
#define MSG_ERR_FILE_OPEN "unable to open the output file.'n"
#define MSG_ERR_UNKNOWN_FORMAT "unknown file format '%s'.\n"
// global constants
#define NO_SAMPLES_PER_FACE 10
#define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1
#define BBOX_FACTOR 0.1
#define INFLATE_PERCENTAGE 0.02
#define MIN_SIZE 125 /* 125 = 5^3 */
#define N_HIST_BINS 256
#define PRINT_EVERY_N_ELEMENTS 1000
class CFace;
class CVertex;
struct UsedTypes:public vcg::UsedTypes< vcg::Use<CFace>::AsFaceType, vcg::Use<CVertex>::AsVertexType>{};
class CVertex : public vcg::Vertex<UsedTypes,vcg::vertex::Coord3d,vcg::vertex::Qualityf,vcg::vertex::Normal3d,vcg::vertex::Color4b,vcg::vertex::BitFlags> {};
class CFace : public vcg::Face< UsedTypes,vcg::face::VertexRef, vcg::face::Normal3d, vcg::face::EdgePlane,vcg::face::Color4b,vcg::face::Mark,vcg::face::BitFlags> {};
class CMesh : public vcg::tri::TriMesh< std::vector<CVertex>, std::vector<CFace> > {};
// -----------------------------------------------------------------------------------------------
using namespace vcg;
////////////////// Command line Flags and parameters
bool NumberOfSamples = false;
bool SamplesPerAreaUnit = false;
bool CleaningFlag=false;
// -----------------------------------------------------------------------------------------------
void Usage()
{
printf("\nUsage: "\
"metro file1 file2 [opt]\n"\
"Where opt can be:\n"\
" -v disable vertex sampling\n"\
" -e disable edge sampling\n"\
" -f disable face sampling\n"\
" -u ignore unreferred vertices\n"\
" -sx set the face sampling mode\n"\
" where x can be:\n"\
" -s0 montecarlo sampling\n"\
" -s1 subdivision sampling\n"\
" -s2 similar triangles sampling (Default)\n"\
" -n# set the required number of samples (overrides -A)\n"\
" -a# set the required number of samples per area unit (overrides -N)\n"\
" -c save a mesh with error as per-vertex colour and quality\n"\
" -C # # Set the min/max values used for color mapping\n"\
" -L Remove duplicated and unreferenced vertices before processing\n"\
" -h write files with histograms of error distribution\n"\
" -G Use a static Uniform Grid as Search Structure (default)\n"\
" -O Use an octree as a Search Structure\n"\
" -A Use an AxisAligned Bounding Box Tree as Search Structure\n"\
" -H Use an Hashed Uniform Grid as Search Structure\n"\
"\n"
"Default options are to sample vertexes, edge and faces by taking \n"
"a number of samples that is approx. 10x the face number.\n"
);
exit(-1);
}
// simple aux function that compute the name for the file containing the stored computations
std::string SaveFileName(const std::string &filename)
{
int pos=filename.find_last_of('.',filename.length());
std::string fileout=filename.substr(0,pos)+"_metro.ply";
return fileout;
}
// Open Mesh
void OpenMesh(const char *filename, CMesh &m)
{
int err = tri::io::Importer<CMesh>::Open(m,filename);
if(err) {
printf("Error in reading %s: '%s'\n",filename,tri::io::Importer<CMesh>::ErrorMsg(err));
if(tri::io::Importer<CMesh>::ErrorCritical(err)) exit(-1);
}
printf("read mesh `%s'\n", filename);
if(CleaningFlag){
int dup = tri::Clean<CMesh>::RemoveDuplicateVertex(m);
int unref = tri::Clean<CMesh>::RemoveUnreferencedVertex(m);
printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,filename);
}
}
int main(int argc, char**argv)
{
CMesh S1, S2;
float ColorMin=0, ColorMax=0;
double dist1_max, dist2_max;
unsigned long n_samples_target, elapsed_time;
double n_samples_per_area_unit;
int flags;
// print program info
printf("-------------------------------\n"
" Metro V.4.07 \n"
" http://vcg.isti.cnr.it\n"
" release date: " __DATE__ "\n"
"-------------------------------\n\n");
if(argc <= 2) Usage();
// default parameters
flags = SamplingFlags::VERTEX_SAMPLING |
SamplingFlags::EDGE_SAMPLING |
SamplingFlags::FACE_SAMPLING |
SamplingFlags::SIMILAR_SAMPLING;
// parse command line.
for(int i=3; i < argc;)
{
if(argv[i][0]=='-')
switch(argv[i][1])
{
case 'h' : flags |= SamplingFlags::HIST; break;
case 'v' : flags &= ~SamplingFlags::VERTEX_SAMPLING; break;
case 'e' : flags &= ~SamplingFlags::EDGE_SAMPLING; break;
case 'f' : flags &= ~SamplingFlags::FACE_SAMPLING; break;
case 'u' : flags |= SamplingFlags::INCLUDE_UNREFERENCED_VERTICES; break;
case 's' :
switch(argv[i][2])
{
case '0': flags = (flags | SamplingFlags::MONTECARLO_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
case '1': flags = (flags | SamplingFlags::SUBDIVISION_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
case '2': flags = (flags | SamplingFlags::SIMILAR_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
exit(0);
}
break;
case 'n': NumberOfSamples = true; n_samples_target = (unsigned long) atoi(&(argv[i][2])); break;
case 'a': SamplesPerAreaUnit = true; n_samples_per_area_unit = (unsigned long) atoi(&(argv[i][2])); break;
case 'c': flags |= SamplingFlags::SAVE_ERROR; break;
case 'L': CleaningFlag=true; break;
case 'C': ColorMin=float(atof(argv[i+1])); ColorMax=float(atof(argv[i+2])); i+=2; break;
case 'A': flags |= SamplingFlags::USE_AABB_TREE; printf("Using AABB Tree as search structure\n"); break;
case 'G': flags |= SamplingFlags::USE_STATIC_GRID; printf("Using static uniform grid as search structure\n"); break;
case 'H': flags |= SamplingFlags::USE_HASH_GRID; printf("Using hashed uniform grid as search structure\n"); break;
case 'O': flags |= SamplingFlags::USE_OCTREE; printf("Using octree as search structure\n"); break;
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
exit(0);
}
i++;
}
if(!(flags & SamplingFlags::USE_HASH_GRID) && !(flags & SamplingFlags::USE_AABB_TREE) && !(flags & SamplingFlags::USE_OCTREE))
flags |= SamplingFlags::USE_STATIC_GRID;
// load input meshes.
OpenMesh(argv[1],S1);
OpenMesh(argv[2],S2);
string S1NewName=SaveFileName(argv[1]);
string S2NewName=SaveFileName(argv[2]);
if(!NumberOfSamples && !SamplesPerAreaUnit)
{
NumberOfSamples = true;
n_samples_target = 10 * max(S1.fn,S2.fn);// take 10 samples per face
}
// compute face information
tri::UpdateComponentEP<CMesh>::Set(S1);
tri::UpdateComponentEP<CMesh>::Set(S2);
// set bounding boxes for S1 and S2
tri::UpdateBounding<CMesh>::Box(S1);
tri::UpdateBounding<CMesh>::Box(S2);
// set Bounding Box.
Box3<CMesh::ScalarType> bbox, tmp_bbox_M1=S1.bbox, tmp_bbox_M2=S2.bbox;
bbox.Add(S1.bbox);
bbox.Add(S2.bbox);
bbox.Offset(bbox.Diag()*0.02);
S1.bbox = bbox;
S2.bbox = bbox;
// initialize time info.
int t0=clock();
Sampling<CMesh> ForwardSampling(S1,S2);
Sampling<CMesh> BackwardSampling(S2,S1);
// print mesh info.
printf("Mesh info:\n");
printf(" M1: '%s'\n\tvertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[1], S1.vn, S1.fn, ForwardSampling.GetArea());
printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M1.min[0], tmp_bbox_M1.min[1], tmp_bbox_M1.min[2], tmp_bbox_M1.max[0], tmp_bbox_M1.max[1], tmp_bbox_M1.max[2]);
printf("\tbbox diagonal %f\n", (float)tmp_bbox_M1.Diag());
printf(" M2: '%s'\n\tvertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[2], S2.vn, S2.fn, BackwardSampling.GetArea());
printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M2.min[0], tmp_bbox_M2.min[1], tmp_bbox_M2.min[2], tmp_bbox_M2.max[0], tmp_bbox_M2.max[1], tmp_bbox_M2.max[2]);
printf("\tbbox diagonal %f\n", (float)tmp_bbox_M2.Diag());
// Forward distance.
printf("\nForward distance (M1 -> M2):\n");
ForwardSampling.SetFlags(flags);
if(NumberOfSamples)
{
ForwardSampling.SetSamplesTarget(n_samples_target);
n_samples_per_area_unit = ForwardSampling.GetNSamplesPerAreaUnit();
}
else
{
ForwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit);
n_samples_target = ForwardSampling.GetNSamplesTarget();
}
printf("target # samples : %lu\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
ForwardSampling.Hausdorff();
dist1_max = ForwardSampling.GetDistMax();
printf("\ndistances:\n max : %f (%f wrt bounding box diagonal)\n", (float)dist1_max, (float)dist1_max/bbox.Diag());
printf(" mean : %f\n", ForwardSampling.GetDistMean());
printf(" RMS : %f\n", ForwardSampling.GetDistRMS());
printf("# vertex samples %9lu\n", ForwardSampling.GetNVertexSamples());
printf("# edge samples %9lu\n", ForwardSampling.GetNEdgeSamples());
printf("# area samples %9lu\n", ForwardSampling.GetNAreaSamples());
printf("# total samples %9lu\n", ForwardSampling.GetNSamples());
printf("# samples per area unit: %f\n\n", ForwardSampling.GetNSamplesPerAreaUnit());
// Backward distance.
printf("\nBackward distance (M2 -> M1):\n");
BackwardSampling.SetFlags(flags);
if(NumberOfSamples)
{
BackwardSampling.SetSamplesTarget(n_samples_target);
n_samples_per_area_unit = BackwardSampling.GetNSamplesPerAreaUnit();
}
else
{
BackwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit);
n_samples_target = BackwardSampling.GetNSamplesTarget();
}
printf("target # samples : %lu\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
BackwardSampling.Hausdorff();
dist2_max = BackwardSampling.GetDistMax();
printf("\ndistances:\n max : %f (%f wrt bounding box diagonal)\n", (float)dist2_max, (float)dist2_max/bbox.Diag());
printf(" mean : %f\n", BackwardSampling.GetDistMean());
printf(" RMS : %f\n", BackwardSampling.GetDistRMS());
printf("# vertex samples %9lu\n", BackwardSampling.GetNVertexSamples());
printf("# edge samples %9lu\n", BackwardSampling.GetNEdgeSamples());
printf("# area samples %9lu\n", BackwardSampling.GetNAreaSamples());
printf("# total samples %9lu\n", BackwardSampling.GetNSamples());
printf("# samples per area unit: %f\n\n", BackwardSampling.GetNSamplesPerAreaUnit());
// compute time info.
elapsed_time = clock() - t0;
int n_total_sample=ForwardSampling.GetNSamples()+BackwardSampling.GetNSamples();
double mesh_dist_max = max(dist1_max , dist2_max);
printf("\nHausdorff distance: %f (%f wrt bounding box diagonal)\n",(float)mesh_dist_max,(float)mesh_dist_max/bbox.Diag());
printf(" Computation time : %d ms\n",(int)(1000.0*elapsed_time/CLOCKS_PER_SEC));
printf(" # samples/second : %f\n\n", (float)n_total_sample/((float)elapsed_time/CLOCKS_PER_SEC));
// save error files.
if(flags & SamplingFlags::SAVE_ERROR)
{
int saveMask = vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ;
//p.mask|=vcg::ply::PLYMask::PM_VERTCOLOR|vcg::ply::PLYMask::PM_VERTQUALITY;
if(ColorMax!=0 || ColorMin != 0){
vcg::tri::UpdateColor<CMesh>::PerVertexQualityRamp(S1,ColorMin,ColorMax);
vcg::tri::UpdateColor<CMesh>::PerVertexQualityRamp(S2,ColorMin,ColorMax);
}
tri::io::ExporterPLY<CMesh>::Save( S1,S1NewName.c_str(),saveMask);
tri::io::ExporterPLY<CMesh>::Save( S2,S2NewName.c_str(),saveMask);
}
// save error files.
if(flags & SamplingFlags::HIST)
{
ForwardSampling.GetHist().FileWrite("forward_result.csv");
BackwardSampling.GetHist().FileWrite("backward_result.csv");
}
return 0;
}
// -----------------------------------------------------------------------------------------------

10
vcglib/apps/metro/metro.pro

@ -0,0 +1,10 @@
TARGET = metro
DEPENDPATH += ../..
INCLUDEPATH += . ../.. ../../eigenlib
CONFIG += console stl c++11 debug_and_release
TEMPLATE = app
SOURCES += metro.cpp ../../wrap/ply/plylib.cpp
# Mac specific Config required to avoid to make application bundles
CONFIG -= app_bundle

96
vcglib/apps/metro/readme.txt

@ -0,0 +1,96 @@
VCGLib http://www.vcglib.net o o
Visual and Computer Graphics Library o o
_ O _
Copyright(C) 2005-2006 \/)\/
Visual Computing Lab http://vcg.isti.cnr.it /\/|
ISTI - Italian National Research Council |
\
Metro 4.07 2007/05/11
All rights reserved.
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 2 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 (http://www.gnu.org/licenses/gpl.txt)
for more details.
--- Synopsis ---
Metro is a tool designed to evaluate the difference between two triangular meshes.
Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation.
Please, when using this tool, cite the following reference:
P. Cignoni, C. Rocchini and R. Scopigno
"Metro: measuring error on simplified surfaces"
Computer Graphics Forum, Blackwell Publishers, vol. 17(2), June 1998, pp 167-174
For any question about this software please contact:
Paolo Cignoni ( paolo.cignoni@isti.cnr.it )
--- General Info ---
Metro is a tool designed to evaluate the difference between two triangular meshes.
Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation.
Three different surface sampling methods are implemented:
* Montecarlo sampling (pick k random samples in the interior of each face)
* Subdivision sampling (recursively subdivide each face along the longest edge and choose the sample in the center of each cell)
* Similar Triangles sampling (subdivide each face F in k polygons similar to F and sample the face in correspondence with the vertices of these polygons, internal to F)
Note that the three methods described above are used to sample only the interior of each face.
A different scheme is used to sample vertices and edges: vertices are sampled in the straightforward manner,
while edges are sampled by uniformly interleaving samples along each edge.
Three different Spatial indexing structures can be used to find the closest point to a sample, a Statically Allocated Uniform Grid, a Hashed Uniform Grid and a Hierarchy of axis aligned bounding boxes.
--- Basic usage ---
Metro is a command-line tool which allows the user to select among different sampling schemes.
A list of the command-line parameters accepted by the tool is shown in the following.
Usage: Metro file1 file2 [opts]
where "file1" and "file2" are the input meshes in PLY, OFF or STL format, and opts can be:
-v disable vertex sampling
-e disable edge sampling
-f disable face sampling
-u ignore unreferred vertices
-sx set the face sampling mode
where x can be:
-s0 montecarlo sampling
-s1 subdivision sampling
-s2 similar triangles sampling (Default)
-n# set the required number of samples (overrides -A)
-a# set the required number of samples per area unit (overrides -N)
-c save a mesh with error as per-vertex colour and quality
-C # # Set the min/max values used for color mapping
-L Remove duplicated and unreferenced vertices before processing
-h write files with histograms of error distribution
-G Use a static Uniform Grid as Search Structure (default)
-A Use an Axis Aligned Bounding Box Tree as Search Structure
-H Use an Hashed Uniform Grid as Search Structure
-O Use an Octree as Search Structure
The -C option is useful in combination with -c option for creating a set of
meshes with a coherent coloring scheme.
It sets how the errors are mapped into color according to the following formula,
let e be the error and ColorRamp be a R->RGB function mapping 0..1 values
into a smooth RedYellowGreenCyanBlue ramp:
e=Clamp(e,min,max);
VertexColor = ColorRamp( (e-min)/(max-min) );
The Histogram files saved by the -h option contains two column of numbers
e_i and p_i; p_i denotes the fraction of the surface having an error
between e_i and e_{i+1}. The sum of the second column values should give 1.

BIN
vcglib/apps/metro/sample/knot_max_simplified.STL

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_orig.ply

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_orig_metro.ply

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_subsampled.ply

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_subsampled_metro.ply

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_vcg_simplified.ply

Binary file not shown.

BIN
vcglib/apps/metro/sample/knot_vcg_simplified_metro.ply

Binary file not shown.

7
vcglib/apps/metro/sample/readme.txt

@ -0,0 +1,7 @@
This directory contains four 3d models that can be used to test metro. The models represent the same toroidal knot at two different level of details.
- knot_orig.ply 12800 vertexes, 25600 triangles: the original high resolution mesh
- knot_subsampled.ply 800 vertexes, 1600 triangles: a low res model obtained by simple uniform subsampling
- knot_vcg_simplified.ply 800 vertexes, 1600 triangles: a low res model obtained by our library simplification code
- knot_max_simplified.stl 800 vertexes, 1600 triangles: a low res model obtained by using a commercial tool

603
vcglib/apps/metro/sampling.h

@ -0,0 +1,603 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#ifndef __VCGLIB__SAMPLING
#define __VCGLIB__SAMPLING
#include <time.h>
#include <vcg/complex/algorithms/closest.h>
#include <vcg/space/box3.h>
#include <vcg/math/histogram.h>
#include <vcg/space/color4.h>
#include <vcg/simplex/face/distance.h>
#include <vcg/complex/algorithms/update/color.h>
#include <vcg/space/index/grid_static_ptr.h>
#include <vcg/space/index/aabb_binary_tree/aabb_binary_tree.h>
#include <vcg/space/index/octree.h>
#include <vcg/space/index/spatial_hashing.h>
namespace vcg
{
struct SamplingFlags{
enum{
HIST = 0x0001,
VERTEX_SAMPLING = 0x0002,
EDGE_SAMPLING = 0x0004,
FACE_SAMPLING = 0x0008,
MONTECARLO_SAMPLING = 0x0010,
SUBDIVISION_SAMPLING = 0x0020,
SIMILAR_SAMPLING = 0x0040,
NO_SAMPLING = 0x0070,
SAVE_ERROR = 0x0100,
INCLUDE_UNREFERENCED_VERTICES = 0x0200,
USE_STATIC_GRID = 0x0400,
USE_HASH_GRID = 0x0800,
USE_AABB_TREE = 0x1000,
USE_OCTREE = 0x2000
};
};
// -----------------------------------------------------------------------------------------------
template <class MetroMesh>
class Sampling
{
public:
private:
typedef typename MetroMesh::CoordType CoordType;
typedef typename MetroMesh::ScalarType ScalarType;
typedef typename MetroMesh::VertexType VertexType;
typedef typename MetroMesh::VertexPointer VertexPointer;
typedef typename MetroMesh::VertexIterator VertexIterator;
typedef typename MetroMesh::FaceIterator FaceIterator;
typedef typename MetroMesh::FaceType FaceType;
typedef typename MetroMesh::FaceContainer FaceContainer;
typedef GridStaticPtr <FaceType, typename MetroMesh::ScalarType > MetroMeshGrid;
typedef SpatialHashTable <FaceType, typename MetroMesh::ScalarType > MetroMeshHash;
typedef AABBBinaryTreeIndex <FaceType, typename MetroMesh::ScalarType, vcg::EmptyClass> MetroMeshAABB;
typedef Octree <FaceType, typename MetroMesh::ScalarType > MetroMeshOctree;
typedef Point3<typename MetroMesh::ScalarType> Point3x;
// data structures
MetroMesh &S1;
MetroMesh &S2;
MetroMeshGrid gS2;
MetroMeshHash hS2;
MetroMeshAABB tS2;
MetroMeshOctree oS2;
unsigned int n_samples_per_face ;
float n_samples_edge_to_face_ratio ;
float bbox_factor ;
float inflate_percentage ;
unsigned int min_size ;
int n_hist_bins ;
int print_every_n_elements ;
int referredBit ;
// parameters
double dist_upper_bound;
double n_samples_per_area_unit;
unsigned long n_samples_target;
int Flags;
// results
Histogram<double> hist;
unsigned long n_total_samples;
unsigned long n_total_area_samples;
unsigned long n_total_edge_samples;
unsigned long n_total_vertex_samples;
double max_dist;
double mean_dist;
double RMS_dist;
double volume;
double area_S1;
// globals
int n_samples;
// private methods
inline double ComputeMeshArea(MetroMesh & mesh);
float AddSample(const Point3x &p);
inline void AddRandomSample(FaceIterator &T);
inline void SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge);
void VertexSampling();
void EdgeSampling();
void FaceSubdiv(const Point3x & v0, const Point3x &v1, const Point3x & v2, int maxdepth);
void SimilarTriangles(const Point3x &v0, const Point3x &v1, const Point3x &v2, int n_samples_per_edge);
void MontecarloFaceSampling();
void SubdivFaceSampling();
void SimilarFaceSampling();
public :
// public methods
Sampling(MetroMesh &_s1, MetroMesh &_s2);
~Sampling();
void Hausdorff();
double GetArea() {return area_S1;}
double GetDistMax() {return max_dist;}
double GetDistMean() {return mean_dist;}
double GetDistRMS() {return RMS_dist;}
double GetDistVolume() {return volume;}
unsigned long GetNSamples() {return n_total_samples;}
unsigned long GetNAreaSamples() {return n_total_area_samples;}
unsigned long GetNEdgeSamples() {return n_total_edge_samples;}
unsigned long GetNVertexSamples() {return n_total_vertex_samples;}
double GetNSamplesPerAreaUnit() {return n_samples_per_area_unit;}
unsigned long GetNSamplesTarget() {return n_samples_target;}
Histogram<double> &GetHist() {return hist;}
void SetFlags(int flags) {Flags = flags;}
void ClearFlag(int flag) {Flags &= (flag ^ -1);}
void SetParam(double _n_samp) {n_samples_target = _n_samp;}
void SetSamplesTarget(unsigned long _n_samp);
void SetSamplesPerAreaUnit(double _n_samp);
};
// -----------------------------------------------------------------------------------------------
// constructor
template <class MetroMesh>
Sampling<MetroMesh>::Sampling(MetroMesh &_s1, MetroMesh &_s2):S1(_s1),S2(_s2)
{
Flags = 0;
area_S1 = ComputeMeshArea(_s1);
// set default numbers
n_samples_per_face = 10;
n_samples_edge_to_face_ratio = 0.1f;
bbox_factor = 0.1f;
inflate_percentage = 0.02f;
min_size = 125; /* 125 = 5^3 */
n_hist_bins = 256;
print_every_n_elements = S1.fn/100;
if(print_every_n_elements <= 1)
print_every_n_elements = 2;
referredBit = VertexType::NewBitFlag();
// store the unreferred vertices
FaceIterator fi; VertexIterator vi; int i;
for(fi = _s1.face.begin(); fi!= _s1.face.end(); ++fi)
for(i=0;i<3;++i) (*fi).V(i)->SetUserBit(referredBit);
}
template <class MetroMesh>
Sampling<MetroMesh>::~Sampling()
{
VertexType::DeleteBitFlag(referredBit);
}
// set sampling parameters
template <class MetroMesh>
void Sampling<MetroMesh>::SetSamplesTarget(unsigned long _n_samp)
{
n_samples_target = _n_samp;
n_samples_per_area_unit = n_samples_target / (double)area_S1;
}
template <class MetroMesh>
void Sampling<MetroMesh>::SetSamplesPerAreaUnit(double _n_samp)
{
n_samples_per_area_unit = _n_samp;
n_samples_target = (unsigned long)((double) n_samples_per_area_unit * area_S1);
}
// auxiliary functions
template <class MetroMesh>
inline double Sampling<MetroMesh>::ComputeMeshArea(MetroMesh & mesh)
{
FaceIterator face;
double area = 0.0;
for(face=mesh.face.begin(); face != mesh.face.end(); face++)
if(!(*face).IsD())
area += DoubleArea(*face);
return area/2.0;
}
template <class MetroMesh>
float Sampling<MetroMesh>::AddSample(const Point3x &p )
{
FaceType *f=0;
Point3x normf, bestq, ip;
ScalarType dist;
dist = dist_upper_bound;
// compute distance between p_i and the mesh S2
if(Flags & SamplingFlags::USE_AABB_TREE)
f=tri::GetClosestFaceEP<MetroMesh,MetroMeshAABB>(S2, tS2, p, dist_upper_bound, dist, normf, bestq, ip);
if(Flags & SamplingFlags::USE_HASH_GRID)
f=tri::GetClosestFaceEP<MetroMesh,MetroMeshHash>(S2, hS2, p, dist_upper_bound, dist, normf, bestq, ip);
if(Flags & SamplingFlags::USE_STATIC_GRID)
f=tri::GetClosestFaceEP<MetroMesh,MetroMeshGrid>(S2, gS2, p, dist_upper_bound, dist, normf, bestq, ip);
if (Flags & SamplingFlags::USE_OCTREE)
f=tri::GetClosestFaceEP<MetroMesh,MetroMeshOctree>(S2, oS2, p, dist_upper_bound, dist, normf, bestq, ip);
// update distance measures
if(dist == dist_upper_bound)
return -1.0;
if(dist > max_dist)
max_dist = dist; // L_inf
mean_dist += dist; // L_1
RMS_dist += dist*dist; // L_2
n_total_samples++;
if(Flags & SamplingFlags::HIST)
hist.Add((float)fabs(dist));
return (float)dist;
}
// -----------------------------------------------------------------------------------------------
// --- Vertex Sampling ---------------------------------------------------------------------------
template <class MetroMesh>
void Sampling<MetroMesh>::VertexSampling()
{
// Vertex sampling.
int cnt = 0;
float error;
printf("Vertex sampling\n");
VertexIterator vi;
typename std::vector<VertexPointer>::iterator vif;
for(vi=S1.vert.begin();vi!=S1.vert.end();++vi)
if( (*vi).IsUserBit(referredBit) || // it is referred
((Flags&SamplingFlags::INCLUDE_UNREFERENCED_VERTICES) != 0) ) //include also unreferred
{
error = AddSample((*vi).cP());
n_total_vertex_samples++;
// save vertex quality
if(Flags & SamplingFlags::SAVE_ERROR) (*vi).Q() = error;
// print progress information
if(!(++cnt % print_every_n_elements))
printf("Sampling vertices %d%%\r", (100 * cnt/S1.vn));
}
printf(" \r");
}
// -----------------------------------------------------------------------------------------------
// --- Edge Sampling -----------------------------------------------------------------------------
template <class MetroMesh>
inline void Sampling<MetroMesh>::SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge)
{
// uniform sampling of the segment v0v1.
Point3x e((v1-v0)/(double)(n_samples_per_edge+1));
int i;
for(i=1; i <= n_samples_per_edge; i++)
{
AddSample(v0 + e*i);
n_total_edge_samples++;
}
}
template <class MetroMesh>
void Sampling<MetroMesh>::EdgeSampling()
{
// Edge sampling.
typedef std::pair<VertexPointer, VertexPointer> pvv;
std::vector< pvv > Edges;
printf("Edge sampling\n");
// compute edge list.
FaceIterator fi;
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
for(int i=0; i<3; ++i)
{
Edges.push_back(std::make_pair((*fi).V0(i),(*fi).V1(i)));
if(Edges.back().first > Edges.back().second)
std::swap(Edges.back().first, Edges.back().second);
}
sort(Edges.begin(), Edges.end());
typename std::vector< pvv>::iterator edgeend = unique(Edges.begin(), Edges.end());
Edges.resize(edgeend-Edges.begin());
// sample edges.
typename std::vector<pvv>::iterator ei;
double n_samples_per_length_unit;
double n_samples_decimal = 0.0;
int cnt=0;
if(Flags & SamplingFlags::FACE_SAMPLING)
n_samples_per_length_unit = sqrt((double)n_samples_per_area_unit);
else
n_samples_per_length_unit = n_samples_per_area_unit;
for(ei=Edges.begin(); ei!=Edges.end(); ++ei)
{
n_samples_decimal += Distance((*ei).first->cP(),(*ei).second->cP()) * n_samples_per_length_unit;
n_samples = (int) n_samples_decimal;
SampleEdge((*ei).first->cP(), (*ei).second->cP(), (int) n_samples);
n_samples_decimal -= (double) n_samples;
// print progress information
if(!(++cnt % print_every_n_elements))
printf("Sampling edge %lu%%\r", (100 * cnt/Edges.size()));
}
printf(" \r");
}
// -----------------------------------------------------------------------------------------------
// --- Face Sampling -----------------------------------------------------------------------------
// Montecarlo sampling.
template <class MetroMesh>
inline void Sampling<MetroMesh>::AddRandomSample(FaceIterator &T)
{
// random sampling over the input face.
double rnd_1, rnd_2;
// vertices of the face T.
Point3x p0(T->V(0)->cP());
Point3x p1(T->V(1)->cP());
Point3x p2(T->V(2)->cP());
// calculate two edges of T.
Point3x v1(p1 - p0);
Point3x v2(p2 - p0);
// choose two random numbers.
rnd_1 = (double)rand() / (double)RAND_MAX;
rnd_2 = (double)rand() / (double)RAND_MAX;
if(rnd_1 + rnd_2 > 1.0)
{
rnd_1 = 1.0 - rnd_1;
rnd_2 = 1.0 - rnd_2;
}
// add a random point on the face T.
AddSample (p0 + (v1 * rnd_1 + v2 * rnd_2));
n_total_area_samples++;
}
template <class MetroMesh>
void Sampling<MetroMesh>::MontecarloFaceSampling()
{
// Montecarlo sampling.
double n_samples_decimal = 0.0;
FaceIterator fi;
srand(clock());
// printf("Montecarlo face sampling\n");
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
if(!(*fi).IsD())
{
// compute # samples in the current face.
n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit;
n_samples = (int) n_samples_decimal;
// for every sample p_i in T...
for(int i=0; i < n_samples; i++)
AddRandomSample(fi);
n_samples_decimal -= (double) n_samples;
// print progress information
// if(!(++cnt % print_every_n_elements))
// printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
}
// printf(" \r");
}
// Subdivision sampling.
template <class MetroMesh>
void Sampling<MetroMesh>::FaceSubdiv(const Point3x & v0, const Point3x & v1, const Point3x & v2, int maxdepth)
{
// recursive face subdivision.
if(maxdepth == 0)
{
// ground case.
AddSample((v0+v1+v2)/3.0f);
n_total_area_samples++;
n_samples++;
return;
}
// compute the longest edge.
double maxd01 = SquaredDistance(v0,v1);
double maxd12 = SquaredDistance(v1,v2);
double maxd20 = SquaredDistance(v2,v0);
int res;
if(maxd01 > maxd12)
if(maxd01 > maxd20) res = 0;
else res = 2;
else
if(maxd12 > maxd20) res = 1;
else res = 2;
// break the input triangle along the median to the the longest edge.
Point3x pp;
switch(res)
{
case 0 : pp = (v0+v1)/2;
FaceSubdiv(v0,pp,v2,maxdepth-1);
FaceSubdiv(pp,v1,v2,maxdepth-1);
break;
case 1 : pp = (v1+v2)/2;
FaceSubdiv(v0,v1,pp,maxdepth-1);
FaceSubdiv(v0,pp,v2,maxdepth-1);
break;
case 2 : pp = (v2+v0)/2;
FaceSubdiv(v0,v1,pp,maxdepth-1);
FaceSubdiv(pp,v1,v2,maxdepth-1);
break;
}
}
template <class MetroMesh>
void Sampling<MetroMesh>::SubdivFaceSampling()
{
// Subdivision sampling.
int cnt = 0, maxdepth;
double n_samples_decimal = 0.0;
typename MetroMesh::FaceIterator fi;
printf("Subdivision face sampling\n");
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
{
// compute # samples in the current face.
n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit;
n_samples = (int) n_samples_decimal;
if(n_samples)
{
// face sampling.
maxdepth = ((int)(log((double)n_samples)/log(2.0)));
n_samples = 0;
FaceSubdiv((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), maxdepth);
}
n_samples_decimal -= (double) n_samples;
// print progress information
if(!(++cnt % print_every_n_elements))
printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
}
printf(" \r");
}
// Similar Triangles sampling.
template <class MetroMesh>
void Sampling<MetroMesh>::SimilarTriangles(const Point3x & v0, const Point3x & v1, const Point3x & v2, int n_samples_per_edge)
{
Point3x V1((v1-v0)/(double)(n_samples_per_edge-1));
Point3x V2((v2-v0)/(double)(n_samples_per_edge-1));
int i, j;
// face sampling.
for(i=1; i < n_samples_per_edge-1; i++)
for(j=1; j < n_samples_per_edge-1-i; j++)
{
AddSample( v0 + (V1*(double)i + V2*(double)j) );
n_total_area_samples++;
n_samples++;
}
}
template <class MetroMesh>
void Sampling<MetroMesh>::SimilarFaceSampling()
{
// Similar Triangles sampling.
int cnt = 0, n_samples_per_edge;
double n_samples_decimal = 0.0;
FaceIterator fi;
printf("Similar Triangles face sampling\n");
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
{
// compute # samples in the current face.
n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit;
n_samples = (int) n_samples_decimal;
if(n_samples)
{
// face sampling.
n_samples_per_edge = (int)((sqrt(1.0+8.0*(double)n_samples) +5.0)/2.0);
n_samples = 0;
SimilarTriangles((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), n_samples_per_edge);
}
n_samples_decimal -= (double) n_samples;
// print progress information
if(!(++cnt % print_every_n_elements))
printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
}
printf(" \r");
}
// -----------------------------------------------------------------------------------------------
// --- Distance ----------------------------------------------------------------------------------
template <class MetroMesh>
void Sampling<MetroMesh>::Hausdorff()
{
Box3< ScalarType> bbox;
// set grid meshes.
if(Flags & SamplingFlags::USE_HASH_GRID) hS2.Set(S2.face.begin(),S2.face.end());
if(Flags & SamplingFlags::USE_AABB_TREE) tS2.Set(S2.face.begin(),S2.face.end());
if(Flags & SamplingFlags::USE_STATIC_GRID) gS2.Set(S2.face.begin(),S2.face.end());
if(Flags & SamplingFlags::USE_OCTREE) oS2.Set(S2.face.begin(),S2.face.end());
// set bounding box
bbox = S2.bbox;
dist_upper_bound = /*bbox_factor * */bbox.Diag();
if(Flags & SamplingFlags::HIST)
hist.SetRange(0.0, dist_upper_bound/100.0, n_hist_bins);
// initialize sampling statistics.
n_total_area_samples = n_total_edge_samples = n_total_vertex_samples = n_total_samples = n_samples = 0;
max_dist = -HUGE_VAL;
mean_dist = RMS_dist = 0;
// Vertex sampling.
if(Flags & SamplingFlags::VERTEX_SAMPLING)
VertexSampling();
// Edge sampling.
if(n_samples_target > n_total_samples)
{
n_samples_target -= (int) n_total_samples;
n_samples_per_area_unit = n_samples_target / area_S1;
if(Flags & SamplingFlags::EDGE_SAMPLING)
{
EdgeSampling();
if(n_samples_target > n_total_samples) n_samples_target -= (int) n_total_samples;
else n_samples_target=0;
}
// Face sampling.
if((Flags & SamplingFlags::FACE_SAMPLING) && (n_samples_target > 0))
{
n_samples_per_area_unit = n_samples_target / area_S1;
if(Flags & SamplingFlags::MONTECARLO_SAMPLING) MontecarloFaceSampling();
if(Flags & SamplingFlags::SUBDIVISION_SAMPLING) SubdivFaceSampling();
if(Flags & SamplingFlags::SIMILAR_SAMPLING) SimilarFaceSampling();
}
}
// compute vertex colour
if(Flags & SamplingFlags::SAVE_ERROR)
vcg::tri::UpdateColor<MetroMesh>::PerVertexQualityRamp(S1);
// compute statistics
n_samples_per_area_unit = (double) n_total_samples / area_S1;
volume = mean_dist / n_samples_per_area_unit / 2.0;
mean_dist /= n_total_samples;
RMS_dist = sqrt(RMS_dist / n_total_samples);
}
}
#endif

15
vcglib/apps/minimal_project/CMakeLists.txt

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.13)
project(trimesh_base)
add_subdirectory(vcglib)
set(CMAKE_CXX_STANDARD 14)
set(SOURCES
simple_main.cpp)
add_executable(simple_main
${SOURCES})
target_link_libraries(
simple_main
PUBLIC
vcglib
)

74
vcglib/apps/minimal_project/simple_main.cpp

@ -0,0 +1,74 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/*! \file trimesh_base.cpp
\ingroup code_sample
\brief the minimal example of using the lib
This file contain a minimal example of the library, showing how to load a mesh and how to compute per vertex normals on it.
*/
#include<vcg/complex/complex.h>
#include<wrap/io_trimesh/import_off.h>
class MyVertex; class MyEdge; class MyFace;
struct MyUsedTypes : public vcg::UsedTypes<vcg::Use<MyVertex> ::AsVertexType,
vcg::Use<MyEdge> ::AsEdgeType,
vcg::Use<MyFace> ::AsFaceType>{};
class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags >{};
class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VertexRef, vcg::face::BitFlags > {};
class MyEdge : public vcg::Edge< MyUsedTypes> {};
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> , std::vector<MyEdge> > {};
class MyVertex0 : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::BitFlags >{};
class MyVertex1 : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags >{};
class MyVertex2 : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Color4b, vcg::vertex::CurvatureDirf,
vcg::vertex::Qualityf, vcg::vertex::Normal3f, vcg::vertex::BitFlags >{};
int main( int argc, char **argv )
{
if(argc<2)
{
printf("Usage trimesh_base <meshfilename.off>\n");
return -1;
}
/*!
*/
MyMesh m;
if(vcg::tri::io::ImporterOFF<MyMesh>::Open(m,argv[1])!=vcg::tri::io::ImporterOFF<MyMesh>::NoError)
{
printf("Error reading file %s\n",argv[1]);
exit(0);
}
vcg::tri::RequirePerVertexNormal(m);
vcg::tri::UpdateNormal<MyMesh>::PerVertexNormalized(m);
printf("Input mesh vn:%i fn:%i\n",m.VN(),m.FN());
return 0;
}

10
vcglib/apps/plymc/plymc.pro

@ -0,0 +1,10 @@
TARGET = plymc
DEPENDPATH += .
INCLUDEPATH += ../..
CONFIG += console c++11
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += ../../wrap/ply/plylib.cpp \
plymc_main.cpp

223
vcglib/apps/plymc/plymc_main.cpp

@ -0,0 +1,223 @@
/*
* plymc_main.cpp
* filter_plymc
*
* Created by Paolo Cignoni on 10/23/09.
* Copyright 2009 ISTI - CNR. All rights reserved.
*
*/
#include <vcg/complex/algorithms/create/plymc/plymc.h>
#include "simplemeshprovider.h"
#define _PLYMC_VER "4.0"
using namespace std;
using namespace vcg;
string MYbasename = "plymcout";
string VolumeBaseName;
string subtag=""; // la stringa da appendere al nome di file per generare i nomi di file relativi a vari sottopezzi
string alnfile;
/************ Command Line Parameters *******/
int saveMask=vcg::tri::io::Mask::IOM_ALL;
void usage()
{
printf(
"\nUsage:\n"
" plymc [options] filein.ply [filein.ply...]\n"
" plymc [options] filein.aln \n"
"Options: (no leading space before numeric values!) \n"
" -oname Set the base output name (default plymcout, without 'ply' extension)\n"
" -vname Enable the saving of the final volume with the specified filename\n"
" -C## Set numbers mesh that can be cached (default: 6)\n"
" -c## Set numbers of k cells (default: 10000)\n"
" -V# Set the required voxel size (override -c)\n"
" -s... Compute only a subvolume (specify 6 integers) \n"
" -S... Compute all the subvolumes of a partition (specify 3 int) \n"
" -X... Compute a range of the the subvolumes of a partition (specify 9 int)\n"
" -M Apply a 'safe' simplification step that removes only the unecessary triangles\n"
" -w# Set distance field Expansion factor in voxel (default 3)\n"
" -W# Set distance field Exp. as an absolute dist (override -w)\n"
" -a# Set angle threshold for distance field expansion (default 30)\n"
" -f# Set the fill threshold (default 12: all voxel having less \n"
" than 12 adjacent are not automaticall filled)\n"
" -L# Set Number of smoothing passes to be done after merging of all meshes\n"
" -R# Set Number of Refill passes to be done after merging of all meshes\n"
" -l# Make a single smoothing step after each expansion\n"
" -G# Disable Geodesic Quality\n"
" -F# Use per vertex quality defined in plyfile (geodesic is disabled)\n"
" -O# Set an Offset (<0!) threshold and build a double surface\n"
" -q# Set Quality threshold for smoothing. Only whose distance (in voxel)\n"
" is lower than the specified one are smoothed (default 3 voxel)\n"
" -Q# Same of above but expressed in absolute units.\n"
" -p use vertex splatting instead face rasterizing\n"
" -d# set <n> as verbose level (default 0)\n"
" -D# save <n> debug slices during processing\n"
"\nNotes:\n\n"
"The Quality threshold can be expressed in voxel unit or in absolute units.\n"
"It represents the geodetic distance from the mesh border.\n"
"I.e. -q3 means that all voxels that are within 3voxel from the mesh border\n"
"are smoothed.\n\n"
"A partition in the working volume is defined using 3 integers, that \n"
"specify the subdivision along the three axis.\n"
"To automatically compute ALL subvolumes of a given subdivision use '-S' \n"
"-S 1 1 1 default no subdivision at all\n"
"-S 2 2 2 compute all the octant of a octree-like subdivision\n"
"-S 1 1 4 compute four Z-slices\n\n"
"To work only on a SINGLE subvolume of the partition you have to specify \n"
"six integers: the first three ints specify the subdivision along the\n"
"three axis and the last three ones which subvolume you desire.\n"
"the parameter to be used is '-s' \n"
"-s 1 1 1 0 0 0 default no subdivision at all\n"
"-s 1 1 3 0 0 1 make three Z-slices and take the middle one \n"
"-s 2 2 2 1 1 1 the last octant in a octree-like subdivision\n\n"
"To START FROM a specific subvolume of the partition you have to specify \n"
"six integers: the first three ints specify the subdivision along the\n"
"three axis and the last three ones which subvolume you want to start\n"
"the process will go on using lexicographic order. Subvolumes are ordered\n"
"by Z, then by Y, then by X\n"
"The parameter to be used is '-K' \n"
"-K 4 4 4 0 0 0 a partition of 64 blocks, starting from the first one\n"
"-K 4 4 4 1 0 3 a partition of 64 blocks, starting from block 19 (index 1 0 3)\n\n"
"To work only on a specific subvolume range of the partition you have \n"
"to specify nine integers: the first three ints specify the subdivision\n"
"along the three axis and, the next three which is the starting subvolume\n"
"and the last three which is the last subvolume to be computed.\n"
"the process will compute all blocks with x,y,z index included in the interval\n"
"specified: Xstart<=X<=Xend Ystart<=Y<=Yend Zstart<=Z<=Zend\n"
"-X 3 3 3 0 0 0 2 2 2 three subdivision on each axis, all subvolumes\n"
"-X 2 2 2 1 0 0 1 1 1 three subdivision on each axis, only the 'right' part\n\n"
);
exit(-1);
}
int main(int argc, char *argv[])
{
Histogram<float> h;
tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> > pmc;
tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> >::Parameter &p = pmc.p;
// This line is required to be sure that the decimal separatore is ALWAYS the . and not the ,
// see the comment at the beginning of the file
setlocale(LC_ALL, "En_US");
printf( "\n PlyMC " _PLYMC_VER " (" __DATE__ ")\n"
" Copyright 2002-2016 Visual Computing Group I.S.T.I. C.N.R.\n"
" Paolo Cignoni (p.cignoni@isti.cnr.it)\n\n");
//// Parameters
int i=1;
if(argc<2) usage();
while(argv[i][0]=='-')
{
switch(argv[i][1])
{
case 'o' : p.basename=argv[i]+2;printf("Setting Basename to %s\n",MYbasename.c_str());break;
case 'C' : pmc.MP.setCacheSize(atoi(argv[i]+2));printf("Setting MaxSize of MeshCache to %i\n",atoi(argv[i]+2)); break;
case 'c' : p.NCell =atoi(argv[i]+2);printf("Setting NCell to %i\n",p.NCell); break;
case 'v' : p.SaveVolumeFlag=true; VolumeBaseName=argv[i]+2; printf("Saving Volume enabled: volume Basename to %s\n",VolumeBaseName.c_str());break;
case 'V' : p.VoxSize =atof(argv[i]+2);printf("Setting VoxSize to %f; overridden NCell\n",p.VoxSize);p.NCell=0;break;
case 'w' : p.WideNum =atoi(argv[i]+2);printf("Setting WideNum to %i\n",p.WideNum);break;
case 'W' : p.WideSize=atof(argv[i]+2);printf("Setting WideSize to %f;overridden WideNum\n",p.WideSize);break;
case 'L' : p.SmoothNum =atoi(argv[i]+2);printf("Setting Laplacian SmoothNum to %i\n",p.SmoothNum);break;
case 'R' : p.RefillNum =atoi(argv[i]+2);printf("Setting Refilling Num to %i\n",p.RefillNum);break;
case 'q' : p.QualitySmoothVox=atof(argv[i]+2);printf("Setting QualitySmoothThr to %f; \n",p.QualitySmoothVox);break;
case 'Q' : p.QualitySmoothAbs=atof(argv[i]+2);printf("Setting QualitySmoothAbsolute to %f; it will override the default %f voxel value\n",p.QualitySmoothAbs,p.QualitySmoothVox);break;
case 'l' : p.IntraSmoothFlag=true; printf("Setting Laplacian Smooth after expansion \n");break;
case 'G' : p.GeodesicQualityFlag=false; printf("Disabling Geodesic Quality\n");break;
case 'F' : p.PLYFileQualityFlag=true; p.GeodesicQualityFlag=false; printf("Enabling PlyFile (and disabling Geodesic) Quality\n");break;
case 'f' : p.FillThr=atoi(argv[i]+2);printf("Setting Fill Threshold to %i\n",p.FillThr);break;
case 'a' : p.ExpAngleDeg=atoi(argv[i]+2);printf("Setting Expanding Angle Threshold to %f Degree\n",p.ExpAngleDeg);break;
case 'O' : p.OffsetThr=atof(argv[i]+2);printf("Setting Offset Threshold to %f \n",p.OffsetThr);p.OffsetFlag=true;break;
case 's' :
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]); p.IDiv[2]=atoi(argv[++i]);
p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]);
p.IPosE[0]=p.IPosS[0]; p.IPosE[1]=p.IPosS[1]; p.IPosE[2]=p.IPosS[2];
if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2]))
{
printf("the subvolume you have requested is invalid (out of bounds)");
exit(-1);
}
printf("Computing ONLY subvolume [%i,%i,%i] on a %ix%ix%i\n",p.IPosS[0],p.IPosS[1],p.IPosS[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]);
break;
case 'S' :
p.IDiv[0]=atoi(argv[++i]);p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
p.IPosS=Point3i(0,0,0);
p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1;
printf("Autocomputing ALL subvolumes on a %ix%ix%i\n",p.IDiv[0],p.IDiv[1],p.IDiv[2]);
break;
case 'K' :
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
p.IPosB[0]=atoi(argv[++i]);p.IPosB[1]=atoi(argv[++i]);p.IPosB[2]=atoi(argv[++i]);
p.IPosS=Point3i(0,0,0);
p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1;
if((p.IPosB[0]>=p.IDiv[0]) || (p.IPosB[1]>=p.IDiv[1]) || (p.IPosB[2]>=p.IDiv[2]))
{
printf("the start subvolume you have requested is invalid (out of bounds)");
exit(-1);
}
printf("Autocomputing ALL subvolumes FROM [%i,%i,%i] on a %ix%ix%i\n",p.IPosB[0],p.IPosB[1],p.IPosB[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]);
break;
case 'X' :
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]);
p.IPosE[0]=atoi(argv[++i]);p.IPosE[1]=atoi(argv[++i]);p.IPosE[2]=atoi(argv[++i]);
// test if the interval is ok
int Istart,Iend;
Istart = p.IPosS[2] + (p.IPosS[1]*p.IDiv[2]) + (p.IPosS[0]*p.IDiv[2]*p.IDiv[1]);
Iend = p.IPosE[2] + (p.IPosE[1]*p.IDiv[2]) + (p.IPosE[0]*p.IDiv[2]*p.IDiv[1]);
if((Iend-Istart)<=0)
{
printf("the range you have requested is invalid (reversed or empty)");
exit(-1);
}
if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2]) ||
(p.IPosE[0]>=p.IDiv[0]) || (p.IPosE[1]>=p.IDiv[1]) || (p.IPosE[2]>=p.IDiv[2]))
{
printf("the subvolume you have requested is invalid (out of bounds)");
exit(-1);
}
printf("Autocomputing subvolumes FROM [%i,%i,%i] TO [%i,%i,%i] on a %ix%ix%i\n",p.IPosS[0],p.IPosS[1],p.IPosS[2],p.IPosE[0],p.IPosE[1],p.IPosE[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]);
break;
// case 'B' : p.SafeBorder =atoi(argv[i]+2);printf("Setting SafeBorder among blocks to %i*%i (default 1)\n",p.SafeBorder,Volume<Voxelf>::BLOCKSIDE());break;
case 'p' : p.VertSplatFlag =true; printf("Enabling VertexSplatting instead of face rasterization\n");break;
case 'd' : p.VerboseLevel=atoi(argv[i]+2);printf("Enabling VerboseLevel= %i )\n",p.VerboseLevel);break;
case 'D' : p.VerboseLevel=1; p.SliceNum=atoi(argv[i]+2);printf("Enabling Debug Volume saving of %i slices (VerboseLevel=1)\n",p.SliceNum);break;
case 'M' : p.SimplificationFlag =true; printf("Enabling PostReconstruction simplification\n"); break;
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
}
++i;
}
Matrix44f Identity;
Identity.SetIdentity();
string alnfile;
while(i<argc)
{
if(strcmp(strrchr(argv[i],'.'),".aln")==0)
pmc.MP.openALN(argv[i]);
else
pmc.MP.AddSingleMesh(argv[i]);
++i;
}
if(pmc.MP.size()==0) usage();
printf("End Parsing\n\n");
pmc.Process();
return 0;
}

206
vcglib/apps/plymc/simplemeshprovider.h

@ -0,0 +1,206 @@
#ifndef SIMPLEMESHPROVIDER_H
#define SIMPLEMESHPROVIDER_H
#include <list>
#include <vector>
#include <vcg/space/box3.h>
#include <wrap/ply/plystuff.h>
#include <wrap/io_trimesh/import.h>
using namespace std;
using namespace vcg;
template<class TriMeshType>
class MeshCache
{
class Pair
{
public:
Pair(){used=0;}
TriMeshType *M;
std::string Name;
int used; // 'data' dell'ultimo accesso. si butta fuori quello lru
};
std::list<Pair> MV;
public:
void clear();
MeshCache() {MaxSize=6;}
~MeshCache() {
typename std::list<Pair>::iterator mi;
for(mi=MV.begin();mi!=MV.end();++mi)
delete (*mi).M;
}
// Restituisce true se la mesh e' in cache;
// restituisce in ogni caso il puntatore dove sta (o dovrebbe stare) la mesh
// Gestione LRU
bool Find(std::string &name, TriMeshType * &sm)
{
typename std::list<Pair>::iterator mi;
typename std::list<Pair>::iterator oldest; // quello che e' piu' tempo che non viene acceduto.
int last;
last = std::numeric_limits<int>::max();
oldest = MV.begin();
for(mi=MV.begin();mi!=MV.end();++mi)
{
if((*mi).used<last)
{
last=(*mi).used;
oldest=mi;
}
if((*mi).Name==name) {
sm=(*mi).M;
(*mi).used++;
return true;
}
}
// we have not found the requested mesh
// either allocate a new mesh or give back a previous mesh.
if(MV.size()>MaxSize) {
sm=(*oldest).M;
(*oldest).used=0;
(*oldest).Name=name;
} else {
MV.push_back(Pair());
MV.back().Name=name;
MV.back().M=new TriMeshType();
sm=MV.back().M;
}
return false;
}
size_t MaxSize;
size_t size() const {return MV.size();}
};
template<class TriMeshType>
class SimpleMeshProvider
{
std::vector< std::string > meshnames;
std::vector<vcg::Matrix44f> TrV;
std::vector<float> WV; // vettore con i pesi da applicare alla mesh.
std::vector<vcg::Box3f> BBV; // vettore con i bbox trasformati delle mesh da scannare.
vcg::Box3f fullBBox;
MeshCache<TriMeshType> MC;
public:
int size() {return meshnames.size();}
int getCacheSize() {return MC.MaxSize;}
int setCacheSize(size_t newsize)
{
if(newsize == MC.MaxSize)
return MC.MaxSize;
if(newsize <= 0)
return MC.MaxSize;
MC.MaxSize = newsize;
return newsize;
}
bool openALN (const char* alnName)
{
// vector<RangeMap> rmaps;
// ALNParser::ParseALN(rmaps, alnName);
// for(size_t i=0; i<rmaps.size(); i++)
// AddSingleMesh(rmaps[i].filename.c_str(), rmaps[i].transformation, rmaps[i].quality);
return true;
}
bool AddSingleMesh(const char* meshName, Matrix44f &tr, float meshWeight=1)
{
assert(WV.size()==meshnames.size() && TrV.size() == WV.size());
TrV.push_back(tr);
meshnames.push_back(meshName);
WV.push_back(meshWeight);
BBV.push_back(Box3f());
return true;
}
bool AddSingleMesh(const char* meshName)
{
Matrix44f identity; identity.SetIdentity();
return AddSingleMesh(meshName, identity);
}
vcg::Box3f bb(int i) {return BBV[i];}
vcg::Box3f fullBB(){ return fullBBox;}
vcg::Matrix44f Tr(int i) const {return TrV[i];}
std::string MeshName(int i) const {return meshnames[i];}
float W(int i) const {return WV[i];}
void Clear()
{
meshnames.clear();
TrV.clear();
WV.clear();
BBV.clear();
fullBBox.SetNull();
MC.clear();
}
bool Find(int i, TriMeshType * &sm)
{
return MC.Find(meshnames[i],sm);
}
bool InitBBox()
{
fullBBox.SetNull();
for(int i=0;i<int(meshnames.size());++i)
{
Box3d b;
bool ret;
Matrix44f mt;
Matrix44f Id; Id.SetIdentity();
mt.Import(TrV[i]);
printf("bbox scanning %4i/%i [%16s] \r",i+1,(int)meshnames.size(), meshnames[i].c_str());
if(tri::io::Importer<TriMeshType>::FileExtension(meshnames[i],"PLY") || tri::io::Importer<TriMeshType>::FileExtension(meshnames[i],"ply"))
{
if(!(TrV[i]==Id))
ret=ply::ScanBBox(meshnames[i].c_str(),BBV[i],mt,true,0);
else
ret=vcg::ply::ScanBBox(meshnames[i].c_str(),BBV[i]);
}
else
{ printf("Trying to import a non-ply file %s\n",meshnames[i].c_str());fflush(stdout);
TriMeshType m;
int retVal=tri::io::Importer<TriMeshType>::Open(m,meshnames[i].c_str());
ret = (retVal==0);
tri::UpdateBounding<TriMeshType>::Box(m);
BBV[i].Import(m.bbox);
}
if( ! ret)
{
printf("\n\nwarning:\n file '%s' not found\n",meshnames[i].c_str());fflush(stdout);
continue;
}
fullBBox.Add(BBV[i]);
}
return true;
}
};
class SVertex;
class SFace;
class SUsedTypes: public vcg::UsedTypes < vcg::Use<SVertex>::AsVertexType,
vcg::Use<SFace >::AsFaceType >{};
class SVertex : public Vertex< SUsedTypes, vertex::Coord3f, vertex::Normal3f,vertex::VFAdj, vertex::BitFlags, vertex::Color4b, vertex::Qualityf>{};
class SFace : public Face< SUsedTypes, face::VertexRef, face::Normal3f,face::Qualityf, face::VFAdj, face::BitFlags> {};
class SMesh : public vcg::tri::TriMesh< std::vector< SVertex>, std::vector< SFace > > {};
#endif // SIMPLEMESHPROVIDER_H

65
vcglib/apps/sample/CMakeLists.txt

@ -0,0 +1,65 @@
cmake_minimum_required(VERSION 3.13)
project(VCGExamples)
set(VCG_EXAMPLE_PROJECTS
aabb_binary_tree
colorspace
polygonmesh_base
polygonmesh_dual
polygonmesh_optimize
polygonmesh_polychord_collapse
polygonmesh_smooth
space_index_2d
space_packer
space_rasterized_packer
trimesh_align_pair
trimesh_allocate
trimesh_attribute
trimesh_attribute_ply
trimesh_ball_pivoting
trimesh_base
trimesh_closest
trimesh_clustering
trimesh_color
trimesh_copy
trimesh_create
trimesh_curvature
trimesh_cylinder_clipping
trimesh_disk_parametrization
trimesh_fitting
trimesh_geodesic
trimesh_geodesic_heat
trimesh_harmonic
trimesh_hole
trimesh_implicit_smooth
trimesh_indexing
trimesh_inertia
trimesh_intersection_plane
trimesh_intersection_mesh
trimesh_isosurface
trimesh_join
trimesh_kdtree
trimesh_montecarlo_sampling
trimesh_normal
trimesh_optional
trimesh_pointmatching
trimesh_pointcloud_sampling
trimesh_ray
trimesh_refine
trimesh_remeshing
trimesh_sampling
trimesh_select
trimesh_smooth
trimesh_split_vertex
trimesh_texture
trimesh_texture_clean
trimesh_topology
trimesh_topological_cut
trimesh_voronoi
trimesh_voronoiatlas
trimesh_voronoiclustering
trimesh_voronoisampling)
foreach(VCG_EXAMPLE ${VCG_EXAMPLE_PROJECTS})
add_subdirectory(${VCG_EXAMPLE})
endforeach()

14
vcglib/apps/sample/aabb_binary_tree/CMakeLists.txt

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.13)
project(aabb_binary_tree)
set(SOURCES
aabb_binary_tree.cpp)
add_executable(aabb_binary_tree
${SOURCES})
target_link_libraries(
aabb_binary_tree
PUBLIC
vcglib
)

148
vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.cpp

@ -0,0 +1,148 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <stdio.h>
#include<vcg/complex/complex.h>
#include<vcg/simplex/face/distance.h>
#include<vcg/simplex/face/component_ep.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/update/component_ep.h>
#include <vcg/complex/algorithms/update/flag.h>
#include <vcg/space/intersection3.h>
#include <vcg/space/index/aabb_binary_tree/aabb_binary_tree.h>
typedef float AScalarType;
using namespace vcg;
class AVertex;
class AFace;
struct MyUsedTypes : public vcg::UsedTypes< vcg::Use<AVertex> ::AsVertexType,
vcg::Use<AFace> ::AsFaceType>{};
class AVertex : public Vertex< MyUsedTypes, vertex::Normal3f, vertex::Coord3f,vertex::BitFlags >{};
class AFace : public Face< MyUsedTypes, face::VertexRef, face::Normal3f, face::EdgePlane, face::BitFlags> {};
class AMesh : public vcg::tri::TriMesh< std::vector<AVertex>, std::vector<AFace> > { };
typedef vcg::AABBBinaryTreeIndex<AFace, AScalarType, vcg::EmptyClass> AIndex;
static AMesh gMesh;
static AIndex gIndex;
static void CreateMesh(void) {
vcg::tri::Dodecahedron<AMesh>(gMesh);
vcg::tri::UpdateFlags<AMesh>::Clear(gMesh);
vcg::tri::UpdateNormal<AMesh>::PerVertexNormalized(gMesh);
vcg::tri::UpdateComponentEP<AMesh>::Set(gMesh);
}
static void SetIndex(void) {
gIndex.Set(gMesh.face.begin(), gMesh.face.end());
}
static void TestClosest(void) {
vcg::face::PointDistanceEPFunctor<AIndex::ScalarType> getPtDist;
const AIndex::CoordType queryPoint((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0);
const AIndex::ScalarType maxDist = std::numeric_limits<AIndex::ScalarType>::max();
AIndex::ObjPtr closestFace;
AIndex::ScalarType closestDist;
AIndex::CoordType closestPoint;
vcg::EmptyClass a;
closestFace = gIndex.GetClosest(getPtDist, a, queryPoint, maxDist, closestDist, closestPoint);
printf("GetClosest Test:\n");
if (closestFace != 0) {
printf("\tface : 0x%p\n", closestFace);
printf("\tdistance : %f\n", closestDist);
printf("\tpoint : [%f, %f, %f]\n", closestPoint[0], closestPoint[1], closestPoint[2]);
}
else {
printf("\tno object found (index is probably empty).\n");
}
}
static void TestKClosest(void) {
vcg::face::PointDistanceEPFunctor<AIndex::ScalarType> getPtDist;
const unsigned int k = 10;
const AIndex::CoordType queryPoint((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0);
const AIndex::ScalarType maxDist = std::numeric_limits<AIndex::ScalarType>::max();
std::vector<AIndex::ObjPtr> closestObjects;
std::vector<AIndex::ScalarType> closestDistances;
std::vector<AIndex::CoordType> closestPoints;
vcg::EmptyClass a;
unsigned int rk = gIndex.GetKClosest(getPtDist, a, k, queryPoint, maxDist, closestObjects, closestDistances, closestPoints);
printf("GetKClosest Test:\n");
printf("\tfound %d objects\n", rk);
}
static void TestRay(void) {
const bool TEST_BACK_FACES = true;
vcg::RayTriangleIntersectionFunctor<TEST_BACK_FACES> rayIntersector;
const AIndex::ScalarType maxDist = std::numeric_limits<AIndex::ScalarType>::max();
const AIndex::CoordType rayOrigin((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0);
const AIndex::CoordType rayDirection((AIndex::ScalarType)1, (AIndex::ScalarType)0, (AIndex::ScalarType)0);
const vcg::Ray3<AIndex::ScalarType, false> ray(rayOrigin, rayDirection);
AIndex::ObjPtr isectFace;
AIndex::ScalarType rayT;
AIndex::CoordType isectPt;
vcg::EmptyClass a;
isectFace = gIndex.DoRay(rayIntersector, a , ray, maxDist, rayT);
printf("DoRay Test:\n");
if (isectFace != 0) {
printf("\tface : 0x%p\n", isectFace);
printf("\tray t : %f\n", rayT);
}
else {
printf("\tno object found (index is probably empty).\n");
}
}
int main (int /*argc*/, char ** /*argv*/) {
CreateMesh();
SetIndex();
printf("Spatial Index Tests\n");
printf("---\n");
TestClosest();
printf("---\n");
TestKClosest();
printf("---\n");
TestRay();
printf("---\n");
return (0);
}

3
vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = aabb_binary_tree
SOURCES += aabb_binary_tree.cpp

14
vcglib/apps/sample/colorspace/CMakeLists.txt

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.13)
project(colorspace)
set(SOURCES
colorspace.cpp)
add_executable(colorspace
${SOURCES})
target_link_libraries(
colorspace
PUBLIC
vcglib
)

142
vcglib/apps/sample/colorspace/colorspace.cpp

@ -0,0 +1,142 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
// Standard headers
#include <iostream>
// VCG headers
#include <vcg/space/color4.h>
#include <vcg/space/colorspace.h>
using namespace std;
typedef vcg::ColorSpace<double> ColorSpace;
int main(int argc,char ** argv)
{
// Some Color Space processing examples
cout << endl;
if (argc != 4)
{
cout << " Usage: colorspace <r> <g> <b>" << endl << endl;
cout << " <r> <g> <b> : RGB triplet (0-255)" << endl << endl;
cout << " Note: The RGB triplet is assumed in the sRGB space (D65 illuminant).";
cout << endl << endl;
exit(-2);
}
double r = static_cast<double>(atof(argv[1]));
double g = static_cast<double>(atof(argv[2]));
double b = static_cast<double>(atof(argv[3]));
// RGB components have to be in the range [0.0, 1.0]
vcg::Color4<double> color(r/255.0, g/255.0, b/255.0, 0.0);
// RGB --> RGB (RGB space changing)
///////////////////////////////////////////////
cout << " * RGB --> RGB conversion" << endl << endl;
vcg::Color4<double> rgb = ColorSpace::RGBtoRGB(color, ColorSpace::SRGB, ColorSpace::PAL_RGB);
rgb *= 255.0;
cout << " RGB (PAL/SECAM): " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl;
rgb = ColorSpace::RGBtoRGB(color, ColorSpace::SRGB, ColorSpace::WIDE_GAMUT);
rgb *= 255.0;
cout << " RGB (Wide Gamut): " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl;
// RGB <--> HSL (Hue, Saturation, Lightness)
///////////////////////////////////////////////
cout << " * RGB <--> HSL conversion" << endl << endl;
vcg::Color4<double> hsl = ColorSpace::RGBtoHSL(color);
cout << " RGB --> HSL: " << hsl[0]*360.0 << "° " << hsl[1]*100.0 << "% " << hsl[2]*100.0 << "% " << endl;
rgb = ColorSpace::HSLtoRGB(hsl);
rgb *= 255.0;
cout << " HSL --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl;
// RGB <--> HSV (Hue, Saturation, Value)
///////////////////////////////////////////////
cout << " * RGB <--> HSV conversion" << endl << endl;
vcg::Color4<double> hsv = ColorSpace::RGBtoHSV(color);
cout << " RGB --> HSV: " << hsv[0]*360.0 << "° " << hsv[1]*100.0 << "% " << hsv[2]*100.0 << "% " << endl;
rgb = ColorSpace::HSVtoRGB(hsv);
rgb *= 255.0;
cout << " HSV --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl;
// RGB --> CIELab
///////////////////////////////////////////////
cout << " * RGB <--> Lab conversion" << endl << endl;
vcg::Color4<double> xyzD65 = ColorSpace::RGBtoXYZ(color, ColorSpace::SRGB, ColorSpace::VCG_ILLUMINANT_D65);
vcg::Color4<double> lab = ColorSpace::XYZtoCIELab(xyzD65, ColorSpace::refIlluminant(ColorSpace::SRGB));
cout << " RGB --> CIELab: " << lab[0] << " " << lab[1] << " " << lab[2] << endl;
vcg::Color4<double> xyz = ColorSpace::CIELabtoXYZ(lab, ColorSpace::refIlluminant(ColorSpace::SRGB));
rgb = ColorSpace::XYZtoRGB(xyz, ColorSpace::refIlluminant(ColorSpace::SRGB), ColorSpace::SRGB);
rgb *= 255.0;
cout << " CIELab --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl;
// RGB <--> XYZ
///////////////////////////////////////////////
cout << " * RGB <--> XYZ conversion" << endl << endl;
// RGB --> XYZ (D65)
cout << " RGB --> XYZ (D65): " << xyzD65[0] << " " << xyzD65[1] << " " << xyzD65[2] << endl;
// XYZ (D65) --> RGB
rgb = ColorSpace::XYZtoRGB(xyzD65, ColorSpace::VCG_ILLUMINANT_D65, ColorSpace::SRGB);
rgb *= 255.0;
cout << " XYZ (D65) --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl;
// RGB --> XYZ (D50)
vcg::Color4<double> xyzD50 = ColorSpace::RGBtoXYZ(color, ColorSpace::SRGB, ColorSpace::VCG_ILLUMINANT_D50);
cout << " RGB --> XYZ (D50): " << xyzD50[0] << " " << xyzD50[1] << " " << xyzD50[2] << endl;
// XYZ (D50) --> RGB
rgb = ColorSpace::XYZtoRGB(xyzD50, ColorSpace::VCG_ILLUMINANT_D50, ColorSpace::SRGB);
rgb *= 255.0;
cout << " XYZ (D50) --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl;
// Direct way
xyz = ColorSpace::chromaticAdaptation(xyzD65, ColorSpace::VCG_ILLUMINANT_D65, ColorSpace::VCG_ILLUMINANT_D50);
cout << " XYZ (D65 --> D50): " << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl << endl;
return 0;
}

3
vcglib/apps/sample/colorspace/colorspace.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = colorspace
SOURCES += colorspace.cpp

23
vcglib/apps/sample/common.pri

@ -0,0 +1,23 @@
DEPENDPATH += \
. \
../../..
INCLUDEPATH += \
. \
../../.. \
../../../eigenlib
CONFIG += c++11
TEMPLATE = app
# Mac specific Config required to avoid to make application bundles
CONFIG -= app_bundle
QMAKE_CXXFLAGS += -std=c++11
unix {
CONFIG(release, debug|release) {
DEFINES *= NDEBUG
}
}

94
vcglib/apps/sample/edgemesh_sampling/edgemesh_sampling.cpp

@ -0,0 +1,94 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include<vcg/complex/complex.h>
#include<wrap/io_trimesh/import_off.h>
#include<wrap/io_trimesh/export_off.h>
#include<wrap/io_trimesh/export_ply.h>
#include<vcg/complex/algorithms/point_sampling.h>
#include<vcg/complex/algorithms/create/platonic.h>
using namespace vcg;
using namespace std;
class MyEdge;
class MyFace;
class MyVertex;
struct MyUsedTypes : public UsedTypes< Use<MyVertex> ::AsVertexType,
Use<MyEdge> ::AsEdgeType,
Use<MyFace> ::AsFaceType>{};
class MyVertex : public Vertex<MyUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::VEAdj, vertex::BitFlags >{};
class MyFace : public Face< MyUsedTypes, face::FFAdj, face::Normal3f, face::VertexRef, face::BitFlags > {};
class MyEdge : public Edge<MyUsedTypes,edge::VertexRef, edge::VEAdj, edge::EEAdj, edge::BitFlags >{};
class MyMesh : public tri::TriMesh< vector<MyVertex>, vector<MyFace> , vector<MyEdge> > {};
int main( int argc, char **argv )
{
if(argc<2)
{
printf("Usage edgemesh_sampling <meshfilename.off> radius\n");
return -1;
}
MyMesh m,e;
if(tri::io::ImporterOFF<MyMesh>::Open(m,argv[1])!=0)
{
printf("Error reading file %s\n",argv[1]);
exit(0);
}
printf("Input mesh has %i vert %i faces\n",m.vn,m.fn);
tri::UpdateTopology<MyMesh>::FaceFace(m);
tri::UpdateNormal<MyMesh>::PerVertexNormalizedPerFaceNormalized(m);
tri::UpdateFlags<MyMesh>::FaceFauxSignedCrease(m,math::ToRad(-40.f),math::ToRad(40.f ),false);
assert(tri::Clean<MyMesh>::IsFaceFauxConsistent(m));
tri::BuildFromNonFaux(m,e);
printf("Out mesh has %i vert %i edges\n",e.vn,e.en);
tri::UpdateTopology<MyMesh>::VertexEdge(e);
tri::Clean<MyMesh>::SelectNonManifoldVertexOnEdgeMesh(e);
printf("Selected vertices %lu\n",tri::UpdateSelection<MyMesh>::VertexCount(e));
tri::Clean<MyMesh>::SplitSelectedVertexOnEdgeMesh(e);
printf("Out mesh has %i vert %i edges\n",e.vn,e.en);
tri::Clean<MyMesh>::SelectCreaseVertexOnEdgeMesh(e,math::ToRad(30.f));
printf("Selected vertices %lu\n",tri::UpdateSelection<MyMesh>::VertexCount(e));
tri::Clean<MyMesh>::SplitSelectedVertexOnEdgeMesh(e);
printf("Out mesh has %i vert %i edges\n",e.vn,e.en);
tri::io::ExporterPLY<MyMesh>::Save(e,"out.ply", tri::io::Mask::IOM_EDGEINDEX);
std::vector<Point3f> sampleVec;
tri::TrivialSampler<MyMesh> ps(sampleVec);
tri::SurfaceSampling<MyMesh>::EdgeMeshUniform(e,ps,m.bbox.Diag()/90.0f);
MyMesh sampleMesh;
tri::BuildMeshFromCoordVector(sampleMesh,sampleVec);
tri::io::ExporterPLY<MyMesh>::Save(sampleMesh,"sampleMesh.ply");
return 0;
}

3
vcglib/apps/sample/edgemesh_sampling/edgemesh_sampling.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = edgemesh_sampling
SOURCES += edgemesh_sampling.cpp ../../../wrap/ply/plylib.cpp

17
vcglib/apps/sample/polygonmesh_base/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(polygonmesh_base)
if (VCG_HEADER_ONLY)
set(SOURCES
polygonmesh.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(polygonmesh_base
${SOURCES})
target_link_libraries(
polygonmesh_base
PUBLIC
vcglib
)

204
vcglib/apps/sample/polygonmesh_base/polygonmesh.cpp

@ -0,0 +1,204 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/clean.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <wrap/io_trimesh/import.h>
#include <wrap/io_trimesh/export_ply.h>
/* include the support for half edges */
#include <vcg/complex/algorithms/update/halfedge_indexed.h>
using namespace vcg;
using namespace std;
class TFace;
class TVertex;
struct TUsedTypes: public vcg::UsedTypes< vcg::Use<TVertex>::AsVertexType, vcg::Use<TFace>::AsFaceType >{};
class TVertex : public Vertex< TUsedTypes,
vertex::BitFlags,
vertex::Coord3f,
vertex::Normal3f,
vertex::Mark >{};
class TFace : public Face< TUsedTypes,
face::VertexRef, // three pointers to vertices
face::Normal3f, // normal
face::BitFlags, // flags
face::FFAdj // three pointers to adjacent faces
> {};
/* the mesh is a container of vertices and a container of faces */
class TMesh : public vcg::tri::TriMesh< vector<TVertex>, vector<TFace> > {};
/* Definition of a mesh of polygons that also supports half-edges
*/
class PFace;
class PVertex;
class PHEdge;
class PEdge;
struct PUsedTypes: public vcg::UsedTypes<vcg::Use<PVertex> ::AsVertexType,
vcg::Use<PEdge> ::AsEdgeType,
vcg::Use<PHEdge>::AsHEdgeType,
vcg::Use<PFace> ::AsFaceType
>{};
//class DummyEdge: public vcg::Edge<PolyUsedTypes>{};
class PVertex:public vcg::Vertex< PUsedTypes,
vcg::vertex::Coord3f,
vcg::vertex::Normal3f,
vcg::vertex::Mark,
vcg::vertex::BitFlags,
vcg::vertex::VHAdj>{} ;
class PEdge : public Edge<PUsedTypes>{};
class PHEdge : public HEdge< PUsedTypes, hedge::BitFlags,
//hedge::HFAdj, // pointer to the face
//hedge::HOppAdj, // pointer to the opposite edge
//hedge::HVAdj, // pointer to the vertex
//hedge::HNextAdj, // pointer to the next halfedge
hedge::HEdgeData // the previous 4 components (just more handy, you can comment this and uncomment the previous four lines)
//,hedge::HPrevAdj // pointer to the previous halfedge
>{};
class PFace:public vcg::Face<
PUsedTypes
,vcg::face::PolyInfo // this is necessary if you use component in vcg/simplex/face/component_polygon.h
// It says "this class is a polygon and the memory for its components (e.g. pointer to its vertices
// will be allocated dynamically")
,vcg::face::PFVAdj // Pointer to the vertices (just like FVAdj )
,vcg::face::PFVAdj
,vcg::face::PFFAdj // Pointer to edge-adjacent face (just like FFAdj )
,vcg::face::PFHAdj // Pointer its half -edges ( you may need this if you use half edges)
,vcg::face::BitFlags // bit flags
,vcg::face::Normal3f // normal
> {};
class PMesh: public
vcg::tri::TriMesh<
std::vector<PVertex>, // the vector of vertices
std::vector<PFace >, // the vector of faces
std::vector<PHEdge> , // the vector of edges
std::vector<PEdge> // the vector of edges
>{};
PMesh pm;
TMesh tm0;
int main(int /*argc*/, char *argv[]) {
int loadmask;
if(true){
/*
first way:
1) read a polygon mesh that will be automatically converted in a triangle mesh tagging
the internal edges (i.e. the edges that have been added for triangulating the polygons)
2) make some cleaning
3) import the tagged triangle mesh in a polygon mesh
*/
// vcg::tri::io::ImporterOBJ<CMesh>::Open(mesh,argv[1],loadmask);
// vcg::tri::io::ImporterOFF<TMesh>::Open(tm0,argv[1],loadmask);
vcg::tri::Hexahedron(tm0);
vcg::tri::Clean<TMesh>::RemoveUnreferencedVertex(tm0);
vcg::tri::Clean<TMesh>::RemoveZeroAreaFace(tm0);
vcg::tri::UpdateTopology<TMesh>::FaceFace(tm0);
vcg::tri::Clean<TMesh>::RemoveNonManifoldFace(tm0);
vcg::tri::UpdateTopology<TMesh>::FaceFace(tm0);
assert(vcg::tri::Clean<TMesh>::CountNonManifoldEdgeFF(tm0)==0);
assert(vcg::tri::Clean<TMesh>::CountNonManifoldVertexFF(tm0)==0);
// create a polygon meshe from a trimesh with tagged faces
vcg::tri::PolygonSupport<TMesh,PMesh>::ImportFromTriMesh(pm,tm0);
}
else
{
/* second way:
Load into a polygon mesh straight away.
*/
vcg::tri::io::ImporterOBJ<PMesh>::Open(pm,argv[1],loadmask);
vcg::tri::UpdateTopology<PMesh>::FaceFace(pm);
vcg::tri::Clean<PMesh>::RemoveNonManifoldFace(pm);
vcg::tri::UpdateTopology<PMesh>::FaceFace(pm);
assert(vcg::tri::Clean<PMesh>::CountNonManifoldEdgeFF(pm));
}
// compute the half edges because I'm a half-edge programmer
vcg::tri::UpdateHalfEdges<PMesh>::FromIndexed(pm);
// .... my half edge based code ......
// check for consistency
assert(vcg::tri::UpdateHalfEdges<PMesh>::CheckConsistency(pm));
int size = pm.face.size();
// add a face to each face with more than 3 vertices ( just one pass)
for(int i = 0; i < size; ++i)
if(!(pm.face[i].IsD()))
if(pm.face[i].VN()>3){
PMesh::HEdgePointer ef = pm.face[i].FHp();
PMesh::HEdgePointer ef1 = ef -> HNp();
ef1 = ef1->HNp();
vcg::tri::UpdateHalfEdges<PMesh>::AddHEdge(pm, ef, ef1 );
}
assert(vcg::tri::UpdateHalfEdges<PMesh>::CheckConsistency(pm));
size = pm.face.size();
// remove an edge for each face
for(int i = 0; i < size; ++i)
if(!(pm.face[i].IsD() ))
{
PMesh::HEdgePointer ef = pm.face[i].FHp();
if( ef->HOp()->HFp() !=NULL){
vcg::tri::UpdateHalfEdges<PMesh>::RemoveHEdge(pm,ef);
}
}
// check for consistency
assert(vcg::tri::UpdateHalfEdges<PMesh>::CheckConsistency(pm));
// recompute indexed data structure from the half edge data structure
// vcg::tri::UpdateIndexed<PMesh>::FromHalfEdges(pm );
// create a triangle mesh from a polygon mesh
TMesh tm1;
vcg::tri::PolygonSupport<TMesh,PMesh>::ImportFromPolyMesh(tm1,pm);
vcg::tri::io::ExporterPLY<TMesh>::Save(tm1,"converted_tri.ply",false);
vcg::tri::io::ExporterPLY<PMesh>::Save(pm,"converted_poly.ply",false);
}

3
vcglib/apps/sample/polygonmesh_base/polygonmesh_base.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = polygonmesh_base
SOURCES += polygonmesh.cpp ../../../wrap/ply/plylib.cpp

17
vcglib/apps/sample/polygonmesh_dual/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(polygonmesh_dual)
if (VCG_HEADER_ONLY)
set(SOURCES
polygonmesh_dual.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(polygonmesh_dual
${SOURCES})
target_link_libraries(
polygonmesh_dual
PUBLIC
vcglib
)

122
vcglib/apps/sample/polygonmesh_dual/polygonmesh_dual.cpp

@ -0,0 +1,122 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <vcg/complex/complex.h>
/*include the algorithms for updating: */
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/clean.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <wrap/io_trimesh/export_obj.h>
#include <wrap/io_trimesh/import_obj.h>
#include <vcg/complex/algorithms/dual_meshing.h>
#include <vcg/complex/algorithms/polygon_support.h>
using namespace vcg;
using namespace std;
// forward declarations
class TFace;
class TVertex;
struct TUsedTypes: public vcg::UsedTypes< vcg::Use<TVertex>::AsVertexType, vcg::Use<TFace>::AsFaceType >{};
/* Definition of a mesh of triangles
*/
class TVertex : public Vertex< TUsedTypes,
vertex::BitFlags,
vertex::Coord3f,
vertex::Normal3f,
vertex::Mark >{};
class TFace : public Face< TUsedTypes,
face::VertexRef, // three pointers to vertices
face::Normal3f, // normal
face::BitFlags, // flags
face::FFAdj // three pointers to adjacent faces
> {};
/* the mesh is a container of vertices and a container of faces */
class TMesh : public vcg::tri::TriMesh< vector<TVertex>, vector<TFace> > {};
/* Definition of a mesh of polygons that also supports half-edges
*/
class PFace;
class PVertex;
struct PUsedTypes: public vcg::UsedTypes<vcg::Use<PVertex> ::AsVertexType,
vcg::Use<PFace> ::AsFaceType>{};
class PVertex:public vcg::Vertex< PUsedTypes,
vcg::vertex::Coord3f,
vcg::vertex::Normal3f,
vcg::vertex::Mark,
vcg::vertex::Qualityf,
vcg::vertex::BitFlags>{} ;
class PFace:public vcg::Face<
PUsedTypes
,vcg::face::PolyInfo // this is necessary if you use component in vcg/simplex/face/component_polygon.h
// It says "this class is a polygon and the memory for its components (e.g. pointer to its vertices
// will be allocated dynamically")
,vcg::face::PFVAdj // Pointer to the vertices (just like FVAdj )
,vcg::face::PFVAdj
,vcg::face::PFFAdj // Pointer to edge-adjacent face (just like FFAdj )
,vcg::face::BitFlags // bit flags
,vcg::face::Qualityf // quality
,vcg::face::Normal3f // normal
> {};
class PMesh: public
vcg::tri::TriMesh<
std::vector<PVertex>, // the vector of vertices
std::vector<PFace > // the vector of faces
>{};
TMesh primalT;
PMesh primal,dual;
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
vcg::tri::Sphere<TMesh>(primalT,2);
vcg::tri::PolygonSupport<TMesh,PMesh>::ImportFromTriMesh(primal,primalT);
vcg::tri::DualMeshing<PMesh>::MakeDual(primal,dual);
vcg::tri::io::ExporterOBJ<PMesh>::Save(dual,"./dual.obj",vcg::tri::io::Mask::IOM_BITPOLYGONAL);
vcg::tri::DualMeshing<PMesh>::MakeDual(dual,primal);
vcg::tri::io::ExporterOBJ<PMesh>::Save(primal,"./dual_dual.obj",vcg::tri::io::Mask::IOM_BITPOLYGONAL);
}

3
vcglib/apps/sample/polygonmesh_dual/polygonmesh_dual.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = polygonmesh_base
SOURCES += polygonmesh_dual.cpp ../../../wrap/ply/plylib.cpp

17
vcglib/apps/sample/polygonmesh_optimize/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(polygonmesh_optimize)
if (VCG_HEADER_ONLY)
set(SOURCES
polygonmesh_optimize.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(polygonmesh_optimize
${SOURCES})
target_link_libraries(
polygonmesh_optimize
PUBLIC
vcglib
)

180
vcglib/apps/sample/polygonmesh_optimize/polygonmesh_optimize.cpp

@ -0,0 +1,180 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <vcg/complex/complex.h>
/*include the algorithms for updating: */
#include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/complex/algorithms/update/normal.h>
#include <vcg/complex/algorithms/clean.h>
#include <vcg/complex/algorithms/create/platonic.h>
#include <wrap/io_trimesh/export_obj.h>
#include <wrap/io_trimesh/import_ply.h>
#include <vcg/complex/algorithms/dual_meshing.h>
#include <vcg/complex/algorithms/polygon_support.h>
#include <vcg/complex/algorithms/polygonal_algorithms.h>
#include <vcg/complex/algorithms/update/quality.h>
using namespace vcg;
using namespace std;
// forward declarations
class TFace;
class TVertex;
struct TUsedTypes: public vcg::UsedTypes< vcg::Use<TVertex>::AsVertexType, vcg::Use<TFace>::AsFaceType >{};
/* Definition of a mesh of triangles
*/
class TVertex : public Vertex< TUsedTypes,
vertex::BitFlags,
vertex::Coord3f,
vertex::Normal3f,
vertex::Mark >{};
class TFace : public Face< TUsedTypes,
face::VertexRef, // three pointers to vertices
face::Normal3f, // normal
face::BitFlags, // flags
face::FFAdj // three pointers to adjacent faces
> {};
/* the mesh is a container of vertices and a container of faces */
class TMesh : public vcg::tri::TriMesh< vector<TVertex>, vector<TFace> > {};
/* Definition of a mesh of polygons that also supports half-edges
*/
class PFace;
class PVertex;
struct PUsedTypes: public vcg::UsedTypes<vcg::Use<PVertex> ::AsVertexType,
vcg::Use<PFace> ::AsFaceType>{};
class PVertex:public vcg::Vertex< PUsedTypes,
vcg::vertex::Coord3f,
vcg::vertex::Normal3f,
vcg::vertex::Mark,
vcg::vertex::BitFlags>{} ;
class PFace:public vcg::Face<
PUsedTypes
,vcg::face::PolyInfo // this is necessary if you use component in vcg/simplex/face/component_polygon.h
// It says "this class is a polygon and the memory for its components (e.g. pointer to its vertices
// will be allocated dynamically")
,vcg::face::PFVAdj // Pointer to the vertices (just like FVAdj )
,vcg::face::PFVAdj
,vcg::face::PFFAdj // Pointer to edge-adjacent face (just like FFAdj )
,vcg::face::BitFlags // bit flags
,vcg::face::Normal3f // normal
,face::Qualityd // face quality
> {};
class PMesh: public
vcg::tri::TriMesh<
std::vector<PVertex>, // the vector of vertices
std::vector<PFace > // the vector of faces
>{};
TMesh primalT;
PMesh primal,dual,dual_opt,dual_flat;
int main(int argc, char *argv[])
{
assert(argc>1);
std::cout<<"Opening file " << argv[0] << std::endl;
int res=vcg::tri::io::ImporterPLY<TMesh>::Open(primalT,argv[1]);
assert(res==vcg::ply::E_NOERROR);
vcg::tri::PolygonSupport<TMesh,PMesh>::ImportFromTriMesh(primal,primalT);
vcg::tri::DualMeshing<PMesh>::MakeDual(primal,dual);
vcg::tri::io::ExporterOBJ<PMesh>::Save(dual,"./dual_no_optimized.obj",vcg::tri::io::Mask::IOM_BITPOLYGONAL);
//copy the mesh
vcg::tri::Append<PMesh,PMesh>::Mesh(dual_opt,dual);
vcg::tri::Append<PMesh,PMesh>::Mesh(dual_flat,dual);
vcg::PolygonalAlgorithm<PMesh>::SmoothReprojectPCA(dual_opt);
vcg::tri::io::ExporterOBJ<PMesh>::Save(dual_opt,"./dual_optimized.obj",vcg::tri::io::Mask::IOM_BITPOLYGONAL);
vcg::PolygonalAlgorithm<PMesh>::FlattenFaces(dual_flat);
vcg::tri::io::ExporterOBJ<PMesh>::Save(dual_flat,"./dual_flattened.obj",vcg::tri::io::Mask::IOM_BITPOLYGONAL);
//update the quality as template
std::pair<typename PMesh::ScalarType,typename PMesh::ScalarType> minmax_dual,minmax_dual_opt,minmax_dual_flat;
typename PMesh::ScalarType Avg_dual,Avg_dual_opt,Avg_dual_flat;
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual,PolygonalAlgorithm<PMesh>::QTemplate);
minmax_dual=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual);
Avg_dual=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual);
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual_opt,PolygonalAlgorithm<PMesh>::QTemplate);
minmax_dual_opt=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual_opt);
Avg_dual_opt=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual_opt);
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual_flat,PolygonalAlgorithm<PMesh>::QTemplate);
minmax_dual_flat=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual_flat);
Avg_dual_flat=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual_flat);
std::cout<<std::endl<<std::endl<<"Template Quality No Optimized min / max " <<minmax_dual.first<<" / "<<minmax_dual.second<<std::endl;
std::cout<<"Template Quality Optimized min / max " <<minmax_dual_opt.first<<" / "<<minmax_dual_opt.second<<std::endl;
std::cout<<"Template Quality Flattened min / max " <<minmax_dual_flat.first<<" / "<<minmax_dual_flat.second<<std::endl<<std::endl;
std::cout<<"Template Quality No Optimized Average " <<Avg_dual<<std::endl;
std::cout<<"Template Quality Optimized Average " <<Avg_dual_opt<<std::endl;
std::cout<<"Template Quality Flattened Average " <<Avg_dual_flat<<std::endl<<std::endl<<std::endl<<std::endl;
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual,PolygonalAlgorithm<PMesh>::QPlanar);
minmax_dual=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual);
Avg_dual=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual);
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual_opt,PolygonalAlgorithm<PMesh>::QPlanar);
minmax_dual_opt=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual_opt);
Avg_dual_opt=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual_opt);
vcg::PolygonalAlgorithm<PMesh>::UpdateQuality(dual_flat,PolygonalAlgorithm<PMesh>::QPlanar);
minmax_dual_flat=tri::Stat<PMesh>::ComputePerFaceQualityMinMax(dual_flat);
Avg_dual_flat=tri::Stat<PMesh>::ComputePerFaceQualityAvg(dual_flat);
std::cout<<"Flatness Quality No Optimized min / max " <<minmax_dual.first<<" / "<<minmax_dual.second<<std::endl;
std::cout<<"Flatness Quality Optimized min / max " <<minmax_dual_opt.first<<" / "<<minmax_dual_opt.second<<std::endl;
std::cout<<"Flatness Quality Flattened min / max " <<minmax_dual_flat.first<<" / "<<minmax_dual_flat.second<<std::endl<<std::endl;
std::cout<<"Flatness Quality No Optimized Average " <<Avg_dual<<std::endl;
std::cout<<"Flatness Quality Optimized Average " <<Avg_dual_opt<<std::endl;
std::cout<<"Flatness Quality Flattened Average " <<Avg_dual_flat<<std::endl;
}

3
vcglib/apps/sample/polygonmesh_optimize/polygonmesh_optimize.pro

@ -0,0 +1,3 @@
include(../common.pri)
TARGET = polygonmesh_base
SOURCES += polygonmesh_optimize.cpp ../../../wrap/ply/plylib.cpp

17
vcglib/apps/sample/polygonmesh_polychord_collapse/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(polygonmesh_polychord_collapse)
if (VCG_HEADER_ONLY)
set(SOURCES
polygonmesh_polychord_collapse.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(polygonmesh_polychord_collapse
${SOURCES})
target_link_libraries(
polygonmesh_polychord_collapse
PUBLIC
vcglib
)

106
vcglib/apps/sample/polygonmesh_polychord_collapse/polygonmesh_polychord_collapse.cpp

@ -0,0 +1,106 @@
#include <iostream>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/clean.h>
#include <wrap/io_trimesh/import.h>
#include <wrap/io_trimesh/export.h>
#include <vcg/complex/algorithms/polygon_support.h>
#include <vcg/complex/algorithms/polygon_polychord_collapse.h>
using namespace vcg;
class PolyVertex;
class PolyFace;
struct PolyUsedTypes : public vcg::UsedTypes<
vcg::Use<PolyVertex>::AsVertexType,
vcg::Use<PolyFace>::AsFaceType
> {};
class PolyVertex : public vcg::Vertex<
PolyUsedTypes,
vcg::vertex::Coord3f,
vcg::vertex::Normal3f,
vcg::vertex::BitFlags
> {};
class PolyFace : public vcg::Face<
PolyUsedTypes,
vcg::face::PolyInfo,
vcg::face::Normal3f,
vcg::face::BitFlags,
vcg::face::PFVAdj,
vcg::face::PFFAdj
> {};
class PolyMesh : public vcg::tri::TriMesh<
std::vector<PolyVertex>,
std::vector<PolyFace>
> {
public:
/**
* @brief open Loads a polygonal mesh from file.
* @param mesh The mesh object into which to extract the mesh.
* @param filename The filename where the mesh is stored.
* @return An error code.
*/
static int openMesh (PolyMesh &mesh, const char *filename)
{
// try to load the mesh from the file
int err = vcg::tri::io::Importer<PolyMesh>::Open(mesh, filename);
// check if successfully loaded
if (err == 0)
{
// update bounding box
vcg::tri::UpdateBounding<PolyMesh>::Box(mesh);
// update topology
vcg::tri::UpdateTopology<PolyMesh>::FaceFace(mesh);
// update normals TODO: compute average normal in the polygon
vcg::tri::UpdateNormal<PolyMesh>::PerFaceNormalized(mesh);
// update flags
vcg::tri::UpdateFlags<PolyMesh>::Clear(mesh);
}
return err;
}
/**
* @brief saveMesh Writes a polygonal mesh into a file.
* @param mesh The mesh to write.
* @param filename The filename where to store the mesh.
* @return
*/
static int saveMesh (PolyMesh &mesh, const char *filename) {
// try to write the mesh into the file
return vcg::tri::io::Exporter<PolyMesh>::Save(mesh, filename);
}
};
int main(int argc, char *argv[])
{
if (argc < 2) {
std::cout << "Error. Usage: " << argv[0] << " meshfilename" << std::endl;
return -1;
}
PolyMesh mesh;
// open mesh
int err = PolyMesh::openMesh(mesh, argv[1]);
if (err != 0)
return err;
// collapse **********************************************************************************************
vcg::tri::PolychordCollapse<PolyMesh>::CollapseAllPolychords(mesh, true);
// these don't work with polygonal meshes:
vcg::tri::Allocator<PolyMesh>::CompactFaceVector(mesh);
vcg::tri::Allocator<PolyMesh>::CompactVertexVector(mesh);
// save mesh
PolyMesh::saveMesh(mesh, "output.obj");
return 0;
}

3
vcglib/apps/sample/polygonmesh_polychord_collapse/polygonmesh_polychord_collapse.pro

@ -0,0 +1,3 @@
include(../common.pri)
SOURCES += polygonmesh_polychord_collapse.cpp ../../../wrap/ply/plylib.cpp
TARGET = polygonmesh_polychord_collapse

459
vcglib/apps/sample/polygonmesh_quadsimpl/polygonmesh_quadsimpl.cpp

@ -0,0 +1,459 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* 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 2 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 (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include <sstream>
#include <vcg/complex/complex.h>
#include <vcg/complex/algorithms/clean.h>
#include <wrap/io_trimesh/import.h>
#include <wrap/io_trimesh/export_off.h>
#include <vcg/complex/algorithms/polygon_support.h>
#include <vcg/complex/algorithms/local_optimization/quad_diag_collapse.h>
#include <vcg/complex/algorithms/update/fitmaps.h>
using namespace vcg;
using namespace std;
// forward declarations
class CFace;
class CVertex;
class CHEdge;
class CEdge;
class MyPolyVertex;
struct CUsedTypes: public vcg::UsedTypes< vcg::Use<CVertex>::AsVertexType, vcg::Use<CFace>::AsFaceType >{};
// Mesh of triangles
class CVertex : public Vertex<
CUsedTypes,
vertex::BitFlags,
vertex::Coord3f,
vertex::Normal3f,
vertex::VFAdj,
vertex::Mark,
vcg::vertex::Curvaturef,
vcg::vertex::CurvatureDirf,
vertex::Color4b,
vertex::Qualityf
>{};
class CFace : public Face<
CUsedTypes,
face::VertexRef,
face::Normal3f,
face::BitFlags,
face::FFAdj,
face::VFAdj,
face::Mark,
face::EdgePlane
> {};
class CMesh : public vcg::tri::TriMesh< vector<CVertex>, vector<CFace> > {};
// Poly mesh
class MyPolyFace;
class MyPolyVertex;
struct PolyUsedTypes: public vcg::UsedTypes<
vcg::Use<MyPolyVertex> ::AsVertexType,
vcg::Use<CEdge> ::AsEdgeType,
vcg::Use<CHEdge> ::AsHEdgeType,
vcg::Use<MyPolyFace> ::AsFaceType
>{};
class MyPolyVertex:public Vertex<
PolyUsedTypes,
vertex::Coord3f,
vertex::Normal3f,
vertex::Mark,
vertex::BitFlags,
vertex::VHAdj,
vertex::VFAdj
>{};
class CEdge : public Edge<PolyUsedTypes>{};
class CHEdge : public HEdge<
PolyUsedTypes,
hedge::BitFlags,
hedge::HFAdj,
hedge::HOppAdj,
hedge::HNextAdj,
hedge::HVAdj,
hedge::HPrevAdj,
hedge::Mark
>{};
class MyPolyFace:public Face<
PolyUsedTypes,
face::PolyInfo,
face::PFVAdj,
face::PFFAdj,
face::PFHAdj,
face::BitFlags,
face::Normal3f,
face::Mark
> {};
class MyPolyMesh: public tri::TriMesh<
std::vector<MyPolyVertex>,
std::vector<MyPolyFace>,
std::vector<CHEdge>,
std::vector<CEdge>
>{};
/*!
* \brief Collapse operation for adaptive simplification using fitmaps
*
*/
class MyCollapseAdaptive: public vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh> ,vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> >
{
public:
typedef vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh>, vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> > constructor;
MyCollapseAdaptive(HEdgePointer he, int mark):constructor(he,mark){}
};
/*!
* \brief Collapse for uniform simplification
*
*/
class MyCollapse: public vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> >
{
public:
typedef vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> > constructor;
MyCollapse(HEdgePointer he, int mark):constructor(he,mark){}
};
typedef CMesh::FaceType TriFaceType;
typedef vcg::GridStaticPtr<CMesh::FaceType, TriFaceType::ScalarType> GRID;
typedef CMesh::PerVertexAttributeHandle<float> Fitmap_attr;
/*! Initializes the grid for smoothing and fitmaps
*
* \param m Reference mesh
*
*/
void initGrid(CMesh & m)
{
GRID* grid = new GRID();
vcg::tri::UpdateBounding<CMesh>::Box(m);
vcg::tri::UpdateEdges<CMesh>::Set(m);
grid->Set(m.face.begin(), m.face.end());
// grid->ShowStats(stdout);
MyCollapse::grid() = grid;
MyCollapseAdaptive::grid() = grid;
}
/*! Initializes the heap of operations on a mesh
*
* \param m Mesh
* \param loc
* \param Adaptive Specifies if simplificaton will be adaptive
*
*/
void init_heap(MyPolyMesh &m, vcg::LocalOptimization<MyPolyMesh> &loc, bool adaptive)
{
if(adaptive)
MyCollapseAdaptive::Init(m, loc.h);
else
MyCollapse::Init(m,loc.h);
std::make_heap(loc.h.begin(),loc.h.end());
if(!loc.h.empty())
loc.currMetric=loc.h.front().pri;
}
/*! Read fitmaps values from a file and loads them into a mesh
*
* \param m Mesh
* \param fn Name of the file to read
*
*/
bool read_fitmaps(CMesh &m, const char *fn)
{
ifstream fitmaps;
fitmaps.open(fn);
if(! fitmaps.is_open())
return false;
Fitmap_attr S_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"S-Fitmap");
Fitmap_attr M_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"M-Fitmap");
int index;
float S_fit, M_fit;
do
{
fitmaps >> index >> S_fit >> M_fit;
S_Fit[m.vert[index]] = S_fit;
M_Fit[m.vert[index]] = M_fit;
}while(fitmaps.good());
bool eof = fitmaps.eof();
fitmaps.close();
return eof;
}
/*! Writes fitmaps values into a file
*
* \param m Mesh
* \param fn Name of the file to write
*
*/
bool store_fitmaps(CMesh &m, const char *fn)
{
ofstream fitmaps;
fitmaps.open(fn);
if(! fitmaps.is_open())
return false;
Fitmap_attr S_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"S-Fitmap");
Fitmap_attr M_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"M-Fitmap");
for(unsigned int i =0; i< m.vert.size(); i++)
{
if( !(m.vert[i].IsD()) )
{
fitmaps << i << " " << S_Fit[m.vert[i]] << " " << M_Fit[m.vert[i]] << endl;
if(!fitmaps.good())
{
fitmaps.close();
return false;
}
}
}
fitmaps.close();
return true;
}
/*! Load fitmaps for a mesh, computing them or reading values from a file
*
* \param m Mesh
* \param fn Name of the mesh file
*
*/
void load_fitmaps(CMesh &m, char* fn)
{
Fitmap_attr S_Fit = tri::Allocator<CMesh>::AddPerVertexAttribute<float> (m, string("S-Fitmap"));
Fitmap_attr M_Fit = tri::Allocator<CMesh>::AddPerVertexAttribute<float> (m, string("M-Fitmap"));
string filename(fn);
int found = filename.find_last_of("/");
string name = filename.substr(found+1);
string suffix = ".fmp";
if( !read_fitmaps( m, (name + suffix).c_str()) )
{
tri::Fitmaps<CMesh>::computeSFitmap(m);
for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
S_Fit[vi] = vi->Q();
tri::Fitmaps<CMesh>::computeMFitmap(m, 5);
for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
M_Fit[vi] = vi->Q();
store_fitmaps(m, ( name + suffix).c_str());
}
}
/*! Load a mesh, from a file
*
* \param m Mesh that will be filled with data from a file
* \param fn Name of the mesh file
* \param loadFitmaps Specifies if fitmaps have to be loaded
*
*/
void loadMesh(CMesh & m, char* fn, bool loadFitmaps = false)
{
int ret = vcg::tri::io::Importer<CMesh>::Open(m,fn);
if(ret != 0)
{
cerr << "Error reading file " << fn << endl;
exit(1);
}
tri::Clean<CMesh>::RemoveDegenerateFace(m);
tri::Clean<CMesh>::RemoveDuplicateFace(m);
tri::Clean<CMesh>::RemoveDuplicateVertex(m);
tri::Clean<CMesh>::RemoveUnreferencedVertex(m);
tri::UpdateTopology<CMesh>::FaceFace(m);
tri::Clean<CMesh>::RemoveNonManifoldFace(m);
tri::UpdateTopology<CMesh>::FaceFace(m);
tri::Clean<CMesh>::RemoveNonManifoldVertex(m);
tri::UpdateTopology<CMesh>::FaceFace(m);
// update bounding box
vcg::tri::UpdateBounding<CMesh>::Box (m);
// update Normals
vcg::tri::UpdateNormals<CMesh>::PerVertexNormalizedPerFace(m);
vcg::tri::UpdateNormals<CMesh>::PerFaceNormalized(m);
if(loadFitmaps)
load_fitmaps(m,fn);
}
int main(int argc, char *argv[]) {
// HE mesh
MyPolyMesh pm;
// Tri meshes
CMesh mesh,refMesh;
char* meshfile = NULL;
char* trimeshfile = NULL;
char* outfile = "output.off";
int faces;
bool adaptive = false;
if(argc < 2)
{
cerr << "Usage: " << argv[0] << " -meshfile filename [-trimeshfile filename] -faces num_faces [-adaptive] [-outfile filename]" << endl;
}
for(int i=1; i< argc; i++)
{
string arg = string(argv[i]);
if ( arg == "-meshfile")
meshfile = argv[++i];
else if (arg == "-trimeshfile")
trimeshfile = argv[++i];
else if (arg == "-faces")
{
stringstream myStream(argv[++i], stringstream::in | stringstream::out);
myStream >> faces;
}
else if (arg == "-outfile")
outfile = argv[++i];
else if (arg == "-adaptive")
adaptive = true;
}
if( !meshfile)
{
cerr << "Missing mesh filename" << endl;
exit(1);
}
if(faces < 0)
{
cerr << "Missing faces number" << endl;
exit(1);
}
// Load the mesh to simplify
loadMesh(mesh, meshfile);
// Load the reference mesh
if(trimeshfile)
loadMesh(refMesh, trimeshfile, adaptive);
else
loadMesh(refMesh, meshfile, adaptive);
initGrid(refMesh);
MyCollapse::refMesh() = &refMesh;
MyCollapseAdaptive::refMesh() = &refMesh;
vcg::tri::PolygonSupport<CMesh,MyPolyMesh>::ImportFromTriMesh(pm,mesh);
vcg::tri::UpdateHalfEdges<MyPolyMesh>::FromIndexed(pm);
// After loading check mesh consistency
assert(vcg::tri::UpdateHalfEdges<MyPolyMesh>::CheckConsistency(pm));
HalfedgeQuadClean<MyPolyMesh>::remove_singlets(pm);
HalfedgeQuadClean<MyPolyMesh>::remove_doublets(pm);
vcg::LocalOptimization<MyPolyMesh> loc(pm);
init_heap(pm, loc, adaptive);
loc.HeapSimplexRatio = 9;
loc.SetTargetSimplices(faces);
// Perform simplification
loc.DoOptimization();
assert(vcg::tri::UpdateHalfEdges<MyPolyMesh>::CheckConsistency(pm));
vcg::tri::UpdateIndexed<MyPolyMesh>::FromHalfEdges(pm );
int ret = tri::io::ExporterOFF<MyPolyMesh>::Save(pm, outfile, tri::io::Mask::IOM_BITPOLYGONAL );
if(ret != 0 )
{
cerr << "Error saving file" << endl;
exit(1);
}
cout << "Simplification ended successfully!" << endl;
}

3
vcglib/apps/sample/polygonmesh_quadsimpl/polygonmesh_quadsimpl.pro

@ -0,0 +1,3 @@
include(../common.pri)
SOURCES += polygonmesh_quadsimpl.cpp ../../../wrap/ply/plylib.cpp
TARGET = polygonmesh_quadsimpl

17
vcglib/apps/sample/polygonmesh_smooth/CMakeLists.txt

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(polygonmesh_smooth)
if (VCG_HEADER_ONLY)
set(SOURCES
polygonmesh_smooth.cpp
${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp)
endif()
add_executable(polygonmesh_smooth
${SOURCES})
target_link_libraries(
polygonmesh_smooth
PUBLIC
vcglib
)

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

Loading…
Cancel
Save