diff --git a/src/osgPlugins/dxf/dxfEntity.cpp b/src/osgPlugins/dxf/dxfEntity.cpp index f27df73d5..739da693e 100644 --- a/src/osgPlugins/dxf/dxfEntity.cpp +++ b/src/osgPlugins/dxf/dxfEntity.cpp @@ -29,6 +29,7 @@ RegisterEntityProxy g_dxfVertex; RegisterEntityProxy g_dxfPolyline; RegisterEntityProxy g_dxfLWPolyline; RegisterEntityProxy g_dxfInsert; +RegisterEntityProxy g_dxfText; void dxfBasicEntity::assign(dxfFile* , codeValue& cv) @@ -732,7 +733,7 @@ dxfInsert::drawScene(scene* sc) // (with the files I have, the results are equal to Voloview, // and better than Deep Exploration and Lightwave). - // sanity check (useful when no block remains after all SOLIDS, TEXT, ... have been filtered out) + // sanity check (useful when no block remains after all unsupported entities have been filtered out) if (!_block) return; @@ -771,6 +772,147 @@ dxfInsert::drawScene(scene* sc) } +void +dxfText::assign(dxfFile* dxf, codeValue& cv) +{ + switch (cv._groupCode) { + case 1: + _string = cv._string; + break; + case 10: + _point1.x() = cv._double; + break; + case 20: + _point1.y() = cv._double; + break; + case 30: + _point1.z() = cv._double; + break; + case 11: + _point2.x() = cv._double; + break; + case 21: + _point2.y() = cv._double; + break; + case 31: + _point2.z() = cv._double; + break; + case 40: + _height = cv._double; + break; + case 41: + _xscale = cv._double; + break; + case 50: + _rotation = cv._double; + break; + case 71: + _flags = cv._int; + break; + case 72: + _hjustify = cv._int; + break; + case 73: + _vjustify = cv._int; + break; + case 210: + _ocs.x() = cv._double; + break; + case 220: + _ocs.y() = cv._double; + break; + case 230: + _ocs.z() = cv._double; + break; + default: + dxfBasicEntity::assign(dxf, cv); + break; + } +} + + +void +dxfText::drawScene(scene* sc) +{ + osgText::Text::AlignmentType align; + + Matrixd m; + getOCSMatrix(_ocs, m); + sc->ocs(m); + + ref_ptr _text = new osgText::Text; + _text->setText(_string); + + _text->setCharacterSize( _height, 1.0/_xscale ); + _text->setFont("arial.ttf"); + + Quat qr( DegreesToRadians(_rotation), Z_AXIS ); + + if ( _flags & 2 ) qr = Quat( PI, Y_AXIS ) * qr; + if ( _flags & 4 ) qr = Quat( PI, X_AXIS ) * qr; + + _text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION); + _text->setRotation(qr); + + if ( _hjustify != 0 || _vjustify !=0 ) _point1 = _point2; + + switch (_vjustify) { + case 3: + switch (_hjustify) { + case 2: + align = osgText::Text::RIGHT_TOP; + break; + case 1: + align = osgText::Text::CENTER_TOP; + break; + default: + align = osgText::Text::LEFT_TOP; + } + break; + case 2: + switch (_hjustify) { + case 2: + align = osgText::Text::RIGHT_CENTER; + break; + case 1: + align = osgText::Text::CENTER_CENTER; + break; + default: + align = osgText::Text::LEFT_CENTER; + } + break; + case 1: + switch (_hjustify) { + case 2: + align = osgText::Text::RIGHT_BOTTOM; + break; + case 1: + align = osgText::Text::CENTER_BOTTOM; + break; + default: + align = osgText::Text::LEFT_BOTTOM; + } + break; + default: + switch (_hjustify) { + case 2: + align = osgText::Text::RIGHT_BOTTOM_BASE_LINE; + break; + case 1: + align = osgText::Text::CENTER_BOTTOM_BASE_LINE; + break; + default: + align = osgText::Text::LEFT_BOTTOM_BASE_LINE; + } + break; + } + + _text->setAlignment(align); + + sc->addText(getLayer(), _color, _point1, _text.get()); + sc->ocs_clear(); +} + // static void diff --git a/src/osgPlugins/dxf/dxfEntity.h b/src/osgPlugins/dxf/dxfEntity.h index b6591c0f1..18d26643b 100644 --- a/src/osgPlugins/dxf/dxfEntity.h +++ b/src/osgPlugins/dxf/dxfEntity.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "dxfBlock.h" @@ -250,6 +251,40 @@ protected: osg::Vec3d _ocs; }; +class dxfText : public dxfBasicEntity +{ +public: + dxfText() : + _string(""), + _point1(0,0,0), + _point2(0,0,0), + _height(1), + _xscale(1), + _rotation(0), + _flags(0), + _hjustify(0), + _vjustify(0), + _ocs(0,0,1) {} + + virtual ~dxfText() {} + virtual dxfBasicEntity* create() { return new dxfText; } + virtual const char* name() { return "TEXT"; } + virtual void assign(dxfFile* dxf, codeValue& cv); + virtual void drawScene(scene* sc); + +protected: + std::string _string; // 1 + osg::Vec3d _point1; // 10,20,30 + osg::Vec3d _point2; // 11,21,31 + osg::Vec3d _ocs; // 210,220,230 + double _height; // 40 + double _xscale; // 41 + double _rotation; // 50 + int _flags; // 71 + int _hjustify; // 72 + int _vjustify; // 73 +}; + class dxfEntity : public osg::Referenced { public: diff --git a/src/osgPlugins/dxf/scene.cpp b/src/osgPlugins/dxf/scene.cpp index 6075e9617..83478cb52 100644 --- a/src/osgPlugins/dxf/scene.cpp +++ b/src/osgPlugins/dxf/scene.cpp @@ -169,6 +169,30 @@ void scene::addQuads(const std::string & l, unsigned short color, std::vectorfindOrCreateLayer(l); + if (layer->getFrozen()) return; + sceneLayer* ly = findOrCreateSceneLayer(l); + + // Apply the scene settings to the text size and rotation + + Vec3d pscene(addVertex(point)); + Vec3d xvec = addVertex( point + (text->getRotation() * X_AXIS) ) - pscene; + Vec3d yvec = addVertex( point + (text->getRotation() * Y_AXIS) ) - pscene; + text->setCharacterSize( text->getCharacterHeight()*yvec.length(), text->getCharacterAspectRatio()*yvec.length()/xvec.length() ); + + Matrix qm = _r * _m; + Vec3d t, s; + Quat ro, so; + qm.decompose( t, ro, s, so ); + text->setRotation( text->getRotation() * ro ); + + sceneLayer::textInfo ti( correctedColorIndex(l,color), pscene, text ); + ly->_textList.push_back(ti); +} + + unsigned short scene::correctedColorIndex(const std::string & l, unsigned short color) { diff --git a/src/osgPlugins/dxf/scene.h b/src/osgPlugins/dxf/scene.h index d6370daf2..3bc43a600 100644 --- a/src/osgPlugins/dxf/scene.h +++ b/src/osgPlugins/dxf/scene.h @@ -25,6 +25,7 @@ #include #include #include +#include #include class dxfLayerTable; @@ -105,12 +106,12 @@ osg::Geometry* createQuadGeometry( osg::Vec3Array* vertices, osg::Vec3Array* nor } static inline -osg::Geode* createModel(const std::string & name, osg::Geometry* geom) +osg::Geode* createModel(const std::string & name, osg::Drawable* drawable) { - osg::Geode* geom_geode = new osg::Geode; - geom_geode->addDrawable(geom); - geom_geode->setName(name); - return geom_geode; + osg::Geode* geode = new osg::Geode; + geode->addDrawable(drawable); + geode->setName(name); + return geode; } @@ -145,6 +146,7 @@ public: osgLines(root, b); osgTriangles(root, b); osgQuads(root, b); + osgText(root, b); } MapVListList _linestrips; MapVList _lines; @@ -152,7 +154,19 @@ public: MapVList _trinorms; MapVList _quads; MapVList _quadnorms; + + struct textInfo + { + textInfo(short int color, osg::Vec3 point, osgText::Text *text) : + _color(color), _point(point), _text(text) {}; + short int _color; + osg::Vec3d _point; + osg::ref_ptr _text; + }; + typedef std::vector TextList; + TextList _textList; + protected: std::string _name; @@ -236,6 +250,19 @@ protected: } } } + void osgText(osg::Group* root, bounds &b) + { + if (_textList.size()) { + for (TextList::iterator titr = _textList.begin(); + titr != _textList.end(); ++titr) { + titr->_text->setColor(getColor(titr->_color)); + osg::Vec3d v1=titr->_point; + osg::Vec3 v2(v1.x() - b._min.x(), v1.y() - b._min.y(), v1.z() - b._min.z()); + titr->_text->setPosition(v2); + root->addChild(createModel(_name, titr->_text.get())); + } + } + } }; @@ -292,6 +319,8 @@ public: void addLineLoop(const std::string & l, unsigned short color, std::vector & vertices); void addTriangles(const std::string & l, unsigned short color, std::vector & vertices, bool inverted=false); void addQuads(const std::string & l, unsigned short color, std::vector & vertices, bool inverted=false); + void addText(const std::string & l, unsigned short color, osg::Vec3d & point, osgText::Text *text); + osg::Group* scene2osg() { osg::Group* root = NULL;