Example #1
0
int main(int argc, char **argv)
{
    const char *value;
    p_ply iply, oply;
    iply = ply_open("input.ply", NULL);
    if (!iply) return 1;
    if (!ply_read_header(iply)) return 1;
    oply = ply_create("output.ply", PLY_LITTLE_ENDIAN, NULL);
    if (!oply) return 1;
    if (!setup_callbacks(iply, oply)) return 1;
    /* pass comments and obj_infos from input to output */
    value = NULL;
    while ((value = ply_get_next_comment(iply, value)))
        if (!ply_add_comment(oply, value)) return 1;
    value = NULL;
    while ((value = ply_get_next_obj_info(iply, value)))
        if (!ply_add_obj_info(oply, value)) return 1;;
    /* write output header */
    if (!ply_write_header(oply)) return 1;
    /* read input file generating callbacks that pass data to output file */
    if (!ply_read(iply)) return 1;
    /* close up, we are done */
    if (!ply_close(iply)) return 1;
    if (!ply_close(oply)) return 1;
    return 0;
}
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;
}
Example #3
0
/* given a format mode, an input file name and an output file name,
 * convert input file to output in given format mode */
int main(int argc, char **argv) {
    const char *value = NULL;
    e_ply_storage_mode storage_mode = PLY_LITTLE_ENDIAN;
    const char *iname = NULL, *oname = NULL;
    p_ply iply = NULL, oply = NULL;
    /* parse command line arguments */
    parse_arguments(argc, argv, &storage_mode, &iname, &oname);
    /* open input file and make sure we parsed its header */
    iply = ply_open(iname, NULL, 0, NULL);
    if (!iply) error("Unable to open file '%s'", iname);
    if (!ply_read_header(iply)) error("Failed reading '%s' header", iname);
    /* create output file */
    oply = ply_create(oname, storage_mode, NULL, 0, NULL);
    if (!oply) error("Unable to create file '%s'", oname);
    /* create elements and properties in output file and 
     * setup callbacks for them in input file */
    setup_callbacks(iply, oply); 
    /* pass comments and obj_infos from input to output */
    value = NULL;
    while ((value = ply_get_next_comment(iply, value)))
        if (!ply_add_comment(oply, value))
            error("Failed adding comments");
    value = NULL;
    while ((value = ply_get_next_obj_info(iply, value)))
        if (!ply_add_obj_info(oply, value))
            error("Failed adding comments");
    /* write output header */
    if (!ply_write_header(oply)) error("Failed writing '%s' header", oname);
    /* read input file generating callbacks that pass data to output file */
    if (!ply_read(iply)) error("Conversion failed");
    /* close up, we are done */
    if (!ply_close(iply)) error("Error closing file '%s'", iname);
    if (!ply_close(oply)) error("Error closing file '%s'", oname);
    return 0;
}
	bool load(const std::string& filename) {
		p_ply ply = ply_open(filename.c_str(), nil, 0, nil) ;

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

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

		current_vertex_ = 0 ;
		current_color_  = 0 ;
		check_for_colors(ply) ;

		long nvertices = ply_set_read_cb(ply, "vertex", "x", PlyMeshLoad::vertex_cb, this, 0) ;
		ply_set_read_cb(ply, "vertex", "y", PlyMeshLoad::vertex_cb, this, 1) ;
		ply_set_read_cb(ply, "vertex", "z", PlyMeshLoad::vertex_cb, this, 2) ;

		long nfaces = ply_set_read_cb(ply, "face", "vertex_indices", PlyMeshLoad::face_cb, this, 0);
		if (nfaces == 0) {
			Logger::err("PlyMeshLoad") 
				<< "0 facet, maybe a point cloud file" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		ply_set_read_cb(ply, "tristrips", "vertex_indices", PlyMeshLoad::tristrip_cb, this, 0);

		builder_.begin_surface() ;
		builder_.create_vertices(nvertices, has_colors_) ;

		if(!ply_read(ply)) {
			Logger::err("PlyMeshLoad") 
				<< filename << ": problem occurred while parsing PLY file" << std::endl ;
			ply_close(ply) ;
			builder_.end_surface() ;
			return false ;
		}

		ply_close(ply) ;
		builder_.end_surface() ;

		if (nfaces == 0)
			return false;
		else
			return true ;
	}
Example #5
0
int loadPlyFile() {
	p_ply ply = ply_open(filename, NULL, 0, NULL);

	if (!ply) return -1;
	if (!ply_read_header(ply)) return -1;

	vertex_count = ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
	ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 1);
	ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 2);

	ply_set_read_cb(ply, "vertex", "nx", NULL, NULL, 0);
	ply_set_read_cb(ply, "vertex", "ny", NULL, NULL, 0);
	ply_set_read_cb(ply, "vertex", "nz", NULL, NULL, 0);

	face_count = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);

	vertices = (double **) malloc(vertex_count * sizeof(double *));
	faces    = (int **) malloc(face_count * sizeof(int *));

	if (!ply_read(ply)) return -1;

	ply_close(ply);

	return 1;
}
Example #6
0
int Model::init(char filename[]){
    p_ply ply = ply_open(filename, NULL, 0, NULL);
    if (!ply) return 1;
    if (!ply_read_header(ply)) return 1;
    nvertices = ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 1);
    ntriangles = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);
    count_t = 0;
    count_v = 0;
    if(vertices != NULL){
		delete [] vertices;
		}
    if(triangles != NULL){
		delete [] triangles;
		}
	if(nml != NULL){
		delete [] nml;
		}
	vertices = new vertex[nvertices];
	triangles = new triangle[ntriangles];
	nml = new normal[ntriangles];
    if (!ply_read(ply)) return 1;
    ply_close(ply);
    return 0;
	}
