int face_cb(p_ply_argument argument) { long length, value_index; static int index = 0; static double p[3]; static double t; ply_get_argument_property(argument, NULL, &length, &value_index); switch (value_index) { case 0: case 1: { printf("%g ", ply_get_argument_value(argument)); t = ply_get_argument_value(argument); p[index] = t; index++; } break; case 2: { printf("%g\n", ply_get_argument_value(argument)); t = ply_get_argument_value(argument); p[index] = t; index++; Vec3f * v = new Vec3f(p[0],p[1],p[2]); m_triangles.push_back(v); index = 0; } break; default: break; } return 1; }
static int mash_ply_loader_face_read_cb (p_ply_argument argument) { long prop_num; MashPlyLoaderData *data; gint32 length, index; ply_get_argument_user_data (argument, (void **) &data, &prop_num); ply_get_argument_property (argument, NULL, &length, &index); if (index == 0) data->first_vertex = ply_get_argument_value (argument); else if (index == 1) data->last_vertex = ply_get_argument_value (argument); else if (index != -1) { guint new_vertex = ply_get_argument_value (argument); /* Add a triangle with the first vertex, the last vertex and this new vertex */ mash_ply_loader_add_face_index (data, data->first_vertex); mash_ply_loader_add_face_index (data, data->last_vertex); mash_ply_loader_add_face_index (data, new_vertex); /* Use the new vertex as one of the vertices next time around */ data->last_vertex = new_vertex; } return 1; }
static int edge_cb(p_ply_argument argument) { long length; long index; ply_get_argument_property(argument, NULL, &length, &index); if (index < 0) // ignore length argument return 1; void* pinfo = 0; long isEdgeLoop = 0; ply_get_argument_user_data(argument, &pinfo, &isEdgeLoop); PlyLoadInfo& info = *((PlyLoadInfo*)pinfo); // Duplicate indices within a single edge chain so that we can pass them to // OpenGL as GL_LINES (or could use GL_LINE_STRIP?) if (index > 1) info.edges.push_back(info.edges.back()); info.edges.push_back( (unsigned int)ply_get_argument_value(argument)); if (isEdgeLoop && index == length-1) { // Add extra edge to close the loop int firstIdx = info.edges.end()[-2*(length-1)]; info.edges.push_back(info.edges.back()); info.edges.push_back(firstIdx); } return 1; }
static int edge_cb(p_ply_argument argument) { long length; long index; ply_get_argument_property(argument, NULL, &length, &index); if (index < 0) // ignore length argument return 1; void* pinfo = 0; ply_get_argument_user_data(argument, &pinfo, NULL); PlyLoadInfo& info = *((PlyLoadInfo*)pinfo); long vertexIndex = ply_get_argument_value(argument); if (vertexIndex < 0 || vertexIndex >= info.nvertices) { g_logger.warning("Vertex index %d outside of valid range [0,%d] - ignoring edge", vertexIndex, info.nvertices-1); info.prevEdgeIndex = -1; return 1; } // Duplicate indices within a single edge chain so that we can pass them to // OpenGL as GL_LINES (or could use GL_LINE_STRIP?) if (info.prevEdgeIndex != -1) { info.edges.push_back((GLuint)info.prevEdgeIndex); info.edges.push_back((GLuint)vertexIndex); } info.prevEdgeIndex = (index < length-1) ? vertexIndex : -1; return 1; }
static int face_cb(p_ply_argument argument) { long length, value_index; ply_get_argument_property(argument, NULL, &length, &value_index); if(value_index >= 0 && value_index <= 2) { WORD value = static_cast<WORD>(ply_get_argument_value(argument)); buffer.indices.push_back(value); } 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; }
static int list_cb(p_ply_argument argument) { long length; long index; ply_get_argument_property(argument, NULL, &length, &index); if (index < 0) // ignore length argument return 1; void* plist = 0; ply_get_argument_user_data(argument, &plist, NULL); std::vector<unsigned int>& list = *((std::vector<unsigned int>*)plist); list.push_back((unsigned int)ply_get_argument_value(argument)); return 1; }
int add_tristrip_data(p_ply_argument argument) { long length, value_index; ply_get_argument_property(argument, nil, &length, &value_index); if(value_index < 0) { return 1; } int vertex_index = int(ply_get_argument_value(argument)) ; if(value_index == 0) { begin_tristrip() ; } if(vertex_index >= 0) { add_to_tristrip(vertex_index) ; } else { end_tristrip() ; begin_tristrip() ; } if(value_index == length-1) { end_tristrip() ; } return 1; }
int add_face_data(p_ply_argument argument) { long length, value_index; ply_get_argument_property(argument, nil, &length, &value_index); if(value_index < 0) return 1; int vertex_index = int(ply_get_argument_value(argument)) ; if(value_index == 0) { builder_.begin_facet() ; } builder_.add_vertex_to_facet(vertex_index) ; if(value_index == length-1) { builder_.end_facet() ; } return 1; }
static int face_cb(p_ply_argument argument) { long length, value_index; ply_get_argument_property(argument, NULL, &length, &value_index); switch (value_index) { case 0: case 1: printf("%g ", ply_get_argument_value(argument)); break; case 2: printf("%g\n", ply_get_argument_value(argument)); break; default: break; } 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; }
static int face_cb(p_ply_argument argument) { long length, value_index; int position = (int) ply_get_argument_value(argument); ply_get_argument_property(argument, NULL, &length, &value_index); if (value_index < 0) { f++; faces[f] = (int *)malloc(position * sizeof(int)); faces[f][0] = position; return 1; } faces[f][value_index+1] = position; return 1; }
/* Callback to handle face data from RPly */ int rply_face_callback(p_ply_argument argument) { long length, value_index; ply_get_argument_property(argument, nullptr, &length, &value_index); if (length != 3 && length != 4) { Warning( "plymesh: Ignoring face with %i vertices (only triangles and quads " "are supported!)", (int)length); return 1; } else if (value_index < 0) { return 1; } CallbackContext *context; ply_get_argument_user_data(argument, (void **)&context, nullptr); if (value_index >= 0) { int value = (int)ply_get_argument_value(argument); if (value < 0 || value >= context->vertexCount) { Error( "plymesh: Vertex reference %i is out of bounds! " "Valid range is [0..%i)", value, context->vertexCount); context->error = true; } context->face[value_index] = value; } if (value_index == length - 1) { for (int i = 0; i < 3; ++i) context->indices[context->indexCtr++] = context->face[i]; if (length == 4) { /* This was a quad */ context->indices[context->indexCtr++] = context->face[3]; context->indices[context->indexCtr++] = context->face[0]; context->indices[context->indexCtr++] = context->face[2]; } } return 1; }
static int face_cb(p_ply_argument argument) { long length; long index; ply_get_argument_property(argument, NULL, &length, &index); if (index < 0) // ignore length argument return 1; void* pinfo = 0; long isList = 0; ply_get_argument_user_data(argument, &pinfo, &isList); if (isList && length != 3) { // Not a triangle - ignore for now! g_logger.warning("Ignoring non-triangular face with %d vertices\n", length); return 1; } ((PlyLoadInfo*)pinfo)->faces.push_back( (unsigned int)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; }
int Model::face_cb(p_ply_argument argument) { long length, value_index; int x,y,z; ply_get_argument_property(argument, NULL, &length, &value_index); switch (value_index) { case 0: triangles[count_t].x = (int)ply_get_argument_value(argument); break; case 1: triangles[count_t].y = (int)ply_get_argument_value(argument); break; case 2: triangles[count_t].z = (int)ply_get_argument_value(argument); compute_normal(count_t); // Compute normal after all vertices of traingle are known count_t++; break; default: break; } return 1; }
static int face_cb(p_ply_argument argument) { long length; long index; ply_get_argument_property(argument, NULL, &length, &index); void* pinfo = 0; long indexType = 0; ply_get_argument_user_data(argument, &pinfo, &indexType); PlyLoadInfo& info = *(PlyLoadInfo*)pinfo; long vertexIndex = ply_get_argument_value(argument); if (info.currPoly.addIndex(indexType, length, index, vertexIndex)) { // If the vertex array has been read, we can immediately triangulate. // If not, need to defer until later. if (info.verts.empty()) info.deferredPolys.push_back(info.currPoly); else info.currPoly.triangulate(info.verts, info.triangles); info.currPoly.reset(); } 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; }
static int mash_ply_loader_vertex_read_cb (p_ply_argument argument) { long prop_num; MashPlyLoaderData *data; gint32 length, index; double value; ply_get_argument_user_data (argument, (void **) &data, &prop_num); ply_get_argument_property (argument, NULL, &length, &index); if (length != 1 || index != 0) { g_set_error (&data->error, MASH_DATA_ERROR, MASH_DATA_ERROR_INVALID, "List type property not supported for vertex element '%s'", mash_ply_loader_properties[prop_num].name); return 0; } value = ply_get_argument_value (argument); /* Colors are specified as a byte so we need to treat them specially */ if (((1 << prop_num) & MASH_PLY_LOADER_COLOR_PROPS)) data->current_vertex[data->prop_map[prop_num]] = value; else *(gfloat *) (data->current_vertex + data->prop_map[prop_num]) = value; data->got_props |= 1 << prop_num; /* If we've got enough properties for a complete vertex then add it to the array */ if (data->got_props == data->available_props) { int i; /* Flip any axes that have been specified in the MashPlyLoaderFlags */ if ((data->available_props & MASH_PLY_LOADER_VERTEX_PROPS) == MASH_PLY_LOADER_VERTEX_PROPS) for (i = 0; i < 3; i++) if ((data->flags & (MASH_DATA_NEGATE_X << i))) { gfloat *pos = (gfloat *) (data->current_vertex + data->prop_map[i]); *pos = -*pos; } if ((data->available_props & MASH_PLY_LOADER_NORMAL_PROPS) == MASH_PLY_LOADER_NORMAL_PROPS) for (i = 0; i < 3; i++) if ((data->flags & (MASH_DATA_NEGATE_X << i))) { gfloat *pos = (gfloat *) (data->current_vertex + data->prop_map[i + 3]); *pos = -*pos; } g_byte_array_append (data->vertices, data->current_vertex, data->n_vertex_bytes); data->got_props = 0; /* Update the bounding box for the data */ for (i = 0; i < 3; i++) { gfloat *min = &data->min_vertex.x + i; gfloat *max = &data->max_vertex.x + i; gfloat value = *(gfloat *) (data->current_vertex + data->prop_map[i]); if (value < *min) *min = value; if (value > *max) *max = value; } } return 1; }