Files
OpenSceneGraph/src/osgPlugins/dxf/dxfEntity.h
2016-06-08 09:57:02 +01:00

392 lines
12 KiB
C++

/* dxfReader for OpenSceneGraph Copyright (C) 2005 by GraphArchitecture ( grapharchitecture.com )
* Programmed by Paul de Repentigny <pdr@grapharchitecture.com>
*
* OpenSceneGraph is (C) 2004 Robert Osfield
*
* This library is provided as-is, without support of any kind.
*
* Read DXF docs or OSG docs for any related questions.
*
* You may contact the author if you have suggestions/corrections/enhancements.
*/
#ifndef DXF_ENTITY
#define DXF_ENTITY 1
#include <vector>
#include <string>
#include <iostream>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/Vec3d>
#include <osg/Node>
#include <osg/Matrixd>
#include <osgText/Text>
#include "dxfBlock.h"
class scene;
class codeValue;
class dxfFile;
static inline void
getOCSMatrix(const osg::Vec3d& ocs, osg::Matrixd& m)
{
static const double one_64th = 1.0/64.0;
m.makeIdentity();
if (ocs == osg::Vec3d(0,0,1)) return;
osg::Vec3d ax(1,0,0), ay(0,1,0), az(0,0,1);
osg::Vec3d ocsaxis(ocs);
ocsaxis.normalize();
if (fabs(ocsaxis.x()) < one_64th && fabs(ocsaxis.y()) < one_64th) {
ax = ay ^ ocsaxis;
} else {
ax = az ^ ocsaxis;
}
ax.normalize();
ay = ocsaxis ^ ax;
ay.normalize();
m = osg::Matrixd( ax.x(), ax.y(), ax.z(), 0,
ay.x(), ay.y(), ay.z(), 0,
ocsaxis.x(), ocsaxis.y(), ocsaxis.z(), 0,
0,0,0,1);
// m = m.inverse(m);
}
class dxfBasicEntity : public osg::Referenced
{
public:
dxfBasicEntity() : _color(0), _useAccuracy(false), _maxError(0.01), _improveAccuracyOnly(false) {}
virtual ~dxfBasicEntity() {}
virtual dxfBasicEntity* create() = 0;
virtual const char* name() = 0;
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene*) {}
const std::string getLayer() const { return _layer; }
void setAccuracy(bool useAccuracy,double maxError,bool improveAccuracyOnly) {
_useAccuracy=useAccuracy;
_maxError=maxError;
_improveAccuracyOnly=improveAccuracyOnly;
}
protected:
std::string _layer;
unsigned short _color;
bool _useAccuracy; // true to specify a maximum deviation for curve rendering
double _maxError; // the error in model units, if _useAccuracy==true
bool _improveAccuracyOnly;// if true only use _maxError where it would increase the quality of curves compared to the previous algorithm
};
class dxfCircle : public dxfBasicEntity
{
public:
dxfCircle() : _radius(0), _ocs(0,0,1) {}
virtual ~dxfCircle() {}
virtual dxfBasicEntity* create() { // we create a copy which uses our accuracy settings
dxfBasicEntity* circle=new dxfCircle;
circle->setAccuracy(_useAccuracy,_maxError,_improveAccuracyOnly);
return circle;
}
virtual const char* name() { return "CIRCLE"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
osg::Vec3d _center;
double _radius;
osg::Vec3d _ocs;
};
class dxfArc : public dxfBasicEntity
{
public:
dxfArc() : _radius(0), _startAngle(0), _endAngle(360), _ocs(0,0,1) {}
virtual ~dxfArc() {}
virtual dxfBasicEntity* create() { // we create a copy which uses our accuracy settings
dxfBasicEntity* arc=new dxfArc;
arc->setAccuracy(_useAccuracy,_maxError,_improveAccuracyOnly);
//std::cout<<"dxfArc::create with _useAccuracy="<<_useAccuracy<<" maxError="<<_maxError<<" improveAccuracyOnly="<<_improveAccuracyOnly<<std::endl;
return arc;
}
virtual const char* name() { return "ARC"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
osg::Vec3d _center;
double _radius;
double _startAngle;
double _endAngle;
osg::Vec3d _ocs;
};
class dxfPoint : public dxfBasicEntity
{
public:
dxfPoint() : _ocs(0,0,1) {}
virtual ~dxfPoint() {}
virtual dxfBasicEntity* create() { return new dxfPoint; }
virtual const char* name() { return "POINT"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
osg::Vec3d _a;
//osg::Vec3d _b;
osg::Vec3d _ocs;
};
class dxfLine : public dxfBasicEntity
{
public:
dxfLine() : _ocs(0,0,1) {}
virtual ~dxfLine() {}
virtual dxfBasicEntity* create() { return new dxfLine; }
virtual const char* name() { return "LINE"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
osg::Vec3d _a;
osg::Vec3d _b;
osg::Vec3d _ocs;
};
class dxf3DFace : public dxfBasicEntity
{
public:
dxf3DFace()
{
_vertices[0] = osg::Vec3d(0,0,0);
_vertices[1] = osg::Vec3d(0,0,0);
_vertices[2] = osg::Vec3d(0,0,0);
_vertices[3] = osg::Vec3d(0,0,0);
}
virtual ~dxf3DFace() {}
virtual dxfBasicEntity* create() { return new dxf3DFace; }
virtual const char* name() { return "3DFACE"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
osg::Vec3d _vertices[4];
};
class dxfVertex : public dxfBasicEntity
{
public:
dxfVertex() : _vertex(osg::Vec3d(0,0,0)), _indice1(0), _indice2(0), _indice3(0), _indice4(0) {}
virtual ~dxfVertex() {}
virtual dxfBasicEntity* create() { return new dxfVertex; }
virtual const char* name() { return "VERTEX"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
void getVertex(double &x, double &y, double &z) { x=_vertex.x();y=_vertex.y();z=_vertex.z(); }
const osg::Vec3d& getVertex() const { return _vertex; }
unsigned int getIndice1() const { return _indice1; }
unsigned int getIndice2() const { return _indice2; }
unsigned int getIndice3() const { return _indice3; }
unsigned int getIndice4() const { return _indice4; }
protected:
osg::Vec3d _vertex;
unsigned int _indice1, _indice2, _indice3, _indice4;
};
class dxfPolyline : public dxfBasicEntity
{
public:
dxfPolyline() : _currentVertex(NULL),
_elevation(0.0),
_flag(0),
_mcount(0),
_ncount(0),
_nstart(0),
_nend(0),
_ocs(osg::Vec3d(0,0,1)),
_mdensity(0),
_ndensity(0),
_surfacetype(0)
{}
virtual ~dxfPolyline() {}
virtual dxfBasicEntity* create() { return new dxfPolyline; }
virtual const char* name() { return "POLYLINE"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual int vertexCount() { return _vertices.size(); }
virtual void drawScene(scene* sc);
protected:
dxfVertex* _currentVertex;
std::vector<osg::ref_ptr<dxfVertex> > _vertices;
std::vector<osg::ref_ptr<dxfVertex> > _indices;
double _elevation;
unsigned short _flag;
unsigned int _mcount;
unsigned int _ncount;
unsigned short _nstart; // 71
unsigned short _nend; //72
osg::Vec3d _ocs; //210 220 230
unsigned short _mdensity; // 73
unsigned short _ndensity; // 74
unsigned short _surfacetype; //75
};
class dxfLWPolyline : public dxfBasicEntity
{
public:
dxfLWPolyline() :
_elevation(0.0),
_flag(0),
_vcount(0),
_ocs(osg::Vec3d(0,0,1)),
_lastv(0,0,0)
{}
virtual ~dxfLWPolyline() {}
virtual dxfBasicEntity* create() { return new dxfLWPolyline; }
virtual const char* name() { return "LWPOLYLINE"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual int vertexCount() { return _vertices.size(); }
virtual void drawScene(scene* sc);
protected:
double _elevation;
unsigned short _flag;
unsigned short _vcount; // 90
osg::Vec3d _ocs; //210 220 230
osg::Vec3d _lastv;
std::vector< osg::Vec3d > _vertices;
};
class dxfInsert : public dxfBasicEntity
{
public:
dxfInsert() : _block(NULL),
_done(false),
_rotation(0),
_scale(1,1,1),
_point(osg::Vec3d(0,0,0)),
_ocs(osg::Vec3d(0,0,1)) {}
virtual ~dxfInsert() {}
virtual dxfBasicEntity* create() { return new dxfInsert; }
virtual const char* name() { return "INSERT"; }
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual void drawScene(scene* sc);
protected:
std::string _blockName;
osg::ref_ptr<dxfBlock> _block;
bool _done; // since we are on a SEQEND, we must
// make sure not getting values addressed to other
// entities (dxf garble things) in the sequence
double _rotation;
osg::Vec3d _scale;
osg::Vec3d _point;
osg::Vec3d _ocs;
};
class dxfText : public dxfBasicEntity
{
public:
dxfText() :
_string(""),
_point1(0,0,0),
_point2(0,0,0),
_ocs(0,0,1),
_height(1),
_xscale(1),
_rotation(0),
_flags(0),
_hjustify(0),
_vjustify(0) {}
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:
dxfEntity(std::string s) : _entity(NULL), _seqend(false)
{
_entity = findByName(s);
if (_entity) {
_entityList.push_back(_entity);
// std::cout << "entity " << s << std::endl;
}
}
virtual void assign(dxfFile* dxf, codeValue& cv);
virtual bool done() { return !_seqend; }
static void registerEntity(dxfBasicEntity*);
static void unregisterEntity(dxfBasicEntity*);
static dxfBasicEntity* findByName(std::string s)
{
dxfBasicEntity* be = _registry[s].get();
if (be)
return be->create();
else {
std::cout << " no " << s << std::endl;
return NULL;
}
}
virtual void drawScene(scene* sc);
dxfBasicEntity* getEntity() { return _entity; }
// Returns the exemplar from the registry - all other entities of this type are created by this one via entity->create
static dxfBasicEntity* getRegistryEntity(std::string s) {
return _registry[s].get();
}
protected:
std::vector<osg::ref_ptr<dxfBasicEntity> > _entityList;
static std::map<std::string, osg::ref_ptr<dxfBasicEntity> > _registry;
dxfBasicEntity* _entity;
bool _seqend; // bypass 0 codes. needs a 0 seqend to close.
};
/** Proxy class for automatic registration of dxf entities reader/writers.*/
template<class T>
class RegisterEntityProxy
{
public:
RegisterEntityProxy()
{
_rw = new T;
dxfEntity::registerEntity(_rw.get());
}
~RegisterEntityProxy()
{
dxfEntity::unregisterEntity(_rw.get());
}
T* get() { return _rw.get(); }
protected:
osg::ref_ptr<T> _rw;
};
#endif