Example #7
0
void MeshBase::loadDataFromPly( const std::string& filename )
{
  p_ply ply = ply_open( filename.c_str(), 0);
  if( !ply ) {
    throw MeshException( "Error opening ply file during second pass (" + filename + ")" );
  }

  if( !ply_read_header( ply ) ) {
    throw MeshException( "Error parsing ply header during second pass ("
                         + filename + ")" );
  }

  MeshGroup& group = getFirstGroup();

  PlyData data( m_vertex_data, m_normal_data, group.vertex_indices, group.normal_indices );

  ply_set_read_cb( ply, "vertex", "x", plyVertexLoadDataCB, &data, 0);
  ply_set_read_cb( ply, "vertex", "y", plyVertexLoadDataCB, &data, 1);
  ply_set_read_cb( ply, "vertex", "z", plyVertexLoadDataCB, &data, 2);

  ply_set_read_cb( ply, "vertex", "nx", plyVertexLoadDataCB, &data, 3);
  ply_set_read_cb( ply, "vertex", "ny", plyVertexLoadDataCB, &data, 4);
  ply_set_read_cb( ply, "vertex", "nz", plyVertexLoadDataCB, &data, 5);

  ply_set_read_cb( ply, "face", "vertex_indices", plyFaceLoadDataCB, &data, 0);

  if( !ply_read( ply ) ) {
    throw MeshException( "Error parsing ply file (" + filename + ")" );
  }
  ply_close(ply);
}
Example #8
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);
    }
