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

Revision 1976, 6.8 KB checked in by mattausch, 17 years ago (diff)

valid function for degenerated obj-triangles

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