Subversion Repositories gelsvn

Rev

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
{

        /** 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;

        /** 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