@ -26,41 +26,69 @@
*/
/** @file
* @ brief Function @ ref Magnum : : MeshTools : : subdivide ( )
* @ brief Function @ ref Magnum : : MeshTools : : subdivide ( ) , @ ref Magnum : : MeshTools : : subdivideInPlace ( )
*/
# include <vector>
# include <Corrade/Containers/ArrayViewStl.h>
# include <Corrade/Utility/Assert.h>
namespace Magnum { namespace MeshTools {
# ifndef DOXYGEN_GENERATING_OUTPUT
template < class Vertex , class Interpolator > void subdivideInPlace ( Containers : : ArrayView < UnsignedInt > indices , Containers : : ArrayView < Vertex > vertices , Interpolator interpolator ) ;
# endif
/**
@ brief Subdivide the mesh
@ tparam Vertex Vertex data type
@ tparam Interpolator See ` interpolator ` function parameter
@ tparam Interpolator See the @ p interpolator function parameter
@ param [ in , out ] indices Index array to operate on
@ param [ in , out ] vertices Vertex array to operate on
@ param interpolator Functor or function pointer which interpolates
two adjacent vertices : ` Vertex interpolator ( Vertex a , Vertex b ) `
two adjacent vertices : @ cpp Vertex interpolator ( Vertex a , Vertex b ) @ ce
Goes through all triangle faces and subdivides them into four new . Removing
duplicate vertices in the mesh is up to user .
duplicate vertices in the mesh is up to the user .
@ see @ ref subdivideInPlace ( )
*/
template < class Vertex , class Interpolator > void subdivide ( std : : vector < UnsignedInt > & indices , std : : vector < Vertex > & vertices , Interpolator interpolator ) {
CORRADE_ASSERT ( ! ( indices . size ( ) % 3 ) , " MeshTools::subdivide(): index count is not divisible by 3! " , ) ;
/* For each triangle it'll generate three new vertices and three more
triangles */
indices . reserve ( indices . size ( ) * 4 ) ;
vertices . reserve ( vertices . size ( ) + indices . size ( ) ) ;
vertices . resize ( vertices . size ( ) + indices . size ( ) ) ;
indices . resize ( indices . size ( ) * 4 ) ;
subdivideInPlace ( Containers : : arrayView ( indices ) , Containers : : arrayView ( vertices ) , interpolator ) ;
}
/**
@ brief Subdivide the mesh in - place
@ tparam Vertex Vertex data type
@ tparam Interpolator See the @ p interpolator function parameter
@ param [ in , out ] indices Index array to operate on
@ param [ in , out ] vertices Vertex array to operate on
@ param interpolator Functor or function pointer which interpolates
two adjacent vertices : @ cpp Vertex interpolator ( Vertex a , Vertex b ) @ ce
Assumes the original triangle mesh indices are in the first quarter of the
@ p indices array and original vertices in a prefix of the @ p vertices array ,
with @ cpp indices . size ( ) @ ce left at the end of it for newly added vertices .
Then goes through all those triangle faces and subdivides them into four new ,
filling up the remaining space in both . Removing duplicate vertices in the mesh
is up to the user .
*/
template < class Vertex , class Interpolator > void subdivideInPlace ( Containers : : ArrayView < UnsignedInt > indices , Containers : : ArrayView < Vertex > vertices , Interpolator interpolator ) {
CORRADE_ASSERT ( ! ( indices . size ( ) % 12 ) , " MeshTools::subdivideInto(): can't divide " < < indices . size ( ) < < " indices to four parts with each having triangle faces " , ) ;
/* Subdivide each face to four new */
std : : size_t indexCount = indices . size ( ) ;
const std : : size_t indexCount = indices . size ( ) / 4 ;
std : : size_t indexOffset = indexCount ;
std : : size_t vertexOffset = vertices . size ( ) - indexCount ;
for ( std : : size_t i = 0 ; i ! = indexCount ; i + = 3 ) {
/* Interpolate each side */
UnsignedInt newVertices [ 3 ] ;
for ( int j = 0 ; j ! = 3 ; + + j ) {
newVertices [ j ] = vertices . size ( ) ; vertices . push_back ( interpolator ( vertices [ indices [ i + j ] ] , vertices [ indices [ i + ( j + 1 ) % 3 ] ] ) ) ;
newVertices [ j ] = vertexOffset ;
vertices [ vertexOffset + + ] = interpolator ( vertices [ indices [ i + j ] ] , vertices [ indices [ i + ( j + 1 ) % 3 ] ] ) ;
}
/*
@ -76,11 +104,17 @@ template<class Vertex, class Interpolator> void subdivide(std::vector<UnsignedIn
/ \ / \
orig 1 - - - - - new 1 - - - - orig 2
*/
indices . insert ( indices . end ( ) , {
indices [ i ] , newVertices [ 0 ] , newVertices [ 2 ] ,
newVertices [ 0 ] , indices [ i + 1 ] , newVertices [ 1 ] ,
newVertices [ 2 ] , newVertices [ 1 ] , indices [ i + 2 ]
} ) ;
indices [ indexOffset + + ] = indices [ i ] ;
indices [ indexOffset + + ] = newVertices [ 0 ] ;
indices [ indexOffset + + ] = newVertices [ 2 ] ;
indices [ indexOffset + + ] = newVertices [ 0 ] ;
indices [ indexOffset + + ] = indices [ i + 1 ] ;
indices [ indexOffset + + ] = newVertices [ 1 ] ;
indices [ indexOffset + + ] = newVertices [ 2 ] ;
indices [ indexOffset + + ] = newVertices [ 1 ] ;
indices [ indexOffset + + ] = indices [ i + 2 ] ;
for ( std : : size_t j = 0 ; j ! = 3 ; + + j )
indices [ i + j ] = newVertices [ j ] ;
}