root/OpenSceneGraph/trunk/src/osgPlugins/dxf/dxfEntity.cpp @ 10081

Revision 10081, 29.3 kB (checked in by robert, 6 years ago)

Fixed warning

  • 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#include "dxfEntity.h"
14#include "dxfFile.h"
15#include "scene.h"
16#include "dxfBlock.h"
17#include "codeValue.h"
18
19#include <osg/io_utils> // just for debugging
20
21using namespace std;
22using namespace osg;
23
24// static
25std::map<std::string, ref_ptr<dxfBasicEntity> > dxfEntity::_registry;
26RegisterEntityProxy<dxf3DFace> g_dxf3DFace;
27RegisterEntityProxy<dxfCircle> g_dxfCircle;
28RegisterEntityProxy<dxfArc> g_dxfArc;
29RegisterEntityProxy<dxfPoint> g_dxfPoint;
30RegisterEntityProxy<dxfLine> g_dxfLine;
31RegisterEntityProxy<dxfVertex> g_dxfVertex;
32RegisterEntityProxy<dxfPolyline> g_dxfPolyline;
33RegisterEntityProxy<dxfLWPolyline> g_dxfLWPolyline;
34RegisterEntityProxy<dxfInsert> g_dxfInsert;
35RegisterEntityProxy<dxfText> g_dxfText;
36
37void 
38dxfBasicEntity::assign(dxfFile* , codeValue& cv)
39{
40    switch (cv._groupCode) {
41        case 8:
42            _layer = cv._string;
43            break;
44        case 62:
45            _color = cv._short;
46            break;
47    }
48}
49
50void
51dxf3DFace::assign(dxfFile* dxf, codeValue& cv)
52{
53    double d = cv._double;
54    switch (cv._groupCode) {
55        case 10:
56        case 11:
57        case 12:
58        case 13:
59            _vertices[cv._groupCode - 10].x() = d;
60            break;
61        case 20:
62        case 21:
63        case 22:
64        case 23:
65            _vertices[cv._groupCode - 20].y() = d;
66            break;
67        case 30:
68        case 31:
69        case 32:
70        case 33:
71            _vertices[cv._groupCode - 30].z() = d;
72            break;
73           
74        default:
75            dxfBasicEntity::assign(dxf, cv);
76            break;
77    }
78}
79
80void
81dxf3DFace::drawScene(scene* sc)
82{
83    std::vector<Vec3d> vlist;
84    short nfaces = 3;
85
86    // Hate to do that, but hey, that's written in the DXF specs:
87    if (_vertices[2] != _vertices[3]) nfaces = 4;
88
89    for (short i = nfaces-1; i >= 0; i--)
90        vlist.push_back(_vertices[i]);
91
92    if (nfaces == 3) {
93        // to do make sure we're % 3
94        sc->addTriangles(getLayer(), _color, vlist);
95    } else if (nfaces == 4) {
96        // to do make sure we're % 4
97        sc->addQuads(getLayer(), _color, vlist);
98    }
99}
100
101void
102dxfVertex::assign(dxfFile* dxf, codeValue& cv)
103{
104    double d = cv._double;
105    // 2005.12.13 pdr: learned today that negative indices mean something and were possible
106   
107    int s = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
108    if ( s < 0 ) s = -s;
109    switch (cv._groupCode) {
110        case 10:
111            _vertex.x() = d;
112            break;
113        case 20:
114            _vertex.y() = d;
115            break;
116        case 30:
117            _vertex.z() = d;
118            break;
119        case 71:
120            _indice1 = s;
121            break;
122        case 72:
123            _indice2 = s;
124            break;
125        case 73:
126            _indice3 = s;
127            break;
128        case 74:
129            _indice4 = s;
130            break;
131           
132        default:
133            dxfBasicEntity::assign(dxf, cv);
134            break;
135    }
136}
137
138void
139dxfCircle::assign(dxfFile* dxf, codeValue& cv)
140{
141    double d = cv._double;
142    //unsigned short s = cv._short;
143    switch (cv._groupCode) {
144        case 10:
145            _center.x() = d;
146            break;
147        case 20:
148            _center.y() = d;
149            break;
150        case 30:
151            _center.z() = d;
152            break;
153        case 40:
154            _radius = d;
155            break;
156        case 210:
157            _ocs.x() = d;
158            break;
159        case 220:
160            _ocs.y() = d;
161            break;
162        case 230:
163            _ocs.z() = d;
164            break;
165        default:
166            dxfBasicEntity::assign(dxf, cv);
167            break;
168    }
169}
170
171void
172dxfCircle::drawScene(scene* sc)
173{
174    Matrixd m;
175    getOCSMatrix(_ocs, m);
176    sc->ocs(m);
177    std::vector<Vec3d> vlist;
178
179    double theta=5.0; // we generate polyline from "spokes" at theta degrees at arc's center
180
181    if (_useAccuracy) {
182        // we generate points on a polyline where each point lies on the arc, thus the maximum error occurs at the midpoint of each line segment where it lies furthest inside the arc
183        // If we divide the segment in half and connect the bisection point to the arc's center, we have two rightangled triangles with
184        // one side=r-maxError, hypotenuse=r, and internal angle at center is half the angle we will step with:
185        double maxError=min(_maxError,_radius); // Avoid offending acos() in the edge case where allowable deviation is greater than radius.
186        double newtheta=acos( (_radius-maxError) / _radius);
187        newtheta=osg::RadiansToDegrees(newtheta)*2.0;
188       
189        // Option to only use the new accuracy code when it would improve on the accuracy of the old method
190        if (_improveAccuracyOnly) {
191            theta=min(newtheta,theta);
192        } else {
193            theta=newtheta;
194        }
195    }
196    theta=osg::DegreesToRadians(theta);
197
198    // We create an anglestep<=theta so that the line's points are evenly distributed around the circle
199    unsigned int numsteps=static_cast<unsigned int>(floor(osg::PI*2/theta));
200    if (numsteps<3) numsteps=3; // Sanity check: minimal representation of a circle is a tri
201    double anglestep=osg::PI*2/numsteps;
202
203    double angle1 = 0.0;
204    Vec3d a = _center;
205    Vec3d b;
206    for(unsigned int r=0;r<=numsteps;r++) {
207        b = a + Vec3d(_radius * (double) sin(angle1), _radius * (double) cos(angle1), 0);
208        angle1 += anglestep;
209        vlist.push_back(b);
210    }
211
212    sc->addLineStrip(getLayer(), _color, vlist); // Should really add LineLoop implementation and save a vertex
213    sc->ocs_clear();
214}
215
216
217void
218dxfArc::assign(dxfFile* dxf, codeValue& cv)
219{
220    double d = cv._double;
221    //unsigned short s = cv._short;
222    switch (cv._groupCode) {
223        case 10:
224            _center.x() = d;
225            break;
226        case 20:
227            _center.y() = d;
228            break;
229        case 30:
230            _center.z() = d;
231            break;
232        case 40:
233            _radius = d;
234            break;
235        case 50:
236            _startAngle = d;
237            break;
238        case 51:
239            _endAngle = d;
240            break;
241        case 210:
242            _ocs.x() = d;
243            break;
244        case 220:
245            _ocs.y() = d;
246            break;
247        case 230:
248            _ocs.z() = d;
249            break;
250        default:
251            dxfBasicEntity::assign(dxf, cv);
252            break;
253    }
254}
255
256void
257dxfArc::drawScene(scene* sc)
258{
259    Matrixd m;
260    getOCSMatrix(_ocs, m);
261    sc->ocs(m);
262    std::vector<Vec3d> vlist;
263    double end;
264    double start;
265    if (_startAngle > _endAngle) {
266        start = _startAngle;
267        end = _endAngle + 360;
268    } else {
269        start = _startAngle;
270        end = _endAngle;
271    }
272
273    double theta=5.0; // we generate polyline from "spokes" at theta degrees at arc's center
274
275    if (_useAccuracy) {
276        // we generate points on a polyline where each point lies on the arc, thus the maximum error occurs at the midpoint of each line segment where it lies furthest inside the arc
277        // If we divide the segment in half and connect the bisection point to the arc's center, we have two rightangled triangles with
278        // one side=r-maxError, hypotenuse=r, and internal angle at center is half the angle we will step with:
279        double maxError=min(_maxError,_radius); // Avoid offending acos() in the edge case where allowable deviation is greater than radius.
280        double newtheta=acos( (_radius-maxError) / _radius);
281        newtheta=osg::RadiansToDegrees(newtheta)*2.0;
282        //cout<<"r="<<_radius<<" _me="<<_maxError<<" (_radius-_maxError)="<<(_radius-_maxError)<<" newtheta="<<newtheta<<endl;
283        // Option to only use the new accuracy code when it would improve on the accuracy of the old method
284        if (_improveAccuracyOnly) {
285            theta=min(newtheta,theta);
286        } else {
287            theta=newtheta;
288        }
289    }
290
291    double angle_step = DegreesToRadians(end - start);
292    int numsteps = (int)((end - start)/theta);
293    //cout<<"arc theta="<<osg::RadiansToDegrees(theta)<<" end="<<end<<" start="<<start<<" numsteps="<<numsteps<<" e-s/theta="<<((end-start)/theta)<<" end-start="<<(end-start)<<endl;
294    if (numsteps * theta < (end - start)) numsteps++;
295    numsteps=max(numsteps,2); // Whatever else, minimum representation of an arc is a straightline
296    angle_step /=  (double) numsteps;
297    end = DegreesToRadians((-_startAngle)+90.0);
298    start = DegreesToRadians((-_endAngle)+90.0);
299    double angle1 = start;
300   
301    Vec3d a = _center;
302    Vec3d b;
303
304    for (int r = 0; r <= numsteps; r++)
305    {
306        b = a + Vec3d(_radius * (double) sin(angle1), _radius * (double) cos(angle1), 0);
307        angle1 += angle_step;
308        vlist.push_back(b);
309    }
310
311
312    sc->addLineStrip(getLayer(), _color, vlist);
313    sc->ocs_clear();
314}
315
316void
317dxfLine::assign(dxfFile* dxf, codeValue& cv)
318{
319    double d = cv._double;
320    //unsigned short s = cv._short;
321    switch (cv._groupCode) {
322        case 10:
323            _a.x() = d;
324            break;
325        case 20:
326            _a.y() = d;
327            break;
328        case 30:
329            _a.z() = d;
330            break;
331        case 11:
332            _b.x() = d;
333            break;
334        case 21:
335            _b.y() = d;
336            break;
337        case 31:
338            _b.z() = d;
339            break;
340        case 210:
341            _ocs.x() = d;
342            break;
343        case 220:
344            _ocs.y() = d;
345            break;
346        case 230:
347            _ocs.z() = d;
348            break;
349        default:
350            dxfBasicEntity::assign(dxf, cv);
351            break;
352    }
353}
354
355void
356dxfLine::drawScene(scene* sc)
357{
358    Matrixd m;
359    getOCSMatrix(_ocs, m);
360    // don't know why this doesn't work
361//    sc->ocs(m);
362    sc->addLine(getLayer(), _color, _b, _a);
363//    static long lcount = 0;
364//    std::cout << ++lcount << " ";
365//    sc->ocs_clear();
366}
367void
368dxfPoint::assign(dxfFile* dxf, codeValue& cv)
369{
370    double d = cv._double;
371    //unsigned short s = cv._short;
372    switch (cv._groupCode) {
373        case 10:
374            _a.x() = d;
375            break;
376        case 20:
377            _a.y() = d;
378            break;
379        case 30:
380            _a.z() = d;
381            break;
382        default:
383            dxfBasicEntity::assign(dxf, cv);
384            break;
385    }
386}
387
388void
389dxfPoint::drawScene(scene* sc)
390{
391    Matrixd m;
392    getOCSMatrix(_ocs, m);
393    sc->addPoint(getLayer(), _color,_a);
394}
395
396void 
397dxfPolyline::assign(dxfFile* dxf, codeValue& cv)
398{
399    string s = cv._string;
400    if (cv._groupCode == 0) {
401        if (s == "VERTEX") {
402            _currentVertex = new dxfVertex;
403            _vertices.push_back(_currentVertex);
404        }
405    } else if (_currentVertex) {
406        _currentVertex->assign(dxf, cv);
407
408        if ((_flag & 64 /*i.e. polymesh*/) &&
409            (cv._groupCode == 70 /*i.e. vertex flag*/) &&
410            (cv._int && 128 /*i.e. vertex is actually a face*/))
411            _indices.push_back(_currentVertex); // Add the index only if _currentvertex is actually an index
412    } else {
413        double d = cv._double;
414        switch (cv._groupCode) {
415            case 10:
416                // dummy
417                break;
418            case 20:
419                // dummy
420                break;
421            case 30:
422                _elevation = d; // what is elevation?
423                break;
424            case 70:
425                _flag = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
426                break;
427            case 71:
428                // Meaningful only when _surfacetype == 6, don' trust it for polymeshes.
429                // From the docs :
430                // "The 71 group specifies the number of vertices in the mesh, and the 72 group
431                // specifies the number of faces. Although these counts are correct for all meshes
432                // created with the PFACE command, applications are not required to place correct
433                // values in these fields.)"
434                // Amusing isn't it ?
435                _mcount = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
436                break;
437            case 72:
438                // Meaningful only when _surfacetype == 6, don' trust it for polymeshes.
439                // From the docs :
440                // "The 71 group specifies the number of vertices in the mesh, and the 72 group
441                // specifies the number of faces. Although these counts are correct for all meshes
442                // created with the PFACE command, applications are not required to place correct
443                // values in these fields.)"
444                // Amusing isn't it ?
445                _ncount = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
446                break;
447            case 73:
448                _mdensity = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
449                break;
450            case 74:
451                _ndensity = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
452                break;
453            case 75:
454                _surfacetype = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
455                break;
456            case 210:
457                _ocs.x() = d;
458                break;
459            case 220:
460                _ocs.y() = d;
461                break;
462            case 230:
463                _ocs.z() = d;
464                break;
465            default:
466                dxfBasicEntity::assign(dxf, cv);
467                break;
468        }
469    }
470}
471
472
473void
474dxfPolyline::drawScene(scene* sc)
475{
476    Matrixd m;
477    getOCSMatrix(_ocs, m);
478    sc->ocs(m);
479    std::vector<Vec3d> vlist;
480    std::vector<Vec3d> qlist;
481    Vec3d a, b, c, d;
482    bool invert_order = false;
483    if (_flag & 16) {
484        std::vector<Vec3d> nlist;
485        Vec3d nr;
486        bool nset = false;
487        //dxfVertex* v = NULL;
488        unsigned int ncount;
489        unsigned int mcount;
490        if (_surfacetype == 6) {
491            // I dont have examples of type 5 and 8, but they may be the same as 6
492            mcount = _mdensity;
493            ncount = _ndensity;
494        } else {
495            mcount = _mcount;
496            ncount = _ncount;
497        }
498        for (unsigned int n = 0; n < ncount-1; n++) {
499            for (unsigned int m = 1; m < mcount; m++) {
500                // 0
501                a = _vertices[(m-1)*ncount+n].get()->getVertex();
502                // 1
503                b = _vertices[m*ncount+n].get()->getVertex();
504                // 3
505                c = _vertices[(m)*ncount+n+1].get()->getVertex();
506                // 2
507                d = _vertices[(m-1)*ncount+n+1].get()->getVertex();
508                if (a == b ) {
509                    vlist.push_back(a);
510                    vlist.push_back(c);
511                    vlist.push_back(d);
512                    b = c;
513                    c = d;
514                } else if (c == d) {
515                    vlist.push_back(a);
516                    vlist.push_back(b);
517                    vlist.push_back(c);
518                } else {
519                    qlist.push_back(a);
520                    qlist.push_back(b);
521                    qlist.push_back(c);
522                    qlist.push_back(d);
523                }
524                if (!nset) {
525                    nset = true;
526                    nr = (b - a) ^ (c - a);
527                    nr.normalize();
528                }
529                nlist.push_back(a);
530            }
531        }
532        if (_flag & 1) {
533            for (unsigned int n = 0; n < ncount-1; n++) {
534                // 0
535                a = _vertices[(mcount-1)*ncount+n].get()->getVertex();
536                // 1
537                b = _vertices[0*ncount+n].get()->getVertex();
538                // 3
539                c = _vertices[(0)*ncount+n+1].get()->getVertex();
540                // 2
541                d = _vertices[(mcount-1)*ncount+n+1].get()->getVertex();
542                if (a == b ) {
543                    vlist.push_back(a);
544                    vlist.push_back(c);
545                    vlist.push_back(d);
546                    b = c;
547                    c = d;
548                } else if (c == d) {
549                    vlist.push_back(a);
550                    vlist.push_back(b);
551                    vlist.push_back(c);
552                } else {
553                    qlist.push_back(a);
554                    qlist.push_back(b);
555                    qlist.push_back(c);
556                    qlist.push_back(d);
557                }
558                nlist.push_back(a);
559            }
560        }
561        if (_flag & 32) {
562            for (unsigned int m = 1; m < mcount; m++) {
563                // 0
564                a = _vertices[(m-1)*ncount+(ncount-1)].get()->getVertex();
565                // 1
566                b = _vertices[m*ncount+(ncount-1)].get()->getVertex();
567                // 3
568                c = _vertices[(m)*ncount].get()->getVertex();
569                // 2
570                d = _vertices[(m-1)*ncount].get()->getVertex();
571                if (a == b ) {
572                    vlist.push_back(a);
573                    vlist.push_back(c);
574                    vlist.push_back(d);
575                    b = c;
576                    c = d;
577                } else if (c == d) {
578                    vlist.push_back(a);
579                    vlist.push_back(b);
580                    vlist.push_back(c);
581                } else {
582                    qlist.push_back(a);
583                    qlist.push_back(b);
584                    qlist.push_back(c);
585                    qlist.push_back(d);
586                }
587                nlist.push_back(a);
588            }
589        }
590
591        // a naive attempt to determine vertex ordering
592        VList::iterator itr = nlist.begin();
593        Vec3d lastn = (*itr++);
594        double bad_c = 0;
595        double good_c = 0;
596        long bad=0,good=0;
597        for (; itr != nlist.end(); ) {
598            ++itr;
599            if ((*itr)== lastn) continue;
600            Vec3d diff = ((*itr)-lastn);
601            diff.normalize();
602            float dot = diff * nr;
603            if (dot > 0.0) {
604                bad_c += dot;
605                ++bad;
606            } else {
607                ++good;
608                good_c += dot;
609            }
610        }
611        if (bad > good) {
612            invert_order = true;
613        }
614
615        if (qlist.size())
616            sc->addQuads(getLayer(), _color, qlist, invert_order);
617        if (vlist.size())
618            sc->addTriangles(getLayer(), _color, vlist, invert_order);
619
620    } else if (_flag & 64) {
621        unsigned short _facetype = 3;
622
623        for (unsigned int i = 0; i < _indices.size(); i++) {
624            dxfVertex* vindice = _indices[i].get();
625            if (!vindice) continue;
626            if (vindice->getIndice4()) {
627                _facetype = 4;
628                d = _vertices[vindice->getIndice4()-1].get()->getVertex();
629            } else {
630                _facetype = 3;
631            }
632            if (vindice->getIndice3()) {
633                c = _vertices[vindice->getIndice3()-1].get()->getVertex();
634            } else {
635                c = vindice->getVertex(); // Vertex not indexed. Use as is
636            }
637            if (vindice->getIndice2()) {
638                b = _vertices[vindice->getIndice2()-1].get()->getVertex();
639            } else {
640                b = vindice->getVertex(); // Vertex not indexed. Use as is
641            }
642            if (vindice->getIndice1()) {
643                a = _vertices[vindice->getIndice1()-1].get()->getVertex();
644            } else {
645                a = vindice->getVertex(); // Vertex not indexed. Use as is
646            }
647            if (_facetype == 4) {
648                qlist.push_back(d);
649                qlist.push_back(c);
650                qlist.push_back(b);
651                qlist.push_back(a);
652            } else {
653                // 2005.12.13 pdr: vlist! not qlist!
654                vlist.push_back(c);
655                vlist.push_back(b);
656                vlist.push_back(a);
657            }
658        }
659        if (vlist.size())
660            sc->addTriangles(getLayer(), _color, vlist);
661        if (qlist.size())
662            sc->addQuads(getLayer(), _color, qlist);
663        // is there a flag 1 or 32 for 64?
664    } else {
665        // simple polyline?
666        for (int i = _vertices.size()-1; i >= 0; i--)
667            vlist.push_back(_vertices[i]->getVertex());
668        if (_flag & 1) {
669//            std::cout << "line loop " << _vertices.size() << std::endl;
670            sc->addLineLoop(getLayer(), _color, vlist);
671        } else {
672//            std::cout << "line strip " << _vertices.size() << std::endl;
673            sc->addLineStrip(getLayer(), _color, vlist);
674        }
675
676    }
677    sc->ocs_clear();
678}
679
680void 
681dxfLWPolyline::assign(dxfFile* dxf, codeValue& cv)
682{
683    string s = cv._string;
684
685    double d = cv._double;
686    switch (cv._groupCode) {
687        case 10:
688            _lastv.x() = d;
689            // x
690            break;
691        case 20:
692            _lastv.y() = d;
693            _lastv.z() = _elevation;
694            _vertices.push_back ( _lastv );
695            // y -> on shoot
696            break;
697        case 38:
698            _elevation = d; // what is elevation?
699            break;
700        case 70:
701            _flag = cv._int; // 2005.12.13 pdr: group codes [70,78] now signed int.
702            break;
703        case 90:
704            _vcount = cv._short;
705            break;
706        case 210:
707            _ocs.x() = d;
708            break;
709        case 220:
710            _ocs.y() = d;
711            break;
712        case 230:
713            _ocs.z() = d;
714            break;
715        default:
716            dxfBasicEntity::assign(dxf, cv);
717            break;
718    }
719}
720
721
722void
723dxfLWPolyline::drawScene(scene* sc)
724{
725//    if (getLayer() != "UDF2" && getLayer() != "ENGINES") return;
726//    if (!(_flag & 16)) return;
727    Matrixd m;
728    getOCSMatrix(_ocs, m);
729    sc->ocs(m);
730    if (_flag & 1) {
731//        std::cout << "lwpolyline line loop " << _vertices.size() << std::endl;
732        sc->addLineLoop(getLayer(), _color, _vertices);
733    } else {
734//        std::cout << "lwpolyline line strip " << _vertices.size() << std::endl;
735        sc->addLineStrip(getLayer(), _color, _vertices);
736    }
737    sc->ocs_clear();
738}
739
740void
741dxfInsert::assign(dxfFile* dxf, codeValue& cv)
742{
743    string s = cv._string;
744    if (_done || (cv._groupCode == 0 && s != "INSERT")) {
745        _done = true;
746        return;
747    }
748    if (cv._groupCode == 2 && !_block) {
749        _blockName = s;
750        _block = dxf->findBlock(s);
751    } else {
752        double d = cv._double;
753        switch (cv._groupCode) {
754            case 10:
755                _point.x() = d;
756                break;
757            case 20:
758                _point.y() = d;
759                break;
760            case 30:
761                _point.z() = d;
762                break;
763            case 41:
764                _scale.x() = d;
765                break;
766            case 42:
767                _scale.y() = d;
768                break;
769            case 43:
770                _scale.z() = d;
771                break;
772            case 50:
773                _rotation = d;
774                break;
775            case 210:
776                _ocs.x() = d;
777                break;
778            case 220:
779                _ocs.y() = d;
780                break;
781            case 230:
782                _ocs.z() = d;
783                break;
784            default:
785                dxfBasicEntity::assign(dxf, cv);
786                break;
787        }
788    }
789}
790
791/// hum. read the doc, then come back here. then try to figure.
792void
793dxfInsert::drawScene(scene* sc)
794{
795    // INSERTs can be nested. So pull the current matrix
796    // and push it back after we fill our context
797    // This is a snapshot in time. I will rewrite all this to be cleaner,
798    // but for now, it seems working fine
799    // (with the files I have, the results are equal to Voloview,
800    // and better than Deep Exploration and Lightwave).
801   
802    // sanity check (useful when no block remains after all unsupported entities have been filtered out)
803    if (!_block)
804        return;
805
806    Matrixd back = sc->backMatrix();
807    Matrixd m;
808    m.makeIdentity();
809    sc->pushMatrix(m, true);
810    Vec3d trans = _block->getPosition();
811    sc->blockOffset(-trans);
812    if (_rotation) {
813        sc->pushMatrix(Matrixd::rotate(osg::DegreesToRadians(_rotation), 0,0,1));
814    }
815    sc->pushMatrix(Matrixd::scale(_scale.x(), _scale.y(), _scale.z()));
816    sc->pushMatrix(Matrixd::translate(_point.x(), _point.y(), _point.z()));
817    getOCSMatrix(_ocs, m);
818    sc->pushMatrix(m);
819    sc->pushMatrix(back);
820
821    EntityList& l = _block->getEntityList();
822    for (EntityList::iterator itr = l.begin(); itr != l.end(); ++itr) {
823        dxfBasicEntity* e = (*itr)->getEntity();
824        if (e) {
825            e->drawScene(sc);
826        }
827    }
828
829    sc->popMatrix(); // ocs
830    sc->popMatrix(); // translate
831    sc->popMatrix(); // scale
832    if (_rotation) {
833        sc->popMatrix(); // rotate
834    }
835    sc->popMatrix(); // identity
836    sc->popMatrix(); // back
837    sc->blockOffset(Vec3d(0,0,0));
838
839}
840
841void 
842dxfText::assign(dxfFile* dxf, codeValue& cv)
843{
844    switch (cv._groupCode) {
845        case 1:
846            _string = cv._string;
847            break;
848        case 10:
849            _point1.x() = cv._double;
850            break;
851        case 20:
852            _point1.y() = cv._double;
853            break;
854        case 30:
855            _point1.z() = cv._double;
856            break;
857        case 11:
858            _point2.x() = cv._double;
859            break;
860        case 21:
861            _point2.y() = cv._double;
862            break;
863        case 31:
864            _point2.z() = cv._double;
865            break;
866        case 40:
867            _height = cv._double;
868            break;
869        case 41:
870            _xscale = cv._double;
871            break;
872        case 50:
873            _rotation = cv._double;
874            break;
875        case 71:
876            _flags = cv._int;
877            break;
878        case 72:
879            _hjustify = cv._int;
880            break;
881        case 73:
882            _vjustify = cv._int;
883            break;
884        case 210:
885            _ocs.x() = cv._double;
886            break;
887        case 220:
888            _ocs.y() = cv._double;
889            break;
890        case 230:
891            _ocs.z() = cv._double;
892            break;
893        default:
894            dxfBasicEntity::assign(dxf, cv);
895            break;
896    }
897}
898
899
900void
901dxfText::drawScene(scene* sc)
902{
903    osgText::Text::AlignmentType align;
904
905    Matrixd m;
906    getOCSMatrix(_ocs, m);
907    sc->ocs(m);
908
909    ref_ptr<osgText::Text> _text = new osgText::Text;
910    _text->setText(_string);
911
912    _text->setCharacterSize( _height, 1.0/_xscale );
913    _text->setFont("arial.ttf");
914     
915    Quat qr( DegreesToRadians(_rotation), Z_AXIS );
916   
917    if ( _flags & 2 ) qr = Quat( PI, Y_AXIS ) * qr;
918    if ( _flags & 4 ) qr = Quat( PI, X_AXIS ) * qr;
919   
920    _text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
921    _text->setRotation(qr);
922   
923    if ( _hjustify != 0 || _vjustify !=0 ) _point1 = _point2;
924   
925    switch (_vjustify) {
926    case 3:
927        switch (_hjustify) {
928        case 2:
929            align = osgText::Text::RIGHT_TOP;
930            break;
931        case 1:
932            align = osgText::Text::CENTER_TOP;
933            break;
934        default:
935            align = osgText::Text::LEFT_TOP;
936        }
937        break;
938    case 2:
939        switch (_hjustify) {
940        case 2:
941            align = osgText::Text::RIGHT_CENTER;
942            break;
943        case 1:
944            align = osgText::Text::CENTER_CENTER;
945            break;
946        default:
947            align = osgText::Text::LEFT_CENTER;
948        }
949        break;
950    case 1:
951        switch (_hjustify) {
952        case 2:
953            align = osgText::Text::RIGHT_BOTTOM;
954            break;
955        case 1:
956            align = osgText::Text::CENTER_BOTTOM;
957            break;
958        default:
959            align = osgText::Text::LEFT_BOTTOM;
960        }
961        break;
962    default:
963        switch (_hjustify) {
964        case 2:
965            align = osgText::Text::RIGHT_BOTTOM_BASE_LINE;
966            break;
967        case 1:
968            align = osgText::Text::CENTER_BOTTOM_BASE_LINE;
969            break;
970        default:
971            align = osgText::Text::LEFT_BOTTOM_BASE_LINE;
972        }
973        break;
974    }
975   
976    _text->setAlignment(align);
977   
978    sc->addText(getLayer(), _color, _point1, _text.get());
979    sc->ocs_clear();
980}
981
982
983// static
984void 
985dxfEntity::registerEntity(dxfBasicEntity* entity)
986{
987    _registry[entity->name()] = entity;
988}
989
990// static
991void 
992dxfEntity::unregisterEntity(dxfBasicEntity* entity)
993{
994    map<string, ref_ptr<dxfBasicEntity > >::iterator itr = _registry.find(entity->name());
995    if (itr != _registry.end()) {
996        _registry.erase(itr);
997    }
998}
999
1000void dxfEntity::drawScene(scene* sc)
1001{
1002    for (std::vector<ref_ptr<dxfBasicEntity > >::iterator itr = _entityList.begin();
1003        itr != _entityList.end(); ++itr) {
1004            (*itr)->drawScene(sc);
1005    }
1006}
1007
1008void 
1009dxfEntity::assign(dxfFile* dxf, codeValue& cv)
1010{
1011    string s = cv._string;
1012    if (cv._groupCode == 66 && !(_entity && string("TABLE") == _entity->name())) {
1013        // The funny thing here. Group code 66 has been called 'obsoleted'
1014        // for a POLYLINE. But not for an INSERT. Moreover, a TABLE
1015        // can have a 66 for... an obscure bottom cell color value.
1016        // I decided to rely on the presence of the 66 code for
1017        // the POLYLINE. If you find a better alternative,
1018        // contact me, or correct this code
1019        // and post the correction to osg mailing list
1020        _seqend = true;
1021    } else if (_seqend && cv._groupCode == 0 && s == "SEQEND") {
1022        _seqend = false;
1023//        cout << "... off" << endl;
1024    } else if (_entity) {
1025        _entity->assign(dxf, cv);
1026    }
1027}
Note: See TracBrowser for help on using the browser.