| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | #ifndef DXF_WRITER_NODE_VISITOR_HEADER__ |
|---|
| 20 | #define DXF_WRITER_NODE_VISITOR_HEADER__ |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | #include <string> |
|---|
| 24 | #include <stack> |
|---|
| 25 | #include <sstream> |
|---|
| 26 | |
|---|
| 27 | #include <osg/Notify> |
|---|
| 28 | #include <osg/Node> |
|---|
| 29 | #include <osg/MatrixTransform> |
|---|
| 30 | #include <osg/Geode> |
|---|
| 31 | |
|---|
| 32 | #include <osg/Geometry> |
|---|
| 33 | #include <osg/StateSet> |
|---|
| 34 | #include <osg/Material> |
|---|
| 35 | #include <osg/Texture2D> |
|---|
| 36 | #include <osg/TexGen> |
|---|
| 37 | #include <osg/TexMat> |
|---|
| 38 | |
|---|
| 39 | #include <osgDB/Registry> |
|---|
| 40 | #include <osgDB/ReadFile> |
|---|
| 41 | #include <osgDB/FileUtils> |
|---|
| 42 | #include <osgDB/FileNameUtils> |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | #include <map> |
|---|
| 46 | #include <set> |
|---|
| 47 | #include <iostream> |
|---|
| 48 | struct Layer |
|---|
| 49 | { |
|---|
| 50 | public: |
|---|
| 51 | Layer(const std::string name="",unsigned int color=7) : _name(name),_color(color) { } |
|---|
| 52 | std::string _name; |
|---|
| 53 | unsigned int _color; |
|---|
| 54 | }; |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | #include "aci.h" |
|---|
| 58 | class AcadColor |
|---|
| 59 | { |
|---|
| 60 | public: |
|---|
| 61 | AcadColor() |
|---|
| 62 | { |
|---|
| 63 | int index=10; |
|---|
| 64 | for (int ii=10*3;ii<256*3; ) { |
|---|
| 65 | |
|---|
| 66 | unsigned int red = (int)floor(aci::table[ii++]*255.0f); |
|---|
| 67 | unsigned int green = (int)floor(aci::table[ii++]*255.0f); |
|---|
| 68 | unsigned int blue = (int)floor(aci::table[ii++]*255.0f); |
|---|
| 69 | unsigned int rgb = (red<<16) + (green<<8) + blue; |
|---|
| 70 | _indexColors[rgb]=index++; |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | int findColor(unsigned int rgb) |
|---|
| 79 | { |
|---|
| 80 | int aci = 255; |
|---|
| 81 | ColorMap::const_iterator itr = _indexColors.find(rgb); |
|---|
| 82 | if (itr != _indexColors.end() ) { |
|---|
| 83 | aci = itr->second; |
|---|
| 84 | } else { |
|---|
| 85 | |
|---|
| 86 | aci = nearestColor(rgb); |
|---|
| 87 | |
|---|
| 88 | |
|---|
| 89 | _indexColors[rgb]=aci; |
|---|
| 90 | } |
|---|
| 91 | return aci; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | protected: |
|---|
| 95 | |
|---|
| 96 | void hsv(unsigned int rgb,float &hue,float &sat,float &value) |
|---|
| 97 | { |
|---|
| 98 | int red = rgb>>16; |
|---|
| 99 | int green = (0x0000ff00&rgb)>>8; |
|---|
| 100 | int blue = 0x000000ff&rgb; |
|---|
| 101 | int H=std::max(std::max(red,green),blue); |
|---|
| 102 | int L=std::min(std::min(red,green),blue); |
|---|
| 103 | |
|---|
| 104 | value = (float)H/255.0f; |
|---|
| 105 | sat=(float)(H-L)/(float)H; |
|---|
| 106 | |
|---|
| 107 | if (H==L) { |
|---|
| 108 | hue=0.0; |
|---|
| 109 | }else if (H==red) { |
|---|
| 110 | hue=360.0 + (60.0 * (float)(green-blue)/(float)(H-L)); |
|---|
| 111 | if ( hue > 360 ) { hue-=360; } |
|---|
| 112 | } else if (H==green) { |
|---|
| 113 | hue=120.0 + (60.0 * (float)(blue-red)/(float)(H-L)); |
|---|
| 114 | } else if (H==blue) { |
|---|
| 115 | hue=240.0 + (60.0 * (float)(red-green)/(float)(H-L)); |
|---|
| 116 | } else { |
|---|
| 117 | hue = 0.0; |
|---|
| 118 | } |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | int nearestColor(unsigned int rgb) |
|---|
| 122 | { |
|---|
| 123 | |
|---|
| 124 | float h; |
|---|
| 125 | float s; |
|---|
| 126 | float v; |
|---|
| 127 | hsv(rgb,h,s,v); |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | |
|---|
| 132 | |
|---|
| 133 | int aci=10 + (int)(h/1.5); |
|---|
| 134 | aci -= (aci%10); |
|---|
| 135 | |
|---|
| 136 | if ( v < 0.3 ) { |
|---|
| 137 | aci += 9; |
|---|
| 138 | } else if ( v < 0.5 ) { |
|---|
| 139 | aci += 6; |
|---|
| 140 | } else if ( v < 0.6 ) { |
|---|
| 141 | aci += 4; |
|---|
| 142 | } else if ( v < 0.8 ) { |
|---|
| 143 | aci += 2; |
|---|
| 144 | } else { |
|---|
| 145 | |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | if ( s<0.5 ) { |
|---|
| 149 | aci += 1; |
|---|
| 150 | } |
|---|
| 151 | |
|---|
| 152 | return aci; |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | |
|---|
| 156 | |
|---|
| 157 | protected: |
|---|
| 158 | |
|---|
| 159 | typedef std::map<unsigned int, unsigned char> ColorMap; |
|---|
| 160 | ColorMap _indexColors; |
|---|
| 161 | ColorMap _hueColors; |
|---|
| 162 | }; |
|---|
| 163 | |
|---|
| 164 | class DXFWriterNodeVisitor: public osg::NodeVisitor { |
|---|
| 165 | |
|---|
| 166 | public: |
|---|
| 167 | DXFWriterNodeVisitor(std::ostream& fout) : |
|---|
| 168 | osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), |
|---|
| 169 | _fout(fout), |
|---|
| 170 | _currentStateSet(new osg::StateSet()), |
|---|
| 171 | _firstPass(true), |
|---|
| 172 | _writeTriangleAs3DFace(true) |
|---|
| 173 | { |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | } |
|---|
| 177 | |
|---|
| 178 | static unsigned int getNodeRGB(osg::Geometry *geo,unsigned int index=0) |
|---|
| 179 | { |
|---|
| 180 | osg::Vec4Array* data=static_cast<osg::Vec4Array*>(geo->getColorArray()); |
|---|
| 181 | if ( data && index<data->size() ) { |
|---|
| 182 | return (data->at(index).asABGR())>>8; |
|---|
| 183 | } |
|---|
| 184 | return 0; |
|---|
| 185 | } |
|---|
| 186 | |
|---|
| 187 | |
|---|
| 188 | bool writeHeader(const osg::BoundingSphere &bound); |
|---|
| 189 | void writeFooter(); |
|---|
| 190 | |
|---|
| 191 | void buildColorMap(); |
|---|
| 192 | |
|---|
| 193 | virtual void apply(osg::Geode &node); |
|---|
| 194 | |
|---|
| 195 | virtual void apply(osg::Group &node) |
|---|
| 196 | { |
|---|
| 197 | osg::NodeVisitor::traverse( node ); |
|---|
| 198 | |
|---|
| 199 | } |
|---|
| 200 | |
|---|
| 201 | void traverse (osg::Node &node) |
|---|
| 202 | { |
|---|
| 203 | pushStateSet(node.getStateSet()); |
|---|
| 204 | |
|---|
| 205 | osg::NodeVisitor::traverse( node ); |
|---|
| 206 | |
|---|
| 207 | popStateSet(node.getStateSet()); |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | void pushStateSet(osg::StateSet* ss) |
|---|
| 211 | { |
|---|
| 212 | if (NULL!=ss) { |
|---|
| 213 | |
|---|
| 214 | _stateSetStack.push(_currentStateSet.get()); |
|---|
| 215 | |
|---|
| 216 | |
|---|
| 217 | _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY)); |
|---|
| 218 | _currentStateSet->merge(*ss); |
|---|
| 219 | } |
|---|
| 220 | } |
|---|
| 221 | |
|---|
| 222 | |
|---|
| 223 | void popStateSet(osg::StateSet* ss) |
|---|
| 224 | { |
|---|
| 225 | if (NULL!=ss) { |
|---|
| 226 | |
|---|
| 227 | _currentStateSet = _stateSetStack.top(); |
|---|
| 228 | _stateSetStack.pop(); |
|---|
| 229 | } |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | int getNodeAcadColor(osg::Geometry *geo,int index=0) { return 0;} |
|---|
| 233 | |
|---|
| 234 | protected: |
|---|
| 235 | struct CompareStateSet |
|---|
| 236 | { |
|---|
| 237 | bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const |
|---|
| 238 | { |
|---|
| 239 | return ss1->compare(*ss2, true) < 0; |
|---|
| 240 | } |
|---|
| 241 | }; |
|---|
| 242 | |
|---|
| 243 | |
|---|
| 244 | private: |
|---|
| 245 | |
|---|
| 246 | DXFWriterNodeVisitor& operator = (const DXFWriterNodeVisitor&) { return *this; } |
|---|
| 247 | |
|---|
| 248 | |
|---|
| 249 | void makeGeometryLayer(osg::Geometry* geo); |
|---|
| 250 | |
|---|
| 251 | |
|---|
| 252 | void processGeometry(osg::Geometry* geo, osg::Matrix& m); |
|---|
| 253 | |
|---|
| 254 | |
|---|
| 255 | void processArray(osg::Array* array, const Layer& layer,const osg::Matrix& m = osg::Matrix::identity()); |
|---|
| 256 | |
|---|
| 257 | void processStateSet(osg::StateSet* stateset); |
|---|
| 258 | |
|---|
| 259 | std::string getLayerName(const std::string& defaultValue = ""); |
|---|
| 260 | |
|---|
| 261 | typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack; |
|---|
| 262 | |
|---|
| 263 | |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | std::ostream& _fout; |
|---|
| 267 | std::list<std::string> _nameStack; |
|---|
| 268 | StateSetStack _stateSetStack; |
|---|
| 269 | osg::ref_ptr<osg::StateSet> _currentStateSet; |
|---|
| 270 | |
|---|
| 271 | unsigned int _count; |
|---|
| 272 | std::vector<Layer> _layers; |
|---|
| 273 | bool _firstPass; |
|---|
| 274 | Layer _layer; |
|---|
| 275 | |
|---|
| 276 | bool _writeTriangleAs3DFace; |
|---|
| 277 | |
|---|
| 278 | AcadColor _acadColor; |
|---|
| 279 | |
|---|
| 280 | |
|---|
| 281 | }; |
|---|
| 282 | |
|---|
| 283 | #endif |
|---|