初始化内容
@@ -0,0 +1,4 @@
|
||||
The changelog can be found in the html Documentation.
|
||||
|
||||
The latest changelog for the master can be found here:
|
||||
http://openmesh.org/Daily-Builds/Doc/
|
||||
@@ -0,0 +1,205 @@
|
||||
cmake_minimum_required(VERSION 3.10.0 FATAL_ERROR)
|
||||
|
||||
|
||||
# Set and enforce C++-11 flags
|
||||
#set( CMAKE_CXX_STANDARD_REQUIRED TRUE )
|
||||
#set( CMAKE_CXX_STANDARD 11 )
|
||||
|
||||
enable_testing()
|
||||
|
||||
|
||||
project (OpenMesh
|
||||
VERSION 11.0.0
|
||||
LANGUAGES C CXX )
|
||||
|
||||
# Set AUTO UIC/MOC Policy to new for CMAKE 3.17 or higher
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17")
|
||||
cmake_policy(SET CMP0100 NEW)
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.9" OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "4.9")
|
||||
message(WARNING "Your version of GCC contains an optimizer bug. Please verify that you do not use -O3!")
|
||||
string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE_NEW "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE_NEW}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ( WIN32 )
|
||||
# This is the base directory for windows library search used in the finders we ship.
|
||||
set(CMAKE_WINDOWS_LIBS_DIR "c:/libs" CACHE STRING "Default Library search dir on windows." )
|
||||
endif()
|
||||
|
||||
if (NOT WIN32 AND NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif()
|
||||
|
||||
# add our macro directory to cmake search path
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake-library/finders ${CMAKE_CURRENT_SOURCE_DIR}/cmake-library/VCI )
|
||||
set (CMAKE_DEBUG_POSTFIX "d")
|
||||
|
||||
# include our cmake files
|
||||
include (VCICommon)
|
||||
|
||||
# Disable package building when built as an external library
|
||||
if(${CMAKE_PROJECT_NAME} MATCHES "OpenMesh")
|
||||
include(OpenMeshPackage)
|
||||
endif()
|
||||
|
||||
include (VCIOutput)
|
||||
include(VCIQt)
|
||||
|
||||
# ========================================================================
|
||||
# Definitions
|
||||
# ========================================================================
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(
|
||||
-D_USE_MATH_DEFINES -DNOMINMAX
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(NO_DECREMENT_DEPRECATED_WARNINGS OFF CACHE BOOL "Disables all deprecated warnings warning about decrement operations on normal circulators.")
|
||||
if(NO_DECREMENT_DEPRECATED_WARNINGS)
|
||||
add_definitions( -DNO_DECREMENT_DEPRECATED_WARNINGS )
|
||||
endif()
|
||||
|
||||
# ========================================================================
|
||||
# Windows build style control
|
||||
# ========================================================================
|
||||
|
||||
if ( WIN32 )
|
||||
if ( NOT DEFINED OPENMESH_BUILD_SHARED )
|
||||
set( OPENMESH_BUILD_SHARED false CACHE BOOL "Build as shared library(DLL)?" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ========================================================================
|
||||
# Add bundle targets here
|
||||
# ========================================================================
|
||||
if ( NOT DEFINED BUILD_APPS )
|
||||
set( BUILD_APPS true CACHE BOOL "Enable or disable building of apps" )
|
||||
endif()
|
||||
|
||||
# Only call fixbundle, when we are building OpenMesh standalone
|
||||
if( (${CMAKE_PROJECT_NAME} MATCHES "OpenMesh") AND BUILD_APPS )
|
||||
|
||||
if (WIN32)
|
||||
if ( NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" AND BUILD_APPS )
|
||||
add_custom_target (fixbundle ALL
|
||||
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_BINARY_DIR}/fixbundle.win.cmake" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
add_custom_target (fixbundle ALL
|
||||
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_BINARY_DIR}/fixbundle.cmake"
|
||||
)
|
||||
endif()
|
||||
|
||||
endif() # project OpenMesh
|
||||
|
||||
# ========================================================================
|
||||
# Call the subdirectories with there projects
|
||||
# ========================================================================
|
||||
|
||||
add_subdirectory (src/OpenMesh/Core)
|
||||
add_subdirectory (src/OpenMesh/Tools)
|
||||
add_subdirectory (src/OpenMesh/Apps)
|
||||
|
||||
set(OPENMESH_BENCHMARK_DIR CACHE PATH "Source path of benchmark (https://github.com/google/benchmark).")
|
||||
if (OPENMESH_BENCHMARK_DIR)
|
||||
add_subdirectory(${OPENMESH_BENCHMARK_DIR} benchmark)
|
||||
add_subdirectory(src/Benchmark)
|
||||
endif()
|
||||
|
||||
# Do not build unit tests when build as external library
|
||||
if(${CMAKE_PROJECT_NAME} MATCHES "OpenMesh")
|
||||
add_subdirectory (src/Unittests)
|
||||
else()
|
||||
# If built as a dependent project simulate effects of
|
||||
# successful finder run:
|
||||
set (OPENMESH_FOUND true PARENT_SCOPE)
|
||||
set (OPENMESH_LIBRARIES OpenMeshCore OpenMeshTools PARENT_SCOPE)
|
||||
set (OPENMESH_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src" PARENT_SCOPE)
|
||||
set (OPENMESH_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src" PARENT_SCOPE)
|
||||
|
||||
# Also define variables provided by the old legacy finder.
|
||||
set (OPENMESH_CORE_LIBRARY OpenMeshCore PARENT_SCOPE)
|
||||
set (OPENMESH_TOOLS_LIBRARY OpenMeshTools PARENT_SCOPE)
|
||||
set (OPENMESH_TOOLS_LIBRARY OpenMeshTools PARENT_SCOPE)
|
||||
set (OPENMESH_LIBRARY OpenMeshCore OpenMeshTools PARENT_SCOPE)
|
||||
get_target_property(_OPENMESH_LIBRARY_DIR OpenMeshCore LIBRARY_OUTPUT_DIRECTORY)
|
||||
set (OPENMESH_LIBRARY_DIR "${_OPENMESH_LIBRARY_DIR}" CACHE PATH "The directory where the OpenMesh libraries can be found.")
|
||||
endif()
|
||||
|
||||
if ( NOT DEFINED OPENMESH_DOCS )
|
||||
set( OPENMESH_DOCS true CACHE BOOL "Enable or disable building of documentation" )
|
||||
endif()
|
||||
|
||||
if (OPENMESH_DOCS)
|
||||
add_subdirectory (Doc)
|
||||
endif()
|
||||
|
||||
# ========================================================================
|
||||
# Bundle generation (Targets exist, now configure them)
|
||||
# ========================================================================
|
||||
|
||||
# Only call fixbundle, when we are building OpenMesh standalone
|
||||
if(${CMAKE_PROJECT_NAME} MATCHES "OpenMesh")
|
||||
|
||||
if (WIN32 AND BUILD_APPS)
|
||||
# prepare bundle generation cmake file and add a build target for it
|
||||
configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/cmake/fixbundle.cmake.win.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fixbundle.win.cmake" @ONLY IMMEDIATE)
|
||||
|
||||
if ( NOT "${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles" )
|
||||
# let bundle generation depend on all targets
|
||||
add_dependencies (fixbundle QtViewer DecimaterGui)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# On apple we do a fixbundle, which is only necessary for the apps and not for the libs
|
||||
if (APPLE AND BUILD_APPS)
|
||||
# prepare bundle generation cmake file and add a build target for it
|
||||
configure_file ("${CMAKE_SOURCE_DIR}/cmake/fixbundle.cmake.in"
|
||||
"${CMAKE_BINARY_DIR}/fixbundle.cmake" @ONLY IMMEDIATE)
|
||||
|
||||
# let bundle generation depend on all targets
|
||||
if (QT_FOUND)
|
||||
add_dependencies (fixbundle DecimaterGui ProgViewer QtViewer SubdividerGui)
|
||||
endif()
|
||||
|
||||
# Required for Snow leopard, and the latest qt. Then the resources have to be copied
|
||||
if ( EXISTS "/opt/local/libexec/qt4-mac/lib/QtGui.framework/Versions/4/Resources/qt_menu.nib" )
|
||||
add_custom_command(TARGET OpenMesh POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "/opt/local/libexec/qt4-mac/lib/QtGui.framework/Versions/4/Resources/qt_menu.nib"
|
||||
"${CMAKE_BINARY_DIR}/Build/Libraries/qt_menu.nib" )
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
endif()
|
||||
|
||||
# ========================================================================
|
||||
|
||||
# Generate openmesh.pc file
|
||||
|
||||
set(DEST_DIR "${CMAKE_INSTALL_PREFIX}")
|
||||
set(PRIVATE_LIBS "-lOpenMeshCore -lOpenMeshTools")
|
||||
|
||||
configure_file("openmesh.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/openmesh.pc" @ONLY)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openmesh.pc DESTINATION libdata/pkgconfig)
|
||||
|
||||
# generate target file
|
||||
|
||||
install(EXPORT OpenMeshConfig DESTINATION share/OpenMesh/cmake)
|
||||
|
||||
export(TARGETS OpenMeshCore OpenMeshTools FILE OpenMeshConfig.cmake)
|
||||
|
||||
# display results
|
||||
vci_print_configure_header (OPENMESH "OpenMesh")
|
||||
@@ -0,0 +1,12 @@
|
||||
include (VCIDoxygen)
|
||||
|
||||
IF (DOXYGEN_FOUND)
|
||||
|
||||
# Add a documentation install target
|
||||
vci_create_doc_target(doc-install)
|
||||
|
||||
if (TARGET doc-install)
|
||||
vci_copy_after_build (doc-install "${CMAKE_BINARY_DIR}/Build/${VCI_PROJECT_DATADIR}/Doc/html" "${CMAKE_INSTALL_PREFIX}/${VCI_PROJECT_DATADIR}/doc/html")
|
||||
endif()
|
||||
|
||||
ENDIF(DOXYGEN_FOUND)
|
||||
@@ -0,0 +1,202 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. 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. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder 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 HOLDER *
|
||||
* 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. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Mesh Items Concept
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#error this file is for documentation purposes only
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Concepts {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \ingroup mesh_concepts_group
|
||||
The mesh items class encapsulates the types VertexT, HalfedgeT,
|
||||
EdgeT, and FaceT.
|
||||
\see VertexT, HalfedgeT, EdgeT, FaceT
|
||||
*/
|
||||
struct MeshItems {
|
||||
|
||||
|
||||
/** Interface for the internal vertex type. This minimal interface
|
||||
must be provided by every vertex. It's up to the mesh kernel (or
|
||||
the items used by the mesh kernel) to implement it.
|
||||
|
||||
All methods marked as internal should only be used by the mesh
|
||||
kernel.
|
||||
*/
|
||||
template <class Refs_> class VertexT
|
||||
{
|
||||
public:
|
||||
|
||||
/// Re-export the template argument Refs. This \b must be done!
|
||||
typedef Refs_ Refs;
|
||||
|
||||
/// Default constructor
|
||||
VertexT();
|
||||
|
||||
/// Get an outgoing halfedge
|
||||
HalfedgeHandle halfedge_handle() const;
|
||||
/// Set the outgoing halfedge link
|
||||
void set_halfedge_handle(HalfedgeHandle _eh);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Interface for the internal halfedge type. This minimal interface
|
||||
must be provided by every halfedge. It's up to the mesh kernel (or
|
||||
the items used by the mesh kernel) to implement it.
|
||||
|
||||
All methods marked as internal should only be used by the mesh
|
||||
kernel.
|
||||
*/
|
||||
template <class Refs_> class HalfedgeT
|
||||
{
|
||||
public:
|
||||
|
||||
/// Re-export the template argument Refs. This \b must be done!
|
||||
typedef Refs_ Refs;
|
||||
|
||||
/** Get the vertex the halfedge point to.
|
||||
\internal */
|
||||
VertexHandle vertex_handle() const;
|
||||
|
||||
/** Set the vertex the halfedge point to.
|
||||
\internal */
|
||||
void set_vertex_handle(VertexHandle _vh);
|
||||
|
||||
/** Get the face this halfedge belongs to.
|
||||
\internal */
|
||||
FaceHandle face_handle() const;
|
||||
|
||||
/** Set the face this halfedge belongs to.
|
||||
\internal */
|
||||
void set_face_handle(FaceHandle _fh);
|
||||
|
||||
/** Get the next halfedge inside this face.
|
||||
\internal */
|
||||
HalfedgeHandle next_halfedge_handle() const;
|
||||
|
||||
/** Set the next halfedge inside this face.
|
||||
\internal */
|
||||
void set_next_halfedge_handle(HalfedgeHandle _eh);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Interface for the internal edge type. This minimal interface must
|
||||
be provided by every edge. It's up to the mesh kernel (or the
|
||||
items used by the mesh kernel) to implement it.
|
||||
|
||||
All methods marked as internal should only be used by the mesh
|
||||
kernel.
|
||||
*/
|
||||
template <class Refs_> class EdgeT
|
||||
{
|
||||
public:
|
||||
|
||||
/// Re-export the template argument Refs. This \b must be done!
|
||||
typedef Refs_ Refs;
|
||||
|
||||
/** Store two halfedges.
|
||||
\internal */
|
||||
Halfedge halfedges[2];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Interface for the internal face type. This minimal interface must
|
||||
be provided by every face. It's up to the mesh kernel (or the
|
||||
items used by the mesh kernel) to implement it.
|
||||
|
||||
All methods marked as internal should only be used by the mesh
|
||||
kernel.
|
||||
*/
|
||||
template <class Refs_> class FaceT
|
||||
{
|
||||
public:
|
||||
|
||||
/// Re-export the template argument Refs. This \b must be done!
|
||||
typedef Refs_ Refs;
|
||||
|
||||
/** Compile-time-tag: is this face a triangle? Should be typedef'ed
|
||||
to either GenProg::TagTrue or GenProg::TagFalse */
|
||||
typedef GenProg::TagTrue IsTriangle;
|
||||
/// Run-time test: is this face a triangle?
|
||||
static bool is_triangle();
|
||||
|
||||
/// Get the number of vertices of this face.
|
||||
unsigned char n_vertices() const;
|
||||
/** Set the number of vertices of this face.
|
||||
\internal */
|
||||
void set_n_vertices(unsigned char _n);
|
||||
|
||||
/// Get a halfedge that belongs to this face.
|
||||
HalfedgeHandle halfedge_handle() const;
|
||||
/** Set a halfedge that belongs this face.
|
||||
\internal */
|
||||
void set_halfedge_handle(HalfedgeHandle _eh);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Concepts
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
@@ -0,0 +1,588 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. 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. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder 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 HOLDER *
|
||||
* 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. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Kernel Concept
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#error this file is for documentation purposes only
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Concepts {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \ingroup mesh_concepts_group
|
||||
This class describes the minimum interface a mesh kernel
|
||||
has to implement (because the resulting mesh will rely on
|
||||
this interface).
|
||||
|
||||
This is the template class the actually holds the mesh kernel
|
||||
implementation. All functions marked as internal should only be used
|
||||
by the mesh class (that inherits the kernel). The mesh may then
|
||||
provide wrapper functions that provide the same functionality.
|
||||
|
||||
\todo Check, if the member list is complete.
|
||||
*/
|
||||
template <class FinalMeshItems> class KernelT
|
||||
{
|
||||
public:
|
||||
|
||||
/// \name Mesh Items
|
||||
//@{
|
||||
|
||||
/// Derive this type from the FinalMeshItems
|
||||
typedef typename FinalMeshItems::Vertex Vertex;
|
||||
typedef typename FinalMeshItems::Halfedge Halfedge;
|
||||
typedef typename FinalMeshItems::Edge Edge;
|
||||
typedef typename FinalMeshItems::Face Face;
|
||||
typedef typename FinalMeshItems::Point Point;
|
||||
typedef typename FinalMeshItems::Scalar Scalar;
|
||||
typedef typename FinalMeshItems::Normal Normal;
|
||||
typedef typename FinalMeshItems::Color Color;
|
||||
typedef typename FinalMeshItems::TexCoord TexCoord;
|
||||
typedef typename FinalMeshItems::VertexHandle VertexHandle;
|
||||
typedef typename FinalMeshItems::HalfedgeHandle HalfedgeHandle;
|
||||
typedef typename FinalMeshItems::EdgeHandle EdgeHandle;
|
||||
typedef typename FinalMeshItems::FaceHandle FaceHandle;
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Kernel Iterators
|
||||
//@{
|
||||
/// This type depends on the container type in use.
|
||||
typedef SomeIterator KernelVertexIter;
|
||||
typedef SomeIterator KernelConstVertexIter;
|
||||
typedef SomeIterator KernelEdgeIter;
|
||||
typedef SomeIterator KernelConstEdgeIter;
|
||||
typedef SomeIterator KernelFaceIter;
|
||||
typedef SomeIterator KernelConstFaceIter;
|
||||
//@}
|
||||
|
||||
/// \name Constructor/Destructor
|
||||
//@{
|
||||
/// Default constructor
|
||||
KernelT() {}
|
||||
|
||||
/// Destructor
|
||||
~KernelT();
|
||||
//@}
|
||||
|
||||
/// Assignment operator
|
||||
KernelT& operator=(const KernelT& _rhs);
|
||||
|
||||
|
||||
/** Reserve memory for vertices, edges, faces.
|
||||
*
|
||||
* Reserve memory for the mesh items vertices, edges, faces. Use
|
||||
* this method if you can estimate the memory consumption, for
|
||||
* instance in algorithm expanding the mesh. Depending on the
|
||||
* underlying array type you might be better of using this method,
|
||||
* then letting the array type decide when to increase the
|
||||
* capacity. For instance the STL vector class \c std::vector (used
|
||||
* in the supplied ArrayKernelT) doubles the capacity if it is
|
||||
* exhausted. This might lead to an memory allocation exception,
|
||||
* though an smaller increment would be enough.
|
||||
*/
|
||||
void reserve( size_t _n_vertices,
|
||||
size_t _n_edges,
|
||||
size_t _n_faces );
|
||||
|
||||
|
||||
/// \name Handle -> Item.
|
||||
//@{
|
||||
/// Translate handle to item (see also OpenMesh::PolyMeshT::deref())
|
||||
const Vertex& vertex(VertexHandle _h) const { return deref(_h); }
|
||||
Vertex& vertex(VertexHandle _h) { return deref(_h); }
|
||||
const Halfedge& halfedge(HalfedgeHandle _h) const { return deref(_h); }
|
||||
Halfedge& halfedge(HalfedgeHandle _h) { return deref(_h); }
|
||||
const Edge& edge(EdgeHandle _h) const { return deref(_h); }
|
||||
Edge& edge(EdgeHandle _h) { return deref(_h); }
|
||||
const Face& face(FaceHandle _h) const { return deref(_h); }
|
||||
Face& face(FaceHandle _h) { return deref(_h); }
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Item -> Handle
|
||||
//@{
|
||||
/// Translate item to handle
|
||||
VertexHandle handle(const Vertex& _v) const;
|
||||
HalfedgeHandle handle(const Halfedge& _he) const;
|
||||
EdgeHandle handle(const Edge& _e) const;
|
||||
FaceHandle handle(const Face& _f) const;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Get the i'th item
|
||||
//@{
|
||||
/// Get the i'th item
|
||||
VertexHandle vertex_handle(unsigned int _i) const;
|
||||
HalfedgeHandle halfedge_handle(unsigned int _i) const;
|
||||
EdgeHandle edge_handle(unsigned int _i) const;
|
||||
FaceHandle face_handle(unsigned int _i) const;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Delete items
|
||||
//@{
|
||||
/** Delete all items, i.e. clear all item containers.
|
||||
* The properties will also be removed from the mesh
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/** Delete all items, i.e. clear all item containers.
|
||||
* The properties will be kept
|
||||
*/
|
||||
void clean();
|
||||
|
||||
/** Remove all items that are marked as deleted from the
|
||||
corresponding containers.
|
||||
\note All handles (and indices) to any entity (face, vertex,
|
||||
edge, halfedge) created before garbage collection
|
||||
will be out of sync with the mesh, do not use them anymore!
|
||||
See also \ref deletedElements.
|
||||
\note Needs the Attributes::Status attribute
|
||||
\note This function may not be implemented for all kernels.
|
||||
*/
|
||||
void garbage_collection();
|
||||
|
||||
/** Remove the last vertex imidiately, i.e. call pop_back() for the
|
||||
VertexContainer.
|
||||
*/
|
||||
void remove_last_vertex() { vertices_.pop_back(); }
|
||||
/** Remove the last edge imidiately, i.e. call pop_back() for the
|
||||
EdgeContainer. Used e.g. by the add_face() method of PolyMeshT
|
||||
*/
|
||||
void remove_last_edge() { edges_.pop_back(); }
|
||||
/** Remove the last face imidiately, i.e. call pop_back() for the
|
||||
FaceContainer. Used e.g. by the add_face() method of PolyMeshT
|
||||
*/
|
||||
void remove_last_face() { faces_.pop_back(); }
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
|
||||
/// \name Number of elements
|
||||
//@{
|
||||
/// Returns number of vertices
|
||||
size_t n_vertices() const;
|
||||
/// Returns number of halfedges (should be 2*n_edges())
|
||||
size_t n_halfedges() const;
|
||||
/// Returns number of edges
|
||||
size_t n_edges() const;
|
||||
/// Returns number of faces
|
||||
size_t n_faces() const;
|
||||
/// Is the vertex container empty?
|
||||
bool vertices_empty() const;
|
||||
/// Is the halfedge container empty (should be the same as edges_empty()).
|
||||
bool halfedges_empty() const;
|
||||
/// Is the edge container empty?
|
||||
bool edges_empty() const;
|
||||
/// Is the face container empty?
|
||||
bool faces_empty() const;
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/// \name Vertex connectivity
|
||||
//@{
|
||||
/// Get an outgoing halfedge of a given vertex
|
||||
HalfedgeHandle halfedge_handle(VertexHandle _vh) const;
|
||||
/// Set the outgoing halfedge handle of a given vertex
|
||||
void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh);
|
||||
/// Get the coordinate of a vertex
|
||||
const Point& point(VertexHandle _vh) const;
|
||||
/// Get the coordinate of a vertex
|
||||
const Point& point(const Vertex& _v) const;
|
||||
/// Set the coordinate of a vertex
|
||||
void set_point(VertexHandle _vh, const Point& _p);
|
||||
/// Set the coordinate of a vertex
|
||||
void set_point(Vertex& _v, const Point& _p);
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
|
||||
/// \name Halfedge connectivity
|
||||
//@{
|
||||
/// Get the vertex the halfedge points to
|
||||
VertexHandle to_vertex_handle(HalfedgeHandle _heh) const;
|
||||
/** Get the vertex the halfedge starts from (implemented as to-handle
|
||||
of the opposite halfedge, provided for convenience) */
|
||||
VertexHandle from_vertex_handle(HalfedgeHandle _heh) const;
|
||||
/// Set the to-vertex-handle of the halfedge
|
||||
void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh);
|
||||
/** Get the face the halfedge belongs to.
|
||||
\note The handle is invalid if the halfedge is a boundary halfedge */
|
||||
FaceHandle face_handle(HalfedgeHandle _heh) const;
|
||||
/// Set the face the halfedge belongs to
|
||||
void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh);
|
||||
/// Get the next halfedge handle
|
||||
HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const;
|
||||
/** Set the next halfedge handle. \note If the previous halfedge is
|
||||
also stored (see OpenMesh::Attributes::PrevHalfedge) then this
|
||||
method also has to set this link) */
|
||||
void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh);
|
||||
/** Get the previous halfedge of the given halfedge. The
|
||||
implementation should take care of an existing
|
||||
OpenMesh::Attributes::PrevHalfedge attribute. */
|
||||
HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const;
|
||||
/// Get the opposite halfedge
|
||||
HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const;
|
||||
/// Counter-clockwise rotate the given halfedge around its from vertex
|
||||
HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const;
|
||||
/// Clockwise rotate the given halfedge around its from vertex
|
||||
HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const;
|
||||
/// Get the edge the current halfedge it contained in
|
||||
EdgeHandle edge_handle(HalfedgeHandle _heh) const;
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/// \name Edge connectivity
|
||||
//@{
|
||||
/// Get the first or second halfedge of the given edge
|
||||
HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const;
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/// \name Face connectivity
|
||||
//@{
|
||||
/// Get a halfedge belonging to the face
|
||||
HalfedgeHandle halfedge_handle(FaceHandle _fh) const;
|
||||
/// Set one halfedge of the face
|
||||
void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh);
|
||||
//@}
|
||||
|
||||
|
||||
public: // Standard Property Management
|
||||
|
||||
/// \name set/get value of a standard property
|
||||
//@{
|
||||
|
||||
// vertex
|
||||
const Point& point(VertexHandle _vh) const; ///< Get position
|
||||
void set_point(VertexHandle _vh, const Point& _p); ///< Set position
|
||||
Point& point(VertexHandle _vh); ///< Convenience function
|
||||
|
||||
const Normal& normal(VertexHandle _vh) const; ///< Get normal
|
||||
void set_normal(VertexHandle _vh, const Normal& _n); ///< Set normal
|
||||
|
||||
const Normal& normal(HalfedgeHandle _heh) const; ///< Get normal of the to vertex of the given Halfedge (per face per vertex normals)
|
||||
void set_normal(HalfedgeHandle _heh, const Normal& _n); ///< Set normal of the to vertex of the given Halfedge (per face per vertex normals)
|
||||
|
||||
const Color& color(VertexHandle _vh) const; ///< Get color
|
||||
void set_color(VertexHandle _vh, const Color& _c); ///< Set color
|
||||
|
||||
const TexCoord1D& texcoord1D(VertexHandle _vh) const; ///< Get texture coordinate.
|
||||
void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t); ///< Set texture coordinate.
|
||||
|
||||
const TexCoord2D& texcoord2D(VertexHandle _vh) const; ///< Get texture coordinate.
|
||||
void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t); ///< Set texture coordinate.
|
||||
|
||||
const TexCoord3D& texcoord3D(VertexHandle _vh) const; ///< Get texture coordinate.
|
||||
void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t); ///< Set texture coordinate.
|
||||
|
||||
const TexCoord1D& texcoord1D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords)
|
||||
void set_texcoord1D(HalfedgeHandle _hh, const TexCoord1D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords)
|
||||
|
||||
const TexCoord2D& texcoord2D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords)
|
||||
void set_texcoord2D(HalfedgeHandle _hh, const TexCoord2D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords)
|
||||
|
||||
const TexCoord3D& texcoord3D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords)
|
||||
void set_texcoord3D(HalfedgeHandle _hh, const TexCoord3D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords)
|
||||
|
||||
const StatusInfo& status(VertexHandle _vh) const; ///< Get status
|
||||
StatusInfo& status(VertexHandle _vh); ///< Get status
|
||||
|
||||
// halfedge
|
||||
const StatusInfo& status(HalfedgeHandle _vh) const; ///< Get status
|
||||
StatusInfo& status(HalfedgeHandle _vh); ///< Get status
|
||||
|
||||
const Color& color(HalfedgeHandle _heh) const; ///< Get color
|
||||
void set_color(HalfedgeHandle _heh, const Color& _c); ///< Set color
|
||||
|
||||
// edge
|
||||
const Color& color(EdgeHandle _eh) const; ///< Get color
|
||||
void set_color(EdgeHandle _eh, const Color& _c); ///< Set color
|
||||
|
||||
|
||||
const StatusInfo& status(EdgeHandle _vh) const; ///< Get status
|
||||
StatusInfo& status(EdgeHandle _vh); ///< Get status
|
||||
|
||||
// face
|
||||
const Normal& normal(FaceHandle _fh) const; ///< Get normal
|
||||
void set_normal(FaceHandle _fh, const Normal& _n); ///< Set normal
|
||||
|
||||
const Color& color(FaceHandle _fh) const; ///< Get color
|
||||
void set_color(FaceHandle _fh, const Color& _c); ///< Set color
|
||||
|
||||
const StatusInfo& status(FaceHandle _vh) const; ///< Get status
|
||||
StatusInfo& status(FaceHandle _vh); ///< Get status
|
||||
|
||||
//@}
|
||||
|
||||
/// \name Dynamically add standard properties
|
||||
//@{
|
||||
/// Request property
|
||||
void request_vertex_normals();
|
||||
void request_vertex_colors();
|
||||
void request_vertex_texcoords1D();
|
||||
void request_vertex_texcoords2D();
|
||||
void request_vertex_texcoords3D();
|
||||
void request_vertex_status();
|
||||
|
||||
void request_halfedge_status();
|
||||
void request_halfedge_normals();
|
||||
void request_halfedge_colors();
|
||||
void request_halfedge_texcoords1D();
|
||||
void request_halfedge_texcoords2D();
|
||||
void request_halfedge_texcoords3D();
|
||||
|
||||
void request_edge_status();
|
||||
void request_edge_colors();
|
||||
|
||||
void request_face_normals();
|
||||
void request_face_colors();
|
||||
void request_face_status();
|
||||
void request_face_texture_index();
|
||||
//@}
|
||||
|
||||
/// \name Remove standard properties
|
||||
//@{
|
||||
/// Remove property
|
||||
void release_vertex_normals();
|
||||
void release_vertex_colors();
|
||||
void release_vertex_texcoords1D();
|
||||
void release_vertex_texcoords2D();
|
||||
void release_vertex_texcoords3D();
|
||||
void release_vertex_status();
|
||||
|
||||
void release_halfedge_status();
|
||||
void release_halfedge_normals();
|
||||
void release_halfedge_colors();
|
||||
void release_halfedge_texcoords1D();
|
||||
void release_halfedge_texcoords2D();
|
||||
void release_halfedge_texcoords3D();
|
||||
|
||||
void release_edge_status();
|
||||
void release_edge_colors();
|
||||
|
||||
void release_face_normals();
|
||||
void release_face_colors();
|
||||
void release_face_status();
|
||||
void release_face_texture_index();
|
||||
//@}
|
||||
|
||||
/// \name Check availability of standard properties
|
||||
//@{
|
||||
/// Is property available?
|
||||
bool has_vertex_normals() const;
|
||||
bool has_vertex_colors() const;
|
||||
bool has_vertex_texcoords1D() const;
|
||||
bool has_vertex_texcoords2D() const;
|
||||
bool has_vertex_texcoords3D() const;
|
||||
bool has_vertex_status() const;
|
||||
|
||||
bool has_halfedge_status() const;
|
||||
bool has_halfedge_normals() const;
|
||||
bool has_halfedge_colors() const;
|
||||
bool has_halfedge_texcoords1D() const;
|
||||
bool has_halfedge_texcoords2D() const;
|
||||
bool has_halfedge_texcoords3D() const;
|
||||
|
||||
bool has_edge_status() const;
|
||||
bool has_edge_colors() const;
|
||||
|
||||
bool has_face_normals() const;
|
||||
bool has_face_colors() const;
|
||||
bool has_face_status() const;
|
||||
bool has_face_texture_index() const;
|
||||
//@}
|
||||
|
||||
public: // Property Management
|
||||
|
||||
/// \anchor concepts_kernelt_property_management
|
||||
|
||||
/// \name Property management - add property
|
||||
//@{
|
||||
/// Add property.
|
||||
/// @copydoc OpenMesh::BaseKernel::add_property()
|
||||
template <typename T> void add_property( [VEHFM]PropHandleT<T>& _ph,
|
||||
const std::string& _name = "" );
|
||||
//@}
|
||||
|
||||
/// \name Property management - remove property
|
||||
//@{
|
||||
/// Remove property
|
||||
template <typename T> void remove_property( [VEHFM]PropHandleT<T>& );
|
||||
//@}
|
||||
|
||||
/// \name Property management - get property by name
|
||||
//@{
|
||||
/// Get property handle by name
|
||||
template <typename T>
|
||||
bool get_property_handle( [VEHFM]PropHandleT<T>& ph, const std::string& _n ) const;
|
||||
//@}
|
||||
|
||||
/// \name Property management - get property
|
||||
//@{
|
||||
/// Get property
|
||||
template <typename T> PropertyT<T>& property( [VEHF]PropHandleT<T> _ph );
|
||||
template <typename T> const PropertyT<T>& property( [VEHF]PropHandleT<T> _ph ) const;
|
||||
template <typename T> PropertyT<T>& mproperty( MPropHandleT<T> _ph );
|
||||
template <typename T> const PropertyT<T>& mproperty( MPropHandleT<T> _ph ) const;
|
||||
//@}
|
||||
|
||||
/// \name Property management - get property value for an item
|
||||
//@{
|
||||
|
||||
/// Get value for item represented by the handle.
|
||||
template <typename T>
|
||||
T& property( VPropHandleT<T> _ph, VertexHandle _vh );
|
||||
template <typename T>
|
||||
const T& property( VPropHandleT<T> _ph, VertexHandle _vh ) const;
|
||||
|
||||
template <typename T>
|
||||
T& property( EPropHandleT<T> _ph, EdgeHandle _vh );
|
||||
template <typename T>
|
||||
const T& property( EPropHandleT<T> _ph, EdgeHandle _vh ) const;
|
||||
|
||||
template <typename T>
|
||||
T& property( HPropHandleT<T> _ph, HalfedgeHandle _vh );
|
||||
template <typename T>
|
||||
const T& property( HPropHandleT<T> _ph, HalfedgeHandle _vh ) const;
|
||||
|
||||
template <typename T>
|
||||
T& property( FPropHandleT<T> _ph, FaceHandle _vh );
|
||||
template <typename T>
|
||||
const T& property( FPropHandleT<T> _ph, FaceHandle _vh ) const;
|
||||
|
||||
template <typename T>
|
||||
T& property( MPropHandleT<T> _ph );
|
||||
template <typename T>
|
||||
const T& property( MPropHandleT<T> _ph ) const;
|
||||
|
||||
//@}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// \name Low-level adding new items
|
||||
//@{
|
||||
/** Add a new (default) vertex.
|
||||
\internal */
|
||||
VertexHandle new_vertex();
|
||||
/** Add a new vertex with a given point coordinate.
|
||||
\internal */
|
||||
VertexHandle new_vertex(const Point& _p);
|
||||
/** Add a new vertex (copied from the given one).
|
||||
\internal */
|
||||
VertexHandle new_vertex(const Vertex& _v);
|
||||
/** Add a new edge from \c _start_vertex_handle to \c _end_vertex_handle.
|
||||
This method should add an edge (i.e. two opposite halfedges) and set
|
||||
the corresponding vertex handles of these halfedges.
|
||||
\internal
|
||||
*/
|
||||
HalfedgeHandle new_edge(VertexHandle _start_vertex_handle,
|
||||
VertexHandle _end_vertex_handle);
|
||||
|
||||
/** Adding a new face
|
||||
\internal
|
||||
*/
|
||||
FaceHandle new_face();
|
||||
/** Adding a new face (copied from a \c _f).
|
||||
\internal */
|
||||
FaceHandle new_face(const Face& _f);
|
||||
//@}
|
||||
|
||||
|
||||
// --- iterators ---
|
||||
|
||||
/// \name Kernel item iterators
|
||||
//@{
|
||||
/** Kernel item iterator
|
||||
\internal */
|
||||
KernelVertexIter vertices_begin();
|
||||
KernelConstVertexIter vertices_begin() const;
|
||||
KernelVertexIter vertices_end();
|
||||
KernelConstVertexIter vertices_end() const;
|
||||
KernelEdgeIter edges_begin();
|
||||
KernelConstEdgeIter edges_begin() const;
|
||||
KernelEdgeIter edges_end();
|
||||
KernelConstEdgeIter edges_end() const;
|
||||
KernelFaceIter faces_begin();
|
||||
KernelConstFaceIter faces_begin() const;
|
||||
KernelFaceIter faces_end();
|
||||
KernelConstFaceIter faces_end() const;
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
// --- private functions ---
|
||||
|
||||
/// copy constructor: not used
|
||||
KernelT(const KernelT& _rhs);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Concepts
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
@@ -0,0 +1,22 @@
|
||||
class BaseExporter
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void update() = 0;
|
||||
|
||||
virtual PVertexIter const_vertices_begin() = 0;
|
||||
virtual PVertexIter const_vertices_end() = 0;
|
||||
|
||||
virtual PTexCoordIter const_texcoords_begin() = 0;
|
||||
virtual PTexCoordIter const_texcoords_end() = 0;
|
||||
|
||||
virtual PIdxFaceIter const_idx_faces_begin() = 0;
|
||||
virtual PIdxFaceIter const_idx_faces_end() = 0;
|
||||
|
||||
virtual PFaceIter const_set_faces_begin() = 0;
|
||||
virtual PFaceIter const_set_faces_end() = 0;
|
||||
|
||||
virtual unsigned int n_faces() = 0;
|
||||
virtual unsigned int n_vertices() = 0;
|
||||
virtual unsigned int n_texcoords() = 0;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
class BaseImporter
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void add_vertex (const OpenMesh::Vec3f&) {};
|
||||
virtual void add_normal (const OpenMesh::Vec3f&) {};
|
||||
virtual void add_texture (const OpenMesh::Vec2f&) {};
|
||||
virtual void add_face (const FaceType&) {};
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
class BaseReader
|
||||
{
|
||||
public:
|
||||
|
||||
virtual std::string get_description() const = 0;
|
||||
virtual std::string get_extensions() const = 0;
|
||||
virtual std::string get_magic() const { return std::string(""); }
|
||||
|
||||
virtual bool read(std::istream& _is, BaseImporter& _bi) const = 0;
|
||||
virtual bool read(const std::string& _filename, BaseImporter& _bi) const = 0;
|
||||
|
||||
...
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/CompositeT.hh>
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
using OpenMesh::Subdivider::Adaptive;
|
||||
|
||||
// ---------------------------------------- necessary types
|
||||
|
||||
OpenMesh::TriMesh_ArrayKernelT< CompositeTraits > MyMesh;
|
||||
CompositeT< MyMesh > Subdivider;
|
||||
|
||||
// ---------------------------------------- setup a subdivider
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh; // create mesh and fill it
|
||||
|
||||
if (!OpenMesh::IO::read_mesh(mesh, argv[1]))
|
||||
return 1; // error reading mesh
|
||||
|
||||
Subdivider subdivider(mesh); // bind subdivider to mesh
|
||||
|
||||
// -------------------- add some rules
|
||||
|
||||
// anonymous registration
|
||||
subdivider.add< Tvv3<MyMesh>::Handle >();
|
||||
subdivider.add< VF<MyMesh>::Handle >();
|
||||
subdivider.add< FF<MyMesh>::Handle >();
|
||||
|
||||
// 'named' registration
|
||||
FVc<MyMesh>::Handle hFVc;
|
||||
subdivider.add( hFVc );
|
||||
|
||||
// print pre-computed coefficients to std::cout...
|
||||
std::copy(subdivider.rule( hFVc ).coeffs().begin(),
|
||||
subdivider.rule( hFVc ).coeffs().end(),
|
||||
std::ostream_iterator<double>(std::cout, ", "));
|
||||
|
||||
// prepare subdivider and the traits
|
||||
if (!subdivider.initialize())
|
||||
return 1; // error initializing subdivider
|
||||
|
||||
MyMesh::FaceHandle fh; // select a face
|
||||
subdivider.refine(fh);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
template <class Traits>
|
||||
struct TriMesh_ArrayKernel_GeneratorT
|
||||
{
|
||||
typedef FinalMeshItemsT<ArrayItems, Traits, true> MeshItems;
|
||||
typedef AttribKernelT<MeshItems> AttribKernel;
|
||||
typedef ArrayKernelT<AttribKernel, MeshItems> MeshKernel;
|
||||
typedef TriMeshT<MeshKernel> Mesh;
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
/**************************************************
|
||||
* Vertex circulators
|
||||
**************************************************/
|
||||
|
||||
// Get the vertex-vertex circulator (1-ring) of vertex _vh
|
||||
VertexVertexIter OpenMesh::PolyConnectivity::vv_iter (VertexHandle _vh);
|
||||
|
||||
// Get the vertex-incoming halfedges circulator of vertex _vh
|
||||
VertexIHalfedgeIter OpenMesh::PolyConnectivity::vih_iter (VertexHandle _vh);
|
||||
|
||||
// Get the vertex-outgoing halfedges circulator of vertex _vh
|
||||
VertexOHalfedgeIter OpenMesh::PolyConnectivity::voh_iter (VertexHandle _vh);
|
||||
|
||||
// Get the vertex-edge circulator of vertex _vh
|
||||
VertexEdgeIter OpenMesh::PolyConnectivity::ve_iter (VertexHandle _vh);
|
||||
|
||||
// Get the vertex-face circulator of vertex _vh
|
||||
VertexFaceIter OpenMesh::PolyConnectivity::vf_iter (VertexHandle _vh);
|
||||
|
||||
/**************************************************
|
||||
* Face circulators
|
||||
**************************************************/
|
||||
|
||||
// Get the face-vertex circulator of face _fh
|
||||
FaceVertexIter OpenMesh::PolyConnectivity::fv_iter (FaceHandle _fh);
|
||||
|
||||
// Get the face-halfedge circulator of face _fh
|
||||
FaceHalfedgeIter OpenMesh::PolyConnectivity::fh_iter (FaceHandle _fh);
|
||||
|
||||
// Get the face-edge circulator of face _fh
|
||||
FaceEdgeIter OpenMesh::PolyConnectivity::fe_iter (FaceHandle _fh);
|
||||
|
||||
// Get the face-face circulator of face _fh
|
||||
FaceFaceIter OpenMesh::PolyConnectivity::ff_iter (FaceHandle _fh);
|
||||
|
||||
/**************************************************
|
||||
* Edge circulators
|
||||
**************************************************/
|
||||
|
||||
// Get the edge-vertex circulator of edge _eh
|
||||
EdgeVertexIter OpenMesh::PolyConnectivity::ev_iter (EdgeHandle _eh);
|
||||
|
||||
// Get the edge-halfedge circulator of edge _eh
|
||||
EdgeHalfedgeIter OpenMesh::PolyConnectivity::eh_iter (EdgeHandle _eh);
|
||||
|
||||
// Get the edge-face circulator of of edge _eh
|
||||
EdgeFaceIter OpenMesh::PolyConnectivity::ef_iter (EdgeHandle _eh);
|
||||
@@ -0,0 +1,11 @@
|
||||
MyMesh mesh;
|
||||
|
||||
// (linearly) iterate over all vertices
|
||||
for (MyMesh::VertexIter v_it=mesh.vertices_sbegin(); v_it!=mesh.vertices_end(); ++v_it)
|
||||
{
|
||||
// circulate around the current vertex
|
||||
for (MyMesh::VertexVertexIter vv_it=mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
|
||||
{
|
||||
// do something with e.g. mesh.point(*vv_it)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using namespace OpenMesh;
|
||||
|
||||
typedef TriMesh_ArrayKernelT<> Mesh;
|
||||
typedef Decimater::DecimaterT<Mesh> Decimater;
|
||||
typedef Decimater::ModQuadricT<Mesh>::Handle HModQuadric;
|
||||
|
||||
Mesh mesh; // a mesh object
|
||||
Decimater decimater(mesh); // a decimater object, connected to a mesh
|
||||
HModQuadric hModQuadric; // use a quadric module
|
||||
|
||||
decimater.add(hModQuadric); // register module at the decimater
|
||||
std::cout << decimater.module(hModQuadric).name() << std::endl; // module access
|
||||
|
||||
/*
|
||||
* since we need exactly one priority module (non-binary)
|
||||
* we have to call set_binary(false) for our priority module
|
||||
* in the case of HModQuadric, unset_max_err() calls set_binary(false) internally
|
||||
*/
|
||||
decimater.module(hModQuadric).unset_max_err();
|
||||
|
||||
decimater.initialize();
|
||||
decimater.decimate();
|
||||
|
||||
// after decimation: remove decimated elements from the mesh
|
||||
mesh.garbage_collection();
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <OpenMesh/Core/Utils/GenProg.hh>
|
||||
|
||||
// draw a face normal if we have one
|
||||
void drawFaceNormal(const MyMesh::Face& _f) {
|
||||
drawFaceNormal(_f, GenProg::Bool2Type<OM_Check_Attrib(MyMesh::Face, Normal)>());
|
||||
}
|
||||
|
||||
// normal exists -> use it
|
||||
void drawFaceNormal(const MyMesh::Face& _f, GenProg::Bool2Type<true>) {
|
||||
glNormal3fv(_f.normal());
|
||||
}
|
||||
|
||||
// empty dummy (no normals)
|
||||
void drawFaceNormal(const MyMesh::Face& _f, GenProg::Bool2Type<false>){}
|
||||
@@ -0,0 +1,18 @@
|
||||
MyMesh mesh;
|
||||
|
||||
// iterate over all vertices
|
||||
for (MyMesh::VertexIter v_it=mesh.vertices_begin(); v_it!=mesh.vertices_end(); ++v_it)
|
||||
...; // do something with *v_it, v_it->, or *v_it
|
||||
|
||||
// iterate over all halfedges
|
||||
for (MyMesh::HalfedgeIter h_it=mesh.halfedges_begin(); h_it!=mesh.halfedges_end(); ++h_it)
|
||||
...; // do something with *h_it, h_it->, or *h_it
|
||||
|
||||
// iterate over all edges
|
||||
for (MyMesh::EdgeIter e_it=mesh.edges_begin(); e_it!=mesh.edges_end(); ++e_it)
|
||||
...; // do something with *e_it, e_it->, or *e_it
|
||||
|
||||
// iterator over all faces
|
||||
for (MyMesh::FaceIter f_it=mesh.faces_begin(); f_it!=mesh.faces_end(); ++f_it)
|
||||
...; // do something with *f_it, f_it->, or *f_it
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
|
||||
MyMesh mesh;
|
||||
|
||||
if (!OpenMesh::IO::read_mesh(mesh, "some input file"))
|
||||
{
|
||||
std::cerr << "read error\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// do something with your mesh ...
|
||||
|
||||
if (!OpenMesh::IO::write_mesh(mesh, "some output file"))
|
||||
{
|
||||
std::cerr << "write error\n";
|
||||
exit(1);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
|
||||
// define traits
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
// use double valued coordinates
|
||||
typedef OpenMesh::Vec3d Point;
|
||||
|
||||
// use vertex normals and vertex colors
|
||||
VertexAttributes( OpenMesh::DefaultAttributer::Normal |
|
||||
OpenMesh::DefaultAttributer::Color );
|
||||
|
||||
// store the previous halfedge
|
||||
HalfedgeAttributes( OpenMesh::DefaultAttributer::PrevHalfedge );
|
||||
|
||||
// use face normals
|
||||
FaceAttributes( OpenMesh::DefaultAttributer::Normal );
|
||||
|
||||
// store a face handle for each vertex
|
||||
VertexTraits
|
||||
{
|
||||
typename Base::Refs::FaceHandle my_face_handle;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Select mesh type (TriMesh) and kernel (ArrayKernel)
|
||||
// and define my personal mesh type (MyMesh)
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
// -------------------- Add dynamic data
|
||||
|
||||
// for each vertex an extra double value
|
||||
OpenMesh::VPropHandleT< double > vprop_double;
|
||||
mesh.add_property( vprop_double );
|
||||
|
||||
// for the mesh an extra string
|
||||
OpenMesh::MPropHandleT< string > mprop_string;
|
||||
mesh.add_property( mprop_string );
|
||||
|
||||
// -------------------- do something
|
||||
|
||||
...;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
[...]
|
||||
|
||||
TriMesh::HalfedgeHandle heh, heh_init;
|
||||
|
||||
// Get the halfedge handle assigned to vertex[0]
|
||||
heh = heh_init = mesh.halfedge_handle(vertex[0].handle());
|
||||
|
||||
// heh now holds the handle to the initial halfedge.
|
||||
// We now get further on the boundary by requesting
|
||||
// the next halfedge adjacent to the vertex heh
|
||||
// points to...
|
||||
heh = mesh.next_halfedge_handle(heh);
|
||||
|
||||
// We can do this as often as we want:
|
||||
while(heh != heh_init) {
|
||||
heh = mesh.next_halfedge_handle(heh);
|
||||
}
|
||||
|
||||
[...]
|
||||
@@ -0,0 +1,13 @@
|
||||
// Test if a halfedge lies at a boundary (is not adjacent to a face)
|
||||
bool is_boundary (HalfedgeHandle _heh) const
|
||||
|
||||
// Test if an edge lies at a boundary
|
||||
bool is_boundary (EdgeHandle _eh) const
|
||||
|
||||
// Test if a vertex is adjacent to a boundary edge
|
||||
bool is_boundary (VertexHandle _vh) const
|
||||
|
||||
// Test if a face has at least one adjacent boundary edge.
|
||||
// If _check_vertex=true, this function also tests if at least one
|
||||
// of the adjacent vertices is a boundary vertex
|
||||
bool is_boundary (FaceHandle _fh, bool _check_vertex=false) const
|
||||
@@ -0,0 +1,14 @@
|
||||
[...]
|
||||
|
||||
// Get some vertex handle
|
||||
PolyMesh::VertexHandle v = ...;
|
||||
|
||||
for(PolyMesh::VertexIHalfedgeIter vih_it = mesh.vih_iter(v); vih_it; ++vih_it) {
|
||||
// Iterate over all incoming halfedges...
|
||||
}
|
||||
|
||||
for(PolyMesh::VertexOHalfedgeIter voh_it = mesh.voh_iter(v); voh_it; ++voh_it) {
|
||||
// Iterate over all outgoing halfedges...
|
||||
}
|
||||
|
||||
[...]
|
||||
@@ -0,0 +1,11 @@
|
||||
// Get the face adjacent to the opposite halfedge
|
||||
OpenMesh::PolyConnectivity::opposite_face_handle();
|
||||
|
||||
// Get the handle to the opposite halfedge
|
||||
OpenMesh::Concepts::KernelT::opposite_halfedge_handle();
|
||||
|
||||
// Get the opposite vertex to the opposite halfedge
|
||||
OpenMesh::TriConnectivity::opposite_he_opposite_vh();
|
||||
|
||||
// Get the vertex assigned to the opposite halfedge
|
||||
OpenMesh::TriConnectivity::opposite_vh();
|
||||
@@ -0,0 +1,7 @@
|
||||
// Get the halfedge handle of i.e. the halfedge
|
||||
// that is associated to the first vertex
|
||||
// of our set of vertices
|
||||
PolyMesh::HalfedgeHandle heh = mesh.halfedge_handle(*(mesh.vertices_begin()));
|
||||
|
||||
// Now get the handle of its opposing halfedge
|
||||
PolyMesh::HalfedgeHandle opposite_heh = mesh.opposite_halfedge_handle(heh);
|
||||
@@ -0,0 +1,5 @@
|
||||
// Get the handle of the to vertex
|
||||
OpenMesh::Concepts::KernelT::to_vertex_handle();
|
||||
|
||||
// Get the handle of the from vertex
|
||||
OpenMesh::Concepts::KernelT::from_vertex_handle();
|
||||
@@ -0,0 +1,17 @@
|
||||
struct DefaultTraits
|
||||
{
|
||||
typedef Vec3f Point;
|
||||
typedef Vec3f Normal;
|
||||
typedef Vec2f TexCoord;
|
||||
typedef Vec3uc Color;
|
||||
|
||||
VertexTraits {};
|
||||
HalfedgeTraits {};
|
||||
EdgeTraits {};
|
||||
FaceTraits {};
|
||||
|
||||
VertexAttributes(0);
|
||||
HalfedgeAttributes(Attributes::PrevHalfedge);
|
||||
EdgeAttributes(0);
|
||||
FaceAttributes(0);
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
typedef OpenMesh::Vec3d Point; // use double-values points
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
VertexTraits
|
||||
{
|
||||
int some_additional_index;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
template <class Base, class Refs> struct VertexT : public Base
|
||||
{
|
||||
int some_additional_index;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
VertexTraits
|
||||
{
|
||||
int some_additional_index;
|
||||
typename Base::Refs::FaceHandle my_face_handle;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
VertexAttributes( OpenMesh::Attributes::Normal |
|
||||
OpenMesh::Attributes::Color );
|
||||
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. 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. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder 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 HOLDER *
|
||||
* 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. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
#include <iostream>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<> MyMesh;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Build a simple cube and write it to std::cout
|
||||
|
||||
int main()
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
// generate vertices
|
||||
|
||||
MyMesh::VertexHandle vhandle[8];
|
||||
|
||||
vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1));
|
||||
vhandle[1] = mesh.add_vertex(MyMesh::Point( 1, -1, 1));
|
||||
vhandle[2] = mesh.add_vertex(MyMesh::Point( 1, 1, 1));
|
||||
vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1));
|
||||
vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1));
|
||||
vhandle[5] = mesh.add_vertex(MyMesh::Point( 1, -1, -1));
|
||||
vhandle[6] = mesh.add_vertex(MyMesh::Point( 1, 1, -1));
|
||||
vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1));
|
||||
|
||||
|
||||
// generate (quadrilateral) faces
|
||||
|
||||
std::vector<MyMesh::VertexHandle> face_vhandles;
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
|
||||
// write mesh to output.obj
|
||||
try
|
||||
{
|
||||
if ( !OpenMesh::IO::write_mesh(mesh, "output.off") )
|
||||
{
|
||||
std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch( std::exception& x )
|
||||
{
|
||||
std::cerr << x.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
|
||||
// check command line options
|
||||
if (argc != 4)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read mesh from stdin
|
||||
if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) )
|
||||
{
|
||||
std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// this vector stores the computed centers of gravity
|
||||
std::vector<MyMesh::Point> cogs;
|
||||
std::vector<MyMesh::Point>::iterator cog_it;
|
||||
cogs.reserve(mesh.n_vertices());
|
||||
|
||||
|
||||
// smoothing mesh argv[1] times
|
||||
MyMesh::VertexIter v_it, v_end(mesh.vertices_end());
|
||||
MyMesh::VertexVertexIter vv_it;
|
||||
MyMesh::Point cog;
|
||||
MyMesh::Scalar valence;
|
||||
unsigned int i, N(atoi(argv[1]));
|
||||
|
||||
|
||||
for (i=0; i < N; ++i)
|
||||
{
|
||||
cogs.clear();
|
||||
for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
cog[0] = cog[1] = cog[2] = valence = 0.0;
|
||||
|
||||
for (vv_it=mesh.vv_iter( *v_it ); vv_it.is_valid(); ++vv_it)
|
||||
{
|
||||
cog += mesh.point( *vv_it );
|
||||
++valence;
|
||||
}
|
||||
|
||||
cogs.push_back(cog / valence);
|
||||
}
|
||||
|
||||
for (v_it=mesh.vertices_begin(), cog_it=cogs.begin();
|
||||
v_it!=v_end; ++v_it, ++cog_it)
|
||||
if ( !mesh.is_boundary( *v_it ) )
|
||||
mesh.set_point( *v_it, *cog_it );
|
||||
}
|
||||
|
||||
|
||||
// write mesh to stdout
|
||||
if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) )
|
||||
{
|
||||
std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/DefaultTriMesh.hh>
|
||||
#include <OpenMesh/Core/Utils/PropertyManager.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using MyMesh = OpenMesh::TriMesh;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Read command line options
|
||||
MyMesh mesh;
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const int iterations = argv[1];
|
||||
const std::string infile = argv[2];
|
||||
const std::string outfile = argv[3];
|
||||
|
||||
// Read mesh file
|
||||
if (!OpenMesh::IO::read_mesh(mesh, infile)) {
|
||||
std::cerr << "Error: Cannot read mesh from " << infile << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
// Add a vertex property storing the computed centers of gravity
|
||||
auto cog = OpenMesh::VProp<MyMesh::Point>(mesh);
|
||||
|
||||
// Smooth the mesh several times
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
// Iterate over all vertices to compute centers of gravity
|
||||
for (const auto& vh : mesh.vertices()) {
|
||||
cog[vh] = {0,0,0};
|
||||
int valence = 0;
|
||||
// Iterate over all 1-ring vertices around vh
|
||||
for (const auto& vvh : mesh.vv_range(vh)) {
|
||||
cog[vh] += mesh.point(vvh);
|
||||
++valence;
|
||||
}
|
||||
cog[vh] /= valence;
|
||||
}
|
||||
// Move all vertices to the previously computed positions
|
||||
for (const auto& vh : mesh.vertices()) {
|
||||
mesh.point(vh) = cog[vh];
|
||||
}
|
||||
}
|
||||
} // The cog vertex property is removed from the mesh at the end of this scope
|
||||
|
||||
// Write mesh file
|
||||
if (!OpenMesh::IO::read_mesh(mesh, outfile)) {
|
||||
std::cerr << "Error: Cannot write mesh to " << outfile << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
// --------------------
|
||||
#include "smooth_algo.hh"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
|
||||
// check command line options
|
||||
if (argc != 4)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read mesh from stdin
|
||||
if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) )
|
||||
{
|
||||
std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// smoothing mesh argv[1] times
|
||||
SmootherT<MyMesh> smoother(mesh);
|
||||
smoother.smooth(atoi(argv[1]));
|
||||
|
||||
|
||||
// write mesh to stdout
|
||||
if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) )
|
||||
{
|
||||
std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#include <algorithm>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
template <class Mesh> class SmootherT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Mesh::Point cog_t;
|
||||
typedef OpenMesh::VPropHandleT< cog_t > Property_cog;
|
||||
|
||||
public:
|
||||
|
||||
// construct with a given mesh
|
||||
explicit SmootherT(Mesh& _mesh)
|
||||
: mesh_(_mesh)
|
||||
{
|
||||
mesh_.add_property( cog_ );
|
||||
}
|
||||
|
||||
~SmootherT()
|
||||
{
|
||||
mesh_.remove_property( cog_ );
|
||||
}
|
||||
|
||||
// smooth mesh _iterations times
|
||||
void smooth(unsigned int _iterations)
|
||||
{
|
||||
for (unsigned int i=0; i < _iterations; ++i)
|
||||
{
|
||||
std::for_each(mesh_.vertices_begin(),
|
||||
mesh_.vertices_end(),
|
||||
ComputeCOG(mesh_, cog_));
|
||||
|
||||
std::for_each(mesh_.vertices_begin(),
|
||||
mesh_.vertices_end(),
|
||||
SetCOG(mesh_, cog_));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//--- private classes ---
|
||||
|
||||
class ComputeCOG
|
||||
{
|
||||
public:
|
||||
ComputeCOG(Mesh& _mesh, Property_cog& _cog)
|
||||
: mesh_(_mesh), cog_(_cog)
|
||||
{}
|
||||
|
||||
void operator()(const typename Mesh::VertexHandle& _vh)
|
||||
{
|
||||
typename Mesh::VertexVertexIter vv_it;
|
||||
typename Mesh::Scalar valence(0.0);
|
||||
|
||||
mesh_.property(cog_, _vh) = typename Mesh::Point(0.0, 0.0, 0.0);
|
||||
|
||||
for (vv_it=mesh_.vv_iter(_vh); vv_it.is_valid(); ++vv_it)
|
||||
{
|
||||
mesh_.property(cog_, _vh) += mesh_.point( *vv_it );
|
||||
++valence;
|
||||
}
|
||||
|
||||
mesh_.property(cog_, _vh ) /= valence;
|
||||
}
|
||||
|
||||
private:
|
||||
Mesh& mesh_;
|
||||
Property_cog& cog_;
|
||||
};
|
||||
|
||||
|
||||
class SetCOG
|
||||
{
|
||||
public:
|
||||
SetCOG(Mesh& _mesh, Property_cog& _cog)
|
||||
: mesh_(_mesh), cog_(_cog)
|
||||
{}
|
||||
|
||||
void operator()(const typename Mesh::VertexHandle& _vh)
|
||||
{
|
||||
|
||||
if (!mesh_.is_boundary(_vh))
|
||||
mesh_.set_point( _vh, mesh_.property(cog_, _vh) );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Mesh& mesh_;
|
||||
Property_cog& cog_;
|
||||
};
|
||||
|
||||
|
||||
//--- private elements ---
|
||||
|
||||
Mesh& mesh_;
|
||||
Property_cog cog_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <iostream>
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
if (argc!=2)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <input>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// request vertex normals, so the mesh reader can use normal information
|
||||
// if available
|
||||
mesh.request_vertex_normals();
|
||||
|
||||
// assure we have vertex normals
|
||||
if (!mesh.has_vertex_normals())
|
||||
{
|
||||
std::cerr << "ERROR: Standard vertex property 'Normals' not available!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
OpenMesh::IO::Options opt;
|
||||
if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt))
|
||||
{
|
||||
std::cerr << "Error loading mesh from file " << argv[1] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If the file did not provide vertex normals, then calculate them
|
||||
if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) )
|
||||
{
|
||||
// we need face normals to update the vertex normals
|
||||
mesh.request_face_normals();
|
||||
|
||||
// let the mesh update the normals
|
||||
mesh.update_normals();
|
||||
|
||||
// dispose the face normals, as we don't need them anymore
|
||||
mesh.release_face_normals();
|
||||
}
|
||||
|
||||
// move all vertices one unit length along it's normal direction
|
||||
for (MyMesh::VertexIter v_it = mesh.vertices_begin();
|
||||
v_it != mesh.vertices_end(); ++v_it)
|
||||
{
|
||||
std::cout << "Vertex #" << *v_it << ": " << mesh.point( *v_it );
|
||||
mesh.set_point( *v_it, mesh.point(*v_it)+mesh.normal(*v_it) );
|
||||
std::cout << " moved to " << mesh.point( *v_it ) << std::endl;
|
||||
}
|
||||
|
||||
// don't need the normals anymore? Remove them!
|
||||
mesh.release_vertex_normals();
|
||||
|
||||
// just check if it really works
|
||||
if (mesh.has_vertex_normals())
|
||||
{
|
||||
std::cerr << "Ouch! ERROR! Shouldn't have any vertex normals anymore!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Core/Geometry/VectorT.hh>
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
// Define my personal traits
|
||||
struct MyTraits : OpenMesh::DefaultTraits
|
||||
{
|
||||
// Let Point and Normal be a vector of doubles
|
||||
typedef OpenMesh::Vec3d Point;
|
||||
typedef OpenMesh::Vec3d Normal;
|
||||
|
||||
// Already defined in OpenMesh::DefaultTraits
|
||||
// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
// Uncomment next line to disable attribute PrevHalfedge
|
||||
// HalfedgeAttributes( OpenMesh::Attributes::None );
|
||||
//
|
||||
// or
|
||||
//
|
||||
// HalfedgeAttributes( 0 );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Define my mesh with the new traits!
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
|
||||
|
||||
// ------------------------------------------------------------------ main ----
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
if (argc!=2)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <input>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Just make sure that point element type is double
|
||||
if ( typeid( OpenMesh::vector_traits<MyMesh::Point>::value_type )
|
||||
!= typeid(double) )
|
||||
{
|
||||
std::cerr << "Ouch! ERROR! Data type is wrong!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure that normal element type is double
|
||||
if ( typeid( OpenMesh::vector_traits<MyMesh::Normal>::value_type )
|
||||
!= typeid(double) )
|
||||
{
|
||||
std::cerr << "Ouch! ERROR! Data type is wrong!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Add vertex normals as default property (ref. previous tutorial)
|
||||
mesh.request_vertex_normals();
|
||||
|
||||
// Add face normals as default property
|
||||
mesh.request_face_normals();
|
||||
|
||||
// load a mesh
|
||||
OpenMesh::IO::Options opt;
|
||||
if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt))
|
||||
{
|
||||
std::cerr << "Error loading mesh from file " << argv[1] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If the file did not provide vertex normals, then calculate them
|
||||
if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) &&
|
||||
mesh.has_face_normals() && mesh.has_vertex_normals() )
|
||||
{
|
||||
// let the mesh update the normals
|
||||
mesh.update_normals();
|
||||
}
|
||||
|
||||
// move all vertices one unit length along it's normal direction
|
||||
for (MyMesh::VertexIter v_it = mesh.vertices_begin();
|
||||
v_it != mesh.vertices_end(); ++v_it)
|
||||
{
|
||||
std::cout << "Vertex #" << *v_it << ": " << mesh.point( *v_it );
|
||||
mesh.set_point( *v_it, mesh.point(*v_it)+mesh.normal(*v_it) );
|
||||
std::cout << " moved to " << mesh.point( *v_it ) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
// store barycenter of neighbors in this member
|
||||
VertexTraits
|
||||
{
|
||||
private:
|
||||
Point cog_;
|
||||
public:
|
||||
|
||||
VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { }
|
||||
|
||||
const Point& cog() const { return cog_; }
|
||||
void set_cog(const Point& _p) { cog_ = _p; }
|
||||
};
|
||||
};
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh2;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
#define SIZEOF( entity,b ) \
|
||||
std::cout << _prefix << "size of " << #entity << ": " \
|
||||
<< sizeof( entity ) << std::endl; \
|
||||
b += sizeof( entity )
|
||||
|
||||
template <typename Mesh>
|
||||
void print_size(const std::string& _prefix = "")
|
||||
{
|
||||
size_t total=0;
|
||||
SIZEOF(typename Mesh::Vertex, total);
|
||||
SIZEOF(typename Mesh::Halfedge, total);
|
||||
SIZEOF(typename Mesh::Edge, total);
|
||||
SIZEOF(typename Mesh::Face, total);
|
||||
std::cout << _prefix << "total: " << total << std::endl;
|
||||
}
|
||||
|
||||
#undef SIZEOF
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
// check command line options
|
||||
if (argc < 4 || argc > 5)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " [-s] #iterations infile outfile\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int idx=2;
|
||||
|
||||
// display size of entities of the enhanced and the default mesh type
|
||||
// when commandline option '-s' has been used.
|
||||
if (argc == 5)
|
||||
{
|
||||
if (std::string("-s")==argv[idx-1])
|
||||
{
|
||||
std::cout << "Enhanced mesh size statistics\n";
|
||||
print_size<MyMesh>(" ");
|
||||
|
||||
std::cout << "Default mesh size statistics\n";
|
||||
print_size<MyMesh2>(" ");
|
||||
}
|
||||
// else ignore!
|
||||
++idx;
|
||||
}
|
||||
|
||||
|
||||
// read mesh from stdin
|
||||
std::cout<< " Input mesh: " << argv[idx] << std::endl;
|
||||
if ( ! OpenMesh::IO::read_mesh(mesh, argv[idx]) )
|
||||
{
|
||||
std::cerr << "Error: Cannot read mesh from " << argv[idx] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// smoothing mesh argv[1] times
|
||||
MyMesh::VertexIter v_it, v_end(mesh.vertices_end());
|
||||
MyMesh::VertexVertexIter vv_it;
|
||||
MyMesh::Point cog;
|
||||
MyMesh::Scalar valence;
|
||||
unsigned int i, N(atoi(argv[idx-1]));
|
||||
|
||||
std::cout<< "Smooth mesh " << N << " times\n";
|
||||
|
||||
for (i=0; i < N; ++i)
|
||||
{
|
||||
for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
cog[0] = cog[1] = cog[2] = valence = 0.0;
|
||||
|
||||
for (vv_it=mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
|
||||
{
|
||||
cog += mesh.point( *vv_it );
|
||||
++valence;
|
||||
}
|
||||
|
||||
mesh.data(*v_it).set_cog(cog / valence);
|
||||
}
|
||||
|
||||
for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
if (!mesh.is_boundary(*v_it))
|
||||
mesh.set_point( *v_it, mesh.data(*v_it).cog());
|
||||
}
|
||||
|
||||
|
||||
// write mesh to stdout
|
||||
std::cout<< "Output mesh: " << argv[idx+1] << std::endl;
|
||||
|
||||
if ( ! OpenMesh::IO::write_mesh(mesh, argv[idx+1]) )
|
||||
{
|
||||
std::cerr << "Error: cannot write mesh to " << argv[idx+1] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. 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. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder 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 HOLDER *
|
||||
* 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. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
#include <iostream>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Mesh/Status.hh>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct MyTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<MyTraits> MyMesh;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Build a simple cube and delete it except one face
|
||||
|
||||
int main()
|
||||
{
|
||||
MyMesh mesh;
|
||||
|
||||
// the request has to be called before a vertex/face/edge can be deleted. it grants access to the status attribute
|
||||
mesh.request_face_status();
|
||||
mesh.request_edge_status();
|
||||
mesh.request_vertex_status();
|
||||
|
||||
// generate vertices
|
||||
|
||||
MyMesh::VertexHandle vhandle[8];
|
||||
MyMesh::FaceHandle fhandle[6];
|
||||
|
||||
vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1));
|
||||
vhandle[1] = mesh.add_vertex(MyMesh::Point( 1, -1, 1));
|
||||
vhandle[2] = mesh.add_vertex(MyMesh::Point( 1, 1, 1));
|
||||
vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1));
|
||||
vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1));
|
||||
vhandle[5] = mesh.add_vertex(MyMesh::Point( 1, -1, -1));
|
||||
vhandle[6] = mesh.add_vertex(MyMesh::Point( 1, 1, -1));
|
||||
vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1));
|
||||
|
||||
|
||||
// generate (quadrilateral) faces
|
||||
|
||||
std::vector<MyMesh::VertexHandle> tmp_face_vhandles;
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[0]);
|
||||
tmp_face_vhandles.push_back(vhandle[1]);
|
||||
tmp_face_vhandles.push_back(vhandle[2]);
|
||||
tmp_face_vhandles.push_back(vhandle[3]);
|
||||
fhandle[0] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[7]);
|
||||
tmp_face_vhandles.push_back(vhandle[6]);
|
||||
tmp_face_vhandles.push_back(vhandle[5]);
|
||||
tmp_face_vhandles.push_back(vhandle[4]);
|
||||
fhandle[1] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[1]);
|
||||
tmp_face_vhandles.push_back(vhandle[0]);
|
||||
tmp_face_vhandles.push_back(vhandle[4]);
|
||||
tmp_face_vhandles.push_back(vhandle[5]);
|
||||
fhandle[2] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[2]);
|
||||
tmp_face_vhandles.push_back(vhandle[1]);
|
||||
tmp_face_vhandles.push_back(vhandle[5]);
|
||||
tmp_face_vhandles.push_back(vhandle[6]);
|
||||
fhandle[3] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[3]);
|
||||
tmp_face_vhandles.push_back(vhandle[2]);
|
||||
tmp_face_vhandles.push_back(vhandle[6]);
|
||||
tmp_face_vhandles.push_back(vhandle[7]);
|
||||
fhandle[4] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
|
||||
tmp_face_vhandles.clear();
|
||||
tmp_face_vhandles.push_back(vhandle[0]);
|
||||
tmp_face_vhandles.push_back(vhandle[3]);
|
||||
tmp_face_vhandles.push_back(vhandle[7]);
|
||||
tmp_face_vhandles.push_back(vhandle[4]);
|
||||
fhandle[5] = mesh.add_face(tmp_face_vhandles);
|
||||
|
||||
// And now delete all faces and vertices
|
||||
// except face (vh[7], vh[6], vh[5], vh[4])
|
||||
// whose handle resides in fhandle[1]
|
||||
|
||||
|
||||
// Delete face 0
|
||||
mesh.delete_face(fhandle[0], false);
|
||||
// ... face 2
|
||||
mesh.delete_face(fhandle[2], false);
|
||||
// ... face 3
|
||||
mesh.delete_face(fhandle[3], false);
|
||||
// ... face 4
|
||||
mesh.delete_face(fhandle[4], false);
|
||||
// ... face 5
|
||||
mesh.delete_face(fhandle[5], false);
|
||||
|
||||
|
||||
// If isolated vertices result in a face deletion
|
||||
// they have to be deleted manually. If you want this
|
||||
// to happen automatically, change the second parameter
|
||||
// to true.
|
||||
|
||||
// Now delete the isolated vertices 0, 1, 2 and 3
|
||||
mesh.delete_vertex(vhandle[0], false);
|
||||
mesh.delete_vertex(vhandle[1], false);
|
||||
mesh.delete_vertex(vhandle[2], false);
|
||||
mesh.delete_vertex(vhandle[3], false);
|
||||
|
||||
// Delete all elements that are marked as deleted
|
||||
// from memory.
|
||||
mesh.garbage_collection();
|
||||
|
||||
// write mesh to output.obj
|
||||
try {
|
||||
if ( !OpenMesh::IO::write_mesh(mesh, "output.off") ) {
|
||||
std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch( std::exception& x )
|
||||
{
|
||||
std::cerr << x.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Tools/Utils/getopt.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace OpenMesh;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef TriMesh_ArrayKernelT<> MyMesh;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define CHKROPT( Option ) \
|
||||
std::cout << " provides " << #Option \
|
||||
<< (ropt.check(IO::Options:: Option)?": yes\n":": no\n")
|
||||
|
||||
#define CHKWOPT( Option ) \
|
||||
std::cout << " write " << #Option \
|
||||
<< (wopt.check(IO::Options:: Option)?": yes\n":": no\n")
|
||||
|
||||
#define MESHOPT( msg, tf ) \
|
||||
std::cout << " " << msg << ": " << ((tf)?"yes\n":"no\n")
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
|
||||
IO::Options &ropt, IO::Options &wopt );
|
||||
|
||||
void usage_and_exit(int xcode);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MyMesh mesh;
|
||||
IO::Options ropt, wopt;
|
||||
|
||||
// -------------------- evaluate commandline
|
||||
|
||||
parse_commandline( argc, argv, mesh, ropt, wopt );
|
||||
|
||||
// -------------------- read mesh
|
||||
|
||||
if ( ! IO::read_mesh(mesh,argv[optind], ropt))
|
||||
{
|
||||
std::cerr << "Error loading mesh from file " << argv[optind] << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -------------------- show options
|
||||
|
||||
std::cout << "File " << argv[optind] << std::endl;
|
||||
|
||||
std::cout << " is binary: "
|
||||
<< (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n");
|
||||
|
||||
std::cout << " byte order: ";
|
||||
if (ropt.check(IO::Options::Swap))
|
||||
std::cout << "swapped\n";
|
||||
else if (ropt.check(IO::Options::LSB))
|
||||
std::cout << "little endian\n";
|
||||
else if (ropt.check(IO::Options::MSB))
|
||||
std::cout << "big endian\n";
|
||||
else
|
||||
std::cout << "don't care\n";
|
||||
|
||||
std::cout << " provides VertexNormal"
|
||||
<< ( // strange layout for doxygen
|
||||
ropt.check(IO::Options::VertexNormal)
|
||||
? ": yes\n":": no\n");
|
||||
CHKROPT( VertexColor );
|
||||
CHKROPT( VertexTexCoord );
|
||||
CHKROPT( FaceNormal );
|
||||
CHKROPT( FaceColor );
|
||||
|
||||
|
||||
// -------------------- mesh stats
|
||||
|
||||
std::cout << "# Vertices: " << mesh.n_vertices() << std::endl;
|
||||
std::cout << "# Edges : " << mesh.n_faces() << std::endl;
|
||||
std::cout << "# Faces : " << mesh.n_faces() << std::endl;
|
||||
|
||||
|
||||
// -------------------- show write options
|
||||
|
||||
std::cout << "Selected write options:\n";
|
||||
std::cout << " use binary: "
|
||||
<< (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n");
|
||||
|
||||
std::cout << " byte order: ";
|
||||
if (wopt.check(IO::Options::Swap))
|
||||
std::cout << "swapped\n";
|
||||
else if (wopt.check(IO::Options::LSB))
|
||||
std::cout << "little endian\n";
|
||||
else if (wopt.check(IO::Options::MSB))
|
||||
std::cout << "big endian\n";
|
||||
else
|
||||
std::cout << "don't care\n";
|
||||
|
||||
std::cout << " write VertexNormal"
|
||||
<< (wopt.check(IO::Options::VertexNormal) ? ": yes\n":": no\n");
|
||||
CHKWOPT( VertexColor );
|
||||
CHKWOPT( VertexTexCoord );
|
||||
CHKWOPT( FaceNormal );
|
||||
CHKWOPT( FaceColor );
|
||||
|
||||
// -------------------- show mesh capabilities
|
||||
|
||||
std::cout << "Mesh supports\n";
|
||||
MESHOPT("vertex normals", mesh.has_vertex_normals());
|
||||
MESHOPT("vertex colors", mesh.has_vertex_colors());
|
||||
MESHOPT("texcoords", mesh.has_vertex_texcoords2D());
|
||||
MESHOPT("face normals", mesh.has_face_normals());
|
||||
MESHOPT("face colors", mesh.has_face_colors());
|
||||
|
||||
// -------------------- write mesh
|
||||
|
||||
std::cout << "Write mesh to " << argv[optind+1] << "..";
|
||||
if ( !IO::write_mesh( mesh, argv[optind+1], wopt ) )
|
||||
{
|
||||
std::cerr << "Error" << std::endl;
|
||||
std::cerr << "Possible reasons:\n";
|
||||
std::cerr << "1. Chosen format cannot handle an option!\n";
|
||||
std::cerr << "2. Mesh does not provide necessary information!\n";
|
||||
std::cerr << "3. Or simply cannot open file for writing!\n";
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
std::cout << "Ok.\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
|
||||
IO::Options &ropt, IO::Options &wopt )
|
||||
{
|
||||
int c;
|
||||
while ((c=getopt(_argc, _argv, "bhsBF:LMSV:X:"))!=-1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
// -------------------- read options
|
||||
|
||||
// force binary input
|
||||
case 'b':
|
||||
ropt += IO::Options::Binary;
|
||||
break;
|
||||
|
||||
// force swapping the byte order, when reading a binary file
|
||||
case 's':
|
||||
ropt += IO::Options::Swap;
|
||||
break;
|
||||
|
||||
// -------------------- write options
|
||||
|
||||
// Write binary variant of format if possible
|
||||
case 'B':
|
||||
wopt += IO::Options::Binary;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'F':
|
||||
for(size_t i=0; optarg[i]; ++i)
|
||||
switch(optarg[i]) {
|
||||
case 'n' : wopt += IO::Options::FaceNormal; break;
|
||||
case 'c' : wopt += IO::Options::FaceColor; break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Use little endian when writing binary data
|
||||
case 'L':
|
||||
wopt += IO::Options::LSB;
|
||||
break;
|
||||
|
||||
// Use big endian when writing binary data
|
||||
case 'M':
|
||||
wopt += IO::Options::MSB;
|
||||
break;
|
||||
|
||||
// Swap byte order when writing binary data
|
||||
case 'S':
|
||||
wopt += IO::Options::Swap;
|
||||
break;
|
||||
|
||||
//
|
||||
case 'V':
|
||||
{
|
||||
for(size_t i=0; optarg[i]; ++i)
|
||||
switch(optarg[i]) {
|
||||
case 'n' : // dont't change layout!!
|
||||
wopt += IO::Options::VertexNormal;
|
||||
break;
|
||||
case 't' : wopt += IO::Options::VertexTexCoord; break;
|
||||
case 'c' : wopt += IO::Options::VertexColor; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// -------------------- request mesh' standard properties
|
||||
case 'X':
|
||||
{
|
||||
char entity='\0';
|
||||
for(size_t i=0; optarg[i]; ++i)
|
||||
switch(optarg[i]) {
|
||||
case 'v':
|
||||
case 'f': entity = optarg[i]; break;
|
||||
case 'n':
|
||||
switch(entity) {
|
||||
case 'v': _mesh.request_vertex_normals(); break;
|
||||
case 'f': _mesh.request_face_normals(); break;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
switch(entity) {
|
||||
case 'v': _mesh.request_vertex_colors(); break;
|
||||
case 'f': _mesh.request_face_colors(); break;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
switch(entity) {
|
||||
case 'v': _mesh.request_vertex_texcoords2D(); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// -------------------- help
|
||||
case 'h':
|
||||
usage_and_exit(0);
|
||||
default:
|
||||
usage_and_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( _argc-optind != 2)
|
||||
usage_and_exit(1);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void usage_and_exit(int xcode)
|
||||
{
|
||||
std::ostream &os = xcode ? std::cerr : std::cout;
|
||||
|
||||
os << "Usage: io_options [Options] <input> <output>\n"
|
||||
<< std::endl;
|
||||
os << " Read and write a mesh, using OpenMesh::IO::Options\n"
|
||||
<< std::endl;
|
||||
os << "Options:\n"
|
||||
<< std::endl;
|
||||
os << "a) read options\n"
|
||||
<< std::endl
|
||||
<< " -b\n"
|
||||
<< "\tAssume input file is a binary file\n"
|
||||
<< std::endl
|
||||
<< " -s\n"
|
||||
<< "\tSwap byte order when reading a binary file!\n"
|
||||
<< std::endl;
|
||||
os << "b) write options\n"
|
||||
<< std::endl
|
||||
<< " -B\n"
|
||||
<< "\tWrite binary data\n"
|
||||
<< std::endl
|
||||
<< " -S\n"
|
||||
<< "\tSwap byte order, when writing binary data\n"
|
||||
<< std::endl
|
||||
<< " -M/-L\n"
|
||||
<< "\tUse MSB/LSB byte ordering, when writing binary data\n"
|
||||
<< std::endl
|
||||
<< " -V{n|t|c}\n"
|
||||
<< "\tWrite vertex normals, texcoords, and/or colors\n"
|
||||
<< std::endl
|
||||
<< " -F{n|c}\n"
|
||||
<< "\tWrite face normals, and/or colors\n"
|
||||
<< std::endl;
|
||||
os << "c) Mesh properties\n"
|
||||
<< std::endl
|
||||
<< " -Xv{n|c|t}\n"
|
||||
<< "\tRequest vertex property normals|colors|texcoords\n"
|
||||
<< std::endl
|
||||
<< " -Xf{n|c}\n"
|
||||
<< "\tRequest face property normals|colors\n"
|
||||
<< std::endl;
|
||||
exit(xcode);
|
||||
}
|
||||
|
||||
// end of file
|
||||
// ============================================================================
|
||||
@@ -0,0 +1,119 @@
|
||||
#ifndef FILL_PROPS_HH
|
||||
#define FILL_PROPS_HH
|
||||
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
#include "int2roman.hh"
|
||||
|
||||
|
||||
template <typename Mesh>
|
||||
bool
|
||||
fill_props( Mesh& _m, OpenMesh::VPropHandleT<float> _ph, bool _check=false)
|
||||
{
|
||||
static float a[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f };
|
||||
|
||||
for(typename Mesh::VertexIter it=_m.vertices_begin();
|
||||
it != _m.vertices_end(); ++it)
|
||||
{
|
||||
const float v = a[it->idx()%9];
|
||||
if ( _check && !(_m.property( _ph, *it ) == v) )
|
||||
return false;
|
||||
else
|
||||
_m.property( _ph, *it ) = v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename Mesh>
|
||||
bool
|
||||
fill_props( Mesh& _m, OpenMesh::EPropHandleT<bool> _ph, bool _check=false )
|
||||
{
|
||||
|
||||
for( typename Mesh::EdgeIter it=_m.edges_begin();
|
||||
it != _m.edges_end(); ++it)
|
||||
{
|
||||
const size_t n = it->idx();
|
||||
const bool v = ((n&(n-1))==0); // true for 0,1,2,4,8,..
|
||||
|
||||
if (_check && _m.property( _ph, *it ) != v)
|
||||
{
|
||||
std::cout << " eprop_bool: " << n << " -> "
|
||||
<< _m.property(_ph, *it ) << " != " << v << std::endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_m.property( _ph, *it ) = v;
|
||||
std::cout << " eprop_bool: " << n << " -> " << v << std::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Mesh>
|
||||
bool
|
||||
fill_props(Mesh& _m, OpenMesh::FPropHandleT<std::string> _ph, bool _check=false)
|
||||
{
|
||||
|
||||
for( typename Mesh::FaceIter it=_m.faces_begin();
|
||||
it != _m.faces_end(); ++it)
|
||||
{
|
||||
const int n = (it->idx()) + 1;
|
||||
_m.property( _ph, *it ) = int2roman(n);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename Mesh, typename T>
|
||||
bool
|
||||
fill_props( Mesh& _m, OpenMesh::HPropHandleT<T> _ph, bool _check=false)
|
||||
{
|
||||
T v;
|
||||
static float a[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f };
|
||||
static float b[9] = { 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f };
|
||||
static float c[9] = { 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f, 2.2f };
|
||||
static float d[9] = { 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f, 2.2f, 3.3f };
|
||||
static double values[9] = { 0.1, 0.02, 0.003, 0.0004, 0.00005, 0.000006,
|
||||
0.0000007, 0.00000008, 0.000000009 };
|
||||
|
||||
for( typename Mesh::HalfedgeIter it=_m.halfedges_begin();
|
||||
it != _m.halfedges_end(); ++it)
|
||||
{
|
||||
const int n = it->idx();
|
||||
|
||||
v = it->idx()+1; // ival
|
||||
v = values[n%9]; // dval
|
||||
v = ((n&(n-1))==0); // bval
|
||||
v.vec4fval[0] = a[n%9];
|
||||
v.vec4fval[1] = b[n%9];
|
||||
v.vec4fval[2] = c[n%9];
|
||||
v.vec4fval[3] = d[n%9];
|
||||
|
||||
if ( _check && _m.property( _ph, *it ) != v )
|
||||
return false;
|
||||
else
|
||||
_m.property( _ph, *it ) = v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Mesh, typename T>
|
||||
bool
|
||||
fill_props( Mesh& _m, OpenMesh::MPropHandleT<T> _ph, bool _check=false)
|
||||
{
|
||||
for( typename Mesh::FaceIter it=_m.faces_begin(); it != _m.faces_end(); ++it)
|
||||
{
|
||||
const size_t idx = it->idx();
|
||||
if ( _check && _m.property( _ph )[int2roman(idx+1)] != idx )
|
||||
return false;
|
||||
else
|
||||
_m.property( _ph )[int2roman(idx+1)] = idx;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef GENERATE_CUBE_HH
|
||||
#define GENERATE_CUBE_HH
|
||||
|
||||
template <typename MeshType>
|
||||
size_t generate_cube( MeshType& mesh )
|
||||
{
|
||||
typedef typename MeshType::VertexHandle VertexHandle;
|
||||
typedef typename MeshType::Point Point;
|
||||
|
||||
typename MeshType::VertexHandle vhandle[8];
|
||||
|
||||
vhandle[0] = mesh.add_vertex(Point(-1, -1, 1));
|
||||
vhandle[1] = mesh.add_vertex(Point( 1, -1, 1));
|
||||
vhandle[2] = mesh.add_vertex(Point( 1, 1, 1));
|
||||
vhandle[3] = mesh.add_vertex(Point(-1, 1, 1));
|
||||
vhandle[4] = mesh.add_vertex(Point(-1, -1, -1));
|
||||
vhandle[5] = mesh.add_vertex(Point( 1, -1, -1));
|
||||
vhandle[6] = mesh.add_vertex(Point( 1, 1, -1));
|
||||
vhandle[7] = mesh.add_vertex(Point(-1, 1, -1));
|
||||
|
||||
// generate (quadrilateral) faces
|
||||
|
||||
std::vector< VertexHandle > face_vhandles;
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[7]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
return mesh.n_vertices();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <assert.h>
|
||||
#else
|
||||
# include <cassert>
|
||||
#endif
|
||||
#include "int2roman.hh"
|
||||
|
||||
|
||||
std::string int2roman( size_t decimal, size_t length )
|
||||
{
|
||||
assert( decimal > 0 && decimal < 1000 );
|
||||
|
||||
const size_t nrows = 4;
|
||||
const size_t ncols = 4;
|
||||
|
||||
static size_t table_arabs[ nrows ][ ncols ] = { { 1000, 1000, 1000, 1000 },
|
||||
{ 900, 500, 400, 100 },
|
||||
{ 90, 50, 40, 10 },
|
||||
{ 9, 5, 4, 1 } };
|
||||
|
||||
static char *table_romans[ nrows ][ ncols ] = { { "M", "M", "M", "M" },
|
||||
{ "CM", "D", "CD", "C" },
|
||||
{ "XC", "L", "XL", "X" },
|
||||
{ "IX", "V", "IV", "I" } };
|
||||
|
||||
size_t power; // power of ten
|
||||
size_t index; // Indexes thru values to subtract
|
||||
|
||||
std::string roman = "";
|
||||
roman.reserve(length);
|
||||
|
||||
for ( power = 0; power < nrows; power++ )
|
||||
for ( index = 0; index < ncols; index++ )
|
||||
while ( decimal >= table_arabs[ power ][ index ] )
|
||||
{
|
||||
roman += table_romans[ power ][ index ];
|
||||
decimal -= table_arabs[ power ][ index ];
|
||||
}
|
||||
|
||||
return roman;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef INT2ROMAN_HH
|
||||
#define INT2ROMAN_HH
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string int2roman( size_t decimal, size_t length=30 );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,348 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
// -------------------- little helper
|
||||
#include "generate_cube.hh"
|
||||
#include "stats.hh"
|
||||
#include "fill_props.hh"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Set to 1 to use an PolyMesh type.
|
||||
#define UsePolyMesh 1
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace OpenMesh;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef TriMesh_ArrayKernelT<> TriMesh;
|
||||
typedef PolyMesh_ArrayKernelT<> PolyMesh;
|
||||
|
||||
#if UsePolyMesh
|
||||
typedef PolyMesh Mesh;
|
||||
#else
|
||||
typedef TriMesh Mesh;
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct MyData
|
||||
{
|
||||
int ival;
|
||||
double dval;
|
||||
bool bval;
|
||||
OpenMesh::Vec4f vec4fval;
|
||||
|
||||
MyData()
|
||||
: ival(0), dval(0.0), bval(false)
|
||||
{ }
|
||||
|
||||
MyData( const MyData& _cpy )
|
||||
: ival(_cpy.ival), dval(_cpy.dval), bval(_cpy.bval),
|
||||
vec4fval(_cpy.vec4fval)
|
||||
{ }
|
||||
|
||||
|
||||
// ---------- assignment
|
||||
|
||||
MyData& operator = (const MyData& _rhs)
|
||||
{
|
||||
ival = _rhs.ival;
|
||||
dval = _rhs.dval;
|
||||
bval = _rhs.bval;
|
||||
vec4fval = _rhs.vec4fval;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MyData& operator = (int _rhs) { ival = _rhs; return *this; }
|
||||
MyData& operator = (double _rhs) { dval = _rhs; return *this; }
|
||||
MyData& operator = (bool _rhs) { bval = _rhs; return *this; }
|
||||
MyData& operator = (const OpenMesh::Vec4f& _rhs)
|
||||
{ vec4fval = _rhs; return *this; }
|
||||
|
||||
|
||||
// ---------- comparison
|
||||
|
||||
bool operator == (const MyData& _rhs) const
|
||||
{
|
||||
return ival == _rhs.ival
|
||||
&& dval == _rhs.dval
|
||||
&& bval == _rhs.bval
|
||||
&& vec4fval == _rhs.vec4fval;
|
||||
}
|
||||
|
||||
bool operator != (const MyData& _rhs) const { return !(*this == _rhs); }
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef std::map< std::string, unsigned int > MyMap;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
// support persistence for struct MyData
|
||||
|
||||
template <> struct binary<MyData>
|
||||
{
|
||||
typedef MyData value_type;
|
||||
|
||||
static const bool is_streamable = true;
|
||||
|
||||
// return binary size of the value
|
||||
|
||||
static size_t size_of(void)
|
||||
{
|
||||
return sizeof(int)+sizeof(double)+sizeof(bool)+sizeof(OpenMesh::Vec4f);
|
||||
}
|
||||
|
||||
static size_t size_of(const value_type&)
|
||||
{
|
||||
return size_of();
|
||||
}
|
||||
|
||||
static std::string type_identifier(void)
|
||||
{
|
||||
return "RegisteredDataType";
|
||||
}
|
||||
|
||||
static size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
|
||||
{
|
||||
size_t bytes;
|
||||
bytes = IO::store( _os, _v.ival, _swap );
|
||||
bytes += IO::store( _os, _v.dval, _swap );
|
||||
bytes += IO::store( _os, _v.bval, _swap );
|
||||
bytes += IO::store( _os, _v.vec4fval, _swap );
|
||||
return _os.good() ? bytes : 0;
|
||||
}
|
||||
|
||||
static size_t restore( std::istream& _is, value_type& _v, bool _swap=false)
|
||||
{
|
||||
size_t bytes;
|
||||
bytes = IO::restore( _is, _v.ival, _swap );
|
||||
bytes += IO::restore( _is, _v.dval, _swap );
|
||||
bytes += IO::restore( _is, _v.bval, _swap );
|
||||
bytes += IO::restore( _is, _v.vec4fval, _swap );
|
||||
return _is.good() ? bytes : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <> struct binary< MyMap >
|
||||
{
|
||||
typedef MyMap value_type;
|
||||
|
||||
static const bool is_streamable = true;
|
||||
|
||||
// return generic binary size of self, if known
|
||||
static size_t size_of(void) { return UnknownSize; }
|
||||
|
||||
// return binary size of the value
|
||||
static size_t size_of(const value_type& _v)
|
||||
{
|
||||
if (_v.empty())
|
||||
return sizeof(unsigned int);
|
||||
|
||||
value_type::const_iterator it = _v.begin();
|
||||
unsigned int N = _v.size();
|
||||
size_t bytes = IO::size_of(N);
|
||||
|
||||
for(;it!=_v.end(); ++it)
|
||||
{
|
||||
bytes += IO::size_of( it->first );
|
||||
bytes += IO::size_of( it->second );
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static
|
||||
size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
unsigned int N = _v.size();
|
||||
|
||||
value_type::const_iterator it = _v.begin();
|
||||
|
||||
bytes += IO::store( _os, N, _swap );
|
||||
|
||||
for (; it != _v.end() && _os.good(); ++it)
|
||||
{
|
||||
bytes += IO::store( _os, it->first, _swap );
|
||||
bytes += IO::store( _os, it->second, _swap );
|
||||
}
|
||||
return _os.good() ? bytes : 0;
|
||||
}
|
||||
|
||||
static
|
||||
size_t restore( std::istream& _is, value_type& _v, bool _swap=false)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
unsigned int N = 0;
|
||||
|
||||
_v.clear();
|
||||
|
||||
bytes += IO::restore( _is, N, _swap );
|
||||
value_type::key_type key;
|
||||
value_type::mapped_type val;
|
||||
|
||||
for (size_t i=0; i<N && _is.good(); ++i)
|
||||
{
|
||||
bytes += IO::restore( _is, key, _swap );
|
||||
bytes += IO::restore( _is, val, _swap );
|
||||
_v[key] = val;
|
||||
}
|
||||
return _is.good() ? bytes : 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main(void)
|
||||
{
|
||||
//
|
||||
Mesh mesh;
|
||||
|
||||
|
||||
// generate a geometry
|
||||
generate_cube<Mesh>(mesh);
|
||||
|
||||
|
||||
// should display 8 vertices, 18/12 edges, 12/6 faces (Tri/Poly)
|
||||
mesh_stats(mesh);
|
||||
|
||||
|
||||
// print out information about properties
|
||||
mesh_property_stats(mesh);
|
||||
|
||||
|
||||
std::cout << "Define some custom properties..\n";
|
||||
|
||||
OpenMesh::VPropHandleT<float> vprop_float;
|
||||
OpenMesh::EPropHandleT<bool> eprop_bool;
|
||||
OpenMesh::FPropHandleT<std::string> fprop_string;
|
||||
OpenMesh::HPropHandleT<MyData> hprop_mydata;
|
||||
OpenMesh::MPropHandleT<MyMap> mprop_map;
|
||||
|
||||
std::cout << ".. and registrate them at the mesh object.\n";
|
||||
|
||||
mesh.add_property(vprop_float, "vprop_float");
|
||||
mesh.add_property(eprop_bool, "eprop_bool");
|
||||
mesh.add_property(fprop_string, "fprop_string");
|
||||
mesh.add_property(hprop_mydata, "hprop_mydata");
|
||||
mesh.add_property(mprop_map, "mprop_map");
|
||||
|
||||
|
||||
mesh_property_stats(mesh);
|
||||
|
||||
|
||||
std::cout << "Now let's fill the props..\n";
|
||||
|
||||
fill_props(mesh, vprop_float);
|
||||
fill_props(mesh, eprop_bool);
|
||||
fill_props(mesh, fprop_string);
|
||||
fill_props(mesh, hprop_mydata);
|
||||
fill_props(mesh, mprop_map);
|
||||
|
||||
|
||||
std::cout << "Check props..\n";
|
||||
#define CHK_PROP( PH ) \
|
||||
std::cout << " " << #PH << " " \
|
||||
<< (fill_props(mesh, PH, true)?"ok\n":"error\n")
|
||||
|
||||
CHK_PROP(vprop_float);
|
||||
CHK_PROP(eprop_bool);
|
||||
CHK_PROP(fprop_string);
|
||||
CHK_PROP(hprop_mydata);
|
||||
CHK_PROP(mprop_map);
|
||||
#undef CHK_PROP
|
||||
|
||||
|
||||
std::cout << "Set persistent flag..\n";
|
||||
#define SET_PERS( PH ) \
|
||||
mesh.property(PH).set_persistent(true); \
|
||||
std::cout << " " << #PH << " " \
|
||||
<< (mesh.property(PH).persistent()?"ok\n":"failed!\n")
|
||||
|
||||
mesh.property(vprop_float).set_persistent(true);
|
||||
std::cout << " vprop_float "
|
||||
<< (mesh.property(vprop_float).persistent()?"ok\n":"failed!\n");
|
||||
|
||||
SET_PERS( eprop_bool );
|
||||
SET_PERS( fprop_string );
|
||||
SET_PERS( hprop_mydata );
|
||||
mesh.mproperty(mprop_map).set_persistent(true);
|
||||
std::cout << " mprop_map "
|
||||
<< (mesh.mproperty(mprop_map).persistent()?"ok\n":"failed!\n");
|
||||
|
||||
|
||||
std::cout << "Write mesh..";
|
||||
if (IO::write_mesh( mesh, "persistence-check.om" ))
|
||||
std::cout << " ok\n";
|
||||
else
|
||||
{
|
||||
std::cout << " failed\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
std::cout << "Clear mesh\n";
|
||||
mesh.clear();
|
||||
mesh_stats(mesh, " ");
|
||||
|
||||
|
||||
std::cout << "Read back mesh..";
|
||||
try
|
||||
{
|
||||
if (IO::read_mesh( mesh, "persistence-check.om" ))
|
||||
std::cout << " ok\n";
|
||||
else
|
||||
{
|
||||
std::cout << " failed!\n";
|
||||
return 1;
|
||||
}
|
||||
mesh_stats(mesh, " ");
|
||||
}
|
||||
catch( std::exception &x )
|
||||
{
|
||||
std::cerr << x.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
std::cout << "Check props..\n";
|
||||
#define CHK_PROP( PH ) \
|
||||
std::cout << " " << #PH << " " \
|
||||
<< (fill_props(mesh, PH, true)?"ok\n":"error\n")
|
||||
CHK_PROP(vprop_float);
|
||||
CHK_PROP(eprop_bool);
|
||||
CHK_PROP(fprop_string);
|
||||
CHK_PROP(hprop_mydata);
|
||||
CHK_PROP(mprop_map);
|
||||
#undef CHK_PROP
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of file
|
||||
// ============================================================================
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef STATS_HH
|
||||
#define STATS_HH
|
||||
|
||||
template <typename Mesh>
|
||||
void mesh_stats( Mesh& _m, const std::string& prefix = "" )
|
||||
{
|
||||
std::cout << prefix
|
||||
<< _m.n_vertices() << " vertices, "
|
||||
<< _m.n_edges() << " edges, "
|
||||
<< _m.n_faces() << " faces\n";
|
||||
}
|
||||
|
||||
template <typename Mesh>
|
||||
void mesh_property_stats(Mesh& _m)
|
||||
{
|
||||
std::cout << "Current set of properties:\n";
|
||||
_m.property_stats(std::cout);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/DefaultTriMesh.hh>
|
||||
#include <OpenMesh/Core/Utils/PropertyManager.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using MyMesh = OpenMesh::TriMesh;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Read command line options
|
||||
MyMesh mesh;
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const int iterations = argv[1];
|
||||
const std::string infile = argv[2];
|
||||
const std::string outfile = argv[3];
|
||||
|
||||
// Read mesh file
|
||||
if (!OpenMesh::IO::read_mesh(mesh, infile)) {
|
||||
std::cerr << "Error: Cannot read mesh from " << infile << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
// Add a vertex property storing the laplace vector
|
||||
auto laplace = OpenMesh::VProp<MyMesh::Point>(mesh);
|
||||
|
||||
// Add a vertex property storing the laplace of the laplace
|
||||
auto bi_laplace = OpenMesh::VProp<MyMesh::Point>(mesh);
|
||||
|
||||
// Get a propertymanager of the points property of the mesh to use as functor
|
||||
auto points = OpenMesh::getPointsProperty(mesh);
|
||||
|
||||
// Smooth the mesh several times
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
// Iterate over all vertices to compute laplace vector
|
||||
for (const auto& vh : mesh.vertices())
|
||||
laplace(vh) = vh.vertices().avg(points) - points(vh);
|
||||
|
||||
// Iterate over all vertices to compute the laplace vector of the laplace vectors
|
||||
for (const auto& vh : mesh.vertices())
|
||||
bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh));
|
||||
|
||||
// update points by substracting the bi-laplacian damped by a factor of 0.5
|
||||
for (const auto& vh : mesh.vertices())
|
||||
points(vh) += -0.5 * bi_laplace(vh);
|
||||
}
|
||||
} // The laplace and update properties are removed from the mesh at the end of this scope.
|
||||
|
||||
|
||||
// Write mesh file
|
||||
if (!OpenMesh::IO::read_mesh(mesh, outfile)) {
|
||||
std::cerr << "Error: Cannot write mesh to " << outfile << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/DefaultTriMesh.hh>
|
||||
#include <OpenMesh/Core/Utils/PropertyManager.hh>
|
||||
#include <OpenMesh/Core/Utils/Predicates.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using MyMesh = OpenMesh::TriMesh;
|
||||
|
||||
bool is_divisible_by_3(OpenMesh::FaceHandle vh) { return vh.idx() % 3 == 0; }
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace OpenMesh::Predicates; // for easier access to predicates
|
||||
|
||||
// Read command line options
|
||||
MyMesh mesh;
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: " << argv[0] << " infile" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const std::string infile = argv[1];
|
||||
|
||||
// Read mesh file
|
||||
if (!OpenMesh::IO::read_mesh(mesh, infile)) {
|
||||
std::cerr << "Error: Cannot read mesh from " << infile << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Count boundary vertices
|
||||
std::cout << "Mesh contains " << mesh.vertices().count_if(Boundary()) << " boundary vertices";
|
||||
|
||||
// Selected inner vertices
|
||||
std::cout << "These are the selected inner vertices: " << std::endl;
|
||||
for (auto vh : mesh.vertices().filtered(!Boundary() && Selected()))
|
||||
std::cout << vh.idx() << ", ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// Faces whose id is divisible by 3
|
||||
auto vec = mesh.faces().filtered(is_divisible_by_3).to_vector();
|
||||
std::cout << "There are " << vec.size() << " faces whose id is divisible by 3" << std::endl;
|
||||
|
||||
// Faces which are tagged or whose id is not divisible by 3
|
||||
auto vec2 = mesh.faces().filtered(Tagged() || !make_predicate(is_divisible_by_3)).to_vector();
|
||||
std::cout << "There are " << vec2.size() << " faces which are tagged or whose id is not divisible by 3" << std::endl;
|
||||
|
||||
// Edges that are longer than 10 or shorter than 2
|
||||
OpenMesh::EProp<bool> longer_than_10(mesh);
|
||||
for (auto eh : mesh.edges())
|
||||
longer_than_10[eh] = mesh.calc_edge_length(eh) > 10;
|
||||
std::cout << "There are " <<
|
||||
mesh.edges().count_if(make_predicate(longer_than_10) || make_predicate([&](OpenMesh::EdgeHandle eh) { return mesh.calc_edge_length(eh) < 2; })) <<
|
||||
" edges which are shorter than 2 or longer than 10" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(OpenMesh-Example)
|
||||
|
||||
find_package(OpenMesh)
|
||||
|
||||
set (targetName MyOwnProject)
|
||||
|
||||
add_executable (${targetName} build_cube.cc)
|
||||
target_link_libraries(${targetName} PRIVATE OpenMeshCore OpenMeshTools)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
include (VCICommon)
|
||||
|
||||
include_directories (
|
||||
../../..
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set (targetName MyOwnProject)
|
||||
|
||||
# collect all header and source files
|
||||
vci_append_files (headers "*.hh" .)
|
||||
vci_append_files (sources "*.cc" .)
|
||||
|
||||
vci_add_executable (${targetName} ${headers} ${sources})
|
||||
|
||||
target_link_libraries (${targetName}
|
||||
OpenMeshCore
|
||||
OpenMeshTools
|
||||
)
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page compiling Compiling OpenMesh
|
||||
|
||||
\section compilers Tested compilers
|
||||
|
||||
%OpenMesh has been successfully tested for the following operating
|
||||
systems / compilers. This is only a list of tested compilers.
|
||||
More might be supported but are not tested. Make sure that your compiler
|
||||
supports at least C++11
|
||||
|
||||
<table>
|
||||
|
||||
<tr><td> Linux </td><td>
|
||||
gcc >= 6.3<br>
|
||||
clang >= 3.3<br>
|
||||
</td></tr>
|
||||
|
||||
<tr><td> Windows </td><td>
|
||||
Microsoft Visual Studio 2015<br>
|
||||
Microsoft Visual Studio 2017<br>
|
||||
</td></tr>
|
||||
|
||||
<tr><td> Tested MacOS X Compilers</td>
|
||||
<td>
|
||||
XCode <br>
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
\section req_libs Required libraries (Only if you want to build the included Apps)
|
||||
|
||||
Install the following external libraries / frameworks if you want to use the included Applications:<br><br>
|
||||
<table>
|
||||
<tr><td>Qt5</td><td><a href="http://qt-project.org/downloads" target="_blank">https://www.qt.io/download</a></td></tr>
|
||||
</table><br>
|
||||
|
||||
\section build_systems Chosing build system
|
||||
|
||||
%OpenMesh can be built using the <b>cmake</b> build system.
|
||||
<br>
|
||||
<br>
|
||||
|
||||
\section sec_compiling_unix Unix
|
||||
|
||||
\subsection linux_using_cmake Compiling OpenMesh using CMake
|
||||
|
||||
In order to compile %OpenMesh, create a directory named e.g. "build" in
|
||||
OpenMesh's root directory. <b>Change to the newly created directory</b> and type
|
||||
<br/><br/>
|
||||
<tt>
|
||||
cmake .. ## Generates the appropriate Makefiles<br>
|
||||
make ## Builds the project<br>
|
||||
</tt><br>
|
||||
|
||||
\warning If your compiler does not support c++11 natively, you might have to enable it by changing the cmake call to: <br>
|
||||
<tt>cmake .. -DCMAKE_CXX_FLAGS=-std=c++98</tt>
|
||||
|
||||
You can choose the build type by using cmake with the flag<br>
|
||||
<b>-DCMAKE_BUILD_TYPE=(Debug|Release)</b> The default is: Release <br>
|
||||
|
||||
Other flags are:<br/>
|
||||
<b>-DBUILD_APPS=OFF</b> to disable build of applications and<br/>
|
||||
<b>-DCMAKE_INSTALL_PREFIX=<path></b> to specify the install path.<br/>
|
||||
|
||||
When calling <b>make install</b> cmake will install %OpenMesh into this
|
||||
directory using the subdirectories lib/include/bin.
|
||||
|
||||
CMake builds both shared and static under Linux.
|
||||
|
||||
Everything will then be build in the <b>Build</b> subdirectory containing the libraries in <b>lib</b> and the binaries in <b>bin</b>.
|
||||
|
||||
|
||||
There are some additional targets:<br>
|
||||
<b>doc</b>: Builds the Documentation<br>
|
||||
<b>doc-install</b>: Builds the Documentation and installs it<br>
|
||||
<br>
|
||||
\note When you link against the static libraries of OpenMesh and get the error "can not be used when making a
|
||||
shared object; recompile with -fPIC" you need to add "-fPIC" to the CMAKE_CXX_FLAGS. (This is usually added automatically)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\section sec_compiling_windows Windows
|
||||
|
||||
\subsection windows_using_cmake Compiling OpenMesh using CMake
|
||||
|
||||
Building OpenMesh on Windows requires cmake to generate the project files for Visual Studio.
|
||||
|
||||
|
||||
|
||||
<ul>
|
||||
<li> Get Visual Studio ( 2015-2017 ) </li>
|
||||
<li> Extract %OpenMesh source code. </li>
|
||||
<li> Get all required libraries and install them ( including headers! ).</li>
|
||||
<li> Download and install cmake: <a href="https://cmake.org/download/">www.cmake.org</a>.<br> </li>
|
||||
<li> Start the cmake gui and open the %OpenMesh toplevel directory as source directory </li>
|
||||
<li> Choose a build directory (e.g. create a directory called "build" in OpenMesh's root folder) </li>
|
||||
<li> Click on configure .... If any libraries are left unconfigured, you can adjust the path manually. Rerun configure until everything is configured correctly. <br>
|
||||
Attention: Some build variables are only visible in advanced view mode. Select Visual Studio 9 (2008), Visual Studio 10(2010), Visual Studio 11 (2012), Visual Studio 12 (2013) (Depending on your version) as
|
||||
generator. </li>
|
||||
<li> Click generate to create the visual studio project files </li>
|
||||
<li> You can now find a Visual Studio solution file (OpenMesh.sln) in the <b>build</b> directory you chose in cmake </li>
|
||||
<li> Now you can build %OpenMesh from within Visual Studio using the newly created project file. </li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
\section sec_compiling_macosx MacOS X
|
||||
|
||||
To compile OpenMesh, you need cmake on your system which is the minimal requirement to build OpenMesh.
|
||||
|
||||
We recommend using homebrew (https://brew.sh/index_de) for installing additional packages required for
|
||||
compiling OpenMesh or other projects.
|
||||
|
||||
After installing homebrew, you can use the following command to install cmake:<br>
|
||||
<tt>
|
||||
brew install cmake ## cmake generates the makefiles<br>
|
||||
</tt><br>
|
||||
|
||||
Optional libraries which can be used to build OpenMesh:<br>
|
||||
<tt>
|
||||
brew install googletest # Required to compile the included tests<br>
|
||||
brew install qt # Required to compile the included UI example apps<br>
|
||||
</tt><br>
|
||||
|
||||
Download and install required libraries as stated above.
|
||||
|
||||
You can download %OpenMesh's sources from <tt>www.openmesh.org</tt> or check out the latest repository via GIT (Recommended to get the latest version of OpenMesh):<br/>
|
||||
<tt>https://gitlab.vci.rwth-aachen.de:9000/OpenMesh/OpenMesh</tt>.<br/><br/>
|
||||
|
||||
\subsection mac_using_cmake Compiling OpenMesh using CMake
|
||||
|
||||
We recommend you to use CMake >= 3.7 as build system. This can also easily be installed
|
||||
via Homebrew as well as the Qt >= 6.2 library which is used for some example applications
|
||||
in %OpenMesh.<br/>
|
||||
Once installed, change to %OpenMesh's root directory and create a directory
|
||||
named e.g. "buildDebug" (assuming you want to build with debug symbols).<br/>
|
||||
Then type in the following command to initially set up the build environment:
|
||||
<br/><br/>
|
||||
<tt>
|
||||
cmake .. ## Generates the appropriate Makefiles<br>
|
||||
</tt>
|
||||
<br/>
|
||||
Note: If the build directory is not a subdirectory of %OpenMesh's root folder, replace ".." with %OpenMesh's
|
||||
absolute (or relative) path.
|
||||
In order to manually set specific build variables, just type:
|
||||
<br/><br/>
|
||||
<tt>
|
||||
ccmake . ## Configure build environment<br>
|
||||
</tt>
|
||||
<br/>
|
||||
This opens the CMake configure tool. Change the CMAKE_BUILD_TYPE variable to "Release" in order to prepare build
|
||||
for release configuration. Now, when everything is set up, just type:
|
||||
<br/><br/>
|
||||
<tt>
|
||||
make ## Build %OpenMesh<br>
|
||||
</tt>
|
||||
<br/>
|
||||
And optionally:
|
||||
<br/><br/>
|
||||
<tt>
|
||||
make doc ## Build %OpenMesh's documentation<br>
|
||||
</tt>
|
||||
<br>
|
||||
The mac application bundle will be found under "Build" in the recently created build folder.
|
||||
It automatically contains all needed shared objects (libs, fonts, textures, etc.).
|
||||
|
||||
CMake builds both shared and static under MacOS X.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
/** \page compiling_tests Compiling OpenMesh unit tests
|
||||
|
||||
%OpenMesh comes with a set of unittests for all platforms. In order to run these
|
||||
tests, you need to enable the cmake flag <b>OPENMESH_BUILD_UNIT_TESTS</b>.
|
||||
You also need <a href="https://github.com/google/googletest">GoogleTest</a> on your
|
||||
machine. Configure the cmake variables in OpenMesh to point to your GTest include
|
||||
dirs and libraries (check the Advanced button in cmake, if you don't see these
|
||||
options). Than run cmake and build OpenMesh.
|
||||
|
||||
Afterwards you should have a Unittests subdirectory in your binary build folder.
|
||||
This directory includes the unittest executables and several test files for input
|
||||
and output checks. You can run the executables directly, but
|
||||
make sure, that the working directory is the directory where the executables are.
|
||||
|
||||
**/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,111 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page decimater_docu Mesh Decimation Framework
|
||||
|
||||
The mesh decimation framework has 3 building blocks.
|
||||
|
||||
-# \ref DecimaterAlg
|
||||
-# \ref DecimaterMod
|
||||
-# \ref DecimaterHnd
|
||||
|
||||
\section DecimaterAlg The decimation algorithm
|
||||
|
||||
The decimater (OpenMesh::Decimater::DecimaterT) provides the
|
||||
decimation algorithm, while the decimation modules provide the
|
||||
computational part. The modules compute a priority value due to some
|
||||
error metric, which is used by the decimater to feed a priority
|
||||
queue. The lower the error value, the more a potential collapse
|
||||
moves to the front of the queue. The one with the lowest error will
|
||||
always be the candidate for the next collapse.
|
||||
|
||||
This implementation does a halfedge collapse, hence simply
|
||||
collapsing one vertex into another connected by a halfedge.
|
||||
|
||||
\note The decimater ignores all 'locked' and 'deleted' vertices (see
|
||||
OpenMesh::Attributes::StatusBits)
|
||||
|
||||
\attention The decimater sets temporarily the status bit 'tagged' and
|
||||
clears it after usage regardless of a previous state.
|
||||
|
||||
\section DecimaterLock Block vertices from beeing touched by the Decimater
|
||||
You could mark vertices as locked, which should not be modified by the decimater.
|
||||
|
||||
\code
|
||||
// That might be already requested
|
||||
mesh_->request_vertex_status();
|
||||
|
||||
// Get an iterator over all halfedges
|
||||
Mesh::HalfedgeIter he_it, he_end=mesh_->halfedges_end();
|
||||
|
||||
// If halfedge is boundary, lock the corresponding vertices
|
||||
for (he_it = mesh_->halfedges_begin(); he_it != he_end ; ++he_it)
|
||||
if (mesh_->is_boundary(*he_it)) {
|
||||
mesh_->status(_mesh->to_vertex_handle(*he_it)).set_locked(true);
|
||||
mesh_->status(_mesh->from_vertex_handle(*he_it)).set_locked(true);
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section DecimaterMod Decimating Modules
|
||||
|
||||
The vertex to be removed is determined by a decimation module, which has
|
||||
to be derived from OpenMesh::Decimater::ModBaseT. The framework
|
||||
supplies already a few decimation modules. But it's very easy to build
|
||||
your own (\ref OpenMesh::Decimater::ModBaseT). The most important
|
||||
function of a decimation module is
|
||||
OpenMesh::Decimater::ModBaseT::collapse_priority(). It takes an
|
||||
OpenMesh::Decimater::CollapseInfoT describing a potential halfedge
|
||||
collapse, and returns a value due to some error metric. The error
|
||||
value is used by the decimater to feed a priority queue. Collapses
|
||||
with low error will be executed first, and those with large error
|
||||
later. Of course a module computing the error quadric is provided
|
||||
(OpenMesh::Decimater::ModQuadricT).
|
||||
|
||||
This framework allows to use more than one decimation module with
|
||||
some restrictions. Since the error value is always normalized and
|
||||
sometimes very difficult to compare to other metrics, the framework
|
||||
allows only one non-binary module, i.e. a module computing a float
|
||||
value. Every further module must be a binary module,
|
||||
i.e. collapse_prioerity() returns
|
||||
OpenMesh::Decimater::ModBaseT::LEGAL_COLLAPSE or
|
||||
OpenMesh::Decimater::ModBaseT::ILLEGAL_COLLAPSE. In the algorithm
|
||||
the binary modules are evaluated first. If the evaluated collapse
|
||||
passes the test, then the non-binary module contributes to the
|
||||
decision step.
|
||||
|
||||
In some cases the module does not contribute anything to the
|
||||
decision engine of the decimater, but instead, e.g. simply collects
|
||||
information, while the decimater does it's work. For instance the
|
||||
module OpenMesh::Decimater::ModProgMeshT collects information from
|
||||
all collapses that have been done. This information can be used to
|
||||
generate progressive meshes as described in "Progressive meshes",
|
||||
Hoppe, 1996.
|
||||
|
||||
Provided decimation modules(Binary: B, Continuous: C, Special: X):
|
||||
|
||||
- OpenMesh::Decimater::ModAspectRatioT (B,C)
|
||||
- OpenMesh::Decimater::ModEdgeLengthT (B,C)
|
||||
- OpenMesh::Decimater::ModHausdorffT (B)
|
||||
- OpenMesh::Decimater::ModIndependentSetsT (B)
|
||||
- OpenMesh::Decimater::ModNormalDeviationT (B,C)
|
||||
- OpenMesh::Decimater::ModNormalFlippingT (B)
|
||||
- OpenMesh::Decimater::ModProgMeshT (X)
|
||||
- OpenMesh::Decimater::ModQuadricT (B,C)
|
||||
- OpenMesh::Decimater::ModRoundnessT (B,C)
|
||||
|
||||
\section DecimaterHnd Module Handles
|
||||
|
||||
Similar to properties the modules are represented outside the
|
||||
decimater by module handles. Before using the decimater a
|
||||
non-binary module must be registrated with the decimater.
|
||||
|
||||
See \ref DecimaterExa.
|
||||
|
||||
\section DecimaterExa Basic Setup
|
||||
|
||||
The following small example show the basic steps to setup up a
|
||||
decimater:
|
||||
|
||||
\include decimater.cc
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page holefiller_docu Mesh Hole Filler
|
||||
|
||||
\section HoleFillerAlgo The holefilling algorithm
|
||||
|
||||
The holefiller (OpenMesh::HoleFiller::HoleFillerT) provides a
|
||||
hole filling algorith based on the Filling Holes in Meshes paper
|
||||
by Liepa in 2003.
|
||||
|
||||
\code
|
||||
|
||||
// Initialize holefiller
|
||||
OpenMesh::HoleFiller::HoleFillerT<Mesh> filler(mesh_);
|
||||
|
||||
// Execute the algorithm and fill all holes
|
||||
filler.fill_all_holes();
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#projectlogo
|
||||
{
|
||||
padding-right:64px;
|
||||
right:0px;
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<hr>
|
||||
<address>
|
||||
<small>
|
||||
<a href="http://www.rwth-graphics.de" style="text-decoration:none;">
|
||||
</a>
|
||||
Project <b>$projectname</b>,
|
||||
© Visual Computing Institute, RWTH Aachen.
|
||||
Documentation generated using
|
||||
<a class="el" href="http://www.doxygen.org/index.html">
|
||||
<b>doxygen</b>
|
||||
</a>.
|
||||
</small>
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
@@ -0,0 +1,24 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2550 3900 2550 3300
|
||||
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 2.00 120.00 240.00
|
||||
2550 2700 2550 2100
|
||||
2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5
|
||||
1500 1500 3600 1500 3600 2100 1500 2100 1500 1500
|
||||
2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5
|
||||
1500 2700 3600 2700 3600 3300 1500 3300 1500 2700
|
||||
2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5
|
||||
1500 3900 3600 3900 3600 4500 1500 4500 1500 3900
|
||||
4 1 0 50 0 0 25 0.0000 4 255 990 2475 1950 Kernel\001
|
||||
4 1 0 50 0 0 25 0.0000 4 345 1500 2550 3150 PolyMesh\001
|
||||
4 1 0 50 0 0 25 0.0000 4 255 1290 2550 4350 TriMesh\001
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 777 B |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,65 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\usetikzlibrary{calc,trees,positioning,arrows,chains,shapes.geometric,%
|
||||
decorations.pathreplacing,decorations.pathmorphing,shapes,%
|
||||
matrix,shapes.symbols,positioning}
|
||||
|
||||
\tikzset{
|
||||
kiste/.style={
|
||||
rectangle,
|
||||
rounded corners,
|
||||
% fill=black!10,
|
||||
draw=black, very thick,
|
||||
text width=10em,
|
||||
minimum height=3em,
|
||||
text centered},
|
||||
kkiste/.style={
|
||||
rectangle,
|
||||
rounded corners,
|
||||
% fill=black!10,
|
||||
draw=black, very thick,
|
||||
text width=7em,
|
||||
minimum height=2em,
|
||||
text centered},
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
|
||||
\node[kiste](IOM) at (0,0) {IOManager};
|
||||
\node[kiste,rotate=90](PD) at (-5,-4) {Persistent Data};
|
||||
\node[kiste,rotate=-90](DS) at (5,-4) {Data Structures};
|
||||
|
||||
\path[fill=yellow!20,rounded corners,draw=black!50, dashed]
|
||||
(-3.5,-2) rectangle (-0.5,-6);
|
||||
\path[fill=yellow!20,rounded corners,draw=black!50, dashed]
|
||||
(.5,-2) rectangle (3.5,-6);
|
||||
|
||||
\node[] at (-2,-2.5) {Reader/Writer};
|
||||
\node[kkiste] at (-2,-3.5) {OBJ};
|
||||
\node[] at (-2,-4.25) {$\vdots$};
|
||||
\node[kkiste] at (-2,-5.25) {Custom file format};
|
||||
|
||||
\node[] at (2,-2.5) {Importer/Exporter};
|
||||
\node[kkiste] at (2,-3.5) {OpenMesh};
|
||||
\node[] at (2,-4.25) {$\vdots$};
|
||||
\node[kkiste] at (2,-5.25) {Custom data structure};
|
||||
|
||||
\path [draw,thick,>=latex,<->] (-0.1,-0.6) -- (-2,-1.9) {};
|
||||
\path [draw,thick,>=latex,<->] (0.1,-0.6) -- (2,-1.9) {};
|
||||
|
||||
\path [draw,thick,>=latex,->] (-4.4,-3.8) -- (-3.6,-3.8) {};
|
||||
\path [draw,thick,>=latex,<-] (-4.4,-4.2) -- (-3.6,-4.2) {};
|
||||
|
||||
\path [draw,thick,>=latex,->] (4.4,-3.8) -- (3.6,-3.8) {};
|
||||
\path [draw,thick,>=latex,<-] (4.4,-4.2) -- (3.6,-4.2) {};
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,175 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
\usepackage{color}
|
||||
|
||||
\definecolor{VCI}{RGB}{55,91,64}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
|
||||
%\colorbox{VCI}{
|
||||
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
edge/.style={draw,white,thick},
|
||||
hedge/.style={->,>=latex,shorten >=5pt,draw,white,very thick},
|
||||
redge/.style={line width=3pt,color=red!50!white}
|
||||
]
|
||||
|
||||
\begin{scope}[yshift=-3.6cm]
|
||||
|
||||
\begin{scope}[xshift=-4cm,x={(1.4,0)},y={(0,1.4)}]
|
||||
|
||||
\coordinate (V1) at (-1,1);
|
||||
\coordinate (V2) at (-1,3);
|
||||
\coordinate (V3) at (0,0);
|
||||
\coordinate (V4) at (0,2);
|
||||
\coordinate (V5) at (0,4);
|
||||
\coordinate (V6) at (1,3);
|
||||
\coordinate (V7) at (1,1);
|
||||
|
||||
\draw[edge] (V1) -- (V2) {};
|
||||
\draw[edge] (V2) -- (V4) {};
|
||||
|
||||
|
||||
\draw[hedge] ([xshift=-2pt]V4) -- ([xshift=-2pt]V3) {};
|
||||
\draw[hedge,color=red!50!white] ([xshift=2pt]V3) -- ([xshift=2pt]V4) {};
|
||||
|
||||
\draw[edge] (V3) -- (V1) {};
|
||||
|
||||
\draw[edge] (V4) -- (V6) {};
|
||||
\draw[edge] (V6) -- (V7) {};
|
||||
\draw[edge] (V7) -- (V3) {};
|
||||
|
||||
\draw[edge] (V2) -- (V5) {};
|
||||
\draw[edge] (V5) -- (V6) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
\node[vertex] at (V5) {};
|
||||
\node[vertex] at (V6) {};
|
||||
\node[vertex] at (V7) {};
|
||||
|
||||
\end{scope}
|
||||
|
||||
\draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6);
|
||||
\node[above] at (0, 4.2) {\textcolor{white}{\textbf{Collapse edge}}};
|
||||
|
||||
\begin{scope}[xshift=4cm,x={(1.4,0)},y={(0,1.4)}]
|
||||
|
||||
\coordinate (V1) at (-1,1);
|
||||
\coordinate (V2) at (-1,3);
|
||||
%\coordinate (V3) at (0,0);
|
||||
\coordinate (V4) at (0,2);
|
||||
\coordinate (V5) at (0,4);
|
||||
\coordinate (V6) at (1,3);
|
||||
\coordinate (V7) at (1,1);
|
||||
|
||||
\draw[edge] (V1) -- (V2) {};
|
||||
\draw[edge] (V2) -- (V4) {};
|
||||
\draw[edge] (V4) -- (V1) {};
|
||||
|
||||
\draw[edge] (V4) -- (V6) {};
|
||||
\draw[edge] (V6) -- (V7) {};
|
||||
\draw[edge] (V7) -- (V4) {};
|
||||
|
||||
\draw[edge] (V2) -- (V5) {};
|
||||
\draw[edge] (V5) -- (V6) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V4) {};
|
||||
\node[vertex] at (V5) {};
|
||||
\node[vertex] at (V6) {};
|
||||
\node[vertex] at (V7) {};
|
||||
|
||||
\end{scope}
|
||||
|
||||
\end{scope}
|
||||
|
||||
\begin{scope}[yshift=3.6cm]
|
||||
|
||||
\begin{scope}[xshift=-4cm,x={(1.4,0)},y={(0,1.4)}]
|
||||
|
||||
\coordinate (V1) at (-1,1);
|
||||
\coordinate (V2) at (-1,3);
|
||||
\coordinate (V3) at (0,0);
|
||||
\coordinate (V4) at (0,2);
|
||||
\coordinate (V5) at (0,4);
|
||||
\coordinate (V6) at (1,3);
|
||||
\coordinate (V7) at (1,1);
|
||||
|
||||
\draw[edge] (V1) -- (V2) {};
|
||||
\draw[edge] (V2) -- (V4) {};
|
||||
|
||||
|
||||
\draw[hedge,color=red!50!white] ([xshift=-2pt]V4) -- ([xshift=-2pt]V3) {};
|
||||
\draw[hedge] ([xshift=2pt]V3) -- ([xshift=2pt]V4) {};
|
||||
|
||||
\draw[edge] (V3) -- (V1) {};
|
||||
|
||||
\draw[edge] (V4) -- (V6) {};
|
||||
\draw[edge] (V6) -- (V7) {};
|
||||
\draw[edge] (V7) -- (V3) {};
|
||||
|
||||
\draw[edge] (V2) -- (V5) {};
|
||||
\draw[edge] (V5) -- (V6) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
\node[vertex] at (V5) {};
|
||||
\node[vertex] at (V6) {};
|
||||
\node[vertex] at (V7) {};
|
||||
|
||||
\end{scope}
|
||||
|
||||
\draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6);
|
||||
\node[above] at (0, 4.2) {\textcolor{white}{\textbf{Collapse edge}}};
|
||||
|
||||
\begin{scope}[xshift=4cm,x={(1.4,0)},y={(0,1.4)}]
|
||||
|
||||
\coordinate (V1) at (-1,1);
|
||||
\coordinate (V2) at (-1,3);
|
||||
\coordinate (V3) at (0,0);
|
||||
%\coordinate (V4) at (0,2);
|
||||
\coordinate (V5) at (0,4);
|
||||
\coordinate (V6) at (1,3);
|
||||
\coordinate (V7) at (1,1);
|
||||
|
||||
\draw[edge] (V1) -- (V2) {};
|
||||
\draw[edge] (V2) -- (V3) {};
|
||||
\draw[edge] (V3) -- (V1) {};
|
||||
|
||||
\draw[edge] (V3) -- (V6) {};
|
||||
\draw[edge] (V6) -- (V7) {};
|
||||
\draw[edge] (V7) -- (V3) {};
|
||||
|
||||
\draw[edge] (V2) -- (V5) {};
|
||||
\draw[edge] (V5) -- (V6) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V5) {};
|
||||
\node[vertex] at (V6) {};
|
||||
\node[vertex] at (V7) {};
|
||||
|
||||
\end{scope}
|
||||
|
||||
\end{scope}
|
||||
\end{tikzpicture}
|
||||
|
||||
%}
|
||||
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,79 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
\usepackage{color}
|
||||
|
||||
\definecolor{VCI}{RGB}{55,91,64}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
|
||||
%\colorbox{VCI}{
|
||||
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
edge/.style={draw,white,thick},
|
||||
redge/.style={line width=3pt,color=red!50!white}
|
||||
]
|
||||
|
||||
\begin{scope}[xshift=-5cm]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\draw[edge] (V1) to (V2) {};
|
||||
|
||||
\draw[edge] (V1) -- (V3) {};
|
||||
|
||||
\draw[redge] (V1) -- (V4) {};
|
||||
|
||||
\draw[edge] (V2) -- (V4) {};
|
||||
|
||||
\draw[edge] (V3) -- (V4) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
\end{scope}
|
||||
|
||||
\draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6);
|
||||
\node[above] at (0, 4.2) {\textcolor{white}{\textbf{Flip edge}}};
|
||||
|
||||
\begin{scope}[xshift=5cm]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\draw[edge] (V1) to (V2) {};
|
||||
|
||||
\draw[edge] (V1) -- (V3) {};
|
||||
|
||||
\draw[redge] (V2) -- (V3) {};
|
||||
|
||||
\draw[edge] (V2) -- (V4) {};
|
||||
|
||||
\draw[edge] (V3) -- (V4) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
\end{scope}
|
||||
\end{tikzpicture}
|
||||
|
||||
%}
|
||||
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,48 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=black,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\path[roedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {};
|
||||
\path[roedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {};
|
||||
\path[roedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
\draw[->,>= latex,thick] (-0.4,3) arc (0:320:20pt);
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,50 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,white,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=red!60!white},
|
||||
boedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=blue!60!white}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\path[boedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[roedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {};
|
||||
\path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[boedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {};
|
||||
\path[roedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {};
|
||||
|
||||
\path[roedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {};
|
||||
\path[boedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
%\draw[->, thick] (-0.4,3) arc (0:320:20pt);
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,48 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=black,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {};
|
||||
\path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {};
|
||||
\path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
%\draw[->, thick] (-0.4,3) arc (0:320:20pt);
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,50 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
vertex/.style={draw=none,circle,fill=white,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,white,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=red!60!white},
|
||||
boedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=blue!60!white}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[boedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {};
|
||||
\path[roedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {};
|
||||
\path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
%\draw[->, thick] (-0.4,3) arc (0:320:20pt);
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,48 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=black,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
\coordinate (V3) at (0,6);
|
||||
\coordinate (V4) at (3,3);
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[roedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[roedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {};
|
||||
\path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {};
|
||||
|
||||
\path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {};
|
||||
\path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {};
|
||||
|
||||
\path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {};
|
||||
\path[roedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {};
|
||||
|
||||
\path[roedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {};
|
||||
\path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
\node[vertex] at (V3) {};
|
||||
\node[vertex] at (V4) {};
|
||||
|
||||
\draw[<-,>= latex,thick] (3.3,3) arc (0:320:94pt);
|
||||
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,29 @@
|
||||
\documentclass{minimal}
|
||||
|
||||
% Tikz
|
||||
\usepackage{pgf}
|
||||
\usepackage{tikz}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{tikzpicture}
|
||||
[
|
||||
vertex/.style={draw=none,circle,fill=black,minimum size=2pt},
|
||||
oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick},
|
||||
roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red}
|
||||
]
|
||||
|
||||
\coordinate (V1) at (-3,3);
|
||||
\coordinate (V2) at (0,0);
|
||||
|
||||
\path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {};
|
||||
\path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {};
|
||||
|
||||
\node[vertex] at (V1) {};
|
||||
\node[vertex] at (V2) {};
|
||||
|
||||
\end{tikzpicture}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
|
||||
|
||||
\if OPENMESH_INTERNAL_DOC
|
||||
\mainpage OpenMesh Documentation
|
||||
\else
|
||||
\page OpenMeshDoc OpenMesh Documentation
|
||||
\endif
|
||||
|
||||
\image html OpenMesh_text_128.png
|
||||
|
||||
Welcome to the %OpenMesh documentation. %OpenMesh is a generic and efficient library
|
||||
that offers data structures for representing and manipulating polygonal meshes.
|
||||
It is a powerful tool for handling polygonal
|
||||
meshes. Due to its inherent generative structure it allows the user to
|
||||
create mesh types which are custom tailored to the specific needs of
|
||||
the application. The user can either supply his own data structures
|
||||
for representing vertices, edges and faces or he can conveniently use
|
||||
the predefined structures of %OpenMesh.
|
||||
Additionally %OpenMesh offers dynamic properties allowing the user to attach
|
||||
and detach data to the mesh during runtime.
|
||||
|
||||
Here you can find information on how to build projects using the %OpenMesh library
|
||||
as well as further information on mesh handling in %OpenMesh.
|
||||
The tutorials explain how to use %OpenMesh by demonstrating real code examples.
|
||||
|
||||
\section openmesh-python OpenMesh Python Bindings
|
||||
We also provide python bindings for %OpenMesh. You can find them here:<br/>
|
||||
<tt>https://gitlab.vci.rwth-aachen.de:9000/OpenMesh/openmesh-python</tt>
|
||||
|
||||
\section iov Building OpenMesh
|
||||
In this section all necessary information on how to build projects using %OpenMesh
|
||||
is given.
|
||||
|
||||
\li \subpage compiling
|
||||
\li \subpage compiling_tests
|
||||
|
||||
<br /><br />
|
||||
|
||||
\subpage mesh_docu
|
||||
|
||||
We provide a short overview over the functionality of the %OpenMesh
|
||||
library and some additional concepts in \ref tutorial. Additionally, we explain the
|
||||
most important topics of %OpenMesh in the following sections:
|
||||
|
||||
\li \ref mesh_features
|
||||
\li \ref mesh_hds
|
||||
\li \ref mesh_iterators
|
||||
\li \ref mesh_navigation
|
||||
\li \ref mesh_io
|
||||
\li \ref mesh_operations
|
||||
\li \ref mesh_hierarchy
|
||||
|
||||
The %OpenMeshTools library that contains some useful tools
|
||||
for i.e. mesh processing:
|
||||
|
||||
\li \subpage tools_docu
|
||||
|
||||
<br /><br />
|
||||
\subpage tutorial
|
||||
|
||||
This section is supposed to introduce the basic concepts of
|
||||
%OpenMesh. <!--For detailed information, consult the online documentation
|
||||
(\subpage mesh_docu ).-->
|
||||
|
||||
<!--In this tutorial we will introduce the %OpenMesh library by means of
|
||||
simple examples. The first one just builds a polygonal mesh
|
||||
representing a cube and writes the result to standard output. The
|
||||
following examples develop a simple mesh smoother: Recall that the
|
||||
immediate neighbors of a vertex are called the 1-ring of this
|
||||
vertex. It is well known that a polygonal mesh can be smoothed by
|
||||
repeatedly replacing each vertex' position by the center of gravity
|
||||
(cog) of its 1-ring. The basic smoother will
|
||||
|
||||
\li read a polygonal mesh from standard input,
|
||||
\li compute the cog of the 1-ring of each vertex,
|
||||
\li replace each vertex' position by its cog and finally,
|
||||
\li write the mesh to standard output.-->
|
||||
|
||||
\li \ref mesh_type
|
||||
\li \ref tutorial_01
|
||||
\li \ref tutorial_build
|
||||
\li \ref tutorial_build_internal_apps
|
||||
\li \ref tutorial_02
|
||||
\li \ref tutorial_03
|
||||
\li \ref tutorial_04
|
||||
\li \ref tutorial_11
|
||||
\li \ref tutorial_12
|
||||
\li \ref tutorial_05
|
||||
\li \ref tutorial_06
|
||||
\li \ref tutorial_07
|
||||
\li \ref tutorial_07b
|
||||
\li \ref tutorial_08
|
||||
\li \ref tutorial_09
|
||||
\li \ref tutorial_10
|
||||
|
||||
<br /><br />
|
||||
|
||||
\subpage additional_information
|
||||
|
||||
\li \ref mesh_first_to_read
|
||||
\li \ref mesh_cpp
|
||||
\li \ref mesh_members
|
||||
\li \ref naming_conventions
|
||||
\li \ref mesh_speedup
|
||||
\li \ref om_changelog
|
||||
|
||||
\page mesh_docu Using and understanding OpenMesh
|
||||
\li \subpage mesh_features
|
||||
\li \subpage mesh_hds
|
||||
\li \subpage mesh_iterators
|
||||
\li \subpage mesh_navigation
|
||||
\li \subpage mesh_io
|
||||
\li \subpage mesh_operations
|
||||
\li \subpage mesh_hierarchy
|
||||
\li \subpage mesh_type
|
||||
\li \subpage mesh_eigen
|
||||
|
||||
|
||||
\page additional_information Additional Information on OpenMesh
|
||||
\li \subpage mesh_first_to_read
|
||||
\li \subpage mesh_cpp
|
||||
\li \subpage mesh_members
|
||||
\li \subpage naming_conventions
|
||||
\li \subpage mesh_speedup
|
||||
\li \subpage om_changelog
|
||||
|
||||
**/
|
||||
@@ -0,0 +1,31 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** \page naming_conventions Naming Conventions
|
||||
|
||||
The following naming conventions are used for the %OpenMesh code:
|
||||
|
||||
<b>Files:</b>
|
||||
\li \c MyClass.cc for C++-Implementation of class \c MyClass
|
||||
\li \c MyClassT_impl.hh for Header only C++-Implementation of template class \c MyClass
|
||||
\li \c MyClass.hh for C++-Header of class \c MyClass
|
||||
|
||||
<b>Classes:</b>
|
||||
\li Class names start with a capital letter: \c MyClass
|
||||
\li Class templates end with \c T: \c MyClassTemplateT
|
||||
|
||||
<b>Variables:</b>
|
||||
\li One leading underscore for parameters in function-calls: \c _var
|
||||
\li One trailing underscore for member-variables: \c var_
|
||||
\li Two trailing underscores for static member-variables: \c var__
|
||||
|
||||
<b>Functions:</b>
|
||||
\li Words are separated by underscores: \c my_function()
|
||||
|
||||
<b>Accessing members:</b>
|
||||
\li To get the member \c xxx_ use <tt> const& xxx() const </tt>
|
||||
\li To set the member \c xxx_ use <tt> void set_xxx(arg) </tt>
|
||||
|
||||
**/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,82 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// Documents all used namespaces for doxygen
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Concepts
|
||||
Descriptions of the concepts used in OpenMesh.
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh
|
||||
Contains all the mesh ingredients like the polygonal mesh,
|
||||
the triangle mesh, different mesh kernels and mesh traits.
|
||||
**/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Iterators
|
||||
Contains all mesh iterators and circulators. The two classes
|
||||
OpenMesh::Concepts::IteratorT and OpenMesh::Concepts::CirculatorT describe
|
||||
the interfaces provided by all iterators and circulators, respectively.
|
||||
|
||||
All iterators/circulators defined in this namespace are template classes
|
||||
that require a mesh a template parameter. Therefore you should use
|
||||
the iterators/circulators that are defined by the mesh itself. See
|
||||
OpenMesh::Mesh::PolyMeshT for a complete list of them.
|
||||
|
||||
\see The mesh docu section \ref mesh_iterators for a more detailed
|
||||
description.
|
||||
\see OpenMesh::Concepts::IteratorT
|
||||
\see OpenMesh::Concepts::CirculatorT
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::IO
|
||||
This namespace contains functions for reading and writing polygonal
|
||||
meshes and a list of supported file formats.
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::GenProg
|
||||
Utilities for generative programming.
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Attributes
|
||||
This namespace holds per item attributes like normal/color.
|
||||
There are some macros provided for convenience, see Attributes.hh.
|
||||
\see Attributes.hh
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Kernel_OSG
|
||||
In this namespace resides the OpenSG integration of OpenMesh.
|
||||
Here you find the class
|
||||
OpenMesh::OSG_Kernel::TriMesh_OSGArrayKernelT<> and the
|
||||
template function OpenMesh::OSG_Kernel::bindT<> to link such a
|
||||
mesh with a OpenSG Geometry. */
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Decimater
|
||||
Software related to mesh decimation.
|
||||
\see DecimaterT.hh
|
||||
*/
|
||||
|
||||
|
||||
/** \namespace OpenMesh::Subdivider::Adaptive
|
||||
* Software related to adaptive subdivision of meshes.
|
||||
*/
|
||||
|
||||
/** \namespace OpenMesh::Subdivider::Uniform
|
||||
* Software related to uniform subdivision of meshes.
|
||||
*/
|
||||
|
||||
/** \namespace OpenMesh::VDPM
|
||||
* Software related to view dependent progressive meshes.
|
||||
*/
|
||||
|
||||
/** \namespace OpenMesh::Utils
|
||||
* Collection of little utility classes and helpers.
|
||||
*/
|
||||
@@ -0,0 +1,116 @@
|
||||
/** \page mesh_navigation How to navigate on a mesh
|
||||
|
||||
\section nav_overview Overview
|
||||
|
||||
\li \ref nav_intro
|
||||
\li \ref nav_he
|
||||
\li \ref nav_bound
|
||||
\li \ref nav_io
|
||||
\li \ref nav_opposite
|
||||
\li \ref nav_to_from
|
||||
|
||||
\section nav_intro Introduction
|
||||
|
||||
In this tutorial you will learn how to navigate on a mesh using
|
||||
the %OpenMesh library. In the previous chapter (see \ref mesh_iterators) you have learned
|
||||
how to iterate over vertices, edges, halfedges and faces as well as
|
||||
circulate over certain structures such as 1-rings and many more.
|
||||
So in this tutorial we will focus on efficiently using the
|
||||
halfedge data structure and some very useful attributes such as
|
||||
the boundary flag. We assume that you already made yourself familiar with the halfedge
|
||||
structure which is used in %OpenMesh. Further information on this topic
|
||||
can be found in \ref mesh_hds.
|
||||
|
||||
\section nav_he Navigating over halfedges
|
||||
|
||||
So let's start with navigating over halfedges of a mesh.
|
||||
Assume we have the following mesh topology:
|
||||
|
||||
\image html mesh.normal.png
|
||||
|
||||
We can now select an arbitrary halfedge of this mesh which then offers
|
||||
either one of two possible navigations:
|
||||
|
||||
\li If the chosen halfedge lies at a boundary or in other
|
||||
words is not adjacent to a face, we can now navigate
|
||||
along the boundary (or hole) of our mesh by using \c next_halfedge_handle()
|
||||
or \c prev_halfedge_handle():
|
||||
|
||||
\image html mesh.outer.png
|
||||
|
||||
\li If the chosen halfedge is adjacent to a face, we can then navigate
|
||||
along all halfedges that are adjacent to this face. In other words we circulate
|
||||
around the inner halfedges of one face:
|
||||
|
||||
\image html mesh.inner.png
|
||||
|
||||
In both cases the code would look something like the following example.
|
||||
Depending on whether the initial halfedge is adjacent to a face or not,
|
||||
we will either navigate on the boundary halfedges of our mesh or along
|
||||
the inner halfedges of a face:
|
||||
\include nav_code1.cc
|
||||
|
||||
References:<br />
|
||||
OpenMesh::Concepts::KernelT< FinalMeshItems >::next_halfedge_handle()<br />
|
||||
OpenMesh::Concepts::KernelT< FinalMeshItems >::prev_halfedge_handle()
|
||||
|
||||
\section nav_bound Mesh boundaries
|
||||
|
||||
As you have seen in the previous section, navigating along boundaries
|
||||
is very simple. In general %OpenMesh also offers a boundary attribute
|
||||
for edges, vertices and faces. So testing i.e. whether a face is a boundary
|
||||
face is quite simple using OpenMesh::PolyConnectivity::is_boundary().<br />
|
||||
|
||||
\note You can iterate along boundaries by using the next_halfedge_handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
|
||||
|
||||
So for each type we can make use of one of the following functions:
|
||||
|
||||
\include nav_code2.cc
|
||||
|
||||
\section nav_io Using incoming and outgoing halfedges
|
||||
|
||||
%OpenMesh offers quite a lot of iterators and circulators to easily iterate
|
||||
over the structures of a mesh. A very helpful iterator is the
|
||||
OpenMesh::PolyConnectivity::VertexIHalfedgeIter or the OpenMesh::PolyConnectivity::VertexOHalfedgeIter which are used to iterate
|
||||
over all incoming/outgoing halfedges of a vertex.
|
||||
So, sticking to the illustration below, a OpenMesh::PolyConnectivity:V:ertexIHalfedgeIter for the
|
||||
lower most vertex would iterate over all incoming halfedges (blue),
|
||||
whereas the OpenMesh::PolyConnectivity::OpenMesh::PolyConnectivity::VertexOHalfedgeIter would iterate over all outgoing halfedges (red):
|
||||
|
||||
\image html mesh.inout.png
|
||||
|
||||
A schematic code example of how to use the halfedge iterators as described above:
|
||||
\include nav_code3.cc
|
||||
|
||||
\section nav_opposite Using opposite halfedges
|
||||
|
||||
The halfedge structure splits every edge into two directional parts by creating two
|
||||
directed edges out of one undirected edge. So for every halfedge there exists its
|
||||
counterpart pointing in the opposite direction. %OpenMesh allows to easily navigate
|
||||
through opposing halfedges via the function OpenMesh::Concepts::KernelT< FinalMeshItems >::opposite_halfedge_handle().
|
||||
So in the illustration below \c opposite_halfedge_handle() for the blue halfedge would
|
||||
return the red halfedge:
|
||||
|
||||
\image html mesh.opp.png
|
||||
|
||||
Use this function as described in the example below:
|
||||
|
||||
\include nav_code4a.cc
|
||||
|
||||
There are also a few more functions that offer easy access to opposing structures:
|
||||
|
||||
\include nav_code4.cc
|
||||
|
||||
|
||||
\section nav_to_from Getting the to and from vertices
|
||||
|
||||
\image html mesh.to.from.png
|
||||
|
||||
If you have an halfedge, you can get the to and the from handles of the adjacent vertices.
|
||||
\note The halfedges have a direction. Therefore the to vertex is the from vertex of the opposite halfedge and vice versa.
|
||||
|
||||
\include nav_code_to_from.cc
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,134 @@
|
||||
/** \page mesh_operations Some basic operations: Flipping and collapsing edges
|
||||
|
||||
In this section you will learn about some basic operations on a mesh that %OpenMesh
|
||||
already provides. Comprising the flipping of edges in a triangle mesh as well as
|
||||
collapsing edges by joining the two adjacent vertices.
|
||||
|
||||
\li \ref op_flip
|
||||
\li \ref op_collapse
|
||||
|
||||
\section op_flip Flipping edges in triangle meshes
|
||||
|
||||
Considering two adjacent faces of a triangle mesh, there exist exactly two
|
||||
different configurations of the inner edge. Calling the function
|
||||
OpenMesh::TriConnectivity::flip(EdgeHandle _eh) will flip the specified edge to
|
||||
its opposite orientation as shown in the illustration below.
|
||||
|
||||
\image html mesh.flip.png "Flipping edges in a triangle mesh"
|
||||
|
||||
So, the following snippet of code shows how to use this in your applications:
|
||||
|
||||
\code
|
||||
TriMesh mesh;
|
||||
|
||||
// Add some vertices
|
||||
TriMesh::VertexHandle vhandle[4];
|
||||
|
||||
vhandle[0] = mesh.add_vertex(MyMesh::Point(0, 0, 0));
|
||||
vhandle[1] = mesh.add_vertex(MyMesh::Point(0, 1, 0));
|
||||
vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 0));
|
||||
vhandle[3] = mesh.add_vertex(MyMesh::Point(1, 0, 0));
|
||||
|
||||
// Add two faces
|
||||
std::vector<TriMesh::VertexHandle> face_vhandles;
|
||||
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
// Now the edge adjacent to the two faces connects
|
||||
// vertex vhandle[0] and vhandle[2].
|
||||
|
||||
// Find this edge and then flip it
|
||||
for(TriMesh::EdgeIter it = mesh.edges_begin(); it != mesh.edges_end(); ++it) {
|
||||
|
||||
if(!mesh.is_boundary(*it)) {
|
||||
// Flip edge
|
||||
mesh.flip(*it);
|
||||
}
|
||||
}
|
||||
|
||||
// The edge now connects vertex vhandle[1] and vhandle[3].
|
||||
\endcode
|
||||
|
||||
|
||||
\section op_collapse Collapsing edges
|
||||
|
||||
In this section you will learn how to collapse edges such that the
|
||||
two adjacent vertices join. %OpenMesh provides the function OpenMesh::PolyConnectivity::collapse(HalfedgeHandle _heh) to
|
||||
perform this operation. This will collapse the from-vertex (remeber that halfedges are directed)
|
||||
to the to-vertex of the halfedge as illustrated below. Note that collapsing edges
|
||||
might cause topological inconsistencies to your mesh. You should verify consistency after
|
||||
collapsing edges by calling OpenMesh::PolyConnectivity::is_collapse_ok().
|
||||
|
||||
\note You have to request status attributes in order to use the collapse and delete functions!
|
||||
|
||||
\image html mesh.collapse.png "Collapsing will always be performed in the direction the halfedge points to."
|
||||
|
||||
A simple code example related to the illustration might look like this:
|
||||
|
||||
\code
|
||||
PolyMesh mesh;
|
||||
|
||||
// Request required status flags
|
||||
mesh.request_vertex_status();
|
||||
mesh.request_edge_status();
|
||||
mesh.request_face_status();
|
||||
|
||||
// Add some vertices as in the illustration above
|
||||
PolyMesh::VertexHandle vhandle[7];
|
||||
vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, 1, 0));
|
||||
vhandle[1] = mesh.add_vertex(MyMesh::Point(-1, 3, 0));
|
||||
vhandle[2] = mesh.add_vertex(MyMesh::Point(0, 0, 0));
|
||||
vhandle[3] = mesh.add_vertex(MyMesh::Point(0, 2, 0));
|
||||
vhandle[4] = mesh.add_vertex(MyMesh::Point(0, 4, 0));
|
||||
vhandle[5] = mesh.add_vertex(MyMesh::Point(1, 1, 0));
|
||||
vhandle[6] = mesh.add_vertex(MyMesh::Point(1, 3, 0));
|
||||
|
||||
// Add three quad faces
|
||||
std::vector<PolyMesh::VertexHandle> face_vhandles;
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[0]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[1]);
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
face_vhandles.push_back(vhandle[4]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
face_vhandles.clear();
|
||||
face_vhandles.push_back(vhandle[3]);
|
||||
face_vhandles.push_back(vhandle[2]);
|
||||
face_vhandles.push_back(vhandle[6]);
|
||||
face_vhandles.push_back(vhandle[5]);
|
||||
mesh.add_face(face_vhandles);
|
||||
|
||||
// Now find the edge between vertex vhandle[2]
|
||||
// and vhandle[3]
|
||||
for(PolyMesh::HalfedgeIter it = mesh.halfedges_begin(); it != mesh.halfedges_end(); ++it) {
|
||||
if( mesh.to_vertex_handle(*it) == vhandle[3] &&
|
||||
mesh.from_vertex_handle(*it) == vhandle[2])
|
||||
{
|
||||
// Collapse edge
|
||||
mesh.collapse(*it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Our mesh now looks like in the illustration above after the collapsing.
|
||||
|
||||
\endcode
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,54 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page smoother_docu Smoother Tools
|
||||
|
||||
\section OM_Smoother_Overview Overview
|
||||
|
||||
The %OpenMesh library provides tools for smoothing Triangle- and Polymeshes
|
||||
|
||||
-# Smoother:
|
||||
-# OpenMesh::Smoother::SmootherT
|
||||
-# OpenMesh::Smoother::LaplaceSmootherT
|
||||
-# OpenMesh::Smoother::JacobiLaplaceSmootherT
|
||||
|
||||
\section OM_Smoother_Usage Usage
|
||||
The smoothers directly work on an OpenMesh. The following example shows how to use them:
|
||||
|
||||
\code
|
||||
#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>
|
||||
|
||||
// Initialize smoother with input mesh
|
||||
OpenMesh::Smoother::JacobiLaplaceSmootherT<MyMesh> smoother(mesh);
|
||||
|
||||
smoother.initialize( Tangential_and_Normal, //Smooth direction
|
||||
C0) //Continuity
|
||||
|
||||
// Execute 3 smooth steps
|
||||
smoother.smooth(3);
|
||||
\endcode
|
||||
|
||||
\section Options
|
||||
|
||||
\subsection Continuity
|
||||
\li C0: shape is continuous, but not the tangent
|
||||
\li C1: shape and tangent are continuous
|
||||
\li C2: preserves curvature
|
||||
|
||||
\subsection Component
|
||||
\li Tangential: Smooth in tangential direction
|
||||
\li Normal: Smooth in normal direction
|
||||
\li Tangential_and_Normal: Smooth in tangential and normal direction
|
||||
|
||||
\subsection localError Local Error
|
||||
By default, this option is disabled.
|
||||
You can set local max. local errors (absolute or relative) via following functions:
|
||||
\code
|
||||
void OpenMesh::Smoother::SmootherT<Mesh>::set_relative_local_error(Scalar _err);
|
||||
void OpenMesh::Smoother::SmootherT<Mesh>::set_absolute_local_error(Scalar _err);
|
||||
void OpenMesh::Smoother::SmootherT<Mesh>::disable_local_error_check();
|
||||
\endcode
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,25 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/** \page mesh_speedup Some Notes on how to speedup OpenMesh
|
||||
|
||||
On this page we collect some hints which can be used to speedup OpenMesh. This list is not complete, so if you
|
||||
have additional hints, just tell us.
|
||||
|
||||
<ul>
|
||||
<li> <b>Visual Studio</b>
|
||||
<ul>
|
||||
<li>The prebuild binaries we ship are not compiled with full optimization enabled. You can build it yourself with full
|
||||
optimization. ("Full Optimization" (Project setting: C/C++ ->> Optimization) ). Please remember that you than have
|
||||
to build everything with this flag to avoid incompatibilities.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page subdivider_docu Sudivision Tools
|
||||
|
||||
\section OM_Subdivider_Overview Overview
|
||||
|
||||
The %OpenMesh library provides a few tools for uniform and adaptive
|
||||
subdivision:
|
||||
|
||||
-# Uniform subdivision
|
||||
-# OpenMesh::Subdivider::Uniform::LoopT
|
||||
-# OpenMesh::Subdivider::Uniform::Sqrt3T
|
||||
-# OpenMesh::Subdivider::Uniform::ModifiedButterflyT
|
||||
-# OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT
|
||||
-# OpenMesh::Subdivider::Uniform::CompositeT
|
||||
-# OpenMesh::Subdivider::Uniform::CatmullClarkT
|
||||
-# OpenMesh::Subdivider::Uniform::MidpointT
|
||||
-# Adaptive subdivision
|
||||
-# OpenMesh::Subdivider::Adaptive::CompositeT
|
||||
-# Simple subdivision
|
||||
-# OpenMesh::Subdivider::Uniform::LongestEdgeT
|
||||
|
||||
\section OM_Subdivider_Usage Usage
|
||||
The subdividers directly work on an OpenMesh. The following example shows how to use them:
|
||||
|
||||
\code
|
||||
#include <OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh>
|
||||
|
||||
// Initialize subdivider
|
||||
OpenMesh::Subdivider::Uniform::CatmullClarkT<PolyMesh> catmull;
|
||||
|
||||
// Execute 3 subdivision steps
|
||||
catmull.attach(mesh_);
|
||||
catmull( 3 );
|
||||
catmull.detach();
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,16 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** \page tools_docu OpenMesh Tools Documentation
|
||||
|
||||
\li \subpage decimater_docu
|
||||
\li \subpage subdivider_docu
|
||||
\li \subpage vdpm_docu
|
||||
\li \subpage smoother_docu
|
||||
\li \subpage holefiller_docu
|
||||
\li \subpage smarttagger_docu
|
||||
\li Miscellaneous
|
||||
OpenMesh::StripifierT
|
||||
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,64 @@
|
||||
/** \page tutorial_01 First Steps - Building a cube
|
||||
|
||||
This small example shows:
|
||||
\li How to declare your type \c MyMesh,
|
||||
\li How to add vertices and faces to a mesh,
|
||||
\li How to write a mesh using the IO functions.
|
||||
|
||||
For each program the first step is to define your type \c
|
||||
MyMesh. %OpenMesh supports general polygonal meshes (faces are polygons
|
||||
with varying number of vertices) as well as specialized triangle
|
||||
meshes (all faces are triangles). In this example we want to build a
|
||||
cube from six quadrangles, therefore we choose the polygonal mesh.
|
||||
|
||||
%OpenMesh also supports different mesh kernels, specifying how all the
|
||||
vertices, edges, and faces are stored internally (see also \ref
|
||||
mesh_kernels_group). However, the storage must provide an array like interface.
|
||||
For the tutorial we use the supplied ArrayKernel. The predefined
|
||||
combinations of TriMesh/PolyMesh and the kernel are
|
||||
contained in \c %OpenMesh/src/OpenMesh/Core/Mesh, we use the
|
||||
<tt>PolyMesh_ArrayKernelT</tt>.
|
||||
|
||||
\dontinclude build_cube.cc
|
||||
\skipline PolyMesh_ArrayKernel
|
||||
\skipline MyMesh
|
||||
|
||||
Now since we have declared our type \c MyMesh, we only have to add 8
|
||||
vertices and 6 quadrangles to build a cube. Adding a vertex is done
|
||||
using the <tt>add_vertex</tt> method. It gets a coordinate and returns
|
||||
a handle to the inserted vertex. We store all handles in an array,
|
||||
since we need them for specifying the faces.
|
||||
|
||||
\skipline vhandle[0]
|
||||
\until vhandle[3]
|
||||
|
||||
<br>In order to add a face to the mesh, we have to build a vector holding
|
||||
the handles to the face's vertices. This vector is passed to the
|
||||
\c add_face method. The following block will create a face from the first
|
||||
four vertices:
|
||||
|
||||
\skipline face_vhandles
|
||||
\until add_face
|
||||
|
||||
<br>The orientation of the face is defined by the order in which the
|
||||
vertices are given: If you look at the frontfacing side of the
|
||||
polygon, then the vertices are in counter-clockwise order.
|
||||
|
||||
After creating all of the six faces, we want to write the resulting
|
||||
mesh to standard output. %OpenMesh provides some basic input/output
|
||||
methods in the namespace OpenMesh::IO:
|
||||
|
||||
\skipline write_
|
||||
|
||||
<br>To use the IO facility of %OpenMesh make sure that the include MeshIO.hh is
|
||||
included first.
|
||||
|
||||
\dontinclude build_cube.cc
|
||||
\skipline MeshIO
|
||||
\until PolyMesh_ArrayKernel
|
||||
|
||||
<br>The complete source looks like this:
|
||||
|
||||
\include build_cube.cc
|
||||
|
||||
**/
|
||||