[3357] | 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 |
|
---|
| 9 | using namespace std;
|
---|
| 10 |
|
---|
| 11 | static int sGlobalIndex = 0;
|
---|
| 12 |
|
---|
| 13 |
|
---|
| 14 | VertexArray sVertices;
|
---|
| 15 | VertexArray sNormals;
|
---|
[3358] | 16 | FaceArray sFaces;
|
---|
[3357] | 17 |
|
---|
| 18 |
|
---|
[3358] | 19 |
|
---|
[3357] | 20 | PlyConverter::~PlyConverter()
|
---|
| 21 | {
|
---|
| 22 | for (size_t i = 0; i < mGeometry.size(); ++ i) delete mGeometry[i];
|
---|
| 23 | mGeometry.clear();
|
---|
| 24 | }
|
---|
| 25 |
|
---|
| 26 |
|
---|
[3358] | 27 | void PlyConverter::LoadShape(const VertexArray &vertices,
|
---|
| 28 | const VertexArray &normals,
|
---|
| 29 | const TexcoordArray &texcoords,
|
---|
| 30 | const FaceArray &faces
|
---|
[3357] | 31 | )
|
---|
| 32 | {
|
---|
| 33 | Geometry *geom = new Geometry();
|
---|
[3358] | 34 | size_t idx = 0;
|
---|
[3357] | 35 |
|
---|
[3358] | 36 | for (size_t i = 0; i < faces.size(); ++ i)
|
---|
| 37 | {
|
---|
| 38 | if (i % 1000 == 0)
|
---|
| 39 | cout << "converted " << i << " lines" << endl;
|
---|
[3357] | 40 |
|
---|
[3358] | 41 | Face face = faces[i];
|
---|
[3357] | 42 |
|
---|
[3362] | 43 | if (faces[i].indices.empty()) cout << "error!!" << endl;
|
---|
| 44 |
|
---|
[3358] | 45 | //cout << "size: " << face.indices.size() << endl;
|
---|
[3362] | 46 | for (int j = (int)face.indices.size() - 1; j >= 0; -- j)
|
---|
[3358] | 47 | {
|
---|
[3362] | 48 | //cout << "h " << j << " " << face.indices.size() << endl;
|
---|
| 49 |
|
---|
| 50 | SimpleVec h = vertices[face.indices[j]];
|
---|
[3361] | 51 | SimpleVec v;
|
---|
| 52 |
|
---|
[3362] | 53 | v.x = -h.x * 14;
|
---|
[3361] | 54 | v.y = h.z * 14;
|
---|
| 55 | v.z = h.y * 14;
|
---|
| 56 |
|
---|
| 57 | geom->mVertices.push_back(v);
|
---|
[3357] | 58 |
|
---|
[3358] | 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 | }*/
|
---|
[3357] | 77 | }
|
---|
[3358] | 78 |
|
---|
| 79 | //cout << "idx: " << idx << " " << geom->mVertices.size() << endl;
|
---|
| 80 |
|
---|
| 81 | // no face normals? => create normals
|
---|
[3362] | 82 | const SimpleTri tri(geom->mVertices[idx + 0],
|
---|
[3358] | 83 | geom->mVertices[idx + 1],
|
---|
[3362] | 84 | geom->mVertices[idx + 2]);
|
---|
[3358] | 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();
|
---|
[3357] | 93 | }
|
---|
[3358] | 94 |
|
---|
[3357] | 95 | mGeometry.push_back(geom);
|
---|
[3358] | 96 | mNumShapes = 1;
|
---|
[3357] | 97 | }
|
---|
| 98 |
|
---|
| 99 |
|
---|
| 100 | bool 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 |
|
---|
| 124 | static int vertex_cb(p_ply_argument argument)
|
---|
| 125 | {
|
---|
| 126 | long eol;
|
---|
| 127 | ply_get_argument_user_data(argument, NULL, &eol);
|
---|
| 128 |
|
---|
[3358] | 129 | static SimpleVec v;
|
---|
[3357] | 130 | static int i = 0;
|
---|
| 131 |
|
---|
[3358] | 132 | v[i ++] = (float)ply_get_argument_value(argument);
|
---|
[3359] | 133 | //printf("%g", ply_get_argument_value(argument));
|
---|
[3357] | 134 |
|
---|
[3358] | 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 | }
|
---|
[3357] | 141 |
|
---|
| 142 | return 1;
|
---|
| 143 | }
|
---|
| 144 |
|
---|
| 145 |
|
---|
| 146 | static int face_cb(p_ply_argument argument)
|
---|
| 147 | {
|
---|
| 148 | long length, value_index;
|
---|
| 149 | ply_get_argument_property(argument, NULL, &length, &value_index);
|
---|
| 150 |
|
---|
[3358] | 151 | static Face face;
|
---|
| 152 |
|
---|
[3357] | 153 | switch (value_index)
|
---|
| 154 | {
|
---|
| 155 | case 0:
|
---|
| 156 | case 1:
|
---|
[3358] | 157 | //printf("here4 %g ", ply_get_argument_value(argument));
|
---|
| 158 | face.indices.push_back((int)ply_get_argument_value(argument));
|
---|
[3357] | 159 | break;
|
---|
| 160 | case 2:
|
---|
[3358] | 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();
|
---|
[3357] | 167 | break;
|
---|
| 168 | default:
|
---|
| 169 | break;
|
---|
| 170 | }
|
---|
[3358] | 171 |
|
---|
| 172 |
|
---|
[3357] | 173 | return 1;
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 |
|
---|
| 177 |
|
---|
| 178 | bool 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 |
|
---|
[3358] | 194 | cout << "vertices: " << nvertices << endl;
|
---|
| 195 | cout << "triangles: " << ntriangles << endl;
|
---|
[3357] | 196 |
|
---|
[3358] | 197 | if (!ply_read(ply)) return false;
|
---|
[3357] | 198 | ply_close(ply);
|
---|
| 199 |
|
---|
[3358] | 200 | TexcoordArray texCoords;
|
---|
| 201 | LoadShape(sVertices, sNormals, texCoords, sFaces);
|
---|
| 202 |
|
---|
| 203 | return true;
|
---|
[3357] | 204 | }
|
---|
| 205 |
|
---|
| 206 |
|
---|
| 207 |
|
---|
| 208 | void PlyConverter::WriteGeometry(ogzstream &str, Geometry *geom)
|
---|
| 209 | {
|
---|
[3358] | 210 | size_t vertexCount = (int)geom->mVertices.size();
|
---|
[3357] | 211 | str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
|
---|
| 212 |
|
---|
[3358] | 213 | cout << "writing geometry" << endl;
|
---|
[3357] | 214 |
|
---|
[3358] | 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 |
|
---|
[3357] | 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 |
|
---|
| 235 | bool PlyConverter::WriteFile(const string &filename)
|
---|
| 236 | {
|
---|
| 237 | ogzstream ofile(filename.c_str());
|
---|
| 238 | if (!ofile.is_open()) return false;
|
---|
| 239 |
|
---|
| 240 |
|
---|
[3358] | 241 | mNumShapes = (int)mGeometry.size();
|
---|
| 242 |
|
---|
[3357] | 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);
|
---|
[3358] | 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));
|
---|
[3357] | 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));
|
---|
[3358] | 319 |
|
---|
[3357] | 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 | }
|
---|