1537 changed files with 634197 additions and 0 deletions
@ -0,0 +1,320 @@
@@ -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() |
||||
@ -0,0 +1,674 @@
@@ -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>. |
||||
@ -0,0 +1,35 @@
@@ -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. |
||||
|
||||
[](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). |
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.13) |
||||
|
||||
project(VCGApps) |
||||
|
||||
add_subdirectory(sample) |
||||
add_subdirectory(metro) |
||||
add_subdirectory(tridecimator) |
||||
add_subdirectory(embree) |
||||
@ -0,0 +1,256 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,34 @@
@@ -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 |
||||
@ -0,0 +1,200 @@
@@ -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 (); |
||||
} |
||||
@ -0,0 +1,106 @@
@@ -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_ */ |
||||
@ -0,0 +1,48 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,68 @@
@@ -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); |
||||
} |
||||
@ -0,0 +1,47 @@
@@ -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_ */ |
||||
@ -0,0 +1,197 @@
@@ -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 &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 &Mesh</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="loadTetrahedronPushButton" > |
||||
<property name="text" > |
||||
<string>Load &Tetrahedron</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="loadDodecahedronPushButton" > |
||||
<property name="text" > |
||||
<string>Load &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> |
||||
@ -0,0 +1,46 @@
@@ -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 |
||||
@ -0,0 +1,232 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -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_ */ |
||||
@ -0,0 +1,48 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,243 @@
@@ -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); |
||||
} |
||||
@ -0,0 +1,83 @@
@@ -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_ */ |
||||
@ -0,0 +1,82 @@
@@ -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> |
||||
@ -0,0 +1,28 @@
@@ -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 |
||||
@ -0,0 +1,51 @@
@@ -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 |
||||
@ -0,0 +1,334 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,40 @@
@@ -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 |
||||
@ -0,0 +1,215 @@
@@ -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 (); |
||||
} |
||||
@ -0,0 +1,101 @@
@@ -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 |
||||
@ -0,0 +1,57 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,40 @@
@@ -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 |
||||
} |
||||
@ -0,0 +1,280 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -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 |
||||
@ -0,0 +1,11 @@
@@ -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(); |
||||
} |
||||
@ -0,0 +1,58 @@
@@ -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> >{}; |
||||
|
||||
/****************************************************************************************************************************/ |
||||
@ -0,0 +1,56 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,19 @@
@@ -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 |
||||
|
||||
@ -0,0 +1,39 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,75 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,54 @@
@@ -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 |
||||
@ -0,0 +1,18 @@
@@ -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() |
||||
|
||||
|
||||
@ -0,0 +1,151 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,50 @@
@@ -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 |
||||
) |
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,122 @@
@@ -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
|
||||
@ -0,0 +1,363 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,48 @@
@@ -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 |
||||
@ -0,0 +1,18 @@
@@ -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 |
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@
@@ -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 |
||||
@ -0,0 +1,19 @@
@@ -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 |
||||
@ -0,0 +1,22 @@
@@ -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 |
||||
@ -0,0 +1,866 @@
@@ -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 |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,37 @@
@@ -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 |
||||
@ -0,0 +1,318 @@
@@ -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; |
||||
} |
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
@ -0,0 +1,10 @@
@@ -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 |
||||
@ -0,0 +1,96 @@
@@ -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. |
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@
@@ -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 |
||||
|
||||
@ -0,0 +1,603 @@
@@ -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 |
||||
@ -0,0 +1,15 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,74 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -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 |
||||
|
||||
@ -0,0 +1,223 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,206 @@
@@ -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
|
||||
@ -0,0 +1,65 @@
@@ -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() |
||||
@ -0,0 +1,14 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,148 @@
@@ -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); |
||||
} |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = aabb_binary_tree |
||||
SOURCES += aabb_binary_tree.cpp |
||||
@ -0,0 +1,14 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,142 @@
@@ -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; |
||||
} |
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = colorspace |
||||
SOURCES += colorspace.cpp |
||||
@ -0,0 +1,23 @@
@@ -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 |
||||
} |
||||
} |
||||
@ -0,0 +1,94 @@
@@ -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; |
||||
} |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = edgemesh_sampling |
||||
SOURCES += edgemesh_sampling.cpp ../../../wrap/ply/plylib.cpp |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,204 @@
@@ -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); |
||||
} |
||||
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = polygonmesh_base |
||||
SOURCES += polygonmesh.cpp ../../../wrap/ply/plylib.cpp |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,122 @@
@@ -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); |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = polygonmesh_base |
||||
SOURCES += polygonmesh_dual.cpp ../../../wrap/ply/plylib.cpp |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,180 @@
@@ -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; |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = polygonmesh_base |
||||
SOURCES += polygonmesh_optimize.cpp ../../../wrap/ply/plylib.cpp |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,106 @@
@@ -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; |
||||
} |
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
SOURCES += polygonmesh_polychord_collapse.cpp ../../../wrap/ply/plylib.cpp |
||||
TARGET = polygonmesh_polychord_collapse |
||||
@ -0,0 +1,459 @@
@@ -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; |
||||
|
||||
} |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
SOURCES += polygonmesh_quadsimpl.cpp ../../../wrap/ply/plylib.cpp |
||||
TARGET = polygonmesh_quadsimpl |
||||
@ -0,0 +1,17 @@
@@ -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 |
||||
) |
||||
@ -0,0 +1,132 @@
@@ -0,0 +1,132 @@
|
||||
/****************************************************************************
|
||||
* 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 <vcg/complex/algorithms/polygonal_algorithms.h> |
||||
|
||||
#include <wrap/io_trimesh/export_obj.h> |
||||
#include <wrap/io_trimesh/import_ply.h> |
||||
#include <wrap/io_trimesh/export_off.h> |
||||
#include <wrap/io_trimesh/import_off.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::Mark, // incremental mark
|
||||
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::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::Qualityf // quality
|
||||
,vcg::face::Mark // incremental mark
|
||||
,vcg::face::Normal3f // normal
|
||||
> {}; |
||||
|
||||
class PMesh: public |
||||
vcg::tri::TriMesh< |
||||
std::vector<PVertex>, // the vector of vertices
|
||||
std::vector<PFace > // the vector of faces
|
||||
>{}; |
||||
|
||||
using namespace vcg; |
||||
|
||||
int main(int, char **) |
||||
{ |
||||
TMesh tm; |
||||
PMesh pm; |
||||
math::MarsenneTwisterRNG RndGen; |
||||
tri::io::ImporterOFF<PMesh>::Open(pm,"../../meshes/fertility_quad.off"); |
||||
tri::UpdateBounding<PMesh>::Box(pm); |
||||
tri::UpdateSelection<PMesh>::VertexClear(pm); |
||||
// randomly displace half of the vertices
|
||||
float randScale = pm.bbox.Diag()/200.0f; |
||||
ForEachVertex(pm,[&](PVertex &v){ |
||||
if(v.P()[0] < pm.bbox.Center()[0]) |
||||
v.P() += math::GeneratePointInUnitBallUniform<float,math::MarsenneTwisterRNG>(RndGen)*randScale; |
||||
}); |
||||
|
||||
// Select half of the vertices
|
||||
ForEachVertex(pm,[&](PVertex &v){ |
||||
if(v.P()[2] < pm.bbox.Center()[2]) |
||||
v.SetS(); |
||||
}); |
||||
printf("Input quad mesh has %i %i (sel %zu)\n", pm.VN(), pm.FN(), tri::UpdateSelection<PMesh>::VertexCount(pm)); |
||||
|
||||
tri::io::ImporterPLY<TMesh>::Open(tm,"../../meshes/fertility_tri.ply"); |
||||
tri::UpdateNormal<TMesh>::PerVertexNormalizedPerFaceNormalized(tm); |
||||
printf("Input tri mesh has %i %i\n", tm.VN(), tm.FN()); |
||||
tri::io::ExporterOFF<PMesh>::Save(pm,"./smooth.off"); |
||||
PolygonalAlgorithm<PMesh>::LaplacianReproject(pm,tm,100,0.6,0.3,true); |
||||
tri::io::ExporterOFF<PMesh>::Save(pm,"./smooth2.off"); |
||||
} |
||||
|
||||
|
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
include(../common.pri) |
||||
TARGET = polygonmesh_smooth |
||||
SOURCES += polygonmesh_smooth.cpp ../../../wrap/ply/plylib.cpp |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue