MEM_SmartPtr<BSP_TMesh> BSP_PlyLoader:: NewMeshFromFile( char * file_name, MT_Vector3 &min, MT_Vector3 &max ) { min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY); max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY); PlyProperty vert_props[] = { /* list of property information for a vertex */ {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0}, {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0}, {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0}, }; PlyProperty face_props[] = { /* list of property information for a vertex */ {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)}, }; MEM_SmartPtr<BSP_TMesh> mesh = new BSP_TMesh; if (mesh == NULL) return NULL; int i,j; PlyFile *ply; int nelems; char **elist; int file_type; float version; int nprops; int num_elems; PlyProperty **plist; char *elem_name; LoadVertex load_vertex; LoadFace load_face; /* open a PLY file for reading */ ply = ply_open_for_reading( file_name, &nelems, &elist, &file_type, &version ); if (ply == NULL) return NULL; /* go through each kind of element that we learned is in the file */ /* and read them */ for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); /* print the name of the element, for debugging */ /* if we're on vertex elements, read them in */ if (equal_strings ("vertex", elem_name)) { /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); // make some memory for the vertices mesh->VertexSet().reserve(num_elems); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ ply_get_element (ply, (void *)&load_vertex); // pass the vertex into the mesh builder. if (load_vertex.x < min.x()) { min.x() = load_vertex.x; } else if (load_vertex.x > max.x()) { max.x()= load_vertex.x; } if (load_vertex.y < min.y()) { min.y() = load_vertex.y; } else if (load_vertex.y > max.y()) { max.y()= load_vertex.y; } if (load_vertex.z < min.z()) { min.z() = load_vertex.z; } else if (load_vertex.z > max.z()) { max.z()= load_vertex.z; } BSP_TVertex my_vert; my_vert.m_pos = MT_Vector3(load_vertex.x,load_vertex.y,load_vertex.z); mesh->VertexSet().push_back(my_vert); } } /* if we're on face elements, read them in */ if (equal_strings ("face", elem_name)) { /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { ply_get_element (ply, (void *)&load_face); int v; for (v = 2; v< load_face.nverts; v++) { BSP_TFace f; f.m_verts[0] = load_face.verts[0]; f.m_verts[1] = load_face.verts[v-1]; f.m_verts[2] = load_face.verts[v]; mesh->BuildNormal(f); mesh->FaceSet().push_back(f); } // free up the memory this pile of shit used to allocate the polygon's vertices free (load_face.verts); } } } /* close the PLY file */ ply_close (ply); return mesh; }
read_test() { int i,j,k; PlyFile *ply; int nelems; char **elist; int file_type; float version; int nprops; int num_elems; PlyProperty **plist; Vertex **vlist; Face **flist; char *elem_name; int num_comments; char **comments; int num_obj_info; char **obj_info; /* open a PLY file for reading */ ply = ply_open_for_reading("test", &nelems, &elist, &file_type, &version); /* print what we found out about the file */ printf ("version %f\n", version); printf ("type %d\n", file_type); /* go through each kind of element that we learned is in the file */ /* and read them */ for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); /* print the name of the element, for debugging */ printf ("element %s %d\n", elem_name, num_elems); /* if we're on vertex elements, read them in */ if (equal_strings ("vertex", elem_name)) { /* create a vertex list to hold all the vertices */ vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ vlist[j] = (Vertex *) malloc (sizeof (Vertex)); ply_get_element (ply, (void *) vlist[j]); /* print out vertex x,y,z for debugging */ printf ("vertex: %g %g %g\n", vlist[j]->x, vlist[j]->y, vlist[j]->z); } } /* if we're on face elements, read them in */ if (equal_strings ("face", elem_name)) { /* create a list to hold all the face elements */ flist = (Face **) malloc (sizeof (Face *) * num_elems); /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); ply_get_property (ply, elem_name, &face_props[1]); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ flist[j] = (Face *) malloc (sizeof (Face)); ply_get_element (ply, (void *) flist[j]); /* print out face info, for debugging */ printf ("face: %d, list = ", flist[j]->intensity); for (k = 0; k < flist[j]->nverts; k++) printf ("%d ", flist[j]->verts[k]); printf ("\n"); } } /* print out the properties we got, for debugging */ for (j = 0; j < nprops; j++) printf ("property %s\n", plist[j]->name); } /* grab and print out the comments in the file */ comments = ply_get_comments (ply, &num_comments); for (i = 0; i < num_comments; i++) printf ("comment = '%s'\n", comments[i]); /* grab and print out the object information */ obj_info = ply_get_obj_info (ply, &num_obj_info); for (i = 0; i < num_obj_info; i++) printf ("obj_info = '%s'\n", obj_info[i]); /* close the PLY file */ ply_close (ply); }
LOD_Decimation_InfoPtr NewVertsFromFile( char * file_name, MT_Vector3 &min, MT_Vector3 &max ) { min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY); max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY); PlyProperty vert_props[] = { /* list of property information for a vertex */ {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0}, {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0}, {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0}, }; PlyProperty face_props[] = { /* list of property information for a vertex */ {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,intensity), 0, 0, 0, 0}, {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)}, }; #if 0 MEM_SmartPtr<std::vector<float> > verts = new std::vector<float>; MEM_SmartPtr<std::vector<float> > vertex_normals = new std::vector<float>; MEM_SmartPtr<std::vector<int> > faces = new std::vector<int>; #else std::vector<float>* verts = new std::vector<float>; std::vector<float>* vertex_normals = new std::vector<float>; std::vector<int> * faces = new std::vector<int>; #endif int i,j; PlyFile *ply; int nelems; char **elist; int file_type; float version; int nprops; int num_elems; PlyProperty **plist; char *elem_name; LoadVertex load_vertex; LoadFace load_face; /* open a PLY file for reading */ ply = ply_open_for_reading(file_name, &nelems, &elist, &file_type, &version); if (ply == NULL) return NULL; /* go through each kind of element that we learned is in the file */ /* and read them */ for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); /* print the name of the element, for debugging */ /* if we're on vertex elements, read them in */ if (equal_strings ("vertex", elem_name)) { /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); // make some memory for the vertices verts->reserve(num_elems); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ ply_get_element (ply, (void *)&load_vertex); // pass the vertex into the mesh builder. if (load_vertex.x < min.x()) { min.x() = load_vertex.x; } else if (load_vertex.x > max.x()) { max.x()= load_vertex.x; } if (load_vertex.y < min.y()) { min.y() = load_vertex.y; } else if (load_vertex.y > max.y()) { max.y()= load_vertex.y; } if (load_vertex.z < min.z()) { min.z() = load_vertex.z; } else if (load_vertex.z > max.z()) { max.z()= load_vertex.z; } verts->push_back(load_vertex.x); verts->push_back(load_vertex.y); verts->push_back(load_vertex.z); vertex_normals->push_back(1.0f); vertex_normals->push_back(0.0f); vertex_normals->push_back(0.0f); } } /* if we're on face elements, read them in */ if (equal_strings ("face", elem_name)) { /* set up for getting face elements */ // ply_get_property (ply, elem_name, &face_props[0]); ply_get_property (ply, elem_name, &face_props[1]); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { ply_get_element (ply, (void *)&load_face); faces->push_back(load_face.verts[0]); faces->push_back(load_face.verts[1]); faces->push_back(load_face.verts[2]); // free up the memory this pile of shit used to allocate the polygon's vertices free (load_face.verts); } } } /* close the PLY file */ ply_close (ply); LOD_Decimation_InfoPtr output = new LOD_Decimation_Info; output->vertex_buffer = verts->begin(); output->vertex_num = verts->size()/3; output->triangle_index_buffer = faces->begin(); output->face_num = faces->size()/3; output->intern = NULL; output->vertex_normal_buffer = vertex_normals->begin(); // memory leaks 'r' us #if 0 verts.Release(); vertex_normals.Release(); faces.Release(); #endif return output; }
Polygon* Polygon::loadPolygon(const std::string& filename) { int elementCount; char** elementNames; int fileType; float version; // Open a PLY file for reading char* name = strdup(filename.c_str()); PlyFile* ply = ply_open_for_reading(name, &elementCount, &elementNames, &fileType, &version); free(name); if(!ply) { printf("FAILED\n"); return NULL; } // Print what we found out about the file //printf ("version %f\n", version); //printf ("type %d\n", fileType); std::vector<PlyVertex*> plyVertices; std::vector<PlyFace*> plyFaces; // Go through each kind of element that we learned is in the file and read them for (int i = 0; i < elementCount; i++) { // Get the description of the first element char* elementName = elementNames[i]; int entryCount, propertyCount; PlyProperty** properties = ply_get_element_description(ply, elementName, &entryCount, &propertyCount); // Print the name of the element, for debugging //printf("element %s %d\n", elementName, entryCount); // If we're on vertex elements, read them in if (!strcmp("vertex", elementName)) { // Set up for getting vertex elements ply_get_property(ply, elementName, &VERTEX_PROPERTIES[0]); ply_get_property(ply, elementName, &VERTEX_PROPERTIES[1]); ply_get_property(ply, elementName, &VERTEX_PROPERTIES[2]); plyVertices.reserve(entryCount); // Grab all the vertex elements for (int j = 0; j < entryCount; j++) { PlyVertex* v = new PlyVertex(); // Grab an element from the file ply_get_element(ply, v); plyVertices.push_back(v); // Print out vertex x,y,z for debugging //printf("vertex: %d %lf %lf %lf\n", plyVertices.size(), v->x, v->y, v->z); } } // If we're on face elements, read them in if (!strcmp("face", elementName)) { // Set up for getting face elements ply_get_property(ply, elementName, &FACE_PROPERTIES[0]); ply_get_property(ply, elementName, &FACE_PROPERTIES[1]); plyFaces.reserve(entryCount); // Grab all the face elements for (int j = 0; j < entryCount; j++) { PlyFace* f = new PlyFace(); // Grab an element from the file ply_get_element(ply, f); plyFaces.push_back(f); // Print out face info, for debugging /*printf("face: %d, list = ", f->intensity); for (int k = 0; k < f->nverts; k++) { printf("%d ", f->verts[k]); } printf("\n");*/ } } // Print out the properties we got, for debugging /*for (int j = 0; j < propertyCount; j++) { printf ("property %s\n", properties[j]->name); }*/ } Polygon* polygon = new Polygon(); polygon->vertices.reserve(plyVertices.size()); polygon->vertexArray.reserve(plyVertices.size() * 3); polygon->normalArray.reserve(plyVertices.size() * 3); polygon->colorArray.reserve(plyVertices.size() * 4); polygon->shadowVertexArray.reserve(plyVertices.size() * 3); polygon->shadowNormalArray.reserve(plyVertices.size() * 3); polygon->faces.reserve(plyFaces.size()); Vector3 vec3; polygon->minX = plyVertices[0]->x; polygon->maxX = plyVertices[0]->x; polygon->minY = plyVertices[0]->y; polygon->maxY = plyVertices[0]->y; polygon->minZ = plyVertices[0]->z; polygon->maxZ = plyVertices[0]->z; for(size_t i = 0; i < plyVertices.size(); i++) { vec3.setData(plyVertices[i]->x, plyVertices[i]->y, plyVertices[i]->z); Vertex* v = new Vertex(vec3); polygon->addVertex(v); polygon->minX = MIN(plyVertices[i]->x, polygon->minX); polygon->maxX = MAX(plyVertices[i]->x, polygon->maxX); polygon->minY = MIN(plyVertices[i]->y, polygon->minY); polygon->maxY = MAX(plyVertices[i]->y, polygon->maxY); polygon->minZ = MIN(plyVertices[i]->z, polygon->minZ); polygon->maxZ = MAX(plyVertices[i]->z, polygon->maxZ); delete plyVertices[i]; } polygon->width = polygon->maxX - polygon->minX; polygon->height = polygon->maxY - polygon->minY; polygon->depth = polygon->maxZ - polygon->minZ; printf("(%lf, %lf, %lf) -> (%lf, %lf, %lf) = (%lf, %lf, %lf)\n", polygon->minX, polygon->minY, polygon->minZ, polygon->maxX, polygon->maxY, polygon->maxZ, polygon->width, polygon->height, polygon->depth); for(size_t i = 0; i < plyFaces.size(); i++) { Face* face = new Face(); for(size_t j = 0; j < plyFaces[i]->nverts; j++) { int idx = plyFaces[i]->verts[j]; face->addVertex(idx); polygon->vertices[idx]->addAdjacent(face); } polygon->addFace(face); delete plyFaces[i]; } polygon->planeSize = -MAX(polygon->width, polygon->depth) * 1.5; polygon->planeY = polygon->minY - 0.06; // Close the PLY file. ply_close (ply); return polygon; }
void read_file(FILE *inFile) { int i,j,k; PlyFile *ply; int nprops; int num_elems; PlyProperty **plist; char *elem_name; float version; int get_nx,get_ny,get_nz; /*** Read in the original PLY object ***/ ply = ply_read (inFile, &nelems, &elist); ply_get_info (ply, &version, &file_type); for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); if (equal_strings ("vertex", elem_name)) { /* see if vertex holds any normal information */ get_nx = get_ny = get_nz = 0; for (j = 0; j < nprops; j++) { if (equal_strings ("nx", plist[j]->name)) get_nx = 1; if (equal_strings ("ny", plist[j]->name)) get_ny = 1; if (equal_strings ("nz", plist[j]->name)) get_nz = 1; } /* create a vertex list to hold all the vertices */ vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); nverts = num_elems; /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); if (get_nx) ply_get_property (ply, elem_name, &vert_props[3]); if (get_ny) ply_get_property (ply, elem_name, &vert_props[4]); if (get_nz) ply_get_property (ply, elem_name, &vert_props[5]); vert_other = ply_get_other_properties (ply, elem_name, offsetof(Vertex,other_props)); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { vlist[j] = (Vertex *) malloc (sizeof (Vertex)); ply_get_element (ply, (void *) vlist[j]); } } else if (equal_strings ("face", elem_name)) { /* create a list to hold all the face elements */ flist = (Face **) malloc (sizeof (Face *) * num_elems); nfaces = num_elems; /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); face_other = ply_get_other_properties (ply, elem_name, offsetof(Face,other_props)); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { flist[j] = (Face *) malloc (sizeof (Face)); ply_get_element (ply, (void *) flist[j]); } } else other_elements = ply_get_other_element (ply, elem_name, num_elems); } comments = ply_get_comments (ply, &num_comments); obj_info = ply_get_obj_info (ply, &num_obj_info); ply_close (ply); }
DeformModel::DeformModel(const std::string &fname, unsigned int num_frame, float ply_scale) { Init(); // char ply_fname[256]; _num_frame = num_frame; for (unsigned int cur_f = 0; cur_f < _num_frame; cur_f++) { std::stringstream ply_fname; ply_fname << fname << cur_f << ".ply"; // sprintf(ply_fname, "%s%d.ply", fname, cur_f); std::cout << "Opening " << ply_fname.str() << std::endl; FILE *fp = fopen(ply_fname.str().c_str(), "rb"); assert(fp); // PLY object: PlyFile *ply; // PLY properties: char **elist; int nelems; // hand over the stream to the ply functions: ply = ply_read(fp, &nelems, &elist); assert(ply); int file_type; float version; ply_get_info(ply, &version, &file_type); for (int i=0; i<nelems; i++) { char *elem_name = elist[i]; int num_elems, nprops; PlyProperty **plist = ply_get_element_description(ply, elem_name, &num_elems, &nprops); bool has_vertex_x = false, has_vertex_y = false, has_vertex_z = false, has_colors = false; unsigned char color_components = 0; // this is a vertex: if (equal_strings ("vertex", elem_name)) { for (int j=0; j<nprops; j++) { if (equal_strings("x", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[0]); /* x */ has_vertex_x = true; } else if (equal_strings("y", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[1]); /* y */ has_vertex_y = true; } else if (equal_strings("z", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[2]); /* z */ has_vertex_z = true; } else if (equal_strings("red", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[3]); /* z */ color_components++; } else if (equal_strings("green", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[4]); /* z */ color_components++; } else if (equal_strings("blue", plist[j]->name)) { ply_get_property (ply, elem_name, &vert_props[5]); /* z */ color_components++; } } has_colors = color_components == 3; // test for necessary properties if ((!has_vertex_x) || (!has_vertex_y) || (!has_vertex_z)) { logger->update("Warning: Vertex with less than 3 coordinated detected. Output will most likely be corrupt!"); continue; } // must be first frame, initialize structures: if (_num_vtx == 0) { _num_vtx = num_elems; _vtxs = new vec3f[_num_vtx*_num_frame]; _cur_vtxs = new vec3f[_num_vtx]; _prev_vtxs = new vec3f[_num_vtx]; _vtx_boxes = new BOX[_num_vtx]; _nrms = new vec3f[_num_vtx]; _vtx_fids = new id_list[_num_vtx]; cout << "Vtx # = " << _num_vtx << endl; if (has_colors) _colors = new color3[_num_vtx]; } // grab all the vertex elements PLYVertex plyNewVertex; for (int j=0; j<num_elems; j++) { ply_get_element(ply, (void *)&plyNewVertex); if (has_colors && cur_f == 0) { _colors[j].set(plyNewVertex.color); } _vtxs[cur_f*_num_vtx+j] = vec3f(plyNewVertex.coords) * ply_scale; if (cur_f == 0) { _prev_vtxs[j] = _cur_vtxs[j] = _vtxs[j]; } if (j != 0 && j%1000000 == 0) { cout << " - " << j << " of " << num_elems << " loaded." << endl; } } } // this is a face (and, hopefully, a triangle): else if (equal_strings ("face", elem_name) && _tris == NULL) { // I need this for..., otherwise error ... for (int j=0; j<nprops; j++) { if (equal_strings("vertex_indices", plist[j]->name)) { ply_get_property (ply, elem_name, &face_props[0]); /* vertex_indices */ } } /* grab all the face elements */ PLYFace plyFace; plyFace.other_props = NULL; list<edge2f> edgelist_temp; vector<tri3f> trilist_temp; for (int j = 0; j < num_elems; j++) { ply_get_element(ply, (void *)&plyFace); for (int fi = 0; fi < plyFace.nverts-2; fi++) { // // make a triangle in our format from PLY face + vertices // // copy vertex indices unsigned int id0, id1, id2; id0 = plyFace.verts[0]; id1 = plyFace.verts[fi+1]; id2 = plyFace.verts[fi+2]; tri3f tri(id0, id1, id2); // insert triangle into list trilist_temp.push_back(tri); unsigned int fid = (unsigned int)trilist_temp.size()-1; edgelist_temp.push_back(edge2f(id0, id1, fid)); edgelist_temp.push_back(edge2f(id1, id2, fid)); edgelist_temp.push_back(edge2f(id2, id0, fid)); } free(plyFace.verts); if (j != 0 && j%500000 == 0) { cout << " - " << j << " of " << num_elems << " loaded." << endl; } } edgelist_temp.sort(); list<edge2f> edge_unqie; for (list<edge2f>::iterator it=edgelist_temp.begin(); it!=edgelist_temp.end(); it++) { if (!edge_unqie.empty() && *it == edge_unqie.back()) { // find duplicated with other fid unsigned int fid = (*it).fid(0); assert(fid != -1); edge_unqie.back().set_fid2(fid); } else edge_unqie.push_back(*it); } edgelist_temp.clear(); vector<edge2f> edge_array; _num_edge = (unsigned int)edge_unqie.size(); _edges = new edge2f[_num_edge]; _edg_boxes = new BOX[_num_edge]; unsigned int t=0; for (list<edge2f>::iterator it=edge_unqie.begin(); it != edge_unqie.end(); it++) { _edges[t++] = *it; edge_array.push_back(*it); } // copy over temp list to static array _num_tri = (unsigned int)trilist_temp.size(); cout << "Allocating " << _num_tri*sizeof(tri3f) << " bytes of storage for triangles." << endl; _tris = new tri3f[_num_tri]; _tri_nrms = new vec3f[_num_tri]; _old_tri_nrms = NULL; _tri_edges = new tri3e[_num_tri]; _fac_boxes = new BOX[_num_tri]; _tri_flags = new char[_num_tri]; vector <edge2f>::iterator first = edge_array.begin(); vector <edge2f>::iterator last = edge_array.end(); for (t = 0; t < _num_tri; t++) { _tris[t] = trilist_temp[t]; vector <edge2f>::iterator it1 = lower_bound(first, last, edge2f(_tris[t].id0(), _tris[t].id1(), 0)); vector <edge2f>::iterator it2 = lower_bound(first, last, edge2f(_tris[t].id1(), _tris[t].id2(), 0)); vector <edge2f>::iterator it3 = lower_bound(first, last, edge2f(_tris[t].id2(), _tris[t].id0(), 0)); _tri_edges[t].set(it1-first, it2-first, it3-first); } cout << "Edge # = " << _num_edge << endl; cout << "Tri # = " << _num_tri << endl; } else // otherwise: skip all further NULL; } // PLY parsing ended, clean up vertex buffer and close the file // fclose(fp); ply_close(ply); } UpdateTriNorm(); for (unsigned t = 0; t < _num_tri; t++) for (int i=0; i<3; i++) { unsigned int vid = _tris[t].id(i); _vtx_fids[vid].push_back(t); } BufferAdjacent(); }
void PlyUtility::readPlyFile(char *filename) { int i,j; /* open a PLY file for reading */ ply = ply_open_for_reading(filename, &nelems, &elist, &file_type, &version); /* go through each kind of element that we learned is in the file */ /* and read them */ for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); /* if we're on vertex elements, read them in */ if (equal_strings ("vertex", elem_name)) { vertexCount=num_elems; /* create a vertex list to hold all the vertices */ vlist = (Vertex **) malloc (sizeof (Vertex *) * num_elems); /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ vlist[j] = (Vertex *) malloc (sizeof (Vertex)); ply_get_element (ply, (void *) vlist[j]); if(vx_max<vlist[j]->x)vx_max=vlist[j]->x; if(vy_max<vlist[j]->y)vy_max=vlist[j]->y; if(vz_max<vlist[j]->z)vz_max=vlist[j]->z; if(vx_min>vlist[j]->x)vx_min=vlist[j]->x; if(vy_min>vlist[j]->y)vy_min=vlist[j]->y; if(vz_min>vlist[j]->z)vz_min=vlist[j]->z; } } /* if we're on face elements, read them in */ if (equal_strings ("face", elem_name)) { faceCount=num_elems; /* create a list to hold all the face elements */ flist = (Face **) malloc (sizeof (Face *) * num_elems); /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); ply_get_property (ply, elem_name, &face_props[1]); /* grab all the face elements */ for (j = 0; j < num_elems; j++) { /* grab and element from the file */ flist[j] = (Face *) malloc (sizeof (Face)); ply_get_element (ply, (void *) flist[j]); } } } /* grab and print out the comments in the file */ comments = ply_get_comments (ply, &num_comments); /* grab and print out the object information */ obj_info = ply_get_obj_info (ply, &num_obj_info); /* close the PLY file */ ply_close (ply); }
void ReadFile( MFIList *mfi, Model *model ) { int i,j; PlyFile *ply; int nprops; int num_elems; PlyProperty **plist; char *elem_name; float version; FILE *fp; if ((fp = fopen(mfi->file_info.path, "rb")) == NULL) { crError( "Can't open %s for reading!", mfi->file_info.path ); } ply = ply_read (fp, &nelems, &elist); ply_get_info (ply, &version, &file_type); for (i = 0; i < nelems; i++) { /* get the description of the first element */ elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); if (equal_strings ("vertex", elem_name)) { /* see if vertex holds any normal information */ globals.has_nx = globals.has_ny = globals.has_nz = 0; globals.has_r = globals.has_g = globals.has_b = 0; for (j = 0; j < nprops; j++) { if (equal_strings ("nx", plist[j]->name)) globals.has_nx = 1; if (equal_strings ("ny", plist[j]->name)) globals.has_ny = 1; if (equal_strings ("nz", plist[j]->name)) globals.has_nz = 1; if (equal_strings ("red", plist[j]->name)) globals.has_r = 1; if (equal_strings ("green", plist[j]->name)) globals.has_g = 1; if (equal_strings ("blue", plist[j]->name)) globals.has_b = 1; } /* create a vertex list to hold all the vertices */ model->vlist = (Vertex *) crAlloc (sizeof (*(model->vlist)) * num_elems); model->nverts = num_elems; /* set up for getting vertex elements */ ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); if (globals.has_r) ply_get_property (ply, elem_name, &vert_props[3]); if (globals.has_g) ply_get_property (ply, elem_name, &vert_props[4]); if (globals.has_b) ply_get_property (ply, elem_name, &vert_props[5]); if (globals.has_nx) ply_get_property (ply, elem_name, &vert_props[6]); if (globals.has_ny) ply_get_property (ply, elem_name, &vert_props[7]); if (globals.has_nz) ply_get_property (ply, elem_name, &vert_props[8]); /* grab all the vertex elements */ for (j = 0; j < num_elems; j++) { model->vlist[j].r = 1.0f; model->vlist[j].g = 1.0f; model->vlist[j].b = 1.0f; model->vlist[j].nx = 1.0f; model->vlist[j].ny = 1.0f; model->vlist[j].nz = 1.0f; ply_get_element (ply, model->vlist+j); model->vlist[j].r /= 255.0f; model->vlist[j].g /= 255.0f; model->vlist[j].b /= 255.0f; } } else if (equal_strings ("face", elem_name)) { /* create a list to hold all the face elements */ model->flist = (Face *) crAlloc (sizeof (*(model->flist)) * num_elems); model->nfaces = num_elems; /* set up for getting face elements */ ply_get_property (ply, elem_name, &face_props[0]); /* grab all the face elements */ crDebug( "Reading %s (%d faces)", mfi->file_info.path, model->nfaces ); model->faces = (unsigned int *) crAlloc( model->nfaces * 3 * sizeof( *(model->faces) ) ); for (j = 0; j < num_elems; j++) { ply_get_element (ply, model->flist + j); model->faces[j*3+0] = model->flist[j].verts[0]; model->faces[j*3+1] = model->flist[j].verts[1]; model->faces[j*3+2] = model->flist[j].verts[2]; } } } ply_close (ply); }
void Grid::read_ply_file(char* file_name, const int triangle_type) { // Vertex definition typedef struct Vertex { float x,y,z; // space coordinates } Vertex; // Face definition. This is the same for all files but is placed here to keep all the definitions together typedef struct Face { unsigned char nverts; // number of vertex indices in list int* verts; // vertex index list } Face; // list of property information for a vertex // this varies depending on what you are reading from the file PlyProperty vert_props[] = { {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0}, {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0}, {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0} }; // list of property information for a face. // there is a single property, which is a list // this is the same for all files PlyProperty face_props[] = { {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)} }; // local variables int i,j; PlyFile* ply; int nelems; // number of element types: 2 in our case - vertices and faces char** elist; int file_type; float version; int nprops; // number of properties each element has int num_elems; // number of each type of element: number of vertices or number of faces PlyProperty** plist; Vertex** vlist; Face** flist; char* elem_name; int num_comments; char** comments; int num_obj_info; char** obj_info; // open a ply file for reading ply = ply_open_for_reading(file_name, &nelems, &elist, &file_type, &version); // print what we found out about the file printf ("version %f\n", version); printf ("type %d\n", file_type); // go through each kind of element that we learned is in the file and read them for (i = 0; i < nelems; i++) { // there are only two elements in our files: vertices and faces // get the description of the first element elem_name = elist[i]; plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); // print the name of the element, for debugging cout << "element name " << elem_name << " num elements = " << num_elems << " num properties = " << nprops << endl; // if we're on vertex elements, read in the properties if (equal_strings ("vertex", elem_name)) { // set up for getting vertex elements // the three properties are the vertex coordinates ply_get_property (ply, elem_name, &vert_props[0]); ply_get_property (ply, elem_name, &vert_props[1]); ply_get_property (ply, elem_name, &vert_props[2]); // reserve mesh elements mesh_ptr->num_vertices = num_elems; mesh_ptr->vertices.reserve(num_elems); // grab all the vertex elements for (j = 0; j < num_elems; j++) { Vertex* vertex_ptr = new Vertex; // grab an element from the file ply_get_element (ply, (void *) vertex_ptr); mesh_ptr->vertices.push_back(Point3D(vertex_ptr->x, vertex_ptr->y, vertex_ptr->z)); delete vertex_ptr; } } // if we're on face elements, read them in if (equal_strings ("face", elem_name)) { // set up for getting face elements ply_get_property (ply, elem_name, &face_props[0]); // only one property - a list mesh_ptr->num_triangles = num_elems; objects.reserve(num_elems); // triangles will be stored in Compound::objects // the following code stores the face numbers that are shared by each vertex mesh_ptr->vertex_faces.reserve(mesh_ptr->num_vertices); vector<int> faceList; for (j = 0; j < mesh_ptr->num_vertices; j++) mesh_ptr->vertex_faces.push_back(faceList); // store empty lists so that we can use the [] notation below // grab all the face elements int count = 0; // the number of faces read for (j = 0; j < num_elems; j++) { // grab an element from the file Face* face_ptr = new Face; ply_get_element (ply, (void *) face_ptr); // construct a mesh triangle of the specified type if (triangle_type == flat) { FlatMeshTriangle* triangle_ptr = new FlatMeshTriangle(mesh_ptr, face_ptr->verts[0], face_ptr->verts[1], face_ptr->verts[2]); triangle_ptr->compute_normal(reverse_normal); objects.push_back(triangle_ptr); } if (triangle_type == smooth) { SmoothMeshTriangle* triangle_ptr = new SmoothMeshTriangle(mesh_ptr, face_ptr->verts[0], face_ptr->verts[1], face_ptr->verts[2]); triangle_ptr->compute_normal(reverse_normal); // the "flat triangle" normal is used to compute the average normal at each mesh vertex objects.push_back(triangle_ptr); // it's quicker to do it once here, than have to do it on average 6 times in compute_mesh_normals // the following code stores a list of all faces that share a vertex // it's used for computing the average normal at each vertex in order(num_vertices) time mesh_ptr->vertex_faces[face_ptr->verts[0]].push_back(count); mesh_ptr->vertex_faces[face_ptr->verts[1]].push_back(count); mesh_ptr->vertex_faces[face_ptr->verts[2]].push_back(count); count++; } } if (triangle_type == flat) mesh_ptr->vertex_faces.erase(mesh_ptr->vertex_faces.begin(), mesh_ptr->vertex_faces.end()); } // print out the properties we got, for debugging for (j = 0; j < nprops; j++) printf ("property %s\n", plist[j]->name); } // end of for (i = 0; i < nelems; i++) // grab and print out the comments in the file comments = ply_get_comments (ply, &num_comments); for (i = 0; i < num_comments; i++) printf ("comment = '%s'\n", comments[i]); // grab and print out the object information obj_info = ply_get_obj_info (ply, &num_obj_info); for (i = 0; i < num_obj_info; i++) printf ("obj_info = '%s'\n", obj_info[i]); // close the ply file ply_close (ply); }
void PlyReader::parseFile() { SURGSIM_ASSERT(isValid()) << "'" << m_filename << "' is an invalid .ply file"; if (m_startParseFileCallback != nullptr) { m_startParseFileCallback(); } char* currentElementName; for (int elementIndex = 0; elementIndex < m_data->elementCount; ++elementIndex) { currentElementName = m_data->elementNames[elementIndex]; int numberOfElements; int propertyCount; // Free this after we are done with it PlyProperty** properties = ply_get_element_description(m_data->plyFile, currentElementName, &numberOfElements, &propertyCount); std::vector<int> listOffsets; // Check if the user wanted this element, if yes process if (m_requestedElements.find(currentElementName) != m_requestedElements.end()) { ElementInfo& elementInfo = m_requestedElements[currentElementName]; // Build the propertyinfo structure for (size_t propertyIndex = 0; propertyIndex < elementInfo.requestedProperties.size(); ++propertyIndex) { PropertyInfo& propertyInfo = elementInfo.requestedProperties[propertyIndex]; PlyProperty requestedProperty = {nullptr, 0, 0, 0, 0, 0, 0, 0}; // Create temp char* std::vector<char> writable(propertyInfo.propertyName.size() + 1); std::copy(propertyInfo.propertyName.begin(), propertyInfo.propertyName.end(), writable.begin()); requestedProperty.name = &writable[0]; requestedProperty.internal_type = propertyInfo.dataType; requestedProperty.offset = propertyInfo.dataOffset; requestedProperty.count_internal = propertyInfo.countType; requestedProperty.count_offset = propertyInfo.countOffset; requestedProperty.is_list = (propertyInfo.countType != 0) ? PLY_LIST : PLY_SCALAR; if (requestedProperty.is_list == PLY_LIST) { listOffsets.push_back(propertyInfo.dataOffset); } // Tell ply that we want this property to be read and put into the readbuffer ply_get_property(m_data->plyFile, currentElementName, &requestedProperty); } void* readBuffer = elementInfo.startElementCallback(currentElementName, numberOfElements); for (int element = 0; element < numberOfElements; ++element) { ply_get_element(m_data->plyFile, readBuffer); if (elementInfo.processElementCallback != nullptr) { try { elementInfo.processElementCallback(currentElementName); } catch (const std::exception&) { for (size_t i = 0; i<listOffsets.size(); ++i) { void** item = (void **)((char *)readBuffer + listOffsets[i]); // NOLINT free(item[0]); } for (int i = 0; i < propertyCount; ++i) { free(properties[i]->name); free(properties[i]); } free(properties); throw; } } // Free the lists that where allocated by plyreader // This gains access to the buffer, where ply.c put the address of // the memory that was allocated to carry the information for the list property // it does that for all properties that where marked as lists for (size_t i = 0; i<listOffsets.size(); ++i) { void** item = (void **)((char *)readBuffer + listOffsets[i]); // NOLINT free(item[0]); } } if (elementInfo.endElementCallback != nullptr) { elementInfo.endElementCallback(currentElementName); } } else { // Inefficient way to skip an element, but there does not seem to be an // easy way to ignore an element // The data for other is stored internally in the plyFile data structure // and should not be freed ply_get_other_element(m_data->plyFile, currentElementName, numberOfElements); } // Free the data allocated in the ply_get_element_description call for (int i = 0; i < propertyCount; ++i) { free(properties[i]->name); free(properties[i]); } free(properties); } if (m_endParseFileCallback != nullptr) { m_endParseFileCallback(); } }
cMesh::cMesh(const std::string & Filename, bool doAdjacence) { PlyFile * thePlyFile; int nelems; char **elist; int file_type; float version; int nprops; int num_elems; char *elem_name; thePlyFile = ply_open_for_reading( const_cast<char *>(Filename.c_str()), &nelems, &elist, &file_type, &version); ELISE_ASSERT(thePlyFile != NULL, "cMesh3D.cpp: cMesh::cMesh, cannot open ply file for reading"); for (int i = 0; i < nelems; i++) { elem_name = elist[i]; ply_get_element_description (thePlyFile, elem_name, &num_elems, &nprops); //printf ("element %s %d\n", elem_name, num_elems); if (equal_strings ("vertex", elem_name)) { ply_get_property (thePlyFile, elem_name, &props[0]); ply_get_property (thePlyFile, elem_name, &props[1]); ply_get_property (thePlyFile, elem_name, &props[2]); for (int j = 0; j < num_elems; j++) { sVertex *vert = (sVertex *) malloc (sizeof(sVertex)); ply_get_element (thePlyFile, vert); //ajout du point addPt(Pt3dr(vert->x, vert->y, vert->z)); //printf ("vertex: %g %g %g\n", vert->x, vert->y, vert->z); } } else if (equal_strings ("face", elem_name)) { ply_get_property ( thePlyFile, elem_name, &face_props[0]); for (int j = 0; j < num_elems; j++) { sFace *theFace = (sFace *) malloc (sizeof (sFace)); ply_get_element (thePlyFile, theFace); vector <int> vIndx; for (int aK =0; aK < theFace->nverts; ++aK) vIndx.push_back(theFace->verts[aK]); //ajout du triangle addTriangle(cTriangle(this, vIndx, j)); } } } if (doAdjacence) //remplissage du graphe d'adjacence { int cpt; int id0a, id1a, id2a; int id0b, id1b, id2b; int idc0, idc1; //index des sommets communs id0a = id1a = id2a = idc0 = idc1 = -1; id0b = id1b = id2b = -2; for (int aK = 0; aK < getFacesNumber(); ++aK) { mTriangles[aK].getVertexesIndexes(id0a, id1a, id2a); for (int bK=aK; bK < getFacesNumber(); ++bK) { mTriangles[bK].getVertexesIndexes(id0b, id1b, id2b); cpt = 0; if((id0b == id0a)||(id1b == id0a)||(id2b == id0a)) {cpt++; idc0 = id0a;} if((id0b == id1a)||(id1b == id1a)||(id2b == id1a)) { if (cpt) idc1 = id1a; else idc0 = id1a; cpt++; } if((id0b == id2a)||(id1b == id2a)||(id2b == id2a)) { if (cpt) idc1 = id2a; else idc0 = id2a; cpt++; } if (cpt == 2) { #ifdef _DEBUG printf ("found adjacent triangles : %d %d - vertex : %d %d\n", aK, bK, idc0, idc1); #endif addEdge(cEdge(aK, bK, idc0, idc1)); int idx = getEdgesNumber() - 1; //cout << "adding edge " << idx << endl; mTriangles[aK].addEdge(idx); mTriangles[bK].addEdge(idx); } } } } ply_close (thePlyFile); }
GlCloud* GlCloud::loadPly(string i_filename ,int* incre) { int type = 0; vector <GlVertex> ptList; PlyFile * thePlyFile; int nelems; char **elist; int file_type; float version; int nprops; int num_elems; char *elem_name; PlyProperty ** plist = NULL; (void)plist; thePlyFile = ply_open_for_reading( const_cast<char *>(i_filename.c_str()), &nelems, &elist, &file_type, &version); elem_name = elist[0]; plist = ply_get_element_description (thePlyFile, elem_name, &num_elems, &nprops); #ifdef _DEBUG printf ("file %s\n" , i_filename.c_str()); printf ("version %f\n" , version); printf ("type %d\n" , file_type); printf ("nb elem %d\n" , nelems); printf ("num elems %d\n", num_elems); #endif for (int i = 0; i < nelems; i++) { // get the description of the first element elem_name = elist[i]; plist = ply_get_element_description (thePlyFile, elem_name, &num_elems, &nprops); // print the name of the element, for debugging #ifdef _DEBUG printf ("element %s %d %d\n", elem_name, num_elems, nprops); #endif if (equal_strings ("vertex", elem_name)) { switch(nprops) { case 10: // x y z nx ny nz r g b a { type = 5; for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &oriented_colored_alpha_vert_props[j]); sPlyOrientedColoredAlphaVertex *vertex = (sPlyOrientedColoredAlphaVertex *) malloc (sizeof (sPlyOrientedColoredAlphaVertex)); // grab all the vertex elements for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex--: %g %g %g %g %g %g %u %u %u %u\n", vertex->x, vertex->y, vertex->z, vertex->nx, vertex->ny, vertex->nz, vertex->red, vertex->green, vertex->blue, vertex->alpha); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ), QColor( vertex->red, vertex->green, vertex->blue, vertex->alpha ), QVector3D(vertex->nx, vertex->ny, vertex->nz))); } break; } case 9: // x y z nx ny nz r g b { type = 4; for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &oriented_colored_vert_props[j]); sPlyOrientedColoredVertex *vertex = (sPlyOrientedColoredVertex *) malloc (sizeof (sPlyOrientedColoredVertex)); // grab all the vertex elements for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex--: %g %g %g %g %g %g %u %u %u\n", vertex->x, vertex->y, vertex->z, vertex->nx, vertex->ny, vertex->nz, vertex->red, vertex->green, vertex->blue); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ), QColor( vertex->red, vertex->green, vertex->blue ), QVector3D(vertex->nx, vertex->ny, vertex->nz))); } break; } case 7: { type = 2; // setup for getting vertex elements for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &colored_a_vert_props[j]); sPlyColoredVertexWithAlpha * vertex = (sPlyColoredVertexWithAlpha *) malloc (sizeof (sPlyColoredVertexWithAlpha)); // grab all the vertex elements for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; // grab an element from the file ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex--: %g %g %g %u %u %u %u\n", vertex->x, vertex->y, vertex->z, vertex->red, vertex->green, vertex->blue, vertex->alpha); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ), QColor( vertex->red, vertex->green, vertex->blue, vertex->alpha ))); } break; } case 6: { // can be (x y z r g b) or (x y z nx ny nz) bool wNormales = false; PlyElement *elem = NULL; for (int i = 0; i < nelems; i++) if (equal_strings ("vertex", thePlyFile->elems[i]->name)) elem = thePlyFile->elems[i]; for (int i = 0; i < nprops; i++) if ( "nx"==elem->props[i]->name ) wNormales = true; if (!wNormales) { type = 1; for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &colored_vert_props[j]); sPlyColoredVertex *vertex = (sPlyColoredVertex *) malloc (sizeof (sPlyColoredVertex)); for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex: %g %g %g %u %u %u\n", vertex->x, vertex->y, vertex->z, vertex->red, vertex->green, vertex->blue); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ), QColor( vertex->red, vertex->green, vertex->blue ))); } } else { type = 3; for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &oriented_vert_props[j]); sPlyOrientedVertex *vertex = (sPlyOrientedVertex *) malloc (sizeof (sPlyOrientedVertex)); for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex: %g %g %g %g %g %g\n", vertex->x, vertex->y, vertex->z, vertex->nx, vertex->ny, vertex->nz); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ), Qt::white, QVector3D(vertex->nx, vertex->ny, vertex->nz))); } } break; } case 3: { for (int j = 0; j < nprops ;++j) ply_get_property (thePlyFile, elem_name, &vert_props[j]); sVertex *vertex = (sVertex *) malloc (sizeof (sVertex)); for (int j = 0; j < num_elems; j++) { if (incre) *incre = 100.0f*(float)j/num_elems; ply_get_element (thePlyFile, (void *) vertex); #ifdef _DEBUG printf ("vertex: %g %g %g\n", vertex->x, vertex->y, vertex->z); #endif ptList.push_back( GlVertex (QVector3D ( vertex->x, vertex->y, vertex->z ))); } break; } default: { printf("unable to load a ply unless number of properties is 3, 6, 7, 9 or 10\n"); break; } } } } #ifdef _DEBUG printf("check - point number in cloud: %d\n", (int) ptList.size() ); #endif ply_close (thePlyFile); if(incre) *incre = 0; return new GlCloud(ptList, type); }