Пример #1
0
/* 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);
        }
    }
}
int MapSerializer_ply::num_facet(const std::string& file_name) {
	p_ply ply = ply_open(file_name.c_str(), nil, 0, nil) ;

	if(ply == nil) {
		Logger::err("MapSerializer_ply") << file_name << ": could not open" << std::endl ;
		return false ;
	}

	if(!ply_read_header(ply)) {
		Logger::err("MapSerializer_ply") << file_name << ": invalid PLY file" << std::endl ;
		ply_close(ply) ;
		return false ;
	}

	p_ply_element element = nil ;
	for(;;) {
		element = ply_get_next_element(ply, element) ;
		if(element == nil)
			break ;
		const char* elt_name = nil ;
		long num;
		ply_get_element_info(element, &elt_name, &num) ;

		if(!strcmp(elt_name, "face")) {
			if (num > 0) {
				ply_close(ply) ;
				return num;
			}
		} 
	}
	ply_close(ply) ;
	return 0;
}
Пример #3
0
    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);
    }
Пример #4
0
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;
}
Пример #5
0
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 ;
		}
	}
Пример #7
0
    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;
    }
Пример #8
0
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;
}
Пример #9
0
std::vector<std::shared_ptr<Shape>> CreatePLYMesh(
    const Transform *o2w, const Transform *w2o, bool reverseOrientation,
    const ParamSet &params,
    std::map<std::string, std::shared_ptr<Texture<Float>>> *floatTextures) {
    const std::string filename = params.FindOneFilename("filename", "");
    p_ply ply = ply_open(filename.c_str(), rply_message_callback, 0, nullptr);
    if (!ply) {
        Error("Couldn't open PLY file \"%s\"", filename.c_str());
        return std::vector<std::shared_ptr<Shape>>();
    }

    if (!ply_read_header(ply)) {
        Error("Unable to read the header of PLY file \"%s\"", filename.c_str());
        return std::vector<std::shared_ptr<Shape>>();
    }

    p_ply_element element = nullptr;
    long 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 = nInstances;
        else if (!strcmp(name, "face"))
            faceCount = nInstances;
    }

    if (vertexCount == 0 || faceCount == 0) {
        Error("PLY file \"%s\" is invalid! No face/vertex elements found!",
              filename.c_str());
        return std::vector<std::shared_ptr<Shape>>();
    }

    CallbackContext context;

    if (ply_set_read_cb(ply, "vertex", "x", rply_vertex_callback, &context,
                        0x030) &&
        ply_set_read_cb(ply, "vertex", "y", rply_vertex_callback, &context,
                        0x031) &&
        ply_set_read_cb(ply, "vertex", "z", rply_vertex_callback, &context,
                        0x032)) {
        context.p = new Point3f[vertexCount];
    } else {
        Error("PLY file \"%s\": Vertex coordinate property not found!",
              filename.c_str());
        return std::vector<std::shared_ptr<Shape>>();
    }

    if (ply_set_read_cb(ply, "vertex", "nx", rply_vertex_callback, &context,
                        0x130) &&
        ply_set_read_cb(ply, "vertex", "ny", rply_vertex_callback, &context,
                        0x131) &&
        ply_set_read_cb(ply, "vertex", "nz", rply_vertex_callback, &context,
                        0x132))
        context.n = new Normal3f[vertexCount];

    /* There seem to be lots of different conventions regarding UV coordinate
     * names */
    if ((ply_set_read_cb(ply, "vertex", "u", rply_vertex_callback, &context,
                         0x220) &&
         ply_set_read_cb(ply, "vertex", "v", rply_vertex_callback, &context,
                         0x221)) ||
        (ply_set_read_cb(ply, "vertex", "s", rply_vertex_callback, &context,
                         0x220) &&
         ply_set_read_cb(ply, "vertex", "t", rply_vertex_callback, &context,
                         0x221)) ||
        (ply_set_read_cb(ply, "vertex", "texture_u", rply_vertex_callback,
                         &context, 0x220) &&
         ply_set_read_cb(ply, "vertex", "texture_v", rply_vertex_callback,
                         &context, 0x221)) ||
        (ply_set_read_cb(ply, "vertex", "texture_s", rply_vertex_callback,
                         &context, 0x220) &&
         ply_set_read_cb(ply, "vertex", "texture_t", rply_vertex_callback,
                         &context, 0x221)))
        context.uv = new Point2f[vertexCount];

    /* Allocate enough space in case all faces are quads */
    context.indices = new int[faceCount * 6];
    context.vertexCount = vertexCount;

    ply_set_read_cb(ply, "face", "vertex_indices", rply_face_callback, &context,
                    0);

    if (!ply_read(ply)) {
        Error("Unable to read the contents of PLY file \"%s\"",
              filename.c_str());
        ply_close(ply);
        return std::vector<std::shared_ptr<Shape>>();
    }

    ply_close(ply);

    if (context.error) return std::vector<std::shared_ptr<Shape>>();

    // Look up an alpha texture, if applicable
    std::shared_ptr<Texture<Float>> alphaTex;
    std::string alphaTexName = params.FindTexture("alpha");
    if (alphaTexName != "") {
        if (floatTextures->find(alphaTexName) != floatTextures->end())
            alphaTex = (*floatTextures)[alphaTexName];
        else
            Error("Couldn't find float texture \"%s\" for \"alpha\" parameter",
                  alphaTexName.c_str());
    } else if (params.FindOneFloat("alpha", 1.f) == 0.f) {
        alphaTex.reset(new ConstantTexture<Float>(0.f));
    }

    std::shared_ptr<Texture<Float>> shadowAlphaTex;
    std::string shadowAlphaTexName = params.FindTexture("shadowalpha");
    if (shadowAlphaTexName != "") {
        if (floatTextures->find(shadowAlphaTexName) != floatTextures->end())
            shadowAlphaTex = (*floatTextures)[shadowAlphaTexName];
        else
            Error(
                "Couldn't find float texture \"%s\" for \"shadowalpha\" "
                "parameter",
                shadowAlphaTexName.c_str());
    } else if (params.FindOneFloat("shadowalpha", 1.f) == 0.f)
        shadowAlphaTex.reset(new ConstantTexture<Float>(0.f));

    return CreateTriangleMesh(o2w, w2o, reverseOrientation,
                              context.indexCtr / 3, context.indices,
                              vertexCount, context.p, nullptr, context.n,
                              context.uv, alphaTex, shadowAlphaTex);
}
Пример #10
0
/*******************************************************************************
 *         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 );

}
Пример #11
0
static gboolean
mash_ply_loader_get_indices_type (MashPlyLoaderData *data,
                                  GError **error)
{
  CoglContext *context;
  p_ply_element elem = NULL;

  context = es_get_cogl_context ();

  /* Look for the 'vertices' element */
  while ((elem = ply_get_next_element (data->ply, elem)))
    {
      const char *name;
      gint32 n_instances;

      if (ply_get_element_info (elem, &name, &n_instances))
        {
          if (!strcmp (name, "vertex"))
            {
              if (n_instances <= 0x100)
                {
                  data->indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE;
                  data->faces = g_array_new (FALSE, FALSE, sizeof (guint8));
                }
              else if (n_instances <= 0x10000)
                {
                  data->indices_type = COGL_INDICES_TYPE_UNSIGNED_SHORT;
                  data->faces = g_array_new (FALSE, FALSE, sizeof (guint16));
                }
              else if (cogl_has_feature (context,
                                         COGL_FEATURE_ID_UNSIGNED_INT_INDICES))
                {
                  data->indices_type = COGL_INDICES_TYPE_UNSIGNED_INT;
                  data->faces = g_array_new (FALSE, FALSE, sizeof (guint32));
                }
              else
                {
                  g_set_error (error, MASH_DATA_ERROR,
                               MASH_DATA_ERROR_UNSUPPORTED,
                               "The PLY file requires unsigned int indices "
                               "but this is not supported by your GL driver");
                  return FALSE;
                }

              return TRUE;
            }
        }
      else
        {
          g_set_error (error, MASH_DATA_ERROR,
                       MASH_DATA_ERROR_UNKNOWN,
                       "Error getting element info");
          return FALSE;
        }
    }

  g_set_error (error, MASH_DATA_ERROR,
               MASH_DATA_ERROR_MISSING_PROPERTY,
               "PLY file is missing the vertex element");

  return FALSE;
}