root/OpenSceneGraph/trunk/src/osgPlugins/3dc/ReaderWriter3DC.cpp @ 10010

Revision 10010, 7.1 kB (checked in by robert, 6 years ago)

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.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[1975]1#include <osg/Notify>
2#include <osg/Geode>
3#include <osg/Geometry>
4
5#include <osgDB/FileNameUtils>
[2501]6#include <osgDB/FileUtils>
[9124]7#include <osgDB/fstream>
[1975]8#include <osgDB/Registry>
9
10#include <iostream>
11#include <stdio.h>
[9343]12#include <string.h>
[1975]13
[10010]14class Writer3DCNodeVisitor: public osg::NodeVisitor {
[1975]15
[10010]16    public:
17        Writer3DCNodeVisitor(std::ostream& fout) :
18            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
19            _fout(fout)
20        {
21           // _fout << "# file written by OpenSceneGraph" << std::endl << std::endl;
22        }
[1975]23
[10010]24        virtual void apply(osg::Geode &node);
25
26    protected:
27
28        Writer3DCNodeVisitor& operator = (const Writer3DCNodeVisitor&) { return *this; }
29        std::ostream& _fout;
30
31};
32
33void Writer3DCNodeVisitor::apply( osg::Geode &node )
34{
35    osg::Matrix matrix = osg::computeLocalToWorld(getNodePath());
36
37    unsigned int count = node.getNumDrawables();
38    for ( unsigned int i = 0; i < count; i++ )
39    {
40        osg::Geometry *geometry = node.getDrawable( i )->asGeometry();
41        if ( geometry )
42        {
43            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
44            osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
45            osg::Vec3Array* colours = dynamic_cast<osg::Vec3Array*>(geometry->getColorArray());
46
47            if ( vertices ) {
48                for (unsigned int ii=0;ii<vertices->size();ii++) {
49
50                    // update nodes with world coords
51                    osg::Vec3d v = vertices->at(ii) * matrix;
52                    _fout << v[0] << ' ' << v[1] << ' ' << v[2];
53
54                    if ( colours )
55                    {
56                        v=colours->at(ii);
57                        _fout << ' ' << (int)v[0]*255.0 << ' ' << (int)v[1]*255.0 << ' ' << (int)v[2]*255.0;
58                    }
59                    else
60                    {
61                        _fout << " 255 255 255";
62                    }
63
64                    if ( normals )
65                    {
66                        v = normals->at(ii);
67                        _fout << ' ' << v[0] << ' ' << v[1] << ' ' << v[2];
68                    }
69                    else
70                    {
71                        _fout << " 0.0 0.0 1.0";
72                    }
73
74
75                    _fout << std::endl;
76                }
77            }
78
79        }
80    }
81}
82
[1975]83class ReaderWriter3DC : public osgDB::ReaderWriter
84{
85    public:
[10010]86
[8578]87        ReaderWriter3DC()
88        {
89            supportsExtension("3dc","3DC point cloud format");
90            supportsExtension("asc","3DC point cloud format");
91        }
[10010]92
[3539]93        virtual const char* className() const { return "3DC point cloud reader"; }
[10010]94
[3694]95        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
[1975]96        {
[2501]97            std::string ext = osgDB::getLowerCaseFileExtension(file);
[1975]98            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
[2501]99
[3691]100            std::string fileName = osgDB::findDataFile( file, options );
[2501]101            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
[10010]102
[8300]103            osg::notify(osg::INFO) << "Reading file "<<fileName<<std::endl;
[10010]104
[1975]105            const int LINE_SIZE = 1024;
106            char line[LINE_SIZE];
[10010]107
[2001]108            unsigned int targetNumVertices = 10000;
[10010]109
[2001]110            osg::Geode* geode = new osg::Geode;
111
[1975]112            osg::Geometry* geometry = new osg::Geometry;
[10010]113
[1975]114            osg::Vec3Array* vertices = new osg::Vec3Array;
115            osg::Vec3Array* normals = new osg::Vec3Array;
[4390]116            osg::Vec4ubArray* colours = new osg::Vec4ubArray;
[10010]117
118            osg::Vec3 pos;
119            osg::Vec3 normal(0.0,0.0,1.0);
120            int r=255,g=255,b=255,a=255;
121            char sep;
122
123            osgDB::ifstream fin(fileName.c_str());
124            while (fin)
[1975]125            {
[10010]126                fin.getline(line,LINE_SIZE);
[1975]127                if (line[0]=='#')
128                {
129                    // comment line
[8300]130                    osg::notify(osg::INFO) <<"Comment: "<<line<<std::endl;
[1975]131                }
132                else if (strlen(line)>0)
133                {
[10010]134                    int matched = sscanf(line,"%f%c%f%c%f%c%d%c%d%c%d%c%f%c%f%c%f",
135                                   &pos.x(),&sep,&pos.y(),&sep,&pos.z(),&sep,
136                                   &r,&sep,&g,&sep,&b,&sep,
137                                   &normal.x(),&sep,&normal.y(),&sep,&normal.z());
138
139                    if (matched)
[2001]140                    {
[10010]141
[2001]142                        if (vertices->size()>=targetNumVertices)
143                        {
144                            // finishing setting up the current geometry and add it to the geode.
[2057]145                            geometry->setUseDisplayList(true);   
146                            geometry->setUseVertexBufferObjects(true);   
[2001]147                            geometry->setVertexArray(vertices);
148                            geometry->setNormalArray(normals);
149                            geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
150                            geometry->setColorArray(colours);
151                            geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
152                            geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size()));
[10010]153
[2001]154                            geode->addDrawable(geometry);
155
[10010]156                            // allocate a new geometry
[2001]157                            geometry = new osg::Geometry;
158
159                            vertices = new osg::Vec3Array;
160                            normals = new osg::Vec3Array;
[4390]161                            colours = new osg::Vec4ubArray;
[2001]162
163                            vertices->reserve(targetNumVertices);
164                            normals->reserve(targetNumVertices);
165                            colours->reserve(targetNumVertices);
166
167                        }
[10010]168
[1975]169                        vertices->push_back(pos);
170                        normals->push_back(normal);
[10010]171                        colours->push_back(osg::Vec4ub(r,g,b,a));
[1975]172                    }
173                }
174            }
[1983]175
[2001]176
[2057]177            geometry->setUseDisplayList(true);
178            geometry->setUseVertexBufferObjects(true);   
[1975]179            geometry->setVertexArray(vertices);
180            geometry->setNormalArray(normals);
181            geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
182            geometry->setColorArray(colours);
183            geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
184            geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,vertices->size()));
185
186            geode->addDrawable(geometry);
[10010]187
[1975]188            return geode;
[10010]189
[1975]190        }
[10010]191
192        virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options =NULL) const 
193        {
194            if (!acceptsExtension(osgDB::getFileExtension(fileName)))
195                return WriteResult(WriteResult::FILE_NOT_HANDLED);
196
197            osgDB::ofstream f(fileName.c_str());
198
199            Writer3DCNodeVisitor nv(f);
200
201            // we must cast away constness
202            (const_cast<osg::Node*>(&node))->accept(nv);
203
204            return WriteResult(WriteResult::FILE_SAVED);
205        }
[1975]206};
207
208// now register with Registry to instantiate the above
209// reader/writer.
[7076]210REGISTER_OSGPLUGIN(3dc, ReaderWriter3DC)
Note: See TracBrowser for help on using the browser.