From Paul de Repentinguy, DXF loader plugin. Ported to Linux by Robert Osfield.
This commit is contained in:
24
src/osgPlugins/dxf/GNUmakefile
Normal file
24
src/osgPlugins/dxf/GNUmakefile
Normal file
@@ -0,0 +1,24 @@
|
||||
TOPDIR = ../../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
aci.cpp\
|
||||
dxfBlock.cpp\
|
||||
dxfEntity.cpp\
|
||||
dxfFile.cpp\
|
||||
dxfReader.cpp\
|
||||
dxfSection.cpp\
|
||||
dxfTable.cpp\
|
||||
ReaderWriterDXF.cpp\
|
||||
scene.cpp\
|
||||
|
||||
|
||||
INC += -I$(THISDIR)
|
||||
|
||||
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
|
||||
|
||||
TARGET_BASENAME = dxf
|
||||
include $(TOPDIR)/Make/cygwin_plugin_def
|
||||
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
61
src/osgPlugins/dxf/ReaderWriterDXF.cpp
Normal file
61
src/osgPlugins/dxf/ReaderWriterDXF.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/* 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.
|
||||
*/
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/FileNameUtils>
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "dxfFile.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgDB;
|
||||
using namespace std;
|
||||
|
||||
|
||||
class ReaderWriterdxf : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderWriterdxf() { }
|
||||
virtual const char* className() { return "Autodesk DXF Reader"; }
|
||||
virtual bool acceptsExtension(const std::string& extension) const {
|
||||
return osgDB::equalCaseInsensitive(extension,"dxf");
|
||||
}
|
||||
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) const;
|
||||
protected:
|
||||
};
|
||||
|
||||
// register with Registry to instantiate the above reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterdxf> g_dxfReaderWriterProxy;
|
||||
|
||||
|
||||
// read file and convert to OSG.
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterdxf::readNode(const std::string& filename, const osgDB::ReaderWriter::Options*) const
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(filename);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
// Open
|
||||
dxfFile df(filename);
|
||||
if (df.parseFile()) {
|
||||
// convert to OSG
|
||||
osg::Group* osg_top = df.dxf2osg();
|
||||
return (osg_top);
|
||||
}
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
273
src/osgPlugins/dxf/aci.cpp
Normal file
273
src/osgPlugins/dxf/aci.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "aci.h"
|
||||
|
||||
double aci::table[256*3] =
|
||||
{
|
||||
/* dummy */ 0,0,0,
|
||||
/* 1 */ 1,0,0,
|
||||
/* 2 */ 1,1,0,
|
||||
/* 3 */ 0,1,0,
|
||||
/* 4 */ 0,1,1,
|
||||
/* 5 */ 0,0,1,
|
||||
/* 6 */ 1,0,1,
|
||||
/* 7 */ 1,1,1,
|
||||
/* 8 user defined */ 1,1,1,
|
||||
/* 9 user defined */ 1,1,1,
|
||||
/* 10 */ 1,0,0,
|
||||
/* 11 */ 1,0.5,0.5,
|
||||
/* 12 */ 0.65,0,0,
|
||||
/* 13 */ 0.65,0.325,0.325,
|
||||
/* 14 */ 0.5,0,0,
|
||||
/* 15 */ 0.5,0.25,0.25,
|
||||
/* 16 */ 0.3,0,0,
|
||||
/* 17 */ 0.3,0.15,0.15,
|
||||
/* 18 */ 0.15,0,0,
|
||||
/* 19 */ 0.15,0.075,0.075,
|
||||
/* 20 */ 1,0.25,0,
|
||||
/* 21 */ 1,0.625,0.5,
|
||||
/* 22 */ 0.65,0.1625,0,
|
||||
/* 23 */ 0.65,0.4063,0.325,
|
||||
/* 24 */ 0.5,0.125,0,
|
||||
/* 25 */ 0.5,0.3125,0.25,
|
||||
/* 26 */ 0.3,0.075,0,
|
||||
/* 27 */ 0.3,0.1875,0.15,
|
||||
/* 28 */ 0.15,0.0375,0,
|
||||
/* 29 */ 0.15,0.0938,0.075,
|
||||
/* 30 */ 1,0.5,0,
|
||||
/* 31 */ 1,0.75,0.5,
|
||||
/* 32 */ 0.65,0.325,0,
|
||||
/* 33 */ 0.65,0.4875,0.325,
|
||||
/* 34 */ 0.5,0.25,0,
|
||||
/* 35 */ 0.5,0.375,0.25,
|
||||
/* 36 */ 0.3,0.15,0,
|
||||
/* 37 */ 0.3,0.225,0.15,
|
||||
/* 38 */ 0.15,0.075,0,
|
||||
/* 39 */ 0.15,0.1125,0.075,
|
||||
/* 40 */ 1,0.75,0,
|
||||
/* 41 */ 1,0.875,0.5,
|
||||
/* 42 */ 0.65,0.4875,0,
|
||||
/* 43 */ 0.65,0.5688,0.325,
|
||||
/* 44 */ 0.5,0.375,0,
|
||||
/* 45 */ 0.5,0.4375,0.25,
|
||||
/* 46 */ 0.3,0.225,0,
|
||||
/* 47 */ 0.3,0.2625,0.15,
|
||||
/* 48 */ 0.15,0.1125,0,
|
||||
/* 49 */ 0.15,0.1313,0.075,
|
||||
/* 50 */ 1,1,0,
|
||||
/* 51 */ 1,1,0.5,
|
||||
/* 52 */ 0.65,0.65,0,
|
||||
/* 53 */ 0.65,0.65,0.325,
|
||||
/* 54 */ 0.5,0.5,0,
|
||||
/* 55 */ 0.5,0.5,0.25,
|
||||
/* 56 */ 0.3,0.3,0,
|
||||
/* 57 */ 0.3,0.3,0.15,
|
||||
/* 58 */ 0.15,0.15,0,
|
||||
/* 59 */ 0.15,0.15,0.075,
|
||||
/* 60 */ 0.75,1,0,
|
||||
/* 61 */ 0.875,1,0.5,
|
||||
/* 62 */ 0.4875,0.65,0,
|
||||
/* 63 */ 0.5688,0.65,0.325,
|
||||
/* 64 */ 0.375,0.5,0,
|
||||
/* 65 */ 0.4375,0.5,0.25,
|
||||
/* 66 */ 0.225,0.3,0,
|
||||
/* 67 */ 0.2625,0.3,0.15,
|
||||
/* 68 */ 0.1125,0.15,0,
|
||||
/* 69 */ 0.1313,0.15,0.075,
|
||||
/* 70 */ 0.5,1,0,
|
||||
/* 71 */ 0.75,1,0.5,
|
||||
/* 72 */ 0.325,0.65,0,
|
||||
/* 73 */ 0.4875,0.65,0.325,
|
||||
/* 74 */ 0.25,0.5,0,
|
||||
/* 75 */ 0.375,0.5,0.25,
|
||||
/* 76 */ 0.15,0.3,0,
|
||||
/* 77 */ 0.225,0.3,0.15,
|
||||
/* 78 */ 0.075,0.15,0,
|
||||
/* 79 */ 0.1125,0.15,0.075,
|
||||
/* 80 */ 0.25,1,0,
|
||||
/* 81 */ 0.625,1,0.5,
|
||||
/* 82 */ 0.1625,0.65,0,
|
||||
/* 83 */ 0.4063,0.65,0.325,
|
||||
/* 84 */ 0.125,0.5,0,
|
||||
/* 85 */ 0.3125,0.5,0.25,
|
||||
/* 86 */ 0.075,0.3,0,
|
||||
/* 87 */ 0.1875,0.3,0.15,
|
||||
/* 88 */ 0.0375,0.15,0,
|
||||
/* 89 */ 0.0938,0.15,0.075,
|
||||
/* 90 */ 0,1,0,
|
||||
/* 91 */ 0.5,1,0.5,
|
||||
/* 92 */ 0,0.65,0,
|
||||
/* 93 */ 0.325,0.65,0.325,
|
||||
/* 94 */ 0,0.5,0,
|
||||
/* 95 */ 0.25,0.5,0.25,
|
||||
/* 96 */ 0,0.3,0,
|
||||
/* 97 */ 0.15,0.3,0.15,
|
||||
/* 98 */ 0,0.15,0,
|
||||
/* 99 */ 0.075,0.15,0.075,
|
||||
/* 100 */ 0,1,0.25,
|
||||
/* 101 */ 0.5,1,0.625,
|
||||
/* 102 */ 0,0.65,0.1625,
|
||||
/* 103 */ 0.325,0.65,0.4063,
|
||||
/* 104 */ 0,0.5,0.125,
|
||||
/* 105 */ 0.25,0.5,0.3125,
|
||||
/* 106 */ 0,0.3,0.075,
|
||||
/* 107 */ 0.15,0.3,0.1875,
|
||||
/* 108 */ 0,0.15,0.0375,
|
||||
/* 109 */ 0.075,0.15,0.0938,
|
||||
/* 110 */ 0,1,0.5,
|
||||
/* 111 */ 0.5,1,0.75,
|
||||
/* 112 */ 0,0.65,0.325,
|
||||
/* 113 */ 0.325,0.65,0.4875,
|
||||
/* 114 */ 0,0.5,0.25,
|
||||
/* 115 */ 0.25,0.5,0.375,
|
||||
/* 116 */ 0,0.3,0.15,
|
||||
/* 117 */ 0.15,0.3,0.225,
|
||||
/* 118 */ 0,0.15,0.075,
|
||||
/* 119 */ 0.075,0.15,0.1125,
|
||||
/* 120 */ 0,1,0.75,
|
||||
/* 121 */ 0.5,1,0.875,
|
||||
/* 122 */ 0,0.65,0.4875,
|
||||
/* 123 */ 0.325,0.65,0.5688,
|
||||
/* 124 */ 0,0.5,0.375,
|
||||
/* 125 */ 0.25,0.5,0.4375,
|
||||
/* 126 */ 0,0.3,0.225,
|
||||
/* 127 */ 0.15,0.3,0.2625,
|
||||
/* 128 */ 0,0.15,0.1125,
|
||||
/* 129 */ 0.075,0.15,0.1313,
|
||||
/* 130 */ 0,1,1,
|
||||
/* 131 */ 0.5,1,1,
|
||||
/* 132 */ 0,0.65,0.65,
|
||||
/* 133 */ 0.325,0.65,0.65,
|
||||
/* 134 */ 0,0.5,0.5,
|
||||
/* 135 */ 0.25,0.5,0.5,
|
||||
/* 136 */ 0,0.3,0.3,
|
||||
/* 137 */ 0.15,0.3,0.3,
|
||||
/* 138 */ 0,0.15,0.15,
|
||||
/* 139 */ 0.075,0.15,0.15,
|
||||
/* 140 */ 0,0.75,1,
|
||||
/* 141 */ 0.5,0.875,1,
|
||||
/* 142 */ 0,0.4875,0.65,
|
||||
/* 143 */ 0.325,0.5688,0.65,
|
||||
/* 144 */ 0,0.375,0.5,
|
||||
/* 145 */ 0.25,0.4375,0.5,
|
||||
/* 146 */ 0,0.225,0.3,
|
||||
/* 147 */ 0.15,0.2625,0.3,
|
||||
/* 148 */ 0,0.1125,0.15,
|
||||
/* 149 */ 0.075,0.1313,0.15,
|
||||
/* 150 */ 0,0.5,1,
|
||||
/* 151 */ 0.5,0.75,1,
|
||||
/* 152 */ 0,0.325,0.65,
|
||||
/* 153 */ 0.325,0.4875,0.65,
|
||||
/* 154 */ 0,0.25,0.5,
|
||||
/* 155 */ 0.25,0.375,0.5,
|
||||
/* 156 */ 0,0.15,0.3,
|
||||
/* 157 */ 0.15,0.225,0.3,
|
||||
/* 158 */ 0,0.075,0.15,
|
||||
/* 159 */ 0.075,0.1125,0.15,
|
||||
/* 160 */ 0,0.25,1,
|
||||
/* 161 */ 0.5,0.625,1,
|
||||
/* 162 */ 0,0.1625,0.65,
|
||||
/* 163 */ 0.325,0.4063,0.65,
|
||||
/* 164 */ 0,0.125,0.5,
|
||||
/* 165 */ 0.25,0.3125,0.5,
|
||||
/* 166 */ 0,0.075,0.3,
|
||||
/* 167 */ 0.15,0.1875,0.3,
|
||||
/* 168 */ 0,0.0375,0.15,
|
||||
/* 169 */ 0.075,0.0938,0.15,
|
||||
/* 170 */ 0,0,1,
|
||||
/* 171 */ 0.5,0.5,1,
|
||||
/* 172 */ 0,0,0.65,
|
||||
/* 173 */ 0.325,0.325,0.65,
|
||||
/* 174 */ 0,0,0.5,
|
||||
/* 175 */ 0.25,0.25,0.5,
|
||||
/* 176 */ 0,0,0.3,
|
||||
/* 177 */ 0.15,0.15,0.3,
|
||||
/* 178 */ 0,0,0.15,
|
||||
/* 179 */ 0.075,0.075,0.15,
|
||||
/* 180 */ 0.25,0,1,
|
||||
/* 181 */ 0.625,0.5,1,
|
||||
/* 182 */ 0.1625,0,0.65,
|
||||
/* 183 */ 0.4063,0.325,0.65,
|
||||
/* 184 */ 0.125,0,0.5,
|
||||
/* 185 */ 0.3125,0.25,0.5,
|
||||
/* 186 */ 0.075,0,0.3,
|
||||
/* 187 */ 0.1875,0.15,0.3,
|
||||
/* 188 */ 0.0375,0,0.15,
|
||||
/* 189 */ 0.0938,0.075,0.15,
|
||||
/* 190 */ 0.5,0,1,
|
||||
/* 191 */ 0.75,0.5,1,
|
||||
/* 192 */ 0.325,0,0.65,
|
||||
/* 193 */ 0.4875,0.325,0.65,
|
||||
/* 194 */ 0.25,0,0.5,
|
||||
/* 195 */ 0.375,0.25,0.5,
|
||||
/* 196 */ 0.15,0,0.3,
|
||||
/* 197 */ 0.225,0.15,0.3,
|
||||
/* 198 */ 0.075,0,0.15,
|
||||
/* 199 */ 0.1125,0.075,0.15,
|
||||
/* 200 */ 0.75,0,1,
|
||||
/* 201 */ 0.875,0.5,1,
|
||||
/* 202 */ 0.4875,0,0.65,
|
||||
/* 203 */ 0.5688,0.325,0.65,
|
||||
/* 204 */ 0.375,0,0.5,
|
||||
/* 205 */ 0.4375,0.25,0.5,
|
||||
/* 206 */ 0.225,0,0.3,
|
||||
/* 207 */ 0.2625,0.15,0.3,
|
||||
/* 208 */ 0.1125,0,0.15,
|
||||
/* 209 */ 0.1313,0.075,0.15,
|
||||
/* 210 */ 1,0,1,
|
||||
/* 211 */ 1,0.5,1,
|
||||
/* 212 */ 0.65,0,0.65,
|
||||
/* 213 */ 0.65,0.325,0.65,
|
||||
/* 214 */ 0.5,0,0.5,
|
||||
/* 215 */ 0.5,0.25,0.5,
|
||||
/* 216 */ 0.3,0,0.3,
|
||||
/* 217 */ 0.3,0.15,0.3,
|
||||
/* 218 */ 0.15,0,0.15,
|
||||
/* 219 */ 0.15,0.075,0.15,
|
||||
/* 220 */ 1,0,0.75,
|
||||
/* 221 */ 1,0.5,0.875,
|
||||
/* 222 */ 0.65,0,0.4875,
|
||||
/* 223 */ 0.65,0.325,0.5688,
|
||||
/* 224 */ 0.5,0,0.375,
|
||||
/* 225 */ 0.5,0.25,0.4375,
|
||||
/* 226 */ 0.3,0,0.225,
|
||||
/* 227 */ 0.3,0.15,0.2625,
|
||||
/* 228 */ 0.15,0,0.1125,
|
||||
/* 229 */ 0.15,0.075,0.1313,
|
||||
/* 230 */ 1,0,0.5,
|
||||
/* 231 */ 1,0.5,0.75,
|
||||
/* 232 */ 0.65,0,0.325,
|
||||
/* 233 */ 0.65,0.325,0.4875,
|
||||
/* 234 */ 0.5,0,0.25,
|
||||
/* 235 */ 0.5,0.25,0.375,
|
||||
/* 236 */ 0.3,0,0.15,
|
||||
/* 237 */ 0.3,0.15,0.225,
|
||||
/* 238 */ 0.15,0,0.075,
|
||||
/* 239 */ 0.15,0.075,0.1125,
|
||||
/* 240 */ 1,0,0.25,
|
||||
/* 241 */ 1,0.5,0.625,
|
||||
/* 242 */ 0.65,0,0.1625,
|
||||
/* 243 */ 0.65,0.325,0.4063,
|
||||
/* 244 */ 0.5,0,0.125,
|
||||
/* 245 */ 0.5,0.25,0.3125,
|
||||
/* 246 */ 0.3,0,0.075,
|
||||
/* 247 */ 0.3,0.15,0.1875,
|
||||
/* 248 */ 0.15,0,0.0375,
|
||||
/* 249 */ 0.15,0.075,0.0938,
|
||||
/* 250 */ 0.33,0.33,0.33,
|
||||
/* 251 */ 0.464,0.464,0.464,
|
||||
/* 252 */ 0.598,0.598,0.598,
|
||||
/* 253 */ 0.732,0.732,0.732,
|
||||
/* 254 */ 0.866,0.866,0.866,
|
||||
/* 255 */ 1,1,1
|
||||
};
|
||||
35
src/osgPlugins/dxf/aci.h
Normal file
35
src/osgPlugins/dxf/aci.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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_ACI_COLOR
|
||||
#define DXF_ACI_COLOR 1
|
||||
// lookup table for autocad color index
|
||||
struct aci {
|
||||
// some color positions
|
||||
enum {
|
||||
BLACK,
|
||||
RED,
|
||||
YELLOW,
|
||||
GREEN,
|
||||
CYAN,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
WHITE,
|
||||
USER_2,
|
||||
USER_3,
|
||||
BYLAYER = 256,
|
||||
MIN = 1,
|
||||
MAX = 255
|
||||
};
|
||||
static double table[256*3];
|
||||
};
|
||||
#endif
|
||||
50
src/osgPlugins/dxf/codeValue.h
Normal file
50
src/osgPlugins/dxf/codeValue.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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_CODE_VALUE
|
||||
#define DXF_CODE_VALUE 1
|
||||
|
||||
#include <string>
|
||||
|
||||
/// a group code / value pair handler
|
||||
/// to do: write accessors which check for the correct value
|
||||
/// being asked for (each group code has a value type
|
||||
/// associated with it).
|
||||
class codeValue {
|
||||
public:
|
||||
codeValue() { reset(); }
|
||||
void reset()
|
||||
{
|
||||
_groupCode = -100;
|
||||
_type = 0;
|
||||
_bool = false;
|
||||
_short = 0;
|
||||
_int = 0;
|
||||
_long = 0;
|
||||
_double = 0;
|
||||
_string = "";
|
||||
}
|
||||
int _groupCode;
|
||||
int _type;
|
||||
std::string _unknown;
|
||||
std::string _string;
|
||||
bool _bool;
|
||||
unsigned short _short;
|
||||
int _int;
|
||||
long _long;
|
||||
double _double;
|
||||
};
|
||||
|
||||
typedef std::vector<codeValue> VariableList; // this may be too big, find another way
|
||||
|
||||
#endif
|
||||
58
src/osgPlugins/dxf/dxfBlock.cpp
Normal file
58
src/osgPlugins/dxf/dxfBlock.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "dxfBlock.h"
|
||||
#include "dxfFile.h"
|
||||
#include "codeValue.h"
|
||||
#include "dxfEntity.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
dxfBlock::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
string s = cv._string;
|
||||
if (cv._groupCode == 0) {
|
||||
if (_currentEntity && _currentEntity->done()) {
|
||||
_currentEntity = new dxfEntity(s);
|
||||
_entityList.push_back(_currentEntity);
|
||||
} else if (_currentEntity) {
|
||||
_currentEntity->assign(dxf, cv);
|
||||
} else {
|
||||
_currentEntity = new dxfEntity(s);
|
||||
_entityList.push_back(_currentEntity);
|
||||
}
|
||||
} else if (_currentEntity) {
|
||||
_currentEntity->assign(dxf, cv);
|
||||
} else if (cv._groupCode != 0) {
|
||||
double d = cv._double;
|
||||
switch (cv._groupCode) {
|
||||
case 2:
|
||||
_name = s;
|
||||
case 10:
|
||||
_position.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_position.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_position.z() = d;
|
||||
break;
|
||||
default:
|
||||
// dxf garble
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const osg::Vec3d& dxfBlock::getPosition() const { return _position; }
|
||||
43
src/osgPlugins/dxf/dxfBlock.h
Normal file
43
src/osgPlugins/dxf/dxfBlock.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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_BLOCK
|
||||
#define DXF_BLOCK 1
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/Vec3d>
|
||||
|
||||
class dxfFile;
|
||||
class codeValue;
|
||||
class dxfEntity;
|
||||
|
||||
class dxfBlock : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
dxfBlock() : _currentEntity(NULL) {}
|
||||
virtual ~dxfBlock() {}
|
||||
inline const std::string& getName() const { return _name; }
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
std::vector<dxfEntity*> getEntityList() { return _entityList; }
|
||||
const osg::Vec3d& getPosition() const;
|
||||
protected:
|
||||
std::vector<dxfEntity*> _entityList;
|
||||
dxfEntity* _currentEntity;
|
||||
std::string _name;
|
||||
osg::Vec3d _position;
|
||||
};
|
||||
|
||||
#endif
|
||||
88
src/osgPlugins/dxf/dxfDataTypes.h
Normal file
88
src/osgPlugins/dxf/dxfDataTypes.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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_DATATYPES
|
||||
#define DXF_DATATYPES 1
|
||||
|
||||
#include <osg/Group>
|
||||
|
||||
typedef std::map<std::string, osg::ref_ptr<osg::Group> > LayerTable;
|
||||
|
||||
class dxfDataType {
|
||||
public:
|
||||
enum TYPE {
|
||||
UNKNOWN,
|
||||
STRING,
|
||||
HEX,
|
||||
BOOL,
|
||||
SHORT,
|
||||
INT,
|
||||
LONG,
|
||||
DOUBLE
|
||||
};
|
||||
inline static bool between(int a, int m, int x) { return (a >= m && a <= x); }
|
||||
inline static int typeForCode(int gc) {
|
||||
if ( between(gc, 0, 9) ||
|
||||
gc == 100 || gc == 102 ||
|
||||
between(gc, 300, 309) ||
|
||||
between(gc, 410, 419) ||
|
||||
between(gc, 430, 439) ||
|
||||
between(gc, 470, 479) ||
|
||||
gc == 999 ||
|
||||
between(gc, 1000, 1009)
|
||||
)
|
||||
return STRING;
|
||||
else if ( gc == 105 ||
|
||||
between(gc, 310, 319) ||
|
||||
between(gc, 320, 329) ||
|
||||
between(gc, 330, 369) ||
|
||||
between(gc, 390, 399)
|
||||
)
|
||||
return HEX;
|
||||
else if ( between(gc, 290, 299 ) )
|
||||
return BOOL;
|
||||
else if ( between(gc, 60, 79) ||
|
||||
between(gc, 170, 179) ||
|
||||
between(gc, 270, 279) ||
|
||||
between(gc, 280, 289) ||
|
||||
between(gc, 370, 379) ||
|
||||
between(gc, 380, 389) ||
|
||||
between(gc, 400, 409)
|
||||
)
|
||||
return SHORT;
|
||||
else if ( between(gc, 90, 99) ||
|
||||
between(gc, 450, 459) ||
|
||||
between(gc, 1060, 1070)
|
||||
)
|
||||
return LONG;
|
||||
else if ( between(gc, 420, 429) ||
|
||||
between(gc, 440, 449) ||
|
||||
gc == 1071
|
||||
)
|
||||
return INT;
|
||||
else if ( between(gc, 10, 39) ||
|
||||
between(gc, 40, 59) ||
|
||||
between(gc, 110, 119) ||
|
||||
between(gc, 120, 129) ||
|
||||
between(gc, 130, 139) ||
|
||||
between(gc, 140, 149) ||
|
||||
between(gc, 210, 239) ||
|
||||
between(gc, 460, 469) ||
|
||||
between(gc, 1010, 1019)
|
||||
)
|
||||
return DOUBLE;
|
||||
else
|
||||
return UNKNOWN;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
805
src/osgPlugins/dxf/dxfEntity.cpp
Normal file
805
src/osgPlugins/dxf/dxfEntity.cpp
Normal file
@@ -0,0 +1,805 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "dxfEntity.h"
|
||||
#include "dxfFile.h"
|
||||
#include "scene.h"
|
||||
#include "dxfBlock.h"
|
||||
#include "codeValue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace osg;
|
||||
|
||||
// static
|
||||
std::map<std::string, ref_ptr<dxfBasicEntity> > dxfEntity::_registry;
|
||||
RegisterEntityProxy<dxf3DFace> g_dxf3DFace;
|
||||
RegisterEntityProxy<dxfCircle> g_dxfCircle;
|
||||
RegisterEntityProxy<dxfArc> g_dxfArc;
|
||||
RegisterEntityProxy<dxfLine> g_dxfLine;
|
||||
RegisterEntityProxy<dxfVertex> g_dxfVertex;
|
||||
RegisterEntityProxy<dxfPolyline> g_dxfPolyline;
|
||||
RegisterEntityProxy<dxfLWPolyline> g_dxfLWPolyline;
|
||||
RegisterEntityProxy<dxfInsert> g_dxfInsert;
|
||||
|
||||
void
|
||||
dxfBasicEntity::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
switch (cv._groupCode) {
|
||||
case 8:
|
||||
_layer = cv._string;
|
||||
break;
|
||||
case 62:
|
||||
_color = cv._short;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxf3DFace::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
double d = cv._double;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
_vertices[cv._groupCode - 10].x() = d;
|
||||
break;
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
_vertices[cv._groupCode - 20].y() = d;
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
_vertices[cv._groupCode - 30].z() = d;
|
||||
break;
|
||||
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxf3DFace::drawScene(scene* sc)
|
||||
{
|
||||
std::vector<Vec3d> vlist;
|
||||
short nfaces = 3;
|
||||
|
||||
// Hate to do that, but hey, that's written in the DXF specs:
|
||||
if (_vertices[2] != _vertices[3]) nfaces = 4;
|
||||
|
||||
for (short i = nfaces-1; i >= 0; i--)
|
||||
vlist.push_back(_vertices[i]);
|
||||
|
||||
if (nfaces == 3) {
|
||||
// to do make sure we're % 3
|
||||
sc->addTriangles(getLayer(), _color, vlist);
|
||||
} else if (nfaces == 4) {
|
||||
// to do make sure we're % 4
|
||||
sc->addQuads(getLayer(), _color, vlist);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfVertex::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
double d = cv._double;
|
||||
unsigned short s = cv._short;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_vertex.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_vertex.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_vertex.z() = d;
|
||||
break;
|
||||
case 71:
|
||||
_indice1 = s;
|
||||
break;
|
||||
case 72:
|
||||
_indice2 = s;
|
||||
break;
|
||||
case 73:
|
||||
_indice3 = s;
|
||||
break;
|
||||
case 74:
|
||||
_indice4 = s;
|
||||
break;
|
||||
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfCircle::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
double d = cv._double;
|
||||
unsigned short s = cv._short;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_center.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_center.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_center.z() = d;
|
||||
break;
|
||||
case 40:
|
||||
_radius = d;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfCircle::drawScene(scene* sc)
|
||||
{
|
||||
Matrix m;
|
||||
getOCSMatrix(_ocs, m);
|
||||
sc->ocs(m);
|
||||
std::vector<Vec3d> vlist;
|
||||
int numsteps = 360/5; // baaarghf.
|
||||
double angle_step = osg::DegreesToRadians((double)360.0 / (double) numsteps);
|
||||
double angle1 = 0.0f;
|
||||
double angle2 = 0.0f;
|
||||
Vec3d a = _center;
|
||||
Vec3d b,c;
|
||||
for (int r = 0; r < numsteps; r++)
|
||||
{
|
||||
angle1 = angle2;
|
||||
if (r == numsteps - 1)
|
||||
angle2 = 0.0f;
|
||||
else
|
||||
angle2 += angle_step;
|
||||
b = a + Vec3d(_radius * (double) sin(angle1), _radius * (double) cos(angle1), 0);
|
||||
c = a + Vec3d(_radius * (double) sin(angle2), _radius * (double) cos(angle2), 0);
|
||||
// vlist.push_back(a);
|
||||
vlist.push_back(b);
|
||||
vlist.push_back(c);
|
||||
}
|
||||
sc->addLineStrip(getLayer(), _color, vlist);
|
||||
// sc->addTriangles(getLayer(), _color, vlist);
|
||||
sc->ocs_clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dxfArc::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
double d = cv._double;
|
||||
unsigned short s = cv._short;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_center.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_center.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_center.z() = d;
|
||||
break;
|
||||
case 40:
|
||||
_radius = d;
|
||||
break;
|
||||
case 50:
|
||||
_startAngle = d;
|
||||
break;
|
||||
case 51:
|
||||
_endAngle = d;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfArc::drawScene(scene* sc)
|
||||
{
|
||||
Matrix m;
|
||||
getOCSMatrix(_ocs, m);
|
||||
sc->ocs(m);
|
||||
std::vector<Vec3d> vlist;
|
||||
double end;
|
||||
double start;
|
||||
if (_startAngle > _endAngle) {
|
||||
start = _startAngle;
|
||||
end = _endAngle + 360;
|
||||
} else {
|
||||
start = _startAngle;
|
||||
end = _endAngle;
|
||||
}
|
||||
double angle_step = DegreesToRadians(end - start);
|
||||
int numsteps = (end - start)/5; // hurmghf. say 5 degrees?
|
||||
if (numsteps * 5 < (end - start)) numsteps++;
|
||||
angle_step /= (double) numsteps;
|
||||
end = DegreesToRadians((-_startAngle)+90.0);
|
||||
start = DegreesToRadians((-_endAngle)+90.0);
|
||||
double angle1 = 0.0f;
|
||||
double angle2 = (start);
|
||||
Vec3d a = _center;
|
||||
Vec3d b,c;
|
||||
for (int r = 0; r < numsteps; r++)
|
||||
{
|
||||
angle1 = angle2;
|
||||
angle2 = angle1 + angle_step;
|
||||
b = a + Vec3d(_radius * (double) sin(angle1), _radius * (double) cos(angle1), 0);
|
||||
c = a + Vec3d(_radius * (double) sin(angle2), _radius * (double) cos(angle2), 0);
|
||||
vlist.push_back(b);
|
||||
vlist.push_back(c);
|
||||
}
|
||||
sc->addLineStrip(getLayer(), _color, vlist);
|
||||
sc->ocs_clear();
|
||||
}
|
||||
|
||||
void
|
||||
dxfLine::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
double d = cv._double;
|
||||
unsigned short s = cv._short;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_a.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_a.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_a.z() = d;
|
||||
break;
|
||||
case 11:
|
||||
_b.x() = d;
|
||||
break;
|
||||
case 21:
|
||||
_b.y() = d;
|
||||
break;
|
||||
case 31:
|
||||
_b.z() = d;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfLine::drawScene(scene* sc)
|
||||
{
|
||||
Matrix m;
|
||||
getOCSMatrix(_ocs, m);
|
||||
// don't know why this doesn't work
|
||||
// sc->ocs(m);
|
||||
sc->addLine(getLayer(), _color, _b, _a);
|
||||
static long lcount = 0;
|
||||
// std::cout << ++lcount << " ";
|
||||
// sc->ocs_clear();
|
||||
}
|
||||
|
||||
void
|
||||
dxfPolyline::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
string s = cv._string;
|
||||
if (cv._groupCode == 0) {
|
||||
if (s == "VERTEX") {
|
||||
_currentVertex = new dxfVertex;
|
||||
if (_mcount && (_flag & 64) && _vertices.size() == _mcount) {
|
||||
_indices.push_back(_currentVertex);
|
||||
} else {
|
||||
// don't know if and what to do if no _mcount
|
||||
_vertices.push_back(_currentVertex);
|
||||
}
|
||||
} else {
|
||||
// hum not sure if
|
||||
// 1) that is possible
|
||||
// 2) what to do...
|
||||
}
|
||||
} else if (_currentVertex) {
|
||||
_currentVertex->assign(dxf, cv);
|
||||
} else {
|
||||
double d = cv._double;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
// dummy
|
||||
break;
|
||||
case 20:
|
||||
// dummy
|
||||
break;
|
||||
case 30:
|
||||
_elevation = d; // what is elevation?
|
||||
break;
|
||||
case 70:
|
||||
_flag = cv._short;
|
||||
break;
|
||||
case 71:
|
||||
_mcount = cv._short;
|
||||
break;
|
||||
case 72:
|
||||
_ncount = cv._short;
|
||||
break;
|
||||
case 73:
|
||||
_mdensity = cv._short;
|
||||
break;
|
||||
case 74:
|
||||
_ndensity = cv._short;
|
||||
break;
|
||||
case 75:
|
||||
_surfacetype = cv._short;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dxfPolyline::drawScene(scene* sc)
|
||||
{
|
||||
// if (getLayer() != "UDF2" && getLayer() != "ENGINES") return;
|
||||
// if (!(_flag & 16)) return;
|
||||
Matrix m;
|
||||
getOCSMatrix(_ocs, m);
|
||||
sc->ocs(m);
|
||||
std::vector<Vec3d> vlist;
|
||||
std::vector<Vec3d> qlist;
|
||||
Vec3d a, b, c, d;
|
||||
bool invert_order = false;
|
||||
if (_flag & 16) {
|
||||
std::vector<Vec3d> nlist;
|
||||
Vec3d nr;
|
||||
bool nset = false;
|
||||
dxfVertex* v = NULL;
|
||||
unsigned short ncount;
|
||||
unsigned short mcount;
|
||||
if (_surfacetype ==6) {
|
||||
// I dont have examples of type 5 and 8, but they may be the same as 6
|
||||
mcount = _mdensity;
|
||||
ncount = _ndensity;
|
||||
} else {
|
||||
mcount = _mcount;
|
||||
ncount = _ncount;
|
||||
}
|
||||
for (unsigned short n = 0; n < ncount-1; n++) {
|
||||
for (unsigned short m = 1; m < mcount; m++) {
|
||||
// 0
|
||||
a = _vertices[(m-1)*ncount+n].get()->getVertex();
|
||||
// 1
|
||||
b = _vertices[m*ncount+n].get()->getVertex();
|
||||
// 3
|
||||
c = _vertices[(m)*ncount+n+1].get()->getVertex();
|
||||
// 2
|
||||
d = _vertices[(m-1)*ncount+n+1].get()->getVertex();
|
||||
if (a == b ) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(c);
|
||||
vlist.push_back(d);
|
||||
b = c;
|
||||
c = d;
|
||||
} else if (c == d) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(b);
|
||||
vlist.push_back(c);
|
||||
} else {
|
||||
qlist.push_back(a);
|
||||
qlist.push_back(b);
|
||||
qlist.push_back(c);
|
||||
qlist.push_back(d);
|
||||
}
|
||||
if (!nset) {
|
||||
nset = true;
|
||||
nr = (b - a) ^ (c - a);
|
||||
nr.normalize();
|
||||
}
|
||||
nlist.push_back(a);
|
||||
}
|
||||
}
|
||||
if (_flag & 1) {
|
||||
for (unsigned short n = 0; n < ncount-1; n++) {
|
||||
// 0
|
||||
a = _vertices[(mcount-1)*ncount+n].get()->getVertex();
|
||||
// 1
|
||||
b = _vertices[0*ncount+n].get()->getVertex();
|
||||
// 3
|
||||
c = _vertices[(0)*ncount+n+1].get()->getVertex();
|
||||
// 2
|
||||
d = _vertices[(mcount-1)*ncount+n+1].get()->getVertex();
|
||||
if (a == b ) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(c);
|
||||
vlist.push_back(d);
|
||||
b = c;
|
||||
c = d;
|
||||
} else if (c == d) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(b);
|
||||
vlist.push_back(c);
|
||||
} else {
|
||||
qlist.push_back(a);
|
||||
qlist.push_back(b);
|
||||
qlist.push_back(c);
|
||||
qlist.push_back(d);
|
||||
}
|
||||
nlist.push_back(a);
|
||||
}
|
||||
}
|
||||
if (_flag & 32) {
|
||||
for (unsigned short m = 1; m < mcount; m++) {
|
||||
// 0
|
||||
a = _vertices[(m-1)*ncount+(ncount-1)].get()->getVertex();
|
||||
// 1
|
||||
b = _vertices[m*ncount+(ncount-1)].get()->getVertex();
|
||||
// 3
|
||||
c = _vertices[(m)*ncount].get()->getVertex();
|
||||
// 2
|
||||
d = _vertices[(m-1)*ncount].get()->getVertex();
|
||||
if (a == b ) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(c);
|
||||
vlist.push_back(d);
|
||||
b = c;
|
||||
c = d;
|
||||
} else if (c == d) {
|
||||
vlist.push_back(a);
|
||||
vlist.push_back(b);
|
||||
vlist.push_back(c);
|
||||
} else {
|
||||
qlist.push_back(a);
|
||||
qlist.push_back(b);
|
||||
qlist.push_back(c);
|
||||
qlist.push_back(d);
|
||||
}
|
||||
nlist.push_back(a);
|
||||
}
|
||||
}
|
||||
|
||||
// a naive attempt to determine vertex ordering
|
||||
VList::iterator itr = nlist.begin();
|
||||
Vec3d lastn = (*itr++);
|
||||
double bad_c = 0;
|
||||
double good_c = 0;
|
||||
long bad=0,good=0;
|
||||
for (; itr != nlist.end(); ) {
|
||||
++itr;
|
||||
if ((*itr)== lastn) continue;
|
||||
Vec3d diff = ((*itr)-lastn);
|
||||
diff.normalize();
|
||||
float dot = diff * nr;
|
||||
if (dot > 0.0) {
|
||||
bad_c += dot;
|
||||
++bad;
|
||||
} else {
|
||||
++good;
|
||||
good_c += dot;
|
||||
}
|
||||
}
|
||||
if (bad > good) {
|
||||
invert_order = true;
|
||||
}
|
||||
|
||||
if (qlist.size())
|
||||
sc->addQuads(getLayer(), _color, qlist, invert_order);
|
||||
if (vlist.size())
|
||||
sc->addTriangles(getLayer(), _color, vlist, invert_order);
|
||||
|
||||
} else if (_flag & 64) {
|
||||
if (_ncount > _indices.size())
|
||||
_ncount = _indices.size();
|
||||
unsigned short _facetype = 3;
|
||||
unsigned short count = 0;
|
||||
for (unsigned short i = 0; i < _ncount; i++) {
|
||||
dxfVertex* vindice = _indices[i].get();
|
||||
if (!vindice) continue;
|
||||
dxfVertex* v = NULL;
|
||||
if (vindice->getIndice4()) {
|
||||
_facetype = 4;
|
||||
d = _vertices[vindice->getIndice4()-1].get()->getVertex();
|
||||
} else {
|
||||
_facetype = 3;
|
||||
}
|
||||
if (vindice->getIndice3()) {
|
||||
c = _vertices[vindice->getIndice3()-1].get()->getVertex();
|
||||
} else {
|
||||
c = _vertices[count++].get()->getVertex();
|
||||
}
|
||||
if (vindice->getIndice2()) {
|
||||
b = _vertices[vindice->getIndice2()-1].get()->getVertex();
|
||||
} else {
|
||||
b = _vertices[count++].get()->getVertex();
|
||||
}
|
||||
if (vindice->getIndice1()) {
|
||||
a = _vertices[vindice->getIndice1()-1].get()->getVertex();
|
||||
} else {
|
||||
a = _vertices[count++].get()->getVertex();
|
||||
}
|
||||
if (_facetype == 4) {
|
||||
qlist.push_back(d);
|
||||
qlist.push_back(c);
|
||||
qlist.push_back(b);
|
||||
qlist.push_back(a);
|
||||
} else {
|
||||
qlist.push_back(c);
|
||||
qlist.push_back(b);
|
||||
qlist.push_back(a);
|
||||
}
|
||||
}
|
||||
if (vlist.size())
|
||||
sc->addTriangles(getLayer(), _color, vlist);
|
||||
if (qlist.size())
|
||||
sc->addQuads(getLayer(), _color, qlist);
|
||||
// is there a flag 1 or 32 for 64?
|
||||
} else {
|
||||
// simple polyline?
|
||||
for (short i = _vertices.size()-1; i >= 0; i--)
|
||||
vlist.push_back(_vertices[i]->getVertex());
|
||||
if (_flag & 1) {
|
||||
// std::cout << "line loop " << _vertices.size() << std::endl;
|
||||
sc->addLineLoop(getLayer(), _color, vlist);
|
||||
} else {
|
||||
// std::cout << "line strip " << _vertices.size() << std::endl;
|
||||
sc->addLineStrip(getLayer(), _color, vlist);
|
||||
}
|
||||
|
||||
}
|
||||
sc->ocs_clear();
|
||||
}
|
||||
|
||||
void
|
||||
dxfLWPolyline::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
string s = cv._string;
|
||||
|
||||
double d = cv._double;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_lastv.x() = d;
|
||||
// x
|
||||
break;
|
||||
case 20:
|
||||
_lastv.y() = d;
|
||||
_lastv.z() = _elevation;
|
||||
_vertices.push_back ( _lastv );
|
||||
// y -> on shoot
|
||||
break;
|
||||
case 38:
|
||||
_elevation = d; // what is elevation?
|
||||
break;
|
||||
case 70:
|
||||
_flag = cv._short;
|
||||
break;
|
||||
case 90:
|
||||
_vcount = cv._short;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dxfLWPolyline::drawScene(scene* sc)
|
||||
{
|
||||
// if (getLayer() != "UDF2" && getLayer() != "ENGINES") return;
|
||||
// if (!(_flag & 16)) return;
|
||||
Matrix m;
|
||||
getOCSMatrix(_ocs, m);
|
||||
sc->ocs(m);
|
||||
if (_flag & 1) {
|
||||
// std::cout << "lwpolyline line loop " << _vertices.size() << std::endl;
|
||||
sc->addLineLoop(getLayer(), _color, _vertices);
|
||||
} else {
|
||||
// std::cout << "lwpolyline line strip " << _vertices.size() << std::endl;
|
||||
sc->addLineStrip(getLayer(), _color, _vertices);
|
||||
}
|
||||
sc->ocs_clear();
|
||||
}
|
||||
|
||||
void
|
||||
dxfInsert::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
string s = cv._string;
|
||||
if (_done || (cv._groupCode == 0 && s != "INSERT")) {
|
||||
_done = true;
|
||||
return;
|
||||
}
|
||||
if (cv._groupCode == 2 && !_block) {
|
||||
_blockName = s;
|
||||
_block = dxf->findBlock(s);
|
||||
} else {
|
||||
double d = cv._double;
|
||||
switch (cv._groupCode) {
|
||||
case 10:
|
||||
_point.x() = d;
|
||||
break;
|
||||
case 20:
|
||||
_point.y() = d;
|
||||
break;
|
||||
case 30:
|
||||
_point.z() = d;
|
||||
break;
|
||||
case 41:
|
||||
_scale.x() = d;
|
||||
break;
|
||||
case 42:
|
||||
_scale.y() = d;
|
||||
break;
|
||||
case 43:
|
||||
_scale.z() = d;
|
||||
break;
|
||||
case 50:
|
||||
_rotation = d;
|
||||
break;
|
||||
case 210:
|
||||
_ocs.x() = d;
|
||||
break;
|
||||
case 220:
|
||||
_ocs.y() = d;
|
||||
break;
|
||||
case 230:
|
||||
_ocs.z() = d;
|
||||
break;
|
||||
default:
|
||||
dxfBasicEntity::assign(dxf, cv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// hum. read the doc, then come back here. then try to figure.
|
||||
void
|
||||
dxfInsert::drawScene(scene* sc)
|
||||
{
|
||||
// INSERTs can be nested. So pull the current matrix
|
||||
// and push it back after we fill our context
|
||||
// This is a snapshot in time. I will rewrite all this to be cleaner,
|
||||
// but for now, it seems working fine
|
||||
// (with the files I have, the results are equal to Voloview,
|
||||
// and better than Deep Exploration and Lightwave).
|
||||
Matrixd back = sc->backMatrix();
|
||||
Matrixd m;
|
||||
m.makeIdentity();
|
||||
sc->pushMatrix(m, true);
|
||||
Vec3d trans = _block->getPosition();
|
||||
sc->blockOffset(-trans);
|
||||
if (_rotation) {
|
||||
sc->pushMatrix(Matrixd::rotate(osg::DegreesToRadians(_rotation), 0,0,1));
|
||||
}
|
||||
sc->pushMatrix(Matrixd::scale(_scale.x(), _scale.y(), _scale.z()));
|
||||
sc->pushMatrix(Matrix::translate(_point.x(), _point.y(), _point.z()));
|
||||
getOCSMatrix(_ocs, m);
|
||||
sc->pushMatrix(m);
|
||||
sc->pushMatrix(back);
|
||||
|
||||
std::vector<dxfEntity*> l = _block->getEntityList();
|
||||
for (std::vector<dxfEntity*>::iterator itr = l.begin(); itr != l.end(); ++itr) {
|
||||
dxfBasicEntity* e = (*itr)->getEntity();
|
||||
if (e) {
|
||||
e->drawScene(sc);
|
||||
}
|
||||
}
|
||||
|
||||
sc->popMatrix(); // ocs
|
||||
sc->popMatrix(); // translate
|
||||
sc->popMatrix(); // scale
|
||||
if (_rotation) {
|
||||
sc->popMatrix(); // rotate
|
||||
}
|
||||
sc->popMatrix(); // identity
|
||||
sc->popMatrix(); // back
|
||||
sc->blockOffset(Vec3d(0,0,0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void
|
||||
dxfEntity::registerEntity(dxfBasicEntity* entity)
|
||||
{
|
||||
_registry[entity->name()] = entity;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
dxfEntity::unregisterEntity(dxfBasicEntity* entity)
|
||||
{
|
||||
map<string, ref_ptr<dxfBasicEntity > >::iterator itr = _registry.find(entity->name());
|
||||
if (itr != _registry.end()) {
|
||||
_registry.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void dxfEntity::drawScene(scene* sc)
|
||||
{
|
||||
for (std::vector<ref_ptr<dxfBasicEntity > >::iterator itr = _entityList.begin();
|
||||
itr != _entityList.end(); ++itr) {
|
||||
(*itr)->drawScene(sc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfEntity::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
string s = cv._string;
|
||||
if (cv._groupCode == 66 && !(_entity && string("TABLE") == _entity->name())) {
|
||||
// The funny thing here. Group code 66 has been called 'obsoleted'
|
||||
// for a POLYLINE. But not for an INSERT. Moreover, a TABLE
|
||||
// can have a 66 for... an obscure bottom cell color value.
|
||||
// I decided to rely on the presence of the 66 code for
|
||||
// the POLYLINE. If you find a better alternative,
|
||||
// contact me, or correct this code
|
||||
// and post the correction to osg mailing list
|
||||
_seqend = true;
|
||||
} else if (_seqend && cv._groupCode == 0 && s == "SEQEND") {
|
||||
_seqend = false;
|
||||
// cout << "... off" << endl;
|
||||
} else if (_entity) {
|
||||
_entity->assign(dxf, cv);
|
||||
}
|
||||
}
|
||||
308
src/osgPlugins/dxf/dxfEntity.h
Normal file
308
src/osgPlugins/dxf/dxfEntity.h
Normal file
@@ -0,0 +1,308 @@
|
||||
/* 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/Matrix>
|
||||
|
||||
|
||||
class scene;
|
||||
class dxfBlock;
|
||||
class codeValue;
|
||||
class dxfFile;
|
||||
|
||||
static inline void
|
||||
getOCSMatrix(osg::Vec3d ocs, osg::Matrix &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::Matrix( 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* sc) {}
|
||||
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 short getIndice1() const { return _indice1; }
|
||||
const unsigned short getIndice2() const { return _indice2; }
|
||||
const unsigned short getIndice3() const { return _indice3; }
|
||||
const unsigned short getIndice4() const { return _indice4; }
|
||||
|
||||
protected:
|
||||
osg::Vec3d _vertex;
|
||||
unsigned short _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 short _mcount;
|
||||
unsigned short _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:
|
||||
osg::Vec3d _lastv;
|
||||
std::vector< osg::Vec3d > _vertices;
|
||||
double _elevation;
|
||||
unsigned short _flag;
|
||||
unsigned short _vcount; // 90
|
||||
osg::Vec3d _ocs; //210 220 230
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
120
src/osgPlugins/dxf/dxfFile.cpp
Normal file
120
src/osgPlugins/dxf/dxfFile.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "dxfFile.h"
|
||||
#include "dxfReader.h"
|
||||
#include "dxfBlock.h"
|
||||
#include "dxfEntity.h"
|
||||
#include "dxfDataTypes.h"
|
||||
#include "scene.h"
|
||||
#include "codeValue.h"
|
||||
|
||||
#include <osg/Group>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool
|
||||
dxfFile::parseFile()
|
||||
{
|
||||
if (_fileName == "") return false;
|
||||
_reader = new dxfReader;
|
||||
|
||||
if (_reader->openFile(_fileName)) {
|
||||
codeValue cv;
|
||||
while(_reader->nextGroupCode(cv)) {
|
||||
short result = assign(cv);
|
||||
if (result < 0)
|
||||
return false;
|
||||
else if (result == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// we did not reach 0 EOF
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Group*
|
||||
dxfFile::dxf2osg()
|
||||
{
|
||||
if (!_entities) return NULL;
|
||||
if (!_tables) { // a dxfTable is needed to create undefined layers
|
||||
_tables = new dxfTables;
|
||||
}
|
||||
osg::ref_ptr<dxfLayerTable> layerTable = _tables->getOrCreateLayerTable();
|
||||
// to do: should be more general and pass a pointer to ourselves
|
||||
// which in turn should be able to feed any information
|
||||
// the scene might need
|
||||
_scene = new scene(layerTable.get());
|
||||
_entities->drawScene(_scene.get());
|
||||
osg::Group* g = _scene->scene2osg();
|
||||
return g;
|
||||
}
|
||||
|
||||
dxfBlock*
|
||||
dxfFile::findBlock(std::string name)
|
||||
{
|
||||
if (_blocks.get())
|
||||
return _blocks->findBlock(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// not used. if you want to know what a header variable
|
||||
/// contains, call this. pass the complete variable name
|
||||
/// including "$", for example: "$EXTMAX"
|
||||
VariableList
|
||||
dxfFile::getVariable(std::string var)
|
||||
{
|
||||
return _header->getVariable(var);
|
||||
}
|
||||
|
||||
/// parse the dxf sections
|
||||
short
|
||||
dxfFile::assign(codeValue& cv)
|
||||
{
|
||||
std::string s = cv._string;
|
||||
if (cv._groupCode == 0 && s == std::string("ENDSEC")) {
|
||||
_isNewSection = false;
|
||||
_current = _unknown.get();
|
||||
} else if (cv._groupCode == 0 && s == std::string("SECTION")) {
|
||||
_isNewSection = true;
|
||||
} else if (cv._groupCode == 0 && s == std::string("EOF")) {
|
||||
return 0;
|
||||
} else if (cv._groupCode == 2 && _isNewSection) {
|
||||
_isNewSection = false;
|
||||
// std::cout << "Reading section " << s << std::endl;
|
||||
if (s =="HEADER") {
|
||||
_header = new dxfHeader;
|
||||
_current = _header.get();
|
||||
} else if (s =="TABLES") {
|
||||
_tables = new dxfTables;
|
||||
_current = _tables.get();
|
||||
} else if (s =="BLOCKS") {
|
||||
_blocks = new dxfBlocks;
|
||||
_current = _blocks.get();
|
||||
} else if (s =="ENTITIES") {
|
||||
_entities = new dxfEntities;
|
||||
_current = _entities.get();
|
||||
} else {
|
||||
_current = _unknown.get();
|
||||
}
|
||||
} else if (_isNewSection) {
|
||||
// problem. a 0/SECTION should be followed by a 2/SECTION_NAME
|
||||
std::cout << "No groupcode for changing section " << cv._groupCode << " value: " << s << std::endl;
|
||||
return -1;
|
||||
} else if (_current.get()) {
|
||||
_current->assign(this, cv);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
59
src/osgPlugins/dxf/dxfFile.h
Normal file
59
src/osgPlugins/dxf/dxfFile.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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_FILE
|
||||
#define DXF_FILE 1
|
||||
|
||||
#include <osg/Group>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "dxfSectionBase.h"
|
||||
#include "dxfReader.h"
|
||||
#include "dxfSection.h"
|
||||
#include "codeValue.h"
|
||||
|
||||
class dxfHeader;
|
||||
class dxfTables;
|
||||
class dxfBlocks;
|
||||
class dxfEntities;
|
||||
class dxfSection;
|
||||
class scene;
|
||||
class dxfBlock;
|
||||
|
||||
class dxfFile {
|
||||
public:
|
||||
dxfFile(std::string fileName) :
|
||||
_fileName(fileName),
|
||||
_isNewSection(false)
|
||||
{}
|
||||
bool parseFile();
|
||||
osg::Group* dxf2osg();
|
||||
dxfBlock* findBlock(std::string name);
|
||||
VariableList getVariable(std::string var);
|
||||
protected:
|
||||
short assign(codeValue& cv);
|
||||
std::string _fileName;
|
||||
bool _isNewSection;
|
||||
osg::ref_ptr<dxfReader> _reader;
|
||||
osg::ref_ptr<dxfSection> _current;
|
||||
osg::ref_ptr<dxfHeader> _header;
|
||||
osg::ref_ptr<dxfTables> _tables;
|
||||
osg::ref_ptr<dxfBlocks> _blocks;
|
||||
osg::ref_ptr<dxfEntities> _entities;
|
||||
osg::ref_ptr<dxfSection> _unknown;
|
||||
osg::ref_ptr<scene> _scene;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
204
src/osgPlugins/dxf/dxfReader.cpp
Normal file
204
src/osgPlugins/dxf/dxfReader.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/* 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.
|
||||
*/
|
||||
#include "dxfReader.h"
|
||||
#include "dxfDataTypes.h"
|
||||
#include "codeValue.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static
|
||||
std::string
|
||||
trim(const string& str)
|
||||
{
|
||||
if (!str.size()) return str;
|
||||
string::size_type first = str.find_first_not_of(" \t");
|
||||
string::size_type last = str.find_last_not_of(" \t\r\n");
|
||||
return str.substr(first, last-first+1);
|
||||
}
|
||||
|
||||
/*
|
||||
************** readerBase
|
||||
*/
|
||||
bool readerBase::readGroup(std::ifstream& f, codeValue& cv)
|
||||
{
|
||||
cv.reset();
|
||||
if (readGroupCode(f, cv._groupCode)) {
|
||||
cv._type = dxfDataType::typeForCode(cv._groupCode);
|
||||
switch (cv._type) {
|
||||
case dxfDataType::BOOL:
|
||||
return readValue(f, cv._bool);
|
||||
break;
|
||||
case dxfDataType::SHORT:
|
||||
return readValue(f, cv._short);
|
||||
break;
|
||||
case dxfDataType::INT:
|
||||
return readValue(f, cv._int);
|
||||
break;
|
||||
case dxfDataType::LONG:
|
||||
return readValue(f, cv._long);
|
||||
break;
|
||||
case dxfDataType::DOUBLE:
|
||||
return readValue(f, cv._double);
|
||||
break;
|
||||
case dxfDataType::UNKNOWN:
|
||||
case dxfDataType::STRING:
|
||||
case dxfDataType::HEX:
|
||||
default: // to do: default case an error
|
||||
return readValue(f, cv._string);
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
cv._type = dxfDataType::UNKNOWN;
|
||||
cv._groupCode = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
************** readerText
|
||||
*/
|
||||
|
||||
bool readerText::success(bool inSuccess, string type)
|
||||
{
|
||||
if (!inSuccess)
|
||||
cout << "Error converting line " << _lineCount << " to type " << type << endl;
|
||||
return inSuccess;
|
||||
}
|
||||
|
||||
bool readerText::getTrimmedLine(std::ifstream& f)
|
||||
{
|
||||
static string line = "";
|
||||
if (getline(f, line, _delim)) {
|
||||
++_lineCount;
|
||||
_str.clear();
|
||||
_str.str(trim(line));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool readerText::readGroupCode(std::ifstream& f, int &groupcode)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> groupcode;
|
||||
return success(!_str.fail(), "int");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool readerText::readValue(std::ifstream& f, string &s)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
getline(_str, s);
|
||||
// empty string is valid
|
||||
return success((!_str.fail() || s == ""), "string");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool readerText::readValue(std::ifstream& f, bool &b)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> b;
|
||||
return success(!_str.fail(), "bool");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool readerText::readValue(std::ifstream& f, unsigned short &s)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> s;
|
||||
return success(!_str.fail(), "unsigned short");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool readerText::readValue(std::ifstream& f, int &i)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> i;
|
||||
return success(!_str.fail(), "int");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool readerText::readValue(std::ifstream& f, long &l)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> l;
|
||||
return success(!_str.fail(), "long");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool readerText::readValue(std::ifstream& f, double &d)
|
||||
{
|
||||
if (getTrimmedLine(f)) {
|
||||
_str >> d;
|
||||
return success(!_str.fail(), "double");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
************** dxfReader
|
||||
*/
|
||||
|
||||
|
||||
bool
|
||||
dxfReader::openFile(std::string fileName)
|
||||
{
|
||||
if (fileName.size() == 0) return false;
|
||||
_ifs.open(fileName.c_str(), ios::binary); // found mac autocad with \r delimiters
|
||||
if (!_ifs) {
|
||||
cout << " Can't open " << fileName << endl;
|
||||
return false;
|
||||
}
|
||||
// A binary file starts with "AutoCAD Binary DXF<CR><LF><SUB><NULL>"
|
||||
|
||||
char buf[255];
|
||||
_ifs.get(buf, 255);
|
||||
string sentinel(buf);
|
||||
if (trim(sentinel) == "AutoCAD Binary DXF") {
|
||||
cout << " Binary DXF not supported. For now. Come back soon." << endl;
|
||||
return false;
|
||||
}
|
||||
string::size_type lf = sentinel.find('\n');
|
||||
string::size_type cr = sentinel.find('\r');
|
||||
// gossage. un mac peut mettre juste CR. ca fonctionne pas:
|
||||
// if (cr > 0 && (!lf || lf > cr + 1))
|
||||
// _reader = new readerText('\r');
|
||||
// else
|
||||
_reader = new readerText;
|
||||
_ifs.seekg(0, ios::beg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
dxfReader::nextGroupCode(codeValue& cv)
|
||||
{
|
||||
return (_reader->readGroup(_ifs, cv));
|
||||
}
|
||||
|
||||
102
src/osgPlugins/dxf/dxfReader.h
Normal file
102
src/osgPlugins/dxf/dxfReader.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* File handling.
|
||||
dxfFile creates a dxfReader, which in turn create a readerText or a readerBinary
|
||||
depending on file type.
|
||||
*/
|
||||
#ifndef DXF_READER
|
||||
#define DXF_READER 1
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
class codeValue;
|
||||
|
||||
/// readerBase. abstract base class for reading a dxf file
|
||||
/// and interpreting data types
|
||||
class readerBase :public osg::Referenced
|
||||
{
|
||||
public:
|
||||
readerBase() {}
|
||||
virtual ~readerBase() {}
|
||||
bool readGroup(std::ifstream& f, codeValue& cv);
|
||||
|
||||
protected:
|
||||
virtual bool readGroupCode(std::ifstream& f, int &groupcode) = 0;
|
||||
virtual bool readValue(std::ifstream& f, std::string &s) = 0;
|
||||
virtual bool readValue(std::ifstream& f, bool &b) = 0;
|
||||
virtual bool readValue(std::ifstream& f, unsigned short &s) = 0;
|
||||
virtual bool readValue(std::ifstream& f, int &i) = 0;
|
||||
virtual bool readValue(std::ifstream& f, long &l) = 0;
|
||||
virtual bool readValue(std::ifstream& f, double &d) = 0;
|
||||
};
|
||||
|
||||
/// readerText. convert data using stringstream.
|
||||
class readerText : public readerBase
|
||||
{
|
||||
public:
|
||||
readerText(char delim = '\n') : readerBase(), _lineCount(0), _delim(delim) {}
|
||||
virtual ~readerText() {}
|
||||
|
||||
protected:
|
||||
bool success(bool inSuccess, std::string type);
|
||||
bool getTrimmedLine(std::ifstream& f);
|
||||
|
||||
virtual bool readGroupCode(std::ifstream& f, int &groupcode);
|
||||
virtual bool readValue(std::ifstream& f, std::string &s);
|
||||
virtual bool readValue(std::ifstream& f, bool &b);
|
||||
virtual bool readValue(std::ifstream& f, unsigned short &s);
|
||||
virtual bool readValue(std::ifstream& f, int &i);
|
||||
virtual bool readValue(std::ifstream& f, long &l);
|
||||
virtual bool readValue(std::ifstream& f, double &d);
|
||||
std::stringstream _str;
|
||||
unsigned long _lineCount;
|
||||
char _delim;
|
||||
};
|
||||
|
||||
|
||||
/// readerBinary. to be implemented
|
||||
class readerBinary : public readerBase
|
||||
{
|
||||
public:
|
||||
readerBinary() : readerBase() {}
|
||||
virtual ~readerBinary() {}
|
||||
protected:
|
||||
virtual bool readGroupCode(std::ifstream& f, int &groupcode) {}
|
||||
virtual bool readValue(std::ifstream& f, std::string &s) {}
|
||||
virtual bool readValue(std::ifstream& f, bool &b) {}
|
||||
virtual bool readValue(std::ifstream& f, unsigned short &s) {}
|
||||
virtual bool readValue(std::ifstream& f, int &i) {}
|
||||
virtual bool readValue(std::ifstream& f, long &l) {}
|
||||
virtual bool readValue(std::ifstream& f, double &d) {}
|
||||
};
|
||||
|
||||
/// dxfReader. gets you through the dxf file, one group code/value pair at a time.
|
||||
/// just instanciate, openFile(), then loop while(nextGroupCode())
|
||||
class dxfReader : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
dxfReader() {}
|
||||
virtual ~dxfReader() {}
|
||||
bool openFile(std::string fileName);
|
||||
bool nextGroupCode(codeValue& cv);
|
||||
protected:
|
||||
std::ifstream _ifs;
|
||||
osg::ref_ptr<readerBase> _reader;
|
||||
};
|
||||
|
||||
#endif
|
||||
87
src/osgPlugins/dxf/dxfSection.cpp
Normal file
87
src/osgPlugins/dxf/dxfSection.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "dxfSection.h"
|
||||
#include "dxfEntity.h"
|
||||
#include "dxfBlock.h"
|
||||
|
||||
void dxfHeader::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
if (cv._groupCode == 9) {
|
||||
_inVariable = true;
|
||||
VariableList var;
|
||||
_variables[cv._string] = var;
|
||||
_currentVariable = cv._string;
|
||||
} else if (_inVariable) {
|
||||
VariableList& var = getVariable(_currentVariable);
|
||||
var.push_back(cv);
|
||||
}
|
||||
}
|
||||
|
||||
void dxfTables::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
if (cv._groupCode == 0 && cv._string == "TABLE") {
|
||||
_currentTable = NULL;
|
||||
} else if (cv._groupCode == 2 && !_currentTable.get()) {
|
||||
// treat layer table as a special case
|
||||
if (cv._string == "LAYER") {
|
||||
_layerTable = new dxfLayerTable;
|
||||
_currentTable = _layerTable.get();
|
||||
} else {
|
||||
_currentTable = new dxfTable;
|
||||
_others.push_back(_currentTable.get());
|
||||
}
|
||||
} else if (_currentTable.get()) {
|
||||
_currentTable->assign(dxf, cv);
|
||||
}
|
||||
}
|
||||
|
||||
void dxfBlocks::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
if (cv._groupCode == 0 && cv._string == std::string("BLOCK")) {
|
||||
_currentBlock = new dxfBlock;
|
||||
_blockList.push_back(_currentBlock);
|
||||
} else if (cv._groupCode == 0 && cv._string == std::string("ENDBLK") && _currentBlock) {
|
||||
std::string bn = _currentBlock->getName();
|
||||
_blockNameList[bn] = _currentBlock;
|
||||
} else if (_currentBlock) {
|
||||
_currentBlock->assign(dxf, cv);
|
||||
}
|
||||
}
|
||||
|
||||
void dxfEntities::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
if (cv._groupCode == 0) {
|
||||
if (_currentEntity && _currentEntity->done()) {
|
||||
_currentEntity = new dxfEntity(cv._string);
|
||||
_entityList.push_back(_currentEntity);
|
||||
} else if (_currentEntity) {
|
||||
_currentEntity->assign(dxf, cv);
|
||||
} else {
|
||||
_currentEntity = new dxfEntity(cv._string);
|
||||
_entityList.push_back(_currentEntity);
|
||||
}
|
||||
} else if (_currentEntity) {
|
||||
_currentEntity->assign(dxf, cv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dxfEntities::drawScene(scene* sc)
|
||||
{
|
||||
for (std::vector<dxfEntity*>::iterator itr = _entityList.begin();
|
||||
itr != _entityList.end(); ++itr)
|
||||
(*itr)->drawScene(sc);
|
||||
}
|
||||
dxfBlock*
|
||||
dxfBlocks::findBlock(std::string s) { return _blockNameList[s]; }
|
||||
|
||||
107
src/osgPlugins/dxf/dxfSection.h
Normal file
107
src/osgPlugins/dxf/dxfSection.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
Classes used to parse each section of a DXF file. Not all
|
||||
types of section has been defined here, just the ones
|
||||
I found of interest, ie HEADER, TABLES, BLOCKS, and ENTITIES.
|
||||
Yet to be implemented: CLASSES, OBJECTS, and THUMBNAILIMAGE.
|
||||
*/
|
||||
#ifndef DXF_SECTION
|
||||
#define DXF_SECTION 1
|
||||
|
||||
#include "dxfDataTypes.h"
|
||||
#include "dxfSectionBase.h"
|
||||
#include "dxfFile.h"
|
||||
#include "dxfTable.h"
|
||||
#include "codeValue.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
class dxfEntity;
|
||||
class dxfBlock;
|
||||
|
||||
|
||||
class dxfSection : public dxfSectionBase
|
||||
{
|
||||
public:
|
||||
dxfSection() {}
|
||||
virtual ~dxfSection() {}
|
||||
};
|
||||
|
||||
class dxfHeader : public dxfSection
|
||||
{
|
||||
public:
|
||||
dxfHeader() : _inVariable(false) {}
|
||||
virtual ~dxfHeader() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
VariableList& getVariable(std::string inVar) { return _variables[inVar]; }
|
||||
protected:
|
||||
std::map<std::string, VariableList> _variables;
|
||||
bool _inVariable;
|
||||
std::string _currentVariable;
|
||||
};
|
||||
|
||||
|
||||
class dxfTables : public dxfSection
|
||||
{
|
||||
public:
|
||||
dxfTables() : _inLayerTable(false) {}
|
||||
virtual ~dxfTables() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
dxfLayerTable* getOrCreateLayerTable()
|
||||
{
|
||||
if (!_layerTable.get())
|
||||
_layerTable = new dxfLayerTable;
|
||||
return _layerTable.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _inLayerTable;
|
||||
osg::ref_ptr<dxfLayerTable> _layerTable;
|
||||
std::vector<osg::ref_ptr<dxfTable> > _others;
|
||||
osg::ref_ptr<dxfTable> _currentTable;
|
||||
};
|
||||
|
||||
class dxfEntities : public dxfSection
|
||||
{
|
||||
public:
|
||||
dxfEntities() : _currentEntity(NULL) {}
|
||||
virtual ~dxfEntities() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
virtual void drawScene(scene* sc);
|
||||
|
||||
protected:
|
||||
dxfEntity* _currentEntity;
|
||||
std::vector<dxfEntity*> _entityList;
|
||||
|
||||
};
|
||||
|
||||
class dxfBlocks : public dxfSection
|
||||
{
|
||||
public:
|
||||
dxfBlocks() : _currentBlock(NULL) {}
|
||||
virtual ~dxfBlocks() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
dxfBlock* findBlock(std::string s);
|
||||
|
||||
protected:
|
||||
dxfBlock* _currentBlock;
|
||||
std::map<std::string, dxfBlock*> _blockNameList;
|
||||
std::vector<dxfBlock*> _blockList;
|
||||
};
|
||||
|
||||
#endif
|
||||
30
src/osgPlugins/dxf/dxfSectionBase.h
Normal file
30
src/osgPlugins/dxf/dxfSectionBase.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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_SECTIONBASE
|
||||
#define DXF_SECTIONBASE 1
|
||||
|
||||
#include <osg/Referenced>
|
||||
|
||||
class dxfFile;
|
||||
class codeValue;
|
||||
|
||||
/// abstract base class for sections. see dxfSection.h
|
||||
class dxfSectionBase : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
dxfSectionBase() {}
|
||||
virtual ~dxfSectionBase() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
46
src/osgPlugins/dxf/dxfTable.cpp
Normal file
46
src/osgPlugins/dxf/dxfTable.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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.
|
||||
*/
|
||||
#include "dxfTable.h"
|
||||
#include "dxfFile.h"
|
||||
#include "codeValue.h"
|
||||
|
||||
|
||||
void dxfLayer::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
switch (cv._groupCode) {
|
||||
case 2:
|
||||
_name = cv._string;
|
||||
break;
|
||||
case 62:
|
||||
_color = cv._short;
|
||||
if ((short)_color < 0) _frozen = true;
|
||||
break;
|
||||
case 70:
|
||||
_frozen = (bool)(cv._short & 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dxfLayerTable::assign(dxfFile* dxf, codeValue& cv)
|
||||
{
|
||||
std::string s = cv._string;
|
||||
if (cv._groupCode == 0 ) {
|
||||
if (_currentLayer.get()) {
|
||||
_layers[_currentLayer->getName()] = _currentLayer.get();
|
||||
}
|
||||
if (s == "LAYER") {
|
||||
_currentLayer = new dxfLayer;
|
||||
} // otherwise it's the close call from ENDTAB
|
||||
} else if (_currentLayer.get()) {
|
||||
_currentLayer->assign(dxf, cv);
|
||||
}
|
||||
}
|
||||
75
src/osgPlugins/dxf/dxfTable.h
Normal file
75
src/osgPlugins/dxf/dxfTable.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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_TABLE
|
||||
#define DXF_TABLE 1
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
class dxfFile;
|
||||
class codeValue;
|
||||
|
||||
// special case: the layer table
|
||||
|
||||
class dxfTable : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
dxfTable() {}
|
||||
virtual ~dxfTable() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv) {}
|
||||
};
|
||||
|
||||
|
||||
class dxfLayer : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
dxfLayer(std::string name = "0") : _name(name), _color(7), _frozen(false) {}
|
||||
virtual ~dxfLayer() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
virtual const std::string& getName() const { return _name; }
|
||||
virtual const unsigned short& getColor() const { return _color; }
|
||||
virtual void setName(const std::string& name) { _name = name; }
|
||||
const bool& getFrozen() const { return _frozen; }
|
||||
protected:
|
||||
std::string _name;
|
||||
unsigned short _color;
|
||||
bool _frozen;
|
||||
};
|
||||
|
||||
class dxfLayerTable : public dxfTable
|
||||
{
|
||||
public:
|
||||
dxfLayerTable() {}
|
||||
virtual ~dxfLayerTable() {}
|
||||
virtual void assign(dxfFile* dxf, codeValue& cv);
|
||||
|
||||
dxfLayer* findOrCreateLayer(std::string name)
|
||||
{
|
||||
if (name == "") name = "0"; // nowhere it is said "" is invalid, but...
|
||||
dxfLayer* layer = _layers[name].get();
|
||||
if (!layer) {
|
||||
layer = new dxfLayer;
|
||||
_layers[name] = layer;
|
||||
}
|
||||
return layer;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::map<std::string, osg::ref_ptr<dxfLayer> > _layers;
|
||||
osg::ref_ptr<dxfLayer> _currentLayer;
|
||||
};
|
||||
|
||||
#endif
|
||||
189
src/osgPlugins/dxf/scene.cpp
Normal file
189
src/osgPlugins/dxf/scene.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/* Importation de fichiers DXF dans OpenSceneGraph (see www.openscenegraph.org)
|
||||
Copyright (C) 2004 by Paul de Repentigny <pdr@grapharchitecture.com>
|
||||
*/
|
||||
|
||||
#include "scene.h"
|
||||
#include "dxfTable.h"
|
||||
#include "aci.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace std;
|
||||
|
||||
|
||||
osg::Vec4
|
||||
sceneLayer::getColor(unsigned short color)
|
||||
{
|
||||
// you're supposed to have a correct color in hand
|
||||
unsigned short r = color * 3;
|
||||
unsigned short g = color * 3 + 1;
|
||||
unsigned short b = color * 3 + 2;
|
||||
Vec4 c(aci::table[r], aci::table[g], aci::table[b], 1.0f);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
scene::scene(dxfLayerTable* lt) : _layerTable(lt)
|
||||
{
|
||||
_m.makeIdentity();
|
||||
_r.makeIdentity();
|
||||
}
|
||||
|
||||
void
|
||||
scene::setLayerTable(dxfLayerTable* lt)
|
||||
{
|
||||
_layerTable = lt;
|
||||
}
|
||||
|
||||
Vec3d scene::addVertex(Vec3d v)
|
||||
{
|
||||
v += _t;
|
||||
v = preMultd(_r, v);
|
||||
osg::Matrixd m = osg::Matrix::translate(v.x(), v.y(), v.z());
|
||||
m = m * _m;
|
||||
Vec3d a = preMultd(m, Vec3d(0,0,0));
|
||||
_b.expandBy(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
Vec3d scene::addNormal(Vec3d v)
|
||||
{
|
||||
// to do: vertices are not always listed in order. find why.
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
scene::addLine(std::string l, unsigned short color, Vec3d s, Vec3d e)
|
||||
{
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
if (layer->getFrozen()) return;
|
||||
sceneLayer* ly = findOrCreateSceneLayer(l);
|
||||
Vec3d a(addVertex(s)), b(addVertex(e));
|
||||
ly->_lines[correctedColorIndex(l, color)].push_back(a);
|
||||
ly->_lines[correctedColorIndex(l, color)].push_back(b);
|
||||
}
|
||||
void scene::addLineStrip(std::string l, unsigned short color, std::vector<Vec3d> vertices)
|
||||
{
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
if (layer->getFrozen()) return;
|
||||
sceneLayer* ly = findOrCreateSceneLayer(l);
|
||||
std::vector<Vec3d> converted;
|
||||
for (std::vector<Vec3d>::iterator itr = vertices.begin();
|
||||
itr != vertices.end(); ++itr) {
|
||||
converted.push_back(addVertex(*itr));
|
||||
}
|
||||
ly->_linestrips[correctedColorIndex(l, color)].push_back(converted);
|
||||
}
|
||||
void scene::addLineLoop(std::string l, unsigned short color, std::vector<Vec3d> vertices)
|
||||
{
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
if (layer->getFrozen()) return;
|
||||
sceneLayer* ly = findOrCreateSceneLayer(l);
|
||||
std::vector<Vec3d> converted;
|
||||
for (std::vector<Vec3d>::iterator itr = vertices.begin();
|
||||
itr != vertices.end(); ++itr) {
|
||||
converted.push_back(addVertex(*itr));
|
||||
}
|
||||
converted.push_back(addVertex(vertices.front()));
|
||||
ly->_linestrips[correctedColorIndex(l, color)].push_back(converted);
|
||||
}
|
||||
|
||||
|
||||
void scene::addTriangles(std::string l, unsigned short color, std::vector<Vec3d> vertices, bool inverted)
|
||||
{
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
if (layer->getFrozen()) return;
|
||||
sceneLayer* ly = findOrCreateSceneLayer(l);
|
||||
for (VList::iterator itr = vertices.begin();
|
||||
itr != vertices.end(); ) {
|
||||
VList::iterator a;
|
||||
VList::iterator b;
|
||||
VList::iterator c;
|
||||
if (inverted) {
|
||||
c = itr++;
|
||||
b = itr++;
|
||||
a = itr++;
|
||||
} else {
|
||||
a = itr++;
|
||||
b = itr++;
|
||||
c = itr++;
|
||||
}
|
||||
if (a != vertices.end() &&
|
||||
b != vertices.end() &&
|
||||
c != vertices.end()) {
|
||||
Vec3d n = ((*b - *a) ^ (*c - *a));
|
||||
n.normalize();
|
||||
ly->_trinorms[correctedColorIndex(l, color)].push_back( n );
|
||||
ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*a));
|
||||
ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*b));
|
||||
ly->_triangles[correctedColorIndex(l, color)].push_back(addVertex(*c));
|
||||
}
|
||||
}
|
||||
}
|
||||
void scene::addQuads(std::string l, unsigned short color, std::vector<Vec3d> vertices, bool inverted)
|
||||
{
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
if (layer->getFrozen()) return;
|
||||
|
||||
sceneLayer* ly = findOrCreateSceneLayer(l);
|
||||
for (VList::iterator itr = vertices.begin();
|
||||
itr != vertices.end(); ) {
|
||||
VList::iterator a = vertices.end();
|
||||
VList::iterator b = vertices.end();
|
||||
VList::iterator c = vertices.end();
|
||||
VList::iterator d = vertices.end();
|
||||
if (inverted) {
|
||||
d = itr++;
|
||||
if (itr != vertices.end())
|
||||
c = itr++;
|
||||
if (itr != vertices.end())
|
||||
b = itr++;
|
||||
if (itr != vertices.end())
|
||||
a = itr++;
|
||||
} else {
|
||||
a = itr++;
|
||||
if (itr != vertices.end())
|
||||
b = itr++;
|
||||
if (itr != vertices.end())
|
||||
c = itr++;
|
||||
if (itr != vertices.end())
|
||||
d = itr++;
|
||||
}
|
||||
if (a != vertices.end() &&
|
||||
b != vertices.end() &&
|
||||
c != vertices.end()&&
|
||||
d != vertices.end()) {
|
||||
Vec3d n = ((*b - *a) ^ (*c - *a));
|
||||
n.normalize();
|
||||
short cindex = correctedColorIndex(l, color);
|
||||
ly->_quadnorms[cindex].push_back( n );
|
||||
MapVList mvl = ly->_quads;
|
||||
VList vl = mvl[cindex];
|
||||
vl.push_back(addVertex(*a));
|
||||
vl.push_back(addVertex(*b));
|
||||
vl.push_back(addVertex(*c));
|
||||
vl.push_back(addVertex(*d));
|
||||
mvl[cindex] = vl;
|
||||
ly->_quads = mvl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned short
|
||||
scene::correctedColorIndex(std::string l, unsigned short color)
|
||||
{
|
||||
if (color >= aci::MIN && color <= aci::MAX) {
|
||||
return color;
|
||||
} else if (!color || color == aci::BYLAYER) {
|
||||
dxfLayer* layer = _layerTable->findOrCreateLayer(l);
|
||||
unsigned short lcolor = layer->getColor();
|
||||
if (lcolor >= aci::MIN && lcolor <= aci::MAX) {
|
||||
return lcolor;
|
||||
} else {
|
||||
return aci::WHITE;
|
||||
}
|
||||
} else {
|
||||
return aci::WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
327
src/osgPlugins/dxf/scene.h
Normal file
327
src/osgPlugins/dxf/scene.h
Normal file
@@ -0,0 +1,327 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
/** Simulate the scene with double precision before passing it back to osg.
|
||||
this permits us to scale down offsets from 0,0,0 with a few matrixtransforms,
|
||||
in case the objects are too far from that center.
|
||||
*/
|
||||
|
||||
#ifndef DXF_SCENE
|
||||
#define DXF_SCENE 1
|
||||
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Group>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Vec3d>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
|
||||
class dxfLayerTable;
|
||||
|
||||
class bounds {
|
||||
public:
|
||||
bounds() : _min(DBL_MAX, DBL_MAX, DBL_MAX), _max(-DBL_MAX, -DBL_MAX, -DBL_MAX) {}
|
||||
inline void expandBy(osg::Vec3d v) {
|
||||
if(v.x()<_min.x()) _min.x() = v.x();
|
||||
if(v.x()>_max.x()) _max.x() = v.x();
|
||||
|
||||
if(v.y()<_min.y()) _min.y() = v.y();
|
||||
if(v.y()>_max.y()) _max.y() = v.y();
|
||||
|
||||
if(v.z()<_min.z()) _min.z() = v.z();
|
||||
if(v.z()>_max.z()) _max.z() = v.z();
|
||||
}
|
||||
inline void makeMinValid() {
|
||||
// we count on _min to offset the whole scene
|
||||
// so, we make sure its at 0,0,0 if
|
||||
// bounds are not set (anyway, the scene should be empty,
|
||||
// if we need to set any value of _min to 0).
|
||||
if (_min.x() == DBL_MAX) _min.x() = 0;
|
||||
if (_min.y() == DBL_MAX) _min.y() = 0;
|
||||
if (_min.z() == DBL_MAX) _min.z() = 0;
|
||||
}
|
||||
osg::Vec3d _min;
|
||||
osg::Vec3d _max;
|
||||
};
|
||||
|
||||
|
||||
static inline
|
||||
osg::Geometry* createLnGeometry( osg::PrimitiveSet::Mode lineType, osg::Vec3Array* vertices, osg::Vec4 color)
|
||||
{
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
geom->setVertexArray(vertices);
|
||||
geom->addPrimitiveSet(new osg::DrawArrays(lineType, 0, vertices->size()));
|
||||
osg::Vec4Array* colors = new osg::Vec4Array;
|
||||
colors->push_back(color);
|
||||
geom->setColorArray(colors);
|
||||
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
osg::Vec3Array *norms = new osg::Vec3Array;
|
||||
norms->push_back(osg::Vec3(0,0,1));
|
||||
geom->setNormalArray(norms);
|
||||
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
|
||||
return geom;
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
osg::Geometry* createTriGeometry( osg::Vec3Array* vertices, osg::Vec3Array* normals, osg::Vec4 color)
|
||||
{
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
geom->setVertexArray(vertices);
|
||||
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));
|
||||
osg::Vec4Array* colors = new osg::Vec4Array;
|
||||
colors->push_back(color);
|
||||
geom->setColorArray(colors);
|
||||
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
return geom;
|
||||
}
|
||||
|
||||
static inline
|
||||
osg::Geometry* createQuadGeometry( osg::Vec3Array* vertices, osg::Vec3Array* normals, osg::Vec4 color)
|
||||
{
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
geom->setVertexArray(vertices);
|
||||
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertices->size()));
|
||||
osg::Vec4Array* colors = new osg::Vec4Array;
|
||||
colors->push_back(color);
|
||||
geom->setColorArray(colors);
|
||||
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
geom->setNormalArray(normals);
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
return geom;
|
||||
}
|
||||
static inline
|
||||
osg::Geode* createModel(std::string name, osg::Geometry* geom)
|
||||
{
|
||||
osg::Geode* geom_geode = new osg::Geode;
|
||||
geom_geode->addDrawable(geom);
|
||||
geom_geode->setName(name);
|
||||
return geom_geode;
|
||||
}
|
||||
|
||||
|
||||
static inline osg::Vec3d preMultd(const osg::Matrixd& m, const osg::Vec3d& v)
|
||||
{
|
||||
double d = 1.0f/(m(3,0)*v.x()+m(3,1)*v.y()+m(3,2)*v.z()+m(3,3)) ;
|
||||
return osg::Vec3d( (m(0,0)*v.x() + m(1,0)*v.y() + m(2,0)*v.z() + m(3,0))*d,
|
||||
(m(0,1)*v.x() + m(1,1)*v.y() + m(2,1)*v.z() + m(3,1))*d,
|
||||
(m(0,2)*v.x() + m(1,2)*v.y() + m(2,2)*v.z() + m(3,2))*d) ;
|
||||
}
|
||||
|
||||
static inline osg::Vec3d postMultd(const osg::Matrixd& m, const osg::Vec3d& v)
|
||||
{
|
||||
double d = 1.0f/(m(3,0)*v.x()+m(3,1)*v.y()+m(3,2)*v.z()+m(3,3)) ;
|
||||
return osg::Vec3d( (m(0,0)*v.x() + m(0,1)*v.y() + m(0,2)*v.z() + m(0,3))*d,
|
||||
(m(1,0)*v.x() + m(1,1)*v.y() + m(1,2)*v.z() + m(1,3))*d,
|
||||
(m(2,0)*v.x() + m(2,1)*v.y() + m(2,2)*v.z() + m(2,3))*d) ;
|
||||
}
|
||||
|
||||
typedef std::vector<osg::Vec3d> VList;
|
||||
typedef std::map<unsigned short, VList> MapVList;
|
||||
typedef std::vector<VList> VListList;
|
||||
typedef std::map<unsigned short, VListList> MapVListList;
|
||||
|
||||
|
||||
class sceneLayer : public osg::Referenced {
|
||||
public:
|
||||
sceneLayer(std::string name) : _name(name) {}
|
||||
virtual ~sceneLayer() {}
|
||||
void layer2osg(osg::Group* root, bounds &b)
|
||||
{
|
||||
osgLines(root, b);
|
||||
osgTriangles(root, b);
|
||||
osgQuads(root, b);
|
||||
}
|
||||
MapVListList _linestrips;
|
||||
MapVList _lines;
|
||||
MapVList _triangles;
|
||||
MapVList _trinorms;
|
||||
MapVList _quads;
|
||||
MapVList _quadnorms;
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
|
||||
osg::Vec4 getColor(unsigned short color);
|
||||
void osgLines(osg::Group* root, bounds &b)
|
||||
{
|
||||
for (MapVListList::iterator mitr = _linestrips.begin();
|
||||
mitr != _linestrips.end(); ++mitr) {
|
||||
for (VListList::iterator itr = mitr->second.begin();
|
||||
itr != mitr->second.end(); ++itr) {
|
||||
if (itr->size()) {
|
||||
osg::Vec3Array *coords = new osg::Vec3Array;
|
||||
for (VList::iterator vitr = itr->begin();
|
||||
vitr != itr->end(); ++vitr) {
|
||||
osg::Vec3 v(vitr->x() - b._min.x(), vitr->y() - b._min.y(), vitr->z() - b._min.z());
|
||||
coords->push_back(v);
|
||||
}
|
||||
root->addChild(createModel(_name, createLnGeometry(osg::PrimitiveSet::LINE_STRIP, coords, getColor(mitr->first))));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (MapVList::iterator mitr = _lines.begin();
|
||||
mitr != _lines.end(); ++mitr) {
|
||||
osg::Vec3Array *coords = new osg::Vec3Array;
|
||||
for (VList::iterator itr = mitr->second.begin();
|
||||
itr != mitr->second.end(); ++itr) {
|
||||
osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
|
||||
coords->push_back(v);
|
||||
}
|
||||
root->addChild(createModel(_name, createLnGeometry(osg::PrimitiveSet::LINES, coords, getColor(mitr->first))));
|
||||
}
|
||||
}
|
||||
|
||||
void osgTriangles(osg::Group* root, bounds &b)
|
||||
{
|
||||
if (_triangles.size()) {
|
||||
for (MapVList::iterator mitr = _triangles.begin();
|
||||
mitr != _triangles.end(); ++mitr) {
|
||||
osg::Vec3Array *coords = new osg::Vec3Array;
|
||||
for (VList::iterator itr = mitr->second.begin();
|
||||
itr != mitr->second.end(); ++itr) {
|
||||
osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
|
||||
coords->push_back(v);
|
||||
}
|
||||
osg::Vec3Array *norms = new osg::Vec3Array;
|
||||
VList normlist = _trinorms[mitr->first];
|
||||
for (VList::iterator itr = normlist.begin();
|
||||
itr != normlist.end(); ++itr) {
|
||||
norms->push_back(osg::Vec3(itr->x(), itr->y(), itr->z()));
|
||||
}
|
||||
root->addChild(createModel(_name, createTriGeometry(coords, norms, getColor(mitr->first))));
|
||||
}
|
||||
}
|
||||
}
|
||||
void osgQuads(osg::Group* root, bounds &b)
|
||||
{
|
||||
if (_quads.size()) {
|
||||
for (MapVList::iterator mitr = _quads.begin();
|
||||
mitr != _quads.end(); ++mitr) {
|
||||
osg::Vec3Array *coords = new osg::Vec3Array;
|
||||
for (VList::iterator itr = mitr->second.begin();
|
||||
itr != mitr->second.end(); ++itr) {
|
||||
osg::Vec3 v(itr->x() - b._min.x(), itr->y() - b._min.y(), itr->z() - b._min.z());
|
||||
coords->push_back(v);
|
||||
}
|
||||
osg::Vec3Array *norms = new osg::Vec3Array;
|
||||
VList normlist = _quadnorms[mitr->first];
|
||||
for (VList::iterator itr = normlist.begin();
|
||||
itr != normlist.end(); ++itr) {
|
||||
norms->push_back(osg::Vec3(itr->x(), itr->y(), itr->z()));
|
||||
}
|
||||
root->addChild(createModel(_name, createQuadGeometry(coords, norms, getColor(mitr->first))));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class scene : public osg::Referenced {
|
||||
public:
|
||||
scene(dxfLayerTable* lt = NULL);
|
||||
virtual ~scene() {}
|
||||
void setLayerTable(dxfLayerTable* lt);
|
||||
void pushMatrix(osg::Matrixd m, bool protect = false)
|
||||
{
|
||||
_mStack.push_back(_m);
|
||||
if (protect) // equivalent to setMatrix
|
||||
_m = m;
|
||||
else
|
||||
_m = _m * m;
|
||||
}
|
||||
void popMatrix()
|
||||
{
|
||||
_mStack.pop_back();
|
||||
if (_mStack.size())
|
||||
_m = _mStack.back();
|
||||
else
|
||||
_m.makeIdentity();
|
||||
}
|
||||
void ocs(osg::Matrixd r)
|
||||
{
|
||||
_r = r;
|
||||
}
|
||||
void blockOffset(osg::Vec3d t)
|
||||
{
|
||||
_t = t;
|
||||
}
|
||||
void ocs_clear()
|
||||
{
|
||||
_r.makeIdentity();
|
||||
}
|
||||
osg::Matrixd& backMatrix() { if (_mStack.size()) return _mStack.back(); else return _m; }
|
||||
|
||||
osg::Vec3d addVertex(osg::Vec3d v);
|
||||
osg::Vec3d addNormal(osg::Vec3d v);
|
||||
sceneLayer* findOrCreateSceneLayer(std::string l)
|
||||
{
|
||||
sceneLayer* ly = _layers[l].get();
|
||||
if (!ly) {
|
||||
ly = new sceneLayer(l);
|
||||
_layers[l] = ly;
|
||||
}
|
||||
return ly;
|
||||
}
|
||||
unsigned short correctedColorIndex(std::string l, unsigned short color);
|
||||
|
||||
void addLine(std::string l, unsigned short color, osg::Vec3d s, osg::Vec3d e);
|
||||
void addLineStrip(std::string l, unsigned short color, std::vector<osg::Vec3d> vertices);
|
||||
void addLineLoop(std::string l, unsigned short color, std::vector<osg::Vec3d> vertices);
|
||||
void addTriangles(std::string l, unsigned short color, std::vector<osg::Vec3d> vertices, bool inverted=false);
|
||||
void addQuads(std::string l, unsigned short color, std::vector<osg::Vec3d> vertices, bool inverted=false);
|
||||
osg::Group* scene2osg()
|
||||
{
|
||||
osg::Group* root = NULL;
|
||||
osg::Group* child = NULL;
|
||||
_b.makeMinValid();
|
||||
osg::Vec3 v = osg::Vec3(_b._min.x(), _b._min.y(), _b._min.z());
|
||||
double x = _b._min.x() - (double)v.x();
|
||||
double y = _b._min.y() - (double)v.y();
|
||||
double z = _b._min.z() - (double)v.z();
|
||||
osg::Matrix m = osg::Matrix::translate(v);
|
||||
root = new osg::MatrixTransform(m);
|
||||
if (x || y || z) {
|
||||
m = osg::Matrix::translate(x,y,z);
|
||||
child = new osg::MatrixTransform(m);
|
||||
root->addChild(child);
|
||||
} else {
|
||||
child = root;
|
||||
}
|
||||
// root = mt;
|
||||
for (std::map<std::string, osg::ref_ptr<sceneLayer> >::iterator litr = _layers.begin();
|
||||
litr != _layers.end(); ++litr) {
|
||||
sceneLayer* ly = (*litr).second.get();
|
||||
if (!ly) continue;
|
||||
osg::Group* lg = new osg::Group;
|
||||
lg->setName((*litr).first);
|
||||
child->addChild(lg);
|
||||
ly->layer2osg(lg, _b);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
protected:
|
||||
osg::Matrixd _m;
|
||||
osg::Matrixd _r;
|
||||
osg::Vec3d _t;
|
||||
bounds _b;
|
||||
std::map<std::string, osg::ref_ptr<sceneLayer> > _layers;
|
||||
std::vector<osg::Matrixd> _mStack;
|
||||
dxfLayerTable* _layerTable;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,8 @@
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include "osg/ClipPlane"
|
||||
#include <osg/ClipPlane>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include "osgDB/Registry"
|
||||
#include "osgDB/Input"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
|
||||
Reference in New Issue
Block a user