write_test()
{
  int i,j;
  PlyFile *ply;
  int nelems;
  char **elist;
  int file_type;
  float version;
  int nverts = sizeof (verts) / sizeof (Vertex);
  int nfaces = sizeof (faces) / sizeof (Face);

  /* create the vertex index lists for the faces */
  for (i = 0; i < nfaces; i++)
    faces[i].verts = vert_ptrs[i];

  /* open either a binary or ascii PLY file for writing */
  /* (the file will be called "test.ply" because the routines */
  /*  enforce the .ply filename extension) */

#if 1
  ply = ply_open_for_writing("test", 2, elem_names, PLY_ASCII, &version);
#else
  ply = ply_open_for_writing("test", 2, elem_names, PLY_BINARY_BE, &version);
#endif

  /* describe what properties go into the vertex and face elements */

  ply_element_count (ply, "vertex", nverts);
  ply_describe_property (ply, "vertex", &vert_props[0]);
  ply_describe_property (ply, "vertex", &vert_props[1]);
  ply_describe_property (ply, "vertex", &vert_props[2]);

  ply_element_count (ply, "face", nfaces);
  ply_describe_property (ply, "face", &face_props[0]);
  ply_describe_property (ply, "face", &face_props[1]);

  /* write a comment and an object information field */
  ply_put_comment (ply, "author: Greg Turk");
  ply_put_obj_info (ply, "random information");

  /* we have described exactly what we will put in the file, so */
  /* we are now done with the header info */
  ply_header_complete (ply);

  /* set up and write the vertex elements */
  ply_put_element_setup (ply, "vertex");
  for (i = 0; i < nverts; i++)
    ply_put_element (ply, (void *) &verts[i]);

  /* set up and write the face elements */
  ply_put_element_setup (ply, "face");
  for (i = 0; i < nfaces; i++)
    ply_put_element (ply, (void *) &faces[i]);

  /* close the PLY file */
  ply_close (ply);
}
Example #10
0
void PlyReader::done(PointTableRef table)
{
    if (!ply_close(m_ply))
    {
        std::stringstream ss;
        ss << "Error closing " << m_filename << ".";
        throw pdal_error(ss.str());
    }
}
Example #11
0
void
write_file()
{
  int i,j,k;
  PlyFile *ply;
  int num_elems;
  char *elem_name;

  /*** Write out the final PLY object ***/


  ply = ply_write (stdout, nelems, elist, file_type);


  /* describe what properties go into the vertex and face elements */

  ply_element_count (ply, "vertex", nverts);
  ply_describe_property (ply, "vertex", &vert_props[0]);
  ply_describe_property (ply, "vertex", &vert_props[1]);
  ply_describe_property (ply, "vertex", &vert_props[2]);
  ply_describe_property (ply, "vertex", &vert_props[3]);
  ply_describe_property (ply, "vertex", &vert_props[4]);
  ply_describe_property (ply, "vertex", &vert_props[5]);
  ply_describe_other_properties (ply, vert_other, offsetof(Vertex,other_props));

  ply_element_count (ply, "face", nfaces);
  ply_describe_property (ply, "face", &face_props[0]);
  ply_describe_other_properties (ply, face_other, offsetof(Face,other_props));

  ply_describe_other_elements (ply, other_elements);

  for (i = 0; i < num_comments; i++)
    ply_put_comment (ply, comments[i]);

  for (i = 0; i < num_obj_info; i++)
    ply_put_obj_info (ply, obj_info[i]);

  ply_header_complete (ply);

  /* set up and write the vertex elements */
  ply_put_element_setup (ply, "vertex");
  for (i = 0; i < nverts; i++)
    ply_put_element (ply, (void *) vlist[i]);

  /* set up and write the face elements */
  ply_put_element_setup (ply, "face");
  for (i = 0; i < nfaces; i++)
    ply_put_element (ply, (void *) flist[i]);

  ply_put_other_elements (ply);

  /* close the PLY file */
  ply_close (ply);
}
Example #12
0
bool WritePlyFile(const std::string &filename, int nTriangles,
                  const int *vertexIndices, int nVertices, const Point3f *P,
                  const Vector3f *S, const Normal3f *N, const Point2f *UV) {
    p_ply plyFile =
        ply_create(filename.c_str(), PLY_DEFAULT, PlyErrorCallback, 0, nullptr);
    if (plyFile != nullptr) {
        ply_add_element(plyFile, "vertex", nVertices);
        ply_add_scalar_property(plyFile, "x", PLY_FLOAT);
        ply_add_scalar_property(plyFile, "y", PLY_FLOAT);
        ply_add_scalar_property(plyFile, "z", PLY_FLOAT);
        if (N != nullptr) {
            ply_add_scalar_property(plyFile, "nx", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "ny", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "nz", PLY_FLOAT);
        }
        if (UV != nullptr) {
            ply_add_scalar_property(plyFile, "u", PLY_FLOAT);
            ply_add_scalar_property(plyFile, "v", PLY_FLOAT);
        }
        if (S != nullptr)
            Warning("PLY mesh in \"%s\" will be missing tangent vectors \"S\".",
                    filename.c_str());

        ply_add_element(plyFile, "face", nTriangles);
        ply_add_list_property(plyFile, "vertex_indices", PLY_UINT8, PLY_INT);
        ply_write_header(plyFile);

        for (int i = 0; i < nVertices; ++i) {
            ply_write(plyFile, P[i].x);
            ply_write(plyFile, P[i].y);
            ply_write(plyFile, P[i].z);
            if (N) {
                ply_write(plyFile, N[i].x);
                ply_write(plyFile, N[i].y);
                ply_write(plyFile, N[i].z);
            }
            if (UV) {
                ply_write(plyFile, UV[i].x);
                ply_write(plyFile, UV[i].y);
            }
        }

        for (int i = 0; i < nTriangles; ++i) {
            ply_write(plyFile, 3);
            ply_write(plyFile, vertexIndices[3 * i]);
            ply_write(plyFile, vertexIndices[3 * i + 1]);
            ply_write(plyFile, vertexIndices[3 * i + 2]);
        }
        ply_close(plyFile);
        return true;
    }
    return false;
}
Example #13
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);
}
Example #14
0
void PlyWriter::done(PointTableRef table)
{
    if (!ply_add_element(m_ply, "vertex", m_pointCollector->size()))
    {
        std::stringstream ss;
        ss << "Could not add vertex element";
        throw pdal_error(ss.str());
    }
    auto dimensions = table.layout()->dims();
    for (auto dim : dimensions) {
        std::string name = Dimension::name(dim);
        e_ply_type plyType = getPlyType(Dimension::defaultType(dim));
        if (!ply_add_scalar_property(m_ply, name.c_str(), plyType))
        {
            std::stringstream ss;
            ss << "Could not add scalar property '" << name << "'";
            throw pdal_error(ss.str());
        }
    }
    if (!ply_add_comment(m_ply, "Generated by PDAL"))
    {
        std::stringstream ss;
        ss << "Could not add comment";
        throw pdal_error(ss.str());
    }
    if (!ply_write_header(m_ply))
    {
        std::stringstream ss;
        ss << "Could not write ply header";
        throw pdal_error(ss.str());
    }

    for (PointId index = 0; index < m_pointCollector->size(); ++index)
    {
        for (auto dim : dimensions)
        {
            double value = m_pointCollector->getFieldAs<double>(dim, index);
            if (!ply_write(m_ply, value))
            {
                std::stringstream ss;
                ss << "Error writing dimension '" << Dimension::name(dim) <<
                    "' of point number " << index;
                throw pdal_error(ss.str());
            }
        }
    }

    if (!ply_close(m_ply))
    {
        throw pdal_error("Error closing ply file");
    }
}
Example #15
0
PlyReader::~PlyReader()
{
	if (isValid())
	{
		for (int i=0; i < m_data->elementCount; ++i)
		{
			free(m_data->elementNames[i]);
		}
		free(m_data->elementNames);

		ply_close(m_data->plyFile);
		m_data->plyFile = nullptr;
	}
}
Example #16
0
int main(void) {
    long nvertices, ntriangles;
    p_ply ply = ply_open("input.ply", NULL);
    if (!ply) return 1;
    if (!ply_read_header(ply)) return 1;
    nvertices = ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 1);
    ntriangles = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);
    printf("%ld\n%ld\n", nvertices, ntriangles);
    if (!ply_read(ply)) return 1;
    ply_close(ply);
    return 0;
}
Example #17
0
void PLYDataWriter::write ( const char * filename )
{
    assert ( mesh != NULL );
    p_ply oply;
    oply = ply_create( filename, PLY_ASCII, NULL, 0, NULL );

    if ( oply == NULL )
    {
        throw std::runtime_error( "Access to output file was impossible." );
    }
    write_header ( oply );
    write_vertices ( oply );
    write_faces ( oply );
    ply_close ( oply );
}
Example #18
0
bool PlyBuffer::LoadFromPlyFile(std::wstring fileName, PlyBuffer& vbOut, std::wstring error)
{
	long nvertices, ntriangles;
	// Open the file
	p_ply ply = ply_open(Helper::WStringtoString(fileName).c_str(), NULL, 0, NULL);

	// Check that file is okay
    if (!ply) 
	{
		error = L"Failed at loading file " + fileName;
		return false;
	}
    if (!ply_read_header(ply)) 
		return false;

	// Load info
    nvertices = ply_set_read_cb(ply, "vertex", "x", vertexX, NULL, 0);
    ply_set_read_cb(ply, "vertex", "y", vertexY, NULL, 0);
    ply_set_read_cb(ply, "vertex", "z", vertexZ, NULL, 0);
	ply_set_read_cb(ply, "vertex", "nx", vertexNX, NULL, 0);
	ply_set_read_cb(ply, "vertex", "ny", vertexNY, NULL, 0);
	ply_set_read_cb(ply, "vertex", "nz", vertexNZ, NULL, 0);
	ply_set_read_cb(ply, "vertex", "u", vertexU, NULL, 0);
	ply_set_read_cb(ply, "vertex", "v", vertexV, NULL, 1);

    ntriangles = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);

	// Set space for vertices and indices for speed
	buffer.vertices.reserve(nvertices);
	buffer.indices.reserve(ntriangles);

	// Read file
    if (!ply_read(ply))
		return false;

	// Close file
    ply_close(ply);

	//Copy it to the output
	vbOut = buffer;
	
	// Empty the vertex so that don't take up space
	buffer.vertices = std::vector<PlyBuffer::Vertex>();
	buffer.indices = std::vector<WORD>();

	return true;
}
Example #19
0
int MyGlWindow::loadply()
{

    p_ply ply = ply_open("roof.ply", NULL, 0, NULL);
    if (!ply) return 1;
    if (!ply_read_header(ply)) return 1;

    int nvertices = ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 0);
    ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 1);
    int ntriangles = ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);
    printf("%ld\n%ld\n", nvertices, ntriangles);
    if (!ply_read(ply)) return 1;
    ply_close(ply);

    std::cout << m_points.size() << std::endl;
}
void PlyLoader::load( const optix::Matrix4x4& transform )
{
  p_ply ply = ply_open( _filename.c_str(), 0);
  if( !ply ) {
    throw optix::Exception( "Error opening ply file (" + _filename + ")" );
  }

  if( !ply_read_header( ply ) ) {
    throw optix::Exception( "Error parsing ply header (" + _filename + ")" );
  }

  ModelData data;
  int nverts = ply_set_read_cb( ply, "vertex", "x", vertexCB, &data, 0);
  ply_set_read_cb( ply, "vertex", "y", vertexCB, &data, 1);
  ply_set_read_cb( ply, "vertex", "z", vertexCB, &data, 2);

  int ntris = ply_set_read_cb(ply, "face", "vertex_indices", faceCB, &data, 0);

  data.verts = new optix::float3[ nverts ];
  data.tris  = new optix::int3[ ntris ];

  if( !ply_read( ply ) ) {
    throw optix::Exception( "Error parsing ply file (" + _filename + ")" );
  }
  ply_close(ply);

  _aabb = data.aabb;

  /*
  std::cerr << " done.  got " << nverts << " verts and " << ntris << " tris." << std::endl;

  for( int i = 0; i < 10; ++i ) {
    std::cerr << " v: " << data.verts[i] << std::endl;
  }

  for( int i = 0; i < 10; ++i ) {
    std::cerr << " f: " << data.tris[i] << std::endl;
  }
  */

  createGeometryInstance( data.nverts, data.verts, data.ntris, data.tris );
}
Example #21
0
	MEM_SmartPtr<BSP_TMesh>
