From d053d51cbaddfe3f87fc7d64838995cf59a5c1d7 Mon Sep 17 00:00:00 2001 From: val177 Date: Mon, 7 Sep 2015 12:40:54 +0300 Subject: [PATCH 1/3] Fixed issue #342 --HG-- branch : develop --- .../drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp index 4fece4653..df203f994 100644 --- a/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp +++ b/src/libs/vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.cpp @@ -195,12 +195,12 @@ QPointF VToolTriangle::FindPoint(const QPointF &axisP1, const QPointF &axisP2, c line.setAngle(axis.angle()); line.setLength(step); - int c = qFloor(hypotenuse.length()); + qint64 c = qFloor(hypotenuse.length()); while (1) { line.setLength(line.length()+step); - int a = qFloor(QLineF(line.p2(), firstPoint).length()); - int b = qFloor(QLineF(line.p2(), secondPoint).length()); + qint64 a = qFloor(QLineF(line.p2(), firstPoint).length()); + qint64 b = qFloor(QLineF(line.p2(), secondPoint).length()); if (c*c <= (a*a + b*b)) { return line.p2(); From c9eb629e8c143d246ccc022063a319ef114f4244 Mon Sep 17 00:00:00 2001 From: val177 Date: Mon, 7 Sep 2015 17:39:04 +0300 Subject: [PATCH 2/3] Added dxflib --HG-- branch : feature --- src/app/valentina/valentina.pro | 9 + src/libs/libs.pro | 1 + src/libs/vdxf/dxflib/dl_attributes.h | 260 + src/libs/vdxf/dxflib/dl_codes.h | 549 ++ src/libs/vdxf/dxflib/dl_creationadapter.h | 138 + src/libs/vdxf/dxflib/dl_creationinterface.h | 373 ++ src/libs/vdxf/dxflib/dl_dxf.cpp | 5926 +++++++++++++++++++ src/libs/vdxf/dxflib/dl_dxf.h | 522 ++ src/libs/vdxf/dxflib/dl_entities.h | 1805 ++++++ src/libs/vdxf/dxflib/dl_exception.h | 56 + src/libs/vdxf/dxflib/dl_extrusion.h | 154 + src/libs/vdxf/dxflib/dl_global.h | 13 + src/libs/vdxf/dxflib/dl_writer.h | 729 +++ src/libs/vdxf/dxflib/dl_writer_ascii.cpp | 167 + src/libs/vdxf/dxflib/dl_writer_ascii.h | 75 + src/libs/vdxf/stable.cpp | 30 + src/libs/vdxf/stable.h | 52 + src/libs/vdxf/vdxf.pri | 21 + src/libs/vdxf/vdxf.pro | 96 + 19 files changed, 10976 insertions(+) create mode 100644 src/libs/vdxf/dxflib/dl_attributes.h create mode 100644 src/libs/vdxf/dxflib/dl_codes.h create mode 100644 src/libs/vdxf/dxflib/dl_creationadapter.h create mode 100644 src/libs/vdxf/dxflib/dl_creationinterface.h create mode 100644 src/libs/vdxf/dxflib/dl_dxf.cpp create mode 100644 src/libs/vdxf/dxflib/dl_dxf.h create mode 100644 src/libs/vdxf/dxflib/dl_entities.h create mode 100644 src/libs/vdxf/dxflib/dl_exception.h create mode 100644 src/libs/vdxf/dxflib/dl_extrusion.h create mode 100644 src/libs/vdxf/dxflib/dl_global.h create mode 100644 src/libs/vdxf/dxflib/dl_writer.h create mode 100644 src/libs/vdxf/dxflib/dl_writer_ascii.cpp create mode 100644 src/libs/vdxf/dxflib/dl_writer_ascii.h create mode 100644 src/libs/vdxf/stable.cpp create mode 100644 src/libs/vdxf/stable.h create mode 100644 src/libs/vdxf/vdxf.pri create mode 100644 src/libs/vdxf/vdxf.pro diff --git a/src/app/valentina/valentina.pro b/src/app/valentina/valentina.pro index 550c86896..f64ed64d5 100644 --- a/src/app/valentina/valentina.pro +++ b/src/app/valentina/valentina.pro @@ -2066,6 +2066,15 @@ DEPENDPATH += $$PWD/../../libs/vobj win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vobj/$${DESTDIR}/vobj.lib else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vobj/$${DESTDIR}/libvobj.a +# VDxf static library +unix|win32: LIBS += -L$$OUT_PWD/../../libs/vdxf/$${DESTDIR}/ -lvdxf + +INCLUDEPATH += $$PWD/../../libs/vdxf +DEPENDPATH += $$PWD/../../libs/vdxf + +win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/vdxf.lib +else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/libvdxf.a + # VLayout static library unix|win32: LIBS += -L$$OUT_PWD/../../libs/vlayout/$${DESTDIR}/ -lvlayout diff --git a/src/libs/libs.pro b/src/libs/libs.pro index e793a3f55..af365e150 100644 --- a/src/libs/libs.pro +++ b/src/libs/libs.pro @@ -4,6 +4,7 @@ SUBDIRS = \ vpropertyexplorer \ ifc \ vobj \ + vdxf \ vlayout \ vgeometry \ vpatterndb \ diff --git a/src/libs/vdxf/dxflib/dl_attributes.h b/src/libs/vdxf/dxflib/dl_attributes.h new file mode 100644 index 000000000..7de8ad73d --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_attributes.h @@ -0,0 +1,260 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_ATTRIBUTES_H +#define DL_ATTRIBUTES_H + +#include "dl_global.h" + +#include +#include + +#include "dl_codes.h" + +/** + * Storing and passing around attributes. Attributes + * are the layer name, color, width and line type. + * + * @author Andrew Mustun + */ +class DXFLIB_EXPORT DL_Attributes +{ + +public: + + /** + * Default constructor. + */ + DL_Attributes() : + layer(""), + color(0), + color24(-1), + width(0), + linetype("BYLAYER"), + linetypeScale(1.0), + handle(-1), + inPaperSpace(false) + { + } + + /** + * Constructor for DXF attributes. + * + * @param layer Layer name for this entity or NULL for no layer + * (every entity should be on a named layer!). + * @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER. + * @param width Line thickness. Defaults to zero. -1 = BYLAYER, + * -2 = BYBLOCK, -3 = default width + * @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults + * to "BYLAYER" + */ + DL_Attributes(const std::string& layer, + int color, int width, + const std::string& linetype, + double linetypeScale) : + layer(layer), + color(color), + color24(-1), + width(width), + linetype(linetype), + linetypeScale(linetypeScale), + handle(-1), + inPaperSpace(false) + { + + } + + /** + * Constructor for DXF attributes. + * + * @param layer Layer name for this entity or NULL for no layer + * (every entity should be on a named layer!). + * @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER. + * @param color24 24 bit color (see DXF reference). + * @param width Line thickness. Defaults to zero. -1 = BYLAYER, + * -2 = BYBLOCK, -3 = default width + * @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults + * to "BYLAYER" + */ + DL_Attributes(const std::string& layer, + int color, int color24, int width, + const std::string& linetype, + int handle=-1) : + layer(layer), + color(color), + color24(color24), + width(width), + linetype(linetype), + linetypeScale(1.0), + handle(handle), + inPaperSpace(false) + { + } + + /** + * Sets the layer. If the given pointer points to NULL, the + * new layer name will be an empty but valid string. + */ + void setLayer(const std::string& layer) + { + this->layer = layer; + } + + /** + * @return Layer name. + */ + std::string getLayer() const + { + return layer; + } + + /** + * Sets the color. + * + * @see DL_Codes, dxfColors + */ + void setColor(int color) + { + this->color = color; + } + + /** + * Sets the 24bit color. + * + * @see DL_Codes, dxfColors + */ + void setColor24(int color) + { + this->color24 = color; + } + + /** + * @return Color. + * + * @see DL_Codes, dxfColors + */ + int getColor() const + { + return color; + } + + /** + * @return 24 bit color or -1 if no 24bit color is defined. + * + * @see DL_Codes, dxfColors + */ + int getColor24() const + { + return color24; + } + + /** + * Sets the width. + */ + void setWidth(int width) + { + this->width = width; + } + + /** + * @return Width. + */ + int getWidth() const + { + return width; + } + + /** + * Sets the line type. This can be any string and is not + * checked to be a valid line type. + */ + void setLinetype(const std::string& linetype) + { + this->linetype = linetype; + } + + /** + * Sets the entity specific line type scale. + */ + void setLinetypeScale(double linetypeScale) + { + this->linetypeScale = linetypeScale; + } + + double getLinetypeScale() const + { + return linetypeScale; + } + + /** + * @return Line type. + */ + std::string getLinetype() const + { + if (linetype.length()==0) + { + return "BYLAYER"; + } + else + { + return linetype; + } + } + + void setHandle(int h) + { + handle = h; + } + + int getHandle() const + { + return handle; + } + + void setInPaperSpace(bool on) + { + inPaperSpace = on; + } + + bool isInPaperSpace() + { + return inPaperSpace; + } + +private: + std::string layer; + int color; + int color24; + int width; + std::string linetype; + double linetypeScale; + int handle; + + // DXF code 67 (true: entity in paper space, false: entity in model space (default): + bool inPaperSpace; +}; + +#endif + +// EOF diff --git a/src/libs/vdxf/dxflib/dl_codes.h b/src/libs/vdxf/dxflib/dl_codes.h new file mode 100644 index 000000000..4cd116fad --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_codes.h @@ -0,0 +1,549 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** Copyright (C) 2001 Robert J. Campbell Jr. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +/** + * Defines common DXF codes and constants. + */ + +#ifndef DXF_CODES_H +#define DXF_CODES_H + +#include "dl_global.h" + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#if defined(__OS2__)||defined(__EMX__) +#define strcasecmp(s,t) stricmp(s,t) +#endif + +#if defined(_WIN32) +#define strcasecmp(s,t) _stricmp(s,t) +#endif + + +#ifdef _WIN32 +#undef M_PI +#define M_PI 3.14159265358979323846 +#pragma warning(disable : 4800) +#endif + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +#define DL_DXF_MAXLINE 1024 +#define DL_DXF_MAXGROUPCODE 1100 + +// used to mark invalid vectors: +//#define DL_DXF_MAXDOUBLE 1.0E+10 + +/** + * Codes for colors and DXF versions. + */ +class DXFLIB_EXPORT DL_Codes +{ +public: + /** + * Standard DXF colors. + */ + enum color + { + black = 250, + green = 3, + red = 1, + brown = 15, + yellow = 2, + cyan = 4, + magenta = 6, + gray = 8, + blue = 5, + l_blue = 163, + l_green = 121, + l_cyan = 131, + l_red = 23, + l_magenta = 221, + l_gray = 252, + white = 7, + bylayer = 256, + byblock = 0 + }; + + /** + * Version numbers for the DXF Format. + */ + enum version + { + AC1009, // R12 + AC1012, + AC1014, + AC1015 // R2000 + }; +}; + + +// Extended color palette: +// The first entry is only for direct indexing starting with [1] +// Color 1 is red (1,0,0) +const double dxfColors[][3] = +{ + {0,0,0}, // unused + {1,0,0}, // 1 + {1,1,0}, + {0,1,0}, + {0,1,1}, + {0,0,1}, + {1,0,1}, + {1,1,1}, // black or white + {0.5,0.5,0.5}, + {0.75,0.75,0.75}, + {1,0,0}, // 10 + {1,0.5,0.5}, + {0.65,0,0}, + {0.65,0.325,0.325}, + {0.5,0,0}, + {0.5,0.25,0.25}, + {0.3,0,0}, + {0.3,0.15,0.15}, + {0.15,0,0}, + {0.15,0.075,0.075}, + {1,0.25,0}, // 20 + {1,0.625,0.5}, + {0.65,0.1625,0}, + {0.65,0.4063,0.325}, + {0.5,0.125,0}, + {0.5,0.3125,0.25}, + {0.3,0.075,0}, + {0.3,0.1875,0.15}, + {0.15,0.0375,0}, + {0.15,0.0938,0.075}, + {1,0.5,0}, // 30 + {1,0.75,0.5}, + {0.65,0.325,0}, + {0.65,0.4875,0.325}, + {0.5,0.25,0}, + {0.5,0.375,0.25}, + {0.3,0.15,0}, + {0.3,0.225,0.15}, + {0.15,0.075,0}, + {0.15,0.1125,0.075}, + {1,0.75,0}, // 40 + {1,0.875,0.5}, + {0.65,0.4875,0}, + {0.65,0.5688,0.325}, + {0.5,0.375,0}, + {0.5,0.4375,0.25}, + {0.3,0.225,0}, + {0.3,0.2625,0.15}, + {0.15,0.1125,0}, + {0.15,0.1313,0.075}, + {1,1,0}, // 50 + {1,1,0.5}, + {0.65,0.65,0}, + {0.65,0.65,0.325}, + {0.5,0.5,0}, + {0.5,0.5,0.25}, + {0.3,0.3,0}, + {0.3,0.3,0.15}, + {0.15,0.15,0}, + {0.15,0.15,0.075}, + {0.75,1,0}, // 60 + {0.875,1,0.5}, + {0.4875,0.65,0}, + {0.5688,0.65,0.325}, + {0.375,0.5,0}, + {0.4375,0.5,0.25}, + {0.225,0.3,0}, + {0.2625,0.3,0.15}, + {0.1125,0.15,0}, + {0.1313,0.15,0.075}, + {0.5,1,0}, // 70 + {0.75,1,0.5}, + {0.325,0.65,0}, + {0.4875,0.65,0.325}, + {0.25,0.5,0}, + {0.375,0.5,0.25}, + {0.15,0.3,0}, + {0.225,0.3,0.15}, + {0.075,0.15,0}, + {0.1125,0.15,0.075}, + {0.25,1,0}, // 80 + {0.625,1,0.5}, + {0.1625,0.65,0}, + {0.4063,0.65,0.325}, + {0.125,0.5,0}, + {0.3125,0.5,0.25}, + {0.075,0.3,0}, + {0.1875,0.3,0.15}, + {0.0375,0.15,0}, + {0.0938,0.15,0.075}, + {0,1,0}, // 90 + {0.5,1,0.5}, + {0,0.65,0}, + {0.325,0.65,0.325}, + {0,0.5,0}, + {0.25,0.5,0.25}, + {0,0.3,0}, + {0.15,0.3,0.15}, + {0,0.15,0}, + {0.075,0.15,0.075}, + {0,1,0.25}, // 100 + {0.5,1,0.625}, + {0,0.65,0.1625}, + {0.325,0.65,0.4063}, + {0,0.5,0.125}, + {0.25,0.5,0.3125}, + {0,0.3,0.075}, + {0.15,0.3,0.1875}, + {0,0.15,0.0375}, + {0.075,0.15,0.0938}, + {0,1,0.5}, // 110 + {0.5,1,0.75}, + {0,0.65,0.325}, + {0.325,0.65,0.4875}, + {0,0.5,0.25}, + {0.25,0.5,0.375}, + {0,0.3,0.15}, + {0.15,0.3,0.225}, + {0,0.15,0.075}, + {0.075,0.15,0.1125}, + {0,1,0.75}, // 120 + {0.5,1,0.875}, + {0,0.65,0.4875}, + {0.325,0.65,0.5688}, + {0,0.5,0.375}, + {0.25,0.5,0.4375}, + {0,0.3,0.225}, + {0.15,0.3,0.2625}, + {0,0.15,0.1125}, + {0.075,0.15,0.1313}, + {0,1,1}, // 130 + {0.5,1,1}, + {0,0.65,0.65}, + {0.325,0.65,0.65}, + {0,0.5,0.5}, + {0.25,0.5,0.5}, + {0,0.3,0.3}, + {0.15,0.3,0.3}, + {0,0.15,0.15}, + {0.075,0.15,0.15}, + {0,0.75,1}, // 140 + {0.5,0.875,1}, + {0,0.4875,0.65}, + {0.325,0.5688,0.65}, + {0,0.375,0.5}, + {0.25,0.4375,0.5}, + {0,0.225,0.3}, + {0.15,0.2625,0.3}, + {0,0.1125,0.15}, + {0.075,0.1313,0.15}, + {0,0.5,1}, // 150 + {0.5,0.75,1}, + {0,0.325,0.65}, + {0.325,0.4875,0.65}, + {0,0.25,0.5}, + {0.25,0.375,0.5}, + {0,0.15,0.3}, + {0.15,0.225,0.3}, + {0,0.075,0.15}, + {0.075,0.1125,0.15}, + {0,0.25,1}, // 160 + {0.5,0.625,1}, + {0,0.1625,0.65}, + {0.325,0.4063,0.65}, + {0,0.125,0.5}, + {0.25,0.3125,0.5}, + {0,0.075,0.3}, + {0.15,0.1875,0.3}, + {0,0.0375,0.15}, + {0.075,0.0938,0.15}, + {0,0,1}, // 170 + {0.5,0.5,1}, + {0,0,0.65}, + {0.325,0.325,0.65}, + {0,0,0.5}, + {0.25,0.25,0.5}, + {0,0,0.3}, + {0.15,0.15,0.3}, + {0,0,0.15}, + {0.075,0.075,0.15}, + {0.25,0,1}, // 180 + {0.625,0.5,1}, + {0.1625,0,0.65}, + {0.4063,0.325,0.65}, + {0.125,0,0.5}, + {0.3125,0.25,0.5}, + {0.075,0,0.3}, + {0.1875,0.15,0.3}, + {0.0375,0,0.15}, + {0.0938,0.075,0.15}, + {0.5,0,1}, // 190 + {0.75,0.5,1}, + {0.325,0,0.65}, + {0.4875,0.325,0.65}, + {0.25,0,0.5}, + {0.375,0.25,0.5}, + {0.15,0,0.3}, + {0.225,0.15,0.3}, + {0.075,0,0.15}, + {0.1125,0.075,0.15}, + {0.75,0,1}, // 200 + {0.875,0.5,1}, + {0.4875,0,0.65}, + {0.5688,0.325,0.65}, + {0.375,0,0.5}, + {0.4375,0.25,0.5}, + {0.225,0,0.3}, + {0.2625,0.15,0.3}, + {0.1125,0,0.15}, + {0.1313,0.075,0.15}, + {1,0,1}, // 210 + {1,0.5,1}, + {0.65,0,0.65}, + {0.65,0.325,0.65}, + {0.5,0,0.5}, + {0.5,0.25,0.5}, + {0.3,0,0.3}, + {0.3,0.15,0.3}, + {0.15,0,0.15}, + {0.15,0.075,0.15}, + {1,0,0.75}, // 220 + {1,0.5,0.875}, + {0.65,0,0.4875}, + {0.65,0.325,0.5688}, + {0.5,0,0.375}, + {0.5,0.25,0.4375}, + {0.3,0,0.225}, + {0.3,0.15,0.2625}, + {0.15,0,0.1125}, + {0.15,0.075,0.1313}, + {1,0,0.5}, // 230 + {1,0.5,0.75}, + {0.65,0,0.325}, + {0.65,0.325,0.4875}, + {0.5,0,0.25}, + {0.5,0.25,0.375}, + {0.3,0,0.15}, + {0.3,0.15,0.225}, + {0.15,0,0.075}, + {0.15,0.075,0.1125}, + {1,0,0.25}, // 240 + {1,0.5,0.625}, + {0.65,0,0.1625}, + {0.65,0.325,0.4063}, + {0.5,0,0.125}, + {0.5,0.25,0.3125}, + {0.3,0,0.075}, + {0.3,0.15,0.1875}, + {0.15,0,0.0375}, + {0.15,0.075,0.0938}, + {0.33,0.33,0.33}, // 250 + {0.464,0.464,0.464}, + {0.598,0.598,0.598}, + {0.732,0.732,0.732}, + {0.866,0.866,0.866}, + {1,1,1} // 255 +} +; + + +// AutoCAD VERSION aliases +#define DL_VERSION_R12 DL_Codes::AC1009 +#define DL_VERSION_LT2 DL_Codes::AC1009 +#define DL_VERSION_R13 DL_Codes::AC1012 // not supported yet +#define DL_VERSION_LT95 DL_Codes::AC1012 // not supported yet +#define DL_VERSION_R14 DL_Codes::AC1014 // not supported yet +#define DL_VERSION_LT97 DL_Codes::AC1014 // not supported yet +#define DL_VERSION_LT98 DL_Codes::AC1014 // not supported yet +#define DL_VERSION_2000 DL_Codes::AC1015 +#define DL_VERSION_2002 DL_Codes::AC1015 + + +// DXF Group Codes: + +// Strings +#define DL_STRGRP_START 0 +#define DL_STRGRP_END 9 + +// Coordinates +#define DL_CRDGRP_START 10 +#define DL_CRDGRP_END 19 + +// Real values +#define DL_RLGRP_START 38 +#define DL_RLGRP_END 59 + +// Short integer values +#define DL_SHOGRP_START 60 +#define DL_SHOGRP_END 79 + +// New in Release 13, +#define DL_SUBCLASS 100 + +// More coordinates +#define DL_CRD2GRP_START 210 +#define DL_CRD2GRP_END 239 + +// Extended data strings +#define DL_ESTRGRP_START 1000 +#define DL_ESTRGRP_END 1009 + +// Extended data reals +#define DL_ERLGRP_START 1010 +#define DL_ERLGRP_END 1059 + + +#define DL_Y8_COORD_CODE 28 +#define DL_Z0_COORD_CODE 30 +#define DL_Z8_COORD_CODE 38 + +#define DL_POINT_COORD_CODE 10 +#define DL_INSERT_COORD_CODE 10 + +#define DL_CRD2GRP_START 210 +#define DL_CRD2GRP_END 239 + +#define DL_THICKNESS 39 +#define DL_FIRST_REAL_CODE THICKNESS +#define DL_LAST_REAL_CODE 59 +#define DL_FIRST_INT_CODE 60 +#define DL_ATTFLAGS_CODE 70 +#define DL_PLINE_FLAGS_CODE 70 +#define DL_LAYER_FLAGS_CODE 70 +#define DL_FLD_LEN_CODE 73 // Inside ATTRIB resbuf +#define DL_LAST_INT_CODE 79 +#define DL_X_EXTRU_CODE 210 +#define DL_Y_EXTRU_CODE 220 +#define DL_Z_EXTRU_CODE 230 +#define DL_COMMENT_CODE 999 + +// Start and endpoints of a line +#define DL_LINE_START_CODE 10 // Followed by x coord +#define DL_LINE_END_CODE 11 // Followed by x coord + +// Some codes used by blocks +#define DL_BLOCK_FLAGS_CODE 70 // An int containing flags +#define DL_BLOCK_BASE_CODE 10 // Origin of block definition +#define DL_XREF_DEPENDENT 16 // If a block contains an XREF +#define DL_XREF_RESOLVED 32 // If a XREF resolved ok +#define DL_REFERENCED 64 // If a block is ref'd in DWG + +#define DL_XSCALE_CODE 41 +#define DL_YSCALE_CODE 42 +#define DL_ANGLE_CODE 50 +#define DL_INS_POINT_CODE 10 // Followed by x of ins pnt +#define DL_NAME2_CODE 3 // Second appearance of name + +// Some codes used by circle entities +#define DL_CENTER_CODE 10 // Followed by x of center +#define DL_RADIUS_CODE 40 // Followd by radius of circle + +#define DL_COND_OP_CODE -4 // Conditional op,ads_ssget + +// When using ads_buildlist you MUST use RTDXF0 instead of these +#define DL_ENTITY_TYPE_CODE 0 // Then there is LINE, 3DFACE.. +#define DL_SES_CODE 0 // Start End String Code +#define DL_FILE_SEP_CODE 0 // File separator +#define DL_SOT_CODE 0 // Start Of Table +#define DL_TEXTVAL_CODE 1 +#define DL_NAME_CODE 2 +#define DL_BLOCK_NAME_CODE 2 +#define DL_SECTION_NAME_CODE 2 +#define DL_ENT_HAND_CODE 5 // What follows is hexa string +#define DL_TXT_STYLE_CODE 7 // Inside attributes +#define DL_LAYER_NAME_CODE 8 // What follows is layer name +#define DL_FIRST_XCOORD_CODE 10 // Group code x of 1st coord +#define DL_FIRST_YCOORD_CODE 20 // Group code y of 1st coord +#define DL_FIRST_ZCOORD_CODE 30 // Group code z of 1st coord +#define DL_L_START_CODE 10 +#define DL_L_END_CODE 11 +#define DL_TXTHI_CODE 40 +#define DL_SCALE_X_CODE 41 +#define DL_SCALE_Y_CODE 42 +#define DL_SCALE_Z_CODE 43 +#define DL_BULGE_CODE 42 // Used in PLINE verts for arcs +#define DL_ROTATION_CODE 50 +#define DL_COLOUR_CODE 62 // What follows is a color int +#define DL_LTYPE_CODE 6 // What follows is a linetype + + +// Attribute flags +#define DL_ATTS_FOLLOW_CODE 66 +#define DL_ATT_TAG_CODE 2 +#define DL_ATT_VAL_CODE 1 +#define DL_ATT_FLAGS_CODE 70 // 4 1 bit flags as follows... +#define DL_ATT_INVIS_FLAG 1 +#define DL_ATT_CONST_FLAG 2 +#define DL_ATT_VERIFY_FLAG 4 // Prompt and verify +#define DL_ATT_PRESET_FLAG 8 // No prompt and no verify + +// PLINE defines +// Flags +#define DL_OPEN_PLINE 0x00 +#define DL_CLOSED_PLINE 0x01 +#define DL_POLYLINE3D 0x80 +#define DL_PFACE_MESH 0x40 +#define DL_PGON_MESH 0x10 +// Vertices follow entity, required in POLYLINES +#define DL_VERTS_FOLLOW_CODE 66 // Value should always be 1 +#define DL_VERTEX_COORD_CODE 10 + + +// LAYER flags +#define DL_FROZEN 1 +#define DL_FROZEN_BY_DEF 2 +#define DL_LOCKED 4 +#define DL_OBJECT_USED 64 // Object is ref'd in the dwg + +#define DL_BLOCK_EN_CODE -2 // Block entity definition +#define DL_E_NAME -1 // Entity name + +// Extended data codes +#define DL_EXTD_SENTINEL (-3) +#define DL_EXTD_STR 1000 +#define DL_EXTD_APP_NAME 1001 +#define DL_EXTD_CTL_STR 1002 +#define DL_EXTD_LYR_STR 1003 +#define DL_EXTD_CHUNK 1004 +#define DL_EXTD_HANDLE 1005 +#define DL_EXTD_POINT 1010 +#define DL_EXTD_POS 1011 +#define DL_EXTD_DISP 1012 +#define DL_EXTD_DIR 1013 +#define DL_EXTD_FLOAT 1040 +#define DL_EXTD_DIST 1041 +#define DL_EXTD_SCALE 1042 +#define DL_EXTD_INT16 1070 +#define DL_EXTD_INT32 1071 + +// UCS codes for use in ads_trans +#define DL_WCS_TRANS_CODE 0 +#define DL_UCS_TRANS_CODE 1 +#define DL_DCS_TRANS_CODE 2 +#define DL_PCS_TRANS_CODE 3 + +#endif + diff --git a/src/libs/vdxf/dxflib/dl_creationadapter.h b/src/libs/vdxf/dxflib/dl_creationadapter.h new file mode 100644 index 000000000..8efe738e6 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_creationadapter.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_CREATIONADAPTER_H +#define DL_CREATIONADAPTER_H + +#include "dl_global.h" + +#include "dl_creationinterface.h" + +/** + * An abstract adapter class for receiving DXF events when a DXF file is being read. + * The methods in this class are empty. This class exists as convenience for creating + * listener objects. + * + * @author Andrew Mustun + */ +class DXFLIB_EXPORT DL_CreationAdapter : public DL_CreationInterface +{ +public: + DL_CreationAdapter() {} + virtual ~DL_CreationAdapter() {} + virtual void processCodeValuePair(unsigned int, const std::string&) {} + virtual void endSection() {} + virtual void addLayer(const DL_LayerData&) {} + virtual void addLinetype(const DL_LinetypeData&) {} + virtual void addLinetypeDash(double) {} + virtual void addBlock(const DL_BlockData&) {} + virtual void endBlock() {} + virtual void addTextStyle(const DL_StyleData&) {} + virtual void addPoint(const DL_PointData&) {} + virtual void addLine(const DL_LineData&) {} + virtual void addXLine(const DL_XLineData&) {} + virtual void addRay(const DL_RayData&) {} + + virtual void addArc(const DL_ArcData&) {} + virtual void addCircle(const DL_CircleData&) {} + virtual void addEllipse(const DL_EllipseData&) {} + + virtual void addPolyline(const DL_PolylineData&) {} + virtual void addVertex(const DL_VertexData&) {} + + virtual void addSpline(const DL_SplineData&) {} + virtual void addControlPoint(const DL_ControlPointData&) {} + virtual void addFitPoint(const DL_FitPointData&) {} + virtual void addKnot(const DL_KnotData&) {} + + virtual void addInsert(const DL_InsertData&) {} + + virtual void addMText(const DL_MTextData&) {} + virtual void addMTextChunk(const std::string&) {} + virtual void addText(const DL_TextData&) {} + virtual void addAttribute(const DL_AttributeData&) {} + + virtual void addDimAlign(const DL_DimensionData&, + const DL_DimAlignedData&) {} + virtual void addDimLinear(const DL_DimensionData&, + const DL_DimLinearData&) {} + virtual void addDimRadial(const DL_DimensionData&, + const DL_DimRadialData&) {} + virtual void addDimDiametric(const DL_DimensionData&, + const DL_DimDiametricData&) {} + virtual void addDimAngular(const DL_DimensionData&, + const DL_DimAngularData&) {} + virtual void addDimAngular3P(const DL_DimensionData&, + const DL_DimAngular3PData&) {} + virtual void addDimOrdinate(const DL_DimensionData&, + const DL_DimOrdinateData&) {} + virtual void addLeader(const DL_LeaderData&) {} + virtual void addLeaderVertex(const DL_LeaderVertexData&) {} + + virtual void addHatch(const DL_HatchData&) {} + + virtual void addTrace(const DL_TraceData&) {} + virtual void add3dFace(const DL_3dFaceData&) {} + virtual void addSolid(const DL_SolidData&) {} + + virtual void addImage(const DL_ImageData&) {} + virtual void linkImage(const DL_ImageDefData&) {} + virtual void addHatchLoop(const DL_HatchLoopData&) {} + virtual void addHatchEdge(const DL_HatchEdgeData&) {} + + virtual void addXRecord(const std::string&) {} + virtual void addXRecordString(int, const std::string&) {} + virtual void addXRecordReal(int, double) {} + virtual void addXRecordInt(int, int) {} + virtual void addXRecordBool(int, bool) {} + + virtual void addXDataApp(const std::string&) {} + virtual void addXDataString(int, const std::string&) {} + virtual void addXDataReal(int, double) {} + virtual void addXDataInt(int, int) {} + + virtual void addDictionary(const DL_DictionaryData&) {} + virtual void addDictionaryEntry(const DL_DictionaryEntryData&) {} + + virtual void endEntity() {} + + virtual void addComment(const std::string&) {} + + virtual void setVariableVector(const std::string&, double, double, double, int) {} + virtual void setVariableString(const std::string&, const std::string&, int) {} + virtual void setVariableInt(const std::string&, int, int) {} + virtual void setVariableDouble(const std::string&, double, int) {} +#ifdef DL_COMPAT + virtual void setVariableVector(const char*, double, double, double, int) {} + virtual void setVariableString(const char*, const char*, int) {} + virtual void setVariableInt(const char*, int, int) {} + virtual void setVariableDouble(const char*, double, int) {} + virtual void processCodeValuePair(unsigned int, char*) {} + virtual void addComment(const char*) {} + virtual void addMTextChunk(const char*) {} +#endif + virtual void endSequence() {} +}; + +#endif diff --git a/src/libs/vdxf/dxflib/dl_creationinterface.h b/src/libs/vdxf/dxflib/dl_creationinterface.h new file mode 100644 index 000000000..a824d4aa6 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_creationinterface.h @@ -0,0 +1,373 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_CREATIONINTERFACE_H +#define DL_CREATIONINTERFACE_H + +#include "dl_global.h" + +#include + +#include "dl_attributes.h" +#include "dl_codes.h" +#include "dl_entities.h" +#include "dl_extrusion.h" + +/** + * Abstract class (interface) for the creation of new entities. + * Inherit your class which takes care of the entities in the + * processed DXF file from this interface. + * + * Double arrays passed to your implementation contain 3 double + * values for x, y, z coordinates unless stated differently. + * + * @author Andrew Mustun + */ +class DXFLIB_EXPORT DL_CreationInterface +{ +public: + DL_CreationInterface() + { + extrusion = new DL_Extrusion; + } + virtual ~DL_CreationInterface() + { + delete extrusion; + } + + /** + * Called for every code / value tuple of the DXF file. The complete DXF file + * contents can be handled by the implemetation of this function. + */ + virtual void processCodeValuePair(unsigned int groupCode, const std::string& groupValue) = 0; + + /** + * Called when a section (entity, table entry, etc.) is finished. + */ + virtual void endSection() = 0; + + /** + * Called for every layer. + */ + virtual void addLayer(const DL_LayerData& data) = 0; + + /** + * Called for every linetype. + */ + virtual void addLinetype(const DL_LinetypeData& data) = 0; + + /** + * Called for every dash in linetype pattern + */ + virtual void addLinetypeDash(double length) = 0; + + /** + * Called for every block. Note: all entities added after this + * command go into this block until endBlock() is called. + * + * @see endBlock() + */ + virtual void addBlock(const DL_BlockData& data) = 0; + + /** Called to end the current block */ + virtual void endBlock() = 0; + + /** Called for every text style */ + virtual void addTextStyle(const DL_StyleData& data) = 0; + + /** Called for every point */ + virtual void addPoint(const DL_PointData& data) = 0; + + /** Called for every line */ + virtual void addLine(const DL_LineData& data) = 0; + + /** Called for every xline */ + virtual void addXLine(const DL_XLineData& data) = 0; + + /** Called for every ray */ + virtual void addRay(const DL_RayData& data) = 0; + + /** Called for every arc */ + virtual void addArc(const DL_ArcData& data) = 0; + + /** Called for every circle */ + virtual void addCircle(const DL_CircleData& data) = 0; + + /** Called for every ellipse */ + virtual void addEllipse(const DL_EllipseData& data) = 0; + + /** Called for every polyline start */ + virtual void addPolyline(const DL_PolylineData& data) = 0; + + /** Called for every polyline vertex */ + virtual void addVertex(const DL_VertexData& data) = 0; + + /** Called for every spline */ + virtual void addSpline(const DL_SplineData& data) = 0; + + /** Called for every spline control point */ + virtual void addControlPoint(const DL_ControlPointData& data) = 0; + + /** Called for every spline fit point */ + virtual void addFitPoint(const DL_FitPointData& data) = 0; + + /** Called for every spline knot value */ + virtual void addKnot(const DL_KnotData& data) = 0; + + /** Called for every insert. */ + virtual void addInsert(const DL_InsertData& data) = 0; + + /** Called for every trace start */ + virtual void addTrace(const DL_TraceData& data) = 0; + + /** Called for every 3dface start */ + virtual void add3dFace(const DL_3dFaceData& data) = 0; + + /** Called for every solid start */ + virtual void addSolid(const DL_SolidData& data) = 0; + + + /** Called for every Multi Text entity. */ + virtual void addMText(const DL_MTextData& data) = 0; + + /** + * Called for additional text chunks for MTEXT entities. + * The chunks come at 250 character in size each. Note that + * those chunks come before the actual MTEXT entity. + */ + virtual void addMTextChunk(const std::string& text) = 0; + + /** Called for every Text entity. */ + virtual void addText(const DL_TextData& data) = 0; + + /** Called for every Block Attribute entity. */ + virtual void addAttribute(const DL_AttributeData& data) = 0; + + /** + * Called for every aligned dimension entity. + */ + virtual void addDimAlign(const DL_DimensionData& data, + const DL_DimAlignedData& edata) = 0; + /** + * Called for every linear or rotated dimension entity. + */ + virtual void addDimLinear(const DL_DimensionData& data, + const DL_DimLinearData& edata) = 0; + + /** + * Called for every radial dimension entity. + */ + virtual void addDimRadial(const DL_DimensionData& data, + const DL_DimRadialData& edata) = 0; + + /** + * Called for every diametric dimension entity. + */ + virtual void addDimDiametric(const DL_DimensionData& data, + const DL_DimDiametricData& edata) = 0; + + /** + * Called for every angular dimension (2 lines version) entity. + */ + virtual void addDimAngular(const DL_DimensionData& data, + const DL_DimAngularData& edata) = 0; + + /** + * Called for every angular dimension (3 points version) entity. + */ + virtual void addDimAngular3P(const DL_DimensionData& data, + const DL_DimAngular3PData& edata) = 0; + + /** + * Called for every ordinate dimension entity. + */ + virtual void addDimOrdinate(const DL_DimensionData& data, + const DL_DimOrdinateData& edata) = 0; + + /** + * Called for every leader start. + */ + virtual void addLeader(const DL_LeaderData& data) = 0; + + /** + * Called for every leader vertex + */ + virtual void addLeaderVertex(const DL_LeaderVertexData& data) = 0; + + /** + * Called for every hatch entity. + */ + virtual void addHatch(const DL_HatchData& data) = 0; + + /** + * Called for every image entity. + */ + virtual void addImage(const DL_ImageData& data) = 0; + + /** + * Called for every image definition. + */ + virtual void linkImage(const DL_ImageDefData& data) = 0; + + /** + * Called for every hatch loop. + */ + virtual void addHatchLoop(const DL_HatchLoopData& data) = 0; + + /** + * Called for every hatch edge entity. + */ + virtual void addHatchEdge(const DL_HatchEdgeData& data) = 0; + + /** + * Called for every XRecord with the given handle. + */ + virtual void addXRecord(const std::string& handle) = 0; + + /** + * Called for XRecords of type string. + */ + virtual void addXRecordString(int code, const std::string& value) = 0; + + /** + * Called for XRecords of type double. + */ + virtual void addXRecordReal(int code, double value) = 0; + + /** + * Called for XRecords of type int. + */ + virtual void addXRecordInt(int code, int value) = 0; + + /** + * Called for XRecords of type bool. + */ + virtual void addXRecordBool(int code, bool value) = 0; + + /** + * Called for every beginning of an XData section of the given application. + */ + virtual void addXDataApp(const std::string& appId) = 0; + + /** + * Called for XData tuples. + */ + virtual void addXDataString(int code, const std::string& value) = 0; + + /** + * Called for XData tuples. + */ + virtual void addXDataReal(int code, double value) = 0; + + /** + * Called for XData tuples. + */ + virtual void addXDataInt(int code, int value) = 0; + + /** + * Called for dictionary objects. + */ + virtual void addDictionary(const DL_DictionaryData& data) = 0; + + /** + * Called for dictionary entries. + */ + virtual void addDictionaryEntry(const DL_DictionaryEntryData& data) = 0; + + /** + * Called after an entity has been completed. + */ + virtual void endEntity() = 0; + + /** + * Called for every comment in the DXF file (code 999). + */ + virtual void addComment(const std::string& comment) = 0; + + /** + * Called for every vector variable in the DXF file (e.g. "$EXTMIN"). + */ + virtual void setVariableVector(const std::string& key, double v1, double v2, double v3, int code) = 0; + + /** + * Called for every string variable in the DXF file (e.g. "$ACADVER"). + */ + virtual void setVariableString(const std::string& key, const std::string& value, int code) = 0; + + /** + * Called for every int variable in the DXF file (e.g. "$ACADMAINTVER"). + */ + virtual void setVariableInt(const std::string& key, int value, int code) = 0; + + /** + * Called for every double variable in the DXF file (e.g. "$DIMEXO"). + */ + virtual void setVariableDouble(const std::string& key, double value, int code) = 0; + +#ifdef DL_COMPAT + virtual void setVariableVector(const char* key, double v1, double v2, double v3, int code) = 0; + virtual void setVariableString(const char* key, const char* value, int code) = 0; + virtual void setVariableInt(const char* key, int value, int code) = 0; + virtual void setVariableDouble(const char* key, double value, int code) = 0; + virtual void processCodeValuePair(unsigned int groupCode, char* groupValue) = 0; + virtual void addComment(const char* comment) = 0; + virtual void addMTextChunk(const char* text) = 0; +#endif + + /** + * Called when a SEQEND occurs (when a POLYLINE or ATTRIB is done) + */ + virtual void endSequence() = 0; + + /** Sets the current attributes for entities. */ + void setAttributes(const DL_Attributes& attrib) + { + attributes = attrib; + } + + /** @return the current attributes used for new entities. */ + DL_Attributes getAttributes() + { + return attributes; + } + + /** Sets the current attributes for entities. */ + void setExtrusion(double dx, double dy, double dz, double elevation) + { + extrusion->setDirection(dx, dy, dz); + extrusion->setElevation(elevation); + } + + /** @return the current attributes used for new entities. */ + DL_Extrusion* getExtrusion() + { + return extrusion; + } + +protected: + DL_Attributes attributes; + DL_Extrusion *extrusion; +}; + +#endif diff --git a/src/libs/vdxf/dxflib/dl_dxf.cpp b/src/libs/vdxf/dxflib/dl_dxf.cpp new file mode 100644 index 000000000..3eea2dd09 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_dxf.cpp @@ -0,0 +1,5926 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "dl_dxf.h" + +#include +#include +#include +#include +#include + +#include "dl_attributes.h" +#include "dl_codes.h" +#include "dl_creationadapter.h" +#include "dl_writer_ascii.h" + +#include "iostream" + +/** + * Default constructor. + */ +DL_Dxf::DL_Dxf() +{ + version = DL_VERSION_2000; + + vertices = NULL; + maxVertices = 0; + vertexIndex = 0; + + knots = NULL; + maxKnots = 0; + knotIndex = 0; + + weights = NULL; + weightIndex = 0; + + controlPoints = NULL; + maxControlPoints = 0; + controlPointIndex = 0; + + fitPoints = NULL; + maxFitPoints = 0; + fitPointIndex = 0; + + leaderVertices = NULL; + maxLeaderVertices = 0; + leaderVertexIndex = 0; +} + + + +/** + * Destructor. + */ +DL_Dxf::~DL_Dxf() +{ + if (vertices!=NULL) + { + delete[] vertices; + } + if (knots!=NULL) + { + delete[] knots; + } + if (controlPoints!=NULL) + { + delete[] controlPoints; + } + if (fitPoints!=NULL) + { + delete[] fitPoints; + } + if (weights!=NULL) + { + delete[] weights; + } + if (leaderVertices!=NULL) + { + delete[] leaderVertices; + } +} + + + +/** + * @brief Reads the given file and calls the appropriate functions in + * the given creation interface for every entity found in the file. + * + * @param file Input + * Path and name of file to read + * @param creationInterface + * Pointer to the class which takes care of the entities in the file. + * + * @retval true If \p file could be opened. + * @retval false If \p file could not be opened. + */ +bool DL_Dxf::in(const std::string& file, DL_CreationInterface* creationInterface) +{ + FILE *fp; + firstCall = true; + currentObjectType = DL_UNKNOWN; + + fp = fopen(file.c_str(), "rt"); + if (fp) + { + while (readDxfGroups(fp, creationInterface)) {} + fclose(fp); + return true; + } + + return false; +} + + + +/** + * Reads a DXF file from an existing stream. + * + * @param stream The string stream. + * @param creationInterface + * Pointer to the class which takes care of the entities in the file. + * + * @retval true If \p file could be opened. + * @retval false If \p file could not be opened. + */ +bool DL_Dxf::in(std::stringstream& stream, + DL_CreationInterface* creationInterface) +{ + + if (stream.good()) + { + firstCall=true; + currentObjectType = DL_UNKNOWN; + while (readDxfGroups(stream, creationInterface)) {} + return true; + } + return false; +} + + + +/** + * @brief Reads a group couplet from a DXF file. Calls another function + * to process it. + * + * A group couplet consists of two lines that represent a single + * piece of data. An integer constant on the first line indicates + * the type of data. The value is on the next line.\n + * + * This function reads a couplet, determines the type of data, and + * passes the value to the the appropriate handler function of + * \p creationInterface.\n + * + * \p fp is advanced so that the next call to \p readDXFGroups() reads + * the next couplet in the file. + * + * @param fp Handle of input file + * @param creationInterface Handle of class which processes entities + * in the file + * + * @retval true If EOF not reached. + * @retval false If EOF reached. + */ +bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface) +{ + + static int line = 1; + + // Read one group of the DXF file and strip the lines: + if (DL_Dxf::getStrippedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) && + DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, fp) ) + { + + groupCode = (unsigned int)toInt(groupCodeTmp); + + creationInterface->processCodeValuePair(groupCode, groupValue); + line+=2; + processDXFGroup(creationInterface, groupCode, groupValue); + } + + return !feof(fp); +} + + + +/** + * Same as above but for stringstreams. + */ +bool DL_Dxf::readDxfGroups(std::stringstream& stream, + DL_CreationInterface* creationInterface) +{ + + static int line = 1; + + // Read one group of the DXF file and chop the lines: + if (DL_Dxf::getStrippedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) && + DL_Dxf::getStrippedLine(groupValue, DL_DXF_MAXLINE, stream) ) + { + + groupCode = (unsigned int)toInt(groupCodeTmp); + + line+=2; + processDXFGroup(creationInterface, groupCode, groupValue); + } + return !stream.eof(); +} + + + +/** + * @brief Reads line from file & strips whitespace at start and newline + * at end. + * + * @param s Output\n + * Pointer to character array that chopped line will be returned in. + * @param size Size of \p s. (Including space for NULL.) + * @param fp Input\n + * Handle of input file. + * + * @retval true if line could be read + * @retval false if \p fp is already at end of file + * + * @todo Change function to use safer FreeBSD strl* functions + * @todo Is it a problem if line is blank (i.e., newline only)? + * Then, when function returns, (s==NULL). + */ +bool DL_Dxf::getStrippedLine(std::string& s, unsigned int size, FILE *fp) +{ + if (!feof(fp)) + { + // The whole line in the file. Includes space for NULL. + char* wholeLine = new char[size]; + // Only the useful part of the line + char* line; + + line = fgets(wholeLine, size, fp); + + if (line!=NULL && line[0] != '\0') // Evaluates to fgets() retval + { + // line == wholeLine at this point. + // Both guaranteed to be NULL terminated. + + // Strip leading whitespace and trailing CR/LF. + stripWhiteSpace(&line); + + s = line; + assert(size > s.length()); + } + + delete[] wholeLine; // Done with wholeLine + + return true; + } + else + { + s = ""; + return false; + } +} + + + +/** + * Same as above but for stringstreams. + */ +bool DL_Dxf::getStrippedLine(std::string &s, unsigned int size, + std::stringstream& stream) +{ + + if (!stream.eof()) + { + // Only the useful part of the line + char* line = new char[size+1]; + char* oriLine = line; + stream.getline(line, size); + stripWhiteSpace(&line); + s = line; + assert(size > s.length()); + delete[] oriLine; + return true; + } + else + { + s[0] = '\0'; + return false; + } +} + + + +/** + * @brief Strips leading whitespace and trailing Carriage Return (CR) + * and Line Feed (LF) from NULL terminated string. + * + * @param s Input and output. + * NULL terminates string. + * + * @retval true if \p s is non-NULL + * @retval false if \p s is NULL + */ +bool DL_Dxf::stripWhiteSpace(char** s) +{ + // last non-NULL char: + int lastChar = strlen(*s) - 1; + + // Is last character CR or LF? + while ( (lastChar >= 0) && + (((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) || + ((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) ) + { + (*s)[lastChar] = '\0'; + lastChar--; + } + + // Skip whitespace, excluding \n, at beginning of line + while ((*s)[0]==' ' || (*s)[0]=='\t') + { + ++(*s); + } + + return ((*s) ? true : false); +} + + + +/** + * Processes a group (pair of group code and value). + * + * @param creationInterface Handle to class that creates entities and + * other CAD data from DXF group codes + * + * @param groupCode Constant indicating the data type of the group. + * @param groupValue The data value. + * + * @retval true if done processing current entity and new entity begun + * @retval false if not done processing current entity +*/ +bool DL_Dxf::processDXFGroup(DL_CreationInterface* creationInterface, + int groupCode, const std::string& groupValue) +{ + + //printf("%d\n", groupCode); + //printf("%s\n", groupValue.c_str()); + + // Init values on first call + if (firstCall) + { + settingValue[0] = '\0'; + firstCall=false; + } + + // Indicates comment or dxflib version: + if (groupCode==999) + { + if (!groupValue.empty()) + { + if (groupValue.substr(0, 6)=="dxflib") + { + libVersion = getLibVersion(groupValue.substr(7)); + } + + addComment(creationInterface, groupValue); + } + } + + // Indicates start of new entity or variable: + else if (groupCode==0 || groupCode==9) + { + // If new entity is encountered, the last one is complete. + // Prepare default attributes for next entity: + std::string layer = getStringValue(8, "0"); + + int width; + // Compatibility with qcad1: + if (hasValue(39) && !hasValue(370)) + { + width = getIntValue(39, -1); + } + // since autocad 2002: + else if (hasValue(370)) + { + width = getIntValue(370, -1); + } + // default to BYLAYER: + else + { + width = -1; + } + + int color; + color = getIntValue(62, 256); + int color24; + color24 = getIntValue(420, -1); + int handle; + handle = getIntValue(5, -1); + + std::string linetype = getStringValue(6, "BYLAYER"); + + attrib = DL_Attributes(layer, // layer + color, // color + color24, // 24 bit color + width, // width + linetype, // linetype + handle); // handle + attrib.setInPaperSpace((bool)getIntValue(67, 0)); + attrib.setLinetypeScale(getRealValue(48, 1.0)); + creationInterface->setAttributes(attrib); + + int elevationGroupCode=30; + if (currentObjectType==DL_ENTITY_LWPOLYLINE ) + { + // see lwpolyline group codes reference + elevationGroupCode=38; + } + else + { + // see polyline group codes reference + elevationGroupCode=30; + } + + creationInterface->setExtrusion(getRealValue(210, 0.0), + getRealValue(220, 0.0), + getRealValue(230, 1.0), + getRealValue(elevationGroupCode, 0.0)); + + // Add the previously parsed entity via creationInterface + switch (currentObjectType) + { + case DL_SETTING: + addSetting(creationInterface); + break; + + case DL_LAYER: + addLayer(creationInterface); + break; + + case DL_LINETYPE: + addLinetype(creationInterface); + break; + + case DL_BLOCK: + addBlock(creationInterface); + break; + + case DL_ENDBLK: + endBlock(creationInterface); + break; + + case DL_STYLE: + addTextStyle(creationInterface); + break; + + case DL_ENTITY_POINT: + addPoint(creationInterface); + break; + + case DL_ENTITY_LINE: + addLine(creationInterface); + break; + + case DL_ENTITY_XLINE: + addXLine(creationInterface); + break; + + case DL_ENTITY_RAY: + addRay(creationInterface); + break; + + case DL_ENTITY_POLYLINE: + case DL_ENTITY_LWPOLYLINE: + addPolyline(creationInterface); + break; + + case DL_ENTITY_VERTEX: + addVertex(creationInterface); + break; + + case DL_ENTITY_SPLINE: + addSpline(creationInterface); + break; + + case DL_ENTITY_ARC: + addArc(creationInterface); + break; + + case DL_ENTITY_CIRCLE: + addCircle(creationInterface); + break; + + case DL_ENTITY_ELLIPSE: + addEllipse(creationInterface); + break; + + case DL_ENTITY_INSERT: + addInsert(creationInterface); + break; + + case DL_ENTITY_MTEXT: + addMText(creationInterface); + break; + + case DL_ENTITY_TEXT: + addText(creationInterface); + break; + + case DL_ENTITY_ATTRIB: + addAttribute(creationInterface); + break; + + case DL_ENTITY_DIMENSION: + { + int type = (getIntValue(70, 0)&0x07); + + switch (type) + { + case 0: + addDimLinear(creationInterface); + break; + + case 1: + addDimAligned(creationInterface); + break; + + case 2: + addDimAngular(creationInterface); + break; + + case 3: + addDimDiametric(creationInterface); + break; + + case 4: + addDimRadial(creationInterface); + break; + + case 5: + addDimAngular3P(creationInterface); + break; + + case 6: + addDimOrdinate(creationInterface); + break; + + default: + break; + } + } + break; + + case DL_ENTITY_LEADER: + addLeader(creationInterface); + break; + + case DL_ENTITY_HATCH: + //addHatch(creationInterface); + handleHatchData(creationInterface); + break; + + case DL_ENTITY_IMAGE: + addImage(creationInterface); + break; + + case DL_ENTITY_IMAGEDEF: + addImageDef(creationInterface); + break; + + case DL_ENTITY_TRACE: + addTrace(creationInterface); + break; + + case DL_ENTITY_3DFACE: + add3dFace(creationInterface); + break; + + case DL_ENTITY_SOLID: + addSolid(creationInterface); + break; + + case DL_ENTITY_SEQEND: + endSequence(creationInterface); + break; + + default: + break; + } + + creationInterface->endSection(); + + // reset all values (they are not persistent and only this + // way we can set defaults for omitted values) +// for (int i=0; iaddComment(comment); +} + +void DL_Dxf::addDictionary(DL_CreationInterface* creationInterface) +{ + creationInterface->addDictionary(DL_DictionaryData(getStringValue(5, ""))); +} + +void DL_Dxf::addDictionaryEntry(DL_CreationInterface* creationInterface) +{ + creationInterface->addDictionaryEntry(DL_DictionaryEntryData(getStringValue(3, ""), getStringValue(350, ""))); +} + + + +/** + * Adds a variable from the DXF file. + */ +void DL_Dxf::addSetting(DL_CreationInterface* creationInterface) +{ + int c = -1; + std::map::iterator it = values.begin(); + if (it!=values.end()) + { + c = it->first; + } +// for (int i=0; i<=380; ++i) { +// if (values[i][0]!='\0') { +// c = i; +// break; +// } +// } + + // string + if (c>=0 && c<=9) + { + creationInterface->setVariableString(settingKey, values[c], c); +#ifdef DL_COMPAT + // backwards compatibility: + creationInterface->setVariableString(settingKey.c_str(), values[c].c_str(), c); +#endif + } + // vector + else if (c>=10 && c<=39) + { + if (c==10) + { + creationInterface->setVariableVector( + settingKey, + getRealValue(c, 0.0), + getRealValue(c+10, 0.0), + getRealValue(c+20, 0.0), + c); + } + } + // double + else if (c>=40 && c<=59) + { + creationInterface->setVariableDouble(settingKey, getRealValue(c, 0.0), c); + } + // int + else if (c>=60 && c<=99) + { + creationInterface->setVariableInt(settingKey, getIntValue(c, 0), c); + } + // misc + else if (c>=0) + { + creationInterface->setVariableString(settingKey, getStringValue(c, ""), c); + } +} + + + +/** + * Adds a layer that was read from the file via the creation interface. + */ +void DL_Dxf::addLayer(DL_CreationInterface* creationInterface) +{ + // correct some invalid attributes for layers: + attrib = creationInterface->getAttributes(); + if (attrib.getColor()==256 || attrib.getColor()==0) + { + attrib.setColor(7); + } + if (attrib.getWidth()<0) + { + attrib.setWidth(1); + } + + std::string linetype = attrib.getLinetype(); + std::transform(linetype.begin(), linetype.end(), linetype.begin(), ::toupper); + if (linetype=="BYLAYER" || linetype=="BYBLOCK") + { + attrib.setLinetype("CONTINUOUS"); + } + + // add layer + std::string name = getStringValue(2, ""); + if (name.length()==0) + { + return; + } + + creationInterface->addLayer(DL_LayerData(name, getIntValue(70, 0))); +} + +/** + * Adds a linetype that was read from the file via the creation interface. + */ +void DL_Dxf::addLinetype(DL_CreationInterface* creationInterface) +{ + std::string name = getStringValue(2, ""); + if (name.length()==0) + { + return; + } + int numDashes = getIntValue(73, 0); + //double dashes[numDashes]; + + DL_LinetypeData d( + // name: + name, + // description: + getStringValue(3, ""), + // flags + getIntValue(70, 0), + // number of dashes: + numDashes, + // pattern length: + getRealValue(40, 0.0) + // pattern: + //dashes + ); + + if (name != "By Layer" && name != "By Block" && name != "BYLAYER" && name != "BYBLOCK") + { + creationInterface->addLinetype(d); + } +} + +/** + * Handles all dashes in linetype pattern. + */ +bool DL_Dxf::handleLinetypeData(DL_CreationInterface* creationInterface) +{ + if (groupCode == 49) + { + creationInterface->addLinetypeDash(toReal(groupValue)); + return true; + } + + return false; +} + + +/** + * Adds a block that was read from the file via the creation interface. + */ +void DL_Dxf::addBlock(DL_CreationInterface* creationInterface) +{ + std::string name = getStringValue(2, ""); + if (name.length()==0) + { + return; + } + + DL_BlockData d( + // Name: + name, + // flags: + getIntValue(70, 0), + // base point: + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0)); + + creationInterface->addBlock(d); +} + + + +/** + * Ends a block that was read from the file via the creation interface. + */ +void DL_Dxf::endBlock(DL_CreationInterface* creationInterface) +{ + creationInterface->endBlock(); +} + + + +void DL_Dxf::addTextStyle(DL_CreationInterface* creationInterface) +{ + std::string name = getStringValue(2, ""); + if (name.length()==0) + { + return; + } + + DL_StyleData d( + // name: + name, + // flags + getIntValue(70, 0), + // fixed text heigth: + getRealValue(40, 0.0), + // width factor: + getRealValue(41, 0.0), + // oblique angle: + getRealValue(50, 0.0), + // text generation flags: + getIntValue(71, 0), + // last height used: + getRealValue(42, 0.0), + // primart font file: + getStringValue(3, ""), + // big font file: + getStringValue(4, "") + ); + creationInterface->addTextStyle(d); +} + + +/** + * Adds a point entity that was read from the file via the creation interface. + */ +void DL_Dxf::addPoint(DL_CreationInterface* creationInterface) +{ + DL_PointData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0)); + creationInterface->addPoint(d); +} + + + +/** + * Adds a line entity that was read from the file via the creation interface. + */ +void DL_Dxf::addLine(DL_CreationInterface* creationInterface) +{ + DL_LineData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0)); + + creationInterface->addLine(d); +} + +/** + * Adds an xline entity that was read from the file via the creation interface. + */ +void DL_Dxf::addXLine(DL_CreationInterface* creationInterface) +{ + DL_XLineData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0)); + + creationInterface->addXLine(d); +} + +/** + * Adds a ray entity that was read from the file via the creation interface. + */ +void DL_Dxf::addRay(DL_CreationInterface* creationInterface) +{ + DL_RayData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0)); + + creationInterface->addRay(d); +} + + + +/** + * Adds a polyline entity that was read from the file via the creation interface. + */ +void DL_Dxf::addPolyline(DL_CreationInterface* creationInterface) +{ + DL_PolylineData pd(maxVertices, getIntValue(71, 0), getIntValue(72, 0), getIntValue(70, 0)); + creationInterface->addPolyline(pd); + + maxVertices = std::min(maxVertices, vertexIndex+1); + + if (currentObjectType==DL_ENTITY_LWPOLYLINE) + { + for (int i=0; iaddVertex(d); + } + creationInterface->endEntity(); + } +} + + + +/** + * Adds a polyline vertex entity that was read from the file + * via the creation interface. + */ +void DL_Dxf::addVertex(DL_CreationInterface* creationInterface) +{ + + // vertex defines a face of the mesh if its vertex flags group has the + // 128 bit set but not the 64 bit. 10, 20, 30 are irrelevant and set to + // 0 in this case + if ((getIntValue(70, 0)&128) && !(getIntValue(70, 0)&64)) + { + return; + } + + DL_VertexData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(42, 0.0)); + + creationInterface->addVertex(d); +} + + +/** + * Adds a spline entity that was read from the file via the creation interface. + */ +void DL_Dxf::addSpline(DL_CreationInterface* creationInterface) +{ + DL_SplineData sd(getIntValue(71, 3), + maxKnots, + maxControlPoints, + maxFitPoints, + getIntValue(70, 4)); + + sd.tangentStartX = getRealValue(12, 0.0); + sd.tangentStartY = getRealValue(22, 0.0); + sd.tangentStartZ = getRealValue(32, 0.0); + sd.tangentEndX = getRealValue(13, 0.0); + sd.tangentEndY = getRealValue(23, 0.0); + sd.tangentEndZ = getRealValue(33, 0.0); + + creationInterface->addSpline(sd); + + int i; + for (i=0; iaddControlPoint(d); + } + for (i=0; iaddFitPoint(d); + } + for (i=0; iaddKnot(k); + } + creationInterface->endEntity(); +} + + + +/** + * Adds an arc entity that was read from the file via the creation interface. + */ +void DL_Dxf::addArc(DL_CreationInterface* creationInterface) +{ + DL_ArcData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(40, 0.0), + getRealValue(50, 0.0), + getRealValue(51, 0.0)); + + creationInterface->addArc(d); +} + + + +/** + * Adds a circle entity that was read from the file via the creation interface. + */ +void DL_Dxf::addCircle(DL_CreationInterface* creationInterface) +{ + DL_CircleData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(40, 0.0)); + + creationInterface->addCircle(d); +} + + + +/** + * Adds an ellipse entity that was read from the file via the creation interface. + */ +void DL_Dxf::addEllipse(DL_CreationInterface* creationInterface) +{ + DL_EllipseData d(getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0), + getRealValue(40, 1.0), + getRealValue(41, 0.0), + getRealValue(42, 2*M_PI)); + + creationInterface->addEllipse(d); +} + + + +/** + * Adds an insert entity that was read from the file via the creation interface. + */ +void DL_Dxf::addInsert(DL_CreationInterface* creationInterface) +{ + //printf("addInsert\n"); + //printf("code 50: %s\n", values[50]); + //printf("code 50 length: %d\n", strlen(values[50])); + //printf("code 50:\n"); + //getRealValue(50, 0.0); + + std::string name = getStringValue(2, ""); + if (name.length()==0) + { + return; + } + + DL_InsertData d(name, + // insertion point + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + // scale: + getRealValue(41, 1.0), + getRealValue(42, 1.0), + getRealValue(43, 1.0), + // angle (deg): + getRealValue(50, 0.0), + // cols / rows: + getIntValue(70, 1), + getIntValue(71, 1), + // spacing: + getRealValue(44, 0.0), + getRealValue(45, 0.0)); + + creationInterface->addInsert(d); +} + + + +/** + * Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface. + * + * @author AHM + */ +void DL_Dxf::addTrace(DL_CreationInterface* creationInterface) +{ + DL_TraceData td; + + for (int k = 0; k < 4; k++) + { + td.x[k] = getRealValue(10 + k, 0.0); + td.y[k] = getRealValue(20 + k, 0.0); + td.z[k] = getRealValue(30 + k, 0.0); + } + creationInterface->addTrace(td); +} + + + +/** + * Adds a 3dface entity that was read from the file via the creation interface. + */ +void DL_Dxf::add3dFace(DL_CreationInterface* creationInterface) +{ + DL_3dFaceData td; + + for (int k = 0; k < 4; k++) + { + td.x[k] = getRealValue(10 + k, 0.0); + td.y[k] = getRealValue(20 + k, 0.0); + td.z[k] = getRealValue(30 + k, 0.0); + } + creationInterface->add3dFace(td); +} + + + +/** + * Adds a solid entity (filled trace) that was read from the file via the creation interface. + * + * @author AHM + */ +void DL_Dxf::addSolid(DL_CreationInterface* creationInterface) +{ + DL_SolidData sd; + + for (int k = 0; k < 4; k++) + { + sd.x[k] = getRealValue(10 + k, 0.0); + sd.y[k] = getRealValue(20 + k, 0.0); + sd.z[k] = getRealValue(30 + k, 0.0); + } + creationInterface->addSolid(sd); +} + + +/** + * Adds an MText entity that was read from the file via the creation interface. + */ +void DL_Dxf::addMText(DL_CreationInterface* creationInterface) +{ + double angle = 0.0; + + if (hasValue(50)) + { + if (libVersion<=0x02000200) + { + // wrong but compatible with dxflib <=2.0.2.0: + angle = getRealValue(50, 0.0); + } + else + { + angle = (getRealValue(50, 0.0)*2*M_PI)/360.0; + } + } + else if (hasValue(11) && hasValue(21)) + { + double x = getRealValue(11, 0.0); + double y = getRealValue(21, 0.0); + + if (fabs(x)<1.0e-6) + { + if (y>0.0) + { + angle = M_PI/2.0; + } + else + { + angle = M_PI/2.0*3.0; + } + } + else + { + angle = atan(y/x); + } + } + + DL_MTextData d( + // insertion point + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + // X direction vector + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0), + // height + getRealValue(40, 2.5), + // width + getRealValue(41, 0.0), + // attachment point + getIntValue(71, 1), + // drawing direction + getIntValue(72, 1), + // line spacing style + getIntValue(73, 1), + // line spacing factor + getRealValue(44, 1.0), + // text + getStringValue(1, ""), + // style + getStringValue(7, ""), + // angle + angle); + creationInterface->addMText(d); +} + +/** + * Handles all XRecord data. + */ +bool DL_Dxf::handleXRecordData(DL_CreationInterface* creationInterface) +{ + if (groupCode==105) + { + return false; + } + + if (groupCode==5) + { + creationInterface->addXRecord(groupValue); + return true; + } + + if (groupCode==280) + { + xRecordValues = true; + return true; + } + + if (!xRecordValues) + { + return false; + } + + // string: + if (groupCode<=9 || + groupCode==100 || groupCode==102 || groupCode==105 || + (groupCode>=300 && groupCode<=369) || + (groupCode>=1000 && groupCode<=1009)) + { + + creationInterface->addXRecordString(groupCode, groupValue); + return true; + } + + // int: + else if ((groupCode>=60 && groupCode<=99) || (groupCode>=160 && groupCode<=179) || (groupCode>=270 && groupCode<=289)) + { + creationInterface->addXRecordInt(groupCode, toInt(groupValue)); + return true; + } + + // bool: + else if (groupCode>=290 && groupCode<=299) + { + creationInterface->addXRecordBool(groupCode, toBool(groupValue)); + return true; + } + + // double: + else if ((groupCode>=10 && groupCode<=59) || (groupCode>=110 && groupCode<=149) || (groupCode>=210 && groupCode<=239)) + { + creationInterface->addXRecordReal(groupCode, toReal(groupValue)); + return true; + } + + return false; +} + +/** + * Handles all dictionary data. + */ +bool DL_Dxf::handleDictionaryData(DL_CreationInterface* creationInterface) +{ + if (groupCode==3) + { + return true; + } + + if (groupCode==5) + { + creationInterface->addDictionary(DL_DictionaryData(groupValue)); + return true; + } + + if (groupCode==350) + { + creationInterface->addDictionaryEntry(DL_DictionaryEntryData(getStringValue(3, ""), groupValue)); + return true; + } + return false; +} + + + +/** + * Handles XData for all object types. + */ +bool DL_Dxf::handleXData(DL_CreationInterface* creationInterface) +{ + if (groupCode==1001) + { + creationInterface->addXDataApp(groupValue); + return true; + } + else if (groupCode>=1000 && groupCode<=1009) + { + creationInterface->addXDataString(groupCode, groupValue); + return true; + } + else if (groupCode>=1010 && groupCode<=1059) + { + creationInterface->addXDataReal(groupCode, toReal(groupValue)); + return true; + } + else if (groupCode>=1060 && groupCode<=1070) + { + creationInterface->addXDataInt(groupCode, toInt(groupValue)); + return true; + } + else if (groupCode==1071) + { + creationInterface->addXDataInt(groupCode, toInt(groupValue)); + return true; + } + + return false; +} + +/** + * Handles additional MText data. + */ +bool DL_Dxf::handleMTextData(DL_CreationInterface* creationInterface) +{ + // Special handling of text chunks for MTEXT entities: + if (groupCode==3) + { + creationInterface->addMTextChunk(groupValue); + return true; + } + + return false; +} + + + +/** + * Handles additional polyline data. + */ +bool DL_Dxf::handleLWPolylineData(DL_CreationInterface* /*creationInterface*/) +{ + // Allocate LWPolyline vertices (group code 90): + if (groupCode==90) + { + maxVertices = toInt(groupValue); + if (maxVertices>0) + { + if (vertices!=NULL) + { + delete[] vertices; + } + vertices = new double[4*maxVertices]; + for (int i=0; i=0 && vertexIndex0) + { + if (knots!=NULL) + { + delete[] knots; + } + knots = new double[maxKnots]; + for (int i=0; i0) + { + if (controlPoints!=NULL) + { + delete[] controlPoints; + } + if (weights!=NULL) + { + delete[] weights; + } + controlPoints = new double[3*maxControlPoints]; + weights = new double[maxControlPoints]; + for (int i=0; i0) + { + if (fitPoints!=NULL) + { + delete[] fitPoints; + } + fitPoints = new double[3*maxFitPoints]; + for (int i=0; i=0 && controlPointIndex=0 && fitPointIndex=0 && weightIndex0) + { + if (leaderVertices!=NULL) + { + delete[] leaderVertices; + } + leaderVertices = new double[3*maxLeaderVertices]; + for (int i=0; i=0 && + leaderVertexIndexaddText(d); +} + + + +/** + * Adds an attrib entity that was read from the file via the creation interface. + * @todo add attrib instead of normal text + */ +void DL_Dxf::addAttribute(DL_CreationInterface* creationInterface) +{ + DL_AttributeData d( + // insertion point + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + // alignment point + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0), + // height + getRealValue(40, 2.5), + // x scale + getRealValue(41, 1.0), + // generation flags + getIntValue(71, 0), + // h just + getIntValue(72, 0), + // v just + getIntValue(74, 0), + // tag + getStringValue(2, ""), + // text + getStringValue(1, ""), + // style + getStringValue(7, ""), + // angle + (getRealValue(50, 0.0)*2*M_PI)/360.0); + + creationInterface->addAttribute(d); +} + + + +/** + * @return dimension data from current values. + */ +DL_DimensionData DL_Dxf::getDimData() +{ + // generic dimension data: + return DL_DimensionData( + // def point + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + // text middle point + getRealValue(11, 0.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0), + // type + getIntValue(70, 0), + // attachment point + getIntValue(71, 5), + // line sp. style + getIntValue(72, 1), + // line sp. factor + getRealValue(41, 1.0), + // text + getStringValue(1, ""), + // style + getStringValue(3, ""), + // angle + getRealValue(53, 0.0)); +} + + + +/** + * Adds a linear dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimLinear(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // horizontal / vertical / rotated dimension: + DL_DimLinearData dl( + // definition point 1 + getRealValue(13, 0.0), + getRealValue(23, 0.0), + getRealValue(33, 0.0), + // definition point 2 + getRealValue(14, 0.0), + getRealValue(24, 0.0), + getRealValue(34, 0.0), + // angle + getRealValue(50, 0.0), + // oblique + getRealValue(52, 0.0)); + creationInterface->addDimLinear(d, dl); +} + + + +/** + * Adds an aligned dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimAligned(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // aligned dimension: + DL_DimAlignedData da( + // extension point 1 + getRealValue(13, 0.0), + getRealValue(23, 0.0), + getRealValue(33, 0.0), + // extension point 2 + getRealValue(14, 0.0), + getRealValue(24, 0.0), + getRealValue(34, 0.0)); + creationInterface->addDimAlign(d, da); +} + + + +/** + * Adds a radial dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimRadial(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + DL_DimRadialData dr( + // definition point + getRealValue(15, 0.0), + getRealValue(25, 0.0), + getRealValue(35, 0.0), + // leader length: + getRealValue(40, 0.0)); + creationInterface->addDimRadial(d, dr); +} + + + +/** + * Adds a diametric dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimDiametric(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // diametric dimension: + DL_DimDiametricData dr( + // definition point + getRealValue(15, 0.0), + getRealValue(25, 0.0), + getRealValue(35, 0.0), + // leader length: + getRealValue(40, 0.0)); + creationInterface->addDimDiametric(d, dr); +} + + + +/** + * Adds an angular dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimAngular(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // angular dimension: + DL_DimAngularData da( + // definition point 1 + getRealValue(13, 0.0), + getRealValue(23, 0.0), + getRealValue(33, 0.0), + // definition point 2 + getRealValue(14, 0.0), + getRealValue(24, 0.0), + getRealValue(34, 0.0), + // definition point 3 + getRealValue(15, 0.0), + getRealValue(25, 0.0), + getRealValue(35, 0.0), + // definition point 4 + getRealValue(16, 0.0), + getRealValue(26, 0.0), + getRealValue(36, 0.0)); + creationInterface->addDimAngular(d, da); +} + + +/** + * Adds an angular dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimAngular3P(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // angular dimension (3P): + DL_DimAngular3PData da( + // definition point 1 + getRealValue(13, 0.0), + getRealValue(23, 0.0), + getRealValue(33, 0.0), + // definition point 2 + getRealValue(14, 0.0), + getRealValue(24, 0.0), + getRealValue(34, 0.0), + // definition point 3 + getRealValue(15, 0.0), + getRealValue(25, 0.0), + getRealValue(35, 0.0)); + creationInterface->addDimAngular3P(d, da); +} + + + +/** + * Adds an ordinate dimension entity that was read from the file via the creation interface. + */ +void DL_Dxf::addDimOrdinate(DL_CreationInterface* creationInterface) +{ + DL_DimensionData d = getDimData(); + + // ordinate dimension: + DL_DimOrdinateData dl( + // definition point 1 + getRealValue(13, 0.0), + getRealValue(23, 0.0), + getRealValue(33, 0.0), + // definition point 2 + getRealValue(14, 0.0), + getRealValue(24, 0.0), + getRealValue(34, 0.0), + (getIntValue(70, 0)&64)==64 // true: X-type, false: Y-type + ); + creationInterface->addDimOrdinate(d, dl); +} + + + +/** + * Adds a leader entity that was read from the file via the creation interface. + */ +void DL_Dxf::addLeader(DL_CreationInterface* creationInterface) +{ + // leader (arrow) + DL_LeaderData le( + // arrow head flag + getIntValue(71, 1), + // leader path type + getIntValue(72, 0), + // Leader creation flag + getIntValue(73, 3), + // Hookline direction flag + getIntValue(74, 1), + // Hookline flag + getIntValue(75, 0), + // Text annotation height + getRealValue(40, 1.0), + // Text annotation width + getRealValue(41, 1.0), + // Number of vertices in leader + getIntValue(76, 0) + ); + creationInterface->addLeader(le); + + for (int i=0; iaddLeaderVertex(d); + } + creationInterface->endEntity(); +} + +/** + * Adds a hatch entity that was read from the file via the creation interface. + */ +void DL_Dxf::addHatch(DL_CreationInterface* creationInterface) +{ + DL_HatchData hd(getIntValue(91, 1), + getIntValue(70, 0), + getRealValue(41, 1.0), + getRealValue(52, 0.0), + getStringValue(2, "")); + + creationInterface->addHatch(hd); + + for (unsigned int i=0; iaddHatchLoop(DL_HatchLoopData(hatchEdges[i].size())); + for (unsigned int k=0; kaddHatchEdge(DL_HatchEdgeData(hatchEdges[i][k])); + } + } + + creationInterface->endEntity(); +} + +void DL_Dxf::addHatchLoop() +{ + addHatchEdge(); + hatchEdges.push_back(std::vector()); +} + +void DL_Dxf::addHatchEdge() +{ + if (hatchEdge.defined) + { + if (hatchEdges.size()>0) + { + hatchEdges.back().push_back(hatchEdge); + } + hatchEdge = DL_HatchEdgeData(); + } +} + +/** + * Handles all hatch data. + */ +bool DL_Dxf::handleHatchData(DL_CreationInterface* creationInterface) +{ + // New polyline loop, group code 92 + // or new loop with individual edges, group code 93 + if (groupCode==92 || groupCode==93) + { + if (firstHatchLoop) + { + hatchEdges.clear(); + firstHatchLoop = false; + } + if (groupCode==92 && (toInt(groupValue)&2)==2) + { + addHatchLoop(); + } + if (groupCode==93) + { + addHatchLoop(); + } + return true; + } + + // New hatch edge or new section / entity: add last hatch edge: + if (groupCode==72 || groupCode==0 || groupCode==78 || groupCode==98) + { + // polyline boundaries use code 72 for bulge flag: + if (groupCode!=72 || (getIntValue(92, 0)&2)==0) + { + addHatchEdge(); + } + + if (groupCode==0 /*|| groupCode==78*/) + { + addHatch(creationInterface); + } + else + { + hatchEdge.type = toInt(groupValue); + } + return true; + } + + // polyline boundary: + if ((getIntValue(92, 0)&2)==2) + { + switch (groupCode) + { + case 10: + hatchEdge.type = 0; + hatchEdge.vertices.push_back(std::vector()); + hatchEdge.vertices.back().push_back(toReal(groupValue)); + return true; + case 20: + if (!hatchEdge.vertices.empty()) + { + hatchEdge.vertices.back().push_back(toReal(groupValue)); + hatchEdge.defined = true; + } + return true; + case 42: + if (!hatchEdge.vertices.empty()) + { + hatchEdge.vertices.back().push_back(toReal(groupValue)); + hatchEdge.defined = true; + } + return true; + } + } + else + { + // Line edge: + if (hatchEdge.type==1) + { + switch (groupCode) + { + case 10: + hatchEdge.x1 = toReal(groupValue); + return true; + case 20: + hatchEdge.y1 = toReal(groupValue); + return true; + case 11: + hatchEdge.x2 = toReal(groupValue); + return true; + case 21: + hatchEdge.y2 = toReal(groupValue); + hatchEdge.defined = true; + return true; + } + } + + // Arc edge: + if (hatchEdge.type==2) + { + switch(groupCode) + { + case 10: + hatchEdge.cx = toReal(groupValue); + return true; + case 20: + hatchEdge.cy = toReal(groupValue); + return true; + case 40: + hatchEdge.radius = toReal(groupValue); + return true; + case 50: + hatchEdge.angle1 = toReal(groupValue)/360.0*2*M_PI; + return true; + case 51: + hatchEdge.angle2 = toReal(groupValue)/360.0*2*M_PI; + return true; + case 73: + hatchEdge.ccw = (bool)toInt(groupValue); + hatchEdge.defined = true; + return true; + } + } + + // Ellipse arc edge: + if (hatchEdge.type==3) + { + switch (groupCode) + { + case 10: + hatchEdge.cx = toReal(groupValue); + return true; + case 20: + hatchEdge.cy = toReal(groupValue); + return true; + case 11: + hatchEdge.mx = toReal(groupValue); + return true; + case 21: + hatchEdge.my = toReal(groupValue); + return true; + case 40: + hatchEdge.ratio = toReal(groupValue); + return true; + case 50: + hatchEdge.angle1 = toReal(groupValue)/360.0*2*M_PI; + return true; + case 51: + hatchEdge.angle2 = toReal(groupValue)/360.0*2*M_PI; + return true; + case 73: + hatchEdge.ccw = (bool)toInt(groupValue); + hatchEdge.defined = true; + return true; + } + } + + // Spline edge: + if (hatchEdge.type==4) + { + switch (groupCode) + { + case 94: + hatchEdge.degree = toInt(groupValue); + return true; + case 73: + hatchEdge.rational = toBool(groupValue); + return true; + case 74: + hatchEdge.periodic = toBool(groupValue); + return true; + case 95: + hatchEdge.nKnots = toInt(groupValue); + return true; + case 96: + hatchEdge.nControl = toInt(groupValue); + return true; + case 97: + hatchEdge.nFit = toInt(groupValue); + return true; + case 40: + if (hatchEdge.knots.size() < hatchEdge.nKnots) + { + hatchEdge.knots.push_back(toReal(groupValue)); + } + return true; + case 10: + if (hatchEdge.controlPoints.size() < hatchEdge.nControl) + { + std::vector v; + v.push_back(toReal(groupValue)); + hatchEdge.controlPoints.push_back(v); + } + return true; + case 20: + if (!hatchEdge.controlPoints.empty() && hatchEdge.controlPoints.back().size()==1) + { + hatchEdge.controlPoints.back().push_back(toReal(groupValue)); + } + hatchEdge.defined = true; + return true; + case 42: + if (hatchEdge.weights.size() < hatchEdge.nControl) + { + hatchEdge.weights.push_back(toReal(groupValue)); + } + return true; + case 11: + if (hatchEdge.fitPoints.size() < hatchEdge.nFit) + { + std::vector v; + v.push_back(toReal(groupValue)); + hatchEdge.fitPoints.push_back(v); + } + return true; + case 21: + if (!hatchEdge.fitPoints.empty() && hatchEdge.fitPoints.back().size()==1) + { + hatchEdge.fitPoints.back().push_back(toReal(groupValue)); + } + hatchEdge.defined = true; + return true; + case 12: + hatchEdge.startTangentX = toReal(groupValue); + return true; + case 22: + hatchEdge.startTangentY = toReal(groupValue); + return true; + case 13: + hatchEdge.endTangentX = toReal(groupValue); + return true; + case 23: + hatchEdge.endTangentY = toReal(groupValue); + return true; + } + } + } + + return false; +} + + +/** + * Adds an image entity that was read from the file via the creation interface. + */ +void DL_Dxf::addImage(DL_CreationInterface* creationInterface) +{ + DL_ImageData id(// pass ref insead of name we don't have yet + getStringValue(340, ""), + // ins point: + getRealValue(10, 0.0), + getRealValue(20, 0.0), + getRealValue(30, 0.0), + // u vector: + getRealValue(11, 1.0), + getRealValue(21, 0.0), + getRealValue(31, 0.0), + // v vector: + getRealValue(12, 0.0), + getRealValue(22, 1.0), + getRealValue(32, 0.0), + // image size (pixel): + getIntValue(13, 1), + getIntValue(23, 1), + // brightness, contrast, fade + getIntValue(281, 50), + getIntValue(282, 50), + getIntValue(283, 0)); + + creationInterface->addImage(id); + creationInterface->endEntity(); + currentObjectType = DL_UNKNOWN; +} + + + +/** + * Adds an image definition that was read from the file via the creation interface. + */ +void DL_Dxf::addImageDef(DL_CreationInterface* creationInterface) +{ + DL_ImageDefData id(// handle + getStringValue(5, ""), + getStringValue(1, "")); + + creationInterface->linkImage(id); + creationInterface->endEntity(); + currentObjectType = DL_UNKNOWN; +} + + + +/** + * Ends some special entities like hatches or old style polylines. + */ +void DL_Dxf::endEntity(DL_CreationInterface* creationInterface) +{ + creationInterface->endEntity(); +} + + +/** + * Ends a sequence and notifies the creation interface. + */ +void DL_Dxf::endSequence(DL_CreationInterface* creationInterface) +{ + creationInterface->endSequence(); +} + + +/** + * Converts the given string into an int. + * ok is set to false if there was an error. + */ +//int DL_Dxf::stringToInt(const char* s, bool* ok) { +// if (ok!=NULL) { +// // check string: +// *ok = true; +// int i=0; +// bool dot = false; +// do { +// if (s[i]=='\0') { +// break; +// } else if (s[i]=='.') { +// if (dot==true) { +// //std::cerr << "two dots\n"; +// *ok = false; +// } else { +// dot = true; +// } +// } else if (s[i]<'0' || s[i]>'9') { +// //std::cerr << "NaN: '" << s[i] << "'\n"; +// *ok = false; +// } +// i++; +// } while(s[i]!='\0' && *ok==true); +// } + +// return atoi(s); +//} + + +/** + * @brief Opens the given file for writing and returns a pointer + * to the dxf writer. This pointer needs to be passed on to other + * writing functions. + * + * @param file Full path of the file to open. + * + * @return Pointer to an ascii dxf writer object. + */ +DL_WriterA* DL_Dxf::out(const char* file, DL_Codes::version version) +{ + char* f = new char[strlen(file)+1]; + strcpy(f, file); + this->version = version; + + DL_WriterA* dw = new DL_WriterA(f, version); + if (dw->openFailed()) + { + delete dw; + delete[] f; + return NULL; + } + else + { + delete[] f; + return dw; + } +} + + + +/** + * @brief Writes a DXF header to the file currently opened + * by the given DXF writer object. + */ +void DL_Dxf::writeHeader(DL_WriterA& dw) +{ + dw.comment("dxflib " DL_VERSION); + dw.sectionHeader(); + + dw.dxfString(9, "$ACADVER"); + switch (version) + { + case DL_Codes::AC1009: + dw.dxfString(1, "AC1009"); + break; + case DL_Codes::AC1012: + dw.dxfString(1, "AC1012"); + break; + case DL_Codes::AC1014: + dw.dxfString(1, "AC1014"); + break; + case DL_Codes::AC1015: + dw.dxfString(1, "AC1015"); + break; + } + + // Newer version require that (otherwise a*cad crashes..) + if (version==DL_VERSION_2000) + { + dw.dxfString(9, "$HANDSEED"); + dw.dxfHex(5, 0xFFFF); + } + + // commented out: more variables can be added after that by caller: + //dw.sectionEnd(); +} + + + + +/** + * Writes a point entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writePoint(DL_WriterA& dw, + const DL_PointData& data, + const DL_Attributes& attrib) +{ + dw.entity("POINT"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbPoint"); + } + dw.entityAttributes(attrib); + dw.coord(DL_POINT_COORD_CODE, data.x, data.y, data.z); +} + + + +/** + * Writes a line entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeLine(DL_WriterA& dw, + const DL_LineData& data, + const DL_Attributes& attrib) +{ + dw.entity("LINE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbLine"); + } + dw.entityAttributes(attrib); + dw.coord(DL_LINE_START_CODE, data.x1, data.y1, data.z1); + dw.coord(DL_LINE_END_CODE, data.x2, data.y2, data.z2); +} + + + +/** + * Writes an x line entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeXLine(DL_WriterA& dw, + const DL_XLineData& data, + const DL_Attributes& attrib) +{ + dw.entity("XLINE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbLine"); + } + dw.entityAttributes(attrib); + dw.coord(DL_LINE_START_CODE, data.bx, data.by, data.bz); + dw.coord(DL_LINE_END_CODE, data.dx, data.dy, data.dz); +} + + + +/** + * Writes a ray entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeRay(DL_WriterA& dw, + const DL_RayData& data, + const DL_Attributes& attrib) +{ + dw.entity("RAY"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbLine"); + } + dw.entityAttributes(attrib); + dw.coord(DL_LINE_START_CODE, data.bx, data.by, data.bz); + dw.coord(DL_LINE_END_CODE, data.dx, data.dy, data.dz); +} + + + +/** + * Writes a polyline entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + * @see writeVertex + */ +void DL_Dxf::writePolyline(DL_WriterA& dw, + const DL_PolylineData& data, + const DL_Attributes& attrib) +{ + if (version==DL_VERSION_2000) + { + dw.entity("LWPOLYLINE"); + dw.entityAttributes(attrib); + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbPolyline"); + dw.dxfInt(90, (int)data.number); + dw.dxfInt(70, data.flags); + } + else + { + dw.entity("POLYLINE"); + dw.entityAttributes(attrib); + polylineLayer = attrib.getLayer(); + dw.dxfInt(66, 1); + dw.dxfInt(70, data.flags); + dw.coord(DL_VERTEX_COORD_CODE, 0.0, 0.0, 0.0); + } +} + + + +/** + * Writes a single vertex of a polyline to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeVertex(DL_WriterA& dw, + const DL_VertexData& data) +{ + + + if (version==DL_VERSION_2000) + { + dw.dxfReal(10, data.x); + dw.dxfReal(20, data.y); + dw.dxfReal(30, data.z); + if (fabs(data.bulge)>1.0e-10) + { + dw.dxfReal(42, data.bulge); + } + } + else + { + dw.entity("VERTEX"); + //dw.entityAttributes(attrib); + dw.dxfString(8, polylineLayer); + dw.coord(DL_VERTEX_COORD_CODE, data.x, data.y, data.z); + if (fabs(data.bulge)>1.0e-10) + { + dw.dxfReal(42, data.bulge); + } + } +} + + + +/** + * Writes the polyline end. Only needed for DXF R12. + */ +void DL_Dxf::writePolylineEnd(DL_WriterA& dw) +{ + if (version==DL_VERSION_2000) + { + } + else + { + dw.entity("SEQEND"); + } +} + + +/** + * Writes a spline entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + * @see writeControlPoint + */ +void DL_Dxf::writeSpline(DL_WriterA& dw, + const DL_SplineData& data, + const DL_Attributes& attrib) +{ + + dw.entity("SPLINE"); + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbSpline"); + } + dw.dxfInt(70, data.flags); + dw.dxfInt(71, data.degree); + dw.dxfInt(72, data.nKnots); // number of knots + dw.dxfInt(73, data.nControl); // number of control points + dw.dxfInt(74, data.nFit); // number of fit points +} + + + +/** + * Writes a single control point of a spline to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeControlPoint(DL_WriterA& dw, + const DL_ControlPointData& data) +{ + + dw.dxfReal(10, data.x); + dw.dxfReal(20, data.y); + dw.dxfReal(30, data.z); +} + + + +/** + * Writes a single fit point of a spline to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeFitPoint(DL_WriterA& dw, + const DL_FitPointData& data) +{ + + dw.dxfReal(11, data.x); + dw.dxfReal(21, data.y); + dw.dxfReal(31, data.z); +} + + + +/** + * Writes a single knot of a spline to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeKnot(DL_WriterA& dw, + const DL_KnotData& data) +{ + + dw.dxfReal(40, data.k); +} + + + +/** + * Writes a circle entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeCircle(DL_WriterA& dw, + const DL_CircleData& data, + const DL_Attributes& attrib) +{ + dw.entity("CIRCLE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbCircle"); + } + dw.entityAttributes(attrib); + dw.coord(10, data.cx, data.cy, data.cz); + dw.dxfReal(40, data.radius); +} + + + +/** + * Writes an arc entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeArc(DL_WriterA& dw, + const DL_ArcData& data, + const DL_Attributes& attrib) +{ + dw.entity("ARC"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbCircle"); + } + dw.coord(10, data.cx, data.cy, data.cz); + dw.dxfReal(40, data.radius); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbArc"); + } + dw.dxfReal(50, data.angle1); + dw.dxfReal(51, data.angle2); +} + + + +/** + * Writes an ellipse entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeEllipse(DL_WriterA& dw, + const DL_EllipseData& data, + const DL_Attributes& attrib) +{ + + if (version>DL_VERSION_R12) + { + dw.entity("ELLIPSE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbEllipse"); + } + dw.entityAttributes(attrib); + dw.coord(10, data.cx, data.cy, data.cz); + dw.coord(11, data.mx, data.my, data.mz); + dw.dxfReal(40, data.ratio); + dw.dxfReal(41, data.angle1); + dw.dxfReal(42, data.angle2); + } +} + + + +/** + * Writes a solid entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeSolid(DL_WriterA& dw, + const DL_SolidData& data, + const DL_Attributes& attrib) +{ + dw.entity("SOLID"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbTrace"); + } + dw.entityAttributes(attrib); + dw.coord(10, data.x[0], data.y[0], data.z[0]); + dw.coord(11, data.x[1], data.y[1], data.z[1]); + dw.coord(12, data.x[2], data.y[2], data.z[2]); + dw.coord(13, data.x[3], data.y[3], data.z[3]); + dw.dxfReal(39, data.thickness); +} + +/** + * Writes a trace entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeTrace(DL_WriterA& dw, + const DL_TraceData& data, + const DL_Attributes& attrib) +{ + dw.entity("TRACE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbTrace"); + } + dw.entityAttributes(attrib); + dw.coord(10, data.x[0], data.y[0], data.z[0]); + dw.coord(11, data.x[1], data.y[1], data.z[1]); + dw.coord(12, data.x[2], data.y[2], data.z[2]); + dw.coord(13, data.x[3], data.y[3], data.z[3]); + dw.dxfReal(39, data.thickness); +} + + + +/** + * Writes a 3d face entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::write3dFace(DL_WriterA& dw, + const DL_3dFaceData& data, + const DL_Attributes& attrib) +{ + dw.entity("3DFACE"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbFace"); + } + dw.entityAttributes(attrib); + dw.coord(10, data.x[0], data.y[0], data.z[0]); + dw.coord(11, data.x[1], data.y[1], data.z[1]); + dw.coord(12, data.x[2], data.y[2], data.z[2]); + dw.coord(13, data.x[3], data.y[3], data.z[3]); +} + + + +/** + * Writes an insert to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeInsert(DL_WriterA& dw, + const DL_InsertData& data, + const DL_Attributes& attrib) +{ + + if (data.name.empty()) + { + std::cerr << "DL_Dxf::writeInsert: " + << "Block name must not be empty\n"; + return; + } + + dw.entity("INSERT"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbBlockReference"); + } + dw.entityAttributes(attrib); + dw.dxfString(2, data.name); + dw.dxfReal(10, data.ipx); + dw.dxfReal(20, data.ipy); + dw.dxfReal(30, data.ipz); + if (data.sx!=1.0 || data.sy!=1.0) + { + dw.dxfReal(41, data.sx); + dw.dxfReal(42, data.sy); + dw.dxfReal(43, 1.0); + } + if (data.angle!=0.0) + { + dw.dxfReal(50, data.angle); + } + if (data.cols!=1 || data.rows!=1) + { + dw.dxfInt(70, data.cols); + dw.dxfInt(71, data.rows); + } + if (data.colSp!=0.0 || data.rowSp!=0.0) + { + dw.dxfReal(44, data.colSp); + dw.dxfReal(45, data.rowSp); + } + +} + + + +/** + * Writes a multi text entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeMText(DL_WriterA& dw, + const DL_MTextData& data, + const DL_Attributes& attrib) +{ + + dw.entity("MTEXT"); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbMText"); + } + dw.entityAttributes(attrib); + dw.dxfReal(10, data.ipx); + dw.dxfReal(20, data.ipy); + dw.dxfReal(30, data.ipz); + dw.dxfReal(40, data.height); + dw.dxfReal(41, data.width); + + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.drawingDirection); + + // Creare text chunks of 250 characters each: + int length = data.text.length(); + char chunk[251]; + int i; + for (i=250; iDL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbAlignedDimension"); + } + + dw.dxfReal(13, edata.epx1); + dw.dxfReal(23, edata.epy1); + dw.dxfReal(33, 0.0); + + dw.dxfReal(14, edata.epx2); + dw.dxfReal(24, edata.epy2); + dw.dxfReal(34, 0.0); + + writeDimStyleOverrides(dw, data); +} + + + +/** + * Writes a linear dimension entity to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific linear dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimLinear(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimLinearData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + dw.dxfInt(70, data.type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbAlignedDimension"); + } + + dw.dxfReal(13, edata.dpx1); + dw.dxfReal(23, edata.dpy1); + dw.dxfReal(33, 0.0); + + dw.dxfReal(14, edata.dpx2); + dw.dxfReal(24, edata.dpy2); + dw.dxfReal(34, 0.0); + + dw.dxfReal(50, edata.angle/(2.0*M_PI)*360.0); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbRotatedDimension"); + } + + writeDimStyleOverrides(dw, data); +} + + + +/** + * Writes a radial dimension entity to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific radial dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimRadial(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimRadialData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + dw.dxfInt(70, data.type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbRadialDimension"); + } + + dw.dxfReal(15, edata.dpx); + dw.dxfReal(25, edata.dpy); + dw.dxfReal(35, 0.0); + + dw.dxfReal(40, edata.leader); + + writeDimStyleOverrides(dw, data); +} + + + +/** + * Writes a diametric dimension entity to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific diametric dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimDiametric(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimDiametricData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + dw.dxfInt(70, data.type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDiametricDimension"); + } + + dw.dxfReal(15, edata.dpx); + dw.dxfReal(25, edata.dpy); + dw.dxfReal(35, 0.0); + + dw.dxfReal(40, edata.leader); + + writeDimStyleOverrides(dw, data); +} + + + +/** + * Writes an angular dimension entity to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific angular dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimAngular(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimAngularData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + dw.dxfInt(70, data.type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDb2LineAngularDimension"); + } + + dw.dxfReal(13, edata.dpx1); + dw.dxfReal(23, edata.dpy1); + dw.dxfReal(33, 0.0); + + dw.dxfReal(14, edata.dpx2); + dw.dxfReal(24, edata.dpy2); + dw.dxfReal(34, 0.0); + + dw.dxfReal(15, edata.dpx3); + dw.dxfReal(25, edata.dpy3); + dw.dxfReal(35, 0.0); + + dw.dxfReal(16, edata.dpx4); + dw.dxfReal(26, edata.dpy4); + dw.dxfReal(36, 0.0); +} + + + +/** + * Writes an angular dimension entity (3 points version) to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific angular dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimAngular3P(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimAngular3PData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + dw.dxfInt(70, data.type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfReal(42, data.angle); + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDb3PointAngularDimension"); + } + + dw.dxfReal(13, edata.dpx1); + dw.dxfReal(23, edata.dpy1); + dw.dxfReal(33, 0.0); + + dw.dxfReal(14, edata.dpx2); + dw.dxfReal(24, edata.dpy2); + dw.dxfReal(34, 0.0); + + dw.dxfReal(15, edata.dpx3); + dw.dxfReal(25, edata.dpy3); + dw.dxfReal(35, 0.0); +} + + + + +/** + * Writes an ordinate dimension entity to the file. + * + * @param dw DXF writer + * @param data Generic dimension data for from the file + * @param data Specific ordinate dimension data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeDimOrdinate(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimOrdinateData& edata, + const DL_Attributes& attrib) +{ + + dw.entity("DIMENSION"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + } + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimension"); + } + + dw.dxfReal(10, data.dpx); + dw.dxfReal(20, data.dpy); + dw.dxfReal(30, data.dpz); + + dw.dxfReal(11, data.mpx); + dw.dxfReal(21, data.mpy); + dw.dxfReal(31, 0.0); + + int type = data.type; + if (edata.xtype) + { + type|=0x40; + } + + dw.dxfInt(70, type); + if (version>DL_VERSION_R12) + { + dw.dxfInt(71, data.attachmentPoint); + dw.dxfInt(72, data.lineSpacingStyle); // opt + dw.dxfReal(41, data.lineSpacingFactor); // opt + } + + dw.dxfString(1, data.text); // opt + //dw.dxfString(3, data.style); + dw.dxfString(3, "Standard"); + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbOrdinateDimension"); + } + + dw.dxfReal(13, edata.dpx1); + dw.dxfReal(23, edata.dpy1); + dw.dxfReal(33, 0.0); + + dw.dxfReal(14, edata.dpx2); + dw.dxfReal(24, edata.dpy2); + dw.dxfReal(34, 0.0); +} + + + +/** + * Writes a leader entity to the file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + * @see writeVertex + */ +void DL_Dxf::writeLeader(DL_WriterA& dw, + const DL_LeaderData& data, + const DL_Attributes& attrib) +{ + if (version>DL_VERSION_R12) + { + dw.entity("LEADER"); + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbLeader"); + } + dw.dxfString(3, "Standard"); + dw.dxfInt(71, data.arrowHeadFlag); + dw.dxfInt(72, data.leaderPathType); + dw.dxfInt(73, data.leaderCreationFlag); + dw.dxfInt(74, data.hooklineDirectionFlag); + dw.dxfInt(75, data.hooklineFlag); + dw.dxfReal(40, data.textAnnotationHeight); + dw.dxfReal(41, data.textAnnotationWidth); + dw.dxfInt(76, data.number); + } +} + + + +/** + * Writes a single vertex of a leader to the file. + * + * @param dw DXF writer + * @param data Entity data + */ +void DL_Dxf::writeLeaderVertex(DL_WriterA& dw, + const DL_LeaderVertexData& data) +{ + if (version>DL_VERSION_R12) + { + dw.dxfReal(10, data.x); + dw.dxfReal(20, data.y); + } +} + + + +/** + * Writes the beginning of a hatch entity to the file. + * This must be followed by one or more writeHatchLoop() + * calls and a writeHatch2() call. + * + * @param dw DXF writer + * @param data Entity data. + * @param attrib Attributes + */ +void DL_Dxf::writeHatch1(DL_WriterA& dw, + const DL_HatchData& data, + const DL_Attributes& attrib) +{ + + dw.entity("HATCH"); + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbHatch"); + } + dw.dxfReal(10, 0.0); // elevation + dw.dxfReal(20, 0.0); + dw.dxfReal(30, 0.0); + dw.dxfReal(210, 0.0); // extrusion dir. + dw.dxfReal(220, 0.0); + dw.dxfReal(230, 1.0); + if (data.solid==false) + { + dw.dxfString(2, data.pattern); + } + else + { + dw.dxfString(2, "SOLID"); + } + dw.dxfInt(70, (int)data.solid); + dw.dxfInt(71, 0); // non-associative + dw.dxfInt(91, data.numLoops); +} + + + +/** + * Writes the end of a hatch entity to the file. + * + * @param dw DXF writer + * @param data Entity data. + * @param attrib Attributes + */ +void DL_Dxf::writeHatch2(DL_WriterA& dw, + const DL_HatchData& data, + const DL_Attributes& /*attrib*/) +{ + + dw.dxfInt(75, 0); // odd parity + dw.dxfInt(76, 1); // pattern type + if (data.solid==false) + { + dw.dxfReal(52, data.angle); + dw.dxfReal(41, data.scale); + dw.dxfInt(77, 0); // not double + //dw.dxfInt(78, 0); + dw.dxfInt(78, 1); + dw.dxfReal(53, 45.0); + dw.dxfReal(43, 0.0); + dw.dxfReal(44, 0.0); + dw.dxfReal(45, -0.0883883476483184); + dw.dxfReal(46, 0.0883883476483185); + dw.dxfInt(79, 0); + } + dw.dxfInt(98, 0); + + if (version==DL_VERSION_2000) + { + dw.dxfString(1001, "ACAD"); + dw.dxfReal(1010, data.originX); + dw.dxfReal(1020, data.originY); + dw.dxfInt(1030, 0.0); + } +} + + + +/** + * Writes the beginning of a hatch loop to the file. This + * must happen after writing the beginning of a hatch entity. + * + * @param dw DXF writer + * @param data Entity data. + * @param attrib Attributes + */ +void DL_Dxf::writeHatchLoop1(DL_WriterA& dw, + const DL_HatchLoopData& data) +{ + + dw.dxfInt(92, 1); + dw.dxfInt(93, data.numEdges); + //dw.dxfInt(97, 0); +} + + + +/** + * Writes the end of a hatch loop to the file. + * + * @param dw DXF writer + * @param data Entity data. + * @param attrib Attributes + */ +void DL_Dxf::writeHatchLoop2(DL_WriterA& dw, + const DL_HatchLoopData& /*data*/) +{ + + dw.dxfInt(97, 0); +} + + +/** + * Writes the beginning of a hatch entity to the file. + * + * @param dw DXF writer + * @param data Entity data. + * @param attrib Attributes + */ +void DL_Dxf::writeHatchEdge(DL_WriterA& dw, + const DL_HatchEdgeData& data) +{ + + if (data.type<1 || data.type>4) + { + printf("WARNING: unsupported hatch edge type: %d", data.type); + } + + dw.dxfInt(72, data.type); + + switch (data.type) + { + // line: + case 1: + dw.dxfReal(10, data.x1); + dw.dxfReal(20, data.y1); + dw.dxfReal(11, data.x2); + dw.dxfReal(21, data.y2); + break; + + // arc: + case 2: + dw.dxfReal(10, data.cx); + dw.dxfReal(20, data.cy); + dw.dxfReal(40, data.radius); + dw.dxfReal(50, data.angle1/(2*M_PI)*360.0); + dw.dxfReal(51, data.angle2/(2*M_PI)*360.0); + dw.dxfInt(73, (int)(data.ccw)); + break; + + // ellipse arc: + case 3: + dw.dxfReal(10, data.cx); + dw.dxfReal(20, data.cy); + dw.dxfReal(11, data.mx); + dw.dxfReal(21, data.my); + dw.dxfReal(40, data.ratio); + dw.dxfReal(50, data.angle1/(2*M_PI)*360.0); + dw.dxfReal(51, data.angle2/(2*M_PI)*360.0); + dw.dxfInt(73, (int)(data.ccw)); + break; + + // spline: + case 4: + dw.dxfInt(94, data.degree); + dw.dxfBool(73, data.rational); + dw.dxfBool(74, data.periodic); + dw.dxfInt(95, data.nKnots); + dw.dxfInt(96, data.nControl); + for (unsigned int i=0; i0) + { + dw.dxfInt(97, data.nFit); + for (unsigned int i=0; i1.0e-4 || fabs(data.startTangentY)>1.0e-4) + { + dw.dxfReal(12, data.startTangentX); + dw.dxfReal(22, data.startTangentY); + } + if (fabs(data.endTangentX)>1.0e-4 || fabs(data.endTangentY)>1.0e-4) + { + dw.dxfReal(13, data.endTangentX); + dw.dxfReal(23, data.endTangentY); + } + break; + + default: + break; + } +} + + + +/** + * Writes an image entity. + * + * @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart. + */ +int DL_Dxf::writeImage(DL_WriterA& dw, + const DL_ImageData& data, + const DL_Attributes& attrib) +{ + + /*if (data.file.empty()) { + std::cerr << "DL_Dxf::writeImage: " + << "Image file must not be empty\n"; + return; + }*/ + + dw.entity("IMAGE"); + + dw.entityAttributes(attrib); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbEntity"); + dw.dxfString(100, "AcDbRasterImage"); + dw.dxfInt(90, 0); + } + // insertion point + dw.dxfReal(10, data.ipx); + dw.dxfReal(20, data.ipy); + dw.dxfReal(30, data.ipz); + + // vector along bottom side (1 pixel long) + dw.dxfReal(11, data.ux); + dw.dxfReal(21, data.uy); + dw.dxfReal(31, data.uz); + + // vector along left side (1 pixel long) + dw.dxfReal(12, data.vx); + dw.dxfReal(22, data.vy); + dw.dxfReal(32, data.vz); + + // image size in pixel + dw.dxfReal(13, data.width); + dw.dxfReal(23, data.height); + + // handle of IMAGEDEF object + int handle = dw.incHandle(); + dw.dxfHex(340, handle); + + // flags + dw.dxfInt(70, 15); + + // clipping: + dw.dxfInt(280, 0); + + // brightness, contrast, fade + dw.dxfInt(281, data.brightness); + dw.dxfInt(282, data.contrast); + dw.dxfInt(283, data.fade); + + return handle; +} + + + +/** + * Writes an image definiition entity. + */ +void DL_Dxf::writeImageDef(DL_WriterA& dw, + int handle, + const DL_ImageData& data) +{ + + /*if (data.file.empty()) { + std::cerr << "DL_Dxf::writeImage: " + << "Image file must not be empty\n"; + return; + }*/ + + dw.dxfString(0, "IMAGEDEF"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, handle); + } + + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbRasterImageDef"); + dw.dxfInt(90, 0); + } + // file name: + dw.dxfString(1, data.ref); + + // image size in pixel + dw.dxfReal(10, data.width); + dw.dxfReal(20, data.height); + + dw.dxfReal(11, 1.0); + dw.dxfReal(21, 1.0); + + // loaded: + dw.dxfInt(280, 1); + // units: + dw.dxfInt(281, 0); +} + + +/** + * Writes a layer to the file. Layers are stored in the + * tables section of a DXF file. + * + * @param dw DXF writer + * @param data Entity data from the file + * @param attrib Attributes + */ +void DL_Dxf::writeLayer(DL_WriterA& dw, + const DL_LayerData& data, + const DL_Attributes& attrib) +{ + + if (data.name.empty()) + { + std::cerr << "DL_Dxf::writeLayer: " + << "Layer name must not be empty\n"; + return; + } + + int color = attrib.getColor(); + if (color>=256) + { + std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n"; + color = 7; + } + + if (data.name == "0") + { + dw.tableLayerEntry(0x10); + } + else + { + dw.tableLayerEntry(); + } + + dw.dxfString(2, data.name); + dw.dxfInt(70, data.flags); + dw.dxfInt(62, color); + if (version>=DL_VERSION_2000 && attrib.getColor24()!=-1) + { + dw.dxfInt(420, attrib.getColor24()); + } + + dw.dxfString(6, (attrib.getLinetype().length()==0 ? + std::string("CONTINUOUS") : attrib.getLinetype())); + + if (version>=DL_VERSION_2000) + { + // layer defpoints cannot be plotted + std::string lstr = data.name; + std::transform(lstr.begin(), lstr.end(), lstr.begin(), tolower); + if (lstr=="defpoints") + { + dw.dxfInt(290, 0); + } + } + if (version>=DL_VERSION_2000 && attrib.getWidth()!=-1) + { + dw.dxfInt(370, attrib.getWidth()); + } + if (version>=DL_VERSION_2000) + { + dw.dxfHex(390, 0xF); + } +} + + + +/** + * Writes a line type to the file. Line types are stored in the + * tables section of a DXF file. + */ +void DL_Dxf::writeLinetype(DL_WriterA& dw, + const DL_LinetypeData& data) +{ + + std::string nameUpper = data.name; + std::transform(nameUpper.begin(), nameUpper.end(), nameUpper.begin(), ::toupper); + + if (data.name.empty()) + { + std::cerr << "DL_Dxf::writeLinetype: " + << "Line type name must not be empty\n"; + return; + } + + // ignore BYLAYER, BYBLOCK for R12 + if (version=DL_VERSION_R13) + { + dw.dxfInt(74, 0); + } + } + } +} + + + +/** + * Writes the APPID section to the DXF file. + * + * @param name Application name + */ +void DL_Dxf::writeAppid(DL_WriterA& dw, const std::string& name) +{ + if (name.empty()) + { + std::cerr << "DL_Dxf::writeAppid: " + << "Application name must not be empty\n"; + return; + } + + std::string n = name; + std::transform(n.begin(), n.end(), n.begin(), ::toupper); + + if (n=="ACAD") + { + dw.tableAppidEntry(0x12); + } + else + { + dw.tableAppidEntry(); + } + dw.dxfString(2, name); + dw.dxfInt(70, 0); +} + + + +/** + * Writes a block's definition (no entities) to the DXF file. + */ +void DL_Dxf::writeBlock(DL_WriterA& dw, const DL_BlockData& data) +{ + if (data.name.empty()) + { + std::cerr << "DL_Dxf::writeBlock: " + << "Block name must not be empty\n"; + return; + } + + std::string n = data.name; + std::transform(n.begin(), n.end(), n.begin(), ::toupper); + + if (n=="*PAPER_SPACE") + { + dw.sectionBlockEntry(0x1C); + } + else if (n=="*MODEL_SPACE") + { + dw.sectionBlockEntry(0x20); + } + else if (n=="*PAPER_SPACE0") + { + dw.sectionBlockEntry(0x24); + } + else + { + dw.sectionBlockEntry(); + } + dw.dxfString(2, data.name); + dw.dxfInt(70, 0); + dw.coord(10, data.bpx, data.bpy, data.bpz); + dw.dxfString(3, data.name); + dw.dxfString(1, ""); +} + + + +/** + * Writes a block end. + * + * @param name Block name + */ +void DL_Dxf::writeEndBlock(DL_WriterA& dw, const std::string& name) +{ + std::string n = name; + std::transform(n.begin(), n.end(), n.begin(), ::toupper); + + if (n=="*PAPER_SPACE") + { + dw.sectionBlockEntryEnd(0x1D); + } + else if (n=="*MODEL_SPACE") + { + dw.sectionBlockEntryEnd(0x21); + } + else if (n=="*PAPER_SPACE0") + { + dw.sectionBlockEntryEnd(0x25); + } + else + { + dw.sectionBlockEntryEnd(); + } +} + + + +/** + * Writes a viewport section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked VPORT section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeVPort(DL_WriterA& dw) +{ + dw.dxfString(0, "TABLE"); + dw.dxfString(2, "VPORT"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 0x8); + } + //dw.dxfHex(330, 0); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTable"); + } + dw.dxfInt(70, 1); + dw.dxfString(0, "VPORT"); + //dw.dxfHex(5, 0x2F); + if (version==DL_VERSION_2000) + { + dw.handle(); + } + //dw.dxfHex(330, 8); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbViewportTableRecord"); + } + dw.dxfString( 2, "*Active"); + dw.dxfInt( 70, 0); + dw.dxfReal( 10, 0.0); + dw.dxfReal( 20, 0.0); + dw.dxfReal( 11, 1.0); + dw.dxfReal( 21, 1.0); + dw.dxfReal( 12, 286.3055555555555); + dw.dxfReal( 22, 148.5); + dw.dxfReal( 13, 0.0); + dw.dxfReal( 23, 0.0); + dw.dxfReal( 14, 10.0); + dw.dxfReal( 24, 10.0); + dw.dxfReal( 15, 10.0); + dw.dxfReal( 25, 10.0); + dw.dxfReal( 16, 0.0); + dw.dxfReal( 26, 0.0); + dw.dxfReal( 36, 1.0); + dw.dxfReal( 17, 0.0); + dw.dxfReal( 27, 0.0); + dw.dxfReal( 37, 0.0); + dw.dxfReal( 40, 297.0); + dw.dxfReal( 41, 1.92798353909465); + dw.dxfReal( 42, 50.0); + dw.dxfReal( 43, 0.0); + dw.dxfReal( 44, 0.0); + dw.dxfReal( 50, 0.0); + dw.dxfReal( 51, 0.0); + dw.dxfInt( 71, 0); + dw.dxfInt( 72, 100); + dw.dxfInt( 73, 1); + dw.dxfInt( 74, 3); + dw.dxfInt( 75, 1); + dw.dxfInt( 76, 1); + dw.dxfInt( 77, 0); + dw.dxfInt( 78, 0); + + if (version==DL_VERSION_2000) + { + dw.dxfInt(281, 0); + dw.dxfInt( 65, 1); + dw.dxfReal(110, 0.0); + dw.dxfReal(120, 0.0); + dw.dxfReal(130, 0.0); + dw.dxfReal(111, 1.0); + dw.dxfReal(121, 0.0); + dw.dxfReal(131, 0.0); + dw.dxfReal(112, 0.0); + dw.dxfReal(122, 1.0); + dw.dxfReal(132, 0.0); + dw.dxfInt( 79, 0); + dw.dxfReal(146, 0.0); + } + dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a style section. This section is needed in DL_VERSION_R13. + */ +void DL_Dxf::writeStyle(DL_WriterA& dw, const DL_StyleData& style) +{ +// dw.dxfString( 0, "TABLE"); +// dw.dxfString( 2, "STYLE"); +// if (version==DL_VERSION_2000) { +// dw.dxfHex(5, 3); +// } + //dw.dxfHex(330, 0); +// if (version==DL_VERSION_2000) { +// dw.dxfString(100, "AcDbSymbolTable"); +// } +// dw.dxfInt( 70, 1); + dw.dxfString( 0, "STYLE"); + if (version==DL_VERSION_2000) + { + if (style.name=="Standard") + { + //dw.dxfHex(5, 0x11); + styleHandleStd = dw.handle(); + } + else + { + dw.handle(); + } + } + //dw.dxfHex(330, 3); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbTextStyleTableRecord"); + } + dw.dxfString( 2, style.name); + dw.dxfInt( 70, style.flags); + dw.dxfReal( 40, style.fixedTextHeight); + dw.dxfReal( 41, style.widthFactor); + dw.dxfReal( 50, style.obliqueAngle); + dw.dxfInt( 71, style.textGenerationFlags); + dw.dxfReal( 42, style.lastHeightUsed); + if (version==DL_VERSION_2000) + { + dw.dxfString( 3, ""); + dw.dxfString( 4, ""); + dw.dxfString(1001, "ACAD"); + //dw.dxfString(1000, style.name); + dw.dxfString(1000, style.primaryFontFile); + int xFlags = 0; + if (style.bold) + { + xFlags = xFlags|0x2000000; + } + if (style.italic) + { + xFlags = xFlags|0x1000000; + } + dw.dxfInt(1071, xFlags); + } + else + { + dw.dxfString( 3, style.primaryFontFile); + dw.dxfString( 4, style.bigFontFile); + } + //dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a view section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked VIEW section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeView(DL_WriterA& dw) +{ + dw.dxfString( 0, "TABLE"); + dw.dxfString( 2, "VIEW"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 6); + } + //dw.dxfHex(330, 0); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTable"); + } + dw.dxfInt( 70, 0); + dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a ucs section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked UCS section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeUcs(DL_WriterA& dw) +{ + dw.dxfString( 0, "TABLE"); + dw.dxfString( 2, "UCS"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 7); + } + //dw.dxfHex(330, 0); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTable"); + } + dw.dxfInt( 70, 0); + dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a dimstyle section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked DIMSTYLE section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeDimStyle(DL_WriterA& dw, + double dimasz, double dimexe, double dimexo, + double dimgap, double dimtxt) +{ + + dw.dxfString( 0, "TABLE"); + dw.dxfString( 2, "DIMSTYLE"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 0xA); + dw.dxfString(100, "AcDbSymbolTable"); + } + dw.dxfInt( 70, 1); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbDimStyleTable"); + dw.dxfInt( 71, 0); + } + + + dw.dxfString( 0, "DIMSTYLE"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(105, 0x27); + } + //dw.handle(105); + //dw.dxfHex(330, 0xA); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbDimStyleTableRecord"); + } + dw.dxfString( 2, "Standard"); + if (version==DL_VERSION_R12) + { + dw.dxfString( 3, ""); + dw.dxfString( 4, ""); + dw.dxfString( 5, ""); + dw.dxfString( 6, ""); + dw.dxfString( 7, ""); + dw.dxfReal( 40, 1.0); + } + + dw.dxfReal( 41, dimasz); + dw.dxfReal( 42, dimexo); + dw.dxfReal( 43, 3.75); + dw.dxfReal( 44, dimexe); + if (version==DL_VERSION_R12) + { + dw.dxfReal( 45, 0.0); + dw.dxfReal( 46, 0.0); + dw.dxfReal( 47, 0.0); + dw.dxfReal( 48, 0.0); + } + dw.dxfInt( 70, 0); + if (version==DL_VERSION_R12) + { + dw.dxfInt( 71, 0); + dw.dxfInt( 72, 0); + } + dw.dxfInt( 73, 0); + dw.dxfInt( 74, 0); + if (version==DL_VERSION_R12) + { + dw.dxfInt( 75, 0); + dw.dxfInt( 76, 0); + } + dw.dxfInt( 77, 1); + dw.dxfInt( 78, 8); + dw.dxfReal(140, dimtxt); + dw.dxfReal(141, 2.5); + if (version==DL_VERSION_R12) + { + dw.dxfReal(142, 0.0); + } + dw.dxfReal(143, 0.03937007874016); + if (version==DL_VERSION_R12) + { + dw.dxfReal(144, 1.0); + dw.dxfReal(145, 0.0); + dw.dxfReal(146, 1.0); + } + dw.dxfReal(147, dimgap); + if (version==DL_VERSION_R12) + { + dw.dxfInt(170, 0); + } + dw.dxfInt(171, 3); + dw.dxfInt(172, 1); + if (version==DL_VERSION_R12) + { + dw.dxfInt(173, 0); + dw.dxfInt(174, 0); + dw.dxfInt(175, 0); + dw.dxfInt(176, 0); + dw.dxfInt(177, 0); + dw.dxfInt(178, 0); + } + if (version==DL_VERSION_2000) + { + dw.dxfInt(271, 2); + dw.dxfInt(272, 2); + dw.dxfInt(274, 3); + dw.dxfInt(278, 44); + dw.dxfInt(283, 0); + dw.dxfInt(284, 8); + dw.dxfHex(340, styleHandleStd); + //dw.dxfHex(340, 0x11); + } + // * / + dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a blockrecord section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked BLOCKRECORD section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeBlockRecord(DL_WriterA& dw) +{ + dw.dxfString( 0, "TABLE"); + dw.dxfString( 2, "BLOCK_RECORD"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 1); + } + //dw.dxfHex(330, 0); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTable"); + } + dw.dxfInt( 70, 1); + + dw.dxfString( 0, "BLOCK_RECORD"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 0x1F); + } + //int msh = dw.handle(); + //dw.setModelSpaceHandle(msh); + //dw.dxfHex(330, 1); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbBlockTableRecord"); + } + dw.dxfString( 2, "*Model_Space"); + dw.dxfHex(340, 0x22); + + dw.dxfString( 0, "BLOCK_RECORD"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 0x1B); + } + //int psh = dw.handle(); + //dw.setPaperSpaceHandle(psh); + //dw.dxfHex(330, 1); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbBlockTableRecord"); + } + dw.dxfString( 2, "*Paper_Space"); + dw.dxfHex(340, 0x1E); + + dw.dxfString( 0, "BLOCK_RECORD"); + if (version==DL_VERSION_2000) + { + dw.dxfHex(5, 0x23); + } + //int ps0h = dw.handle(); + //dw.setPaperSpace0Handle(ps0h); + //dw.dxfHex(330, 1); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbBlockTableRecord"); + } + dw.dxfString( 2, "*Paper_Space0"); + dw.dxfHex(340, 0x26); + + //dw.dxfString( 0, "ENDTAB"); +} + + + +/** + * Writes a single block record with the given name. + */ +void DL_Dxf::writeBlockRecord(DL_WriterA& dw, const std::string& name) +{ + dw.dxfString( 0, "BLOCK_RECORD"); + if (version==DL_VERSION_2000) + { + dw.handle(); + } + //dw->dxfHex(330, 1); + if (version==DL_VERSION_2000) + { + dw.dxfString(100, "AcDbSymbolTableRecord"); + dw.dxfString(100, "AcDbBlockTableRecord"); + } + dw.dxfString( 2, name); + dw.dxfHex(340, 0); +} + + + +/** + * Writes a objects section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked OBJECTS section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeObjects(DL_WriterA& dw, const std::string& appDictionaryName) +{ + dw.dxfString( 0, "SECTION"); + dw.dxfString( 2, "OBJECTS"); + + + dw.dxfString( 0, "DICTIONARY"); + dw.dxfHex(5, 0xC); + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(280, 0); + dw.dxfInt(281, 1); + dw.dxfString( 3, "ACAD_GROUP"); + dw.dxfHex(350, 0xD); + dw.dxfString( 3, "ACAD_LAYOUT"); + dw.dxfHex(350, 0x1A); + dw.dxfString( 3, "ACAD_MLINESTYLE"); + dw.dxfHex(350, 0x17); + dw.dxfString( 3, "ACAD_PLOTSETTINGS"); + dw.dxfHex(350, 0x19); + dw.dxfString( 3, "ACAD_PLOTSTYLENAME"); + dw.dxfHex(350, 0xE); + dw.dxfString( 3, "AcDbVariableDictionary"); + int acDbVariableDictionaryHandle = dw.handle(350); + //int acDbVariableDictionaryHandle = dw.getNextHandle(); + //dw.dxfHex(350, acDbVariableDictionaryHandle); + //dw.incHandle(); + + if (appDictionaryName.length()!=0) + { + dw.dxfString( 3, appDictionaryName); + appDictionaryHandle = dw.handle(350); + //appDictionaryHandle = dw.getNextHandle(); + //dw.dxfHex(350, appDictionaryHandle); + //dw.incHandle(); + } + + dw.dxfString( 0, "DICTIONARY"); + dw.dxfHex(5, 0xD); + //dw.handle(); // D + //dw.dxfHex(330, 0xC); + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(280, 0); + dw.dxfInt(281, 1); + + + dw.dxfString( 0, "ACDBDICTIONARYWDFLT"); + dw.dxfHex(5, 0xE); + //dicId4 = dw.handle(); // E + //dw.dxfHex(330, 0xC); // C + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(281, 1); + dw.dxfString( 3, "Normal"); + dw.dxfHex(350, 0xF); + //dw.dxfHex(350, dw.getNextHandle()+5); // F + dw.dxfString(100, "AcDbDictionaryWithDefault"); + dw.dxfHex(340, 0xF); + //dw.dxfHex(340, dw.getNextHandle()+5); // F + + + dw.dxfString( 0, "ACDBPLACEHOLDER"); + dw.dxfHex(5, 0xF); + //dw.handle(); // F + //dw.dxfHex(330, dicId4); // E + + + dw.dxfString( 0, "DICTIONARY"); + //dicId3 = dw.handle(); // 17 + dw.dxfHex(5, 0x17); + //dw.dxfHex(330, 0xC); // C + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(280, 0); + dw.dxfInt(281, 1); + dw.dxfString( 3, "Standard"); + dw.dxfHex(350, 0x18); + //dw.dxfHex(350, dw.getNextHandle()+5); // 18 + + + dw.dxfString( 0, "MLINESTYLE"); + dw.dxfHex(5, 0x18); + //dw.handle(); // 18 + //dw.dxfHex(330, dicId3); // 17 + dw.dxfString(100, "AcDbMlineStyle"); + dw.dxfString( 2, "STANDARD"); + dw.dxfInt( 70, 0); + dw.dxfString( 3, ""); + dw.dxfInt( 62, 256); + dw.dxfReal( 51, 90.0); + dw.dxfReal( 52, 90.0); + dw.dxfInt( 71, 2); + dw.dxfReal( 49, 0.5); + dw.dxfInt( 62, 256); + dw.dxfString( 6, "BYLAYER"); + dw.dxfReal( 49, -0.5); + dw.dxfInt( 62, 256); + dw.dxfString( 6, "BYLAYER"); + + + dw.dxfString( 0, "DICTIONARY"); + dw.dxfHex(5, 0x19); + //dw.handle(); // 17 + //dw.dxfHex(330, 0xC); // C + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(280, 0); + dw.dxfInt(281, 1); + + + dw.dxfString( 0, "DICTIONARY"); + //dicId2 = dw.handle(); // 1A + dw.dxfHex(5, 0x1A); + //dw.dxfHex(330, 0xC); + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(281, 1); + dw.dxfString( 3, "Layout1"); + dw.dxfHex(350, 0x1E); + //dw.dxfHex(350, dw.getNextHandle()+2); // 1E + dw.dxfString( 3, "Layout2"); + dw.dxfHex(350, 0x26); + //dw.dxfHex(350, dw.getNextHandle()+4); // 26 + dw.dxfString( 3, "Model"); + dw.dxfHex(350, 0x22); + //dw.dxfHex(350, dw.getNextHandle()+5); // 22 + + + dw.dxfString( 0, "LAYOUT"); + dw.dxfHex(5, 0x1E); + //dw.handle(); // 1E + //dw.dxfHex(330, dicId2); // 1A + dw.dxfString(100, "AcDbPlotSettings"); + dw.dxfString( 1, ""); + dw.dxfString( 2, "none_device"); + dw.dxfString( 4, ""); + dw.dxfString( 6, ""); + dw.dxfReal( 40, 0.0); + dw.dxfReal( 41, 0.0); + dw.dxfReal( 42, 0.0); + dw.dxfReal( 43, 0.0); + dw.dxfReal( 44, 0.0); + dw.dxfReal( 45, 0.0); + dw.dxfReal( 46, 0.0); + dw.dxfReal( 47, 0.0); + dw.dxfReal( 48, 0.0); + dw.dxfReal( 49, 0.0); + dw.dxfReal(140, 0.0); + dw.dxfReal(141, 0.0); + dw.dxfReal(142, 1.0); + dw.dxfReal(143, 1.0); + dw.dxfInt( 70, 688); + dw.dxfInt( 72, 0); + dw.dxfInt( 73, 0); + dw.dxfInt( 74, 5); + dw.dxfString( 7, ""); + dw.dxfInt( 75, 16); + dw.dxfReal(147, 1.0); + dw.dxfReal(148, 0.0); + dw.dxfReal(149, 0.0); + dw.dxfString(100, "AcDbLayout"); + dw.dxfString( 1, "Layout1"); + dw.dxfInt( 70, 1); + dw.dxfInt( 71, 1); + dw.dxfReal( 10, 0.0); + dw.dxfReal( 20, 0.0); + dw.dxfReal( 11, 420.0); + dw.dxfReal( 21, 297.0); + dw.dxfReal( 12, 0.0); + dw.dxfReal( 22, 0.0); + dw.dxfReal( 32, 0.0); + dw.dxfReal( 14, 1.000000000000000E+20); + dw.dxfReal( 24, 1.000000000000000E+20); + dw.dxfReal( 34, 1.000000000000000E+20); + dw.dxfReal( 15, -1.000000000000000E+20); + dw.dxfReal( 25, -1.000000000000000E+20); + dw.dxfReal( 35, -1.000000000000000E+20); + dw.dxfReal(146, 0.0); + dw.dxfReal( 13, 0.0); + dw.dxfReal( 23, 0.0); + dw.dxfReal( 33, 0.0); + dw.dxfReal( 16, 1.0); + dw.dxfReal( 26, 0.0); + dw.dxfReal( 36, 0.0); + dw.dxfReal( 17, 0.0); + dw.dxfReal( 27, 1.0); + dw.dxfReal( 37, 0.0); + dw.dxfInt( 76, 0); + //dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B + dw.dxfHex(330, 0x1B); + + + dw.dxfString( 0, "LAYOUT"); + dw.dxfHex(5, 0x22); + //dw.handle(); // 22 + //dw.dxfHex(330, dicId2); // 1A + dw.dxfString(100, "AcDbPlotSettings"); + dw.dxfString( 1, ""); + dw.dxfString( 2, "none_device"); + dw.dxfString( 4, ""); + dw.dxfString( 6, ""); + dw.dxfReal( 40, 0.0); + dw.dxfReal( 41, 0.0); + dw.dxfReal( 42, 0.0); + dw.dxfReal( 43, 0.0); + dw.dxfReal( 44, 0.0); + dw.dxfReal( 45, 0.0); + dw.dxfReal( 46, 0.0); + dw.dxfReal( 47, 0.0); + dw.dxfReal( 48, 0.0); + dw.dxfReal( 49, 0.0); + dw.dxfReal(140, 0.0); + dw.dxfReal(141, 0.0); + dw.dxfReal(142, 1.0); + dw.dxfReal(143, 1.0); + dw.dxfInt( 70, 1712); + dw.dxfInt( 72, 0); + dw.dxfInt( 73, 0); + dw.dxfInt( 74, 0); + dw.dxfString( 7, ""); + dw.dxfInt( 75, 0); + dw.dxfReal(147, 1.0); + dw.dxfReal(148, 0.0); + dw.dxfReal(149, 0.0); + dw.dxfString(100, "AcDbLayout"); + dw.dxfString( 1, "Model"); + dw.dxfInt( 70, 1); + dw.dxfInt( 71, 0); + dw.dxfReal( 10, 0.0); + dw.dxfReal( 20, 0.0); + dw.dxfReal( 11, 12.0); + dw.dxfReal( 21, 9.0); + dw.dxfReal( 12, 0.0); + dw.dxfReal( 22, 0.0); + dw.dxfReal( 32, 0.0); + dw.dxfReal( 14, 0.0); + dw.dxfReal( 24, 0.0); + dw.dxfReal( 34, 0.0); + dw.dxfReal( 15, 0.0); + dw.dxfReal( 25, 0.0); + dw.dxfReal( 35, 0.0); + dw.dxfReal(146, 0.0); + dw.dxfReal( 13, 0.0); + dw.dxfReal( 23, 0.0); + dw.dxfReal( 33, 0.0); + dw.dxfReal( 16, 1.0); + dw.dxfReal( 26, 0.0); + dw.dxfReal( 36, 0.0); + dw.dxfReal( 17, 0.0); + dw.dxfReal( 27, 1.0); + dw.dxfReal( 37, 0.0); + dw.dxfInt( 76, 0); + //dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F + dw.dxfHex(330, 0x1F); + + + dw.dxfString( 0, "LAYOUT"); + //dw.handle(); // 26 + dw.dxfHex(5, 0x26); + //dw.dxfHex(330, dicId2); // 1A + dw.dxfString(100, "AcDbPlotSettings"); + dw.dxfString( 1, ""); + dw.dxfString( 2, "none_device"); + dw.dxfString( 4, ""); + dw.dxfString( 6, ""); + dw.dxfReal( 40, 0.0); + dw.dxfReal( 41, 0.0); + dw.dxfReal( 42, 0.0); + dw.dxfReal( 43, 0.0); + dw.dxfReal( 44, 0.0); + dw.dxfReal( 45, 0.0); + dw.dxfReal( 46, 0.0); + dw.dxfReal( 47, 0.0); + dw.dxfReal( 48, 0.0); + dw.dxfReal( 49, 0.0); + dw.dxfReal(140, 0.0); + dw.dxfReal(141, 0.0); + dw.dxfReal(142, 1.0); + dw.dxfReal(143, 1.0); + dw.dxfInt( 70, 688); + dw.dxfInt( 72, 0); + dw.dxfInt( 73, 0); + dw.dxfInt( 74, 5); + dw.dxfString( 7, ""); + dw.dxfInt( 75, 16); + dw.dxfReal(147, 1.0); + dw.dxfReal(148, 0.0); + dw.dxfReal(149, 0.0); + dw.dxfString(100, "AcDbLayout"); + dw.dxfString( 1, "Layout2"); + dw.dxfInt( 70, 1); + dw.dxfInt( 71, 2); + dw.dxfReal( 10, 0.0); + dw.dxfReal( 20, 0.0); + dw.dxfReal( 11, 12.0); + dw.dxfReal( 21, 9.0); + dw.dxfReal( 12, 0.0); + dw.dxfReal( 22, 0.0); + dw.dxfReal( 32, 0.0); + dw.dxfReal( 14, 0.0); + dw.dxfReal( 24, 0.0); + dw.dxfReal( 34, 0.0); + dw.dxfReal( 15, 0.0); + dw.dxfReal( 25, 0.0); + dw.dxfReal( 35, 0.0); + dw.dxfReal(146, 0.0); + dw.dxfReal( 13, 0.0); + dw.dxfReal( 23, 0.0); + dw.dxfReal( 33, 0.0); + dw.dxfReal( 16, 1.0); + dw.dxfReal( 26, 0.0); + dw.dxfReal( 36, 0.0); + dw.dxfReal( 17, 0.0); + dw.dxfReal( 27, 1.0); + dw.dxfReal( 37, 0.0); + dw.dxfInt( 76, 0); + //dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23 + dw.dxfHex(330, 0x23); + + dw.dxfString( 0, "DICTIONARY"); + //dw.dxfHex(5, 0x2C); + //dicId5 = + dw.dxfHex(5, acDbVariableDictionaryHandle); + //dw.handle(); // 2C + //dw.dxfHex(330, 0xC); // C + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(281, 1); + dw.dxfString( 3, "DIMASSOC"); + //dw.dxfHex(350, 0x2F); + dw.dxfHex(350, dw.getNextHandle()+1); // 2E + dw.dxfString( 3, "HIDETEXT"); + //dw.dxfHex(350, 0x2E); + dw.dxfHex(350, dw.getNextHandle()); // 2D + + + dw.dxfString( 0, "DICTIONARYVAR"); + //dw.dxfHex(5, 0x2E); + dw.handle(); // 2E + //dw.dxfHex(330, dicId5); // 2C + dw.dxfString(100, "DictionaryVariables"); + dw.dxfInt(280, 0); + dw.dxfInt( 1, 2); + + + dw.dxfString( 0, "DICTIONARYVAR"); + //dw.dxfHex(5, 0x2D); + dw.handle(); // 2D + //dw.dxfHex(330, dicId5); // 2C + dw.dxfString(100, "DictionaryVariables"); + dw.dxfInt(280, 0); + dw.dxfInt( 1, 1); +} + +void DL_Dxf::writeAppDictionary(DL_WriterA& dw) +{ + dw.dxfString( 0, "DICTIONARY"); + //dw.handle(); + dw.dxfHex(5, appDictionaryHandle); + dw.dxfString(100, "AcDbDictionary"); + dw.dxfInt(281, 1); +} + +int DL_Dxf::writeDictionaryEntry(DL_WriterA& dw, const std::string& name) +{ + dw.dxfString( 3, name); + int handle = dw.getNextHandle(); + dw.dxfHex(350, handle); + dw.incHandle(); + return handle; +} + +void DL_Dxf::writeXRecord(DL_WriterA& dw, int handle, int value) +{ + dw.dxfString( 0, "XRECORD"); + dw.dxfHex(5, handle); + dw.dxfHex(330, appDictionaryHandle); + dw.dxfString(100, "AcDbXrecord"); + dw.dxfInt(280, 1); + dw.dxfInt(90, value); +} + +void DL_Dxf::writeXRecord(DL_WriterA& dw, int handle, double value) +{ + dw.dxfString( 0, "XRECORD"); + dw.dxfHex(5, handle); + dw.dxfHex(330, appDictionaryHandle); + dw.dxfString(100, "AcDbXrecord"); + dw.dxfInt(280, 1); + dw.dxfReal(40, value); +} + +void DL_Dxf::writeXRecord(DL_WriterA& dw, int handle, bool value) +{ + dw.dxfString( 0, "XRECORD"); + dw.dxfHex(5, handle); + dw.dxfHex(330, appDictionaryHandle); + dw.dxfString(100, "AcDbXrecord"); + dw.dxfInt(280, 1); + dw.dxfBool(290, value); +} + +void DL_Dxf::writeXRecord(DL_WriterA& dw, int handle, const std::string& value) +{ + dw.dxfString( 0, "XRECORD"); + dw.dxfHex(5, handle); + dw.dxfHex(330, appDictionaryHandle); + dw.dxfString(100, "AcDbXrecord"); + dw.dxfInt(280, 1); + dw.dxfString(1000, value); +} + +/** + * Writes the end of the objects section. This section is needed in DL_VERSION_R13. + * Note that this method currently only writes a faked OBJECTS section + * to make the file readable by Aut*cad. + */ +void DL_Dxf::writeObjectsEnd(DL_WriterA& dw) +{ + dw.dxfString( 0, "ENDSEC"); +} + + + +/** + * Writes a comment to the DXF file. + */ +void DL_Dxf::writeComment(DL_WriterA& dw, const std::string& comment) +{ + dw.dxfString(999, comment); +} + + +/** + * Checks if the given variable is known by the given DXF version. + */ +bool DL_Dxf::checkVariable(const char* var, DL_Codes::version version) +{ + if (version>=DL_VERSION_2000) + { + return true; + } + else if (version==DL_VERSION_R12) + { + // these are all the variables recognized by dxf r12: + if (!strcmp(var, "$ACADVER")) + { + return true; + } + if (!strcmp(var, "$ACADVER")) + { + return true; + } + if (!strcmp(var, "$ANGBASE")) + { + return true; + } + if (!strcmp(var, "$ANGDIR")) + { + return true; + } + if (!strcmp(var, "$ATTDIA")) + { + return true; + } + if (!strcmp(var, "$ATTMODE")) + { + return true; + } + if (!strcmp(var, "$ATTREQ")) + { + return true; + } + if (!strcmp(var, "$AUNITS")) + { + return true; + } + if (!strcmp(var, "$AUPREC")) + { + return true; + } + if (!strcmp(var, "$AXISMODE")) + { + return true; + } + if (!strcmp(var, "$AXISUNIT")) + { + return true; + } + if (!strcmp(var, "$BLIPMODE")) + { + return true; + } + if (!strcmp(var, "$CECOLOR")) + { + return true; + } + if (!strcmp(var, "$CELTYPE")) + { + return true; + } + if (!strcmp(var, "$CHAMFERA")) + { + return true; + } + if (!strcmp(var, "$CHAMFERB")) + { + return true; + } + if (!strcmp(var, "$CLAYER")) + { + return true; + } + if (!strcmp(var, "$COORDS")) + { + return true; + } + if (!strcmp(var, "$DIMALT")) + { + return true; + } + if (!strcmp(var, "$DIMALTD")) + { + return true; + } + if (!strcmp(var, "$DIMALTF")) + { + return true; + } + if (!strcmp(var, "$DIMAPOST")) + { + return true; + } + if (!strcmp(var, "$DIMASO")) + { + return true; + } + if (!strcmp(var, "$DIMASZ")) + { + return true; + } + if (!strcmp(var, "$DIMBLK")) + { + return true; + } + if (!strcmp(var, "$DIMBLK1")) + { + return true; + } + if (!strcmp(var, "$DIMBLK2")) + { + return true; + } + if (!strcmp(var, "$DIMCEN")) + { + return true; + } + if (!strcmp(var, "$DIMCLRD")) + { + return true; + } + if (!strcmp(var, "$DIMCLRE")) + { + return true; + } + if (!strcmp(var, "$DIMCLRT")) + { + return true; + } + if (!strcmp(var, "$DIMDLE")) + { + return true; + } + if (!strcmp(var, "$DIMDLI")) + { + return true; + } + if (!strcmp(var, "$DIMEXE")) + { + return true; + } + if (!strcmp(var, "$DIMEXO")) + { + return true; + } + if (!strcmp(var, "$DIMGAP")) + { + return true; + } + if (!strcmp(var, "$DIMLFAC")) + { + return true; + } + if (!strcmp(var, "$DIMLIM")) + { + return true; + } + if (!strcmp(var, "$DIMPOST")) + { + return true; + } + if (!strcmp(var, "$DIMRND")) + { + return true; + } + if (!strcmp(var, "$DIMSAH")) + { + return true; + } + if (!strcmp(var, "$DIMSCALE")) + { + return true; + } + if (!strcmp(var, "$DIMSE1")) + { + return true; + } + if (!strcmp(var, "$DIMSE2")) + { + return true; + } + if (!strcmp(var, "$DIMSHO")) + { + return true; + } + if (!strcmp(var, "$DIMSOXD")) + { + return true; + } + if (!strcmp(var, "$DIMSTYLE")) + { + return true; + } + if (!strcmp(var, "$DIMTAD")) + { + return true; + } + if (!strcmp(var, "$DIMTFAC")) + { + return true; + } + if (!strcmp(var, "$DIMTIH")) + { + return true; + } + if (!strcmp(var, "$DIMTIX")) + { + return true; + } + if (!strcmp(var, "$DIMTM")) + { + return true; + } + if (!strcmp(var, "$DIMTOFL")) + { + return true; + } + if (!strcmp(var, "$DIMTOH")) + { + return true; + } + if (!strcmp(var, "$DIMTOL")) + { + return true; + } + if (!strcmp(var, "$DIMTP")) + { + return true; + } + if (!strcmp(var, "$DIMTSZ")) + { + return true; + } + if (!strcmp(var, "$DIMTVP")) + { + return true; + } + if (!strcmp(var, "$DIMTXT")) + { + return true; + } + if (!strcmp(var, "$DIMZIN")) + { + return true; + } + if (!strcmp(var, "$DWGCODEPAGE")) + { + return true; + } + if (!strcmp(var, "$DRAGMODE")) + { + return true; + } + if (!strcmp(var, "$ELEVATION")) + { + return true; + } + if (!strcmp(var, "$EXTMAX")) + { + return true; + } + if (!strcmp(var, "$EXTMIN")) + { + return true; + } + if (!strcmp(var, "$FILLETRAD")) + { + return true; + } + if (!strcmp(var, "$FILLMODE")) + { + return true; + } + if (!strcmp(var, "$HANDLING")) + { + return true; + } + if (!strcmp(var, "$HANDSEED")) + { + return true; + } + if (!strcmp(var, "$INSBASE")) + { + return true; + } + if (!strcmp(var, "$LIMCHECK")) + { + return true; + } + if (!strcmp(var, "$LIMMAX")) + { + return true; + } + if (!strcmp(var, "$LIMMIN")) + { + return true; + } + if (!strcmp(var, "$LTSCALE")) + { + return true; + } + if (!strcmp(var, "$LUNITS")) + { + return true; + } + if (!strcmp(var, "$LUPREC")) + { + return true; + } + if (!strcmp(var, "$MAXACTVP")) + { + return true; + } + if (!strcmp(var, "$MENU")) + { + return true; + } + if (!strcmp(var, "$MIRRTEXT")) + { + return true; + } + if (!strcmp(var, "$ORTHOMODE")) + { + return true; + } + if (!strcmp(var, "$OSMODE")) + { + return true; + } + if (!strcmp(var, "$PDMODE")) + { + return true; + } + if (!strcmp(var, "$PDSIZE")) + { + return true; + } + if (!strcmp(var, "$PELEVATION")) + { + return true; + } + if (!strcmp(var, "$PEXTMAX")) + { + return true; + } + if (!strcmp(var, "$PEXTMIN")) + { + return true; + } + if (!strcmp(var, "$PLIMCHECK")) + { + return true; + } + if (!strcmp(var, "$PLIMMAX")) + { + return true; + } + if (!strcmp(var, "$PLIMMIN")) + { + return true; + } + if (!strcmp(var, "$PLINEGEN")) + { + return true; + } + if (!strcmp(var, "$PLINEWID")) + { + return true; + } + if (!strcmp(var, "$PSLTSCALE")) + { + return true; + } + if (!strcmp(var, "$PUCSNAME")) + { + return true; + } + if (!strcmp(var, "$PUCSORG")) + { + return true; + } + if (!strcmp(var, "$PUCSXDIR")) + { + return true; + } + if (!strcmp(var, "$PUCSYDIR")) + { + return true; + } + if (!strcmp(var, "$QTEXTMODE")) + { + return true; + } + if (!strcmp(var, "$REGENMODE")) + { + return true; + } + if (!strcmp(var, "$SHADEDGE")) + { + return true; + } + if (!strcmp(var, "$SHADEDIF")) + { + return true; + } + if (!strcmp(var, "$SKETCHINC")) + { + return true; + } + if (!strcmp(var, "$SKPOLY")) + { + return true; + } + if (!strcmp(var, "$SPLFRAME")) + { + return true; + } + if (!strcmp(var, "$SPLINESEGS")) + { + return true; + } + if (!strcmp(var, "$SPLINETYPE")) + { + return true; + } + if (!strcmp(var, "$SURFTAB1")) + { + return true; + } + if (!strcmp(var, "$SURFTAB2")) + { + return true; + } + if (!strcmp(var, "$SURFTYPE")) + { + return true; + } + if (!strcmp(var, "$SURFU")) + { + return true; + } + if (!strcmp(var, "$SURFV")) + { + return true; + } + if (!strcmp(var, "$TDCREATE")) + { + return true; + } + if (!strcmp(var, "$TDINDWG")) + { + return true; + } + if (!strcmp(var, "$TDUPDATE")) + { + return true; + } + if (!strcmp(var, "$TDUSRTIMER")) + { + return true; + } + if (!strcmp(var, "$TEXTSIZE")) + { + return true; + } + if (!strcmp(var, "$TEXTSTYLE")) + { + return true; + } + if (!strcmp(var, "$THICKNESS")) + { + return true; + } + if (!strcmp(var, "$TILEMODE")) + { + return true; + } + if (!strcmp(var, "$TRACEWID")) + { + return true; + } + if (!strcmp(var, "$UCSNAME")) + { + return true; + } + if (!strcmp(var, "$UCSORG")) + { + return true; + } + if (!strcmp(var, "$UCSXDIR")) + { + return true; + } + if (!strcmp(var, "$UCSYDIR")) + { + return true; + } + if (!strcmp(var, "$UNITMODE")) + { + return true; + } + if (!strcmp(var, "$USERI1")) + { + return true; + } + if (!strcmp(var, "$USERR1")) + { + return true; + } + if (!strcmp(var, "$USRTIMER")) + { + return true; + } + if (!strcmp(var, "$VISRETAIN")) + { + return true; + } + if (!strcmp(var, "$WORLDVIEW")) + { + return true; + } + if (!strcmp(var, "$FASTZOOM")) + { + return true; + } + if (!strcmp(var, "$GRIDMODE")) + { + return true; + } + if (!strcmp(var, "$GRIDUNIT")) + { + return true; + } + if (!strcmp(var, "$SNAPANG")) + { + return true; + } + if (!strcmp(var, "$SNAPBASE")) + { + return true; + } + if (!strcmp(var, "$SNAPISOPAIR")) + { + return true; + } + if (!strcmp(var, "$SNAPMODE")) + { + return true; + } + if (!strcmp(var, "$SNAPSTYLE")) + { + return true; + } + if (!strcmp(var, "$SNAPUNIT")) + { + return true; + } + if (!strcmp(var, "$VIEWCTR")) + { + return true; + } + if (!strcmp(var, "$VIEWDIR")) + { + return true; + } + if (!strcmp(var, "$VIEWSIZE")) + { + return true; + } + return false; + } + + return false; +} + + + +/** + * @returns the library version as int (4 bytes, each byte one version number). + * e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200 + */ +int DL_Dxf::getLibVersion(const std::string& str) +{ + int d[4]; + int idx = 0; + //char v[4][5]; + std::string v[4]; + int ret = 0; + + for (unsigned int i=0; i=2) + { + d[3] = str.length(); + + v[0] = str.substr(0, d[0]); + v[1] = str.substr(d[0]+1, d[1]-d[0]-1); + v[2] = str.substr(d[1]+1, d[2]-d[1]-1); + if (idx>=3) + { + v[3] = str.substr(d[2]+1, d[3]-d[2]-1); + } + else + { + v[3] = "0"; + } + + ret = (atoi(v[0].c_str())<<(3*8)) + + (atoi(v[1].c_str())<<(2*8)) + + (atoi(v[2].c_str())<<(1*8)) + + (atoi(v[3].c_str())<<(0*8)); + + return ret; + } + else + { + std::cerr << "DL_Dxf::getLibVersion: invalid version number: " << str << "\n"; + return 0; + } +} + +/** + * Converts the given string into a double or returns the given + * default valud (def) if value is NULL or empty. + */ +//double DL_Dxf::toReal(const char* value, double def) { +// if (value!=NULL && value[0] != '\0') { +// printf("toReal: not empty: %s\n", value); +// printf("toReal: val: %f\n", atof(value)); +// printf("toReal: 0: %d\n", value[0]); +// printf("toReal: 1: %d\n", value[1]); +// printf("toReal: 2: %d\n", value[2]); +// double ret; +// if (strchr(value, ',') != NULL) { +// char* tmp = new char[strlen(value)+1]; +// strcpy(tmp, value); +// DL_WriterA::strReplace(tmp, ',', '.'); +// ret = atof(tmp); +// delete[] tmp; +// } +// else { +// ret = atof(value); +// } +// return ret; +// } else { +// return def; +// } +//} + + +/** + * Some test routines. + */ +void DL_Dxf::test() +{ + char* buf1; + char* buf2; + char* buf3; + char* buf4; + char* buf5; + char* buf6; + + buf1 = new char[10]; + buf2 = new char[10]; + buf3 = new char[10]; + buf4 = new char[10]; + buf5 = new char[10]; + buf6 = new char[10]; + + strcpy(buf1, " 10\n"); + strcpy(buf2, "10"); + strcpy(buf3, "10\n"); + strcpy(buf4, " 10 \n"); + strcpy(buf5, " 10 \r"); + strcpy(buf6, "\t10 \n"); + + std::cout << "1 buf1: '" << buf1 << "'\n"; + stripWhiteSpace(&buf1); + std::cout << "2 buf1: '" << buf1 << "'\n"; + //assert(!strcmp(buf1, "10")); + + std::cout << "1 buf2: '" << buf2 << "'\n"; + stripWhiteSpace(&buf2); + std::cout << "2 buf2: '" << buf2 << "'\n"; + + std::cout << "1 buf3: '" << buf3 << "'\n"; + stripWhiteSpace(&buf3); + std::cout << "2 buf3: '" << buf3 << "'\n"; + + std::cout << "1 buf4: '" << buf4 << "'\n"; + stripWhiteSpace(&buf4); + std::cout << "2 buf4: '" << buf4 << "'\n"; + + std::cout << "1 buf5: '" << buf5 << "'\n"; + stripWhiteSpace(&buf5); + std::cout << "2 buf5: '" << buf5 << "'\n"; + + std::cout << "1 buf6: '" << buf6 << "'\n"; + stripWhiteSpace(&buf6); + std::cout << "2 buf6: '" << buf6 << "'\n"; + +} + + diff --git a/src/libs/vdxf/dxflib/dl_dxf.h b/src/libs/vdxf/dxflib/dl_dxf.h new file mode 100644 index 000000000..32eb0c2a8 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_dxf.h @@ -0,0 +1,522 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_DXF_H +#define DL_DXF_H + +#include "dl_global.h" + +#include +#include +#include +#include +#include + +#include "dl_attributes.h" +#include "dl_codes.h" +#include "dl_entities.h" +#include "dl_writer_ascii.h" + +#ifdef _WIN32 +#undef M_PI +#define M_PI 3.14159265358979323846 +#pragma warning(disable : 4800) +#endif + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +class DL_CreationInterface; +class DL_WriterA; + + +#define DL_VERSION "3.7.5.0" + +#define DL_VERSION_MAJOR 3 +#define DL_VERSION_MINOR 7 +#define DL_VERSION_REV 5 +#define DL_VERSION_BUILD 0 + +#define DL_UNKNOWN 0 +#define DL_LAYER 10 +#define DL_BLOCK 11 +#define DL_ENDBLK 12 +#define DL_LINETYPE 13 +#define DL_STYLE 20 +#define DL_SETTING 50 +#define DL_ENTITY_POINT 100 +#define DL_ENTITY_LINE 101 +#define DL_ENTITY_POLYLINE 102 +#define DL_ENTITY_LWPOLYLINE 103 +#define DL_ENTITY_VERTEX 104 +#define DL_ENTITY_SPLINE 105 +#define DL_ENTITY_KNOT 106 +#define DL_ENTITY_CONTROLPOINT 107 +#define DL_ENTITY_ARC 108 +#define DL_ENTITY_CIRCLE 109 +#define DL_ENTITY_ELLIPSE 110 +#define DL_ENTITY_INSERT 111 +#define DL_ENTITY_TEXT 112 +#define DL_ENTITY_MTEXT 113 +#define DL_ENTITY_DIMENSION 114 +#define DL_ENTITY_LEADER 115 +#define DL_ENTITY_HATCH 116 +#define DL_ENTITY_ATTRIB 117 +#define DL_ENTITY_IMAGE 118 +#define DL_ENTITY_IMAGEDEF 119 +#define DL_ENTITY_TRACE 120 +#define DL_ENTITY_SOLID 121 +#define DL_ENTITY_3DFACE 122 +#define DL_ENTITY_XLINE 123 +#define DL_ENTITY_RAY 124 +#define DL_ENTITY_SEQEND 125 +#define DL_XRECORD 200 +#define DL_DICTIONARY 210 + + +/** + * Reading and writing of DXF files. + * + * This class can read in a DXF file and calls methods from the + * interface DL_EntityContainer to add the entities to the + * contianer provided by the user of the library. + * + * It can also be used to write DXF files to a certain extent. + * + * When saving entities, special values for colors and linetypes + * can be used: + * + * Special colors are 0 (=BYBLOCK) and 256 (=BYLAYER). + * Special linetypes are "BYLAYER" and "BYBLOCK". + * + * @author Andrew Mustun + */ +class DXFLIB_EXPORT DL_Dxf +{ +public: + DL_Dxf(); + ~DL_Dxf(); + + bool in(const std::string& file, + DL_CreationInterface* creationInterface); + bool readDxfGroups(FILE* fp, + DL_CreationInterface* creationInterface); + static bool getStrippedLine(std::string& s, unsigned int size, + FILE* stream); + + bool readDxfGroups(std::stringstream& stream, + DL_CreationInterface* creationInterface); + bool in(std::stringstream &stream, + DL_CreationInterface* creationInterface); + static bool getStrippedLine(std::string& s, unsigned int size, + std::stringstream& stream); + + static bool stripWhiteSpace(char** s); + + bool processDXFGroup(DL_CreationInterface* creationInterface, + int groupCode, const std::string& groupValue); + void addSetting(DL_CreationInterface* creationInterface); + void addLayer(DL_CreationInterface* creationInterface); + void addLinetype(DL_CreationInterface *creationInterface); + void addBlock(DL_CreationInterface* creationInterface); + void endBlock(DL_CreationInterface* creationInterface); + void addTextStyle(DL_CreationInterface* creationInterface); + + void addPoint(DL_CreationInterface* creationInterface); + void addLine(DL_CreationInterface* creationInterface); + void addXLine(DL_CreationInterface* creationInterface); + void addRay(DL_CreationInterface* creationInterface); + + void addPolyline(DL_CreationInterface* creationInterface); + void addVertex(DL_CreationInterface* creationInterface); + + void addSpline(DL_CreationInterface* creationInterface); + + void addArc(DL_CreationInterface* creationInterface); + void addCircle(DL_CreationInterface* creationInterface); + void addEllipse(DL_CreationInterface* creationInterface); + void addInsert(DL_CreationInterface* creationInterface); + + void addTrace(DL_CreationInterface* creationInterface); + void add3dFace(DL_CreationInterface* creationInterface); + void addSolid(DL_CreationInterface* creationInterface); + + void addMText(DL_CreationInterface* creationInterface); + void addText(DL_CreationInterface* creationInterface); + + void addAttribute(DL_CreationInterface* creationInterface); + + DL_DimensionData getDimData(); + void addDimLinear(DL_CreationInterface* creationInterface); + void addDimAligned(DL_CreationInterface* creationInterface); + void addDimRadial(DL_CreationInterface* creationInterface); + void addDimDiametric(DL_CreationInterface* creationInterface); + void addDimAngular(DL_CreationInterface* creationInterface); + void addDimAngular3P(DL_CreationInterface* creationInterface); + void addDimOrdinate(DL_CreationInterface* creationInterface); + + void addLeader(DL_CreationInterface* creationInterface); + + void addHatch(DL_CreationInterface* creationInterface); + void addHatchLoop(); + void addHatchEdge(); + bool handleHatchData(DL_CreationInterface* creationInterface); + + void addImage(DL_CreationInterface* creationInterface); + void addImageDef(DL_CreationInterface* creationInterface); + + void addComment(DL_CreationInterface* creationInterface, const std::string& comment); + + void addDictionary(DL_CreationInterface* creationInterface); + void addDictionaryEntry(DL_CreationInterface* creationInterface); + + bool handleXRecordData(DL_CreationInterface* creationInterface); + bool handleDictionaryData(DL_CreationInterface* creationInterface); + + bool handleXData(DL_CreationInterface *creationInterface); + bool handleMTextData(DL_CreationInterface* creationInterface); + bool handleLWPolylineData(DL_CreationInterface* creationInterface); + bool handleSplineData(DL_CreationInterface* creationInterface); + bool handleLeaderData(DL_CreationInterface* creationInterface); + bool handleLinetypeData(DL_CreationInterface* creationInterface); + + void endEntity(DL_CreationInterface* creationInterface); + + void endSequence(DL_CreationInterface* creationInterface); + + //int stringToInt(const char* s, bool* ok=NULL); + + DL_WriterA* out(const char* file, + DL_Codes::version version=DL_VERSION_2000); + + void writeHeader(DL_WriterA& dw); + + void writePoint(DL_WriterA& dw, + const DL_PointData& data, + const DL_Attributes& attrib); + void writeLine(DL_WriterA& dw, + const DL_LineData& data, + const DL_Attributes& attrib); + void writeXLine(DL_WriterA& dw, + const DL_XLineData& data, + const DL_Attributes& attrib); + void writeRay(DL_WriterA& dw, + const DL_RayData& data, + const DL_Attributes& attrib); + void writePolyline(DL_WriterA& dw, + const DL_PolylineData& data, + const DL_Attributes& attrib); + void writeVertex(DL_WriterA& dw, + const DL_VertexData& data); + void writePolylineEnd(DL_WriterA& dw); + void writeSpline(DL_WriterA& dw, + const DL_SplineData& data, + const DL_Attributes& attrib); + void writeControlPoint(DL_WriterA& dw, + const DL_ControlPointData& data); + void writeFitPoint(DL_WriterA& dw, + const DL_FitPointData& data); + void writeKnot(DL_WriterA& dw, + const DL_KnotData& data); + void writeCircle(DL_WriterA& dw, + const DL_CircleData& data, + const DL_Attributes& attrib); + void writeArc(DL_WriterA& dw, + const DL_ArcData& data, + const DL_Attributes& attrib); + void writeEllipse(DL_WriterA& dw, + const DL_EllipseData& data, + const DL_Attributes& attrib); + void writeSolid(DL_WriterA& dw, + const DL_SolidData& data, + const DL_Attributes& attrib); + void writeTrace(DL_WriterA& dw, + const DL_TraceData& data, + const DL_Attributes& attrib); + void write3dFace(DL_WriterA& dw, + const DL_3dFaceData& data, + const DL_Attributes& attrib); + void writeInsert(DL_WriterA& dw, + const DL_InsertData& data, + const DL_Attributes& attrib); + void writeMText(DL_WriterA& dw, + const DL_MTextData& data, + const DL_Attributes& attrib); + void writeText(DL_WriterA& dw, + const DL_TextData& data, + const DL_Attributes& attrib); + void writeAttribute(DL_WriterA& dw, + const DL_AttributeData& data, + const DL_Attributes& attrib); + void writeDimStyleOverrides(DL_WriterA& dw, + const DL_DimensionData& data); + void writeDimAligned(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimAlignedData& edata, + const DL_Attributes& attrib); + void writeDimLinear(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimLinearData& edata, + const DL_Attributes& attrib); + void writeDimRadial(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimRadialData& edata, + const DL_Attributes& attrib); + void writeDimDiametric(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimDiametricData& edata, + const DL_Attributes& attrib); + void writeDimAngular(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimAngularData& edata, + const DL_Attributes& attrib); + void writeDimAngular3P(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimAngular3PData& edata, + const DL_Attributes& attrib); + void writeDimOrdinate(DL_WriterA& dw, + const DL_DimensionData& data, + const DL_DimOrdinateData& edata, + const DL_Attributes& attrib); + void writeLeader(DL_WriterA& dw, + const DL_LeaderData& data, + const DL_Attributes& attrib); + void writeLeaderVertex(DL_WriterA& dw, + const DL_LeaderVertexData& data); + void writeHatch1(DL_WriterA& dw, + const DL_HatchData& data, + const DL_Attributes& attrib); + void writeHatch2(DL_WriterA& dw, + const DL_HatchData& data, + const DL_Attributes& attrib); + void writeHatchLoop1(DL_WriterA& dw, + const DL_HatchLoopData& data); + void writeHatchLoop2(DL_WriterA& dw, + const DL_HatchLoopData& data); + void writeHatchEdge(DL_WriterA& dw, + const DL_HatchEdgeData& data); + + int writeImage(DL_WriterA& dw, + const DL_ImageData& data, + const DL_Attributes& attrib); + + void writeImageDef(DL_WriterA& dw, int handle, + const DL_ImageData& data); + + void writeLayer(DL_WriterA& dw, + const DL_LayerData& data, + const DL_Attributes& attrib); + + void writeLinetype(DL_WriterA& dw, + const DL_LinetypeData& data); + + void writeAppid(DL_WriterA& dw, const std::string& name); + + void writeBlock(DL_WriterA& dw, + const DL_BlockData& data); + void writeEndBlock(DL_WriterA& dw, const std::string& name); + + void writeVPort(DL_WriterA& dw); + void writeStyle(DL_WriterA& dw, const DL_StyleData& style); + void writeView(DL_WriterA& dw); + void writeUcs(DL_WriterA& dw); + void writeDimStyle(DL_WriterA& dw, + double dimasz, double dimexe, double dimexo, + double dimgap, double dimtxt); + void writeBlockRecord(DL_WriterA& dw); + void writeBlockRecord(DL_WriterA& dw, const std::string& name); + void writeObjects(DL_WriterA& dw, const std::string& appDictionaryName = ""); + void writeAppDictionary(DL_WriterA& dw); + int writeDictionaryEntry(DL_WriterA& dw, const std::string& name); + void writeXRecord(DL_WriterA& dw, int handle, int value); + void writeXRecord(DL_WriterA& dw, int handle, double value); + void writeXRecord(DL_WriterA& dw, int handle, bool value); + void writeXRecord(DL_WriterA& dw, int handle, const std::string& value); + void writeObjectsEnd(DL_WriterA& dw); + + void writeComment(DL_WriterA& dw, const std::string& comment); + + /** + * Converts the given string into a double or returns the given + * default valud (def) if value is NULL or empty. + */ + //static double toReal(const char* value, double def=0.0); + + /** + * Converts the given string into an int or returns the given + * default valud (def) if value is NULL or empty. + */ +// static int toInt(const char* value, int def=0) { +// if (value!=NULL && value[0] != '\0') { +// return atoi(value); +// } + +// return def; +// } + + /** + * Converts the given string into a string or returns the given + * default valud (def) if value is NULL or empty. + */ +// static const char* toString(const char* value, const char* def="") { +// if (value!=NULL && value[0] != '\0') { +// return value; +// } else { +// return def; +// } +// } + + static bool checkVariable(const char* var, DL_Codes::version version); + + DL_Codes::version getVersion() + { + return version; + } + + int getLibVersion(const std::string &str); + + static void test(); + + bool hasValue(int code) + { + return values.count(code)==1; + } + + int getIntValue(int code, int def) + { + if (!hasValue(code)) + { + return def; + } + return toInt(values[code]); + } + + int toInt(const std::string& str) + { + char* p; + return strtol(str.c_str(), &p, 10); + } + + bool toBool(const std::string& str) + { + char* p; + return (bool)strtol(str.c_str(), &p, 10); + } + + std::string getStringValue(int code, const std::string& def) + { + if (!hasValue(code)) + { + return def; + } + return values[code]; + } + + double getRealValue(int code, double def) + { + if (!hasValue(code)) + { + return def; + } + return toReal(values[code]); + } + + double toReal(const std::string& str) + { + double ret; + // make sure the real value uses '.' not ',': + std::string str2 = str; + std::replace(str2.begin(), str2.end(), ',', '.'); + // make sure c++ expects '.' not ',': + std::istringstream istr(str2); + istr.imbue(std::locale("C")); + istr >> ret; + return ret; + } + +private: + DL_Codes::version version; + + std::string polylineLayer; + double* vertices; + int maxVertices; + int vertexIndex; + + double* knots; + int maxKnots; + int knotIndex; + + double* weights; + int weightIndex; + + double* controlPoints; + int maxControlPoints; + int controlPointIndex; + + double* fitPoints; + int maxFitPoints; + int fitPointIndex; + + double* leaderVertices; + int maxLeaderVertices; + int leaderVertexIndex; + + bool firstHatchLoop; + DL_HatchEdgeData hatchEdge; + std::vector > hatchEdges; + + std::string xRecordHandle; + bool xRecordValues; + + // Only the useful part of the group code + std::string groupCodeTmp; + // ...same as integer + unsigned int groupCode; + // Only the useful part of the group value + std::string groupValue; + // Current entity type + int currentObjectType; + // Value of the current setting + char settingValue[DL_DXF_MAXLINE+1]; + // Key of the current setting (e.g. "$ACADVER") + std::string settingKey; + // Stores the group codes + std::map values; + // First call of this method. We initialize all group values in + // the first call. + bool firstCall; + // Attributes of the current entity (layer, color, width, line type) + DL_Attributes attrib; + // library version. hex: 0x20003001 = 2.0.3.1 + int libVersion; + // app specific dictionary handle: + unsigned long appDictionaryHandle; + // handle of standard text style, referenced by dimstyle: + unsigned long styleHandleStd; +}; + +#endif + +// EOF diff --git a/src/libs/vdxf/dxflib/dl_entities.h b/src/libs/vdxf/dxflib/dl_entities.h new file mode 100644 index 000000000..67c8597ff --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_entities.h @@ -0,0 +1,1805 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_ENTITIES_H +#define DL_ENTITIES_H + +#include "dl_global.h" + +#include +#include + +/** + * Layer Data. + */ +struct DXFLIB_EXPORT DL_LayerData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_LayerData(const std::string& lName, + int lFlags) + { + name = lName; + flags = lFlags; + } + + /** Layer name. */ + std::string name; + /** Layer flags. (1 = frozen, 2 = frozen by default, 4 = locked) */ + int flags; +}; + + + +/** + * Block Data. + */ +struct DXFLIB_EXPORT DL_BlockData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_BlockData(const std::string& bName, + int bFlags, + double bbpx, double bbpy, double bbpz) + { + name = bName; + flags = bFlags; + bpx = bbpx; + bpy = bbpy; + bpz = bbpz; + } + + /** Block name. */ + std::string name; + /** Block flags. (not used currently) */ + int flags; + /** X Coordinate of base point. */ + double bpx; + /** Y Coordinate of base point. */ + double bpy; + /** Z Coordinate of base point. */ + double bpz; +}; + + +/** + * Line Type Data. + */ +struct DXFLIB_EXPORT DL_LinetypeData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_LinetypeData( + const std::string& name, + const std::string& description, + int flags, + int numberOfDashes, + double patternLength, + double* pattern = NULL + ) + : name(name), + description(description), + flags(flags), + numberOfDashes(numberOfDashes), + patternLength(patternLength), + pattern(pattern) + {} + + /** Linetype name */ + std::string name; + /** Linetype description */ + std::string description; + /** Linetype flags */ + int flags; + /** Number of dashes */ + int numberOfDashes; + /** Pattern length */ + double patternLength; + /** Pattern */ + double* pattern; +}; + + + +/** + * Text style data. + */ +struct DXFLIB_EXPORT DL_StyleData +{ + /** + * Constructor + * Parameters: see member variables. + */ + DL_StyleData( + const std::string& name, + int flags, + double fixedTextHeight, + double widthFactor, + double obliqueAngle, + int textGenerationFlags, + double lastHeightUsed, + const std::string& primaryFontFile, + const std::string& bigFontFile + ) + : name(name), + flags(flags), + fixedTextHeight(fixedTextHeight), + widthFactor(widthFactor), + obliqueAngle(obliqueAngle), + textGenerationFlags(textGenerationFlags), + lastHeightUsed(lastHeightUsed), + primaryFontFile(primaryFontFile), + bigFontFile(bigFontFile), + bold(false), + italic(false) + { + } + + bool operator==(const DL_StyleData& other) + { + // ignore lastHeightUsed: + return (name==other.name && + flags==other.flags && + fixedTextHeight==other.fixedTextHeight && + widthFactor==other.widthFactor && + obliqueAngle==other.obliqueAngle && + textGenerationFlags==other.textGenerationFlags && + primaryFontFile==other.primaryFontFile && + bigFontFile==other.bigFontFile); + } + + /** Style name */ + std::string name; + /** Style flags */ + int flags; + /** Fixed text height or 0 for not fixed. */ + double fixedTextHeight; + /** Width factor */ + double widthFactor; + /** Oblique angle */ + double obliqueAngle; + /** Text generation flags */ + int textGenerationFlags; + /** Last height used */ + double lastHeightUsed; + /** Primary font file name */ + std::string primaryFontFile; + /** Big font file name */ + std::string bigFontFile; + + bool bold; + bool italic; +}; + +/** + * Point Data. + */ +struct DXFLIB_EXPORT DL_PointData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_PointData(double px=0.0, double py=0.0, double pz=0.0) + { + x = px; + y = py; + z = pz; + } + + /*! X Coordinate of the point. */ + double x; + /*! Y Coordinate of the point. */ + double y; + /*! Z Coordinate of the point. */ + double z; +}; + + + +/** + * Line Data. + */ +struct DXFLIB_EXPORT DL_LineData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_LineData(double lx1, double ly1, double lz1, + double lx2, double ly2, double lz2) + { + x1 = lx1; + y1 = ly1; + z1 = lz1; + + x2 = lx2; + y2 = ly2; + z2 = lz2; + } + + /*! X Start coordinate of the point. */ + double x1; + /*! Y Start coordinate of the point. */ + double y1; + /*! Z Start coordinate of the point. */ + double z1; + + /*! X End coordinate of the point. */ + double x2; + /*! Y End coordinate of the point. */ + double y2; + /*! Z End coordinate of the point. */ + double z2; +}; + +/** + * XLine Data. + */ +struct DXFLIB_EXPORT DL_XLineData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_XLineData(double bx, double by, double bz, + double dx, double dy, double dz) : + bx(bx), by(by), bz(bz), + dx(dx), dy(dy), dz(dz) + { + } + + /*! X base point. */ + double bx; + /*! Y base point. */ + double by; + /*! Z base point. */ + double bz; + + /*! X direction vector. */ + double dx; + /*! Y direction vector. */ + double dy; + /*! Z direction vector. */ + double dz; +}; + +/** + * Ray Data. + */ +struct DXFLIB_EXPORT DL_RayData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_RayData(double bx, double by, double bz, + double dx, double dy, double dz) : + bx(bx), by(by), bz(bz), + dx(dx), dy(dy), dz(dz) + { + } + + /*! X base point. */ + double bx; + /*! Y base point. */ + double by; + /*! Z base point. */ + double bz; + + /*! X direction vector. */ + double dx; + /*! Y direction vector. */ + double dy; + /*! Z direction vector. */ + double dz; +}; + + + +/** + * Arc Data. + */ +struct DXFLIB_EXPORT DL_ArcData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_ArcData(double acx, double acy, double acz, + double aRadius, + double aAngle1, double aAngle2) + { + + cx = acx; + cy = acy; + cz = acz; + radius = aRadius; + angle1 = aAngle1; + angle2 = aAngle2; + } + + /*! X Coordinate of center point. */ + double cx; + /*! Y Coordinate of center point. */ + double cy; + /*! Z Coordinate of center point. */ + double cz; + + /*! Radius of arc. */ + double radius; + /*! Startangle of arc in degrees. */ + double angle1; + /*! Endangle of arc in degrees. */ + double angle2; +}; + + + +/** + * Circle Data. + */ +struct DXFLIB_EXPORT DL_CircleData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_CircleData(double acx, double acy, double acz, + double aRadius) + { + + cx = acx; + cy = acy; + cz = acz; + radius = aRadius; + } + + /*! X Coordinate of center point. */ + double cx; + /*! Y Coordinate of center point. */ + double cy; + /*! Z Coordinate of center point. */ + double cz; + + /*! Radius of arc. */ + double radius; +}; + + + +/** + * Polyline Data. + */ +struct DXFLIB_EXPORT DL_PolylineData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_PolylineData(int pNumber, int pMVerteces, int pNVerteces, int pFlags) + { + number = pNumber; + m = pMVerteces; + n = pNVerteces; + flags = pFlags; + } + + /*! Number of vertices in this polyline. */ + unsigned int number; + + /*! Number of vertices in m direction if polyline is a polygon mesh. */ + unsigned int m; + + /*! Number of vertices in n direction if polyline is a polygon mesh. */ + unsigned int n; + + /*! Flags */ + int flags; +}; + + + +/** + * Vertex Data. + */ +struct DXFLIB_EXPORT DL_VertexData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_VertexData(double px=0.0, double py=0.0, double pz=0.0, + double pBulge=0.0) + { + x = px; + y = py; + z = pz; + bulge = pBulge; + } + + /*! X Coordinate of the vertex. */ + double x; + /*! Y Coordinate of the vertex. */ + double y; + /*! Z Coordinate of the vertex. */ + double z; + /*! Bulge of vertex. + * (The tangent of 1/4 of the arc angle or 0 for lines) */ + double bulge; +}; + + +/** + * Trace Data / solid data / 3d face data. + */ +struct DXFLIB_EXPORT DL_TraceData +{ + DL_TraceData() + { + thickness = 0.0; + for (int i=0; i<4; i++) + { + x[i] = 0.0; + y[i] = 0.0; + z[i] = 0.0; + } + } + + /** + * Constructor. + * Parameters: see member variables. + */ + DL_TraceData(double sx1, double sy1, double sz1, + double sx2, double sy2, double sz2, + double sx3, double sy3, double sz3, + double sx4, double sy4, double sz4, + double sthickness=0.0) + { + + thickness = sthickness; + + x[0] = sx1; + y[0] = sy1; + z[0] = sz1; + + x[1] = sx2; + y[1] = sy2; + z[1] = sz2; + + x[2] = sx3; + y[2] = sy3; + z[2] = sz3; + + x[3] = sx4; + y[3] = sy4; + z[3] = sz4; + } + + /*! Thickness */ + double thickness; + + /*! Points */ + double x[4]; + double y[4]; + double z[4]; +}; + + + + + +/** + * Solid Data. + */ +typedef DL_TraceData DL_SolidData; + + +/** + * 3dface Data. + */ +typedef DL_TraceData DL_3dFaceData; + + +/** + * Spline Data. + */ +struct DXFLIB_EXPORT DL_SplineData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_SplineData(int degree, + int nKnots, + int nControl, + int nFit, + int flags) : + degree(degree), + nKnots(nKnots), + nControl(nControl), + nFit(nFit), + flags(flags) + { + } + + /*! Degree of the spline curve. */ + unsigned int degree; + + /*! Number of knots. */ + unsigned int nKnots; + + /*! Number of control points. */ + unsigned int nControl; + + /*! Number of fit points. */ + unsigned int nFit; + + /*! Flags */ + int flags; + + double tangentStartX; + double tangentStartY; + double tangentStartZ; + double tangentEndX; + double tangentEndY; + double tangentEndZ; +}; + + + +/** + * Spline knot data. + */ +struct DXFLIB_EXPORT DL_KnotData +{ + DL_KnotData() {} + /** + * Constructor. + * Parameters: see member variables. + */ + DL_KnotData(double pk) + { + k = pk; + } + + /*! Knot value. */ + double k; +}; + + + +/** + * Spline control point data. + */ +struct DXFLIB_EXPORT DL_ControlPointData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_ControlPointData(double px, double py, double pz, double weight) + { + x = px; + y = py; + z = pz; + w = weight; + } + + /*! X coordinate of the control point. */ + double x; + /*! Y coordinate of the control point. */ + double y; + /*! Z coordinate of the control point. */ + double z; + /*! Weight of control point. */ + double w; +}; + + + +/** + * Spline fit point data. + */ +struct DXFLIB_EXPORT DL_FitPointData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_FitPointData(double x, double y, double z) : x(x), y(y), z(z) {} + + /*! X coordinate of the fit point. */ + double x; + /*! Y coordinate of the fit point. */ + double y; + /*! Z coordinate of the fit point. */ + double z; +}; + + + +/** + * Ellipse Data. + */ +struct DXFLIB_EXPORT DL_EllipseData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_EllipseData(double cx, double cy, double cz, + double mx, double my, double mz, + double ratio, + double angle1, double angle2) + : cx(cx), + cy(cy), + cz(cz), + mx(mx), + my(my), + mz(mz), + ratio(ratio), + angle1(angle1), + angle2(angle2) + { + } + + /*! X Coordinate of center point. */ + double cx; + /*! Y Coordinate of center point. */ + double cy; + /*! Z Coordinate of center point. */ + double cz; + + /*! X coordinate of the endpoint of the major axis. */ + double mx; + /*! Y coordinate of the endpoint of the major axis. */ + double my; + /*! Z coordinate of the endpoint of the major axis. */ + double mz; + + /*! Ratio of minor axis to major axis.. */ + double ratio; + /*! Startangle of ellipse in rad. */ + double angle1; + /*! Endangle of ellipse in rad. */ + double angle2; +}; + + + +/** + * Insert Data. + */ +struct DXFLIB_EXPORT DL_InsertData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_InsertData(const std::string& name, + double ipx, double ipy, double ipz, + double sx, double sy, double sz, + double angle, + int cols, int rows, + double colSp, double rowSp) : + name(name), + ipx(ipx), ipy(ipy), ipz(ipz), + sx(sx), sy(sy), sz(sz), + angle(angle), + cols(cols), rows(rows), + colSp(colSp), rowSp(rowSp) + { + } + + /*! Name of the referred block. */ + std::string name; + /*! X Coordinate of insertion point. */ + double ipx; + /*! Y Coordinate of insertion point. */ + double ipy; + /*! Z Coordinate of insertion point. */ + double ipz; + /*! X Scale factor. */ + double sx; + /*! Y Scale factor. */ + double sy; + /*! Z Scale factor. */ + double sz; + /*! Rotation angle in degrees. */ + double angle; + /*! Number of colums if we insert an array of the block or 1. */ + int cols; + /*! Number of rows if we insert an array of the block or 1. */ + int rows; + /*! Values for the spacing between cols. */ + double colSp; + /*! Values for the spacing between rows. */ + double rowSp; +}; + + + +/** + * MText Data. + */ +struct DXFLIB_EXPORT DL_MTextData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_MTextData(double ipx, double ipy, double ipz, + double dirx, double diry, double dirz, + double height, double width, + int attachmentPoint, + int drawingDirection, + int lineSpacingStyle, + double lineSpacingFactor, + const std::string& text, + const std::string& style, + double angle) : + ipx(ipx), ipy(ipy), ipz(ipz), + dirx(dirx), diry(diry), dirz(dirz), + height(height), width(width), + attachmentPoint(attachmentPoint), + drawingDirection(drawingDirection), + lineSpacingStyle(lineSpacingStyle), + lineSpacingFactor(lineSpacingFactor), + text(text), + style(style), + angle(angle) + { + + } + + /*! X Coordinate of insertion point. */ + double ipx; + /*! Y Coordinate of insertion point. */ + double ipy; + /*! Z Coordinate of insertion point. */ + double ipz; + /*! X Coordinate of X direction vector. */ + double dirx; + /*! Y Coordinate of X direction vector. */ + double diry; + /*! Z Coordinate of X direction vector. */ + double dirz; + /*! Text height */ + double height; + /*! Width of the text box. */ + double width; + /** + * Attachment point. + * + * 1 = Top left, 2 = Top center, 3 = Top right, + * 4 = Middle left, 5 = Middle center, 6 = Middle right, + * 7 = Bottom left, 8 = Bottom center, 9 = Bottom right + */ + int attachmentPoint; + /** + * Drawing direction. + * + * 1 = left to right, 3 = top to bottom, 5 = by style + */ + int drawingDirection; + /** + * Line spacing style. + * + * 1 = at least, 2 = exact + */ + int lineSpacingStyle; + /** + * Line spacing factor. 0.25 .. 4.0 + */ + double lineSpacingFactor; + /*! Text string. */ + std::string text; + /*! Style string. */ + std::string style; + /*! Rotation angle. */ + double angle; +}; + + + +/** + * Text Data. + */ +struct DXFLIB_EXPORT DL_TextData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_TextData(double ipx, double ipy, double ipz, + double apx, double apy, double apz, + double height, double xScaleFactor, + int textGenerationFlags, + int hJustification, + int vJustification, + const std::string& text, + const std::string& style, + double angle) + : ipx(ipx), ipy(ipy), ipz(ipz), + apx(apx), apy(apy), apz(apz), + height(height), xScaleFactor(xScaleFactor), + textGenerationFlags(textGenerationFlags), + hJustification(hJustification), + vJustification(vJustification), + text(text), + style(style), + angle(angle) + { + } + + /*! X Coordinate of insertion point. */ + double ipx; + /*! Y Coordinate of insertion point. */ + double ipy; + /*! Z Coordinate of insertion point. */ + double ipz; + + /*! X Coordinate of alignment point. */ + double apx; + /*! Y Coordinate of alignment point. */ + double apy; + /*! Z Coordinate of alignment point. */ + double apz; + + /*! Text height */ + double height; + /*! Relative X scale factor. */ + double xScaleFactor; + /*! 0 = default, 2 = Backwards, 4 = Upside down */ + int textGenerationFlags; + /** + * Horizontal justification. + * + * 0 = Left (default), 1 = Center, 2 = Right, + * 3 = Aligned, 4 = Middle, 5 = Fit + * For 3, 4, 5 the vertical alignment has to be 0. + */ + int hJustification; + /** + * Vertical justification. + * + * 0 = Baseline (default), 1 = Bottom, 2 = Middle, 3= Top + */ + int vJustification; + /*! Text string. */ + std::string text; + /*! Style (font). */ + std::string style; + /*! Rotation angle of dimension text away from default orientation. */ + double angle; +}; + + +/** + * Block attribute data. + */ +struct DXFLIB_EXPORT DL_AttributeData : public DL_TextData +{ + DL_AttributeData(const DL_TextData& tData, const std::string& tag) + : DL_TextData(tData), tag(tag) + { + + } + + /** + * Constructor. + * Parameters: see member variables. + */ + DL_AttributeData(double ipx, double ipy, double ipz, + double apx, double apy, double apz, + double height, double xScaleFactor, + int textGenerationFlags, + int hJustification, + int vJustification, + const std::string& tag, + const std::string& text, + const std::string& style, + double angle) + : DL_TextData(ipx, ipy, ipz, + apx, apy, apz, + height, xScaleFactor, + textGenerationFlags, + hJustification, + vJustification, + text, + style, + angle), + tag(tag) + { + } + + /*! Tag. */ + std::string tag; +}; + + +/** + * Generic Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimensionData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimensionData(double dpx, double dpy, double dpz, + double mpx, double mpy, double mpz, + int type, + int attachmentPoint, + int lineSpacingStyle, + double lineSpacingFactor, + const std::string& text, + const std::string& style, + double angle, + double linearFactor = 1.0) : + dpx(dpx), dpy(dpy), dpz(dpz), + mpx(mpx), mpy(mpy), mpz(mpz), + type(type), + attachmentPoint(attachmentPoint), + lineSpacingStyle(lineSpacingStyle), + lineSpacingFactor(lineSpacingFactor), + text(text), + style(style), + angle(angle), + linearFactor(linearFactor) + { + + } + + /*! X Coordinate of definition point. */ + double dpx; + /*! Y Coordinate of definition point. */ + double dpy; + /*! Z Coordinate of definition point. */ + double dpz; + /*! X Coordinate of middle point of the text. */ + double mpx; + /*! Y Coordinate of middle point of the text. */ + double mpy; + /*! Z Coordinate of middle point of the text. */ + double mpz; + /** + * Dimension type. + * + * 0 Rotated, horizontal, or vertical + * 1 Aligned + * 2 Angular + * 3 Diametric + * 4 Radius + * 5 Angular 3-point + * 6 Ordinate + * 64 Ordinate type. This is a bit value (bit 7) + * used only with integer value 6. If set, + * ordinate is X-type; if not set, ordinate is + * Y-type + * 128 This is a bit value (bit 8) added to the + * other group 70 values if the dimension text + * has been positioned at a user-defined + * location rather than at the default location + */ + int type; + /** + * Attachment point. + * + * 1 = Top left, 2 = Top center, 3 = Top right, + * 4 = Middle left, 5 = Middle center, 6 = Middle right, + * 7 = Bottom left, 8 = Bottom center, 9 = Bottom right, + */ + int attachmentPoint; + /** + * Line spacing style. + * + * 1 = at least, 2 = exact + */ + int lineSpacingStyle; + /** + * Line spacing factor. 0.25 .. 4.0 + */ + double lineSpacingFactor; + /** + * Text string. + * + * Text string entered explicitly by user or null + * or "<>" for the actual measurement or " " (one blank space). + * for supressing the text. + */ + std::string text; + /*! Dimension style (font name). */ + std::string style; + /** + * Rotation angle of dimension text away from + * default orientation. + */ + double angle; + /** + * Linear factor style override. + */ + double linearFactor; +}; + + + +/** + * Aligned Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimAlignedData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimAlignedData(double depx1, double depy1, double depz1, + double depx2, double depy2, double depz2) + { + + epx1 = depx1; + epy1 = depy1; + epz1 = depz1; + + epx2 = depx2; + epy2 = depy2; + epz2 = depz2; + } + + /*! X Coordinate of Extension point 1. */ + double epx1; + /*! Y Coordinate of Extension point 1. */ + double epy1; + /*! Z Coordinate of Extension point 1. */ + double epz1; + + /*! X Coordinate of Extension point 2. */ + double epx2; + /*! Y Coordinate of Extension point 2. */ + double epy2; + /*! Z Coordinate of Extension point 2. */ + double epz2; +}; + + + +/** + * Linear (rotated) Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimLinearData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimLinearData(double ddpx1, double ddpy1, double ddpz1, + double ddpx2, double ddpy2, double ddpz2, + double dAngle, double dOblique) + { + + dpx1 = ddpx1; + dpy1 = ddpy1; + dpz1 = ddpz1; + + dpx2 = ddpx2; + dpy2 = ddpy2; + dpz2 = ddpz2; + + angle = dAngle; + oblique = dOblique; + } + + /*! X Coordinate of Extension point 1. */ + double dpx1; + /*! Y Coordinate of Extension point 1. */ + double dpy1; + /*! Z Coordinate of Extension point 1. */ + double dpz1; + + /*! X Coordinate of Extension point 2. */ + double dpx2; + /*! Y Coordinate of Extension point 2. */ + double dpy2; + /*! Z Coordinate of Extension point 2. */ + double dpz2; + + /*! Rotation angle (angle of dimension line) in degrees. */ + double angle; + /*! Oblique angle in degrees. */ + double oblique; +}; + + + +/** + * Radial Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimRadialData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimRadialData(double ddpx, double ddpy, double ddpz, double dleader) + { + dpx = ddpx; + dpy = ddpy; + dpz = ddpz; + + leader = dleader; + } + + /*! X Coordinate of definition point. */ + double dpx; + /*! Y Coordinate of definition point. */ + double dpy; + /*! Z Coordinate of definition point. */ + double dpz; + + /*! Leader length */ + double leader; +}; + + + +/** + * Diametric Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimDiametricData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimDiametricData(double ddpx, double ddpy, double ddpz, double dleader) + { + dpx = ddpx; + dpy = ddpy; + dpz = ddpz; + + leader = dleader; + } + + /*! X Coordinate of definition point (DXF 15). */ + double dpx; + /*! Y Coordinate of definition point (DXF 25). */ + double dpy; + /*! Z Coordinate of definition point (DXF 35). */ + double dpz; + + /*! Leader length */ + double leader; +}; + + + +/** + * Angular Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimAngularData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimAngularData(double ddpx1, double ddpy1, double ddpz1, + double ddpx2, double ddpy2, double ddpz2, + double ddpx3, double ddpy3, double ddpz3, + double ddpx4, double ddpy4, double ddpz4) + { + + dpx1 = ddpx1; + dpy1 = ddpy1; + dpz1 = ddpz1; + + dpx2 = ddpx2; + dpy2 = ddpy2; + dpz2 = ddpz2; + + dpx3 = ddpx3; + dpy3 = ddpy3; + dpz3 = ddpz3; + + dpx4 = ddpx4; + dpy4 = ddpy4; + dpz4 = ddpz4; + } + + /*! X Coordinate of definition point 1. */ + double dpx1; + /*! Y Coordinate of definition point 1. */ + double dpy1; + /*! Z Coordinate of definition point 1. */ + double dpz1; + + /*! X Coordinate of definition point 2. */ + double dpx2; + /*! Y Coordinate of definition point 2. */ + double dpy2; + /*! Z Coordinate of definition point 2. */ + double dpz2; + + /*! X Coordinate of definition point 3. */ + double dpx3; + /*! Y Coordinate of definition point 3. */ + double dpy3; + /*! Z Coordinate of definition point 3. */ + double dpz3; + + /*! X Coordinate of definition point 4. */ + double dpx4; + /*! Y Coordinate of definition point 4. */ + double dpy4; + /*! Z Coordinate of definition point 4. */ + double dpz4; +}; + + +/** + * Angular Dimension Data (3 points version). + */ +struct DXFLIB_EXPORT DL_DimAngular3PData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimAngular3PData(double ddpx1, double ddpy1, double ddpz1, + double ddpx2, double ddpy2, double ddpz2, + double ddpx3, double ddpy3, double ddpz3) + { + + dpx1 = ddpx1; + dpy1 = ddpy1; + dpz1 = ddpz1; + + dpx2 = ddpx2; + dpy2 = ddpy2; + dpz2 = ddpz2; + + dpx3 = ddpx3; + dpy3 = ddpy3; + dpz3 = ddpz3; + } + + /*! X Coordinate of definition point 1. */ + double dpx1; + /*! Y Coordinate of definition point 1. */ + double dpy1; + /*! Z Coordinate of definition point 1. */ + double dpz1; + + /*! X Coordinate of definition point 2. */ + double dpx2; + /*! Y Coordinate of definition point 2. */ + double dpy2; + /*! Z Coordinate of definition point 2. */ + double dpz2; + + /*! X Coordinate of definition point 3. */ + double dpx3; + /*! Y Coordinate of definition point 3. */ + double dpy3; + /*! Z Coordinate of definition point 3. */ + double dpz3; +}; + + + +/** + * Ordinate Dimension Data. + */ +struct DXFLIB_EXPORT DL_DimOrdinateData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_DimOrdinateData(double ddpx1, double ddpy1, double ddpz1, + double ddpx2, double ddpy2, double ddpz2, + bool dxtype) + { + + dpx1 = ddpx1; + dpy1 = ddpy1; + dpz1 = ddpz1; + + dpx2 = ddpx2; + dpy2 = ddpy2; + dpz2 = ddpz2; + + xtype = dxtype; + } + + /*! X Coordinate of definition point 1. */ + double dpx1; + /*! Y Coordinate of definition point 1. */ + double dpy1; + /*! Z Coordinate of definition point 1. */ + double dpz1; + + /*! X Coordinate of definition point 2. */ + double dpx2; + /*! Y Coordinate of definition point 2. */ + double dpy2; + /*! Z Coordinate of definition point 2. */ + double dpz2; + + /*! True if the dimension indicates the X-value, false for Y-value */ + bool xtype; +}; + + + +/** + * Leader (arrow). + */ +struct DXFLIB_EXPORT DL_LeaderData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_LeaderData(int lArrowHeadFlag, + int lLeaderPathType, + int lLeaderCreationFlag, + int lHooklineDirectionFlag, + int lHooklineFlag, + double lTextAnnotationHeight, + double lTextAnnotationWidth, + int lNumber) + { + + arrowHeadFlag = lArrowHeadFlag; + leaderPathType = lLeaderPathType; + leaderCreationFlag = lLeaderCreationFlag; + hooklineDirectionFlag = lHooklineDirectionFlag; + hooklineFlag = lHooklineFlag; + textAnnotationHeight = lTextAnnotationHeight; + textAnnotationWidth = lTextAnnotationWidth; + number = lNumber; + } + + /*! Arrow head flag (71). */ + int arrowHeadFlag; + /*! Leader path type (72). */ + int leaderPathType; + /*! Leader creation flag (73). */ + int leaderCreationFlag; + /*! Hookline direction flag (74). */ + int hooklineDirectionFlag; + /*! Hookline flag (75) */ + int hooklineFlag; + /*! Text annotation height (40). */ + double textAnnotationHeight; + /*! Text annotation width (41) */ + double textAnnotationWidth; + /*! Number of vertices in leader (76). */ + int number; +}; + + + +/** + * Leader Vertex Data. + */ +struct DXFLIB_EXPORT DL_LeaderVertexData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_LeaderVertexData(double px=0.0, double py=0.0, double pz=0.0) + { + x = px; + y = py; + z = pz; + } + + /*! X Coordinate of the vertex. */ + double x; + /*! Y Coordinate of the vertex. */ + double y; + /*! Z Coordinate of the vertex. */ + double z; +}; + + + +/** + * Hatch data. + */ +struct DXFLIB_EXPORT DL_HatchData +{ + /** + * Default constructor. + */ + DL_HatchData() {} + + /** + * Constructor. + * Parameters: see member variables. + */ + DL_HatchData(int numLoops, + bool solid, + double scale, + double angle, + const std::string& pattern, + double originX = 0.0, + double originY = 0.0) : + numLoops(numLoops), + solid(solid), + scale(scale), + angle(angle), + pattern(pattern), + originX(originX), + originY(originY) + { + + } + + /*! Number of boundary paths (loops). */ + int numLoops; + /*! Solid fill flag (true=solid, false=pattern). */ + bool solid; + /*! Pattern scale or spacing */ + double scale; + /*! Pattern angle in degrees */ + double angle; + /*! Pattern name. */ + std::string pattern; + /*! Pattern origin */ + double originX; + double originY; +}; + + + +/** + * Hatch boundary path (loop) data. + */ +struct DXFLIB_EXPORT DL_HatchLoopData +{ + /** + * Default constructor. + */ + DL_HatchLoopData() {} + /** + * Constructor. + * Parameters: see member variables. + */ + DL_HatchLoopData(int hNumEdges) + { + numEdges = hNumEdges; + } + + /*! Number of edges in this loop. */ + int numEdges; +}; + + + +/** + * Hatch edge data. + */ +struct DXFLIB_EXPORT DL_HatchEdgeData +{ + /** + * Default constructor. + */ + DL_HatchEdgeData() : defined(false), x1(0.0), y1(0.0), x2(0.0), y2(0.0) + { + } + + /** + * Constructor for a line edge. + * Parameters: see member variables. + */ + DL_HatchEdgeData(double x1, double y1, + double x2, double y2) : + defined(true), + type(1), + x1(x1), + y1(y1), + x2(x2), + y2(y2) + { + } + + /** + * Constructor for an arc edge. + * Parameters: see member variables. + */ + DL_HatchEdgeData(double cx, double cy, + double radius, + double angle1, double angle2, + bool ccw) : + defined(true), + type(2), + cx(cx), + cy(cy), + radius(radius), + angle1(angle1), + angle2(angle2), + ccw(ccw) + { + } + + /** + * Constructor for an ellipse arc edge. + * Parameters: see member variables. + */ + DL_HatchEdgeData(double cx, double cy, + double mx, double my, + double ratio, + double angle1, double angle2, + bool ccw) : + defined(true), + type(3), + cx(cx), + cy(cy), + angle1(angle1), + angle2(angle2), + ccw(ccw), + mx(mx), + my(my), + ratio(ratio) + { + } + + /** + * Constructor for a spline edge. + * Parameters: see member variables. + */ + DL_HatchEdgeData(unsigned int degree, + bool rational, + bool periodic, + unsigned int nKnots, + unsigned int nControl, + unsigned int nFit, + const std::vector& knots, + const std::vector >& controlPoints, + const std::vector >& fitPoints, + const std::vector& weights, + double startTangentX, + double startTangentY, + double endTangentX, + double endTangentY) : + defined(true), + type(4), + degree(degree), + rational(rational), + periodic(periodic), + nKnots(nKnots), + nControl(nControl), + nFit(nFit), + controlPoints(controlPoints), + knots(knots), + weights(weights), + fitPoints(fitPoints), + startTangentX(startTangentX), + startTangentY(startTangentY), + endTangentX(endTangentX), + endTangentY(endTangentY) + { + } + + /** + * Set to true if this edge is fully defined. + */ + bool defined; + + /** + * Edge type. 1=line, 2=arc, 3=elliptic arc, 4=spline. + */ + int type; + + // line edges: + + /*! Start point (X). */ + double x1; + /*! Start point (Y). */ + double y1; + /*! End point (X). */ + double x2; + /*! End point (Y). */ + double y2; + + /*! Center point of arc or ellipse arc (X). */ + double cx; + /*! Center point of arc or ellipse arc (Y). */ + double cy; + /*! Arc radius. */ + double radius; + /*! Start angle of arc or ellipse arc. */ + double angle1; + /*! End angle of arc or ellipse arc. */ + double angle2; + /*! Counterclockwise flag for arc or ellipse arc. */ + bool ccw; + + /*! Major axis end point (X). */ + double mx; + /*! Major axis end point (Y). */ + double my; + /*! Axis ratio */ + double ratio; + + + /*! Spline degree */ + unsigned int degree; + bool rational; + bool periodic; + /*! Number of knots. */ + unsigned int nKnots; + /*! Number of control points. */ + unsigned int nControl; + /*! Number of fit points. */ + unsigned int nFit; + + std::vector > controlPoints; + std::vector knots; + std::vector weights; + std::vector > fitPoints; + + double startTangentX; + double startTangentY; + + double endTangentX; + double endTangentY; + + /** Polyline boundary vertices (x y [bulge])*/ + std::vector > vertices; + //bool closed; +}; + + + +/** + * Image Data. + */ +struct DXFLIB_EXPORT DL_ImageData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_ImageData(const std::string& iref, + double iipx, double iipy, double iipz, + double iux, double iuy, double iuz, + double ivx, double ivy, double ivz, + int iwidth, int iheight, + int ibrightness, int icontrast, int ifade) + { + ref = iref; + ipx = iipx; + ipy = iipy; + ipz = iipz; + ux = iux; + uy = iuy; + uz = iuz; + vx = ivx; + vy = ivy; + vz = ivz; + width = iwidth; + height = iheight; + brightness = ibrightness; + contrast = icontrast; + fade = ifade; + } + + /*! Reference to the image file + (unique, used to refer to the image def object). */ + std::string ref; + /*! X Coordinate of insertion point. */ + double ipx; + /*! Y Coordinate of insertion point. */ + double ipy; + /*! Z Coordinate of insertion point. */ + double ipz; + /*! X Coordinate of u vector along bottom of image. */ + double ux; + /*! Y Coordinate of u vector along bottom of image. */ + double uy; + /*! Z Coordinate of u vector along bottom of image. */ + double uz; + /*! X Coordinate of v vector along left side of image. */ + double vx; + /*! Y Coordinate of v vector along left side of image. */ + double vy; + /*! Z Coordinate of v vector along left side of image. */ + double vz; + /*! Width of image in pixel. */ + int width; + /*! Height of image in pixel. */ + int height; + /*! Brightness (0..100, default = 50). */ + int brightness; + /*! Contrast (0..100, default = 50). */ + int contrast; + /*! Fade (0..100, default = 0). */ + int fade; +}; + + + +/** + * Image Definition Data. + */ +struct DXFLIB_EXPORT DL_ImageDefData +{ + /** + * Constructor. + * Parameters: see member variables. + */ + DL_ImageDefData(const std::string& iref, + const std::string& ifile) + { + ref = iref; + file = ifile; + } + + /*! Reference to the image file + (unique, used to refer to the image def object). */ + std::string ref; + + /*! Image file */ + std::string file; +}; + + + +/** + * Dictionary data. + */ +struct DXFLIB_EXPORT DL_DictionaryData +{ + DL_DictionaryData(const std::string& handle) : handle(handle) {} + std::string handle; +}; + + + +/** + * Dictionary entry data. + */ +struct DXFLIB_EXPORT DL_DictionaryEntryData +{ + DL_DictionaryEntryData(const std::string& name, const std::string& handle) : + name(name), handle(handle) {} + + std::string name; + std::string handle; +}; + +#endif + +// EOF diff --git a/src/libs/vdxf/dxflib/dl_exception.h b/src/libs/vdxf/dxflib/dl_exception.h new file mode 100644 index 000000000..fdca72963 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_exception.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** Copyright (C) 2001 Robert J. Campbell Jr. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_EXCEPTION_H +#define DL_EXCEPTION_H + +#include "dl_global.h" + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +/** + * Used for exception handling. + */ +class DXFLIB_EXPORT DL_Exception {} +; + +/** + * Used for exception handling. + */ +class DXFLIB_EXPORT DL_NullStrExc : public DL_Exception {} +; + +/** + * Used for exception handling. + */ +class DXFLIB_EXPORT DL_GroupCodeExc : public DL_Exception +{ + DL_GroupCodeExc(int gc=0) : groupCode(gc) {} + int groupCode; +}; +#endif + diff --git a/src/libs/vdxf/dxflib/dl_extrusion.h b/src/libs/vdxf/dxflib/dl_extrusion.h new file mode 100644 index 000000000..75f6ff197 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_extrusion.h @@ -0,0 +1,154 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_EXTRUSION_H +#define DL_EXTRUSION_H + +#include "dl_global.h" + +#include + + +/** + * Storing and passing around attributes. Attributes + * are the layer name, color, width and line type. + * + * @author Andrew Mustun + */ +class DXFLIB_EXPORT DL_Extrusion +{ + +public: + + /** + * Default constructor. + */ + DL_Extrusion() + { + direction = new double[3]; + setDirection(0.0, 0.0, 1.0); + setElevation(0.0); + } + + + /** + * Destructor. + */ + ~DL_Extrusion() + { + delete[] direction ; + } + + + /** + * Constructor for DXF extrusion. + * + * @param direction Vector of axis along which the entity shall be extruded + * this is also the Z axis of the Entity coordinate system + * @param elevation Distance of the entities XY plane from the origin of the + * world coordinate system + */ + DL_Extrusion(double dx, double dy, double dz, double elevation) + { + direction = new double[3]; + setDirection(dx, dy, dz); + setElevation(elevation); + } + + + + /** + * Sets the direction vector. + */ + void setDirection(double dx, double dy, double dz) + { + direction[0]=dx; + direction[1]=dy; + direction[2]=dz; + } + + + + /** + * @return direction vector. + */ + double* getDirection() const + { + return direction; + } + + + + /** + * @return direction vector. + */ + void getDirection(double dir[]) const + { + dir[0]=direction[0]; + dir[1]=direction[1]; + dir[2]=direction[2]; + } + + + + /** + * Sets the elevation. + */ + void setElevation(double elevation) + { + this->elevation = elevation; + } + + + + /** + * @return Elevation. + */ + double getElevation() const + { + return elevation; + } + + + + /** + * Copies extrusion (deep copies) from another extrusion object. + */ + DL_Extrusion operator = (const DL_Extrusion& extru) + { + setDirection(extru.direction[0], extru.direction[1], extru.direction[2]); + setElevation(extru.elevation); + + return *this; + } + + + +private: + double *direction; + double elevation; +}; + +#endif + diff --git a/src/libs/vdxf/dxflib/dl_global.h b/src/libs/vdxf/dxflib/dl_global.h new file mode 100644 index 000000000..0d52bea7e --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_global.h @@ -0,0 +1,13 @@ +#if defined(DXFLIB_DLL) +# ifdef _WIN32 +# if defined(DXFLIB_LIBRARY) +# define DXFLIB_EXPORT __declspec(dllexport) +# else +# define DXFLIB_EXPORT __declspec(dllimport) +# endif +# else +# define DXFLIB_EXPORT +# endif +#else +# define DXFLIB_EXPORT +#endif diff --git a/src/libs/vdxf/dxflib/dl_writer.h b/src/libs/vdxf/dxflib/dl_writer.h new file mode 100644 index 000000000..ff744ba50 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_writer.h @@ -0,0 +1,729 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** Copyright (C) 2001 Robert J. Campbell Jr. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DL_WRITER_H +#define DL_WRITER_H + +#include "dl_global.h" + +#ifndef _WIN32 +#include +#endif + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include + +#include "dl_attributes.h" +#include "dl_codes.h" + + + +/** + * Defines interface for writing low level DXF constructs to + * a file. Implementation is defined in derived classes that write + * to binary or ASCII files. + * + * Implements functions that write higher level constructs in terms of + * the low level ones. + * + * @todo Add error checking for string/entry length. + */ +class DXFLIB_EXPORT DL_Writer +{ +public: + /** + * @param version DXF version. Defaults to DL_VERSION_2002. + */ + DL_Writer(DL_Codes::version version) : m_handle(0x30) + { + this->version = version; + modelSpaceHandle = 0; + paperSpaceHandle = 0; + paperSpace0Handle = 0; + } + + virtual ~DL_Writer() {} + ; + + /** Generic section for section 'name'. + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  name
+     * 
+ */ + void section(const char* name) const + { + dxfString(0, "SECTION"); + dxfString(2, name); + } + + /** + * Section HEADER + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  HEADER
+     * 
+ */ + void sectionHeader() const + { + section("HEADER"); + } + + /** + * Section TABLES + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  TABLES
+     * 
+ */ + void sectionTables() const + { + section("TABLES"); + } + + /** + * Section BLOCKS + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  BLOCKS
+     * 
+ */ + void sectionBlocks() const + { + section("BLOCKS"); + } + + /** + * Section ENTITIES + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  ENTITIES
+     * 
+ */ + void sectionEntities() const + { + section("ENTITIES"); + } + + /** + * Section CLASSES + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  CLASSES
+     * 
+ */ + void sectionClasses() const + { + section("CLASSES"); + } + + /** + * Section OBJECTS + * + *
+     *   0
+     *  SECTION
+     *   2
+     *  OBJECTS
+     * 
+ */ + void sectionObjects() const + { + section("OBJECTS"); + } + + /** + * End of a section. + * + *
+     *   0
+     *  ENDSEC
+     * 
+ */ + void sectionEnd() const + { + dxfString(0, "ENDSEC"); + } + + /** + * Generic table for table 'name' with 'num' entries: + * + *
+     *   0
+     *  TABLE
+     *   2
+     *  name
+     *  70
+     *   num
+     * 
+ */ + void table(const char* name, int num, int h=0) const + { + dxfString(0, "TABLE"); + dxfString(2, name); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + dxfString(100, "AcDbSymbolTable"); + } + dxfInt(70, num); + } + + /** Table for layers. + * + * @param num Number of layers in total. + * + *
+     *   0
+     *  TABLE
+     *   2
+     *  LAYER
+     *   70
+     *      num
+     * 
+ */ + void tableLayers(int num) const + { + table("LAYER", num, 2); + } + + /** Table for line types. + * + * @param num Number of line types in total. + * + *
+     *   0
+     *  TABLE
+     *   2
+     *  LTYPE
+     *   70
+     *      num
+     * 
+ */ + void tableLinetypes(int num) const + { + //linetypeHandle = 5; + table("LTYPE", num, 5); + } + + /** Table for application id. + * + * @param num Number of registered applications in total. + * + *
+     *   0
+     *  TABLE
+     *   2
+     *  APPID
+     *   70
+     *      num
+     * 
+ */ + void tableAppid(int num) const + { + table("APPID", num, 9); + } + + /** Table for text style. + * + * @param num Number of text styles. + * + *
+     *   0
+     *  TABLE
+     *   2
+     *  STYLE
+     *   70
+     *      num
+     * 
+ */ + void tableStyle(int num) const + { + table("STYLE", num, 3); + } + + /** + * End of a table. + * + *
+     *   0
+     *  ENDTAB
+     * 
+ */ + void tableEnd() const + { + dxfString(0, "ENDTAB"); + } + + /** + * End of the DXF file. + * + *
+     *   0
+     *  EOF
+     * 
+ */ + void dxfEOF() const + { + dxfString(0, "EOF"); + } + + /** + * Comment. + * + *
+     *  999
+     *  text
+     * 
+ */ + void comment(const char* text) const + { + dxfString(999, text); + } + + /** + * Entity. + * + *
+     *   0
+     *  entTypeName
+     * 
+ * + * @return Unique handle or 0. + */ + void entity(const char* entTypeName) const + { + dxfString(0, entTypeName); + if (version>=DL_VERSION_2000) + { + handle(); + } + } + + /** + * Attributes of an entity. + * + *
+     *   8
+     *  layer
+     *  62
+     *  color
+     *  39
+     *  width
+     *   6
+     *  linetype
+     * 
+ */ + void entityAttributes(const DL_Attributes& attrib) const + { + + // layer name: + dxfString(8, attrib.getLayer()); + + // R12 doesn't accept BYLAYER values. The value has to be missing + // in that case. + if (version>=DL_VERSION_2000 || attrib.getColor()!=256) + { + dxfInt(62, attrib.getColor()); + } + if (version>=DL_VERSION_2000 && attrib.getColor24()!=-1) + { + dxfInt(420, attrib.getColor24()); + } + if (version>=DL_VERSION_2000) + { + dxfInt(370, attrib.getWidth()); + } + if (version>=DL_VERSION_2000) + { + dxfReal(48, attrib.getLinetypeScale()); + } + std::string linetype = attrib.getLinetype(); + std::transform(linetype.begin(), linetype.end(), linetype.begin(), ::toupper); + if (version>=DL_VERSION_2000 || linetype=="BYLAYER") + { + dxfString(6, attrib.getLinetype()); + } + } + + /** + * Subclass. + */ + void subClass(const char* sub) const + { + dxfString(100, sub); + } + + /** + * Layer (must be in the TABLES section LAYER). + * + *
+     *   0
+     *  LAYER
+     * 
+ */ + void tableLayerEntry(unsigned long int h=0) const + { + dxfString(0, "LAYER"); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + dxfString(100, "AcDbSymbolTableRecord"); + dxfString(100, "AcDbLayerTableRecord"); + } + } + + /** + * Line type (must be in the TABLES section LTYPE). + * + *
+     *   0
+     *  LTYPE
+     * 
+ */ + void tableLinetypeEntry(unsigned long int h=0) const + { + dxfString(0, "LTYPE"); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + //dxfHex(330, 0x5); + dxfString(100, "AcDbSymbolTableRecord"); + dxfString(100, "AcDbLinetypeTableRecord"); + } + } + + /** + * Appid (must be in the TABLES section APPID). + * + *
+     *   0
+     *  APPID
+     * 
+ */ + void tableAppidEntry(unsigned long int h=0) const + { + dxfString(0, "APPID"); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + //dxfHex(330, 0x9); + dxfString(100, "AcDbSymbolTableRecord"); + dxfString(100, "AcDbRegAppTableRecord"); + } + } + + /** + * Block (must be in the section BLOCKS). + * + *
+     *   0
+     *  BLOCK
+     * 
+ */ + void sectionBlockEntry(unsigned long int h=0) const + { + dxfString(0, "BLOCK"); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + //dxfHex(330, blockHandle); + dxfString(100, "AcDbEntity"); + if (h==0x1C) + { + dxfInt(67, 1); + } + dxfString(8, "0"); // TODO: Layer for block + dxfString(100, "AcDbBlockBegin"); + } + } + + /** + * End of Block (must be in the section BLOCKS). + * + *
+     *   0
+     *  ENDBLK
+     * 
+ */ + void sectionBlockEntryEnd(unsigned long int h=0) const + { + dxfString(0, "ENDBLK"); + if (version>=DL_VERSION_2000) + { + if (h==0) + { + handle(); + } + else + { + dxfHex(5, h); + } + //dxfHex(330, blockHandle); + dxfString(100, "AcDbEntity"); + if (h==0x1D) + { + dxfInt(67, 1); + } + dxfString(8, "0"); // TODO: Layer for block + dxfString(100, "AcDbBlockEnd"); + } + } + + void color(int col=256) const + { + dxfInt(62, col); + } + void linetype(const char *lt) const + { + dxfString(6, lt); + } + void linetypeScale(double scale) const + { + dxfReal(48, scale); + } + void lineWeight(int lw) const + { + dxfInt(370, lw); + } + + void coord(int gc, double x, double y, double z=0) const + { + dxfReal(gc, x); + dxfReal(gc+10, y); + dxfReal(gc+20, z); + } + + void coordTriplet(int gc, const double* value) const + { + if (value) + { + dxfReal(gc, *value++); + dxfReal(gc+10, *value++); + dxfReal(gc+20, *value++); + } + } + + void resetHandle() const + { + m_handle = 1; + } + + /** + * Writes a unique handle and returns it. + */ + unsigned long handle(int gc=5) const + { + // handle has to be hex + dxfHex(gc, m_handle); + return m_handle++; + } + + /** + * @return Next handle that will be written. + */ + unsigned long getNextHandle() const + { + return m_handle; + } + + /** + * Increases handle, so that the handle returned remains available. + */ + unsigned long incHandle() const + { + return m_handle++; + } + + /** + * Sets the handle of the model space. Entities refer to + * this handle. + */ + void setModelSpaceHandle(unsigned long h) + { + modelSpaceHandle = h; + } + + unsigned long getModelSpaceHandle() + { + return modelSpaceHandle; + } + + /** + * Sets the handle of the paper space. Some special blocks refer to + * this handle. + */ + void setPaperSpaceHandle(unsigned long h) + { + paperSpaceHandle = h; + } + + unsigned long getPaperSpaceHandle() + { + return paperSpaceHandle; + } + + /** + * Sets the handle of the paper space 0. Some special blocks refer to + * this handle. + */ + void setPaperSpace0Handle(unsigned long h) + { + paperSpace0Handle = h; + } + + unsigned long getPaperSpace0Handle() + { + return paperSpace0Handle; + } + + /** + * Must be overwritten by the implementing class to write a + * real value to the file. + * + * @param gc Group code. + * @param value The real value. + */ + virtual void dxfReal(int gc, double value) const = 0; + + /** + * Must be overwritten by the implementing class to write an + * int value to the file. + * + * @param gc Group code. + * @param value The int value. + */ + virtual void dxfInt(int gc, int value) const = 0; + + /** + * Can be overwritten by the implementing class to write a + * bool value to the file. + * + * @param gc Group code. + * @param value The bool value. + */ + virtual void dxfBool(int gc, bool value) const + { + dxfInt(gc, (int)value); + } + + /** + * Must be overwritten by the implementing class to write an + * int value (hex) to the file. + * + * @param gc Group code. + * @param value The int value. + */ + virtual void dxfHex(int gc, int value) const = 0; + + /** + * Must be overwritten by the implementing class to write a + * string to the file. + * + * @param gc Group code. + * @param value The string. + */ + virtual void dxfString(int gc, const char* value) const = 0; + + /** + * Must be overwritten by the implementing class to write a + * string to the file. + * + * @param gc Group code. + * @param value The string. + */ + virtual void dxfString(int gc, const std::string& value) const = 0; + +protected: + mutable unsigned long m_handle; + mutable unsigned long modelSpaceHandle; + mutable unsigned long paperSpaceHandle; + mutable unsigned long paperSpace0Handle; + + /** + * DXF version to be created. + */ + DL_Codes::version version; +private: +}; + +#endif diff --git a/src/libs/vdxf/dxflib/dl_writer_ascii.cpp b/src/libs/vdxf/dxflib/dl_writer_ascii.cpp new file mode 100644 index 000000000..319c34f23 --- /dev/null +++ b/src/libs/vdxf/dxflib/dl_writer_ascii.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved. +** Copyright (C) 2001 Robert J. Campbell Jr. +** +** This file is part of the dxflib project. +** +** This file is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** Licensees holding valid dxflib Professional Edition licenses may use +** this file in accordance with the dxflib Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.ribbonsoft.com for further details. +** +** Contact info@ribbonsoft.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include + +#include "dl_writer_ascii.h" +#include "dl_exception.h" + + +/** + * Closes the output file. + */ +void DL_WriterA::close() const +{ + m_ofile.close(); +} + + +/** + * @retval true Opening file has failed. + * @retval false Otherwise. + */ +bool DL_WriterA::openFailed() const +{ + return m_ofile.fail(); +} + + + +/** + * Writes a real (double) variable to the DXF file. + * + * @param gc Group code. + * @param value Double value + */ +void DL_WriterA::dxfReal(int gc, double value) const +{ + char str[256]; + sprintf(str, "%.16lf", value); + + // fix for german locale: + strReplace(str, ',', '.'); + + // Cut away those zeros at the end: + bool dot = false; + int end = -1; + for (unsigned int i=0; i0 && end<(int)strlen(str)) + { + str[end] = '\0'; + } + + dxfString(gc, str); + m_ofile.flush(); +} + + + +/** + * Writes an int variable to the DXF file. + * + * @param gc Group code. + * @param value Int value + */ +void DL_WriterA::dxfInt(int gc, int value) const +{ + m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n" << value << "\n"; +} + + + +/** + * Writes a hex int variable to the DXF file. + * + * @param gc Group code. + * @param value Int value + */ +void DL_WriterA::dxfHex(int gc, int value) const +{ + char str[12]; + sprintf(str, "%0X", value); + dxfString(gc, str); +} + + + +/** + * Writes a string variable to the DXF file. + * + * @param gc Group code. + * @param value String + */ +void DL_WriterA::dxfString(int gc, const char* value) const +{ + if (value==NULL) + { +#ifndef __GCC2x__ + //throw DL_NullStrExc(); +#endif + } + m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n" + << value << "\n"; +} + + + +void DL_WriterA::dxfString(int gc, const std::string& value) const +{ + m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n" + << value << "\n"; +} + + +/** + * Replaces every occurence of src with dest in the null terminated str. + */ +void DL_WriterA::strReplace(char* str, char src, char dest) +{ + size_t i; + for (i=0; i 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "dl_writer.h" +#include +#include + +/** + * Implements functions defined in DL_Writer for writing low + * level DXF constructs to an ASCII format DXF file. + * + * @para fname File name of the file to be created. + * @para version DXF version. Defaults to DL_VERSION_2002. + * + * @todo What if \c fname is NULL? Or \c fname can't be opened for + * another reason? + */ +class DXFLIB_EXPORT DL_WriterA : public DL_Writer +{ +public: + DL_WriterA(const char* fname, DL_Codes::version version=DL_VERSION_2000) + : DL_Writer(version), m_ofile(fname) {} + virtual ~DL_WriterA() {} + + bool openFailed() const; + void close() const; + void dxfReal(int gc, double value) const; + void dxfInt(int gc, int value) const; + void dxfHex(int gc, int value) const; + void dxfString(int gc, const char* value) const; + void dxfString(int gc, const std::string& value) const; + + static void strReplace(char* str, char src, char dest); + +private: + /** + * DXF file to be created. + */ + mutable std::ofstream m_ofile; + +}; + +#endif + diff --git a/src/libs/vdxf/stable.cpp b/src/libs/vdxf/stable.cpp new file mode 100644 index 000000000..84741ef26 --- /dev/null +++ b/src/libs/vdxf/stable.cpp @@ -0,0 +1,30 @@ +/************************************************************************ + ** + ** @file stable.cpp + ** @author Valentina Zhuravska + ** @date 12 8, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +// Build the precompiled headers. +#include "stable.h" diff --git a/src/libs/vdxf/stable.h b/src/libs/vdxf/stable.h new file mode 100644 index 000000000..191182a90 --- /dev/null +++ b/src/libs/vdxf/stable.h @@ -0,0 +1,52 @@ +/************************************************************************ + ** + ** @file stable.h + ** @author Valentina Zhuravska + ** @date 12 8, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef STABLE_H +#define STABLE_H + +/* I like to include this pragma too, so the build log indicates if pre-compiled headers were in use. */ +#ifndef __clang__ +#pragma message("Compiling precompiled headers for VDxf library.\n") +#endif + +/* Add C includes here */ + +#if defined __cplusplus +/* Add C++ includes here */ + +#ifdef QT_CORE_LIB +#include +#endif + +#ifdef QT_GUI_LIB +# include +#endif + +#endif/*__cplusplus*/ + +#endif // STABLE_H diff --git a/src/libs/vdxf/vdxf.pri b/src/libs/vdxf/vdxf.pri new file mode 100644 index 000000000..95340e6e4 --- /dev/null +++ b/src/libs/vdxf/vdxf.pri @@ -0,0 +1,21 @@ +# ADD TO EACH PATH $$PWD VARIABLE!!!!!! +# This need for corect working file translations.pro + +SOURCES += \ + $$PWD/stable.cpp \ + $$PWD/dxflib/dl_dxf.cpp \ + $$PWD/dxflib/dl_writer_ascii.cpp + +HEADERS += \ + $$PWD/stable.h \ + $$PWD/dxflib/dl_attributes.h \ + $$PWD/dxflib/dl_codes.h \ + $$PWD/dxflib/dl_creationadapter.h \ + $$PWD/dxflib/dl_creationinterface.h \ + $$PWD/dxflib/dl_dxf.h \ + $$PWD/dxflib/dl_entities.h \ + $$PWD/dxflib/dl_exception.h \ + $$PWD/dxflib/dl_extrusion.h \ + $$PWD/dxflib/dl_global.h \ + $$PWD/dxflib/dl_writer.h \ + $$PWD/dxflib/dl_writer_ascii.h diff --git a/src/libs/vdxf/vdxf.pro b/src/libs/vdxf/vdxf.pro new file mode 100644 index 000000000..b709d15d5 --- /dev/null +++ b/src/libs/vdxf/vdxf.pro @@ -0,0 +1,96 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-12-12T14:55:06 +# +#------------------------------------------------- + +# File with common stuff for whole project +include(../../../common.pri) + +# Name of library +TARGET = vdxf + +# We want create a library +TEMPLATE = lib + +CONFIG += \ + staticlib \# Making static library + c++11 # We use C++11 standard + +# Use out-of-source builds (shadow builds) +CONFIG -= debug_and_release debug_and_release_target + +# Since Qt 5.4.0 the source code location is recorded only in debug builds. +# We need this information also in release builds. For this need define QT_MESSAGELOGCONTEXT. +DEFINES += QT_MESSAGELOGCONTEXT + +include(vdxf.pri) + +# This is static library so no need in "make install" + +# directory for executable file +DESTDIR = bin + +# files created moc +MOC_DIR = moc + +# objecs files +OBJECTS_DIR = obj + +# Set using ccache. Function enable_ccache() defined in common.pri. +$$enable_ccache() + +# Set precompiled headers. Function set_PCH() defined in common.pri. +$$set_PCH() + +CONFIG(debug, debug|release){ + # Debug mode + unix { + #Turn on compilers warnings. + *-g++{ + QMAKE_CXXFLAGS += \ + # Key -isystem disable checking errors in system headers. + -isystem "$${OUT_PWD}/$${MOC_DIR}" \ + $$GCC_DEBUG_CXXFLAGS # See common.pri for more details. + + noAddressSanitizer{ # For enable run qmake with CONFIG+=noAddressSanitizer + # do nothing + } else { + #gcc’s 4.8.0 Address Sanitizer + #http://blog.qt.digia.com/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt/ + QMAKE_CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer + QMAKE_CFLAGS += -fsanitize=address -fno-omit-frame-pointer + QMAKE_LFLAGS += -fsanitize=address + } + } + clang*{ + QMAKE_CXXFLAGS += \ + # Key -isystem disable checking errors in system headers. + -isystem "$${OUT_PWD}/$${MOC_DIR}" \ + $$CLANG_DEBUG_CXXFLAGS # See common.pri for more details. + } + } else { + *-g++{ + QMAKE_CXXFLAGS += $$GCC_DEBUG_CXXFLAGS # See common.pri for more details. + } + } + +}else{ + # Release mode + + !unix:*-g++{ + QMAKE_CXXFLAGS += -fno-omit-frame-pointer # Need for exchndl.dll + } + + noDebugSymbols{ # For enable run qmake with CONFIG+=noDebugSymbols + # do nothing + } else { + !macx:!win32-msvc*{ + # Turn on debug symbols in release mode on Unix systems. + # On Mac OS X temporarily disabled. TODO: find way how to strip binary file. + QMAKE_CXXFLAGS_RELEASE += -g -gdwarf-3 + QMAKE_CFLAGS_RELEASE += -g -gdwarf-3 + QMAKE_LFLAGS_RELEASE = + } + } +} From 80b0f38f0d80392ca3a61b723337ffd5fd328228 Mon Sep 17 00:00:00 2001 From: val177 Date: Mon, 7 Sep 2015 22:47:02 +0300 Subject: [PATCH 3/3] Added dxf export --HG-- branch : feature --- .../valentina/dialogs/dialogsavelayout.cpp | 1 + src/app/valentina/mainwindowsnogui.cpp | 23 +- src/app/valentina/mainwindowsnogui.h | 1 + src/libs/vdxf/dxfdef.h | 37 ++ src/libs/vdxf/vdxf.pri | 9 +- src/libs/vdxf/vdxfengine.cpp | 467 ++++++++++++++++++ src/libs/vdxf/vdxfengine.h | 87 ++++ src/libs/vdxf/vdxfpaintdevice.cpp | 146 ++++++ src/libs/vdxf/vdxfpaintdevice.h | 65 +++ 9 files changed, 833 insertions(+), 3 deletions(-) create mode 100644 src/libs/vdxf/dxfdef.h create mode 100644 src/libs/vdxf/vdxfengine.cpp create mode 100644 src/libs/vdxf/vdxfengine.h create mode 100644 src/libs/vdxf/vdxfpaintdevice.cpp create mode 100644 src/libs/vdxf/vdxfpaintdevice.h diff --git a/src/app/valentina/dialogs/dialogsavelayout.cpp b/src/app/valentina/dialogs/dialogsavelayout.cpp index 2a67a2463..db1522b94 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.cpp +++ b/src/app/valentina/dialogs/dialogsavelayout.cpp @@ -50,6 +50,7 @@ const std::vector DialogSaveLayout::availFormats = { VFrmWithTest(tr("Wavefront OBJ (*.obj)"), ".obj"), VFrmWithTest(tr("PS files (*.ps)"), ".ps", 1), //fixme: use 1 to have exe once tested on 1st run, or any other value to test always as original do VFrmWithTest(tr("EPS files (*.eps)"), ".eps", 1), + VFrmWithTest(tr("DXF files (*.dxf)"), ".dxf"), }; diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 4ebb7bcca..7c30007ce 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -30,6 +30,7 @@ #include "core/vapplication.h" #include "../vpatterndb/vcontainer.h" #include "../vobj/vobjpaintdevice.h" +#include "../vdxf/vdxfpaintdevice.h" #include "dialogs/dialoglayoutsettings.h" #include "../vlayout/vlayoutgenerator.h" @@ -209,7 +210,7 @@ void MainWindowsNoGUI::ExportLayout(const DialogSaveLayout &dialog) scenes[i]->setBackgroundBrush( *brush ); shadows[i]->setVisible(false); paper->setPen(QPen(QBrush(Qt::white, Qt::NoBrush), 0.1, Qt::NoPen)); - const QStringList suffix = QStringList() << "svg" << "png" << "pdf" << "eps" << "ps" << "obj"; + const QStringList suffix = QStringList() << "svg" << "png" << "pdf" << "eps" << "ps" << "obj" << "dxf"; switch (suffix.indexOf(suf)) { case 0: //svg @@ -234,6 +235,9 @@ void MainWindowsNoGUI::ExportLayout(const DialogSaveLayout &dialog) ObjFile(name, i); paper->setVisible(true); break; + case 6: //dxf + DxfFile(name, i); + break; default: qDebug() << "Can't recognize file suffix." << Q_FUNC_INFO; break; @@ -675,6 +679,23 @@ void MainWindowsNoGUI::ObjFile(const QString &name, int i) const } } +//--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::DxfFile(const QString &name, int i) const +{ + QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(i)); + if (paper) + { + VDxfPaintDevice generator; + generator.setFileName(name); + generator.setSize(paper->rect().size().toSize()); + generator.setResolution(static_cast(PrintDPI)); + QPainter painter; + painter.begin(&generator); + scenes.at(i)->render(&painter, paper->rect(), paper->rect(), Qt::IgnoreAspectRatio); + painter.end(); + } +} + //--------------------------------------------------------------------------------------------------------------------- QVector MainWindowsNoGUI::AllSheets() { diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index d555154a2..0a96d6563 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -112,6 +112,7 @@ private: void PsFile(const QString &name, int i)const; void PdfToPs(const QStringList ¶ms)const; void ObjFile(const QString &name, int i)const; + void DxfFile(const QString &name, int i)const; QVector AllSheets(); diff --git a/src/libs/vdxf/dxfdef.h b/src/libs/vdxf/dxfdef.h new file mode 100644 index 000000000..b92073651 --- /dev/null +++ b/src/libs/vdxf/dxfdef.h @@ -0,0 +1,37 @@ +/************************************************************************ + ** + ** @file def.h + ** @author Roman Telezhynskyi + ** @date 31 8, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef DXFDEF_H +#define DXFDEF_H + +enum class VarMeasurement : unsigned char { English=0, Metric=1 }; + +//Default drawing units for AutoCAD DesignCenter blocks: +enum class VarInsunits : unsigned char { Inches=1, Millimeters=4, Centimeters=5 }; + +#endif // DXFDEF_H diff --git a/src/libs/vdxf/vdxf.pri b/src/libs/vdxf/vdxf.pri index 95340e6e4..a92d4303a 100644 --- a/src/libs/vdxf/vdxf.pri +++ b/src/libs/vdxf/vdxf.pri @@ -4,7 +4,9 @@ SOURCES += \ $$PWD/stable.cpp \ $$PWD/dxflib/dl_dxf.cpp \ - $$PWD/dxflib/dl_writer_ascii.cpp + $$PWD/dxflib/dl_writer_ascii.cpp \ + $$PWD/vdxfengine.cpp \ + $$PWD/vdxfpaintdevice.cpp HEADERS += \ $$PWD/stable.h \ @@ -18,4 +20,7 @@ HEADERS += \ $$PWD/dxflib/dl_extrusion.h \ $$PWD/dxflib/dl_global.h \ $$PWD/dxflib/dl_writer.h \ - $$PWD/dxflib/dl_writer_ascii.h + $$PWD/dxflib/dl_writer_ascii.h \ + $$PWD/vdxfengine.h \ + $$PWD/vdxfpaintdevice.h \ + $$PWD/dxfdef.h diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp new file mode 100644 index 000000000..23624c555 --- /dev/null +++ b/src/libs/vdxf/vdxfengine.cpp @@ -0,0 +1,467 @@ +/************************************************************************ + ** + ** @file vdxfengine.cpp + ** @author Valentina Zhuravska + ** @date 12 8, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vdxfengine.h" +#include +#include +#include + +//--------------------------------------------------------------------------------------------------------------------- +static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures() +{ +#ifdef Q_CC_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + + return QPaintEngine::PaintEngineFeatures( + QPaintEngine::AllFeatures + & ~QPaintEngine::PatternBrush + & ~QPaintEngine::PerspectiveTransform + & ~QPaintEngine::ConicalGradientFill + & ~QPaintEngine::PorterDuff); + +#ifdef Q_CC_CLANG +#pragma clang diagnostic pop +#endif +} + +//--------------------------------------------------------------------------------------------------------------------- +VDxfEngine::VDxfEngine() + :QPaintEngine(svgEngineFeatures()), + size(), resolution(PrintDPI), matrix(), varMeasurement(VarMeasurement::Metric), + varInsunits(VarInsunits::Centimeters) +{ +} + + //--------------------------------------------------------------------------------------------------------------------- +VDxfEngine::~VDxfEngine() +{ +} + + //--------------------------------------------------------------------------------------------------------------------- +bool VDxfEngine::begin(QPaintDevice *pdev) +{ + Q_UNUSED(pdev) + if (size.isValid() == false) + { + qWarning()<<"VDxfEngine::begin(), size is not valid"; + return false; + } + + dxf = new DL_Dxf(); + DL_Codes::version exportVersion = DL_Codes::AC1015; + QByteArray fileNameArray = getFileName().toLocal8Bit(); + dw = dxf->out(fileNameArray.data(), exportVersion); + + if (dw==NULL) + { + qWarning("VDxfEngine::begin(), can't open file"); + return false; + } + + dxf->writeHeader(*dw); + + dxf->writeComment(*dw, "Valentina DXF File"); + + dw->dxfString(9, "$ANGDIR"); // 1 = Clockwise angles, 0 = Counterclockwise + dw->dxfInt(70, 0); // Qt use counterclockwise + + dw->dxfString(9, "$MEASUREMENT"); // Sets drawing units: 0 = English; 1 = Metric + dw->dxfInt(70, static_cast(varMeasurement)); + + dw->dxfString(9, "$INSUNITS"); + dw->dxfInt(70, static_cast(varInsunits)); + + QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz"); + dateTime.chop(1);// we need hundredths of a second + dw->dxfString(9, "$TDCREATE"); + dw->dxfString(40, dateTime.toUtf8().constData()); + + dw->sectionEnd(); + + dw->sectionTables(); + dxf->writeVPort(*dw); + dw->tableEnd(); + int numberOfLayers = 1; + dw->tableLayers(numberOfLayers); + + dxf->writeLayer(*dw, + DL_LayerData("0", 0), + DL_Attributes( + std::string(""), // leave empty + DL_Codes::black, // default color + 100, // default width + "CONTINUOUS", // default line style + 1.0)); // default line type scale + dw->tableEnd(); + dw->sectionEnd(); + + dw->sectionEntities(); + return true; +} + + //--------------------------------------------------------------------------------------------------------------------- +bool VDxfEngine::end() +{ + dw->sectionEnd(); + dw->dxfEOF(); + dw->close(); + delete dw; + delete dxf; + return true; +} + + //--------------------------------------------------------------------------------------------------------------------- + // cppcheck-suppress unusedFunction +void VDxfEngine::updateState(const QPaintEngineState &state) +{ + QPaintEngine::DirtyFlags flags = state.state(); + + // always stream full gstate, which is not required, but... + flags |= QPaintEngine::AllDirty; + + + if (flags & QPaintEngine::DirtyTransform) + { + matrix = state.matrix(); // Save new matrix for moving paths + } +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawPath(const QPainterPath &path) +{ + QPolygonF polygon = path.toFillPolygon(matrix); + if (polygon.size() < 3) + { + return; + } + + for (int i=1; i < polygon.count(); i++) + { + dxf->writeLine( + *dw, + DL_LineData(polygon.at(i-1).x(), // start point + getSize().height() - polygon.at(i-1).y(), + 0.0, + polygon.at(i).x(), // end point + getSize().height() - polygon.at(i).y(), + 0.0), + DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawLines(const QLineF * lines, int lineCount) +{ + for (int i = 0; i < lineCount; i++) + { + QPointF p1 = matrix.map(lines[i].p1()); + QPointF p2 = matrix.map(lines[i].p2()); + + dxf->writeLine( + *dw, + DL_LineData(p1.x(), // start point + getSize().height() - p1.y(), + 0.0, + p2.x(), // end point + getSize().height() - p2.y(), + 0.0), + DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawLines(const QLine * lines, int lineCount) +{ + QPaintEngine::drawLines(lines, lineCount); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) +{ + Q_UNUSED(mode) + + for (int i = 1; i < pointCount; i++) + { + QPointF p1 = matrix.map(points[i-1]); + QPointF p2 = matrix.map(points[i]); + + dxf->writeLine( + *dw, + DL_LineData(p1.x(), // start point + getSize().height() - p1.y(), + 0.0, + p2.x(), // end point + getSize().height() - p2.y(), + 0.0), + DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawPolygon(const QPoint *points, int pointCount, QPaintEngine::PolygonDrawMode mode) +{ + QPaintEngine::drawPolygon(points, pointCount, mode); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawEllipse(const QRectF & rect) +{ + QRectF newRect = matrix.mapRect(rect); + double rotationAngle = atan(matrix.m12()/matrix.m11()); + + double majorX, majorY; // distanse between center and endpoint of the major axis + double ratio; // ratio of minor axis to major axis + if(rect.width()<= rect.height()) + { + majorX = (rect.top() - rect.center().y())*sin(rotationAngle)*matrix.m11()/cos(rotationAngle); + // major axis * sin(rotation angle) * x-scale-factor + majorY = (rect.top() - rect.center().y())*matrix.m22(); + // major axis * cos(rotation angle) * y-scale-factor, where y-scale-factor = matrix.m22()/cos(rotationAngle) + ratio = rect.width()/rect.height(); + } + else + { + majorX = (rect.right() - rect.center().x())*matrix.m11(); + // major axis * cos(rotation angle) * x-scale-factor, where y-scale-factor = matrix.m22()/cos(rotationAngle) + majorY = (rect.right() - rect.center().x())*sin(rotationAngle)*matrix.m22()/cos(rotationAngle); + // major axis * sin(rotation angle) * y-scale-factor + ratio = rect.height()/rect.width(); + } + dxf->writeEllipse( + *dw, + DL_EllipseData(newRect.center().x(), // center X + getSize().height() - newRect.center().y(), // center Y + 0, // center Z + majorX, + majorY, + 0, + ratio, + 0,6.28 // startangle and endangle of ellipse in rad + ), + DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawEllipse(const QRect & rect) +{ + QPaintEngine::drawEllipse(rect); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::drawTextItem(const QPointF & p, const QTextItem & textItem) +{ + QPointF startPoint = matrix.map(p); + double rotationAngle = atan(matrix.m12()/matrix.m11()); + + int textSize = textItem.font().pixelSize() == -1 ? textItem.font().pointSize() : textItem.font().pixelSize(); + dxf->writeText( + *dw, + DL_TextData(startPoint.x(), + getSize().height() - startPoint.y(), + 0, + startPoint.x(), + getSize().height() - startPoint.y(), + 0, + textSize * matrix.m11(), + 1, // relative X scale factor + 0, // flag (0 = default, 2 = Backwards, 4 = Upside down) + 0, // Horizontal justification (0 = Left (default), 1 = Center, 2 = Right,) + 0, // Vertical justification (0 = Baseline (default), 1 = Bottom, 2 = Middle, 3= Top) + textItem.text().toUtf8().constData(), // text data + textItem.font().family().toUtf8().constData(), // font + -rotationAngle + ), + DL_Attributes("0", getPenColor(), state->pen().width(), getPenStyle(), 1.0)); +} + + //--------------------------------------------------------------------------------------------------------------------- +QPaintEngine::Type VDxfEngine::type() const +{ + return QPaintEngine::User; +} + + //--------------------------------------------------------------------------------------------------------------------- + // cppcheck-suppress unusedFunction +void VDxfEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) +{ + Q_UNUSED(r) + Q_UNUSED(pm) + Q_UNUSED(sr) +} + + //--------------------------------------------------------------------------------------------------------------------- +QSize VDxfEngine::getSize() const +{ + return size; +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::setSize(const QSize &value) +{ + Q_ASSERT(!isActive()); + size = value; +} + + //--------------------------------------------------------------------------------------------------------------------- +int VDxfEngine::getResolution() const +{ + return resolution; +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::setResolution(int value) +{ + Q_ASSERT(!isActive()); + resolution = value; +} + + //--------------------------------------------------------------------------------------------------------------------- +QString VDxfEngine::getFileName() const +{ + return fileName; +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::setFileName(const QString &value) +{ + Q_ASSERT(!isActive()); + fileName = value; +} + +//--------------------------------------------------------------------------------------------------------------------- +std::string VDxfEngine::getPenStyle() +{ + switch (state->pen().style()) + { + case Qt::SolidLine: + return "BYLAYER"; + break; + case Qt::DashLine: + return "DASHED"; + break; + case Qt::DotLine: + return "DOT"; + break; + case Qt::DashDotLine: + return "DASHDOT"; + break; + case Qt::DashDotDotLine: + return "DIVIDE"; + break; + default: + return "BYLAYER"; + break; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +int VDxfEngine::getPenColor() +{ + QColor color = state->pen().color(); + + if(color == Qt::black) + { + return DL_Codes::black; + } + else if(color == Qt::white) + { + return DL_Codes::white; + } + else if(color == Qt::darkGray) + { + return DL_Codes::gray; + } + else if(color == Qt::gray) + { + return DL_Codes::l_gray; + } + else if(color == Qt::darkMagenta) + { + return DL_Codes::magenta; + } + else if(color == Qt::magenta) + { + return DL_Codes::l_magenta; + } + else if(color == Qt::cyan) + { + return DL_Codes::l_cyan; + } + else if(color == Qt::darkCyan) + { + return DL_Codes::cyan; + } + else if(color == Qt::blue) + { + return DL_Codes::l_blue; + } + else if(color == Qt::darkBlue) + { + return DL_Codes::blue; + } + else if(color == Qt::darkGreen) + { + return DL_Codes::green; + } + else if(color == Qt::green) + { + return DL_Codes::l_green; + } + else if(color == Qt::darkRed) + { + return DL_Codes::red; + } + else if(color == Qt::red) + { + return DL_Codes::l_red; + } + else if(color == Qt::yellow) + { + return DL_Codes::yellow; + } + else + { + return DL_Codes::bylayer; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::setMeasurement(const VarMeasurement &var) +{ + Q_ASSERT(!isActive()); + varMeasurement = var; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::setInsunits(const VarInsunits &var) +{ + Q_ASSERT(!isActive()); + varInsunits = var; +} diff --git a/src/libs/vdxf/vdxfengine.h b/src/libs/vdxf/vdxfengine.h new file mode 100644 index 000000000..217fb044d --- /dev/null +++ b/src/libs/vdxf/vdxfengine.h @@ -0,0 +1,87 @@ +/************************************************************************ + ** + ** @file vdxfengine.h + ** @author Valentina Zhuravska + ** @date 12 8, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VDXFENGINE_H +#define VDXFENGINE_H + +#include +#include "dxflib/dl_dxf.h" +#include "../vmisc/def.h" +#include "dxfdef.h" + +class QTextStream; + +class VDxfEngine : public QPaintEngine +{ +public: + VDxfEngine(); + virtual ~VDxfEngine() Q_DECL_OVERRIDE; + + virtual bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE; + virtual bool end() Q_DECL_OVERRIDE; + virtual void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE; + virtual void drawPath(const QPainterPath &path) Q_DECL_OVERRIDE; + virtual void drawLines(const QLineF * lines, int lineCount) Q_DECL_OVERRIDE; + virtual void drawLines(const QLine * lines, int lineCount) Q_DECL_OVERRIDE; + virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE; + virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE; + virtual void drawEllipse(const QRectF & rect) Q_DECL_OVERRIDE; + virtual void drawEllipse(const QRect & rect) Q_DECL_OVERRIDE; + virtual void drawTextItem(const QPointF & p, const QTextItem & textItem) Q_DECL_OVERRIDE; + virtual Type type() const Q_DECL_OVERRIDE; + virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE; + + QSize getSize() const; + void setSize(const QSize &value); + + int getResolution() const; + void setResolution(int value); + + QString getFileName() const; + void setFileName(const QString &value); + + std::string getPenStyle(); + int getPenColor(); + + void setMeasurement(const VarMeasurement &var); + void setInsunits(const VarInsunits &var); + +private: + Q_DISABLE_COPY(VDxfEngine) + QSize size; + int resolution; + QString fileName; + QMatrix matrix; + DL_Dxf* dxf; + DL_WriterA* dw; + VarMeasurement varMeasurement; + VarInsunits varInsunits; + +}; + +#endif // VDXFENGINE_H diff --git a/src/libs/vdxf/vdxfpaintdevice.cpp b/src/libs/vdxf/vdxfpaintdevice.cpp new file mode 100644 index 000000000..c9a583451 --- /dev/null +++ b/src/libs/vdxf/vdxfpaintdevice.cpp @@ -0,0 +1,146 @@ +/************************************************************************ + ** + ** @file vdxfpaintdevice.cpp + ** @author Valentina Zhuravska + ** @date 12 812, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vdxfpaintdevice.h" +#include "vdxfengine.h" + +#include + + //--------------------------------------------------------------------------------------------------------------------- +VDxfPaintDevice::VDxfPaintDevice() + :QPaintDevice(), engine(new VDxfEngine()), fileName() +{ +} + + //--------------------------------------------------------------------------------------------------------------------- +VDxfPaintDevice::~VDxfPaintDevice() +{ + delete engine; +} + + //--------------------------------------------------------------------------------------------------------------------- + // cppcheck-suppress unusedFunction +QPaintEngine *VDxfPaintDevice::paintEngine() const +{ + return engine; +} + + //--------------------------------------------------------------------------------------------------------------------- + // cppcheck-suppress unusedFunction +QString VDxfPaintDevice::getFileName() const +{ + return fileName; +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::setFileName(const QString &value) +{ + if (engine->isActive()) + { + qWarning("VDxfPaintDevice::setFileName(), cannot set file name while Dxf is being generated"); + return; + } + + fileName = value; + engine->setFileName(fileName); +} + + //--------------------------------------------------------------------------------------------------------------------- +QSize VDxfPaintDevice::getSize() +{ + return engine->getSize(); +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::setSize(const QSize &size) +{ + if (engine->isActive()) + { + qWarning("VDxfPaintDevice::setSize(), cannot set size while Dxf is being generated"); + return; + } + engine->setSize(size); +} + + //--------------------------------------------------------------------------------------------------------------------- +int VDxfPaintDevice::getResolution() const +{ + return engine->getResolution(); +} + + //--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::setResolution(int dpi) +{ + engine->setResolution(dpi); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::setMeasurement(const VarMeasurement &var) +{ + engine->setMeasurement(var); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::setInsunits(const VarInsunits &var) +{ + engine->setInsunits(var); +} + + //--------------------------------------------------------------------------------------------------------------------- +int VDxfPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const +{ + switch (metric) + { + case QPaintDevice::PdmDepth: + return 32; + case QPaintDevice::PdmWidth: + return engine->getSize().width(); + case QPaintDevice::PdmHeight: + return engine->getSize().height(); + case QPaintDevice::PdmDpiX: + return engine->getResolution(); + case QPaintDevice::PdmDpiY: + return engine->getResolution(); + case QPaintDevice::PdmHeightMM: + return qRound(engine->getSize().height() * 25.4 / engine->getResolution()); + case QPaintDevice::PdmWidthMM: + return qRound(engine->getSize().width() * 25.4 / engine->getResolution()); + case QPaintDevice::PdmNumColors: + return static_cast(0xffffffff); + case QPaintDevice::PdmPhysicalDpiX: + return engine->getResolution(); + case QPaintDevice::PdmPhysicalDpiY: + return engine->getResolution(); + case QPaintDevice::PdmDevicePixelRatio: + return 1; + default: + qWarning("VDxfPaintDevice::metric(), unhandled metric %d\n", metric); + break; + } + return 0; +} diff --git a/src/libs/vdxf/vdxfpaintdevice.h b/src/libs/vdxf/vdxfpaintdevice.h new file mode 100644 index 000000000..a69a35541 --- /dev/null +++ b/src/libs/vdxf/vdxfpaintdevice.h @@ -0,0 +1,65 @@ +/************************************************************************ + ** + ** @file vdxfpaintdevice.h + ** @author Valentina Zhuravska + ** @date 12 812, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VDXFPAINTDEVICE_H +#define VDXFPAINTDEVICE_H + +#include +#include +#include "dxfdef.h" + +class VDxfEngine; + +class VDxfPaintDevice : public QPaintDevice +{ +public: + VDxfPaintDevice(); + virtual ~VDxfPaintDevice() Q_DECL_OVERRIDE; + virtual QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; + + QString getFileName() const; + void setFileName(const QString &value); + + QSize getSize(); + void setSize(const QSize &size); + + int getResolution() const; + void setResolution(int dpi); + + void setMeasurement(const VarMeasurement &var); + void setInsunits(const VarInsunits &var); + +protected: + virtual int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE; +private: + Q_DISABLE_COPY(VDxfPaintDevice) + VDxfEngine *engine; + QString fileName; +}; + +#endif // VDXFPAINTDEVICE_H