Subversion Repositories gelsvn

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

#pragma warning(disable: 4786) // disable warning C4786: symbol greater than 255 

#include <iostream>
#include "TriMeshBuilder.h"

#define my_max(x,y) ((x)>(y)?(x):(y))

using namespace std;

namespace IMesh
{

        TriMeshBuilder::TriMeshBuilder(): did_call_get_trimesh(false)
        {
                // Register the default face set
                register_face_set();
                
                // Register the vertex position attribute. There is really no sense
                // in a mesh without geometry, so this is default.
                register_vertex_attribute("VA_POS", VA_POS);
                assert(VA_POS.idx == 0);
        }

        void TriMeshBuilder::clear()
        {
                // If a trimesh was not emitted, we remove any allocated dynamic memory
                if(!did_call_get_trimesh)
                        clean_up();

                // Clear all variables
                TriMeshData::clear();
                did_call_get_trimesh = false;

                // Register the default face set
                register_face_set();
                
                // Register the vertex position attribute. There is really no sense
                // in a mesh without geometry, so this is default.
                register_vertex_attribute("VA_POS", VA_POS);
                assert(VA_POS.idx == 0);
        }
        
        TriMeshBuilder::~TriMeshBuilder()
        {
                // If a trimesh was not emitted, we remove allocated dynamic memory.
                if(!did_call_get_trimesh)
                        clean_up();
        }
                
        int TriMeshBuilder::register_face_set()
        {
                assert(!did_call_get_trimesh);
                int n = face_sets.size();
                if(n==0)
                        face_sets.push_back(new FaceSet);
                else 
                        face_sets.push_back(new FaceSet(*face_sets[0]));
                return n;
        }

        void TriMeshBuilder::register_face_colors()
        {
                assert(!did_call_get_trimesh);
                register_face_attribute("FA_COL", FA_COL);
        }
        
        void TriMeshBuilder::register_face_normals()
        {
                assert(!did_call_get_trimesh);
                register_face_attribute("FA_NORM", FA_NORM);
        }

                
        void TriMeshBuilder::register_vertex_normals(int face_set)
        {
                assert(!did_call_get_trimesh);
                register_vertex_attribute("VA_NORM", VA_NORM, face_set);
        }
        

        void TriMeshBuilder::register_vertex_colors(int face_set)
        {
                assert(!did_call_get_trimesh);
                register_vertex_attribute("VA_COL", VA_COL, face_set);
        }
                

        void TriMeshBuilder::register_vertex_texcoords(int face_set)
        {
                assert(!did_call_get_trimesh);
                register_vertex_attribute("VA_TEX", VA_TEX, face_set);
        }
        
        void TriMeshBuilder::add_face(const CGLA::Vec3i& face)
        {
                assert(!did_call_get_trimesh);
                ++faces_size;

                int i; // To placate MSVC 6.0 ... which sucks
                for(i=0;i<face_sets.size();++i)
                        face_sets[i]->push_back(face);
        }


        
        TriMesh* TriMeshBuilder::get_trimesh() 
        {
                assert(!did_call_get_trimesh);

#ifndef NDEBUG
                int face_set_no;  // To placate MSVC 6.0 ... which sucks
                for(face_set_no=0;face_set_no<face_sets.size();++face_set_no)
                        {
                                int n = face_sets[face_set_no]->size();
                                if(n != faces_size)
                                        {
                                                cout << "Face set " << face_set_no << " has wrong size : "
                                                                 << n << endl;
                                                exit(1);
                                        }

                                int j;
                                int max_vertex=-1;
                                for(j=0;j<n;++j)
                                        {
                                                max_vertex = my_max(max_vertex, (*face_sets[face_set_no])[j][0]);
                                                max_vertex = my_max(max_vertex, (*face_sets[face_set_no])[j][1]);
                                                max_vertex = my_max(max_vertex, (*face_sets[face_set_no])[j][2]);
                                        }

                                int vattr_no;
                                for(vattr_no=0; vattr_no<face_set_mapping.size(); ++vattr_no)
                                {
                                        if(face_set_mapping[vattr_no] == face_set_no)
                                                if(vert_attr[vattr_no]->size() > (max_vertex+1))
                                                        {
                                                                cout << "Excess vertex attributes in attribute vector "
                                                                                 << vattr_no  << " associated with face set "
                                                                                 << face_set_no << endl;
                                                                exit(1);
                                                        }

                                                else if(vert_attr[vattr_no]->size() < (max_vertex+1))
                                                        {
                                                                cout << "Face set " << face_set_no << " addresses beyond the "
                                                                                 << "end of attribute vector " << vattr_no << endl;
                                                                exit(1);
                                                        }
                                }

                        }
                int i;
                for(i=0;i<face_attr.size();++i)
                        {
                                int n = face_attr[i]->size();
                                if(n != faces_size)
                                        {
                                                cout << "Face attribute vector " << i 
                                                                 << " has wrong size : " << n << endl;
                                                exit(0);
                                        }
                        }
#endif

                did_call_get_trimesh = true;
                return new TriMesh(*this);
        }
}