1 /* Importation de fichiers DXF dans OpenSceneGraph (see www.openscenegraph.org)
2 Copyright (C) 2004 by Paul de Repentigny <pdr@grapharchitecture.com>
3 */
4 
5 #include "scene.h"
6 #include "dxfTable.h"
7 #include "aci.h"
8 
9 using namespace osg;
10 using namespace std;
11 
12 
13 osg::Vec4
getColor(unsigned short color)14 sceneLayer::getColor(unsigned short color)
15 {
16     // you're supposed to have a correct color in hand
17     unsigned short r = color * 3;
18     unsigned short g = color * 3 + 1;
19     unsigned short b = color * 3 + 2;
20     Vec4 c(aci::table[r], aci::table[g], aci::table[b], 1.0f);
21     return c;
22 }
23 
24 
scene(dxfLayerTable * lt)25 scene::scene(dxfLayerTable* lt) : _layerTable(lt)
26 {
27     _m.makeIdentity();
28     _r.makeIdentity();
29 }
30 
31 void
setLayerTable(dxfLayerTable * lt)32 scene::setLayerTable(dxfLayerTable* lt)
33 {
34     _layerTable = lt;
35 }
36 
addVertex(Vec3d v)37 Vec3d scene::addVertex(Vec3d v)
38 {
39     v += _t;
40     v = preMultd(_r, v);
41     osg::Matrixd m = osg::Matrixd::translate(v.x(), v.y(), v.z());
42     m = m * _m;
43     Vec3d a = preMultd(m, Vec3d(0,0,0));
44     _b.expandBy(a);
45     return a;
46 }
47 
addNormal(Vec3d v)48 Vec3d scene::addNormal(Vec3d v)
49 {
50     // to do: vertices are not always listed in order. find why.
51     return v;
52 }
53 void
addPoint(const std::string & l,unsigned short color,Vec3d & s)54 scene::addPoint(const std::string & l, unsigned short color, Vec3d & s)
55 {
56     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
57     if (layer->getFrozen()) return;
58     sceneLayer* ly = findOrCreateSceneLayer(l);
59     Vec3d a(addVertex(s));
60     ly->_points[correctedColorIndex(l, color)].push_back(a);
61 }
62 
63 void
addLine(const std::string & l,unsigned short color,Vec3d & s,Vec3d & e)64 scene::addLine(const std::string & l, unsigned short color, Vec3d & s, Vec3d & e)
65 {
66     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
67     if (layer->getFrozen()) return;
68     sceneLayer* ly = findOrCreateSceneLayer(l);
69     Vec3d a(addVertex(s)), b(addVertex(e));
70     ly->_lines[correctedColorIndex(l, color)].push_back(a);
71     ly->_lines[correctedColorIndex(l, color)].push_back(b);
72 }
addLineStrip(const std::string & l,unsigned short color,std::vector<Vec3d> & vertices)73 void scene::addLineStrip(const std::string & l, unsigned short color, std::vector<Vec3d> & vertices)
74 {
75     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
76     if (layer->getFrozen()) return;
77     sceneLayer* ly = findOrCreateSceneLayer(l);
78     std::vector<Vec3d> converted;
79     for (std::vector<Vec3d>::iterator itr = vertices.begin();
80         itr != vertices.end(); ++itr) {
81             converted.push_back(addVertex(*itr));
82     }
83     ly->_linestrips[correctedColorIndex(l, color)].push_back(converted);
84 }
addLineLoop(const std::string & l,unsigned short color,std::vector<Vec3d> & vertices)85 void scene::addLineLoop(const std::string & l, unsigned short color, std::vector<Vec3d> & vertices)
86 {
87     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
88     if (layer->getFrozen()) return;
89     sceneLayer* ly = findOrCreateSceneLayer(l);
90     std::vector<Vec3d> converted;
91     for (std::vector<Vec3d>::iterator itr = vertices.begin();
92         itr != vertices.end(); ++itr) {
93             converted.push_back(addVertex(*itr));
94     }
95     converted.push_back(addVertex(vertices.front()));
96     ly->_linestrips[correctedColorIndex(l, color)].push_back(converted);
97 }
98 
99 
addTriangles(const std::string & l,unsigned short color,std::vector<Vec3d> & vertices,bool inverted)100 void scene::addTriangles(const std::string & l, unsigned short color, std::vector<Vec3d> & vertices, bool inverted)
101 {
102     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
103     if (layer->getFrozen()) return;
104     sceneLayer* ly = findOrCreateSceneLayer(l);
105     for (VList::iterator itr = vertices.begin();
106         itr != vertices.end(); ) {
107             VList::iterator a;
108             VList::iterator b;
109             VList::iterator c;
110             if (inverted) {
111                 c = itr++;
112                 b = itr++;
113                 a = itr++;
114             } else {
115                 a = itr++;
116                 b = itr++;
117                 c = itr++;
118             }
119             if (a != vertices.end() &&
120                 b != vertices.end() &&
121                 c != vertices.end()) {
122                 Vec3d n = ((*b - *a) ^ (*c - *a));
123                 n.normalize();
124                 ly->_trinorms[correctedColorIndex(l, color)].push_back( n );
125                 ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*a));
126                 ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*b));
127                 ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*c));
128             }
129     }
130 }
addQuads(const std::string & l,unsigned short color,std::vector<Vec3d> & vertices,bool inverted)131 void scene::addQuads(const std::string & l, unsigned short color, std::vector<Vec3d> & vertices, bool inverted)
132 {
133     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
134     if (layer->getFrozen()) return;
135 
136     sceneLayer* ly = findOrCreateSceneLayer(l);
137     for (VList::iterator itr = vertices.begin();
138         itr != vertices.end(); ) {
139             VList::iterator a = vertices.end();
140             VList::iterator b = vertices.end();
141             VList::iterator c = vertices.end();
142             VList::iterator d = vertices.end();
143             if (inverted) {
144                 d = itr++;
145                 if (itr != vertices.end())
146                     c = itr++;
147                 if (itr != vertices.end())
148                     b = itr++;
149                 if (itr != vertices.end())
150                     a = itr++;
151             } else {
152                 a = itr++;
153                 if (itr != vertices.end())
154                     b = itr++;
155                 if (itr != vertices.end())
156                     c = itr++;
157                 if (itr != vertices.end())
158                     d = itr++;
159             }
160             if (a != vertices.end() &&
161                 b != vertices.end() &&
162                 c != vertices.end()&&
163                 d != vertices.end()) {
164                 Vec3d n = ((*b - *a) ^ (*c - *a));
165                 n.normalize();
166                 short cindex = correctedColorIndex(l, color);
167                 ly->_quadnorms[cindex].push_back( n );
168                 VList& vl = ly->_quads[cindex];
169                 vl.push_back(addVertex(*a));
170                 vl.push_back(addVertex(*b));
171                 vl.push_back(addVertex(*c));
172                 vl.push_back(addVertex(*d));
173             }
174     }
175 }
176 
177 
addText(const std::string & l,unsigned short color,Vec3d & point,osgText::Text * text)178 void scene::addText(const std::string & l, unsigned short color, Vec3d & point, osgText::Text *text)
179 {
180     dxfLayer* layer = _layerTable->findOrCreateLayer(l);
181     if (layer->getFrozen()) return;
182     sceneLayer* ly = findOrCreateSceneLayer(l);
183 
184     // Apply the scene settings to the text size and rotation
185 
186     Vec3d pscene(addVertex(point));
187     Vec3d xvec = addVertex( point + (text->getRotation() * X_AXIS) ) - pscene;
188     Vec3d yvec = addVertex( point + (text->getRotation() * Y_AXIS) ) - pscene;
189     text->setCharacterSize( text->getCharacterHeight()*yvec.length(), text->getCharacterAspectRatio()*yvec.length()/xvec.length() );
190 
191     Matrix qm = _r * _m;
192     Vec3d t, s;
193     Quat ro, so;
194     qm.decompose( t, ro, s, so );
195     text->setRotation( text->getRotation() * ro );
196 
197     sceneLayer::textInfo ti( correctedColorIndex(l,color), pscene, text );
198     ly->_textList.push_back(ti);
199 }
200 
201 
202 unsigned short
correctedColorIndex(const std::string & l,unsigned short color)203 scene::correctedColorIndex(const std::string & l, unsigned short color)
204 {
205     if (color >= aci::MIN && color <= aci::MAX)
206     {
207         return color;
208     }
209     else if (!color || color == aci::BYLAYER)
210     {
211         dxfLayer* layer = _layerTable->findOrCreateLayer(l);
212         unsigned short lcolor = layer->getColor();
213         if (lcolor >= aci::MIN && lcolor <= aci::MAX)
214         {
215             return lcolor;
216         }
217     }
218     return aci::WHITE;
219 }
220