source: GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp @ 2691

Revision 2691, 7.3 KB checked in by mattausch, 16 years ago (diff)

fixed several errors

RevLine 
[1233]1#include <stdlib.h>
[1221]2#include <iostream>
3#include <list>
4#include <map>
[1976]5#include <math.h>
6
[1221]7#include "Vector3.h"
8#include "Mesh.h"
9#include "SceneGraph.h"
10
11#include "ObjParser.h"
12//#include "Material.h"
[1328]13#include "Triangle3.h"
[1221]14#include "Environment.h"
15#include "ResourceManager.h"
[1315]16#include "IntersectableWrapper.h"
[1221]17
18
[2176]19using namespace std;
20
[1221]21namespace GtpVisibilityPreprocessor {
22
[1344]23#define CONNECT_SEQUENTIAL_FACES 0
[1221]24#define ROTATE_SCENE 0
[1328]25
[1976]26// hack: define this as in the intel ray tracer
27#define FLT_EPSILON 1.192092896e-07f
28
[1221]29// HACK
[1328]30static void RotateMesh(Mesh *mesh)
31{
32        VertexContainer::iterator it, it_end = mesh->mVertices.end();
[1221]33
[1328]34        const float angle = 30.0f * PI / 180.0f;
35        const Matrix4x4 rot = RotationYMatrix(angle);
[1221]36
[1328]37        for (it = mesh->mVertices.begin(); it != it_end; ++ it)
38        {
39                (*it) = rot * (*it);       
[1221]40        }
[1328]41}
[1221]42
[1344]43
[1328]44struct ltstr
45{
46        bool operator()(const string s1, const string s2) const
[1221]47        {
[1328]48                return s1 < s2;
49        }
50};
[1221]51
52
[1328]53static Face *LoadFace(char *str,
54                                          const VertexContainer &vertices,
55                                          map<int, Vector3> &hashTable)
[1221]56{
[1328]57        char *pch = strtok(str + 1, " ");
[1221]58       
59        VertexIndexContainer indices;
60        while (pch != NULL)
61        {
62                const int index = (int)strtol(pch, NULL, 10) - 1;
63                //Debug << index << " x ";
64               
65                // store vertex in hash table
66                hashTable[index] = vertices[index];
67                indices.push_back(index);
68               
69                pch = strtok(NULL, " ");
70        }
71
72        return new Face(indices);
73}
74
75
[1972]76static void LoadTriangles(char *str,
77                                                  const VertexContainer &vertices,
[1979]78                                                  vector<Triangle3> &triangles,
79                                                  const int line)
[1221]80{
[2539]81        vector<char *> substrings;
82
83        // extract the triples of the form v/t/n v/t/n ...
[1328]84        char *pch = strtok(str + 1, " ");
[2539]85
86        while (pch != NULL)
87        {
88                substrings.push_back(pch);
89                pch = strtok(NULL, " ");         
90        }
91
92        //for (int i = 0; i < substrings.size(); ++ i)
93        //      cout << "sub: " << substrings[i] << " ";
94
[1328]95        VertexIndexContainer indices;
[2539]96
97        for (int i = 0; i < substrings.size(); ++ i)
98        {
99                // discard normal and texture indices
100                // and only keep first index
101       
102                char *str = strtok(substrings[i], "/");   
103                const int index = (int)strtol(str, NULL, 10) - 1;
104
105                // store indices
106                if (index >= 0)
107                        indices.push_back(index);
108
109                //cout << "i " << index << " ";
110
111                // new triangle found
112                // problem: don't know how intel ray tracer tesselates
113                if ((int)indices.size() > 2)
[1972]114                {
[2539]115                        const int idx2 = (int)indices.size() - 2;
116                        const int idx3 = (int)indices.size() - 1;
[1972]117
118                        triangles.push_back(Triangle3(vertices[indices[0]],
[2539]119                                                                                  vertices[indices[idx2]],             
120                                                                                  vertices[indices[idx3]]));
[1972]121                }
[1328]122        }
123}
124
125
126static Mesh *CreateMesh(FaceContainer &faces,
127                                                const map<int, Vector3> &hashTable)
128{
[1221]129        Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
130       
131        FaceContainer::const_iterator fit, fit_end = faces.end();
132
133        for (fit = faces.begin(); fit != fit_end; ++ fit)
134        {
135                Face *face = *fit;
136                VertexIndexContainer::iterator vit, vit_end = face->mVertexIndices.end();
137               
138                for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit)
139                {
140                        // go through indices
[2307]141                        const int index = *vit;
[1221]142                        map<int, Vector3>::const_iterator hit = hashTable.find(index);
143
144                        // correct face index (nust be relative to start of verices)
[1314]145                        (*vit) = (int)distance(hashTable.begin(), hit);
[1221]146                }
147        }
148
149        VertexContainer vertices;
150
151        map<int, Vector3>::const_iterator hit, hit_end = hashTable.end();
152
153        // store vertices in given order
154        for (hit = hashTable.begin(); hit != hit_end; ++ hit)
155        {
156                mesh->mVertices.push_back((*hit).second);
157        }
158
159        mesh->mFaces = faces;
[1292]160        // can't do cleanup because coupling with kdf file for intel ray tracer
161        mesh->Preprocess(false);
162
[1221]163        return mesh;
164}
165
166
167// HACK: associate mesh instances with triangles
[1328]168static void AssociateFacesWithInstance(MeshInstance *mi,
169                                                                           vector<FaceParentInfo> &parents)
[1221]170{
[1344]171        Mesh *mesh = mi->GetMesh();
172
173        int i = 0;
[1655]174        FaceContainer::const_iterator fit, fit_end = mesh->mFaces.end();
175
[1344]176        for (fit = mesh->mFaces.begin(); fit != fit_end; ++ fit, i++)
[1221]177        {
[1344]178                parents.push_back(FaceParentInfo(mi, i));
[1221]179        }
180}
181
182
[1328]183static void ProcessMesh(FaceContainer &faces,
184                                                map<int, Vector3> &hashTable,
[2600]185                                                SceneGraphLeaf *root,
[1328]186                                                vector<FaceParentInfo> *parents)
187{
188        Mesh *mesh = CreateMesh(faces, hashTable);
189        // make an instance of this mesh
190        MeshInstance *mi = new MeshInstance(mesh);
191               
192        if (parents)
193        {
194                AssociateFacesWithInstance(mi, *parents);
195        }
196
197        root->mGeometry.push_back(mi); 
198
199        // reset tables
200        hashTable.clear();
201        faces.clear();
202}
203
204
[1973]205bool TriangleValid(const Triangle3 &triangle)
206{
[1976]207        const Vector3 a = triangle.mVertices[0] - triangle.mVertices[1];
208        const Vector3 b = triangle.mVertices[0] - triangle.mVertices[2];
209        const Vector3 cross_a_b = CrossProd(a, b);
[1973]210
[2575]211#define SMALL_FLT   1e-5
212       
213        if (SqrMagnitude(cross_a_b) <= 0.0001 * SMALL_FLT * SMALL_FLT)
[1976]214        {
[1978]215                // v0, v1 & v2 lies on a line (area == 0)
[1976]216                return false;
217        }
[1973]218
[1976]219        return true;
[1973]220}
221
[1976]222
[1221]223bool ObjParser::ParseFile(const string filename,
[2600]224                                                  SceneGraphLeaf *root,
[1379]225                                                  const bool loadMeshes,
[1281]226                                                  vector<FaceParentInfo> *parents)
[1221]227{
228        FILE *file;
229        if ((file = fopen(filename.c_str(), "rt")) == NULL)
[1344]230        {       
[1221]231                return false;
[1344]232        }
233
[1221]234        map<int, Vector3> hashTable; // table associating indices with vectors
[1327]235        VertexContainer vertices; // table for vertices
[1221]236        FaceContainer faces;
237
[1979]238        int line = 0;
239
[2307]240        char str[100000];
[1221]241        int meshGrouping;
242        Environment::GetSingleton()->GetIntValue("ObjParser.meshGrouping", meshGrouping);
243
[1292]244        int nMaxFaces = meshGrouping;
245
[2307]246        while (fgets(str, 100000, file) != NULL)
[2119]247        {
[2539]248                switch (str[0])
[1221]249                {
[1876]250                case 'v': // vertex  or normal
[2119]251                        {
[2539]252                                switch (str[1])
253                                {
254                                case 'n' :
255                                        // do nothing for normals
256                                        break;
257                                case 't':
258                                        // do nothing for textures
259                                        break;
260                                default:
[2672]261                                       
262                                        float x, y, z;
[2539]263                                        sscanf(str + 1, "%f %f %f", &x, &y, &z);
264                                        vertices.push_back(Vector3(x,y,z));
[2672]265                                        //cout <<"v " << x << " " << y << " "<< z << " ";
[2539]266                                }
[2119]267                                break;
[1233]268                        }
[1221]269                case 'f':
270                        {
[1421]271                                if (loadMeshes)
272                                {
273                                        Face *face = LoadFace(str, vertices, hashTable);
[2119]274
[1421]275                                        if (!face) break;
[2539]276
[1421]277                                        faces.push_back(face);
[1328]278
[2307]279                                        if ((int)faces.size() >= nMaxFaces)
[1421]280                                        {
281                                                ProcessMesh(faces, hashTable, root, parents);
282                                        }
283                                }
284                                else
[1221]285                                {
[2307]286                                        ++ line;
[2539]287
288                                        //////////
[2672]289                                        // construct triangles from indices in the current line
[2539]290
[1972]291                                        vector<Triangle3> triangles;
[1979]292                                        LoadTriangles(str, vertices, triangles, line);
[1978]293
[1972]294                                        vector<Triangle3>::const_iterator tit, tit_end = triangles.end();
[1344]295
[1972]296                                        for (tit = triangles.begin(); tit != tit_end; ++ tit)
[1421]297                                        {
[2691]298                                                // test if the triangle is valid (i.e., not degenerated)
299                                                // matt: removed this option so tris can be mapped to intel
300                                                if (0 && !TriangleValid(*tit))
301                                                        continue;
302                                               
303                                                TriangleIntersectable *obj = new TriangleIntersectable(*tit);
304                                                root->mGeometry.push_back(obj);
[1421]305                                        }
[1344]306                                }
[1221]307                                break;
[1314]308                        }   // end face
[1221]309                default:
310                        break;
311                }
312        }
[2539]313
[2691]314        cout << "\n*********\n***** " << root->mGeometry.size() << " " << " lines: " << line << endl;
[1421]315        if (loadMeshes)
316        {
317                // there could be faces remaining
318                if (!faces.empty())
319                {       
320                        ProcessMesh(faces, hashTable, root, parents);
321                }
[1221]322        }
[1421]323
[1344]324        // reset tables
325        hashTable.clear();
326        faces.clear();
[1221]327        fclose(file);
[1344]328       
[1221]329        return true;
330}
331
[1272]332}
Note: See TracBrowser for help on using the repository browser.