2015-04-28 11:54:17 +00:00
/* ========================================================================= *
2009-06-04 08:46:29 +00:00
* *
* OpenMesh *
2015-04-28 11:33:32 +00:00
* Copyright ( c ) 2001 - 2015 , RWTH - Aachen University *
2015-04-28 13:07:46 +00:00
* Department of Computer Graphics and Multimedia *
2015-04-28 11:33:32 +00:00
* 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 . *
2015-04-28 11:54:17 +00:00
* *
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2009-06-04 08:46:29 +00:00
2019-01-15 11:21:12 +01:00
2009-02-06 13:37:46 +00:00
//=============================================================================
//
// CLASS TriMeshT
//
//=============================================================================
# ifndef OPENMESH_TRIMESH_HH
# define OPENMESH_TRIMESH_HH
//== INCLUDES =================================================================
# include <OpenMesh/Core/System/config.h>
# include <OpenMesh/Core/Mesh/PolyMeshT.hh>
2017-07-28 08:43:13 +02:00
# include <OpenMesh/Core/Mesh/Tags.hh>
2009-02-06 13:37:46 +00:00
# include <vector>
//== NAMESPACES ===============================================================
namespace OpenMesh {
//== CLASS DEFINITION =========================================================
/** \class TriMeshT TriMeshT.hh <OpenMesh/Mesh/TriMeshT.hh>
Base type for a triangle mesh .
Base type for a triangle mesh , parameterized by a mesh kernel . The
mesh inherits all methods from the kernel class and the
more general polygonal mesh PolyMeshT . Therefore it provides
the same types for items , handles , iterators and so on .
\ param Kernel : template argument for the mesh kernel
\ note You should use the predefined mesh - kernel combinations in
\ ref mesh_types_group
\ see \ ref mesh_type
\ see OpenMesh : : PolyMeshT
*/
template < class Kernel >
class TriMeshT : public PolyMeshT < Kernel >
{
public :
// self
typedef TriMeshT < Kernel > This ;
typedef PolyMeshT < Kernel > PolyMesh ;
//@{
2017-07-28 08:43:13 +02:00
/// Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT)
static constexpr bool is_polymesh ( ) { return false ; }
static constexpr bool is_trimesh ( ) { return true ; }
using ConnectivityTag = TriConnectivityTag ;
2009-02-06 13:37:46 +00:00
enum { IsPolyMesh = 0 } ;
enum { IsTriMesh = 1 } ;
//@}
//--- items ---
typedef typename PolyMesh : : Scalar Scalar ;
typedef typename PolyMesh : : Point Point ;
typedef typename PolyMesh : : Normal Normal ;
typedef typename PolyMesh : : Color Color ;
typedef typename PolyMesh : : TexCoord1D TexCoord1D ;
typedef typename PolyMesh : : TexCoord2D TexCoord2D ;
typedef typename PolyMesh : : TexCoord3D TexCoord3D ;
typedef typename PolyMesh : : Vertex Vertex ;
typedef typename PolyMesh : : Halfedge Halfedge ;
typedef typename PolyMesh : : Edge Edge ;
typedef typename PolyMesh : : Face Face ;
//--- handles ---
typedef typename PolyMesh : : VertexHandle VertexHandle ;
typedef typename PolyMesh : : HalfedgeHandle HalfedgeHandle ;
typedef typename PolyMesh : : EdgeHandle EdgeHandle ;
typedef typename PolyMesh : : FaceHandle FaceHandle ;
//--- iterators ---
typedef typename PolyMesh : : VertexIter VertexIter ;
typedef typename PolyMesh : : ConstVertexIter ConstVertexIter ;
typedef typename PolyMesh : : EdgeIter EdgeIter ;
typedef typename PolyMesh : : ConstEdgeIter ConstEdgeIter ;
typedef typename PolyMesh : : FaceIter FaceIter ;
typedef typename PolyMesh : : ConstFaceIter ConstFaceIter ;
//--- circulators ---
typedef typename PolyMesh : : VertexVertexIter VertexVertexIter ;
typedef typename PolyMesh : : VertexOHalfedgeIter VertexOHalfedgeIter ;
typedef typename PolyMesh : : VertexIHalfedgeIter VertexIHalfedgeIter ;
typedef typename PolyMesh : : VertexEdgeIter VertexEdgeIter ;
typedef typename PolyMesh : : VertexFaceIter VertexFaceIter ;
typedef typename PolyMesh : : FaceVertexIter FaceVertexIter ;
typedef typename PolyMesh : : FaceHalfedgeIter FaceHalfedgeIter ;
typedef typename PolyMesh : : FaceEdgeIter FaceEdgeIter ;
typedef typename PolyMesh : : FaceFaceIter FaceFaceIter ;
typedef typename PolyMesh : : ConstVertexVertexIter ConstVertexVertexIter ;
typedef typename PolyMesh : : ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter ;
typedef typename PolyMesh : : ConstVertexIHalfedgeIter ConstVertexIHalfedgeIter ;
typedef typename PolyMesh : : ConstVertexEdgeIter ConstVertexEdgeIter ;
typedef typename PolyMesh : : ConstVertexFaceIter ConstVertexFaceIter ;
typedef typename PolyMesh : : ConstFaceVertexIter ConstFaceVertexIter ;
typedef typename PolyMesh : : ConstFaceHalfedgeIter ConstFaceHalfedgeIter ;
typedef typename PolyMesh : : ConstFaceEdgeIter ConstFaceEdgeIter ;
typedef typename PolyMesh : : ConstFaceFaceIter ConstFaceFaceIter ;
// --- constructor/destructor
/// Default constructor
TriMeshT ( ) : PolyMesh ( ) { }
2016-12-08 18:18:59 +01:00
explicit TriMeshT ( PolyMesh rhs ) : PolyMesh ( ( rhs . triangulate ( ) , rhs ) )
{
}
2009-02-06 13:37:46 +00:00
/// Destructor
virtual ~ TriMeshT ( ) { }
//--- halfedge collapse / vertex split ---
2012-09-21 07:56:50 +00:00
/** \brief Vertex Split: inverse operation to collapse().
*
* Insert the new vertex at position v0 . The vertex will be added
2020-03-18 09:21:21 +01:00
* as the inverse of the edge collapse . The faces above the split
2012-09-21 07:56:50 +00:00
* will be correctly attached to the two new edges
*
2020-03-18 09:21:21 +01:00
* < pre >
*
2012-09-21 07:56:50 +00:00
* Before :
* v_l v0 v_r
* x x x
* \ /
* \ /
* \ /
* \ /
* \ /
* \ /
* x
* v1
*
* After :
* v_l v0 v_r
* x - - - - - - x - - - - - - x
* \ | /
* \ | /
* \ | /
* \ | /
* \ | /
* \ | /
* x
* v1
*
2020-03-18 09:21:21 +01:00
* < / pre >
*
2012-09-21 07:56:50 +00:00
* @ param _v0_point Point position for the new point
* @ param _v1 Vertex that will be split
* @ param _vl Left vertex handle
* @ param _vr Right vertex handle
* @ return Newly inserted halfedge
*/
2009-02-06 13:37:46 +00:00
inline HalfedgeHandle vertex_split ( Point _v0_point , VertexHandle _v1 ,
VertexHandle _vl , VertexHandle _vr )
2014-08-28 11:44:20 +00:00
{ return PolyMesh : : vertex_split ( this - > add_vertex ( _v0_point ) , _v1 , _vl , _vr ) ; }
2009-02-06 13:37:46 +00:00
2012-09-21 07:56:50 +00:00
/** \brief Vertex Split: inverse operation to collapse().
*
* Insert the new vertex at position v0 . The vertex will be added
2020-03-18 09:21:21 +01:00
* as the inverse of the edge collapse . The faces above the split
2012-09-21 07:56:50 +00:00
* will be correctly attached to the two new edges
*
2020-03-18 09:21:21 +01:00
* < pre >
*
2012-09-21 07:56:50 +00:00
* Before :
* v_l v0 v_r
* x x x
* \ /
* \ /
* \ /
* \ /
* \ /
* \ /
* x
* v1
*
* After :
* v_l v0 v_r
* x - - - - - - x - - - - - - x
* \ | /
* \ | /
* \ | /
* \ | /
* \ | /
* \ | /
* x
* v1
*
2020-03-18 09:21:21 +01:00
* < / pre >
*
2012-09-21 07:56:50 +00:00
* @ param _v0 Vertex handle for the newly inserted point ( Input has to be unconnected ! )
* @ param _v1 Vertex that will be split
* @ param _vl Left vertex handle
* @ param _vr Right vertex handle
* @ return Newly inserted halfedge
*/
2009-02-06 13:37:46 +00:00
inline HalfedgeHandle vertex_split ( VertexHandle _v0 , VertexHandle _v1 ,
VertexHandle _vl , VertexHandle _vr )
{ return PolyMesh : : vertex_split ( _v0 , _v1 , _vl , _vr ) ; }
2012-09-19 15:42:03 +00:00
/** \brief Edge split (= 2-to-4 split)
*
* The properties of the new edges will be undefined !
*
2012-09-21 07:56:50 +00:00
*
2012-09-19 15:42:03 +00:00
* @ param _eh Edge handle that should be splitted
* @ param _p New point position that will be inserted at the edge
* @ return Vertex handle of the newly added vertex
*/
2019-10-17 14:55:25 +02:00
inline SmartVertexHandle split ( EdgeHandle _eh , const Point & _p )
2012-09-21 07:56:50 +00:00
{
//Do not call PolyMeshT function below as this does the wrong operation
2019-10-17 14:55:25 +02:00
const SmartVertexHandle vh = this - > add_vertex ( _p ) ; Kernel : : split ( _eh , vh ) ; return vh ;
2012-09-21 07:56:50 +00:00
}
2009-02-06 13:37:46 +00:00
2012-09-19 15:42:03 +00:00
/** \brief Edge split (= 2-to-4 split)
*
* The properties of the new edges will be adjusted to the properties of the original edge
*
* @ param _eh Edge handle that should be splitted
* @ param _p New point position that will be inserted at the edge
* @ return Vertex handle of the newly added vertex
*/
2019-10-17 14:55:25 +02:00
inline SmartVertexHandle split_copy ( EdgeHandle _eh , const Point & _p )
2012-09-21 07:56:50 +00:00
{
//Do not call PolyMeshT function below as this does the wrong operation
2019-10-17 14:55:25 +02:00
const SmartVertexHandle vh = this - > add_vertex ( _p ) ; Kernel : : split_copy ( _eh , vh ) ; return vh ;
2012-09-21 07:56:50 +00:00
}
2012-09-19 15:42:03 +00:00
/** \brief Edge split (= 2-to-4 split)
*
* The properties of the new edges will be undefined !
*
* @ param _eh Edge handle that should be splitted
* @ param _vh Vertex handle that will be inserted at the edge
*/
2009-02-06 13:37:46 +00:00
inline void split ( EdgeHandle _eh , VertexHandle _vh )
2012-09-21 07:56:50 +00:00
{
//Do not call PolyMeshT function below as this does the wrong operation
Kernel : : split ( _eh , _vh ) ;
}
2009-02-06 13:37:46 +00:00
2012-09-19 15:42:03 +00:00
/** \brief Edge split (= 2-to-4 split)
*
* The properties of the new edges will be adjusted to the properties of the original edge
*
* @ param _eh Edge handle that should be splitted
* @ param _vh Vertex handle that will be inserted at the edge
*/
inline void split_copy ( EdgeHandle _eh , VertexHandle _vh )
2012-09-21 07:56:50 +00:00
{
//Do not call PolyMeshT function below as this does the wrong operation
Kernel : : split_copy ( _eh , _vh ) ;
}
2012-09-19 15:42:03 +00:00
/** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function).
*
* The properties of the new faces will be undefined !
*
* @ param _fh Face handle that should be splitted
* @ param _p New point position that will be inserted in the face
2012-11-26 12:52:24 +00:00
*
* @ return Vertex handle of the new vertex
2012-09-19 15:42:03 +00:00
*/
2019-10-17 14:55:25 +02:00
inline SmartVertexHandle split ( FaceHandle _fh , const Point & _p )
{ const SmartVertexHandle vh = this - > add_vertex ( _p ) ; PolyMesh : : split ( _fh , vh ) ; return vh ; }
2009-02-06 13:37:46 +00:00
2012-09-19 15:42:03 +00:00
/** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function).
*
* The properties of the new faces will be adjusted to the properties of the original face
*
* @ param _fh Face handle that should be splitted
* @ param _p New point position that will be inserted in the face
2012-11-26 12:52:24 +00:00
*
* @ return Vertex handle of the new vertex
2012-09-19 15:42:03 +00:00
*/
2019-10-17 14:55:25 +02:00
inline SmartVertexHandle split_copy ( FaceHandle _fh , const Point & _p )
{ const SmartVertexHandle vh = this - > add_vertex ( _p ) ; PolyMesh : : split_copy ( _fh , vh ) ; return vh ; }
2012-09-19 15:42:03 +00:00
2017-04-26 16:58:38 +02:00
/** \brief Face split (= 1-to-4) split, splits edges at midpoints and adds 4 new faces in the interior).
*
* @ param _fh Face handle that should be splitted
*/
inline void split ( FaceHandle _fh )
{
// Collect halfedges of face
HalfedgeHandle he0 = this - > halfedge_handle ( _fh ) ;
HalfedgeHandle he1 = this - > next_halfedge_handle ( he0 ) ;
HalfedgeHandle he2 = this - > next_halfedge_handle ( he1 ) ;
EdgeHandle eh0 = this - > edge_handle ( he0 ) ;
EdgeHandle eh1 = this - > edge_handle ( he1 ) ;
EdgeHandle eh2 = this - > edge_handle ( he2 ) ;
// Collect points of face
VertexHandle p0 = this - > to_vertex_handle ( he0 ) ;
VertexHandle p1 = this - > to_vertex_handle ( he1 ) ;
VertexHandle p2 = this - > to_vertex_handle ( he2 ) ;
// Calculate midpoint coordinates
2018-04-12 15:16:50 +02:00
const Point new0 = ( this - > point ( p0 ) + this - > point ( p2 ) ) * static_cast < typename vector_traits < Point > : : value_type > ( 0.5 ) ;
const Point new1 = ( this - > point ( p0 ) + this - > point ( p1 ) ) * static_cast < typename vector_traits < Point > : : value_type > ( 0.5 ) ;
const Point new2 = ( this - > point ( p1 ) + this - > point ( p2 ) ) * static_cast < typename vector_traits < Point > : : value_type > ( 0.5 ) ;
2017-04-26 16:58:38 +02:00
// Add vertices at midpoint coordinates
VertexHandle v0 = this - > add_vertex ( new0 ) ;
VertexHandle v1 = this - > add_vertex ( new1 ) ;
VertexHandle v2 = this - > add_vertex ( new2 ) ;
2017-05-30 14:35:54 +02:00
const bool split0 = ! this - > is_boundary ( eh0 ) ;
const bool split1 = ! this - > is_boundary ( eh1 ) ;
const bool split2 = ! this - > is_boundary ( eh2 ) ;
2017-04-26 16:58:38 +02:00
// delete original face
this - > delete_face ( _fh ) ;
// split boundary edges of deleted face ( if not boundary )
if ( split0 ) {
this - > split ( eh0 , v0 ) ;
}
if ( split1 ) {
this - > split ( eh1 , v1 ) ;
}
if ( split2 ) {
this - > split ( eh2 , v2 ) ;
}
// Retriangulate
this - > add_face ( v0 , p0 , v1 ) ;
this - > add_face ( p2 , v0 , v2 ) ;
this - > add_face ( v2 , v1 , p1 ) ;
this - > add_face ( v2 , v0 , v1 ) ;
}
2012-09-19 15:42:03 +00:00
/** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function).
*
* The properties of the new faces will be undefined !
*
* @ param _fh Face handle that should be splitted
* @ param _vh Vertex handle that will be inserted at the face
*/
2009-02-06 13:37:46 +00:00
inline void split ( FaceHandle _fh , VertexHandle _vh )
{ PolyMesh : : split ( _fh , _vh ) ; }
2012-09-19 15:42:03 +00:00
/** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function).
*
* The properties of the new faces will be adjusted to the properties of the original face
*
* @ param _fh Face handle that should be splitted
* @ param _vh Vertex handle that will be inserted at the face
*/
inline void split_copy ( FaceHandle _fh , VertexHandle _vh )
{ PolyMesh : : split_copy ( _fh , _vh ) ; }
2019-03-14 16:59:07 +01:00
/** \brief Calculates the area of a face
*
* @ param _fh Handle of the face to calculate the area of
*/
Scalar calc_face_area ( FaceHandle _fh ) const
{
const HalfedgeHandle heh = this - > halfedge_handle ( _fh ) ;
return this - > calc_sector_area ( heh ) ;
}
2010-03-09 13:32:23 +00:00
/** \name Normal vector computation
*/
//@{
/** Calculate normal vector for face _fh (specialized for TriMesh). */
Normal calc_face_normal ( FaceHandle _fh ) const ;
//@}
2009-02-06 13:37:46 +00:00
} ;
//=============================================================================
} // namespace OpenMesh
//=============================================================================
# if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_TRIMESH_C)
# define OPENMESH_TRIMESH_TEMPLATES
2019-02-20 12:14:46 +01:00
# include "TriMeshT_impl.hh"
2009-02-06 13:37:46 +00:00
# endif
//=============================================================================
# endif // OPENMESH_TRIMESH_HH defined
//=============================================================================