- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/dxf/DXFWriterNodeVisitor.cpp
r13017 r13041 8 8 * Based on OBJ writer plugin by Ulrich Hertlein 9 9 * 10 * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for 11 * real-time rendering of large 3D photo-realistic models. 10 * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for 11 * real-time rendering of large 3D photo-realistic models. 12 12 * The OSG homepage is http://www.openscenegraph.org/ 13 13 */ … … 19 19 20 20 #include "DXFWriterNodeVisitor.h" 21 21 22 22 // ROBERT - is there any need for a value visitor like this or is it just overkill? 23 23 … … 28 28 class ValueVisitor : public osg::ValueVisitor { 29 29 public: 30 ValueVisitor(std::ostream& fout, const Layer &layer,const osg::Matrix& m = osg::Matrix::identity()) : 31 osg::ValueVisitor(), 32 _fout(fout), 33 _layer(layer), 34 _m(m) 35 { 36 //_applyMatrix = (_m != osg::Matrix::identity()); 37 } 38 39 virtual void apply(osg::Vec3 & inv) 40 { 30 ValueVisitor(std::ostream& fout, const Layer &layer,const osg::Matrix& m = osg::Matrix::identity()) : 31 osg::ValueVisitor(), 32 _fout(fout), 33 _layer(layer), 34 _m(m) 35 { 36 //_applyMatrix = (_m != osg::Matrix::identity()); 37 } 38 39 virtual void apply(osg::Vec3 & inv) 40 { 41 41 osg::Vec3 point(inv) ; 42 point = point * _m; 43 _fout << "0 \nVERTEX\n 8\n"<<_layer._name<<"\n"; 42 point = point * _m; 43 _fout << "0 \nVERTEX\n 8\n"<<_layer._name<<"\n"; 44 44 if ( _layer._color ) { 45 _fout << "62\n"<<_layer._color<<"\n"; 46 } 47 48 _fout <<" 10\n"<<point.x()<<"\n 20\n"<<point.y()<<"\n 30\n"<<point.z()<<"\n"; 49 } 50 45 _fout << "62\n"<<_layer._color<<"\n"; 46 } 47 48 _fout <<" 10\n"<<point.x()<<"\n 20\n"<<point.y()<<"\n 30\n"<<point.z()<<"\n"; 49 } 50 51 51 private: 52 52 … … 55 55 std::ostream& _fout; 56 56 osg::Matrix _m; 57 const Layer _layer; 57 const Layer _layer; 58 58 }; 59 59 */ … … 61 61 /** writes all primitives of a primitive-set out to a stream, decomposes quads to triangles, line-strips to lines etc */ 62 62 class DxfPrimitiveIndexWriter : public osg::PrimitiveIndexFunctor { 63 63 64 64 public: 65 65 DxfPrimitiveIndexWriter(std::ostream& fout,osg::Geometry* geo,const Layer &layer,AcadColor &acad, 66 const osg::Matrix& m = osg::Matrix::identity(),bool writeTriangleAs3DFace = true) : 67 osg::PrimitiveIndexFunctor(), 68 _fout(fout), 66 const osg::Matrix& m = osg::Matrix::identity(),bool writeTriangleAs3DFace = true) : 67 osg::PrimitiveIndexFunctor(), 68 _fout(fout), 69 69 _geo(geo), 70 70 _layer(layer), … … 73 73 _writeTriangleAs3DFace(writeTriangleAs3DFace) 74 74 { 75 76 } 77 75 76 } 77 78 78 virtual void setVertexArray(unsigned int,const osg::Vec2*) {} 79 79 … … 81 81 82 82 virtual void setVertexArray(unsigned int,const osg::Vec4* ) {} 83 83 84 84 virtual void setVertexArray(unsigned int,const osg::Vec2d*) {} 85 85 … … 87 87 88 88 virtual void setVertexArray(unsigned int,const osg::Vec4d* ) {} 89 90 91 void write(unsigned int i,int c) 92 { 93 const osg::Vec3 point = ((osg::Vec3Array *)_geo->getVertexArray())->at(i) * _m; 94 _fout <<c+10<<"\n "<<point.x()<<"\n"<<20+c<<"\n "<<point.y()<<"\n"<<30+c<<"\n "<<point.z()<<"\n"; 95 } 96 97 // operator for triangles 89 90 91 void write(unsigned int i,int c) 92 { 93 const osg::Vec3 point = ((osg::Vec3Array *)_geo->getVertexArray())->at(i) * _m; 94 _fout <<c+10<<"\n "<<point.x()<<"\n"<<20+c<<"\n "<<point.y()<<"\n"<<30+c<<"\n "<<point.z()<<"\n"; 95 } 96 97 // operator for triangles 98 98 void writeTriangle(unsigned int i1, unsigned int i2, unsigned int i3) 99 { 99 { 100 100 if (_writeTriangleAs3DFace) 101 101 { 102 102 _fout << "0 \n3DFACE\n 8\n"<<_layer._name<<"\n"; 103 103 if ( _layer._color ) { 104 _fout << "62\n"<<_layer._color<<"\n"; 104 _fout << "62\n"<<_layer._color<<"\n"; 105 105 } else { 106 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 106 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 107 107 // Acad2000 supports 24bit color but most dxf importers don't 108 //_fout << "420\n"<<DXFWriterNodeVisitor::getNodeRGB(_geo,i1)<<"\n"; 108 //_fout << "420\n"<<DXFWriterNodeVisitor::getNodeRGB(_geo,i1)<<"\n"; 109 109 } 110 110 write(i1,0); 111 111 write(i2,1); 112 112 write(i3,2); 113 write(i1,3); // yes you have to write the first point again 113 write(i1,3); // yes you have to write the first point again 114 114 } 115 115 else … … 117 117 _fout << "0 \nLINE\n 8\n"<<_layer._name<<"\n"; 118 118 if ( _layer._color ) { 119 _fout << "62\n"<<_layer._color<<"\n"; 119 _fout << "62\n"<<_layer._color<<"\n"; 120 120 } else { 121 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 121 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 122 122 } 123 123 write(i1,0); … … 126 126 _fout << "0 \nLINE\n 8\n"<<_layer._name<<"\n"; 127 127 if ( _layer._color ) { 128 _fout << "62\n"<<_layer._color<<"\n"; 128 _fout << "62\n"<<_layer._color<<"\n"; 129 129 } else { 130 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i2))<<"\n"; 130 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i2))<<"\n"; 131 131 } 132 132 write(i2,0); … … 135 135 _fout << "0 \nLINE\n 8\n"<<_layer._name<<"\n"; 136 136 if ( _layer._color ) { 137 _fout << "62\n"<<_layer._color<<"\n"; 137 _fout << "62\n"<<_layer._color<<"\n"; 138 138 } else { 139 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i3))<<"\n"; 139 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i3))<<"\n"; 140 140 } 141 141 write(i3,0); … … 146 146 147 147 // operator for lines 148 void writeLine(unsigned int i1, unsigned int i2) 149 { 148 void writeLine(unsigned int i1, unsigned int i2) 149 { 150 150 _fout << "0 \nLINE\n 8\n"<<_layer._name<<"\n"; 151 151 if ( _layer._color ) { 152 _fout << "62\n"<<_layer._color<<"\n"; 152 _fout << "62\n"<<_layer._color<<"\n"; 153 153 } else { 154 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 154 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 155 155 } 156 156 write(i1,0); 157 157 write(i2,1); 158 158 } 159 159 160 160 // operator for points 161 void writePoint(unsigned int i1) 161 void writePoint(unsigned int i1) 162 162 { 163 163 _fout << "0 \nPOINT\n 8\n"<<_layer._name<<"\n"; 164 164 if ( _layer._color ) { 165 _fout << "62\n"<<_layer._color<<"\n"; 165 _fout << "62\n"<<_layer._color<<"\n"; 166 166 } else { 167 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 168 //_fout << "420\n"<<DXFWriterNodeVisitor::getNodeRGB(_geo,i1)<<"\n"; 169 170 } 171 write(i1,0); 167 _fout << "62\n"<<_acad.findColor(DXFWriterNodeVisitor::getNodeRGB(_geo,i1))<<"\n"; 168 //_fout << "420\n"<<DXFWriterNodeVisitor::getNodeRGB(_geo,i1)<<"\n"; 169 170 } 171 write(i1,0); 172 172 } 173 173 … … 191 191 } 192 192 193 virtual void drawArrays(GLenum mode,GLint first,GLsizei count); 194 193 virtual void drawArrays(GLenum mode,GLint first,GLsizei count); 194 195 195 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) 196 196 { … … 200 200 { 201 201 drawElementsImplementation<GLushort>(mode, count, indices); 202 } 202 } 203 203 204 204 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) 205 205 { 206 206 drawElementsImplementation<GLuint>(mode, count, indices); 207 } 207 } 208 208 209 209 protected: 210 211 template<typename T>void drawElementsImplementation(GLenum mode, GLsizei count, const T* indices) 210 211 template<typename T>void drawElementsImplementation(GLenum mode, GLsizei count, const T* indices) 212 212 { 213 213 if (indices==0 || count==0) return; 214 214 215 typedef const T* IndexPointer; 215 typedef const T* IndexPointer; 216 216 217 217 switch(mode) … … 222 222 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3) 223 223 writeTriangle(*iptr,*(iptr+1),*(iptr+2)); 224 224 225 225 break; 226 226 } … … 271 271 IndexPointer ilast = &indices[count]; 272 272 for(IndexPointer iptr=indices;iptr<ilast;++iptr) 273 273 274 274 { 275 275 writePoint(*iptr); … … 289 289 case(GL_LINE_STRIP): 290 290 { 291 291 292 292 IndexPointer ilast = &indices[count]; 293 293 for(IndexPointer iptr=indices+1;iptr<ilast;iptr+=2) … … 313 313 break; 314 314 } 315 } 316 315 } 316 317 317 private: 318 318 … … 321 321 std::ostream& _fout; 322 322 GLenum _modeCache; 323 std::vector<GLuint> _indexCache; 324 osg::Geometry* _geo; 325 323 std::vector<GLuint> _indexCache; 324 osg::Geometry* _geo; 325 326 326 Layer _layer; 327 327 AcadColor _acad; // needed to lookup new colors … … 387 387 case(GL_POINTS): 388 388 { 389 389 390 390 for(GLsizei i=0;i<count;++i) 391 391 { … … 421 421 } 422 422 default: 423 OSG_WARN << "DXFWriterNodeVisitor :: can't handle mode " << mode << std::endl; 423 OSG_WARN << "DXFWriterNodeVisitor :: can't handle mode " << mode << std::endl; 424 424 break; 425 425 } 426 426 } 427 427 428 428 429 429 // TODO - illegal acad characters 430 std::string DXFWriterNodeVisitor::getLayerName(const std::string& defaultvalue) 430 std::string DXFWriterNodeVisitor::getLayerName(const std::string& defaultvalue) 431 431 { 432 432 433 433 std::string layerName=defaultvalue; 434 434 std::transform(layerName.begin(), layerName.end(), layerName.begin(), toupper); 435 435 436 436 // remove illegal ACAD characters 437 437 size_t found=0; … … 462 462 // if (array == NULL) 463 463 // return; 464 // 465 // ValueVisitor vv(_fout, layer,m); 466 // for(unsigned int i = 0; i < array->getNumElements(); ++i) { 467 // array->accept(i, vv); 464 // 465 // ValueVisitor vv(_fout, layer,m); 466 // for(unsigned int i = 0; i < array->getNumElements(); ++i) { 467 // array->accept(i, vv); 468 468 // } 469 // 469 // 470 470 // OSG_DEBUG << "processArray "<<layer._name<<"\n"; 471 471 // OSG_DEBUG << "# " << array->getNumElements() << " elements written" << std::endl; 472 // 472 // 473 473 //} 474 474 475 void DXFWriterNodeVisitor::processStateSet(osg::StateSet* ss) 475 void DXFWriterNodeVisitor::processStateSet(osg::StateSet* ss) 476 476 { 477 // anything to do if no material/texture? 477 // anything to do if no material/texture? 478 478 479 479 osg::PolygonMode * pm = dynamic_cast<osg::PolygonMode *>(ss->getAttribute(osg::StateAttribute::POLYGONMODE)); … … 484 484 } 485 485 486 void DXFWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) 486 void DXFWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) 487 487 { 488 488 489 489 490 490 // We only want to create a new layer for geometry with something to draw … … 492 492 493 493 processStateSet(_currentStateSet.get()); 494 494 495 495 if ( _firstPass ) { 496 496 // Must have unique layer names … … 499 499 500 500 // if single colour include in header 501 if ( osg::Geometry::BIND_OVERALL == geo->getColorBinding() ) { 501 if ( osg::Geometry::BIND_OVERALL == geo->getColorBinding() ) { 502 502 _layer._color = _acadColor.findColor(getNodeRGB(geo)); // per layer color 503 503 } else if ( osg::Geometry::BIND_OFF== geo->getColorBinding() ) { … … 505 505 } else { 506 506 _layer._color = 0; // per point color 507 } 507 } 508 508 _layers.push_back(_layer); 509 509 … … 511 511 _layer = _layers[_count++]; 512 512 OSG_DEBUG << "writing Layer " << _layer._name << std::endl; 513 if ( geo->getNumPrimitiveSets() ) { 514 for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) 515 { 513 if ( geo->getNumPrimitiveSets() ) { 514 for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) 515 { 516 516 osg::PrimitiveSet* ps = geo->getPrimitiveSet(i); 517 517 DxfPrimitiveIndexWriter pif(_fout, geo,_layer,_acadColor,m,_writeTriangleAs3DFace); 518 518 ps->accept(pif); 519 } 520 } else { 519 } 520 } else { 521 521 // Is array visitor necessary for only dealing with vertex arrays? 522 //processArray(geo->getVertexArray(), _layer,m); 522 //processArray(geo->getVertexArray(), _layer,m); 523 523 if ( geo->getVertexArray() ) { 524 524 osg::Vec3Array* data=static_cast<osg::Vec3Array*>(geo->getVertexArray()); … … 526 526 { 527 527 osg::Vec3 point = data->at(ii) * m; 528 _fout << "0 \nVERTEX\n 8\n"<<_layer._name<<"\n"; 528 _fout << "0 \nVERTEX\n 8\n"<<_layer._name<<"\n"; 529 529 if ( _layer._color ) { 530 _fout << "62\n"<<_layer._color<<"\n"; 531 } else { 532 _fout << "62\n"<<_acadColor.findColor(getNodeRGB(geo,ii))<<"\n"; 530 _fout << "62\n"<<_layer._color<<"\n"; 531 } else { 532 _fout << "62\n"<<_acadColor.findColor(getNodeRGB(geo,ii))<<"\n"; 533 533 } 534 _fout<<" 10\n"<<point.x()<<"\n 20\n"<<point.y()<<"\n 30\n"<<point.z()<<"\n"; 534 _fout<<" 10\n"<<point.x()<<"\n 20\n"<<point.y()<<"\n 30\n"<<point.z()<<"\n"; 535 535 } 536 536 } … … 545 545 { 546 546 547 pushStateSet(node.getStateSet()); 547 pushStateSet(node.getStateSet()); 548 548 osg::Matrix m = osg::computeLocalToWorld(getNodePath()); 549 549 unsigned int count = node.getNumDrawables(); … … 554 554 if ( g != NULL ) 555 555 { 556 pushStateSet(g->getStateSet()); 557 processGeometry(g,m); 556 pushStateSet(g->getStateSet()); 557 processGeometry(g,m); 558 558 popStateSet(g->getStateSet()); 559 559 } … … 561 561 562 562 563 popStateSet(node.getStateSet()); 563 popStateSet(node.getStateSet()); 564 564 } 565 565 … … 570 570 return false; 571 571 } 572 _fout << "999\n written by OpenSceneGraph" << std::endl; 572 _fout << "999\n written by OpenSceneGraph" << std::endl; 573 573 574 574 _fout << "0\nSECTION\n2\nHEADER\n"; 575 575 _fout << "9\n$ACADVER\n1\nAC1006\n"; // specify minimum autocad version AC1006=R10 576 576 577 577 _fout << "9\n$EXTMIN\n10\n"<<bound.center().x()-bound.radius()<<"\n20\n"<<bound.center().y()-bound.radius()<<"\n30\n"<<bound.center().z()-bound.radius()<<"\n"; 578 578 _fout << "9\n$EXTMAX\n10\n"<<bound.center().x()+bound.radius()<<"\n20\n"<<bound.center().y()+bound.radius()<<"\n30\n"<<bound.center().z()+bound.radius()<<"\n"; … … 592 592 593 593 _fout << "0\nSECTION\n2\nENTITIES\n"; 594 _firstPass=false; 594 _firstPass=false; 595 595 _count=0; 596 596 … … 601 601 { 602 602 _fout << "0\nENDSEC\n0\nEOF"; 603 _fout << std::endl; 603 _fout << std::endl; 604 604 } 605 605
