int reader_t::vertex_cb(p_ply_argument argument) { long value_index, element_index; vertexes_t* vertexes; ply_get_argument_element(argument, nullptr, &element_index); ply_get_argument_user_data(argument, (void**) &vertexes, &value_index); (*vertexes)[element_index][value_index] = ply_get_argument_value(argument); return 1; }
int reader_t::face_cb(p_ply_argument argument) { long value_index, element_index; faces_t* faces; ply_get_argument_element(argument, nullptr, &element_index); ply_get_argument_property(argument, nullptr, nullptr, &value_index); ply_get_argument_user_data(argument, (void**) &faces, nullptr); if (value_index != -1) (*faces)[element_index][value_index] = ply_get_argument_value(argument); return 1; }
/* Callback to handle vertex data from RPly */ int rply_vertex_callback(p_ply_argument argument) { Float **buffers; long index, flags; ply_get_argument_user_data(argument, (void **)&buffers, &flags); ply_get_argument_element(argument, nullptr, &index); int bufferIndex = (flags & 0xF00) >> 8; int stride = (flags & 0x0F0) >> 4; int offset = flags & 0x00F; Float *buffer = buffers[bufferIndex]; if (buffer) buffer[index * stride + offset] = (float)ply_get_argument_value(argument); return 1; }
// rply face callback static int FaceCB(p_ply_argument argument) { void *userData = NULL; ply_get_argument_user_data(argument, &userData, NULL); Triangle *verts = *static_cast<Triangle **> (userData); long triIndex; ply_get_argument_element(argument, NULL, &triIndex); long length, valueIndex; ply_get_argument_property(argument, NULL, &length, &valueIndex); if (valueIndex >= 0 && valueIndex < 3) { verts[triIndex].v[valueIndex] = static_cast<unsigned int> (ply_get_argument_value(argument)); } return 1; }
// rply uv callback static int UVCB(p_ply_argument argument) { long userIndex = 0; void *userData = NULL; ply_get_argument_user_data(argument, &userData, &userIndex); UV *uv = *static_cast<UV **> (userData); long uvIndex; ply_get_argument_element(argument, NULL, &uvIndex); if (userIndex == 0) uv[uvIndex].u = static_cast<float>(ply_get_argument_value(argument)); else if (userIndex == 1) uv[uvIndex].v = static_cast<float>(ply_get_argument_value(argument)); return 1; }
int ply_parser_call_back(p_ply_argument argument) { p_ply_element elem; p_ply_property prop; const char* elem_name; const char* prop_name; PLYParser* parser; long prop_len; long value_idx; assert_success(ply_get_argument_element(argument, &elem, NULL)); assert_success(ply_get_argument_property(argument, &prop, &prop_len, &value_idx)); assert_success(ply_get_element_info(elem, &elem_name, NULL)); assert_success(ply_get_property_info(prop, &prop_name, NULL, NULL, NULL)); assert_success(ply_get_argument_user_data(argument, (void**)&parser, NULL)); Float value = ply_get_argument_value(argument); if (value_idx >= 0) parser->add_property_value(elem_name, prop_name, value); return 1; }
// rply color callback static int ColorCB(p_ply_argument argument) { long userIndex = 0; void *userData = NULL; ply_get_argument_user_data(argument, &userData, &userIndex); RGB* c = *static_cast<RGB **> (userData); long colIndex; ply_get_argument_element(argument, NULL, &colIndex); if (userIndex == 0) c[colIndex].r = static_cast<float>(ply_get_argument_value(argument) / 255.0); else if (userIndex == 1) c[colIndex].g = static_cast<float>(ply_get_argument_value(argument) / 255.0); else if (userIndex == 2) c[colIndex].b = static_cast<float>(ply_get_argument_value(argument) / 255.0); return 1; }
// rply vertex callback static int VertexCB(p_ply_argument argument) { long userIndex = 0; void *userData = NULL; ply_get_argument_user_data(argument, &userData, &userIndex); Point* p = *static_cast<Point **> (userData); long vertIndex; ply_get_argument_element(argument, NULL, &vertIndex); if (userIndex == 0) p[vertIndex].x = static_cast<float>(ply_get_argument_value(argument)); else if (userIndex == 1) p[vertIndex].y = static_cast<float>(ply_get_argument_value(argument)); else if (userIndex == 2) p[vertIndex].z = static_cast<float>(ply_get_argument_value(argument)); return 1; }
// rply normal callback static int NormalCB(p_ply_argument argument) { long userIndex = 0; void *userData = NULL; ply_get_argument_user_data(argument, &userData, &userIndex); Normal* n = *static_cast<Normal **> (userData); long normIndex; ply_get_argument_element(argument, NULL, &normIndex); if (userIndex == 0) n[normIndex].x = static_cast<float>(ply_get_argument_value(argument)); else if (userIndex == 1) n[normIndex].y = static_cast<float>(ply_get_argument_value(argument)); else if (userIndex == 2) n[normIndex].z = static_cast<float>(ply_get_argument_value(argument)); return 1; }
void load_ply(const std::string &filename, MatrixXu &F, MatrixXf &V, bool load_faces, const ProgressCallback &progress) { auto message_cb = [](p_ply ply, const char *msg) { cerr << "rply: " << msg << endl; }; Timer<> timer; cout << "Loading \"" << filename << "\" .. "; cout.flush(); p_ply ply = ply_open(filename.c_str(), message_cb, 0, nullptr); if (!ply) throw std::runtime_error("Unable to open PLY file \"" + filename + "\"!"); if (!ply_read_header(ply)) { ply_close(ply); throw std::runtime_error("Unable to open PLY header of \"" + filename + "\"!"); } p_ply_element element = nullptr; uint32_t vertexCount = 0, faceCount = 0; /* Inspect the structure of the PLY file */ while ((element = ply_get_next_element(ply, element)) != nullptr) { const char *name; long nInstances; ply_get_element_info(element, &name, &nInstances); if (!strcmp(name, "vertex")) vertexCount = (uint32_t) nInstances; else if (!strcmp(name, "face")) faceCount = (uint32_t) nInstances; } if (vertexCount == 0 && faceCount == 0) throw std::runtime_error("PLY file \"" + filename + "\" is invalid! No face/vertex/elements found!"); if (load_faces) F.resize(3, faceCount); V.resize(3, vertexCount); struct VertexCallbackData { MatrixXf &V; const ProgressCallback &progress; VertexCallbackData(MatrixXf &V, const ProgressCallback &progress) : V(V), progress(progress) {} }; struct FaceCallbackData { MatrixXu &F; const ProgressCallback &progress; FaceCallbackData(MatrixXu &F, const ProgressCallback &progress) : F(F), progress(progress) {} }; auto rply_vertex_cb = [](p_ply_argument argument) -> int { VertexCallbackData *data; long index, coord; ply_get_argument_user_data(argument, (void **) &data, &coord); ply_get_argument_element(argument, nullptr, &index); data->V(coord, index) = (Float) ply_get_argument_value(argument); if (data->progress && coord == 0 && index % 500000 == 0) data->progress("Loading vertex data", index / (Float) data->V.cols()); return 1; }; auto rply_index_cb = [](p_ply_argument argument) -> int { FaceCallbackData *data; long length, value_index, index; ply_get_argument_property(argument, nullptr, &length, &value_index); if (length != 3) throw std::runtime_error("Only triangle faces are supported!"); ply_get_argument_user_data(argument, (void **) &data, nullptr); ply_get_argument_element(argument, nullptr, &index); if (value_index >= 0) data->F(value_index, index) = (uint32_t) ply_get_argument_value(argument); if (data->progress && value_index == 0 && index % 500000 == 0) data->progress("Loading face data", index / (Float) data->F.cols()); return 1; }; VertexCallbackData vcbData(V, progress); FaceCallbackData fcbData(F, progress); if (!ply_set_read_cb(ply, "vertex", "x", rply_vertex_cb, &vcbData, 0) || !ply_set_read_cb(ply, "vertex", "y", rply_vertex_cb, &vcbData, 1) || !ply_set_read_cb(ply, "vertex", "z", rply_vertex_cb, &vcbData, 2)) { ply_close(ply); throw std::runtime_error("PLY file \"" + filename + "\" does not contain vertex position data!"); } if (load_faces) { if (!ply_set_read_cb(ply, "face", "vertex_indices", rply_index_cb, &fcbData, 0)) { ply_close(ply); throw std::runtime_error("PLY file \"" + filename + "\" does not contain vertex indices!"); } } if (!ply_read(ply)) { ply_close(ply); throw std::runtime_error("Error while loading PLY data from \"" + filename + "\"!"); } ply_close(ply); cout << "done. (V=" << vertexCount; if (load_faces) cout << ", F=" << faceCount; cout << ", took " << timeString(timer.value()) << ")" << endl; }