Files
OpenSceneGraph/src/osgPlugins/dxf/dxfEntity.h
Robert Osfield d70cf68ae6 From Sylvain Marie, "changed raw pointers to smart pointers in the dxfBlock, dxfTables and
dxfSection classes, so their members data are correctly deleted.
- changed some methods signatures to pass arguments by reference instead of
by value. The performance and memory usage are enhanced (the reader was
clogging the heap when reading some large DXF files)

The updated files have been compiled and tested with a variety of DXF files
on XP with VS2003, but the changes should not disturb any other compiler."
2006-12-05 15:31:07 +00:00

311 lines
9.2 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 "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) {}
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; }
protected:
std::string _layer;
unsigned short _color;
};
class dxfCircle : public dxfBasicEntity
{
public:
dxfCircle() : _radius(0), _ocs(0,0,1) {}
virtual ~dxfCircle() {}
virtual dxfBasicEntity* create() { return new dxfCircle; }
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() { return new dxfArc; }
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 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; }
const unsigned int getIndice1() const { return _indice1; }
const unsigned int getIndice2() const { return _indice2; }
const unsigned int getIndice3() const { return _indice3; }
const 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 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; }
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