From Martin Beckett, "I have fixed up the 3DC reader to handle any field separator so it can read x,y,z files and added ability to write a 3DC file."

From Robert Osfield, refactor of the above code to retain a bit more of the original funcionality, and to avoid the need to hand maintained XCode projects from being updated.
This commit is contained in:
Robert Osfield
2009-04-09 16:31:31 +00:00
parent 37ef864bdd
commit 4efd7a558d

View File

@@ -11,21 +11,87 @@
#include <stdio.h>
#include <string.h>
class Writer3DCNodeVisitor: public osg::NodeVisitor {
using namespace osg;
public:
Writer3DCNodeVisitor(std::ostream& fout) :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_fout(fout)
{
// _fout << "# file written by OpenSceneGraph" << std::endl << std::endl;
}
virtual void apply(osg::Geode &node);
protected:
Writer3DCNodeVisitor& operator = (const Writer3DCNodeVisitor&) { return *this; }
std::ostream& _fout;
};
void Writer3DCNodeVisitor::apply( osg::Geode &node )
{
osg::Matrix matrix = osg::computeLocalToWorld(getNodePath());
unsigned int count = node.getNumDrawables();
for ( unsigned int i = 0; i < count; i++ )
{
osg::Geometry *geometry = node.getDrawable( i )->asGeometry();
if ( geometry )
{
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
osg::Vec3Array* colours = dynamic_cast<osg::Vec3Array*>(geometry->getColorArray());
if ( vertices ) {
for (unsigned int ii=0;ii<vertices->size();ii++) {
// update nodes with world coords
osg::Vec3d v = vertices->at(ii) * matrix;
_fout << v[0] << ' ' << v[1] << ' ' << v[2];
if ( colours )
{
v=colours->at(ii);
_fout << ' ' << (int)v[0]*255.0 << ' ' << (int)v[1]*255.0 << ' ' << (int)v[2]*255.0;
}
else
{
_fout << " 255 255 255";
}
if ( normals )
{
v = normals->at(ii);
_fout << ' ' << v[0] << ' ' << v[1] << ' ' << v[2];
}
else
{
_fout << " 0.0 0.0 1.0";
}
_fout << std::endl;
}
}
}
}
}
class ReaderWriter3DC : public osgDB::ReaderWriter
{
public:
ReaderWriter3DC()
{
supportsExtension("3dc","3DC point cloud format");
supportsExtension("asc","3DC point cloud format");
}
virtual const char* className() const { return "3DC point cloud reader"; }
virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
@@ -33,15 +99,28 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
std::string fileName = osgDB::findDataFile( file, options );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
osg::notify(osg::INFO) << "Reading file "<<fileName<<std::endl;
const int LINE_SIZE = 1024;
char line[LINE_SIZE];
unsigned int targetNumVertices = 10000;
osg::Geode* geode = new osg::Geode;
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec3Array* normals = new osg::Vec3Array;
osg::Vec4ubArray* colours = new osg::Vec4ubArray;
osg::Vec3 pos;
osg::Vec3 normal(0.0,0.0,1.0);
int r=255,g=255,b=255,a=255;
char sep;
osgDB::ifstream fin(fileName.c_str());
unsigned int num = 0;
while (fin)
{
fin.getline(line,LINE_SIZE);
@@ -50,57 +129,16 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
// comment line
osg::notify(osg::INFO) <<"Comment: "<<line<<std::endl;
}
else
{
++num;
}
}
osg::notify(osg::INFO) << "num="<<num<<std::endl;
unsigned int targetNumVertices = 10000;
osg::Geode* geode = new osg::Geode;
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec3Array* normals = new osg::Vec3Array;
osg::Vec4ubArray* colours = new osg::Vec4ubArray;
vertices->reserve(targetNumVertices);
normals->reserve(targetNumVertices);
colours->reserve(targetNumVertices);
fin.close();
osgDB::ifstream fin2(fileName.c_str());
while (fin2)
{
fin2.getline(line,LINE_SIZE);
if (line[0]=='#')
{
// comment line
osg::notify(osg::INFO) <<"Comment: "<<line<<std::endl;
}
else if (strlen(line)>0)
{
++num;
osg::Vec3 pos,normal;
int r,g,b;
int a = sscanf(line,"%f %f %f %d %d %d %f %f %f",
&pos.x(),&pos.y(),&pos.z(),
&r,&g,&b,
&normal.x(),&normal.y(),&normal.z());
if (a)
int matched = sscanf(line,"%f%c%f%c%f%c%d%c%d%c%d%c%f%c%f%c%f",
&pos.x(),&sep,&pos.y(),&sep,&pos.z(),&sep,
&r,&sep,&g,&sep,&b,&sep,
&normal.x(),&sep,&normal.y(),&sep,&normal.z());
if (matched)
{
if (vertices->size()>=targetNumVertices)
{
// finishing setting up the current geometry and add it to the geode.
@@ -112,10 +150,10 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
geometry->setColorArray(colours);
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size()));
geode->addDrawable(geometry);
// allocate a new geometry
// allocate a new geometry
geometry = new osg::Geometry;
vertices = new osg::Vec3Array;
@@ -127,14 +165,12 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
colours->reserve(targetNumVertices);
}
vertices->push_back(pos);
normals->push_back(normal);
colours->push_back(osg::Vec4ub(r,g,b,255));
colours->push_back(osg::Vec4ub(r,g,b,a));
}
}
}
@@ -148,11 +184,25 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size()));
geode->addDrawable(geometry);
return geode;
}
virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options =NULL) const
{
if (!acceptsExtension(osgDB::getFileExtension(fileName)))
return WriteResult(WriteResult::FILE_NOT_HANDLED);
osgDB::ofstream f(fileName.c_str());
Writer3DCNodeVisitor nv(f);
// we must cast away constness
(const_cast<osg::Node*>(&node))->accept(nv);
return WriteResult(WriteResult::FILE_SAVED);
}
};
// now register with Registry to instantiate the above