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

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