BSP_PlyLoader::
NewMeshFromFile(
	char * file_name,
	MT_Vector3 &min,
	MT_Vector3 &max

) {

	min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY);
	max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY);
	
	PlyProperty vert_props[] = { /* list of property information for a vertex */
	  {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0},
	  {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0},
	  {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0},
	};

	PlyProperty face_props[] = { /* list of property information for a vertex */
	  {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts),
	   1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)},
	};

	MEM_SmartPtr<BSP_TMesh> mesh = new BSP_TMesh;

	if (mesh == NULL) return NULL;

	int i,j;
	PlyFile *ply;
	int nelems;
	char **elist;
	int file_type;
	float version;
	int nprops;
	int num_elems;
	PlyProperty **plist;

	char *elem_name;

	LoadVertex load_vertex;
	LoadFace load_face;

	/* open a PLY file for reading */
	ply = ply_open_for_reading(
		file_name,
		&nelems,
		&elist, 
		&file_type, 
		&version
	);

	if (ply == NULL) return NULL;

	/* go through each kind of element that we learned is in the file */
	/* and read them */

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

		/* print the name of the element, for debugging */

		/* if we're on vertex elements, read them in */

		if (equal_strings ("vertex", elem_name)) {

			/* 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]);

			// make some memory for the vertices		
			mesh->VertexSet().reserve(num_elems);

			/* grab all the vertex elements */
			for (j = 0; j < num_elems; j++) {

				/* grab and element from the file */
				ply_get_element (ply, (void *)&load_vertex);
				// pass the vertex into the mesh builder.
					
				if (load_vertex.x < min.x()) {
					min.x() = load_vertex.x;
				} else
				if (load_vertex.x > max.x()) {
					max.x()= load_vertex.x;
				}

				if (load_vertex.y < min.y()) {
					min.y() = load_vertex.y;
				} else
				if (load_vertex.y > max.y()) {
					max.y()= load_vertex.y;
				}

				if (load_vertex.z < min.z()) {
					min.z() = load_vertex.z;
				} else
				if (load_vertex.z > max.z()) {
					max.z()= load_vertex.z;
				}

				BSP_TVertex my_vert;
				my_vert.m_pos = MT_Vector3(load_vertex.x,load_vertex.y,load_vertex.z);
				mesh->VertexSet().push_back(my_vert);
			}
		

		}

		/* if we're on face elements, read them in */
		if (equal_strings ("face", elem_name)) {

			/* set up for getting face elements */

			ply_get_property (ply, elem_name, &face_props[0]);

			/* grab all the face elements */
			for (j = 0; j < num_elems; j++) {

				ply_get_element (ply, (void *)&load_face);

				int v;
				for (v = 2; v< load_face.nverts; v++) {

					BSP_TFace f;

					f.m_verts[0] = load_face.verts[0];
					f.m_verts[1] = load_face.verts[v-1];
					f.m_verts[2] = load_face.verts[v];

					mesh->BuildNormal(f);	
					mesh->FaceSet().push_back(f);
				}
				// free up the memory this pile of shit used to allocate the polygon's vertices
				free (load_face.verts);
			}

		}
	}
  /* close the PLY file */
  ply_close (ply);

 return mesh;
}
Example #22
0
void write_ply(const std::string &filename, const MatrixXu &F,
               const MatrixXf &V, const MatrixXf &N, const MatrixXf &Nf, const MatrixXf &UV,
               const MatrixXf &C, const ProgressCallback &progress) {
    auto message_cb = [](p_ply ply, const char *msg) {
        cerr << "rply: " << msg << endl;
    };

    Timer<> timer;
    cout << "Writing \"" << filename << "\" (V=" << V.cols()
         << ", F=" << F.cols() << ") .. ";
    cout.flush();

    if (N.size() > 0 && Nf.size() > 0)
        throw std::runtime_error("Please specify either face or vertex normals but not both!");

    p_ply ply = ply_create(filename.c_str(), PLY_DEFAULT, message_cb, 0, nullptr);
    if (!ply)
        throw std::runtime_error("Unable to write PLY file!");

    ply_add_comment(ply, "Generated by Instant Meshes");
    ply_add_element(ply, "vertex", V.cols());
    ply_add_scalar_property(ply, "x", PLY_FLOAT);
    ply_add_scalar_property(ply, "y", PLY_FLOAT);
    ply_add_scalar_property(ply, "z", PLY_FLOAT);

    if (N.size() > 0) {
        ply_add_scalar_property(ply, "nx", PLY_FLOAT);
        ply_add_scalar_property(ply, "ny", PLY_FLOAT);
        ply_add_scalar_property(ply, "nz", PLY_FLOAT);
        if (N.cols() != V.cols() || N.rows() != 3)
            throw std::runtime_error("Vertex normal matrix has incorrect size");
    }

    if (UV.size() > 0) {
        ply_add_scalar_property(ply, "u", PLY_FLOAT);
        ply_add_scalar_property(ply, "v", PLY_FLOAT);
        if (UV.cols() != V.cols() || UV.rows() != 2)
            throw std::runtime_error("Texture coordinate matrix has incorrect size");
    }

    if (C.size() > 0) {
        ply_add_scalar_property(ply, "red", PLY_FLOAT);
        ply_add_scalar_property(ply, "green", PLY_FLOAT);
        ply_add_scalar_property(ply, "blue", PLY_FLOAT);
        if (C.cols() != V.cols() || (C.rows() != 3 && C.rows() != 4))
            throw std::runtime_error("Color matrix has incorrect size");
    }

    /* Check for irregular faces */
    std::map<uint32_t, std::pair<uint32_t, std::map<uint32_t, uint32_t>>> irregular;
    size_t nIrregular = 0;
    if (F.rows() == 4) {
        for (uint32_t f=0; f<F.cols(); ++f) {
            if (F(2, f) == F(3, f)) {
                nIrregular++;
                auto &value = irregular[F(2, f)];
                value.first = f;
                value.second[F(0, f)] = F(1, f);
            }
        }
    }

    ply_add_element(ply, "face", F.cols() - nIrregular + irregular.size());
    ply_add_list_property(ply, "vertex_indices", PLY_UINT8, PLY_INT);
    if (Nf.size() > 0) {
        ply_add_scalar_property(ply, "nx", PLY_FLOAT);
        ply_add_scalar_property(ply, "ny", PLY_FLOAT);
        ply_add_scalar_property(ply, "nz", PLY_FLOAT);
        if (Nf.cols() != F.cols() || Nf.rows() != 3)
            throw std::runtime_error("Face normal matrix has incorrect size");
    }
    ply_write_header(ply);

    for (uint32_t j=0; j<V.cols(); ++j) {
        for (uint32_t i=0; i<V.rows(); ++i)
            ply_write(ply, V(i, j));
        if (N.size() > 0) {
            for (uint32_t i=0; i<N.rows(); ++i)
                ply_write(ply, N(i, j));
        }
        if (UV.size() > 0) {
            for (uint32_t i=0; i<UV.rows(); ++i)
                ply_write(ply, UV(i, j));
        }
        if (C.size() > 0) {
            for (uint32_t i=0; i<std::min(3u, (uint32_t) C.rows()); ++i)
                ply_write(ply, C(i, j));
        }
        if (progress && j % 500000 == 0)
            progress("Writing vertex data", j / (Float) V.cols());
    }

    for (uint32_t f=0; f<F.cols(); ++f) {
        if (F.rows() == 4 && F(2, f) == F(3, f))
            continue;
        ply_write(ply, F.rows());
        for (uint32_t i=0; i<F.rows(); ++i)
            ply_write(ply, F(i, f));
        if (Nf.size() > 0) {
            for (uint32_t i=0; i<Nf.rows(); ++i)
                ply_write(ply, Nf(i, f));
        }
        if (progress && f % 500000 == 0)
            progress("Writing face data", f / (Float) F.cols());
    }

    for (auto item : irregular) {
        auto face = item.second;
        uint32_t v = face.second.begin()->first, first = v;
        ply_write(ply, face.second.size());
        while (true) {
            ply_write(ply, v);
            v = face.second[v];
            if (v == first)
                break;
        }
        if (Nf.size() > 0) {
            for (uint32_t i=0; i<Nf.rows(); ++i)
                ply_write(ply, Nf(i, face.first));
        }
    }

    ply_close(ply);
    cout << "done. (";
    if (irregular.size() > 0)
        cout << irregular.size() << " irregular faces, ";
    cout << "took " << timeString(timer.value()) << ")" << endl;
}
Example #23
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;
}
Example #24
0
IGL_INLINE bool igl::writePLY(
  const std::string & filename,
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedF> & F,
  const Eigen::PlainObjectBase<DerivedN> & N,
  const Eigen::PlainObjectBase<DerivedUV> & UV,
  const bool ascii)
{
  // Largely based on obj2ply.c

  typedef struct Vertex
  {
    double x,y,z,w;          /* position */
    double nx,ny,nz;         /* surface normal */
    double s,t;              /* texture coordinates */
  } Vertex;

  typedef struct Face
  {
    unsigned char nverts;    /* number of vertex indices in list */
    int *verts;              /* vertex index list */
  } Face;

  PlyProperty vert_props[] =
  { /* list of property information for a vertex */
    {"x", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,x), 0, 0, 0, 0},
    {"y", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,y), 0, 0, 0, 0},
    {"z", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,z), 0, 0, 0, 0},
    {"nx", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nx), 0, 0, 0, 0},
    {"ny", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,ny), 0, 0, 0, 0},
    {"nz", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,nz), 0, 0, 0, 0},
    {"s", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,s), 0, 0, 0, 0},
    {"t", PLY_DOUBLE, PLY_DOUBLE, offsetof(Vertex,t), 0, 0, 0, 0},
  };

  PlyProperty face_props[] =
  { /* list of property information for a face */
    {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
      1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
  };
  const bool has_normals = N.rows() > 0;
  const bool has_texture_coords = UV.rows() > 0;
  std::vector<Vertex> vlist(V.rows());
  std::vector<Face> flist(F.rows());
  for(size_t i = 0;i<(size_t)V.rows();i++)
  {
    vlist[i].x = V(i,0);
    vlist[i].y = V(i,1);
    vlist[i].z = V(i,2);
    if(has_normals)
    {
      vlist[i].nx = N(i,0);
      vlist[i].ny = N(i,1);
      vlist[i].nz = N(i,2);
    }
    if(has_texture_coords)
    {
      vlist[i].s = UV(i,0);
      vlist[i].t = UV(i,1);
    }
  }
  for(size_t i = 0;i<(size_t)F.rows();i++)
  {
    flist[i].nverts = F.cols();
    flist[i].verts = new int[F.cols()];
    for(size_t c = 0;c<(size_t)F.cols();c++)
    {
      flist[i].verts[c] = F(i,c);
    }
  }

  const char * elem_names[] = {"vertex","face"};
  FILE * fp = fopen(filename.c_str(),"w");
  if(fp==NULL)
  {
    return false;
  }
  PlyFile * ply = ply_write(fp, 2,elem_names,
      (ascii ? PLY_ASCII : PLY_BINARY_LE));
  if(ply==NULL)
  {
    return false;
  }

  std::vector<PlyProperty> plist;
  plist.push_back(vert_props[0]);
  plist.push_back(vert_props[1]);
  plist.push_back(vert_props[2]);
  if (has_normals)
  {
    plist.push_back(vert_props[3]);
    plist.push_back(vert_props[4]);
    plist.push_back(vert_props[5]);
  }
  if (has_texture_coords)
  {
    plist.push_back(vert_props[6]);
    plist.push_back(vert_props[7]);
  }
  ply_describe_element(ply, "vertex", V.rows(),plist.size(),
    &plist[0]);

  ply_describe_element(ply, "face", F.rows(),1,&face_props[0]);
  ply_header_complete(ply);
  int native_binary_type = get_native_binary_type2();
  ply_put_element_setup(ply, "vertex");
  for(const auto v : vlist)
  {
    ply_put_element(ply, (void *) &v, &native_binary_type);
  }
  ply_put_element_setup(ply, "face");
  for(const auto f : flist)
  {
    ply_put_element(ply, (void *) &f, &native_binary_type);
  }

  ply_close(ply);
  for(size_t i = 0;i<(size_t)F.rows();i++)
  {
    delete[] flist[i].verts;
  }
  return true;
}
Example #25
0
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);
}
	bool save(const std::string& filename) {
		if(map_ == nil) {
			Logger::err("PlyMeshSave") << "mesh is null" << std::endl ;
			return false ;
		}

		p_ply ply = ply_create(filename.c_str(), PLY_LITTLE_ENDIAN, nil, 0, nil) ;

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

		//////////////////////////////////////////////////////////////////////////

		if (!ply_add_comment(ply, "saved by [email protected]")) {
			Logger::err("PlyMeshSave") << "unable to add comment" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		int num_v = map_->size_of_vertices();
		if (!ply_add_element(ply, "vertex", num_v)) {
			Logger::err("PlyMeshSave") << "unable to add element \'vertex\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}
		
		e_ply_type length_type, value_type;
		length_type = value_type = static_cast<e_ply_type>(-1);
		std::string pos[3] = { "x", "y", "z" };
		for (unsigned int i=0; i<3; ++i) {
			if (!ply_add_property(ply, pos[i].c_str(), PLY_FLOAT, length_type, value_type)) {
				Logger::err("PlyMeshSave") << "unable to add property \'" << pos[i] << "\'" << std::endl ;
				ply_close(ply) ;
				return false ;
			}
		}

		MapVertexAttribute<Color> vertex_color;
		vertex_color.bind_if_defined(const_cast<Map*>(map_), "color") ;
		if (vertex_color.is_bound()) {
			std::string color[4] = { "red", "green", "blue", "alpha" };
			for (unsigned int i=0; i<4; ++i) {
				if (!ply_add_property(ply, color[i].c_str(), PLY_UCHAR, length_type, value_type)) {
					Logger::err("PlyMeshSave") << "unable to add property \'" << color[i] << "\'" << std::endl ;
					ply_close(ply) ;
					return false ;
				}
			}
		}
		
		int num_f = map_->size_of_facets();
		if (!ply_add_element(ply, "face", num_f)) {
			Logger::err("PlyMeshSave") << "unable to add element \'face\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}
		if (!ply_add_property(ply, "vertex_indices", PLY_LIST, PLY_UCHAR, PLY_INT)) {
			Logger::err("PlyMeshSave") << "unable to add property \'vertex_indices\'" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		if(!ply_write_header(ply)) {
			Logger::err("PlyMeshSave") << filename << ": invalid PLY file" << std::endl ;
			ply_close(ply) ;
			return false ;
		}

		//////////////////////////////////////////////////////////////////////////
		
		FOR_EACH_VERTEX_CONST(Map, map_, it) {
			const vec3& p = it->point();
			ply_write(ply, p.x);
			ply_write(ply, p.y);
			ply_write(ply, p.z);
			if (vertex_color.is_bound()) {
				const Color& c = vertex_color[it];
				double r = c.r() * color_mult_;	ogf_clamp(r, 0.0, 255.0);
				double g = c.g() * color_mult_;	ogf_clamp(g, 0.0, 255.0);
				double b = c.b() * color_mult_;	ogf_clamp(b, 0.0, 255.0);
				double a = c.a() * color_mult_; ogf_clamp(a, 0.0, 255.0);
				ply_write(ply, r);
				ply_write(ply, g);
				ply_write(ply, b);
				ply_write(ply, a);
			}
		}

		// ply files numbering starts with 0
		Attribute<Map::Vertex, int> vertex_id(map_->vertex_attribute_manager());
		MapEnumerator::enumerate_vertices(const_cast<Map*>(map_), vertex_id, 0);
		FOR_EACH_FACET_CONST(Map, map_, it) {
			ply_write(ply, it->nb_vertices());
			Map::Halfedge* h = it->halfedge();
			do 
			{
				int id = vertex_id[h->vertex()];
				ply_write(ply, id);
				h = h->next();
			} while (h != it->halfedge());
		}
Example #27
0
/*******************************************************************************
 *         Name:  main
 *  Description:  
 ******************************************************************************/
int main( void ) {
	int i;

	/* Create new PLY file. */
	p_ply oply = ply_create( "new.ply", PLY_ASCII, NULL, 0, NULL );
	if ( !oply ) {
		fprintf( stderr, "ERROR: Could not create »new.ply«\n" );
		return EXIT_FAILURE;
	}

	/* Add object information to PLY. */
	if ( !ply_add_obj_info( oply, "This is just a test." ) ) {
		fprintf( stderr, "ERROR: Could not add object info.\n" );
		return EXIT_FAILURE;
	}

	/* Add a comment, too. */
	if ( !ply_add_comment( oply, "Just some comment…" ) ) {
		fprintf( stderr, "ERROR: Could not add comment.\n" );
		return EXIT_FAILURE;
	}

	/* Add vertex element. We want to add 9999 vertices. */
	if ( !ply_add_element( oply, "vertex", 99999 ) ) {
		fprintf( stderr, "ERROR: Could not add element.\n" );
		return EXIT_FAILURE;
	}

	/* Add vertex properties: x, y, z, r, g, b */
	if ( !ply_add_property( oply, "x",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "y",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "z",     PLY_FLOAT, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "red",   PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "green", PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	if ( !ply_add_property( oply, "blue",  PLY_UCHAR, 0, 0 ) ) {
		fprintf( stderr, "ERROR: Could not add property x.\n" );
		return EXIT_FAILURE;
	}

	/* Write header to file */
	if ( !ply_write_header( oply ) ) {
		fprintf( stderr, "ERROR: Could not write header.\n" );
		return EXIT_FAILURE;
	}

	/* Now we generate random data to add to the file: */
	srand ( time( NULL ) );

	for ( i = 0; i < 99999; i++ ) {
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* x */
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* y */
		ply_write( oply, (double) ( rand() % 10000 ) / 10.0 ); /* z */
		ply_write( oply, rand() % 256 ); /* red   */
		ply_write( oply, rand() % 256 ); /* blue  */
		ply_write( oply, rand() % 256 ); /* green */
	}

	if ( !ply_close( oply ) ) {
		fprintf( stderr, "ERROR: Could not close file.\n" );
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;

}
Example #28
0
Geometry::Geometry(const string &fileName) {
	p_ply plyfile = ply_open(fileName.c_str(), NULL);
	if (!plyfile) {
		stringstream ss;
		ss << "Unable to read PLY mesh file '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	if (!ply_read_header(plyfile)) {
		stringstream ss;
		ss << "Unable to read PLY header from '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	Point *p;
	long plyNbVerts = ply_set_read_cb(plyfile, "vertex", "x", VertexCB, &p, 0);
	ply_set_read_cb(plyfile, "vertex", "y", VertexCB, &p, 1);
	ply_set_read_cb(plyfile, "vertex", "z", VertexCB, &p, 2);
	if (plyNbVerts <= 0) {
		stringstream ss;
		ss << "No vertices found in '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	Triangle *vi;
	long plyNbTris = ply_set_read_cb(plyfile, "face", "vertex_indices", FaceCB, &vi, 0);
	if (plyNbTris <= 0) {
		stringstream ss;
		ss << "No triangles found in '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	Normal *n;
	long plyNbNormals = ply_set_read_cb(plyfile, "vertex", "nx", NormalCB, &n, 0);
	ply_set_read_cb(plyfile, "vertex", "ny", NormalCB, &n, 1);
	ply_set_read_cb(plyfile, "vertex", "nz", NormalCB, &n, 2);
	if ((plyNbNormals > 0) && (plyNbNormals != plyNbVerts)) {
		stringstream ss;
		ss << "Wrong count of normals in '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	RGB *c;
	long plyNbColors = ply_set_read_cb(plyfile, "vertex", "red", ColorCB, &c, 0);
	ply_set_read_cb(plyfile, "vertex", "green", ColorCB, &c, 1);
	ply_set_read_cb(plyfile, "vertex", "blue", ColorCB, &c, 2);

	if ((plyNbColors <= 0) || ((plyNbColors > 0) && (plyNbColors != plyNbVerts))) {
		stringstream ss;
		ss << "Wrong count of colors in '" << fileName << "'";
		throw runtime_error(ss.str());
	}

	p = new Point[plyNbVerts];
	vi = new Triangle[plyNbTris];
	c = new RGB[plyNbColors];
	n = new Normal[plyNbVerts];

	if (!ply_read(plyfile)) {
		stringstream ss;
		ss << "Unable to parse PLY file '" << fileName << "'";

		delete[] p;
		delete[] vi;
		delete[] c;
		delete[] n;

		throw runtime_error(ss.str());
	}

	ply_close(plyfile);

	vertexCount = plyNbVerts;
	triangleCount = plyNbTris;
	vertices = p;
	triangles = vi;
	vertNormals = n;
	vertColors = c;

	// Scale vertex colors
	for (unsigned int i = 0; i < vertexCount; ++i)
		c[i] *= 0.75f;

	// It looks like normals exported by Blender are bugged
	for (unsigned int i = 0; i < vertexCount; ++i)
		vertNormals[i] = Normal(0.f, 0.f, 0.f);
	for (unsigned int i = 0; i < triangleCount; ++i) {
		const Vector e1 = vertices[triangles[i].v[1]] - vertices[triangles[i].v[0]];
		const Vector e2 = vertices[triangles[i].v[2]] - vertices[triangles[i].v[0]];
		const Normal n = Normal(Normalize(Cross(e1, e2)));
		vertNormals[triangles[i].v[0]] += n;
		vertNormals[triangles[i].v[1]] += n;
		vertNormals[triangles[i].v[2]] += n;
	}
	int printedWarning = 0;
	for (unsigned int i = 0; i < vertexCount; ++i) {
		vertNormals[i] = Normalize(vertNormals[i]);
		// Check for degenerate triangles/normals, they can freeze the GPU
		if (isnan(vertNormals[i].x) || isnan(vertNormals[i].y) || isnan(vertNormals[i].z)) {
			if (printedWarning < 15) {
				cerr << "The model contains a degenerate normal (index " << i << ")" << endl;
				++printedWarning;
			} else if (printedWarning == 15) {
				cerr << "The model contains more degenerate normals" << endl;
				++printedWarning;
			}
			vertNormals[i] = Normal(0.f, 0.f, 1.f);
		}
	}

	/*if (plyNbNormals <= 0) {
		// Calculate normals
		for (unsigned int i = 0; i < triangleCount; ++i) {
			const Vector e1 = vertices[triangles[i].v[1]] - vertices[triangles[i].v[0]];
			const Vector e2 = vertices[triangles[i].v[2]] - vertices[triangles[i].v[0]];
			const Normal n = Normal(Normalize(Cross(e1, e2)));
			vertNormals[triangles[i].v[0]] = n;
			vertNormals[triangles[i].v[1]] = n;
			vertNormals[triangles[i].v[2]] = n;
		}
	}*/
}
Example #29
0
	 LOD_Decimation_InfoPtr 
NewVertsFromFile(
	char * file_name,
	MT_Vector3 &min,
	MT_Vector3 &max
) {

	min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY);
	max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY);

	
	PlyProperty vert_props[] = { /* list of property information for a vertex */
	  {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0},
	  {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0},
	  {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0},
	};

	PlyProperty face_props[] = { /* list of property information for a vertex */
	  {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,intensity), 0, 0, 0, 0},
	  {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts),
	   1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)},
	};
#if 0
	MEM_SmartPtr<std::vector<float> > verts = new std::vector<float>;
	MEM_SmartPtr<std::vector<float> > vertex_normals = new std::vector<float>;

	MEM_SmartPtr<std::vector<int> > faces = new std::vector<int>;
#else
	std::vector<float>* verts = new std::vector<float>;
	std::vector<float>*  vertex_normals = new std::vector<float>;

	std::vector<int> * faces = new std::vector<int>;
#endif

  int i,j;
  PlyFile *ply;
  int nelems;
  char **elist;
  int file_type;
  float version;
  int nprops;
  int num_elems;
  PlyProperty **plist;

  char *elem_name;

	LoadVertex load_vertex;
	LoadFace load_face;

  /* open a PLY file for reading */
  ply = ply_open_for_reading(file_name, &nelems, &elist, &file_type, &version);

 if (ply == NULL) return NULL;
  /* go through each kind of element that we learned is in the file */
  /* and read them */

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

    /* print the name of the element, for debugging */

    /* if we're on vertex elements, read them in */
    if (equal_strings ("vertex", elem_name)) {

      /* 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]);

		// make some memory for the vertices		
  		verts->reserve(num_elems);

      /* grab all the vertex elements */
      for (j = 0; j < num_elems; j++) {

        /* grab and element from the file */
        ply_get_element (ply, (void *)&load_vertex);
		// pass the vertex into the mesh builder.
			
	
		if (load_vertex.x < min.x()) {
			min.x() = load_vertex.x;
		} else
		if (load_vertex.x > max.x()) {
			max.x()= load_vertex.x;
		}

		if (load_vertex.y < min.y()) {
			min.y() = load_vertex.y;
		} else
		if (load_vertex.y > max.y()) {
			max.y()= load_vertex.y;
		}

		if (load_vertex.z < min.z()) {
			min.z() = load_vertex.z;
		} else
		if (load_vertex.z > max.z()) {
			max.z()= load_vertex.z;
		}

		verts->push_back(load_vertex.x);
		verts->push_back(load_vertex.y);
		verts->push_back(load_vertex.z);

		vertex_normals->push_back(1.0f);
		vertex_normals->push_back(0.0f);
		vertex_normals->push_back(0.0f);


      }
    }

    /* if we're on face elements, read them in */
    if (equal_strings ("face", elem_name)) {

      /* set up for getting face elements */

 //     ply_get_property (ply, elem_name, &face_props[0]);
      ply_get_property (ply, elem_name, &face_props[1]);

      /* grab all the face elements */
      for (j = 0; j < num_elems; j++) {

        ply_get_element (ply, (void *)&load_face);

		faces->push_back(load_face.verts[0]);
		faces->push_back(load_face.verts[1]);
		faces->push_back(load_face.verts[2]);

		// free up the memory this pile of shit used to allocate the polygon's vertices

		free (load_face.verts);
      }

    }
  }
  /* close the PLY file */
  ply_close (ply);

  LOD_Decimation_InfoPtr output = new LOD_Decimation_Info;

  output->vertex_buffer = verts->begin();
  output->vertex_num = verts->size()/3;

  output->triangle_index_buffer = faces->begin();
  output->face_num = faces->size()/3;
  output->intern = NULL;
  output->vertex_normal_buffer = vertex_normals->begin();

  // memory leaks 'r' us	
#if 0
  verts.Release();
  vertex_normals.Release();
  faces.Release();
#endif
  return output;
}
read_test()
{
  int i,j,k;
  PlyFile *ply;
  int nelems;
  char **elist;
  int file_type;
  float version;
  int nprops;
  int num_elems;
  PlyProperty **plist;
  Vertex **vlist;
  Face **flist;
  char *elem_name;
  int num_comments;
  char **comments;
  int num_obj_info;
  char **obj_info;

  /* open a PLY file for reading */
  ply = ply_open_for_reading("test", &nelems, &elist, &file_type, &version);

  /* print what we found out about the file */
  printf ("version %f\n", version);
  printf ("type %d\n", file_type);

  /* go through each kind of element that we learned is in the file */
  /* and read them */

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

    /* print the name of the element, for debugging */
    printf ("element %s %d\n", elem_name, num_elems);

    /* if we're on vertex elements, read them in */
    if (equal_strings ("vertex", elem_name)) {

		/* create a vertex list to hold all the vertices */
		vlist = (Vertex **) malloc (sizeof (Vertex *) * 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]);

		/* grab all the vertex elements */
		for (j = 0; j < num_elems; j++) {

		/* grab and element from the file */
		vlist[j] = (Vertex *) malloc (sizeof (Vertex));
		ply_get_element (ply, (void *) vlist[j]);

		/* print out vertex x,y,z for debugging */
		printf ("vertex: %g %g %g\n", vlist[j]->x, vlist[j]->y, vlist[j]->z);
      }
    }

    /* if we're on face elements, read them in */
    if (equal_strings ("face", elem_name)) {

      /* create a list to hold all the face elements */
      flist = (Face **) malloc (sizeof (Face *) * num_elems);

      /* set up for getting face elements */

      ply_get_property (ply, elem_name, &face_props[0]);
      ply_get_property (ply, elem_name, &face_props[1]);

      /* grab all the face elements */
      for (j = 0; j < num_elems; j++) {

        /* grab and element from the file */
        flist[j] = (Face *) malloc (sizeof (Face));
        ply_get_element (ply, (void *) flist[j]);

        /* print out face info, for debugging */
        printf ("face: %d, list = ", flist[j]->intensity);
        for (k = 0; k < flist[j]->nverts; k++)
          printf ("%d ", flist[j]->verts[k]);
        printf ("\n");
      }
    }
    
    /* print out the properties we got, for debugging */
    for (j = 0; j < nprops; j++)
      printf ("property %s\n", plist[j]->name);
  }

  /* grab and print out the comments in the file */
  comments = ply_get_comments (ply, &num_comments);
  for (i = 0; i < num_comments; i++)
    printf ("comment = '%s'\n", comments[i]);

  /* grab and print out the object information */
  obj_info = ply_get_obj_info (ply, &num_obj_info);
  for (i = 0; i < num_obj_info; i++)
    printf ("obj_info = '%s'\n", obj_info[i]);

  /* close the PLY file */
  ply_close (ply);
}