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

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