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

Revision 3359, 7.5 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("%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        int texCoordCount = 0;
218        str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
219
220        //if (texCoordCount) str.write(reinterpret_cast<char *>(geom->mTexcoords), sizeof(float) * texCoordCount * 2);
221}
222
223
224bool PlyConverter::WriteFile(const string &filename)
225{
226        ogzstream ofile(filename.c_str());
227        if (!ofile.is_open()) return false;
228       
229
230        mNumShapes = (int)mGeometry.size();
231
232        /////////
233        //-- write textures
234
235#ifdef USE_TEXTURE
236        int textureCount = 1;
237#else
238        int textureCount = 0;
239#endif
240        ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
241
242        if (textureCount > 0)
243        {
244                // hack
245                const string texName("wood.jpg");
246
247                int texnameSize = (int)texName.length() + 1;
248                ofile.write(reinterpret_cast<char *>(&texnameSize), sizeof(int));
249
250                ofile.write(texName.c_str(), sizeof(char) * texnameSize);
251
252                int boundS = 1, boundT = 1;
253
254                ofile.write(reinterpret_cast<char *>(&boundS), sizeof(int));
255                ofile.write(reinterpret_cast<char *>(&boundT), sizeof(int));
256        }
257
258
259        ///////////
260        //-- write shapes
261
262        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
263
264        vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
265
266        for (it = mGeometry.begin(); it != it_end; ++ it)
267        {
268                WriteGeometry(ofile, *it);
269
270
271                ///////
272                //-- texture
273
274                int texId = 0;
275                ofile.write(reinterpret_cast<char *>(&texId), sizeof(int));
276
277                bool alphaTestEnabled = false;
278                //bool cullFaceEnabled = false;
279                bool cullFaceEnabled = true;
280
281                ofile.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
282                ofile.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
283
284                // material
285                bool hasMaterial = false;
286                ofile.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
287        }
288
289
290        int entityCount = 1;
291        ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
292
293
294        //////////
295        //-- write single scene entity
296
297        // no transformation
298        bool hasTrafo = false;
299        ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
300
301        // a dummy lod
302        int numLODs = 1;
303        ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
304
305        float dist = 0;
306        ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
307        ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
308       
309
310        // all shapes belong to this scene entity
311        for (int i = 0; i < mNumShapes; ++ i)
312        {
313                int shapeId = i;
314                ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
315        }
316
317        return true;
318}
Note: See TracBrowser for help on using the repository browser.