plyio.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:22k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include "ply++.h"
  3. #include <stdlib.h>
  4. #include "strings.h"
  5. #include <iostream.h>
  6. #include <limits.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #ifdef WIN32
  10. #else
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #endif
  14. #include "timer.h"
  15. #include "vector.h"
  16. #include "Mesh.h"
  17. #include "plyio.h"
  18. #define SHOW(x) cout << #x " = " << x << endl
  19. static int Verbose = 1;
  20. struct PlyVertex {
  21.   float x, y, z;
  22.   float nx, ny, nz;
  23.   uchar diff_r, diff_g, diff_b;
  24.   float tex_u, tex_v;
  25.   float intensity;
  26.   float std_dev;
  27.   float confidence;
  28. };
  29. const int MAX_FACE_VERTS = 100;
  30. struct PlyFace {
  31.   uchar nverts;
  32.   int verts[MAX_FACE_VERTS];
  33. };
  34. struct CoordConfVert {
  35.    float v[3];
  36.    float conf;
  37. };
  38. struct TriLocal {
  39.    uchar nverts;
  40.    int index[3];
  41. };
  42. static PlyProperty vert_prop_x =  
  43.    {"x", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  44. static PlyProperty vert_prop_y =  
  45.   {"y", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  46. static PlyProperty vert_prop_z =  
  47.   {"z", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  48. static PlyProperty vert_prop_nx =  
  49.    {"nx", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  50. static PlyProperty vert_prop_ny =  
  51.   {"ny", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  52. static PlyProperty vert_prop_nz =  
  53.   {"nz", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  54. static PlyProperty vert_prop_texture_u =  
  55.   {"texture_u", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  56. static PlyProperty vert_prop_texture_v =  
  57.   {"texture_v", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  58. static PlyProperty vert_prop_intens =  
  59.   {"intensity", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  60. static PlyProperty vert_prop_std_dev =  
  61.   {"std_dev", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  62. static PlyProperty vert_prop_confidence =  
  63.   {"confidence", PLY_FLOAT, PLY_FLOAT, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  64. static PlyProperty vert_prop_diff_r =  
  65.   {"diffuse_red", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  66. static PlyProperty vert_prop_diff_g =  
  67.   {"diffuse_green", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  68. static PlyProperty vert_prop_diff_b =  
  69.   {"diffuse_blue", PLY_UCHAR, PLY_UCHAR, 0, 0, PLY_START_TYPE, PLY_START_TYPE, 0};
  70. static PlyProperty face_props[] = { 
  71.   {"vertex_indices", PLY_INT, PLY_INT, 0, 1, PLY_UCHAR, PLY_UCHAR, 0},
  72.   //{"vertex_indices", PLY_INT, PLY_INT, 4, 1, PLY_INT, PLY_INT, 0},
  73. };
  74. static PlyProperty tstrips_props[] = {
  75.   {"vertex_indices", PLY_INT, PLY_INT, 4, 1, PLY_INT, PLY_INT, 0},
  76. };
  77. static Mesh *oldReadPlyFile(char *filename);
  78. static Mesh *mattReadPlyFile(char *filename);
  79. static void
  80. set_offsets(void)
  81. {
  82.   static int first = 1;
  83.   if (first) {
  84.     first = 0;
  85.     vert_prop_x.offset          = offsetof(PlyVertex,x);
  86.     vert_prop_y.offset          = offsetof(PlyVertex,y);
  87.     vert_prop_z.offset          = offsetof(PlyVertex,z);
  88.     vert_prop_nx.offset         = offsetof(PlyVertex,nx);
  89.     vert_prop_ny.offset         = offsetof(PlyVertex,ny);
  90.     vert_prop_nz.offset         = offsetof(PlyVertex,nz);
  91.     vert_prop_intens.offset     = offsetof(PlyVertex, intensity);
  92.     vert_prop_std_dev.offset    = offsetof(PlyVertex, std_dev);
  93.     vert_prop_confidence.offset = offsetof(PlyVertex, confidence);
  94.     vert_prop_diff_r.offset     = offsetof(PlyVertex,diff_r);
  95.     vert_prop_diff_g.offset     = offsetof(PlyVertex,diff_g);
  96.     vert_prop_diff_b.offset     = offsetof(PlyVertex,diff_b);
  97.     vert_prop_texture_u.offset  = offsetof(PlyVertex,tex_u);
  98.     vert_prop_texture_v.offset  = offsetof(PlyVertex,tex_v);
  99.   }
  100. }
  101. Mesh *
  102. readPlyFile(char *filename)
  103. {
  104.   /*
  105.   //Mesh* mesh = mattReadPlyFile (filename);
  106.   //if (mesh == NULL) {
  107.     Mesh *mesh = oldReadPlyFile (filename);
  108.     if (mesh != NULL)
  109.       //printf ("Warning: file %s does not conform to dmich'sn"
  110.       //      "expected ply layout; cannot use fastread code.n", 
  111.       //      filename);
  112.       printf ("Warning: using oldReadPlyFile()n");
  113.     else
  114.       printf ("Cannot read plyfile %sn", filename);
  115.     //}
  116.   */
  117.   Mesh *mesh = new Mesh;
  118.   if (mesh->readPlyFile (filename)) {
  119.     return mesh;
  120.   }
  121.   delete mesh;
  122.   return NULL;
  123. }
  124. //
  125. // Read in data from the ply file
  126. //
  127. /*
  128. Mesh *
  129. oldReadPlyFile(char *filename)
  130. {
  131.   int i, j;
  132.   int nelems;
  133.   char **elist;
  134.   char **obj_info;
  135.   int num_obj_info;
  136.   char *elem_name;
  137.   int nprops;
  138.   int num_elems;
  139.   int hasNormals = 0;
  140.   int hasConfidence = 0;
  141.   int hasIntensity = 0;
  142.   int hasStdDev = 0;
  143.   int hasDiffuseColors = 0;
  144.   int notATriangleMesh = 0;
  145.   int hasTexture = 0;
  146.   int skipTexture = 1;
  147.   char texFile[PATH_MAX];
  148.   Timer t ("Read ply file (via plylib)");
  149.   face_props[0].offset = offsetof(PlyFace, verts);
  150.   face_props[0].count_offset = offsetof(PlyFace, nverts);  // count offset
  151.     
  152.   PlyFile ply;
  153.   if (ply.open_for_reading(filename, &nelems, &elist) == 0)
  154.     return NULL;
  155.   Mesh *mesh = new Mesh;
  156.   // Look for a texture file reference
  157.   char temp[PATH_MAX];
  158.   obj_info = ply.get_obj_info (&num_obj_info);
  159.   for (i = 0; i < num_obj_info; i++) {
  160.     if (strstr(obj_info[i], "texture_file")) {
  161.       sscanf(obj_info[i], "%s%s", temp, texFile);
  162.       FILE *fp = fopen(texFile, "r");
  163.       if (fp != NULL) {
  164. fclose(fp);
  165. skipTexture = 0;
  166. strcpy(mesh->texFileName, texFile);
  167.       }
  168.     }
  169.   }
  170.    
  171.   vector<PlyProperty> vert_props;
  172.   set_offsets();
  173.   Vertex *vert;
  174.   PlyVertex plyVert;
  175.   PlyFace plyFace;
  176.   for (i = 0; i < nelems; i++) {
  177.     // get the description of the first element
  178.     elem_name = elist[i];
  179.     ply.get_element_description(elem_name, &num_elems, &nprops);
  180.     // if we're on vertex elements, read them in
  181.     if (equal_strings ("vertex", elem_name)) {
  182.     
  183.       Timer tv ("Read vertices");
  184.       mesh->numVerts = num_elems;
  185.       mesh->verts = new Vertex[num_elems];
  186.     
  187.       if (ply.is_valid_property("vertex", vert_prop_x.name) &&
  188.   ply.is_valid_property("vertex", vert_prop_y.name) &&
  189.   ply.is_valid_property("vertex", vert_prop_z.name)) {
  190. ply.get_property(elem_name, &vert_prop_x);
  191. ply.get_property(elem_name, &vert_prop_y);
  192. ply.get_property(elem_name, &vert_prop_z);
  193.       }
  194.   
  195.       if (ply.is_valid_property("vertex", vert_prop_nx.name) &&
  196.   ply.is_valid_property("vertex", vert_prop_ny.name) &&
  197.   ply.is_valid_property("vertex", vert_prop_nz.name) ) {
  198. ply.get_property(elem_name, &vert_prop_nx);
  199. ply.get_property(elem_name, &vert_prop_ny);
  200. ply.get_property(elem_name, &vert_prop_nz);
  201. hasNormals = 1;
  202.       }
  203.       mesh->hasVertNormals = hasNormals;
  204.   
  205.       if (ply.is_valid_property("vertex", vert_prop_intens.name)) {
  206. ply.get_property(elem_name, &vert_prop_intens);
  207. hasIntensity = 1;
  208.       }
  209.     
  210.       if (ply.is_valid_property("vertex", vert_prop_std_dev.name)){
  211. ply.get_property(elem_name, &vert_prop_std_dev);
  212. hasStdDev = 1;
  213.       }
  214.     
  215.       if (ply.is_valid_property("vertex", 
  216. vert_prop_confidence.name)) {
  217. ply.get_property(elem_name, &vert_prop_confidence);
  218. hasConfidence = 1;
  219. mesh->vertConfidence = new float[num_elems];
  220.       }
  221.     
  222.       if (ply.is_valid_property("vertex", "diffuse_red") &&
  223.   ply.is_valid_property("vertex", "diffuse_green") &&
  224.   ply.is_valid_property("vertex", "diffuse_blue")) {
  225. ply.get_property(elem_name, &vert_prop_diff_r);
  226. ply.get_property(elem_name, &vert_prop_diff_g);
  227. ply.get_property(elem_name, &vert_prop_diff_b);
  228. hasDiffuseColors = 1;
  229. mesh->vertMatDiff = new vec3uc[num_elems];
  230.       }
  231.     
  232.       if (!skipTexture) {
  233. if (ply.is_valid_property("vertex", "texture_u") &&
  234.     ply.is_valid_property("vertex", "texture_v")) {
  235.   ply.get_property(elem_name, &vert_prop_texture_u);
  236.   ply.get_property(elem_name, &vert_prop_texture_v);
  237.   hasTexture = 1;
  238.   mesh->texture = new vec2f[num_elems];
  239. }
  240.       }
  241.       if (Verbose) cout << "Reading vertices..." << endl;
  242.       SHOW(mesh->numVerts);
  243.       // grab all the vertex elements
  244.       for (j = 0; j < mesh->numVerts; j++) {
  245. ply.get_element ((void *) &plyVert);
  246. vert = &mesh->verts[j];
  247. vert->coord.setValue(plyVert.x, plyVert.y, plyVert.z);
  248. if (hasNormals) {
  249.   vert->norm.setValue(plyVert.nx, plyVert.ny, plyVert.nz);
  250. }
  251. if (hasDiffuseColors) {
  252.   mesh->vertMatDiff[j][0] = plyVert.diff_r;
  253.   mesh->vertMatDiff[j][1] = plyVert.diff_g;
  254.   mesh->vertMatDiff[j][2] = plyVert.diff_b;
  255. }
  256. if (hasConfidence) {
  257.   mesh->vertConfidence[j] = plyVert.confidence;
  258. }
  259. if (hasTexture) {
  260.   mesh->texture[j][0] = plyVert.tex_u;
  261.   mesh->texture[j][1] = plyVert.tex_v;
  262. }
  263.       }
  264.       if (Verbose) cout << "Done." << endl;
  265.     }
  266.     if (equal_strings ("face", elem_name)) {
  267.       Timer tf ("Read faces");
  268.       ply.get_property(elem_name, face_props);
  269.       assert(mesh->tris.size() == 0);
  270.       if (num_elems == 0)
  271. continue;
  272.       if (Verbose) cout << "Reading Tris..." << endl;
  273.       SHOW(num_elems);
  274.       for (j = 0; j < num_elems; j++) {
  275. ply.get_element_noalloc((void *) &plyFace);
  276. if (plyFace.nverts != 3)
  277.   notATriangleMesh = 1;
  278. assert(plyFace.nverts <= MAX_FACE_VERTS);
  279. mesh->tris.push_back(Triangle(plyFace.verts[0],
  280.       plyFace.verts[1],
  281.       plyFace.verts[2]));
  282. //delete[] plyFace.verts;
  283.       }
  284.       if (notATriangleMesh) {
  285. cerr << "readPlyFile: Not a triangle mesh!" << endl;
  286.       }
  287.       if (Verbose) cout << "Done." << endl;
  288.     }
  289.     if (equal_strings ("tristrips", elem_name)) {
  290.       struct {
  291. int nverts; int* vertData;
  292.       } info;
  293.       if (num_elems != 1)
  294. continue;
  295.       if (Verbose) cout << "Reading TStrips..." << endl;
  296.       ply.get_property(elem_name, tstrips_props);
  297.       ply.get_element ((void*)&info);
  298.       mesh->tstrips = new vector<int> (info.nverts);
  299.       for (int iv = 0; iv < info.nverts; iv++) {
  300. mesh->tstrips->push_back (info.vertData[iv]);
  301.       }
  302.       mesh->trisFromStrip();
  303.       if (Verbose) cout << "Done." << endl;
  304.     }
  305.   }
  306.   return mesh;
  307. }
  308. */
  309. int SizeOfProp[] = { 0, 1, 2, 4, 1, 2, 4, 4, 8 };
  310. int 
  311. CalcPropertySize (PlyElement* elem)
  312. {
  313.   int size = 0;
  314.   int type;
  315.   /*
  316.   for (int i = 0; i < elem->nprops; i++) {
  317.     type = elem->props[i]->external_type;
  318.     if (type <= PLY_START_TYPE || type >= PLY_END_TYPE) {
  319.       printf ("Unknown type %d found for property %s in elem %sn",
  320.       type, elem->props[i]->name, elem->name);
  321.       return 0;
  322.     }
  323.   */
  324.   for (int i = 0; i < elem->props.size(); i++) {
  325.     type = elem->props[i].external_type;
  326.     if (type <= PLY_START_TYPE || type >= PLY_END_TYPE) {
  327.       printf ("Unknown type %d found for property %s in elem %sn",
  328.       type, elem->props[i].name, elem->name);
  329.       return 0;
  330.     }
  331.     size += SizeOfProp[type];
  332.   }
  333.   return size;
  334. }
  335. #if defined(WIN32) || defined(i386)
  336. void 
  337. CopyReverseWord (void* dest, void* src, int nWords)
  338.   //like memcpy but copies 32-bit words instead of bytes, and flips byte order
  339.   //to convert endian-ness as it copies.  Used to read PLY files (which are
  340.   //currently all big-endian) on PC's (which are little-endian).
  341. {
  342.   for (int i = 0; i < nWords; i++) {
  343.     unsigned long temp = *(unsigned long*)src;
  344.     
  345.     temp = (temp >> 24) | ((temp >> 8) & 0xFF00) | 
  346.       ((temp << 8) & 0xFF0000) | (temp << 24);
  347.     (*(unsigned long*)dest) = temp;
  348.     src  = ((char*)src)  + 4;
  349.     dest = ((char*)dest) + 4;
  350.   }
  351. }
  352. #endif
  353. Mesh*
  354. mattReadPlyFile (char* filename)
  355. {
  356.   /*
  357.     int nelems;
  358.     char **elist;
  359.     char **obj_info;
  360.     int num_obj_info;
  361.     int file_type;
  362.     float version;
  363.     bool skipTexture = FALSE;
  364.     char texFile[PATH_MAX];
  365.     Timer t ("Read ply file (Matt's way)");
  366.     PlyFile *ply = 
  367. ply_open_for_reading(filename, &nelems, &elist, &file_type, &version);
  368.     if (!ply)
  369. return NULL;
  370.     if (file_type != PLY_BINARY_BE)  //if it ever becomes an issue, the code
  371.         return NULL;  //is already here to read PLY_BINARY_LE too
  372.                       //but right now, none of these exist anyway
  373.     Mesh *mesh = new Mesh;
  374.     // Look for a texture file reference
  375.     char temp[PATH_MAX];
  376.     obj_info = ply_get_obj_info (ply, &num_obj_info);
  377.     for (int i = 0; i < num_obj_info; i++) {
  378. if (strstr(obj_info[i], "texture_file")) {
  379.     sscanf(obj_info[i], "%s%s", temp, texFile);
  380.     FILE *fp = fopen(texFile, "r");
  381.     if (fp != NULL) {
  382. fclose(fp);
  383. skipTexture = TRUE;
  384. strcpy(mesh->texFileName, texFile);
  385.     }
  386. }
  387.     }
  388.     
  389.     if (strcmp (elist[0], "vertex") != 0)
  390.       return NULL;//first element must be vertex
  391.     if (strcmp (elist[1], "face") != 0 && strcmp (elist[1], "tristrips") != 0)
  392.       return NULL;//second element must be triangles or strips
  393.     //read in vertex data
  394.     int nVerts = ply->elems[0]->num;
  395.     int cbVertex = ply->elems[0]->size;
  396.     //if (cbVertex <= 0)
  397.     cbVertex = CalcPropertySize (ply->elems[0]);
  398.     char* vBuffer = new char[nVerts * cbVertex];
  399.     if (nVerts != fread (vBuffer, cbVertex, nVerts, ply->fp)) {
  400.         delete vBuffer;
  401. delete mesh;
  402. return NULL;
  403.     }
  404.     //read in face data, if available
  405. #if 0  // pack pragma is not supported by n32 compiler
  406. #pragma pack (1)
  407.     typedef struct { uchar nV; int vindex[3]; } RAWFACE;
  408.     static const int kRawFaceSize = sizeof(RAWFACE);
  409. #pragma pack (0)
  410. #else
  411.     static const int kRawFaceSize = 13;
  412. #endif
  413.     int nFaces;
  414.     char* pFaces;
  415.     int nStrips;
  416.     int* pStrips;
  417.     if (!strcmp (elist[1], "face")) {
  418.       nStrips = 0; pStrips = NULL;
  419.       nFaces = ply->elems[1]->num;
  420.       pFaces = new char [nFaces * kRawFaceSize];
  421.       if (nFaces != fread ((char*)pFaces, kRawFaceSize, nFaces, ply->fp)) {
  422.   delete vBuffer;
  423.   delete pFaces;
  424.   delete mesh;
  425.   return NULL;
  426.       }
  427.     } else {
  428.       //otherwise, tristrips
  429.       nFaces = 0; pFaces = NULL;
  430.       fread ((char*)&nStrips, sizeof(int), 1, ply->fp);
  431.       mesh->tstrips = new vector<int> (nStrips); //reserve space
  432.       pStrips = &(*mesh->tstrips)[0]; //and read right into it
  433.       if (1 != fread ((char*)pStrips, sizeof(int), nStrips, ply->fp)) {
  434.   delete vBuffer;
  435.   delete mesh->tstrips;
  436.   delete mesh;
  437.   return NULL;
  438.       }
  439.     }
  440.     //transfer
  441.     int ofsX = -1, ofsY = -1, ofsZ = -1;
  442.     int ofsNx = -1, ofsNy = -1, ofsNz = -1;
  443.     int ofsIntensity = -1, ofsConf = -1;
  444.     //int ofsStdDev = -1; //this was here but unused and causing warnings
  445.     int ofsD_Red = -1, ofsD_Green = -1, ofsD_Blue = -1;
  446.     int ofsTexU = -1, ofsTexV = -1;
  447.     
  448.     int ofs = 0;
  449.     for (i = 0; i < ply->elems[0]->nprops; i++) {
  450.       PlyProperty* pProp = ply->elems[0]->props[i];
  451.       if      (!strcmp (pProp->name, "x"))
  452. ofsX = ofs;
  453.       else if (!strcmp (pProp->name, "y"))
  454. ofsY = ofs;
  455.       else if (!strcmp (pProp->name, "z"))
  456. ofsZ = ofs;
  457.       else if (!strcmp (pProp->name, "nx"))
  458. ofsNx = ofs;
  459.       else if (!strcmp (pProp->name, "ny"))
  460. ofsNy = ofs;
  461.       else if (!strcmp (pProp->name, "nz"))
  462. ofsNz = ofs;
  463.       else if (!strcmp (pProp->name, "intensity"))
  464. ofsIntensity = ofs;
  465.       //else if (!strcmp (pProp->name, "std_dev"))
  466.       //  ofsStdDev = ofs;
  467.       else if (!strcmp (pProp->name, "confidence"))
  468. ofsConf = ofs;
  469.       else if (!strcmp (pProp->name, "diffuse_red"))
  470. ofsD_Red = ofs;
  471.       else if (!strcmp (pProp->name, "diffuse_green"))
  472. ofsD_Green = ofs;
  473.       else if (!strcmp (pProp->name, "diffuse_blue"))
  474. ofsD_Blue = ofs;
  475.       else if (!strcmp (pProp->name, "texture_u"))
  476. ofsTexU = ofs;
  477.       else if (!strcmp (pProp->name, "texture_v"))
  478. ofsTexV = ofs;
  479.       ofs += SizeOfProp [pProp->external_type];
  480.     }
  481.     assert (ofsX != -1 && ofsY != -1 && ofsZ != -1);
  482.     mesh->numVerts = nVerts;
  483.     mesh->verts = new Vertex[nVerts];
  484.     if (ofsConf != -1)
  485.       mesh->vertConfidence = new float[nVerts];
  486.     if (ofsIntensity != -1)
  487.       mesh->vertIntensity = new float[nVerts];
  488.     if (ofsNx != -1 && ofsNy == -1 && ofsNz == -1)
  489.       mesh->hasVertNormals = TRUE;
  490.     else
  491.       ofsNx = ofsNy = ofsNz = -1;
  492.     if (ofsD_Red != -1 && ofsD_Green != -1 && ofsD_Blue != -1)
  493.       mesh->vertMatDiff = new vec3uc[nVerts];
  494.     else
  495.       ofsD_Red = ofsD_Green = ofsD_Blue = -1;
  496.     if (ofsTexU != -1 && ofsTexV != -1 && !skipTexture) {
  497.       mesh->texture = new vec2f[nVerts];
  498.       mesh->hasTexture = TRUE;
  499.     }
  500.     else
  501.       ofsTexU = ofsTexV = -1;
  502.     //don't actually know what to do with std_dev data
  503.     //verify assumptions about what is stored contiguously
  504.     assert (ofsY == ofsX + sizeof(float));
  505.     assert (ofsZ == ofsY + sizeof(float));
  506.     if (ofsNx != -1) {
  507.       assert (ofsNy == ofsNx + sizeof(float));
  508.       assert (ofsNz == ofsNy + sizeof(float));
  509.     }
  510.     if (ofsD_Red != -1) {
  511.       assert (ofsD_Green == ofsD_Red + sizeof(uchar));
  512.       assert (ofsD_Blue == ofsD_Green + sizeof(uchar));
  513.     }
  514.     if (ofsTexU != -1)
  515.       assert (ofsTexV == ofsTexU + sizeof(float));
  516.     char* vert;
  517.     for (vert = vBuffer, i = 0; i < nVerts;
  518.  vert += cbVertex, i++) {
  519. #if defined(WIN32) || defined(i386)
  520.       CopyReverseWord (&mesh->verts[i].coord, vert + ofsX, 3);
  521.       if (ofsNx != -1)
  522. CopyReverseWord (&mesh->verts[i].norm, vert + ofsNx, 3);
  523.       if (ofsD_Red != -1)
  524. memcpy (mesh->vertMatDiff+i, vert + ofsD_Red, 3*sizeof(uchar));
  525.       if (ofsTexU != -1)
  526. CopyReverseWord (mesh->texture+i, vert + ofsTexU, 2);
  527.       if (ofsIntensity != -1)
  528. CopyReverseWord (mesh->vertIntensity+i, vert + ofsIntensity, 1);
  529.       if (ofsConf != -1)
  530. CopyReverseWord (mesh->vertConfidence+i, vert + ofsConf, 1);
  531. #else
  532.       memcpy (&mesh->verts[i].coord, vert + ofsX, 3*sizeof(float));
  533.       if (ofsNx != -1)
  534. memcpy (&mesh->verts[i].norm, vert + ofsNx, 3*sizeof(float));
  535.       if (ofsD_Red != -1)
  536. memcpy (mesh->vertMatDiff+i, vert + ofsD_Red, 3*sizeof(uchar));
  537.       if (ofsTexU != -1)
  538. memcpy (mesh->texture+i, vert + ofsTexU, 2*sizeof(float));
  539.       if (ofsIntensity != -1)
  540. memcpy (mesh->vertIntensity+i, vert + ofsIntensity, sizeof(float));
  541.       if (ofsConf != -1)
  542. memcpy (mesh->vertConfidence+i, vert + ofsConf, sizeof(float));
  543. #endif
  544.     }
  545.     delete vBuffer;
  546.     if (nFaces) {
  547.       assert(mesh->tris.size() == 0);
  548.       mesh->tris.reserve (nFaces);
  549.       char* pFace;
  550.       char* endFaces = pFaces + (nFaces*kRawFaceSize);
  551.       for (pFace = pFaces; pFace < endFaces; pFace += kRawFaceSize) {
  552. if (*pFace !=3 ) fprintf(stderr, "nV = %dn", (int)*pFace);
  553. assert (*pFace == 3);
  554. mesh->tris.push_back(Triangle());
  555. Triangle *pTri = mesh->tris.end()-1;
  556. #if defined(WIN32) || defined(i386)
  557. CopyReverseWord (&pTri->vindex1, pFace + 1, 3);
  558. #else
  559. memcpy (&pTri->vindex1, pFace + 1, kRawFaceSize - 1);
  560. #endif
  561.       }
  562.       delete pFaces;
  563.     } else {
  564.       //already have data in tstrips vector
  565.       mesh->trisFromStrip();
  566.     }
  567.     ply_close(ply);
  568.     return mesh;
  569.   */
  570.   return NULL;
  571. }
  572. int
  573. writePlyFile(char *filename, MeshSet *meshSet, 
  574.      int level, int useColorNotTexture, int writeNormals)
  575. {
  576. #if 1
  577.   return meshSet->meshes[level]->writePlyFile(filename,
  578.       useColorNotTexture,
  579.       writeNormals,
  580.       meshSet);
  581. #else
  582.   int i;
  583.   int hasIntensity;
  584.   int hasColor;
  585.   int hasConfidence;
  586.   int hasTexture;
  587.   char *elem_names[] = {"vertex", "face"};
  588.   Mesh *mesh = meshSet->meshes[level];
  589.   hasIntensity = mesh->vertIntensity != NULL;
  590.   hasColor = mesh->vertMatDiff != NULL;
  591.   hasConfidence = mesh->vertConfidence != NULL;
  592.   hasTexture = mesh->texture != NULL;
  593.   PlyFile ply;
  594.   if (!ply.open_for_writing(filename, 2, elem_names,PLY_BINARY_BE))
  595.     return 0;
  596.   if (hasTexture && !useColorNotTexture) {
  597.     char obj_info[PATH_MAX];
  598.     sprintf(obj_info, "%s %s", "texture_file", mesh->texFileName);
  599.     ply.put_obj_info(obj_info);
  600.   }
  601.   vector<PlyProperty> vert_props;
  602.   set_offsets();
  603.   vert_props.push_back(vert_prop_x);
  604.   vert_props.push_back(vert_prop_y);
  605.   vert_props.push_back(vert_prop_z);
  606.   if (writeNormals) {
  607.     vert_props.push_back(vert_prop_nx);
  608.     vert_props.push_back(vert_prop_ny);
  609.     vert_props.push_back(vert_prop_nz);
  610.   }
  611.   if (hasIntensity) {
  612.     vert_props.push_back(vert_prop_intens);
  613.   }
  614.     
  615.   if (hasConfidence) {
  616.     vert_props.push_back(vert_prop_confidence);
  617.     hasConfidence = 1;
  618.   }
  619.     
  620.   if (hasColor || (hasTexture && useColorNotTexture)) {
  621.     vert_props.push_back(vert_prop_diff_r);
  622.     vert_props.push_back(vert_prop_diff_g);
  623.     vert_props.push_back(vert_prop_diff_b);
  624.   }
  625.     
  626.   if (hasTexture && !useColorNotTexture) {
  627.     vert_props.push_back(vert_prop_texture_u);
  628.     vert_props.push_back(vert_prop_texture_v);
  629.   }
  630.   // count offset
  631.   face_props[0].offset = offsetof(PlyFace, verts);
  632.   face_props[0].count_offset = offsetof(PlyFace, nverts);  
  633.     
  634.   ply.describe_element("vertex", mesh->numVerts, 
  635. vert_props.size(), &vert_props[0]);
  636.   ply.describe_element("face", mesh->tris.size(), 1, face_props);
  637.   ply.header_complete();
  638.     
  639.     // set up and write the vertex elements
  640.   PlyVertex plyVert;
  641.   Vertex *vert;
  642.   ply.put_element_setup("vertex");
  643.   for (i = 0; i < mesh->numVerts; i++) {
  644.     vert = &mesh->verts[i];
  645.     plyVert.x = vert->coord.x;
  646.     plyVert.y = vert->coord.y;
  647.     plyVert.z = vert->coord.z;
  648.     if (hasIntensity)
  649.       plyVert.intensity = mesh->vertIntensity[i];
  650.     
  651.     if (hasConfidence)
  652.       plyVert.confidence = mesh->vertConfidence[i];
  653.     
  654.     if (hasColor) {
  655.       plyVert.diff_r = mesh->vertMatDiff[i][0];
  656.       plyVert.diff_g = mesh->vertMatDiff[i][1];
  657.       plyVert.diff_b = mesh->vertMatDiff[i][2];
  658.     }
  659.     if (writeNormals) {
  660.       plyVert.nx = vert->norm.x;
  661.       plyVert.ny = vert->norm.y;
  662.       plyVert.nz = vert->norm.z;
  663.     }
  664.     if (hasTexture && !useColorNotTexture) {
  665.       plyVert.tex_u = mesh->texture[i][0];
  666.       plyVert.tex_v = mesh->texture[i][1];
  667.     } 
  668.     else if (hasTexture && useColorNotTexture) {
  669.       float texU = mesh->texture[i][0];
  670.       float texV = mesh->texture[i][1];
  671.       int xOff = int(texU*meshSet->texXdim);
  672.       int yOff = int(texV*meshSet->texYdim);
  673.       // shouldn't that be texXdim, not texYdim*yOff ??
  674.       uchar *col = &meshSet->
  675. texture[3*(xOff + meshSet->texYdim*yOff)];
  676.       plyVert.diff_r = col[0];
  677.       plyVert.diff_g = col[1];
  678.       plyVert.diff_b = col[2];
  679.     }
  680.     ply.put_element((void *) &plyVert);
  681.   }
  682.   PlyFace plyFace;
  683.   Triangle *tri;
  684.   ply.put_element_setup("face");
  685.   for (i = 0; i < mesh->tris.size(); i++) {
  686.     tri = &mesh->tris[i];
  687.     plyFace.nverts = 3;
  688.     /*
  689.     vertIndices[0] = tri->vindex1;
  690.     vertIndices[1] = tri->vindex2;
  691.     vertIndices[2] = tri->vindex3;
  692.     plyFace.verts = (int *)vertIndices;
  693.     */
  694.     plyFace.verts[0] = tri->vindex1;
  695.     plyFace.verts[1] = tri->vindex2;
  696.     plyFace.verts[2] = tri->vindex3;
  697.     ply.put_element_static_strg((void *) &plyFace);
  698.   }
  699.   return 1;
  700. #endif
  701. }