Rev 39 | Go to most recent revision | Blame | Last modification | View Log | RSS feed
#ifndef __IMESH_TRIMESH_H__
#define __IMESH_TRIMESH_H__
#include <iostream>
#include "AttrVec.h"
namespace IMesh
{
/** \brief Data for a triangle mesh. Not used directly.
The TriMeshData class represents the data contents of a TriMesh, and
it also contains almost all of the functions used to set or get values.
TriMeshData is never used directly, but TriMesh and TriMeshBuilder
inherit from this class. */
class TriMeshData
{
private:
// We do not allow assignment.
TriMeshData& operator=(const TriMeshData&);
protected:
// The following attribute handles contain the attribute numbers
// of the default face attributes face normals and face colours.
// If these attributes are unused, the integers are -1
AttrHandle<CGLA::Vec3f> FA_NORM;
AttrHandle<CGLA::Vec4f> FA_COL;
// The following handles contain the attribute numbers of the
// default vertex attributes: vertex position, normal, colour, and
// texture coordinates.
AttrHandle<CGLA::Vec3f> VA_POS;
AttrHandle<CGLA::Vec3f> VA_NORM;
AttrHandle<CGLA::Vec4f> VA_COL;
AttrHandle<CGLA::Vec4f> VA_TEX;
/// number of faces.
int faces_size;
/// vector of face sets.
std::vector<FaceSet*> face_sets;
/// vector of face attribute vectors
std::vector<AttrVecIf*> face_attr;
/// Mapping from vertex attribute to face set.
std::vector<int> face_set_mapping;
/// vector of vertex attribute vectors.
std::vector<AttrVecIf*> vert_attr;
/** Construct an empty instance of TriMesh data. This constructor is used
by the builder when creating a fresh TriMesh. */
TriMeshData();
/** Copy constructor. This is called from the TriMesh constructor when
the TriMeshBuilder creates a new TriMesh. */
TriMeshData(const TriMeshData& tmd);
/** Resets all variables to the values initialized by the constructor
but it does not remove dynamic memory. */
void clear();
/** Remove all dynamice memory used. */
void clean_up();
public:
//----------------------------------------------------------------------
// Functions that find handles
//----------------------------------------------------------------------
/** Get the handle corresponding to a given vertex attribute vector */
template<class ATTR>
bool get_vattr_handle(const std::string& name,
AttrHandle<ATTR>& handle) const
{
for(int i=0;i< vert_attr.size(); ++i)
{
if (vert_attr[i]->get_name() == name)
{
handle.idx = i;
return true;
}
}
return false;
}
/** Get the handle corresponding to a given face attribute vector */
template<class ATTR>
bool get_fattr_handle(const std::string& name,
AttrHandle<ATTR>& handle) const
{
for(int i=0;i< face_attr.size(); ++i)
{
if (face_attr[i]->get_name() == name)
{
handle.idx = i;
return true;
}
}
return false;
}
// The following functions return the number of faces, vertices, and attributes.
/// Returns the number of faces
int no_faces() const
{
return faces_size;
}
/// Return the number of vertex attributes associated with the attribute handles
template<class ATTR>
int no_vattrib(const AttrHandle<ATTR>& handle) const
{
assert(handle.idx>=0);
return vert_attr[handle.idx]->size();
}
/// Return the number of vertices.
int no_vertices() const
{
return no_vattrib(VA_POS);
}
/// Return the number of vertex normals.
int no_vnorm() const
{
if(VA_NORM.idx >=0)
return no_vattrib(VA_NORM);
return 0;
}
/// Return the number of vertex colours
int no_vcol() const
{
if(VA_COL.idx >=0)
return no_vattrib(VA_COL);
return 0;
}
/// Return the number of vertex texture coords
int no_vtex() const
{
if(VA_TEX.idx >=0)
return no_vattrib(VA_TEX);
return 0;
}
//----------------------------------------------------------------------
// Set functions
//----------------------------------------------------------------------
/** Set face. The arguments are the face set, the face index and a Vec3i
containing the three indices. */
CGLA::Vec3i& face(int fidx, int face_set=0)
{
assert(fidx < face_sets[face_set]->size());
return (*face_sets[face_set])[fidx];
}
/** Template function used to set a face attribute. The template argument
is the attribute type. The arguments are the atttribute number,
the face index, and the value. */
template<class ATTR>
ATTR& fattr(AttrHandle<ATTR> handle, int fidx)
{
return attr<ATTR>(*face_attr[handle.idx],fidx);
}
/** Template function used to set a vertex attribute. The template
argument is the attribute type. The arguments are the attribute
number, the index of a face, the corresponding corner, and the
value of the attribute belonging to the thus specified vertex. */
template<class ATTR>
ATTR& vattr(AttrHandle<ATTR> handle, int fidx, int crnr)
{
int face_set = face_set_mapping[handle.idx];
int vidx = (*face_sets[face_set])[fidx][crnr];
return attr<ATTR>(*vert_attr[handle.idx],vidx);
}
/** Template function used to set a vertex attribute. The template
argument is the type of the attribute, and the arugments are the
attribute number, the vertex index, and the value. */
template<class ATTR>
ATTR& vattr(AttrHandle<ATTR> handle, int vidx)
{
return attr<ATTR>(*vert_attr[handle.idx],vidx);
}
//----------------------------------------------------------------------
// Get functions
//----------------------------------------------------------------------
/** Get a face. Returns a Vec3i with the face's corner indices.
The arguments are the "face set" and the face index. */
const CGLA::Vec3i face(int fidx,int face_set=0) const
{
assert(fidx < face_sets[face_set]->size());
return (*face_sets[face_set])[fidx];
}
/// Template function that gets face attribute.
template<class ATTR>
const ATTR& fattr(AttrHandle<ATTR> handle, int fidx) const
{
return attr<ATTR>(*face_attr[handle.idx],fidx);
}
/// Template function that gets vertex attribute from face index and corner
template<class ATTR>
const ATTR& vattr(AttrHandle<ATTR> handle, int fidx, int crnr) const
{
int face_set = face_set_mapping[handle.idx];
int vidx = (*face_sets[face_set])[fidx][crnr];
return attr<ATTR>(*vert_attr[handle.idx],vidx);
}
/// Get vertex attribute from vertex index
template<class ATTR>
const ATTR& vattr(AttrHandle<ATTR> handle, int vidx) const
{
return attr<ATTR>(*vert_attr[handle.idx],vidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the face normal
// ----------------------------------------------------------------------
/// Set a face normal
const CGLA::Vec3f& fnorm(int fidx)
{
return fattr(FA_NORM, fidx);
}
/// Get a face normal
const CGLA::Vec3f& fnorm(int fidx) const
{
return fattr(FA_NORM, fidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the face colour
// ----------------------------------------------------------------------
/// Set a face colour
CGLA::Vec4f& fcol(int fidx)
{
return fattr(FA_COL, fidx);
}
/// Get a face colour
const CGLA::Vec4f& fcol(int fidx) const
{
return fattr(FA_COL, fidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the vertex position
// ----------------------------------------------------------------------
/// Set a vertex position using a face index and corner.
CGLA::Vec3f& vpos(int fidx, int crnr)
{
return vattr(VA_POS, fidx, crnr);
}
/// Set a vertex position using a direct vertex index
CGLA::Vec3f& vpos(int vidx)
{
return vattr(VA_POS, vidx);
}
/// Get a vertex position using a face index and a corner
const CGLA::Vec3f& vpos(int fidx, int crnr) const
{
return vattr(VA_POS, fidx, crnr);
}
/// Get a vertex position using a direct index
const CGLA::Vec3f& vpos(int vidx) const
{
return vattr(VA_POS, vidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the vertex normal
// ----------------------------------------------------------------------
/// Set a vertex normal using a face index and corner.
CGLA::Vec3f& vnorm(int fidx, int crnr)
{
return vattr(VA_NORM, fidx, crnr);
}
/// Set a vertex normal using a direct vertex index
CGLA::Vec3f& vnorm(int vidx)
{
return vattr(VA_NORM, vidx);
}
/// Get a vertex normal using a face index and a corner
const CGLA::Vec3f& vnorm(int fidx, int crnr) const
{
return vattr(VA_NORM, fidx, crnr);
}
/// Get a vertex normal using a direct index
const CGLA::Vec3f& vnorm(int vidx) const
{
return vattr(VA_NORM, vidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the vertex colour
// ----------------------------------------------------------------------
/// Set a vertex colour using a face index and corner.
CGLA::Vec4f& vcol(int fidx, int crnr)
{
return vattr(VA_COL, fidx, crnr);
}
/// Set a vertex colour using a direct vertex index
CGLA::Vec4f& vcol(int vidx)
{
return vattr(VA_COL, vidx);
}
/// Get a vertex colour using a face index and a corner
const CGLA::Vec4f& vcol(int fidx, int crnr) const
{
return vattr(VA_COL, fidx, crnr);
}
/// Get a vertex colour using a direct index
const CGLA::Vec4f& vcol(int vidx) const
{
return vattr(VA_COL, vidx);
}
// ----------------------------------------------------------------------
// Utility functions for getting and setting the vertex tex coord
// ----------------------------------------------------------------------
/// Set a vertex texture coord using a face index and corner.
CGLA::Vec4f& vtex(int fidx, int crnr)
{
return vattr(VA_TEX, fidx, crnr);
}
/// Set a vertex texture coord using a direct vertex index
CGLA::Vec4f& vtex(int vidx)
{
return vattr(VA_TEX, vidx);
}
/// Get a vertex texture coord using a face index and a corner
const CGLA::Vec4f& vtex(int fidx, int crnr) const
{
return vattr(VA_TEX, fidx, crnr);
}
/// Get a vertex texture coord using a direct index
const CGLA::Vec4f& vtex(int vidx) const
{
return vattr(VA_TEX, vidx);
}
};
class TriMeshBuilder;
/** \brief The IMesh triangle mesh class.
The TriMesh class represents a triangle mesh. It cannot be instantiated
except by the TriMeshBuilder class. All data and methods are defined
in the TriMeshData class from which this class inherits. */
class TriMesh: public TriMeshData
{
friend class TriMeshBuilder;
private:
// The following constructors are private and undefined. Hence
// they cannot be used.
TriMesh(const TriMesh&);
TriMesh& operator=(const TriMesh&);
TriMesh();
// The only legal constructor takes a TriMeshData object as argument
// This constructor can only be called by the TriMeshBuilder since it
// us a friend of TriMesh.
/// Construct a TriMesh from an instance of TriMeshData
TriMesh(const TriMeshData& tmd): TriMeshData(tmd) {}
void *data;
public:
/// Destructor deletes all attribute vectors.
~TriMesh()
{
clean_up();
}
void get_bsphere(CGLA::Vec3f& c, float& r) const;
void get_bbox(CGLA::Vec3f& p0, CGLA::Vec3f& p7) const;
void set_data(void *data) {
this->data = data;
}
void* get_data() {
return data;
}
};
}
#endif