2016-05-06 04:07:13 +02:00
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
2016-06-29 14:19:20 +02:00
* Copyright ( C ) 2004 \ / ) \ / *
2016-05-06 04:07:13 +02:00
* Visual Computing Lab / \ / | *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved . *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License ( http : //www.gnu.org/licenses/gpl.txt) *
* for more details . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef __VCG_GL_MESH_ATTRIBUTES_INFO
# define __VCG_GL_MESH_ATTRIBUTES_INFO
2016-05-11 14:00:59 +02:00
# include <vector>
# include <string>
2016-06-04 18:20:59 +02:00
# include <bitset>
2016-05-11 14:00:59 +02:00
2016-05-06 04:07:13 +02:00
namespace vcg
{
2016-06-04 18:20:59 +02:00
struct GLMeshAttributesInfo
2016-05-06 04:07:13 +02:00
{
2016-06-04 18:20:59 +02:00
struct Exception : public std : : exception
2016-05-06 04:07:13 +02:00
{
2016-06-04 18:20:59 +02:00
Exception ( const char * text )
2016-05-06 04:07:13 +02:00
: std : : exception ( ) , _text ( text ) { }
2016-06-04 18:20:59 +02:00
~ Exception ( ) throw ( ) { }
2016-05-06 04:07:13 +02:00
inline const char * what ( ) const throw ( ) { return _text . c_str ( ) ; }
private :
std : : string _text ;
} ;
/*WARNING!!!! why not a plain and simple enum? because i need to add further values to this enumeration, but the user of the class should not be interested and/or directly manage those other additional values*/
/*the struct is extended in GLMeshAttributesFeeder class, introducing the ATT_VERTINDICES and ATT_EDGEINDICES values for the class internal use*/
struct ATT_NAMES
{
static const unsigned int ATT_VERTPOSITION = 0 ;
static const unsigned int ATT_VERTNORMAL = 1 ;
static const unsigned int ATT_FACENORMAL = 2 ;
static const unsigned int ATT_VERTCOLOR = 3 ;
static const unsigned int ATT_FACECOLOR = 4 ;
2016-06-04 18:20:59 +02:00
static const unsigned int ATT_VERTTEXTURE = 5 ;
static const unsigned int ATT_WEDGETEXTURE = 6 ;
enum { ATT_ARITY = 7 } ;
2016-05-06 04:07:13 +02:00
ATT_NAMES ( )
: _val ( ATT_VERTPOSITION )
{
}
ATT_NAMES ( unsigned int att )
{
2016-06-30 09:39:22 +02:00
if ( att > = ATT_NAMES : : enumArity ( ) )
2016-06-04 18:20:59 +02:00
throw Exception ( " Out of range value \n " ) ;
2016-05-06 04:07:13 +02:00
else
_val = att ;
}
static unsigned int enumArity ( )
{
2016-06-04 18:20:59 +02:00
return ATT_NAMES : : ATT_ARITY ;
2016-05-06 04:07:13 +02:00
}
operator unsigned int ( ) const
{
return _val ;
}
bool operator = = ( unsigned int r ) const
{
return ( _val = = r ) ;
}
bool operator ! = ( unsigned int r ) const
{
return ( _val ! = r ) ;
}
protected :
unsigned int _val ;
} ;
enum PRIMITIVE_MODALITY
2016-06-04 18:20:59 +02:00
{
PR_POINTS = 0 ,
PR_WIREFRAME_EDGES = 1 ,
PR_WIREFRAME_TRIANGLES = 2 ,
PR_SOLID = 3 ,
PR_ARITY = 4
2016-05-06 04:07:13 +02:00
} ;
2016-06-04 18:20:59 +02:00
static PRIMITIVE_MODALITY next ( PRIMITIVE_MODALITY pm )
2016-05-22 17:40:41 +02:00
{
2016-06-04 18:20:59 +02:00
int tmp = static_cast < int > ( pm ) ;
if ( tmp = = PR_ARITY )
throw Exception ( " PRIMITIVE_MODALITY iterator: PR_ARITY passed as parameter! " ) ;
+ + tmp ;
return static_cast < PRIMITIVE_MODALITY > ( tmp ) ;
2016-05-22 17:40:41 +02:00
}
2016-06-04 18:20:59 +02:00
typedef std : : bitset < PR_ARITY > PRIMITIVE_MODALITY_MASK ;
2016-05-22 17:40:41 +02:00
2016-05-06 04:07:13 +02:00
template < typename ATT_NAMES_DERIVED_CLASS >
class RenderingAtts
{
public :
2016-06-29 14:19:20 +02:00
RenderingAtts ( bool defaultvalue = false )
2016-05-06 04:07:13 +02:00
{
2016-06-29 14:19:20 +02:00
reset ( defaultvalue ) ;
2016-05-06 04:07:13 +02:00
}
RenderingAtts ( const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & att )
{
reset ( ) ;
//_atts = new bool[ATT_NAMES_DERIVED_CLASS::enumArity()];
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
( * this ) [ ii ] = att [ ii ] ;
}
~ RenderingAtts ( )
{
}
RenderingAtts < ATT_NAMES_DERIVED_CLASS > & operator = ( const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & att )
{
reset ( ) ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
( * this ) [ ii ] = att [ ii ] ;
return ( * this ) ;
}
/*bool operator[](ATT_NAMES_DERIVED_CLASS att) const
{
unsigned int ii = att ;
if ( ii > = ATT_NAMES_DERIVED_CLASS : : enumArity ( ) )
throw GLFeederException ( " Out of range value \n " ) ;
return _atts [ ii ] ;
}
bool & operator [ ] ( ATT_NAMES_DERIVED_CLASS att )
{
unsigned int ii = att ;
if ( ii > = ATT_NAMES_DERIVED_CLASS : : enumArity ( ) )
throw GLFeederException ( " Out of range value \n " ) ;
return _atts [ ii ] ;
} */
bool operator [ ] ( unsigned int ind ) const
{
if ( ind > = ATT_NAMES_DERIVED_CLASS : : enumArity ( ) )
2016-06-04 18:20:59 +02:00
throw Exception ( " Out of range value \n " ) ;
2016-05-06 04:07:13 +02:00
return _atts [ ind ] ;
}
bool & operator [ ] ( unsigned int ind )
{
if ( ind > = ATT_NAMES_DERIVED_CLASS : : enumArity ( ) )
2016-06-04 18:20:59 +02:00
throw Exception ( " Out of range value \n " ) ;
2016-05-06 04:07:13 +02:00
return _atts [ ind ] ;
}
2016-06-29 14:19:20 +02:00
void reset ( bool defaultvalue = false )
2016-05-06 04:07:13 +02:00
{
//delete[] _atts;
//_atts = new bool[ATT_NAMES_DERIVED_CLASS::enumArity()];
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
2016-06-29 14:19:20 +02:00
_atts [ ii ] = defaultvalue ;
2016-05-06 04:07:13 +02:00
}
static RenderingAtts < ATT_NAMES_DERIVED_CLASS > unionSet ( const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & a , const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & b )
{
RenderingAtts < ATT_NAMES_DERIVED_CLASS > res ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
res [ ii ] = a [ ii ] | | b [ ii ] ;
return res ;
}
static RenderingAtts < ATT_NAMES_DERIVED_CLASS > complementSet ( const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & a , const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & b )
{
/*TRUTH TABLE*/
//this[ATT_NAMES] | rq[ATT_NAMES] | res
// true | true | false
// true | false | true
// false | true | false
// false | false | false
RenderingAtts < ATT_NAMES_DERIVED_CLASS > res = a ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
{
if ( res [ ii ] )
res [ ii ] = ! ( b [ ii ] ) ;
}
return res ;
}
static RenderingAtts < ATT_NAMES_DERIVED_CLASS > intersectionSet ( const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & a , const RenderingAtts < ATT_NAMES_DERIVED_CLASS > & b )
{
RenderingAtts < ATT_NAMES_DERIVED_CLASS > res ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
res [ ii ] = a [ ii ] & & b [ ii ] ;
return res ;
}
2018-01-04 01:57:04 +01:00
size_t serialize ( std : : string & str ) const
2017-11-27 13:26:15 +01:00
{
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
str . append ( ( ( _atts [ ii ] ) ? " 1 " : " 0 " ) ) ;
return ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ;
}
void deserialize ( const std : : string & str )
{
std : : bitset < ATT_NAMES_DERIVED_CLASS : : ATT_ARITY > bset ( str ) ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES_DERIVED_CLASS : : enumArity ( ) ; + + ii )
_atts [ ATT_NAMES_DERIVED_CLASS : : enumArity ( ) - ii - 1 ] = bset [ ii ] ;
}
2016-05-06 04:07:13 +02:00
//template<typename MESHTYPE>
//static void computeARequestedAttributesSetCompatibleWithMesh(const MESHTYPE& mesh,const PRIMITIVE_MODALITY_MASK,RenderingAtts<ATT_NAMES_DERIVED_CLASS>& rqatt)
//{
// if (mesh.VN() == 0)
// {
// rqatt.reset();
// return;
// }
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTPOSITION] = true;
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTNORMAL] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTNORMAL] && vcg::tri::HasPerVertexNormal(mesh);
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FACENORMAL] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FACENORMAL] && vcg::tri::HasPerFaceNormal(mesh);
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTCOLOR] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTCOLOR] && vcg::tri::HasPerVertexColor(mesh);
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FACECOLOR] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FACECOLOR] && vcg::tri::HasPerFaceColor(mesh);
2016-06-04 18:20:59 +02:00
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FIXEDCOLOR] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_FIXEDCOLOR];
2016-05-06 04:07:13 +02:00
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTTEXTURE] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_VERTTEXTURE] && vcg::tri::HasPerVertexTexCoord(mesh);
// rqatt[ATT_NAMES_DERIVED_CLASS::ATT_WEDGETEXTURE] = rqatt[ATT_NAMES_DERIVED_CLASS::ATT_WEDGETEXTURE] && vcg::tri::HasPerWedgeTexCoord(mesh);
//}
protected :
/*an array of enumArity() bool values*/
bool _atts [ ATT_NAMES_DERIVED_CLASS : : ATT_ARITY ] ;
2016-06-04 18:20:59 +02:00
//std::bitset<ATT_NAMES_DERIVED_CLASS::ATT_ARITY> _atts;
2016-05-06 04:07:13 +02:00
} ;
typedef RenderingAtts < ATT_NAMES > RendAtts ;
2016-05-11 14:00:59 +02:00
struct DebugInfo
{
std : : string _tobeallocated ;
std : : string _tobedeallocated ;
std : : string _tobeupdated ;
std : : string _currentlyallocated ;
std : : vector < std : : string > _perviewdata ;
DebugInfo ( )
: _tobeallocated ( ) , _tobedeallocated ( ) , _tobeupdated ( ) , _currentlyallocated ( ) , _perviewdata ( )
{
}
void reset ( )
{
_tobeallocated . clear ( ) ;
_tobedeallocated . clear ( ) ;
_tobeupdated . clear ( ) ;
_currentlyallocated . clear ( ) ;
_perviewdata . clear ( ) ;
}
2016-06-04 18:20:59 +02:00
static const char * primitiveName ( size_t ind )
{
static std : : string res ;
if ( ind = = size_t ( PR_POINTS ) )
res = std : : string ( " PR_POINTS " ) ;
if ( ind = = size_t ( PR_WIREFRAME_EDGES ) )
res = std : : string ( " PR_WIREFRAME_EDGES " ) ;
if ( ind = = size_t ( PR_WIREFRAME_TRIANGLES ) )
res = std : : string ( " PR_WIREFRAME_TRIANGLES " ) ;
if ( ind = = size_t ( PR_SOLID ) )
res = std : : string ( " PR_SOLID " ) ;
return res . c_str ( ) ;
}
2016-05-11 14:00:59 +02:00
} ;
2016-08-31 13:45:11 +02:00
2016-05-06 04:07:13 +02:00
protected :
struct INT_ATT_NAMES : public ATT_NAMES
{
/*WARNING!!!!!! the edges index bo it's just used only by the edges and quads meshes, NOT by the triangle meshes. Triangles meshes use just the vertex index array*/
/*WHY? cause quads meshes need both index arrays. One to render the "usual" mesh, the other one to render the wireframe quadrangulation on top of it*/
/*A triangles meshes rendered in wireframe or in solid wireframe, in order to save GPU memory, use the glPolygonMode approach*/
/*Edges meshes uses the edges index array just for a matter of coherence*/
2016-06-04 18:20:59 +02:00
/*WARNING!!!! to be changed whit ATT_NAMES::enumArity() (and so on...) as soon as constexpr will be supported by most of the old c++ compilers*/
static const unsigned int ATT_VERTINDICES = 7 ;
static const unsigned int ATT_EDGEINDICES = 8 ;
enum { ATT_ARITY = 9 } ;
2016-05-06 04:07:13 +02:00
INT_ATT_NAMES ( )
: ATT_NAMES ( )
{
}
INT_ATT_NAMES ( unsigned int att )
: ATT_NAMES ( )
{
2016-06-29 15:06:46 +02:00
if ( att > = INT_ATT_NAMES : : enumArity ( ) )
2016-06-04 18:20:59 +02:00
throw Exception ( " Out of range value \n " ) ;
2016-05-06 04:07:13 +02:00
else
_val = att ;
}
static unsigned int enumArity ( )
{
2016-06-04 18:20:59 +02:00
return INT_ATT_NAMES : : ATT_ARITY ;
2016-05-06 04:07:13 +02:00
}
operator unsigned int ( ) const
{
return _val ;
}
} ;
class InternalRendAtts : public RenderingAtts < INT_ATT_NAMES >
{
public :
2017-11-27 13:26:15 +01:00
typedef INT_ATT_NAMES AttName ;
2016-05-06 04:07:13 +02:00
InternalRendAtts ( )
: RenderingAtts < INT_ATT_NAMES > ( )
{
}
InternalRendAtts ( const RendAtts & reqatt )
: RenderingAtts < INT_ATT_NAMES > ( )
{
for ( unsigned int ii = 0 ; ii < ATT_NAMES : : enumArity ( ) ; + + ii )
{
( * this ) [ ii ] = reqatt [ ii ] ;
}
( * this ) [ INT_ATT_NAMES : : ATT_VERTINDICES ] = false ;
( * this ) [ INT_ATT_NAMES : : ATT_EDGEINDICES ] = false ;
}
InternalRendAtts ( const RendAtts & reqatt , PRIMITIVE_MODALITY pm )
: RenderingAtts < INT_ATT_NAMES > ( )
{
for ( unsigned int ii = 0 ; ii < ATT_NAMES : : enumArity ( ) ; + + ii )
( * this ) [ ii ] = reqatt [ ii ] ;
( * this ) [ INT_ATT_NAMES : : ATT_VERTINDICES ] = isVertexIndexingRequired ( reqatt , pm ) ;
( * this ) [ INT_ATT_NAMES : : ATT_EDGEINDICES ] = isEdgeIndexingRequired ( pm ) ;
}
InternalRendAtts ( const RenderingAtts < INT_ATT_NAMES > & r )
: RenderingAtts < INT_ATT_NAMES > ( r )
{
}
//upcast from InternalRendAtts to RendAtts
operator RendAtts ( ) const
{
RendAtts rendatt ;
for ( unsigned int ii = 0 ; ii < ATT_NAMES : : enumArity ( ) ; + + ii )
rendatt [ ii ] = _atts [ ii ] ;
return rendatt ;
}
2016-06-04 18:20:59 +02:00
InternalRendAtts & setIndexingIfNeeded ( PRIMITIVE_MODALITY pm )
{
( * this ) [ INT_ATT_NAMES : : ATT_VERTINDICES ] = isVertexIndexingRequired ( ( * this ) , pm ) ;
( * this ) [ INT_ATT_NAMES : : ATT_EDGEINDICES ] = isEdgeIndexingRequired ( pm ) ;
return ( * this ) ;
}
2016-05-06 04:07:13 +02:00
static bool isPerVertexAttribute ( INT_ATT_NAMES name )
{
return ( ( name = = INT_ATT_NAMES : : ATT_VERTPOSITION ) | | ( name = = INT_ATT_NAMES : : ATT_VERTNORMAL ) | | ( name = = INT_ATT_NAMES : : ATT_VERTCOLOR ) | | ( name = = INT_ATT_NAMES : : ATT_VERTTEXTURE ) ) ;
}
static bool replicatedPipelineNeeded ( const RendAtts & rqatt )
{
return ( rqatt [ INT_ATT_NAMES : : ATT_FACENORMAL ] | | rqatt [ INT_ATT_NAMES : : ATT_FACECOLOR ] | | rqatt [ INT_ATT_NAMES : : ATT_WEDGETEXTURE ] ) ;
}
static bool isVertexIndexingRequired ( const RendAtts & rqatt , PRIMITIVE_MODALITY pm )
{
return ( ! replicatedPipelineNeeded ( rqatt ) & & ( ( pm = = PR_SOLID ) | | ( pm = = PR_WIREFRAME_TRIANGLES ) ) ) ;
}
static bool isEdgeIndexingRequired ( PRIMITIVE_MODALITY pm )
{
return ( pm = = PR_WIREFRAME_EDGES ) ;
}
2016-06-04 18:20:59 +02:00
/*static void suggestedMinimalAttributeSetForPrimitiveModalityMask(PRIMITIVE_MODALITY_MASK pm,RenderingAtts<INT_ATT_NAMES>& atts)
2016-05-11 14:00:59 +02:00
{
if ( ( pm = = ( unsigned int ) ( PR_NONE ) ) | | ( pm = = ( unsigned int ) ( PR_BBOX ) ) )
{
atts . reset ( ) ;
return ;
}
if ( pm & PR_POINTS )
{
atts [ INT_ATT_NAMES : : ATT_VERTPOSITION ] = true ;
}
if ( pm & PR_WIREFRAME_EDGES )
{
atts [ INT_ATT_NAMES : : ATT_VERTPOSITION ] = true ;
atts [ INT_ATT_NAMES : : ATT_EDGEINDICES ] = true ;
}
if ( ( pm & PR_WIREFRAME_TRIANGLES ) | | ( pm & PR_SOLID ) )
{
atts [ INT_ATT_NAMES : : ATT_VERTPOSITION ] = true ;
atts [ INT_ATT_NAMES : : ATT_VERTINDICES ] = true ;
}
2016-06-04 18:20:59 +02:00
} */
2016-05-06 04:07:13 +02:00
} ;
} ;
}
2016-06-30 09:39:22 +02:00
# endif