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); }
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(); } }