source: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/PlyConverter.cpp @ 3362

Revision 3362, 7.8 KB checked in by mattausch, 15 years ago (diff)

cleaned up algorithm

Line 
1#include "PlyConverter.h"
2#include "SimpleTri.h"
3#include "SimpleVec.h"
4#include "gzstream.h"
5#include <iostream>
6#include "rply.h"
7
8
9using namespace std;
10
11static int sGlobalIndex = 0;
12
13
14VertexArray sVertices;
15VertexArray sNormals;
16FaceArray sFaces;
17
18
19
20PlyConverter::~PlyConverter()
21{
22        for (size_t i = 0; i < mGeometry.size(); ++ i) delete mGeometry[i];
23        mGeometry.clear();
24}
25
26
27void PlyConverter::LoadShape(const VertexArray &vertices,
28                                                         const VertexArray &normals,
29                                                         const TexcoordArray &texcoords,
30                                                         const FaceArray &faces
31                                                         )
32{
33        Geometry *geom = new Geometry();
34        size_t idx = 0;
35
36        for (size_t i = 0; i < faces.size(); ++ i)
37        {
38                if (i % 1000 == 0)
39                        cout << "converted " << i << " lines" << endl;
40
41                Face face = faces[i];
42
43                if (faces[i].indices.empty()) cout << "error!!" << endl;
44
45                //cout << "size: " << face.indices.size() << endl;
46                for (int j = (int)face.indices.size() - 1; j >= 0; -- j)
47                {
48                        //cout << "h " << j << " " << face.indices.size() << endl;
49
50                        SimpleVec h = vertices[face.indices[j]];
51                        SimpleVec v;
52                       
53                        v.x = -h.x * 14;
54                        v.y = h.z * 14;
55                        v.z = h.y * 14;
56       
57                        geom->mVertices.push_back(v);
58
59                        /*if (!normals.empty())
60                        {
61                                for (int j = 0; j < 3; ++ j)
62                                        faceNormals.push_back(Normalize(normals[nIndices[idx[j]]]));
63                        }
64                        else
65                        {
66                                // no face normals? => create normals
67                                const SimpleTri tri(vertices[indices[idx[0]]],
68                                                        vertices[indices[idx[1]]],
69                                                                        vertices[indices[idx[2]]]);
70
71                                const SimpleVec n = tri.GetNormal();
72
73                                faceNormals.push_back(n);
74                                faceNormals.push_back(n);
75                                faceNormals.push_back(n);
76                        }*/
77                }
78
79                //cout << "idx: " << idx << " " << geom->mVertices.size() << endl;
80
81                // no face normals? => create normals
82                const SimpleTri tri(geom->mVertices[idx + 0],
83                                        geom->mVertices[idx + 1],
84                                                        geom->mVertices[idx + 2]);
85
86                const SimpleVec n = tri.GetNormal();
87
88                geom->mNormals.push_back(n);
89                geom->mNormals.push_back(n);
90                geom->mNormals.push_back(n);
91
92                idx += faces[i].indices.size();
93        }
94
95        mGeometry.push_back(geom);
96        mNumShapes = 1;
97}
98
99
100bool PlyConverter::Convert(const string &filename,
101                                                   const std::string &outputFilename)
102{
103        mNumShapes = 0;
104       
105        for (size_t i = 0; i < mGeometry.size(); ++ i) delete mGeometry[i];
106        mGeometry.clear();
107
108        if (!ReadFile(filename))
109        {
110                cerr << "could not read file" << endl;
111                return false;
112        }
113
114        if (!WriteFile(outputFilename))
115        {
116                cerr << "could not write file" << endl;
117                return false;
118        }
119
120        return true;
121}
122
123
124static int vertex_cb(p_ply_argument argument)
125{
126    long eol;
127    ply_get_argument_user_data(argument, NULL, &eol);
128
129        static SimpleVec v;
130        static int i = 0;
131
132        v[i ++] = (float)ply_get_argument_value(argument);
133        //printf("%g", ply_get_argument_value(argument));
134   
135        if (eol)
136        {
137                sVertices.push_back(v);
138                if (sVertices.size() % 10000 == 0) cout << "read in " << sVertices.size() << " vertices" << endl;
139                i = 0;
140        }
141   
142        return 1;
143}
144
145
146static int face_cb(p_ply_argument argument)
147{
148    long length, value_index;
149    ply_get_argument_property(argument, NULL, &length, &value_index);
150
151        static Face face;
152       
153        switch (value_index)
154        {
155        case 0:
156        case 1:
157            //printf("here4 %g ", ply_get_argument_value(argument));
158                        face.indices.push_back((int)ply_get_argument_value(argument));
159            break;
160        case 2:
161            //printf("here5 %g\n", ply_get_argument_value(argument));
162                        face.indices.push_back((int)ply_get_argument_value(argument));
163                        sFaces.push_back(face);
164                        if (sFaces.size() % 10000 == 0) cout << "read in " << sFaces.size() << " faces" << endl;
165
166                        face.indices.clear();
167            break;
168        default:
169            break;
170    }
171
172
173    return 1;
174}
175
176
177
178bool PlyConverter::ReadFile(const string &filename)
179{
180        long nvertices, ntriangles;
181
182        p_ply ply = ply_open(filename.c_str(), NULL);
183   
184        if (!ply) return 1;
185    if (!ply_read_header(ply)) return 1;
186   
187        nvertices = ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
188
189    ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 0);
190    ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 1);
191
192        ntriangles = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);
193
194        cout << "vertices: " << nvertices << endl;
195        cout << "triangles: " << ntriangles << endl;
196
197    if (!ply_read(ply)) return false;
198    ply_close(ply);
199
200        TexcoordArray texCoords;
201        LoadShape(sVertices, sNormals, texCoords, sFaces);
202
203    return true;
204}
205
206
207
208void PlyConverter::WriteGeometry(ogzstream &str, Geometry *geom)
209{
210        size_t vertexCount = (int)geom->mVertices.size();
211        str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
212
213        cout << "writing geometry" << endl;
214
215        //SimpleVec vertices = new SimpleVec[vertexCount];
216        //for (size_t i = 0; i < vertexCount; ++ i) vertices[i] = geom->mVertices[i];
217        //for (size_t i = 0; i < vertexCount; ++ i) vertices[i] = geom->mNormals[i];
218
219        for (size_t i = 0; i < vertexCount; ++ i)
220                str.write(reinterpret_cast<char *>(&geom->mVertices[i]), sizeof(SimpleVec));
221
222        for (size_t i = 0; i < vertexCount; ++ i)
223                str.write(reinterpret_cast<char *>(&geom->mNormals[i]), sizeof(SimpleVec));
224
225        cout << "finished writing geometry" << endl;
226        //if (texCoordCount) str.write(reinterpret_cast<char *>(geom->mTexcoords), sizeof(float) * texCoordCount * 2);
227
228        int texCoordCount = 0;
229        str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
230
231        //if (texCoordCount) str.write(reinterpret_cast<char *>(geom->mTexcoords), sizeof(float) * texCoordCount * 2);
232}
233
234
235bool PlyConverter::WriteFile(const string &filename)
236{
237        ogzstream ofile(filename.c_str());
238        if (!ofile.is_open()) return false;
239       
240
241        mNumShapes = (int)mGeometry.size();
242
243        /////////
244        //-- write textures
245
246#ifdef USE_TEXTURE
247        int textureCount = 1;
248#else
249        int textureCount = 0;
250#endif
251        ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
252
253        if (textureCount > 0)
254        {
255                // hack
256                const string texName("wood.jpg");
257
258                int texnameSize = (int)texName.length() + 1;
259                ofile.write(reinterpret_cast<char *>(&texnameSize), sizeof(int));
260
261                ofile.write(texName.c_str(), sizeof(char) * texnameSize);
262
263                int boundS = 1, boundT = 1;
264
265                ofile.write(reinterpret_cast<char *>(&boundS), sizeof(int));
266                ofile.write(reinterpret_cast<char *>(&boundT), sizeof(int));
267        }
268
269
270        ///////////
271        //-- write shapes
272
273        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
274
275        vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
276
277        for (it = mGeometry.begin(); it != it_end; ++ it)
278        {
279                WriteGeometry(ofile, *it);
280
281
282                ///////
283                //-- texture
284
285                int texId = 0;
286                ofile.write(reinterpret_cast<char *>(&texId), sizeof(int));
287
288                bool alphaTestEnabled = false;
289                //bool cullFaceEnabled = false;
290                bool cullFaceEnabled = true;
291
292                ofile.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
293                ofile.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
294
295                // material
296                bool hasMaterial = false;
297                ofile.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
298        }
299
300
301        int entityCount = 1;
302        ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
303
304
305        //////////
306        //-- write single scene entity
307
308        // no transformation
309        bool hasTrafo = false;
310        ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
311
312        // a dummy lod
313        int numLODs = 1;
314        ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
315
316        float dist = 0;
317        ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
318        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
319       
320
321        // all shapes belong to this scene entity
322        for (int i = 0; i < mNumShapes; ++ i)
323        {
324                int shapeId = i;
325                ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
326        }
327
328        return true;
329}
Note: See TracBrowser for help on using the repository browser.