root/OpenSceneGraph/trunk/src/osgPlugins/dxf/scene.h @ 13041

Revision 13041, 14.3 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* dxfReader for OpenSceneGraph  Copyright (C) 2005 by GraphArchitecture ( grapharchitecture.com )
2 * Programmed by Paul de Repentigny <pdr@grapharchitecture.com>
3 *
4 * OpenSceneGraph is (C) 2004 Robert Osfield
5 *
6 * This library is provided as-is, without support of any kind.
7 *
8 * Read DXF docs or OSG docs for any related questions.
9 *
10 * You may contact the author if you have suggestions/corrections/enhancements.
11 */
12
13
14/** Simulate the scene with double precision before passing it back to osg.
15    this permits us to scale down offsets from 0,0,0 with a few matrixtransforms,
16    in case the objects are too far from that center.
17    */
18
19#ifndef DXF_SCENE
20#define DXF_SCENE 1
21
22#include <osg/Matrixd>
23#include <osg/Group>
24#include <osg/MatrixTransform>
25#include <osg/Geometry>
26#include <osg/Geode>
27#include <osg/Vec3d>
28#include <osgText/Text>
29#include <osgUtil/SmoothingVisitor>
30
31class dxfLayerTable;
32
33class bounds {
34public:
35    bounds() : _min(DBL_MAX, DBL_MAX, DBL_MAX), _max(-DBL_MAX, -DBL_MAX, -DBL_MAX) {}
36    inline void expandBy(const osg::Vec3d & v) {
37        if(v.x()<_min.x()) _min.x() = v.x();
38        if(v.x()>_max.x()) _max.x() = v.x();
39
40        if(v.y()<_min.y()) _min.y() = v.y();
41        if(v.y()>_max.y()) _max.y() = v.y();
42
43        if(v.z()<_min.z()) _min.z() = v.z();
44        if(v.z()>_max.z()) _max.z() = v.z();
45    }
46    inline void makeMinValid() {
47        // we count on _min to offset the whole scene
48        // so, we make sure its at 0,0,0 if
49        // bounds are not set (anyway, the scene should be empty,
50        // if we need to set any value of _min to 0).
51        if (_min.x() == DBL_MAX) _min.x() = 0;
52        if (_min.y() == DBL_MAX) _min.y() = 0;
53        if (_min.z() == DBL_MAX) _min.z() = 0;
54    }
55    osg::Vec3d _min;
56    osg::Vec3d _max;
57};
58
59
60static inline
61osg::Geometry* createPtGeometry( osg::PrimitiveSet::Mode pointType, osg::Vec3Array* vertices, const osg::Vec4 & color)
62{
63    osg::Geometry* geom = new osg::Geometry;
64    geom->setVertexArray(vertices);
65    geom->addPrimitiveSet(new osg::DrawArrays(pointType, 0, vertices->size()));
66    osg::Vec4Array* colors = new osg::Vec4Array;
67    colors->push_back(color);
68    geom->setColorArray(colors);
69    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
70    osg::Vec3Array *norms = new osg::Vec3Array;
71    norms->push_back(osg::Vec3(0,0,1));
72    geom->setNormalArray(norms);
73    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
74    return geom;
75}
76
77static inline
78osg::Geometry* createLnGeometry( osg::PrimitiveSet::Mode lineType, osg::Vec3Array* vertices, const osg::Vec4 & color)
79{
80    osg::Geometry* geom = new osg::Geometry;
81    geom->setVertexArray(vertices);
82    geom->addPrimitiveSet(new osg::DrawArrays(lineType, 0, vertices->size()));
83    osg::Vec4Array* colors = new osg::Vec4Array;
84    colors->push_back(color);
85    geom->setColorArray(colors);
86    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
87    osg::Vec3Array *norms = new osg::Vec3Array;
88    norms->push_back(osg::Vec3(0,0,1));
89    geom->setNormalArray(norms);
90    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
91    return geom;
92}
93
94static inline
95osg::Geometry* createTriGeometry( osg::Vec3Array* vertices, osg::Vec3Array* normals, const osg::Vec4 & color)
96{
97    osg::Geometry* geom = new osg::Geometry;
98    geom->setVertexArray(vertices);
99    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));
100    osg::Vec4Array* colors = new osg::Vec4Array;
101    colors->push_back(color);
102    geom->setColorArray(colors);
103    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
104    geom->setNormalArray(normals);
105    geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
106    return geom;
107}
108
109static inline
110osg::Geometry* createQuadGeometry( osg::Vec3Array* vertices, osg::Vec3Array* normals, const osg::Vec4 & color)
111{
112    osg::Geometry* geom = new osg::Geometry;
113    geom->setVertexArray(vertices);
114    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertices->size()));
115    osg::Vec4Array* colors = new osg::Vec4Array;
116    colors->push_back(color);
117    geom->setColorArray(colors);
118    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
119    geom->setNormalArray(normals);
120    geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
121    return geom;
122}
123
124static inline
125osg::Geode* createModel(const std::string & name, osg::Drawable* drawable)
126{
127    osg::Geode* geode = new osg::Geode;
128    geode->addDrawable(drawable);
129    geode->setName(name);
130    return geode;
131}
132
133
134static inline osg::Vec3d preMultd(const osg::Matrixd& m, const osg::Vec3d& v)
135{
136    double d = 1.0f/(m(3,0)*v.x()+m(3,1)*v.y()+m(3,2)*v.z()+m(3,3)) ;
137    return osg::Vec3d( (m(0,0)*v.x() + m(1,0)*v.y() + m(2,0)*v.z() + m(3,0))*d,
138        (m(0,1)*v.x() + m(1,1)*v.y() + m(2,1)*v.z() + m(3,1))*d,
139        (m(0,2)*v.x() + m(1,2)*v.y() + m(2,2)*v.z() + m(3,2))*d) ;
140}
141
142static inline osg::Vec3d postMultd(const osg::Matrixd& m, const osg::Vec3d& v)
143{
144    double d = 1.0f/(m(3,0)*v.x()+m(3,1)*v.y()+m(3,2)*v.z()+m(3,3)) ;
145    return osg::Vec3d( (m(0,0)*v.x() + m(0,1)*v.y() + m(0,2)*v.z() + m(0,3))*d,
146        (m(1,0)*v.x() + m(1,1)*v.y() + m(1,2)*v.z() + m(1,3))*d,
147        (m(2,0)*v.x() + m(2,1)*v.y() + m(2,2)*v.z() + m(2,3))*d) ;
148}
149
150typedef std::vector<osg::Vec3d> VList;
151typedef std::map<unsigned short, VList> MapVList;
152typedef std::vector<VList> VListList;
153typedef std::map<unsigned short, VListList> MapVListList;
154
155
156class sceneLayer : public osg::Referenced {
157public:
158    sceneLayer(std::string name) : _name(name) {}
159    virtual ~sceneLayer() {}
160    void layer2osg(osg::Group* root, bounds &b)
161    {
162        osgPoints(root, b);
163        osgLines(root, b);
164        osgTriangles(root, b);
165        osgQuads(root, b);
166        osgText(root, b);
167    }
168    MapVListList    _linestrips;
169    MapVList        _points;
170    MapVList        _lines;
171    MapVList        _triangles;
172    MapVList        _trinorms;
173    MapVList        _quads;
174    MapVList        _quadnorms;
175
176    struct textInfo
177    {
178        textInfo(short int color, osg::Vec3 point, osgText::Text *text) :
179            _color(color), _point(point), _text(text) {};
180        short int _color;
181        osg::Vec3d _point;
182        osg::ref_ptr<osgText::Text> _text;
183    };
184
185    typedef std::vector<textInfo> TextList;
186    TextList _textList;
187
188protected:
189    std::string        _name;
190
191    osg::Vec4        getColor(unsigned short color);
192
193    void osgPoints(osg::Group* root, bounds &b)
194    {
195
196        for (MapVList::iterator mitr = _points.begin();
197            mitr != _points.end(); ++mitr) {
198            osg::Vec3Array *coords = new osg::Vec3Array;
199            for (VList::iterator itr = mitr->second.begin();
200                itr != mitr->second.end(); ++itr) {
201                osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
202                coords->push_back(v);
203            }
204            root->addChild(createModel(_name, createPtGeometry(osg::PrimitiveSet::POINTS, coords, getColor(mitr->first))));
205        }
206    }
207
208    void osgLines(osg::Group* root, bounds &b)
209    {
210        for(MapVListList::iterator mlitr = _linestrips.begin();
211            mlitr != _linestrips.end();
212            ++mlitr)
213        {
214            for(VListList::iterator itr = mlitr->second.begin();
215                itr != mlitr->second.end();
216                ++itr)
217            {
218                if (itr->size()) {
219                    osg::Vec3Array *coords = new osg::Vec3Array;
220                    for (VList::iterator vitr = itr->begin();
221                        vitr != itr->end(); ++vitr) {
222                        osg::Vec3 v(vitr->x() - b._min.x(), vitr->y() - b._min.y(), vitr->z() - b._min.z());
223                        coords->push_back(v);
224                    }
225                    root->addChild(createModel(_name, createLnGeometry(osg::PrimitiveSet::LINE_STRIP, coords, getColor(mlitr->first))));
226                }
227            }
228        }
229        for (MapVList::iterator mitr = _lines.begin();
230            mitr != _lines.end(); ++mitr) {
231            osg::Vec3Array *coords = new osg::Vec3Array;
232            for (VList::iterator itr = mitr->second.begin();
233                itr != mitr->second.end(); ++itr) {
234                osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
235                coords->push_back(v);
236            }
237            root->addChild(createModel(_name, createLnGeometry(osg::PrimitiveSet::LINES, coords, getColor(mitr->first))));
238        }
239    }
240
241    void osgTriangles(osg::Group* root, bounds &b)
242    {
243        if (_triangles.size()) {
244            for (MapVList::iterator mitr = _triangles.begin();
245                mitr != _triangles.end(); ++mitr) {
246                osg::Vec3Array *coords = new osg::Vec3Array;
247                VList::iterator itr;
248                for (itr = mitr->second.begin();
249                    itr != mitr->second.end(); ++itr)
250                {
251                    osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
252                    coords->push_back(v);
253                }
254                osg::Vec3Array *norms = new osg::Vec3Array;
255                VList& normlist = _trinorms[mitr->first];
256                for (itr = normlist.begin();
257                    itr != normlist.end(); ++itr)
258                {
259                    osg::Vec3 norm(itr->x(), itr->y(), itr->z());
260                    for (int i = 0; i < 3; ++i)
261                        norms->push_back(norm);
262                }
263                root->addChild(createModel(_name, createTriGeometry(coords, norms, getColor(mitr->first))));
264            }
265        }
266    }
267    void osgQuads(osg::Group* root, bounds &b)
268    {
269        if (_quads.size()) {
270            for (MapVList::iterator mitr = _quads.begin();
271                mitr != _quads.end(); ++mitr) {
272                osg::Vec3Array *coords = new osg::Vec3Array;
273                VList::iterator itr;
274                for (itr = mitr->second.begin();
275                    itr != mitr->second.end(); ++itr) {
276                    osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
277                    coords->push_back(v);
278                }
279                osg::Vec3Array *norms = new osg::Vec3Array;
280                VList& normlist = _quadnorms[mitr->first];
281                for (itr = normlist.begin();
282                    itr != normlist.end(); ++itr) {
283                    osg::Vec3 norm(itr->x(), itr->y(), itr->z());
284                    for (int i = 0; i < 4; ++i)
285                        norms->push_back(norm);
286                }
287                root->addChild(createModel(_name, createQuadGeometry(coords, norms, getColor(mitr->first))));
288            }
289        }
290    }
291    void osgText(osg::Group* root, bounds &b)
292    {
293        if (_textList.size()) {
294            for (TextList::iterator titr = _textList.begin();
295                    titr != _textList.end(); ++titr) {
296                titr->_text->setColor(getColor(titr->_color));
297                osg::Vec3d v1=titr->_point;
298                osg::Vec3 v2(v1.x() - b._min.x(), v1.y() - b._min.y(), v1.z() - b._min.z());
299                titr->_text->setPosition(v2);
300                root->addChild(createModel(_name, titr->_text.get()));
301            }
302        }
303    }
304};
305
306
307class scene : public osg::Referenced {
308public:
309    scene(dxfLayerTable* lt = NULL);
310    virtual ~scene() {}
311    void setLayerTable(dxfLayerTable* lt);
312    void pushMatrix(const osg::Matrixd& m, bool protect = false)
313    {
314        _mStack.push_back(_m);
315        if (protect) // equivalent to setMatrix
316            _m = m;
317        else
318            _m = _m * m;
319    }
320    void popMatrix()
321    {
322        _mStack.pop_back();
323        if (_mStack.size())
324            _m = _mStack.back();
325        else
326            _m.makeIdentity();
327    }
328    void ocs(const osg::Matrixd& r)
329    {
330        _r = r;
331    }
332    void blockOffset(const osg::Vec3d& t)
333    {
334        _t = t;
335    }
336    void ocs_clear()
337    {
338        _r.makeIdentity();
339    }
340    osg::Matrixd& backMatrix() { if (_mStack.size()) return _mStack.back(); else return _m; }
341
342    osg::Vec3d addVertex(osg::Vec3d v);
343    osg::Vec3d addNormal(osg::Vec3d v);
344    sceneLayer* findOrCreateSceneLayer(const std::string & l)
345    {
346        sceneLayer* ly = _layers[l].get();
347        if (!ly) {
348            ly = new sceneLayer(l);
349            _layers[l] = ly;
350        }
351        return ly;
352    }
353    unsigned short correctedColorIndex(const std::string & l, unsigned short color);
354
355    void addPoint(const std::string & l, unsigned short color, osg::Vec3d & s);
356    void addLine(const std::string & l, unsigned short color, osg::Vec3d & s, osg::Vec3d & e);
357    void addLineStrip(const std::string & l, unsigned short color, std::vector<osg::Vec3d> & vertices);
358    void addLineLoop(const std::string & l, unsigned short color, std::vector<osg::Vec3d> & vertices);
359    void addTriangles(const std::string & l, unsigned short color, std::vector<osg::Vec3d> & vertices, bool inverted=false);
360    void addQuads(const std::string & l, unsigned short color, std::vector<osg::Vec3d> & vertices, bool inverted=false);
361    void addText(const std::string & l, unsigned short color, osg::Vec3d & point, osgText::Text *text);
362
363    osg::Group* scene2osg()
364    {
365        osg::Group* root = NULL;
366        osg::Group* child = NULL;
367        _b.makeMinValid();
368        osg::Vec3 v = osg::Vec3(_b._min.x(), _b._min.y(), _b._min.z());
369        double x = _b._min.x() - (double)v.x();
370        double y = _b._min.y() - (double)v.y();
371        double z = _b._min.z() - (double)v.z();
372        osg::Matrixd m = osg::Matrixd::translate(v);
373        root = new osg::MatrixTransform(m);
374        if (x || y || z) {
375            m = osg::Matrixd::translate(x,y,z);
376            child = new osg::MatrixTransform(m);
377            root->addChild(child);
378        } else {
379            child = root;
380        }
381//            root = mt;
382        for (std::map<std::string, osg::ref_ptr<sceneLayer> >::iterator litr = _layers.begin();
383            litr != _layers.end(); ++litr) {
384            sceneLayer* ly = (*litr).second.get();
385            if (!ly) continue;
386            osg::Group* lg = new osg::Group;
387            lg->setName((*litr).first);
388            child->addChild(lg);
389            ly->layer2osg(lg, _b);
390        }
391        return root;
392    }
393protected:
394    osg::Matrixd                _m;
395    osg::Matrixd                _r;
396    osg::Vec3d                  _t;
397    bounds                      _b;
398    std::map<std::string, osg::ref_ptr<sceneLayer> >        _layers;
399    std::vector<osg::Matrixd>   _mStack;
400    dxfLayerTable*              _layerTable;
401};
402
403#endif
Note: See TracBrowser for help on using the browser.