/* prepares the conversion */ static void setup_callbacks(p_ply iply, p_ply oply) { p_ply_element element = NULL; /* iterate over all elements in input file */ while ((element = ply_get_next_element(iply, element))) { p_ply_property property = NULL; gint32 ninstances = 0; const char *element_name; ply_get_element_info(element, &element_name, &ninstances); /* add this element to output file */ if (!ply_add_element(oply, element_name, ninstances)) error("Unable to add output element '%s'", element_name); /* iterate over all properties of current element */ while ((property = ply_get_next_property(element, property))) { const char *property_name; e_ply_type type, length_type, value_type; ply_get_property_info(property, &property_name, &type, &length_type, &value_type); /* setup input callback for this property */ if (!ply_set_read_cb(iply, element_name, property_name, callback, oply, 0)) error("Unable to setup input callback for property '%s'", property_name); /* add this property to output file */ if (!ply_add_property(oply, property_name, type, length_type, value_type)) error("Unable to add output property '%s'", property_name); } } }
static int setup_callbacks(p_ply iply, p_ply oply) { p_ply_element element = NULL; /* iterate over all elements in input file */ while ((element = ply_get_next_element(iply, element))) { p_ply_property property = NULL; long nelems = 0; const char *element_name; ply_get_element_info(element, &element_name, &nelems); /* add this element to output file */ if (!ply_add_element(oply, element_name, nelems)) return 0; /* iterate over all properties of current element */ while ((property = ply_get_next_property(element, property))) { const char *property_name; e_ply_type type, length_type, value_type; ply_get_property_info(property, &property_name, &type, &length_type, &value_type); /* setup input callback for this property */ if (!ply_set_read_cb(iply, element_name, property_name, callback, oply, 0)) return 0; /* add this property to output file */ if (!ply_add_property(oply, property_name, type, length_type, value_type)) return 0; } } return 1; }
void parse_ply(const std::string& filename, PLYParser* parser) { p_ply ply = ply_open(filename.c_str(), NULL, 0, NULL); assert_success(ply != NULL); assert_success(ply_read_header(ply)); const char* elem_name; const char* prop_name; long num_elements; p_ply_element element = ply_get_next_element(ply, NULL); while (element != NULL) { assert_success(ply_get_element_info(element, &elem_name, &num_elements)); p_ply_property property = ply_get_next_property(element, NULL); while (property != NULL) { assert_success(ply_get_property_info(property, &prop_name, NULL, NULL, NULL)); ply_set_read_cb(ply, elem_name, prop_name, ply_parser_call_back, parser, 0); parser->add_property(elem_name, prop_name, num_elements); property = ply_get_next_property(element, property); } element = ply_get_next_element(ply, element); } assert_success(ply_read(ply)); ply_close(ply); }
void PlyReader::initialize() { p_ply ply = openPly(m_filename); p_ply_element vertex_element = nullptr; bool found_vertex_element = false; const char* element_name; long element_count; while ((vertex_element = ply_get_next_element(ply, vertex_element))) { if (!ply_get_element_info(vertex_element, &element_name, &element_count)) { std::stringstream ss; ss << "Error reading element info in " << m_filename << "."; throw pdal_error(ss.str()); } if (strcmp(element_name, "vertex") == 0) { found_vertex_element = true; break; } } if (!found_vertex_element) { std::stringstream ss; ss << "File " << m_filename << " does not contain a vertex element."; throw pdal_error(ss.str()); } p_ply_property property = nullptr; while ((property = ply_get_next_property(vertex_element, property))) { const char* name; e_ply_type type; e_ply_type length_type; e_ply_type value_type; if (!ply_get_property_info(property, &name, &type, &length_type, &value_type)) { std::stringstream ss; ss << "Error reading property info in " << m_filename << "."; throw pdal_error(ss.str()); } // For now, we'll just use PDAL's built in dimension matching. // We could be smarter about this, e.g. by using the length // and value type attributes. Dimension::Id::Enum dim = Dimension::id(name); if (dim != Dimension::Id::Unknown) { m_vertexDimensions[name] = dim; } } ply_close(ply); }
void check_for_colors(p_ply ply) { p_ply_element element = nil ; bool has_r = false ; bool has_g = false ; bool has_b = false ; bool has_red = false ; bool has_green = false ; bool has_blue = false ; for(;;) { element = ply_get_next_element(ply, element) ; if(element == nil) { break ; } const char* elt_name = nil ; ply_get_element_info(element, &elt_name, nil) ; if(!strcmp(elt_name, "vertex")) { p_ply_property prop = nil ; for(;;) { prop = ply_get_next_property(element, prop) ; if(prop == nil) { break ; } const char* prop_name = nil ; ply_get_property_info(prop, &prop_name, nil, nil, nil) ; has_r = has_r || !strcmp(prop_name, "r") ; has_g = has_g || !strcmp(prop_name, "g") ; has_b = has_b || !strcmp(prop_name, "b") ; has_red = has_red || !strcmp(prop_name, "red") ; has_green = has_green || !strcmp(prop_name, "green") ; has_blue = has_blue || !strcmp(prop_name, "blue") ; } } } if(has_r && has_g && has_b) { has_colors_ = true ; color_mult_ = 1.0 ; ply_set_read_cb(ply, "vertex", "r", PlyMeshLoad::color_cb, this, 0) ; ply_set_read_cb(ply, "vertex", "g", PlyMeshLoad::color_cb, this, 1) ; ply_set_read_cb(ply, "vertex", "b", PlyMeshLoad::color_cb, this, 2) ; } else if(has_red && has_green && has_blue) { has_colors_ = true ; color_mult_ = 1.0 / 255.0 ; ply_set_read_cb(ply, "vertex", "red", PlyMeshLoad::color_cb, this, 0) ; ply_set_read_cb(ply, "vertex", "green", PlyMeshLoad::color_cb, this, 1) ; ply_set_read_cb(ply, "vertex", "blue", PlyMeshLoad::color_cb, this, 2) ; } else { has_colors_ = false ; } }
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; }
/******************************************************************************* * Name: loadPly * Description: Load a ply file into memory. ******************************************************************************/ void loadPly( char * filename, size_t idx ) { printf( "Loading »%s«…\n", filename ); p_ply ply = ply_open( filename, NULL, 0, NULL ); if ( !ply ) { fprintf( stderr, "error: Could not open »%s«.\n", filename ); exit( EXIT_FAILURE ); } if ( !ply_read_header( ply ) ) { fprintf( stderr, "error: Could not read header.\n" ); exit( EXIT_FAILURE ); } /* Check if there are vertices and get the amount of vertices. */ char buf[256] = ""; char elemname[256] = "point"; const char * name = buf; long int nvertices = 0; long int count = 0; p_ply_element elem = NULL; while ( ( elem = ply_get_next_element( ply, elem ) ) ) { ply_get_element_info( elem, &name, &count ); if ( !strcmp( name, "vertex" ) ) { nvertices = count; strcpy( elemname, "vertex" ); p_ply_property prop = NULL; if ( g_clouds[ idx ].colors ) { free( g_clouds[ idx ].colors ); } while ( ( prop = ply_get_next_property( elem, prop ) ) ) { ply_get_property_info( prop, &name, NULL, NULL, NULL ); if ( !strcmp( name, "red" ) ) { /* We have color information */ g_clouds[ idx ].colors = ( uint8_t * ) realloc( g_clouds[ idx ].colors, nvertices * 3 * sizeof(uint8_t) ); } } } else if ( !strcmp( name, "point" ) ) { nvertices = count; strcpy( elemname, "point" ); p_ply_property prop = NULL; if ( g_clouds[ idx ].colors ) { free( g_clouds[ idx ].colors ); } while ( ( prop = ply_get_next_property( elem, prop ) ) ) { ply_get_property_info( prop, &name, NULL, NULL, NULL ); if ( !strcmp( name, "red" ) ) { /* We have color information */ g_clouds[ idx ].colors = ( uint8_t * ) realloc( g_clouds[ idx ].colors, nvertices * 3 * sizeof(uint8_t) ); } } /* Point is more important than vertex. Thus we can stop immediately if * we got this element. */ break; } } if ( !nvertices ) { fprintf( stderr, "warning: No vertices in ply.\n" ); return; } /* Allocate memory. */ g_clouds[ idx ].pointcount = nvertices; nvertices++; g_clouds[ idx ].vertices = (float*) malloc( nvertices * 3 * sizeof(float) ); uint8_t* color = g_clouds[ idx ].colors; g_clouds[ idx ].boundingbox.min.x = DBL_MAX; g_clouds[ idx ].boundingbox.min.y = DBL_MAX; g_clouds[ idx ].boundingbox.min.z = DBL_MAX; g_clouds[ idx ].boundingbox.max.x = DBL_MIN; g_clouds[ idx ].boundingbox.max.y = DBL_MIN; g_clouds[ idx ].boundingbox.max.z = DBL_MIN; struct { float* v; boundingbox_t* b; } d = { g_clouds[ idx ].vertices, &g_clouds[ idx ].boundingbox }; /* Set callbacks. */ nvertices = ply_set_read_cb( ply, elemname, "x", plyVertexCb, &d, 0 ); ply_set_read_cb( ply, elemname, "y", plyVertexCb, &d, 1 ); ply_set_read_cb( ply, elemname, "z", plyVertexCb, &d, 2 ); if ( color ) { ply_set_read_cb( ply, elemname, "red", plyColorCb, &color, 0 ); ply_set_read_cb( ply, elemname, "green", plyColorCb, &color, 1 ); ply_set_read_cb( ply, elemname, "blue", plyColorCb, &color, 2 ); } /* Read ply file. */ if ( !ply_read( ply ) ) { fprintf( stderr, "error: could not read »%s«.\n", filename ); exit( EXIT_FAILURE ); } ply_close( ply ); printf( "%ld values read.\nPoint cloud loaded.", nvertices ); g_maxdim = max( max( max( g_maxdim, d.b->max.x - d.b->min.x ), d.b->max.y - d.b->min.y ), d.b->max.z - d.b->min.z ); g_bb.max.x = max( g_bb.max.x, d.b->max.x ); g_bb.max.y = max( g_bb.max.y, d.b->max.y ); g_bb.max.z = max( g_bb.max.z, d.b->max.z ); g_bb.min.x = min( g_bb.min.x, d.b->min.x ); g_bb.min.y = min( g_bb.min.y, d.b->min.y ); g_bb.min.z = min( g_bb.min.z, d.b->min.z ); }