+++ /dev/null
-// filterdxf.cpp
-//
-// Part of the Architektonas Project
-// Originally part of QCad Community Edition by Andrew Mustun
-// Extensively rewritten and refactored by James L. Hammons
-// Portions copyright (C) 2001-2003 RibbonSoft
-// Copyright (C) 2010 Underground Software
-// See the README and GPLv2 files for licensing and warranty information
-//
-// JLH = James L. Hammons <jlhamm@acm.org>
-//
-// Who When What
-// --- ---------- -----------------------------------------------------------
-// JLH 05/28/2010 Added this text. :-)
-//
-
-#include "filterdxf.h"
-
-#include <stdio.h>
-#include <QtCore>
-#include "dl_attributes.h"
-#include "dl_codes.h"
-#include "dl_writer_ascii.h"
-#include "dimaligned.h"
-#include "dimangular.h"
-#include "dimdiametric.h"
-#include "dimlinear.h"
-#include "dimradial.h"
-#include "hatch.h"
-#include "image.h"
-#include "leader.h"
-#include "system.h"
-
-/**
- * Default constructor.
- *
- */
-FilterDXF::FilterDXF(): FilterInterface()
-{
- DEBUG->print("FilterDXF::FilterDXF()");
-
- addImportFormat(RS2::FormatDXF);
- addExportFormat(RS2::FormatDXF);
- addExportFormat(RS2::FormatDXF12);
-
- mtext = "";
- polyline = NULL;
- leader = NULL;
- hatch = NULL;
- hatchLoop = NULL;
- currentContainer = NULL;
- graphic = NULL;
- //exportVersion = DL_Codes::VER_2002;
- //systemVariables.setAutoDelete(true);
- DEBUG->print("FilterDXF::FilterDXF(): OK");
-}
-
-/**
- * Destructor.
- */
-FilterDXF::~FilterDXF()
-{
- DEBUG->print("FilterDXF::~FilterDXF()");
- DEBUG->print("FilterDXF::~FilterDXF(): OK");
-}
-
-/**
- * Implementation of the method used for RS_Import to communicate
- * with this filter.
- *
- * @param g The graphic in which the entities from the file
- * will be created or the graphics from which the entities are
- * taken to be stored in a file.
- */
-bool FilterDXF::fileImport(Drawing & g, const QString & file, RS2::FormatType /*type*/)
-{
- DEBUG->print("FilterDXF::fileImport");
- //DEBUG->timestamp();
-
- DEBUG->print("DXF Filter: importing file '%s'...", (const char *)QFile::encodeName(file));
-
- graphic = &g;
- currentContainer = graphic;
- this->file = file;
-
- DEBUG->print("graphic->countLayers(): %d", graphic->countLayers());
-
- //graphic->setAutoUpdateBorders(false);
- DEBUG->print("FilterDXF::fileImport: reading file");
- bool success = dxf.in((const char *)QFile::encodeName(file), this);
- DEBUG->print("FilterDXF::fileImport: reading file: OK");
- //graphic->setAutoUpdateBorders(true);
-
- if (!success)
- {
- DEBUG->print(Debug::D_WARNING, "Cannot open DXF file '%s'.",
- (const char *)QFile::encodeName(file));
- return false;
- }
-
- DEBUG->print("FilterDXF::fileImport: adding variables");
-
- // add some variables that need to be there for DXF drawings:
- if (graphic->getVariableString("$DIMSTYLE", "").isEmpty())
- {
- DEBUG->print("FilterDXF::fileImport: adding DIMSTYLE");
- graphic->addVariable("$DIMSTYLE", "Standard", 2);
- DEBUG->print("FilterDXF::fileImport: adding DIMSTYLE: OK");
- }
-
- DEBUG->print("FilterDXF::fileImport: adding variables: OK");
-
- DEBUG->print("FilterDXF::fileImport: updating inserts");
- graphic->updateInserts();
- DEBUG->print("FilterDXF::fileImport: updating inserts: OK");
-
- DEBUG->print("FilterDXF::fileImport OK");
- //DEBUG->timestamp();
-
- return true;
-}
-
-/**
- * Implementation of the method which handles layers.
- */
-void FilterDXF::addLayer(const DL_LayerData& data) {
- DEBUG->print("FilterDXF::addLayer");
- DEBUG->print(" adding layer: %s", data.name.c_str());
-
- DEBUG->print("FilterDXF::addLayer: creating layer");
- Layer* layer = new Layer(data.name.c_str());
- DEBUG->print("FilterDXF::addLayer: set pen");
- layer->setPen(attributesToPen(attributes));
- //layer->setFlags(data.flags&0x07);
-
- DEBUG->print("FilterDXF::addLayer: flags");
- if (data.flags&0x01) {
- layer->freeze(true);
- }
- if (data.flags&0x04) {
- layer->lock(true);
- }
-
- DEBUG->print("FilterDXF::addLayer: add layer to graphic");
- graphic->addLayer(layer);
- DEBUG->print("FilterDXF::addLayer: OK");
-}
-
-/**
- * Implementation of the method which handles blocks.
- *
- * @todo Adding blocks to blocks (stack for currentContainer)
- */
-void FilterDXF::addBlock(const DL_BlockData & data)
-{
- DEBUG->print("FilterDXF::addBlock");
- DEBUG->print(" adding block: %s", data.name.c_str());
-
- // Prevent special blocks (paper_space, model_space) from being added:
- if (QString(data.name.c_str()).toLower() != "*paper_space0"
- && QString(data.name.c_str()).toLower() != "*paper_space"
- && QString(data.name.c_str()).toLower() != "*model_space"
- && QString(data.name.c_str()).toLower() != "$paper_space0"
- && QString(data.name.c_str()).toLower() != "$paper_space"
- && QString(data.name.c_str()).toLower() != "$model_space")
- {
-
-#ifndef RS_NO_COMPLEX_ENTITIES
- if (QString(data.name.c_str()).startsWith("__CE"))
- {
- EntityContainer * ec = new EntityContainer();
- ec->setLayer("0");
- currentContainer = ec;
- graphic->addEntity(ec);
- //currentContainer->setLayer(graphic->findLayer("0"));
- }
- else
- {
-#endif
- Vector bp(data.bpx, data.bpy);
- Block * block = new Block(graphic, BlockData(data.name.c_str(), bp, false));
- //block->setFlags(flags);
-
- if (graphic->addBlock(block))
- currentContainer = block;
-#ifndef RS_NO_COMPLEX_ENTITIES
- }
-#endif
- }
-}
-
-/**
- * Implementation of the method which closes blocks.
- */
-void FilterDXF::endBlock()
-{
- currentContainer = graphic;
-}
-
-/**
- * Implementation of the method which handles point entities.
- */
-void FilterDXF::addPoint(const DL_PointData & data)
-{
- Vector v(data.x, data.y);
- Point * entity = new Point(currentContainer, PointData(v));
- setEntityAttributes(entity, attributes);
- currentContainer->addEntity(entity);
-}
-
-/**
- * Implementation of the method which handles line entities.
- */
-void FilterDXF::addLine(const DL_LineData & data)
-{
- DEBUG->print("FilterDXF::addLine");
-
- Vector v1(data.x1, data.y1);
- Vector v2(data.x2, data.y2);
-
- DEBUG->print("FilterDXF::addLine: create line");
-
- if (currentContainer == NULL)
- DEBUG->print("FilterDXF::addLine: currentContainer is NULL");
-
- Line * entity = new Line(currentContainer, LineData(v1, v2));
- DEBUG->print("FilterDXF::addLine: set attributes");
- setEntityAttributes(entity, attributes);
-
- DEBUG->print("FilterDXF::addLine: add entity");
-
- currentContainer->addEntity(entity);
-
- DEBUG->print("FilterDXF::addLine: OK");
-}
-
-/**
- * Implementation of the method which handles arc entities.
- *
- * @param angle1 Start angle in deg (!)
- * @param angle2 End angle in deg (!)
- */
-void FilterDXF::addArc(const DL_ArcData& data) {
- DEBUG->print("FilterDXF::addArc");
- //printf("LINE (%12.6f, %12.6f, %12.6f) (%12.6f, %12.6f, %12.6f)\n",
- // p1[0], p1[1], p1[2],
- // p2[0], p2[1], p2[2]);
- Vector v(data.cx, data.cy);
- ArcData d(v, data.radius,
- data.angle1/ARAD,
- data.angle2/ARAD,
- false);
- Arc* entity = new Arc(currentContainer, d);
- setEntityAttributes(entity, attributes);
-
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles ellipse entities.
- *
- * @param angle1 Start angle in rad (!)
- * @param angle2 End angle in rad (!)
- */
-void FilterDXF::addEllipse(const DL_EllipseData& data) {
- DEBUG->print("FilterDXF::addEllipse");
-
- Vector v1(data.cx, data.cy);
- Vector v2(data.mx, data.my);
-
- EllipseData ed(v1, v2,
- data.ratio,
- data.angle1,
- data.angle2,
- false);
- Ellipse* entity = new Ellipse(currentContainer, ed);
- setEntityAttributes(entity, attributes);
-
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles circle entities.
- */
-void FilterDXF::addCircle(const DL_CircleData& data) {
- DEBUG->print("FilterDXF::addCircle");
- //printf("LINE (%12.6f, %12.6f, %12.6f) (%12.6f, %12.6f, %12.6f)\n",
- // p1[0], p1[1], p1[2],
- // p2[0], p2[1], p2[2]);
-
- Vector v(data.cx, data.cy);
- CircleData d(v, data.radius);
- Circle* entity = new Circle(currentContainer, d);
- setEntityAttributes(entity, attributes);
-
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles polyline entities.
- */
-void FilterDXF::addPolyline(const DL_PolylineData& data) {
- DEBUG->print("FilterDXF::addPolyline");
- //DEBUG->print("FilterDXF::addPolyline()");
- PolylineData d(Vector(false),
- Vector(false),
- data.flags&0x1);
- polyline = new Polyline(currentContainer, d);
- setEntityAttributes(polyline, attributes);
-
- currentContainer->addEntity(polyline);
-}
-
-
-
-/**
- * Implementation of the method which handles polyline vertices.
- */
-void FilterDXF::addVertex(const DL_VertexData& data) {
- DEBUG->print("FilterDXF::addVertex(): %f/%f bulge: %f",
- data.x, data.y, data.bulge);
-
- Vector v(data.x, data.y);
-
- if (polyline!=NULL) {
- polyline->addVertex(v, data.bulge);
- }
-}
-
-
-
-/**
- * Implementation of the method which handles splines.
- */
-void FilterDXF::addSpline(const DL_SplineData& data) {
- DEBUG->print("FilterDXF::addSpline: degree: %d", data.degree);
-
- if (data.degree>=1 && data.degree<=3) {
- SplineData d(data.degree, ((data.flags&0x1)==0x1));
- spline = new Spline(currentContainer, d);
- setEntityAttributes(spline, attributes);
-
- currentContainer->addEntity(spline);
- } else {
- DEBUG->print(Debug::D_WARNING,
- "FilterDXF::addSpline: Invalid degree for spline: %d. "
- "Accepted values are 1..3.", data.degree);
- }
-}
-
-/*virtual*/ void FilterDXF::addKnot(const DL_KnotData &)
-{
-}
-
-/**
- * Implementation of the method which handles spline control points.
- */
-void FilterDXF::addControlPoint(const DL_ControlPointData & data)
-{
- DEBUG->print("FilterDXF::addControlPoint: %f/%f", data.x, data.y);
-
- Vector v(data.x, data.y);
-
- if (spline != NULL)
- {
- spline->addControlPoint(v);
- spline->update();
- }
-}
-
-/**
- * Implementation of the method which handles inserts.
- */
-void FilterDXF::addInsert(const DL_InsertData & data)
-{
- DEBUG->print("FilterDXF::addInsert");
-
- if (QString(data.name.c_str()).left(3) == "A$C")
- return;
-
- Vector ip(data.ipx, data.ipy);
- Vector sc(data.sx, data.sy);
- Vector sp(data.colSp, data.rowSp);
-
- //cout << "Insert: " << name << " " << ip << " " << cols << "/" << rows << endl;
-
- InsertData d(data.name.c_str(), ip, sc, data.angle / ARAD, data.cols, data.rows,
- sp, NULL, RS2::NoUpdate);
- Insert * entity = new Insert(currentContainer, d);
- setEntityAttributes(entity, attributes);
- DEBUG->print(" id: %d", entity->getId());
- //entity->update();
- currentContainer->addEntity(entity);
-}
-
-/*virtual*/ void FilterDXF::addTrace(const DL_TraceData &)
-{
-}
-
-/*virtual*/ void FilterDXF::addSolid(const DL_SolidData &)
-{
-}
-
-/**
- * Implementation of the method which handles text
- * chunks for MText entities.
- */
-void FilterDXF::addMTextChunk(const char * text)
-{
- DEBUG->print("FilterDXF::addMTextChunk: %s", text);
- //mtext += text;
- //mtext += QString::fromUtf8(text);
-
- /*
- QCString locallyEncoded = text;
- QString enc = System::getEncoding(variables.getString("$DWGCODEPAGE", "ANSI_1252"));
- QTextCodec *codec = QTextCodec::codecForName(enc); // get the codec for Japanese
- if (codec!=NULL) {
- mtext += codec->toUnicode(toNativeString(locallyEncoded));
-} else {
- mtext += toNativeString(text);
-}
- */
- mtext += text;
-}
-
-/**
- * Implementation of the method which handles
- * multi texts (MTEXT).
- */
-void FilterDXF::addMText(const DL_MTextData & data)
-{
- DEBUG->print("FilterDXF::addMText: %s", data.text.c_str());
-
- Vector ip(data.ipx, data.ipy);
- RS2::VAlign valign;
- RS2::HAlign halign;
- RS2::TextDrawingDirection dir;
- RS2::TextLineSpacingStyle lss;
- QString sty = data.style.c_str();
-
- if (data.attachmentPoint <= 3)
- valign = RS2::VAlignTop;
- else if (data.attachmentPoint <= 6)
- valign = RS2::VAlignMiddle;
- else
- valign = RS2::VAlignBottom;
-
- if (data.attachmentPoint % 3 == 1)
- halign = RS2::HAlignLeft;
- else if (data.attachmentPoint % 3 == 2)
- halign = RS2::HAlignCenter;
- else
- halign = RS2::HAlignRight;
-
- if (data.drawingDirection == 1)
- dir = RS2::LeftToRight;
- else if (data.drawingDirection == 3)
- dir = RS2::TopToBottom;
- else
- dir = RS2::ByStyle;
-
- if (data.lineSpacingStyle == 1)
- lss = RS2::AtLeast;
- else
- lss = RS2::Exact;
-
- mtext += QString(data.text.c_str());
-
- QString locallyEncoded = mtext;
- QString enc = System::getEncoding(variables.getString("$DWGCODEPAGE", "ANSI_1252"));
- // get the codec for Japanese
- QTextCodec * codec = QTextCodec::codecForName(enc.toAscii());
-
- if (codec != NULL)
- mtext = codec->toUnicode(toNativeString(locallyEncoded).toAscii());
- else
- mtext = toNativeString(mtext);
-
- // use default style for the drawing:
- if (sty.isEmpty())
- {
- // japanese, cyrillic:
- QString codepage = variables.getString("$DWGCODEPAGE", "ANSI_1252");
-
- if (codepage == "ANSI_932" || codepage == "ANSI_1251")
- sty = "Unicode";
- else
- sty = variables.getString("$TEXTSTYLE", "Standard");
- }
-
- DEBUG->print("Text as unicode:");
- DEBUG->printUnicode(mtext);
-
- TextData d(ip, data.height, data.width, valign, halign, dir, lss,
- data.lineSpacingFactor, mtext, sty, data.angle, RS2::NoUpdate);
- Text * entity = new Text(currentContainer, d);
-
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-
- mtext = "";
-}
-
-
-
-/**
- * Implementation of the method which handles
- * texts (TEXT).
- */
-void FilterDXF::addText(const DL_TextData& data) {
- DEBUG->print("FilterDXF::addText");
- int attachmentPoint;
- Vector refPoint;
- double angle = data.angle;
-
- // TODO: check, maybe implement a separate TEXT instead of using MTEXT
-
- // baseline has 5 vertical alignment modes:
- if (data.vJustification!=0 || data.hJustification!=0) {
- switch (data.hJustification) {
- default:
- case 0: // left aligned
- attachmentPoint = 1;
- refPoint = Vector(data.apx, data.apy);
- break;
- case 1: // centered
- attachmentPoint = 2;
- refPoint = Vector(data.apx, data.apy);
- break;
- case 2: // right aligned
- attachmentPoint = 3;
- refPoint = Vector(data.apx, data.apy);
- break;
- case 3: // aligned (TODO)
- attachmentPoint = 2;
- refPoint = Vector((data.ipx+data.apx)/2.0,
- (data.ipy+data.apy)/2.0);
- angle =
- Vector(data.ipx, data.ipy).angleTo(
- Vector(data.apx, data.apy));
- break;
- case 4: // Middle (TODO)
- attachmentPoint = 2;
- refPoint = Vector(data.apx, data.apy);
- break;
- case 5: // fit (TODO)
- attachmentPoint = 2;
- refPoint = Vector((data.ipx+data.apx)/2.0,
- (data.ipy+data.apy)/2.0);
- angle =
- Vector(data.ipx, data.ipy).angleTo(
- Vector(data.apx, data.apy));
- break;
- }
-
- switch (data.vJustification) {
- default:
- case 0: // baseline
- case 1: // bottom
- attachmentPoint += 6;
- break;
-
- case 2: // middle
- attachmentPoint += 3;
- break;
-
- case 3: // top
- break;
- }
- } else {
- //attachmentPoint = (data.hJustification+1)+(3-data.vJustification)*3;
- attachmentPoint = 7;
- refPoint = Vector(data.ipx, data.ipy);
- }
-
- int drawingDirection = 5;
- double width = 100.0;
-
- mtext = "";
- addMText(DL_MTextData(
- refPoint.x,
- refPoint.y,
- refPoint.z,
- data.height, width,
- attachmentPoint,
- drawingDirection,
- RS2::Exact,
- 1.0,
- data.text.c_str(), data.style,
- angle));
-}
-
-
-
-/**
- * Implementation of the method which handles
- * dimensions (DIMENSION).
- */
-DimensionData FilterDXF::convDimensionData(
- const DL_DimensionData& data) {
-
- Vector defP(data.dpx, data.dpy);
- Vector midP(data.mpx, data.mpy);
- RS2::VAlign valign;
- RS2::HAlign halign;
- RS2::TextLineSpacingStyle lss;
- QString sty = data.style.c_str();
- QString t; //= data.text;
-
- // middlepoint of text can be 0/0 which is considered to be invalid (!):
- // 0/0 because older QCad versions save the middle of the text as 0/0
- // althought they didn't suport saving of the middle of the text.
- if (fabs(data.mpx)<1.0e-6 && fabs(data.mpy)<1.0e-6) {
- midP = Vector(false);
- }
-
- if (data.attachmentPoint<=3) {
- valign=RS2::VAlignTop;
- } else if (data.attachmentPoint<=6) {
- valign=RS2::VAlignMiddle;
- } else {
- valign=RS2::VAlignBottom;
- }
-
- if (data.attachmentPoint%3==1) {
- halign=RS2::HAlignLeft;
- } else if (data.attachmentPoint%3==2) {
- halign=RS2::HAlignCenter;
- } else {
- halign=RS2::HAlignRight;
- }
-
- if (data.lineSpacingStyle==1) {
- lss = RS2::AtLeast;
- } else {
- lss = RS2::Exact;
- }
-
- t = toNativeString(data.text.c_str());
-
- if (sty.isEmpty()) {
- sty = variables.getString("$DIMSTYLE", "Standard");
- }
-
- DEBUG->print("Text as unicode:");
- DEBUG->printUnicode(t);
-
- // data needed to add the actual dimension entity
- return DimensionData(defP, midP,
- valign, halign,
- lss,
- data.lineSpacingFactor,
- t, sty, data.angle);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * aligned dimensions (DIMENSION).
- */
-void FilterDXF::addDimAlign(const DL_DimensionData& data,
- const DL_DimAlignedData& edata) {
- DEBUG->print("FilterDXF::addDimAligned");
-
- DimensionData dimensionData = convDimensionData(data);
-
- Vector ext1(edata.epx1, edata.epy1);
- Vector ext2(edata.epx2, edata.epy2);
-
- DimAlignedData d(ext1, ext2);
-
- DimAligned* entity = new DimAligned(currentContainer,
- dimensionData, d);
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * linear dimensions (DIMENSION).
- */
-void FilterDXF::addDimLinear(const DL_DimensionData& data,
- const DL_DimLinearData& edata) {
- DEBUG->print("FilterDXF::addDimLinear");
-
- DimensionData dimensionData = convDimensionData(data);
-
- Vector dxt1(edata.dpx1, edata.dpy1);
- Vector dxt2(edata.dpx2, edata.dpy2);
-
- DimLinearData d(dxt1, dxt2, Math::deg2rad(edata.angle),
- Math::deg2rad(edata.oblique));
-
- DimLinear* entity = new DimLinear(currentContainer,
- dimensionData, d);
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * radial dimensions (DIMENSION).
- */
-void FilterDXF::addDimRadial(const DL_DimensionData& data,
- const DL_DimRadialData& edata) {
- DEBUG->print("FilterDXF::addDimRadial");
-
- DimensionData dimensionData = convDimensionData(data);
- Vector dp(edata.dpx, edata.dpy);
-
- DimRadialData d(dp, edata.leader);
-
- DimRadial* entity = new DimRadial(currentContainer,
- dimensionData, d);
-
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * diametric dimensions (DIMENSION).
- */
-void FilterDXF::addDimDiametric(const DL_DimensionData& data,
- const DL_DimDiametricData& edata) {
- DEBUG->print("FilterDXF::addDimDiametric");
-
- DimensionData dimensionData = convDimensionData(data);
- Vector dp(edata.dpx, edata.dpy);
-
- DimDiametricData d(dp, edata.leader);
-
- DimDiametric* entity = new DimDiametric(currentContainer,
- dimensionData, d);
-
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * angular dimensions (DIMENSION).
- */
-void FilterDXF::addDimAngular(const DL_DimensionData& data,
- const DL_DimAngularData& edata) {
- DEBUG->print("FilterDXF::addDimAngular");
-
- DimensionData dimensionData = convDimensionData(data);
- Vector dp1(edata.dpx1, edata.dpy1);
- Vector dp2(edata.dpx2, edata.dpy2);
- Vector dp3(edata.dpx3, edata.dpy3);
- Vector dp4(edata.dpx4, edata.dpy4);
-
- DimAngularData d(dp1, dp2, dp3, dp4);
-
- DimAngular* entity = new DimAngular(currentContainer,
- dimensionData, d);
-
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles
- * angular dimensions (DIMENSION).
- */
-void FilterDXF::addDimAngular3P(const DL_DimensionData& data,
- const DL_DimAngular3PData& edata) {
- DEBUG->print("FilterDXF::addDimAngular3P");
-
- DimensionData dimensionData = convDimensionData(data);
- Vector dp1(edata.dpx3, edata.dpy3);
- Vector dp2(edata.dpx1, edata.dpy1);
- Vector dp3(edata.dpx3, edata.dpy3);
- Vector dp4 = dimensionData.definitionPoint;
- dimensionData.definitionPoint = Vector(edata.dpx2, edata.dpy2);
-
- DimAngularData d(dp1, dp2, dp3, dp4);
-
- DimAngular* entity = new DimAngular(currentContainer,
- dimensionData, d);
-
- setEntityAttributes(entity, attributes);
- entity->update();
- currentContainer->addEntity(entity);
-}
-
-
-
-/**
- * Implementation of the method which handles leader entities.
- */
-void FilterDXF::addLeader(const DL_LeaderData& data) {
- DEBUG->print("FilterDXF::addDimLeader");
- //DEBUG->print("FilterDXF::addPolyline()");
- LeaderData d(data.arrowHeadFlag==1);
- leader = new Leader(currentContainer, d);
- setEntityAttributes(leader, attributes);
-
- currentContainer->addEntity(leader);
-}
-
-
-
-/**
- * Implementation of the method which handles leader vertices.
- */
-void FilterDXF::addLeaderVertex(const DL_LeaderVertexData& data) {
- DEBUG->print("FilterDXF::addLeaderVertex");
- //DEBUG->print("FilterDXF::addVertex() bulge: %f", bulge);
-
- Vector v(data.x, data.y);
-
- if (leader!=NULL) {
- leader->addVertex(v);
- }
-}
-
-
-
-/**
- * Implementation of the method which handles hatch entities.
- */
-void FilterDXF::addHatch(const DL_HatchData& data) {
- DEBUG->print("FilterDXF::addHatch()");
-
- hatch = new Hatch(currentContainer,
- HatchData(data.solid,
- data.scale,
- data.angle,
- QString(data.pattern.c_str())));
- setEntityAttributes(hatch, attributes);
-
- currentContainer->addEntity(hatch);
-}
-
-
-
-/**
- * Implementation of the method which handles hatch loops.
- */
-void FilterDXF::addHatchLoop(const DL_HatchLoopData& /*data*/) {
- DEBUG->print("FilterDXF::addHatchLoop()");
- if (hatch!=NULL) {
- hatchLoop = new EntityContainer(hatch);
- hatchLoop->setLayer(NULL);
- hatch->addEntity(hatchLoop);
- }
-}
-
-
-
-/**
- * Implementation of the method which handles hatch edge entities.
- */
-void FilterDXF::addHatchEdge(const DL_HatchEdgeData& data) {
- DEBUG->print("FilterDXF::addHatchEdge()");
-
- if (hatchLoop!=NULL) {
- Entity* e = NULL;
- switch (data.type) {
- case 1:
- DEBUG->print("FilterDXF::addHatchEdge(): "
- "line: %f,%f %f,%f",
- data.x1, data.y1, data.x2, data.y2);
- e = new Line(hatchLoop,
- LineData(Vector(data.x1, data.y1),
- Vector(data.x2, data.y2)));
- break;
- case 2:
- if (data.ccw && data.angle1<1.0e-6 && data.angle2>2*M_PI-1.0e-6) {
- e = new Circle(hatchLoop,
- CircleData(Vector(data.cx, data.cy),
- data.radius));
- } else {
- if (data.ccw) {
- e = new Arc(
- hatchLoop,
- ArcData(Vector(data.cx, data.cy),
- data.radius,
- Math::correctAngle(data.angle1),
- Math::correctAngle(data.angle2),
- false));
- } else {
- e = new Arc(
- hatchLoop,
- ArcData(Vector(data.cx, data.cy),
- data.radius,
- Math::correctAngle(2*M_PI-data.angle1),
- Math::correctAngle(2*M_PI-data.angle2),
- true));
- }
- }
- break;
- default:
- break;
- }
-
- if (e!=NULL) {
- e->setLayer(NULL);
- hatchLoop->addEntity(e);
- }
- }
-}
-
-
-
-/**
- * Implementation of the method which handles image entities.
- */
-void FilterDXF::addImage(const DL_ImageData& data) {
- DEBUG->print("FilterDXF::addImage");
-
- Vector ip(data.ipx, data.ipy);
- Vector uv(data.ux, data.uy);
- Vector vv(data.vx, data.vy);
- Vector size(data.width, data.height);
-
- Image* image =
- new Image(
- currentContainer,
- ImageData(QString(data.ref.c_str()).toInt(NULL, 16),
- ip, uv, vv,
- size,
- QString(""),
- data.brightness,
- data.contrast,
- data.fade));
-
- setEntityAttributes(image, attributes);
- currentContainer->addEntity(image);
-}
-
-/**
- * Implementation of the method which links image entities to image files.
- */
-void FilterDXF::linkImage(const DL_ImageDefData & data)
-{
- DEBUG->print("FilterDXF::linkImage");
-
- int handle = QString(data.ref.c_str()).toInt(NULL, 16);
- QString sfile(data.file.c_str());
- QFileInfo fiDxf(file);
- QFileInfo fiBitmap(sfile);
-
- // try to find the image file:
-
- // first: absolute path:
- if (!fiBitmap.exists())
- {
- DEBUG->print("File %s doesn't exist.", (const char *)QFile::encodeName(sfile));
- // try relative path:
-// QString f1 = fiDxf.dirPath(true) + "/" + sfile;
- QString f1 = fiDxf.absolutePath() + "/" + sfile;
-
- if (QFileInfo(f1).exists())
- sfile = f1;
- else
- {
- DEBUG->print("File %s doesn't exist.", (const char *)QFile::encodeName(f1));
- // try drawing path:
-// QString f2 = fiDxf.dirPath(true) + "/" + fiBitmap.fileName();
- QString f2 = fiDxf.absolutePath() + "/" + fiBitmap.fileName();
-
- if (QFileInfo(f2).exists())
- {
- sfile = f2;
- }
- else
- {
- DEBUG->print("File %s doesn't exist.", (const char *)QFile::encodeName(f2));
- }
- }
- }
-
- // Also link images in subcontainers (e.g. inserts):
- for(Entity * e=graphic->firstEntity(RS2::ResolveNone); e!=NULL;
- e=graphic->nextEntity(RS2::ResolveNone))
- {
- if (e->rtti() == RS2::EntityImage)
- {
- Image * img = (Image *)e;
-
- if (img->getHandle() == handle)
- {
- img->setFile(sfile);
- DEBUG->print("image found: %s", (const char *)QFile::encodeName(img->getFile()));
- img->update();
- }
- }
- }
-
- // update images in blocks:
- for(uint i=0; i<graphic->countBlocks(); ++i)
- {
- Block * b = graphic->blockAt(i);
-
- for(Entity * e=b->firstEntity(RS2::ResolveNone); e!=NULL; e=b->nextEntity(RS2::ResolveNone))
- {
- if (e->rtti() == RS2::EntityImage)
- {
- Image * img = (Image *)e;
-
- if (img->getHandle() == handle)
- {
- img->setFile(sfile);
- DEBUG->print("image in block found: %s",
- (const char*)QFile::encodeName(img->getFile()));
- img->update();
- }
- }
- }
- }
-
- DEBUG->print("linking image: OK");
-}
-
-/**
- * Finishes a hatch entity.
- */
-void FilterDXF::endEntity()
-{
- DEBUG->print("FilterDXF::endEntity");
-
- if (hatch != NULL)
- {
- DEBUG->print("hatch->update()");
-
- if (hatch->validate())
- hatch->update();
- else
- {
- graphic->removeEntity(hatch);
- DEBUG->print(Debug::D_ERROR, "FilterDXF::endEntity(): updating hatch failed: invalid hatch area");
- }
-
- hatch = NULL;
- }
-}
-
-/*virtual*/ void FilterDXF::endSequence()
-{
-}
-
-/**
- * Sets a vector variable from the DXF file.
- */
-void FilterDXF::setVariableVector(const char * key, double v1, double v2, double v3, int code)
-{
- DEBUG->print("FilterDXF::setVariableVector");
-
- // update document's variable list:
- if (currentContainer->rtti() == RS2::EntityDrawing)
- ((Drawing *)currentContainer)->addVariable(QString(key), Vector(v1, v2, v3), code);
-}
-
-/**
- * Sets a string variable from the DXF file.
- */
-void FilterDXF::setVariableString(const char * key, const char * value, int code)
-{
- DEBUG->print("FilterDXF::setVariableString");
-
- // update local DXF variable list:
- variables.add(QString(key), QString(value), code);
-
- // update document's variable list:
- if (currentContainer->rtti()==RS2::EntityDrawing)
- {
- ((Drawing *)currentContainer)->addVariable(QString(key), QString(value), code);
- }
-}
-
-
-
-/**
- * Sets an int variable from the DXF file.
- */
-void FilterDXF::setVariableInt(const char* key, int value, int code)
-{
- DEBUG->print("FilterDXF::setVariableInt");
-
- // update document's variable list:
- if (currentContainer->rtti()==RS2::EntityDrawing)
- {
- ((Drawing *)currentContainer)->addVariable(QString(key), value, code);
- }
-}
-
-
-
-/**
- * Sets a double variable from the DXF file.
- */
-void FilterDXF::setVariableDouble(const char* key, double value, int code)
-{
- DEBUG->print("FilterDXF::setVariableDouble");
-
- // update document's variable list:
- if (currentContainer->rtti() == RS2::EntityDrawing)
- {
- ((Drawing *)currentContainer)->addVariable(QString(key), value, code);
- }
-}
-
-/**
- * Implementation of the method used for RS_Export to communicate
- * with this filter.
- *
- * @param file Full path to the DXF file that will be written.
- */
-bool FilterDXF::fileExport(Drawing & g, const QString & file, RS2::FormatType type)
-{
- DEBUG->print("FilterDXF::fileExport: exporting file '%s'...",
- (const char *)QFile::encodeName(file));
- DEBUG->print("FilterDXF::fileExport: file type '%d'", (int)type);
-
- this->graphic = &g;
-
-#ifndef Q_OS_WIN
- // check if we can write to that directory:
-// QString path = QFileInfo(file).dirPath(true);
- QString path = QFileInfo(file).absolutePath();
-
- if (QFileInfo(path).isWritable() == false)
- {
- DEBUG->print("FilterDXF::fileExport: can't write file: no permission");
- return false;
- }
- //
-#endif
-
- // set version for DXF filter:
- DL_Codes::version exportVersion;
-
- if (type == RS2::FormatDXF12)
- {
- exportVersion = DL_Codes::AC1009;
- }
- else
- {
- exportVersion = DL_Codes::AC1015;
- }
-
- //DL_WriterA* dw = dxf.out(file, VER_R12);
- DL_WriterA * dw = dxf.out((const char *)QFile::encodeName(file), exportVersion);
-
- if (dw == NULL)
- {
- DEBUG->print("FilterDXF::fileExport: can't write file");
- return false;
- }
-
- // Header
- DEBUG->print("writing headers...");
- dxf.writeHeader(*dw);
-
- // Variables
- DEBUG->print("writing variables...");
- writeVariables(*dw);
-
- // Section TABLES
- DEBUG->print("writing tables...");
- dw->sectionTables();
-
- // VPORT:
- dxf.writeVPort(*dw);
-
- // Line types:
- DEBUG->print("writing line types...");
- int numLT = (int)RS2::BorderLineX2 - (int)RS2::LineByBlock;
-
- if (type == RS2::FormatDXF12)
- numLT -= 2;
-
- dw->tableLineTypes(numLT);
-
- for(int t=(int)RS2::LineByBlock; t<=(int)RS2::BorderLineX2; ++t)
- {
- if ((RS2::LineType)t != RS2::NoPen)
- writeLineType(*dw, (RS2::LineType)t);
- }
-
- dw->tableEnd();
-
- // Layers:
- DEBUG->print("writing layers...");
- dw->tableLayers(graphic->countLayers());
-
- for(uint i=0; i<graphic->countLayers(); ++i)
- {
- Layer * l = graphic->layerAt(i);
- writeLayer(*dw, l);
- }
-
- dw->tableEnd();
-
- // STYLE:
- DEBUG->print("writing styles...");
- dxf.writeStyle(*dw);
-
- // VIEW:
- DEBUG->print("writing views...");
- dxf.writeView(*dw);
-
- // UCS:
- DEBUG->print("writing ucs...");
- dxf.writeUcs(*dw);
-
- // Appid:
- DEBUG->print("writing appid...");
- dw->tableAppid(1);
- writeAppid(*dw, "ACAD");
- dw->tableEnd();
-
- // DIMSTYLE:
- DEBUG->print("writing dim styles...");
- dxf.writeDimStyle(*dw,
- graphic->getVariableDouble("$DIMASZ", 2.5),
- graphic->getVariableDouble("$DIMEXE", 1.25),
- graphic->getVariableDouble("$DIMEXO", 0.625),
- graphic->getVariableDouble("$DIMGAP", 0.625),
- graphic->getVariableDouble("$DIMTXT", 2.5));
-
- // BLOCK_RECORD:
- if (type == RS2::FormatDXF)
- {
- DEBUG->print("writing block records...");
- dxf.writeBlockRecord(*dw);
-
- for(uint i=0; i<graphic->countBlocks(); ++i)
- {
- Block * blk = graphic->blockAt(i);
- dxf.writeBlockRecord(*dw, std::string((const char *)blk->getName().toLocal8Bit()));
- /*
- // v2.0.4.9..:
- //writeBlock(*dw, blk);
- dw->dxfString( 0, "BLOCK_RECORD");
- //dw.dxfHex(5, 0x1F);
- dw->handle();
- dw->dxfHex(330, 1);
- dw->dxfString(100, "AcDbSymbolTableRecord");
- dw->dxfString(100, "AcDbBlockTableRecord");
- dw->dxfString( 2, blk->getName().toLocal8Bit());
- dw->dxfHex(340, 0);
- */
- }
-
- dw->tableEnd();
- }
-
- // end of tables:
- DEBUG->print("writing end of section TABLES...");
- dw->sectionEnd();
-
- // Section BLOCKS:
- DEBUG->print("writing blocks...");
- dw->sectionBlocks();
-
- if (type == RS2::FormatDXF)
- {
- Block b1(graphic, BlockData("*Model_Space", Vector(0.0, 0.0), false));
- writeBlock(*dw, &b1);
- Block b2(graphic, BlockData("*Paper_Space", Vector(0.0, 0.0), false));
- writeBlock(*dw, &b2);
- Block b3(graphic, BlockData("*Paper_Space0", Vector(0.0, 0.0), false));
- writeBlock(*dw, &b3);
- }
-
- for(uint i=0; i<graphic->countBlocks(); ++i)
- {
- Block * blk = graphic->blockAt(i);
-
- // Save block if it's not a model or paper space:
- // Careful: other blocks with * / $ exist
- //if (blk->getName().at(0)!='*' &&
- // blk->getName().at(0)!='$') {
- writeBlock(*dw, blk);
- //}
- }
-
- dw->sectionEnd();
-
- // Section ENTITIES:
- DEBUG->print("writing section ENTITIES...");
- dw->sectionEntities();
-
- for(Entity * e=graphic->firstEntity(RS2::ResolveNone); e!=NULL;
- e=graphic->nextEntity(RS2::ResolveNone))
- {
- writeEntity(*dw, e);
- }
-
- DEBUG->print("writing end of section ENTITIES...");
- dw->sectionEnd();
-
- if (type == RS2::FormatDXF)
- {
- DEBUG->print("writing section OBJECTS...");
- dxf.writeObjects(*dw);
-
- // IMAGEDEF's from images in entities and images in blocks
- QStringList written;
-
- for(uint i=0; i<graphic->countBlocks(); ++i)
- {
- Block * block = graphic->blockAt(i);
-
- for(Entity * e=block->firstEntity(RS2::ResolveAll); e!=NULL;
- e=block->nextEntity(RS2::ResolveAll))
- {
- if (e->rtti() == RS2::EntityImage)
- {
- Image * img = ((Image *)e);
-
- if (written.contains(file) == 0 && img->getHandle() != 0)
- {
- writeImageDef(*dw, img);
- written.append(img->getFile());
- }
- }
- }
- }
-
- for(Entity * e=graphic->firstEntity(RS2::ResolveNone); e!=NULL;
- e=graphic->nextEntity(RS2::ResolveNone))
- {
- if (e->rtti() == RS2::EntityImage)
- {
- Image * img = ((Image *)e);
-
- if (written.contains(file) == 0 && img->getHandle() != 0)
- {
- writeImageDef(*dw, img);
- written.append(img->getFile());
- }
- }
- }
- DEBUG->print("writing end of section OBJECTS...");
- dxf.writeObjectsEnd(*dw);
- }
-
- DEBUG->print("writing EOF...");
- dw->dxfEOF();
-
- DEBUG->print("close..");
- dw->close();
-
- delete dw;
-
- // check if file was actually written (strange world of windoze xp):
- if (QFileInfo(file).exists() == false)
- {
- DEBUG->print("FilterDXF::fileExport: file could not be written");
- return false;
- }
-
- return true;
-}
-
-/**
- * Writes all known variable settings to the DXF file.
- */
-void FilterDXF::writeVariables(DL_WriterA & dw)
-{
-// Q3DictIterator<Variable> it(graphic->getVariableDict());
- QHashIterator<QString, Variable *> it(graphic->getVariableDict());
-
-// for (; it.current(); ++it)
- while (it.hasNext())
- {
- it.next();
-
- // exclude variables that are not known to DXF 12:
- if (!DL_Dxf::checkVariable(it.key().toLatin1(), dxf.getVersion()))
- continue;
-
- if (it.key() != "$ACADVER" && it.key() != "$HANDSEED")
- {
- dw.dxfString(9, (const char *)it.key().toAscii().data());
-
- switch (it.value()->getType())
- {
- case RS2::VariableVoid:
- break;
- case RS2::VariableInt:
- dw.dxfInt(it.value()->getCode(), it.value()->getInt());
- break;
- case RS2::VariableDouble:
- dw.dxfReal(it.value()->getCode(), it.value()->getDouble());
- break;
- case RS2::VariableString:
- dw.dxfString(it.value()->getCode(), (const char *)it.value()->getString().toAscii().data());
- break;
- case RS2::VariableVector:
- dw.dxfReal(it.value()->getCode(), it.value()->getVector().x);
- dw.dxfReal(it.value()->getCode() + 10, it.value()->getVector().y);
-
- if (isVariableTwoDimensional(it.key()) == false)
- dw.dxfReal(it.value()->getCode() + 20, it.value()->getVector().z);
-
- break;
- }
- }
- }
-
- dw.sectionEnd();
-}
-
-/**
- * Writes one layer to the DXF file.
- *
- * @todo Add support for unicode layer names
- */
-void FilterDXF::writeLayer(DL_WriterA & dw, Layer * l)
-{
- if (l == NULL)
- {
- DEBUG->print(Debug::D_WARNING, "FilterDXF::writeLayer: layer is NULL");
- return;
- }
-
- DEBUG->print("FilterDXF::writeLayer %s", l->getName().toLatin1().data());
-
- dxf.writeLayer(dw, DL_LayerData((const char *)l->getName().toLocal8Bit(),
- l->isFrozen() + (l->isLocked() << 2)), DL_Attributes(std::string(""),
- colorToNumber(l->getPen().getColor()), widthToNumber(l->getPen().getWidth()),
- (const char *)lineTypeToName(l->getPen().getLineType()).toLocal8Bit()));
-
- DEBUG->print("FilterDXF::writeLayer end");
-}
-
-/**
- * Writes a line type to the DXF file.
- */
-void FilterDXF::writeLineType(DL_WriterA & dw, RS2::LineType t)
-{
- dxf.writeLineType(dw, DL_LineTypeData((const char *)lineTypeToName(t).toLocal8Bit(), 0));
-}
-
-
-
-/**
- * Writes an application id to the DXF file.
- *
- * @param appid Application ID (e.g. "QCad").
- */
-void FilterDXF::writeAppid(DL_WriterA& dw, const char* appid) {
- dxf.writeAppid(dw, appid);
-}
-
-
-
-/**
- * Writes a block (just the definition, not the entities in it).
- */
-void FilterDXF::writeBlock(DL_WriterA& dw, Block* blk) {
- if (blk==NULL) {
- DEBUG->print(Debug::D_WARNING,
- "FilterDXF::writeBlock: Block is NULL");
- return;
- }
-
- DEBUG->print("writing block: %s", (const char*)blk->getName().toLocal8Bit());
-
- dxf.writeBlock(dw,
- DL_BlockData((const char*)blk->getName().toLocal8Bit(), 0,
- blk->getBasePoint().x,
- blk->getBasePoint().y,
- blk->getBasePoint().z));
- for (Entity* e=blk->firstEntity(RS2::ResolveNone);
- e!=NULL;
- e=blk->nextEntity(RS2::ResolveNone)) {
- writeEntity(dw, e);
- }
- dxf.writeEndBlock(dw, (const char*)blk->getName().toLocal8Bit());
-}
-
-
-
-/**
- * Writes the given entity to the DXF file.
- */
-void FilterDXF::writeEntity(DL_WriterA& dw, Entity* e) {
- writeEntity(dw, e, getEntityAttributes(e));
-}
-
-
-/**
- * Writes the given entity to the DXF file.
- */
-void FilterDXF::writeEntity(DL_WriterA& dw, Entity* e,
- const DL_Attributes& attrib) {
-
- if (e==NULL || e->getFlag(RS2::FlagUndone)) {
- return;
- }
- DEBUG->print("writing Entity");
-
- switch (e->rtti()) {
- case RS2::EntityPoint:
- writePoint(dw, (Point*)e, attrib);
- break;
- case RS2::EntityLine:
- writeLine(dw, (Line*)e, attrib);
- break;
- case RS2::EntityPolyline:
- writePolyline(dw, (Polyline*)e, attrib);
- break;
- case RS2::EntitySpline:
- writeSpline(dw, (Spline*)e, attrib);
- break;
- case RS2::EntityVertex:
- break;
- case RS2::EntityCircle:
- writeCircle(dw, (Circle*)e, attrib);
- break;
- case RS2::EntityArc:
- writeArc(dw, (Arc*)e, attrib);
- break;
- case RS2::EntityEllipse:
- writeEllipse(dw, (Ellipse*)e, attrib);
- break;
- case RS2::EntityInsert:
- writeInsert(dw, (Insert*)e, attrib);
- break;
- case RS2::EntityText:
- writeText(dw, (Text*)e, attrib);
- break;
-
- case RS2::EntityDimAligned:
- case RS2::EntityDimAngular:
- case RS2::EntityDimLinear:
- case RS2::EntityDimRadial:
- case RS2::EntityDimDiametric:
- writeDimension(dw, (Dimension*)e, attrib);
- break;
- case RS2::EntityDimLeader:
- writeLeader(dw, (Leader*)e, attrib);
- break;
- case RS2::EntityHatch:
- writeHatch(dw, (Hatch*)e, attrib);
- break;
- case RS2::EntityImage:
- writeImage(dw, (Image*)e, attrib);
- break;
- case RS2::EntitySolid:
- writeSolid(dw, (Solid*)e, attrib);
- break;
-
-#ifndef RS_NO_COMPLEX_ENTITIES
-
- case RS2::EntityContainer:
- writeEntityContainer(dw, (EntityContainer*)e, attrib);
- break;
-#endif
-
- default:
- break;
- }
-}
-
-
-
-/**
- * Writes the given Point entity to the file.
- */
-void FilterDXF::writePoint(DL_WriterA& dw, Point* p,
- const DL_Attributes& attrib) {
- dxf.writePoint(
- dw,
- DL_PointData(p->getPos().x,
- p->getPos().y,
- 0.0),
- attrib);
-}
-
-
-/**
- * Writes the given Line( entity to the file.
- */
-void FilterDXF::writeLine(DL_WriterA& dw, Line* l,
- const DL_Attributes& attrib) {
- dxf.writeLine(
- dw,
- DL_LineData(l->getStartpoint().x,
- l->getStartpoint().y,
- 0.0,
- l->getEndpoint().x,
- l->getEndpoint().y,
- 0.0),
- attrib);
-}
-
-
-
-/**
- * Writes the given polyline entity to the file.
- */
-void FilterDXF::writePolyline(DL_WriterA& dw,
- Polyline* l,
- const DL_Attributes& attrib) {
-
- int count = l->count();
- if (l->isClosed()==false) {
- count++;
- }
-
- dxf.writePolyline(
- dw,
- DL_PolylineData(count,
- 0, 0,
- l->isClosed()*0x1),
- attrib);
- bool first = true;
- Entity* nextEntity = 0;
- AtomicEntity* ae = NULL;
- Entity* lastEntity = l->lastEntity(RS2::ResolveNone);
- for (Entity* v=l->firstEntity(RS2::ResolveNone);
- v!=NULL;
- v=nextEntity) {
-
- nextEntity = l->nextEntity(RS2::ResolveNone);
-
- if (!v->isAtomic()) {
- continue;
- }
-
- ae = (AtomicEntity*)v;
- double bulge=0.0;
-
- // Write vertex:
- if (first) {
- if (v->rtti()==RS2::EntityArc) {
- bulge = ((Arc*)v)->getBulge();
- }
- dxf.writeVertex(dw,
- DL_VertexData(ae->getStartpoint().x,
- ae->getStartpoint().y,
- 0.0,
- bulge));
- first = false;
- }
-
- //if (dxf.getVersion()==VER_R12) {
- if (nextEntity!=NULL) {
- if (nextEntity->rtti()==RS2::EntityArc) {
- bulge = ((Arc*)nextEntity)->getBulge();
- }
- else {
- bulge = 0.0;
- }
- }
- /*} else {
- if (v->rtti()==RS2::EntityArc) {
- bulge = ((Arc*)v)->getBulge();
- }
- }*/
-
-
- if (l->isClosed()==false || v!=lastEntity) {
- dxf.writeVertex(dw,
- DL_VertexData(ae->getEndpoint().x,
- ae->getEndpoint().y,
- 0.0,
- bulge));
- }
- }
- dxf.writePolylineEnd(dw);
-}
-
-
-
-/**
- * Writes the given spline entity to the file.
- */
-void FilterDXF::writeSpline(DL_WriterA & dw, Spline * s, const DL_Attributes & attrib)
-{
- // split spline into atomic entities for DXF R12:
- if (dxf.getVersion() == VER_R12)
- {
- writeAtomicEntities(dw, s, attrib, RS2::ResolveNone);
- return;
- }
-
- if (s->getNumberOfControlPoints() < s->getDegree() + 1)
- {
- DEBUG->print(Debug::D_ERROR, "FilterDXF::writeSpline: "
- "Discarding spline: not enough control points given.");
- return;
- }
-
- // Number of control points:
- int numCtrl = s->getNumberOfControlPoints();
-
- // Number of knots (= number of control points + spline degree + 1)
- int numKnots = numCtrl + s->getDegree() + 1;
-
- int flags;
-
- if (s->isClosed())
- flags = 11;
- else
- flags = 8;
-
- // write spline header:
- dxf.writeSpline(dw, DL_SplineData(s->getDegree(), numKnots, numCtrl, flags), attrib);
-
- // write spline knots:
- QList<Vector> cp = s->getControlPoints();
- QList<Vector>::iterator it;
-
- int k = s->getDegree() + 1;
- DL_KnotData kd;
-
- for(int i=1; i<=numKnots; i++)
- {
- if (i <= k)
- kd = DL_KnotData(0.0);
- else if (i <= numKnots - k)
- kd = DL_KnotData(1.0 / (numKnots - 2 * k + 1) * (i - k));
- else
- kd = DL_KnotData(1.0);
-
- dxf.writeKnot(dw, kd);
- }
-
- // write spline control points:
- for(it=cp.begin(); it!=cp.end(); ++it)
- {
- dxf.writeControlPoint(dw, DL_ControlPointData((*it).x, (*it).y, 0.0));
- }
-}
-
-/**
- * Writes the given circle entity to the file.
- */
-void FilterDXF::writeCircle(DL_WriterA& dw, Circle* c,
- const DL_Attributes& attrib) {
- dxf.writeCircle(
- dw,
- DL_CircleData(c->getCenter().x,
- c->getCenter().y,
- 0.0,
- c->getRadius()),
- attrib);
-
-}
-
-
-
-void FilterDXF::writeArc(DL_WriterA& dw, Arc* a,
- const DL_Attributes& attrib) {
- double a1, a2;
- if (a->isReversed()) {
- a1 = a->getAngle2()*ARAD;
- a2 = a->getAngle1()*ARAD;
- } else {
- a1 = a->getAngle1()*ARAD;
- a2 = a->getAngle2()*ARAD;
- }
- dxf.writeArc(
- dw,
- DL_ArcData(a->getCenter().x,
- a->getCenter().y,
- 0.0,
- a->getRadius(),
- a1, a2),
- attrib);
-}
-
-
-void FilterDXF::writeEllipse(DL_WriterA& dw, Ellipse* s,
- const DL_Attributes& attrib) {
- if (s->isReversed()) {
- dxf.writeEllipse(
- dw,
- DL_EllipseData(s->getCenter().x,
- s->getCenter().y,
- 0.0,
- s->getMajorP().x,
- s->getMajorP().y,
- 0.0,
- s->getRatio(),
- s->getAngle2(),
- s->getAngle1()),
- attrib);
- } else {
- dxf.writeEllipse(
- dw,
- DL_EllipseData(s->getCenter().x,
- s->getCenter().y,
- 0.0,
- s->getMajorP().x,
- s->getMajorP().y,
- 0.0,
- s->getRatio(),
- s->getAngle1(),
- s->getAngle2()),
- attrib);
- }
-}
-
-void FilterDXF::writeInsert(DL_WriterA & dw, Insert * i, const DL_Attributes & attrib)
-{
- dxf.writeInsert(dw, DL_InsertData(i->getName().toLatin1().data(),
- i->getInsertionPoint().x, i->getInsertionPoint().y, 0.0,
- i->getScale().x, i->getScale().y, 0.0,
- i->getAngle() * ARAD, i->getCols(), i->getRows(),
- i->getSpacing().x, i->getSpacing().y),
- attrib);
-}
-
-void FilterDXF::writeText(DL_WriterA & dw, Text * t, const DL_Attributes & attrib)
-{
- if (dxf.getVersion()==VER_R12)
- {
- int hJust=0;
- int vJust=0;
-
- if (t->getHAlign()==RS2::HAlignLeft) {
- hJust=0;
- } else if (t->getHAlign()==RS2::HAlignCenter) {
- hJust=1;
- } else if (t->getHAlign()==RS2::HAlignRight) {
- hJust=2;
- }
-
- if (t->getVAlign()==RS2::VAlignTop) {
- vJust=3;
- } else if (t->getVAlign()==RS2::VAlignMiddle) {
- vJust=2;
- } else if (t->getVAlign()==RS2::VAlignBottom) {
- vJust=1;
- }
-
- dxf.writeText(
- dw,
- DL_TextData(t->getInsertionPoint().x,
- t->getInsertionPoint().y,
- 0.0,
- t->getInsertionPoint().x,
- t->getInsertionPoint().y,
- 0.0,
- t->getHeight(),
- 1.0,
- 0,
- hJust, vJust,
- (const char*)toDxfString(
- t->getText()).toLocal8Bit(),
- (const char*)t->getStyle().toLocal8Bit(),
- t->getAngle()),
- attrib);
- }
- else
- {
- int attachmentPoint=1;
-
- if (t->getHAlign()==RS2::HAlignLeft) {
- attachmentPoint=1;
- } else if (t->getHAlign()==RS2::HAlignCenter) {
- attachmentPoint=2;
- } else if (t->getHAlign()==RS2::HAlignRight) {
- attachmentPoint=3;
- }
-
- if (t->getVAlign()==RS2::VAlignTop) {
- attachmentPoint+=0;
- } else if (t->getVAlign()==RS2::VAlignMiddle) {
- attachmentPoint+=3;
- } else if (t->getVAlign()==RS2::VAlignBottom) {
- attachmentPoint+=6;
- }
-
- dxf.writeMText(
- dw,
- DL_MTextData(t->getInsertionPoint().x,
- t->getInsertionPoint().y,
- 0.0,
- t->getHeight(),
- t->getWidth(),
- attachmentPoint,
- t->getDrawingDirection(),
- t->getLineSpacingStyle(),
- t->getLineSpacingFactor(),
- (const char*)toDxfString(
- t->getText()).toLocal8Bit(),
- (const char*)t->getStyle().toLocal8Bit(),
- t->getAngle()),
- attrib);
- }
-}
-
-
-
-void FilterDXF::writeDimension(DL_WriterA& dw, Dimension* d,
- const DL_Attributes& attrib) {
-
- // split hatch into atomic entities:
- if (dxf.getVersion()==VER_R12) {
- writeAtomicEntities(dw, d, attrib, RS2::ResolveNone);
- return;
- }
-
- int type;
- int attachmentPoint=1;
- if (d->getHAlign()==RS2::HAlignLeft) {
- attachmentPoint=1;
- } else if (d->getHAlign()==RS2::HAlignCenter) {
- attachmentPoint=2;
- } else if (d->getHAlign()==RS2::HAlignRight) {
- attachmentPoint=3;
- }
- if (d->getVAlign()==RS2::VAlignTop) {
- attachmentPoint+=0;
- } else if (d->getVAlign()==RS2::VAlignMiddle) {
- attachmentPoint+=3;
- } else if (d->getVAlign()==RS2::VAlignBottom) {
- attachmentPoint+=6;
- }
-
- switch (d->rtti()) {
- case RS2::EntityDimAligned:
- type = 1;
- break;
- case RS2::EntityDimLinear:
- type = 0;
- break;
- case RS2::EntityDimRadial:
- type = 4;
- break;
- case RS2::EntityDimDiametric:
- type = 3;
- break;
- default:
- type = 0;
- break;
- }
-
- DL_DimensionData dimData(d->getDefinitionPoint().x,
- d->getDefinitionPoint().y,
- 0.0,
- d->getMiddleOfText().x,
- d->getMiddleOfText().y,
- 0.0,
- type,
- attachmentPoint,
- d->getLineSpacingStyle(),
- d->getLineSpacingFactor(),
- (const char*)toDxfString(
- d->getText()).toLocal8Bit(),
- (const char*)d->getStyle().toLocal8Bit(),
- d->getAngle());
-
- if (d->rtti()==RS2::EntityDimAligned) {
- DimAligned* da = (DimAligned*)d;
-
- DL_DimAlignedData dimAlignedData(da->getExtensionPoint1().x,
- da->getExtensionPoint1().y,
- 0.0,
- da->getExtensionPoint2().x,
- da->getExtensionPoint2().y,
- 0.0);
-
- dxf.writeDimAligned(dw, dimData, dimAlignedData, attrib);
- } else if (d->rtti()==RS2::EntityDimLinear) {
- DimLinear* dl = (DimLinear*)d;
-
- DL_DimLinearData dimLinearData(dl->getExtensionPoint1().x,
- dl->getExtensionPoint1().y,
- 0.0,
- dl->getExtensionPoint2().x,
- dl->getExtensionPoint2().y,
- 0.0,
- dl->getAngle(),
- dl->getOblique());
-
- dxf.writeDimLinear(dw, dimData, dimLinearData, attrib);
- } else if (d->rtti()==RS2::EntityDimRadial) {
- DimRadial* dr = (DimRadial*)d;
-
- DL_DimRadialData dimRadialData(dr->getDefinitionPoint().x,
- dr->getDefinitionPoint().y,
- 0.0,
- dr->getLeader());
-
- dxf.writeDimRadial(dw, dimData, dimRadialData, attrib);
- } else if (d->rtti()==RS2::EntityDimDiametric) {
- DimDiametric* dr = (DimDiametric*)d;
-
- DL_DimDiametricData dimDiametricData(dr->getDefinitionPoint().x,
- dr->getDefinitionPoint().y,
- 0.0,
- dr->getLeader());
-
- dxf.writeDimDiametric(dw, dimData, dimDiametricData, attrib);
- } else if (d->rtti()==RS2::EntityDimAngular) {
- DimAngular* da = (DimAngular*)d;
-
- DL_DimAngularData dimAngularData(da->getDefinitionPoint1().x,
- da->getDefinitionPoint1().y,
- 0.0,
- da->getDefinitionPoint2().x,
- da->getDefinitionPoint2().y,
- 0.0,
- da->getDefinitionPoint3().x,
- da->getDefinitionPoint3().y,
- 0.0,
- da->getDefinitionPoint4().x,
- da->getDefinitionPoint4().y,
- 0.0);
-
- dxf.writeDimAngular(dw, dimData, dimAngularData, attrib);
- }
-
-}
-
-
-void FilterDXF::writeLeader(DL_WriterA& dw, Leader* l,
- const DL_Attributes& attrib) {
- if (l->count()>0) {
- dxf.writeLeader(
- dw,
- DL_LeaderData(l->hasArrowHead(),
- 0,
- 3,
- 0,
- 0,
- 1.0,
- 10.0,
- l->count()),
- attrib);
- bool first = true;
- for (Entity* v=l->firstEntity(RS2::ResolveNone);
- v!=NULL;
- v=l->nextEntity(RS2::ResolveNone)) {
-
- // Write line verties:
- if (v->rtti()==RS2::EntityLine) {
- Line* l = (Line*)v;
- if (first) {
- dxf.writeLeaderVertex(
- dw,
- DL_LeaderVertexData(l->getStartpoint().x,
- l->getStartpoint().y,
- 0.0));
- first = false;
- }
- dxf.writeLeaderVertex(
- dw,
- DL_LeaderVertexData(l->getEndpoint().x,
- l->getEndpoint().y,
- 0.0));
- }
- }
- } else {
- DEBUG->print(Debug::D_WARNING,
- "dropping leader with no vertices");
- }
-}
-
-
-void FilterDXF::writeHatch(DL_WriterA& dw, Hatch* h,
- const DL_Attributes& attrib) {
-
- // split hatch into atomic entities:
- if (dxf.getVersion()==VER_R12) {
- writeAtomicEntities(dw, h, attrib, RS2::ResolveAll);
- return;
- }
-
- bool writeIt = true;
- if (h->countLoops()>0) {
- // check if all of the loops contain entities:
- for (Entity* l=h->firstEntity(RS2::ResolveNone);
- l!=NULL;
- l=h->nextEntity(RS2::ResolveNone)) {
-
- if (l->isContainer() && !l->getFlag(RS2::FlagTemp)) {
- if (l->count()==0) {
- writeIt = false;
- }
- }
- }
- } else {
- writeIt = false;
- }
-
- if (!writeIt) {
- DEBUG->print(Debug::D_WARNING,
- "FilterDXF::writeHatch: Dropping Hatch");
- } else {
- DL_HatchData data(h->countLoops(),
- h->isSolid(),
- h->getScale(),
- h->getAngle(),
- (const char*)h->getPattern().toLocal8Bit());
- dxf.writeHatch1(dw, data, attrib);
-
- for (Entity* l=h->firstEntity(RS2::ResolveNone);
- l!=NULL;
- l=h->nextEntity(RS2::ResolveNone)) {
-
- // Write hatch loops:
- if (l->isContainer() && !l->getFlag(RS2::FlagTemp)) {
- EntityContainer* loop = (EntityContainer*)l;
- DL_HatchLoopData lData(loop->count());
- dxf.writeHatchLoop1(dw, lData);
-
- for (Entity* ed=loop->firstEntity(RS2::ResolveNone);
- ed!=NULL;
- ed=loop->nextEntity(RS2::ResolveNone)) {
-
- // Write hatch loop edges:
- if (ed->rtti()==RS2::EntityLine) {
- Line* ln = (Line*)ed;
- dxf.writeHatchEdge(
- dw,
- DL_HatchEdgeData(ln->getStartpoint().x,
- ln->getStartpoint().y,
- ln->getEndpoint().x,
- ln->getEndpoint().y));
- } else if (ed->rtti()==RS2::EntityArc) {
- Arc* ar = (Arc*)ed;
- if (!ar->isReversed()) {
- dxf.writeHatchEdge(
- dw,
- DL_HatchEdgeData(ar->getCenter().x,
- ar->getCenter().y,
- ar->getRadius(),
- ar->getAngle1(),
- ar->getAngle2(),
- true));
- } else {
- dxf.writeHatchEdge(
- dw,
- DL_HatchEdgeData(ar->getCenter().x,
- ar->getCenter().y,
- ar->getRadius(),
- 2*M_PI-ar->getAngle1(),
- 2*M_PI-ar->getAngle2(),
- false));
- }
- } else if (ed->rtti()==RS2::EntityCircle) {
- Circle* ci = (Circle*)ed;
- dxf.writeHatchEdge(
- dw,
- DL_HatchEdgeData(ci->getCenter().x,
- ci->getCenter().y,
- ci->getRadius(),
- 0.0,
- 2*M_PI,
- true));
- }
- }
- dxf.writeHatchLoop2(dw, lData);
- }
- }
- dxf.writeHatch2(dw, data, attrib);
- }
-
-}
-
-
-
-void FilterDXF::writeSolid(DL_WriterA& dw, Solid* s,
- const DL_Attributes& attrib) {
-
- // split solid into line entities:
- //if (dxf.getVersion()==VER_R12) {
- for (int i=0; i<3; ++i) {
- dxf.writeLine(
- dw,
- DL_LineData(s->getCorner(i).x,
- s->getCorner(i).y,
- 0.0,
- s->getCorner((i+1)%3).x,
- s->getCorner((i+1)%3).y,
- 0.0),
- attrib);
- }
- //return;
- //}
-}
-
-
-void FilterDXF::writeImage(DL_WriterA& dw, Image* i,
- const DL_Attributes& attrib) {
- int handle = dxf.writeImage(
- dw,
- DL_ImageData(std::string(""),
- i->getInsertionPoint().x,
- i->getInsertionPoint().y,
- 0.0,
- i->getUVector().x,
- i->getUVector().y,
- 0.0,
- i->getVVector().x,
- i->getVVector().y,
- 0.0,
- i->getWidth(),
- i->getHeight(),
- i->getBrightness(),
- i->getContrast(),
- i->getFade()),
- attrib);
- i->setHandle(handle);
-}
-
-
-
-void FilterDXF::writeEntityContainer(DL_WriterA& dw, EntityContainer* con,
- const DL_Attributes& /*attrib*/) {
- QString blkName;
- blkName = "__CE";
-
- // Creating an unique ID from the element ID
- int tmp, c=1; // tmp = temporary var c = counter var
- tmp = con->getId();
-
- while (true) {
- tmp = tmp/c;
- blkName.append((char) tmp %10 + 48);
- c *= 10;
- if (tmp < 10) {
- break;
- }
- }
-
- //Block definition
- dw.sectionTables();
- dxf.writeBlockRecord(dw);
- dw.dxfString( 0, "BLOCK_RECORD");
-
- dw.handle();
- dw.dxfHex(330, 1);
- dw.dxfString(100, "AcDbSymbolTableRecord");
- dw.dxfString(100, "AcDbBlockTableRecord");
- dw.dxfString( 2, blkName.toLatin1());
- dw.dxfHex(340, 0);
- dw.dxfString(0, "ENDTAB");
-
- //Block creation
- BlockData blkdata(blkName, Vector(0,0), false);
-
- Block* blk = new Block(graphic, blkdata);
-
- for (Entity* e1 = con->firstEntity(); e1 != NULL;
- e1 = con->nextEntity() ) {
- blk->addEntity(e1);
- }
- writeBlock(dw, blk);
- //delete e1;
-
-}
-
-
-
-/**
- * Writes the atomic entities of the given cotnainer to the file.
- */
-void FilterDXF::writeAtomicEntities(DL_WriterA& dw, EntityContainer* c,
- const DL_Attributes& attrib,
- RS2::ResolveLevel level) {
-
- for (Entity* e=c->firstEntity(level);
- e!=NULL;
- e=c->nextEntity(level)) {
-
- writeEntity(dw, e, attrib);
- }
-}
-
-/**
- * Writes an IMAGEDEF object into an OBJECT section.
- */
-void FilterDXF::writeImageDef(DL_WriterA& dw, Image* i) {
- if (i==NULL || i->getFlag(RS2::FlagUndone)) {
- return;
- }
-
- dxf.writeImageDef(
- dw,
- i->getHandle(),
- DL_ImageData((const char*)i->getFile().toLocal8Bit(),
- i->getInsertionPoint().x,
- i->getInsertionPoint().y,
- 0.0,
- i->getUVector().x,
- i->getUVector().y,
- 0.0,
- i->getVVector().x,
- i->getVVector().y,
- 0.0,
- i->getWidth(),
- i->getHeight(),
- i->getBrightness(),
- i->getContrast(),
- i->getFade()));
-}
-
-
-
-/**
- * Sets the entities attributes according to the attributes
- * that come from a DXF file.
- */
-void FilterDXF::setEntityAttributes(Entity* entity,
- const DL_Attributes& attrib) {
- DEBUG->print("FilterDXF::setEntityAttributes");
-
- Pen pen;
- pen.setColor(Qt::black);
- pen.setLineType(RS2::SolidLine);
-
- // Layer:
- if (attrib.getLayer().empty()) {
- entity->setLayer("0");
- } else {
- // add layer in case it doesn't exist:
- if (graphic->findLayer(attrib.getLayer().c_str())==NULL) {
- addLayer(DL_LayerData(attrib.getLayer(), 0));
- }
- entity->setLayer(attrib.getLayer().c_str());
- }
-
- // Color:
- pen.setColor(numberToColor(attrib.getColor()));
-
- // Linetype:
- pen.setLineType(nameToLineType(attrib.getLineType().c_str()));
-
- // Width:
- pen.setWidth(numberToWidth(attrib.getWidth()));
-
- entity->setPen(pen);
- DEBUG->print("FilterDXF::setEntityAttributes: OK");
-}
-
-/**
- * Gets the entities attributes as a DL_Attributes object.
- */
-DL_Attributes FilterDXF::getEntityAttributes(Entity * entity)
-{
- // Layer:
- Layer * layer = entity->getLayer();
- QString layerName;
-
- if (layer != NULL)
- layerName = layer->getName();
- else
- layerName = "NULL";
-
- Pen pen = entity->getPen(false);
-
- // Color:
- int color = colorToNumber(pen.getColor());
- //printf("Color is: %s -> %d\n", pen.getColor().name().toLatin1(), color);
-
- // Linetype:
- QString lineType = lineTypeToName(pen.getLineType());
-
- // Width:
- int width = widthToNumber(pen.getWidth());
-
- DL_Attributes attrib(layerName.toLatin1().data(), color, width, lineType.toLatin1().data());
-
- return attrib;
-}
-
-/**
- * @return Pen with the same attributes as 'attrib'.
- */
-Pen FilterDXF::attributesToPen(const DL_Attributes & attrib) const
-{
- /*
- printf("converting Color %d to %s\n",
- attrib.getColor(), numberToColor(attrib.getColor()).name().toLatin1());
- */
-
- Pen pen(numberToColor(attrib.getColor()),
- numberToWidth(attrib.getWidth()),
- nameToLineType(attrib.getLineType().c_str()));
- return pen;
-}
-
-
-
-/**
- * Converts a color index (num) into a Color object.
- * Please refer to the dxflib documentation for details.
- *
- * @param num Color number.
- * @param comp Compatibility with older QCad versions (1.5.3 and older)
- */
-Color FilterDXF::numberToColor(int num, bool comp) {
- // Compatibility with QCad 1.5.3 and older:
- if (comp) {
- switch(num) {
- case 0:
- return Qt::black;
- break;
- case 1:
- return Qt::darkBlue;
- break;
- case 2:
- return Qt::darkGreen;
- break;
- case 3:
- return Qt::darkCyan;
- break;
- case 4:
- return Qt::darkRed;
- break;
- case 5:
- return Qt::darkMagenta;
- break;
- case 6:
- return Qt::darkYellow;
- break;
- case 7:
- return Qt::lightGray;
- break;
- case 8:
- return Qt::darkGray;
- break;
- case 9:
- return Qt::blue;
- break;
- case 10:
- return Qt::green;
- break;
- case 11:
- return Qt::cyan;
- break;
- case 12:
- return Qt::red;
- break;
- case 13:
- return Qt::magenta;
- break;
- case 14:
- return Qt::yellow;
- break;
- case 15:
- return Qt::black;
- break;
- default:
- break;
- }
- } else {
- if (num==0) {
- return Color(RS2::FlagByBlock);
- } else if (num==256) {
- return Color(RS2::FlagByLayer);
- } else if (num<=255 && num>=0) {
- return Color((int)(dxfColors[num][0]*255),
- (int)(dxfColors[num][1]*255),
- (int)(dxfColors[num][2]*255));
- } else {
- DEBUG->print(Debug::D_WARNING,
- "FilterDXF::numberToColor: Invalid color number given.");
- return Color(RS2::FlagByLayer);
- }
- }
- return Color();
-}
-
-
-
-/**
- * Converts a color into a color number in the DXF palette.
- * The color that fits best is chosen.
- */
-int FilterDXF::colorToNumber(const Color& col) {
-
- //printf("Searching color for %s\n", col.name().toLatin1());
-
- // Special color BYBLOCK:
- if (col.getFlag(RS2::FlagByBlock)) {
- return 0;
- }
-
- // Special color BYLAYER
- else if (col.getFlag(RS2::FlagByLayer)) {
- return 256;
- }
-
- // Special color black is not in the table but white represents both
- // black and white
- else if (col.red()==0 && col.green()==0 && col.blue()==0) {
- return 7;
- }
-
- // All other colors
- else {
- int num=0;
- int diff=255*3; // smallest difference to a color in the table found so far
-
- // Run through the whole table and compare
- for (int i=1; i<=255; i++) {
- int d = abs(col.red()-(int)(dxfColors[i][0]*255))
- + abs(col.green()-(int)(dxfColors[i][1]*255))
- + abs(col.blue()-(int)(dxfColors[i][2]*255));
-
- if (d<diff) {
- /*
- printf("color %f,%f,%f is closer\n",
- dxfColors[i][0],
- dxfColors[i][1],
- dxfColors[i][2]);
- */
- diff = d;
- num = i;
- if (d==0) {
- break;
- }
- }
- }
- //printf(" Found: %d, diff: %d\n", num, diff);
- return num;
- }
-}
-
-/**
- * Converts a line type name (e.g. "CONTINUOUS") into a RS2::LineType
- * object.
- */
-RS2::LineType FilterDXF::nameToLineType(const QString & name)
-{
- QString uName = name.toUpper();
-
- // Standard linetypes for QCad II / AutoCAD
- if (uName.isEmpty() || uName == "BYLAYER")
- return RS2::LineByLayer;
- else if (uName == "BYBLOCK")
- return RS2::LineByBlock;
- else if (uName == "CONTINUOUS" || uName == "ACAD_ISO01W100")
- return RS2::SolidLine;
- else if (uName == "ACAD_ISO07W100" || uName == "DOT")
- return RS2::DotLine;
- else if (uName == "DOT2")
- return RS2::DotLine2;
- else if (uName == "DOTX2")
- return RS2::DotLineX2;
- else if (uName == "ACAD_ISO02W100" || uName == "ACAD_ISO03W100"
- || uName == "DASHED" || uName == "HIDDEN")
- return RS2::DashLine;
- else if (uName == "DASHED2" || uName == "HIDDEN2")
- return RS2::DashLine2;
- else if (uName == "DASHEDX2" || uName == "HIDDENX2")
- return RS2::DashLineX2;
- else if (uName == "ACAD_ISO10W100" || uName == "DASHDOT")
- return RS2::DashDotLine;
- else if (uName == "DASHDOT2")
- return RS2::DashDotLine2;
- else if (uName == "ACAD_ISO04W100" || uName == "DASHDOTX2")
- return RS2::DashDotLineX2;
- else if (uName == "ACAD_ISO12W100" || uName == "DIVIDE")
- return RS2::DivideLine;
- else if (uName == "DIVIDE2")
- return RS2::DivideLine2;
- else if (uName == "ACAD_ISO05W100" || uName == "DIVIDEX2")
- return RS2::DivideLineX2;
- else if (uName == "CENTER")
- return RS2::CenterLine;
- else if (uName == "CENTER2")
- return RS2::CenterLine2;
- else if (uName == "CENTERX2")
- return RS2::CenterLineX2;
- else if (uName == "BORDER")
- return RS2::BorderLine;
- else if (uName == "BORDER2")
- return RS2::BorderLine2;
- else if (uName == "BORDERX2")
- return RS2::BorderLineX2;
-
- return RS2::SolidLine;
-}
-
-/**
- * Converts a LineType into a name for a line type.
- */
-QString FilterDXF::lineTypeToName(RS2::LineType lineType)
-{
- // Standard linetypes for QCad II / AutoCAD
- switch (lineType)
- {
- case RS2::SolidLine:
- return "CONTINUOUS";
- break;
-
- case RS2::DotLine:
- return "DOT";
- break;
- case RS2::DotLine2:
- return "DOT2";
- break;
- case RS2::DotLineX2:
- return "DOTX2";
- break;
-
- case RS2::DashLine:
- return "DASHED";
- break;
- case RS2::DashLine2:
- return "DASHED2";
- break;
- case RS2::DashLineX2:
- return "DASHEDX2";
- break;
-
- case RS2::DashDotLine:
- return "DASHDOT";
- break;
- case RS2::DashDotLine2:
- return "DASHDOT2";
- break;
- case RS2::DashDotLineX2:
- return "DASHDOTX2";
- break;
-
- case RS2::DivideLine:
- return "DIVIDE";
- break;
- case RS2::DivideLine2:
- return "DIVIDE2";
- break;
- case RS2::DivideLineX2:
- return "DIVIDEX2";
- break;
-
- case RS2::CenterLine:
- return "CENTER";
- break;
- case RS2::CenterLine2:
- return "CENTER2";
- break;
- case RS2::CenterLineX2:
- return "CENTERX2";
- break;
-
- case RS2::BorderLine:
- return "BORDER";
- break;
- case RS2::BorderLine2:
- return "BORDER2";
- break;
- case RS2::BorderLineX2:
- return "BORDERX2";
- break;
-
-
- case RS2::LineByLayer:
- return "ByLayer";
- break;
- case RS2::LineByBlock:
- return "ByBlock";
- break;
- default:
- break;
- }
-
- return "CONTINUOUS";
-}
-
-
-
-/**
- * Converts a LineType into a name for a line type.
- */
-/*QString FilterDXF::lineTypeToDescription(RS2::LineType lineType) {
-
- // Standard linetypes for QCad II / AutoCAD
- switch (lineType) {
- case RS2::SolidLine:
- return "Solid line";
- case RS2::DotLine:
- return "ISO Dashed __ __ __ __ __ __ __ __ __ __ _";
- case RS2::DashLine:
- return "ISO Dashed with Distance __ __ __ _";
- case RS2::DashDotLine:
- return "ISO Long Dashed Dotted ____ . ____ . __";
- case RS2::DashDotDotLine:
- return "ISO Long Dashed Double Dotted ____ .. __";
- case RS2::LineByLayer:
- return "";
- case RS2::LineByBlock:
- return "";
- default:
- break;
- }
-
- return "CONTINUOUS";
-}*/
-
-
-
-/**
- * Converts a line width number (e.g. 1) into a RS2::LineWidth.
- */
-RS2::LineWidth FilterDXF::numberToWidth(int num) {
- switch (num) {
- case -1:
- return RS2::WidthByLayer;
- break;
- case -2:
- return RS2::WidthByBlock;
- break;
- case -3:
- return RS2::WidthDefault;
- break;
- default:
- if (num<3) {
- return RS2::Width00;
- } else if (num<7) {
- return RS2::Width01;
- } else if (num<11) {
- return RS2::Width02;
- } else if (num<14) {
- return RS2::Width03;
- } else if (num<16) {
- return RS2::Width04;
- } else if (num<19) {
- return RS2::Width05;
- } else if (num<22) {
- return RS2::Width06;
- } else if (num<27) {
- return RS2::Width07;
- } else if (num<32) {
- return RS2::Width08;
- } else if (num<37) {
- return RS2::Width09;
- } else if (num<45) {
- return RS2::Width10;
- } else if (num<52) {
- return RS2::Width11;
- } else if (num<57) {
- return RS2::Width12;
- } else if (num<65) {
- return RS2::Width13;
- } else if (num<75) {
- return RS2::Width14;
- } else if (num<85) {
- return RS2::Width15;
- } else if (num<95) {
- return RS2::Width16;
- } else if (num<103) {
- return RS2::Width17;
- } else if (num<112) {
- return RS2::Width18;
- } else if (num<130) {
- return RS2::Width19;
- } else if (num<149) {
- return RS2::Width20;
- } else if (num<180) {
- return RS2::Width21;
- } else if (num<205) {
- return RS2::Width22;
- } else {
- return RS2::Width23;
- }
- break;
- }
- return (RS2::LineWidth)num;
-}
-
-
-
-/**
- * Converts a RS2::LineWidth into an int width.
- */
-int FilterDXF::widthToNumber(RS2::LineWidth width) {
- switch (width) {
- case RS2::WidthByLayer:
- return -1;
- break;
- case RS2::WidthByBlock:
- return -2;
- break;
- case RS2::WidthDefault:
- return -3;
- break;
- default:
- return (int)width;
- break;
- }
- return (int)width;
-}
-
-/**
- * Converts a native unicode string into a DXF encoded string.
- *
- * DXF endoding includes the following special sequences:
- * - %%%c for a diameter sign
- * - %%%d for a degree sign
- * - %%%p for a plus/minus sign
- */
-QString FilterDXF::toDxfString(const QString & string)
-{
- /*
- QString res = string;
- // Line feed:
- res = res.replace(QRegExp("\\n"), "\\P");
- // Space:
- res = res.replace(QRegExp(" "), "\\~");
- // diameter:
- res = res.replace(QChar(0x2205), "%%c");
- // degree:
- res = res.replace(QChar(0x00B0), "%%d");
- // plus/minus
- res = res.replace(QChar(0x00B1), "%%p");
- */
-
- QString res = "";
-
- for(int i=0; i<string.length(); ++i)
- {
- int c = string.at(i).unicode();
- switch (c)
- {
- case 0x0A:
- res += "\\P";
- break;
- case 0x20:
- res += "\\~";
- break;
- // diameter:
- case 0x2205:
- res += "%%c";
- break;
- // degree:
- case 0x00B0:
- res += "%%d";
- break;
- // plus/minus
- case 0x00B1:
- res += "%%p";
- break;
- default:
- if (c > 127)
- {
- QString hex;
- hex = QString("%1").arg(c, 4, 16);
- hex = hex.replace(' ', '0');
- res += QString("\\U+%1").arg(hex);
- }
- else
- res += string.at(i);
-
- break;
- }
- }
-
- return res;
-}
-
-/**
- * Converts a DXF encoded string into a native Unicode string.
- */
-QString FilterDXF::toNativeString(const QString & string)
-{
- QString res = string;
- // Line feed:
- res = res.replace(QRegExp("\\\\P"), "\n");
- // Space:
- res = res.replace(QRegExp("\\\\~"), " ");
- // diameter:
- res = res.replace(QRegExp("%%c"), QChar(0x2205));
- // degree:
- res = res.replace(QRegExp("%%d"), QChar(0x00B0));
- // plus/minus
- res = res.replace(QRegExp("%%p"), QChar(0x00B1));
-
- // Unicode characters:
- QString cap = "";
- int uCode = 0;
- bool ok = false;
-
- do
- {
- QRegExp regexp("\\\\U\\+[0-9A-Fa-f]{4,4}");
-// regexp.search(res);
- regexp.indexIn(res);
- cap = regexp.cap();
-
- if (!cap.isNull())
- {
- uCode = cap.right(4).toInt(&ok, 16);
- // workaround for Qt 3.0.x:
- res.replace(QRegExp("\\\\U\\+" + cap.right(4)), QChar(uCode));
- // for Qt 3.1:
- //res.replace(cap, QChar(uCode));
- }
- }
- while (!cap.isNull());
-
- // ASCII code:
- cap = "";
- uCode = 0;
- ok = false;
-
- do
- {
- QRegExp regexp("%%[0-9]{3,3}");
-// regexp.search(res);
- regexp.indexIn(res);
- cap = regexp.cap();
-
- if (!cap.isNull())
- {
- uCode = cap.right(3).toInt(&ok, 10);
- // workaround for Qt 3.0.x:
- res.replace(QRegExp("%%" + cap.right(3)), QChar(uCode));
- // for Qt 3.1:
- //res.replace(cap, QChar(uCode));
- }
- }
- while (!cap.isNull());
-
- // Ignore font tags:
- res = res.replace(QRegExp("\\\\f[0-9A-Za-z| ]{0,};"), "");
-
- // Ignore {}
- res = res.replace("\\{", "#curly#");
- res = res.replace("{", "");
- res = res.replace("#curly#", "{");
-
- res = res.replace("\\}", "#curly#");
- res = res.replace("}", "");
- res = res.replace("#curly#", "}");
-
- DEBUG->print("FilterDXF::toNativeString:");
- DEBUG->printUnicode(res);
- return res;
-}
-
-/**
- * Converts the given number from a DXF file into an AngleFormat enum.
- *
- * @param num $DIMAUNIT from DXF (0: decimal deg, 1: deg/min/sec, 2: gradians,
- * 3: radians, 4: surveyor's units)
- *
- * @ret Matching AngleFormat enum value.
- */
-RS2::AngleFormat FilterDXF::numberToAngleFormat(int num) {
-
- RS2::AngleFormat af;
-
- switch (num) {
- default:
- case 0:
- af = RS2::DegreesDecimal;
- break;
- case 1:
- af = RS2::DegreesMinutesSeconds;
- break;
- case 2:
- af = RS2::Gradians;
- break;
- case 3:
- af = RS2::Radians;
- break;
- case 4:
- af = RS2::Surveyors;
- break;
- }
-
- return af;
-}
-
-
-/**
- * Converts AngleFormat enum to DXF number.
- */
-int FilterDXF::angleFormatToNumber(RS2::AngleFormat af) {
-
- int num;
-
- switch (af) {
- default:
- case RS2::DegreesDecimal:
- num = 0;
- break;
- case RS2::DegreesMinutesSeconds:
- num = 1;
- break;
- case RS2::Gradians:
- num = 2;
- break;
- case RS2::Radians:
- num = 3;
- break;
- case RS2::Surveyors:
- num = 4;
- break;
- }
-
- return num;
-}
-
-
-
-/**
- * converts a DXF unit setting (e.g. INSUNITS) to a unit enum.
- */
-RS2::Unit FilterDXF::numberToUnit(int num) {
- switch (num) {
- default:
- case 0:
- return RS2::None;
- break;
- case 1:
- return RS2::Inch;
- break;
- case 2:
- return RS2::Foot;
- break;
- case 3:
- return RS2::Mile;
- break;
- case 4:
- return RS2::Millimeter;
- break;
- case 5:
- return RS2::Centimeter;
- break;
- case 6:
- return RS2::Meter;
- break;
- case 7:
- return RS2::Kilometer;
- break;
- case 8:
- return RS2::Microinch;
- break;
- case 9:
- return RS2::Mil;
- break;
- case 10:
- return RS2::Yard;
- break;
- case 11:
- return RS2::Angstrom;
- break;
- case 12:
- return RS2::Nanometer;
- break;
- case 13:
- return RS2::Micron;
- break;
- case 14:
- return RS2::Decimeter;
- break;
- case 15:
- return RS2::Decameter;
- break;
- case 16:
- return RS2::Hectometer;
- break;
- case 17:
- return RS2::Gigameter;
- break;
- case 18:
- return RS2::Astro;
- break;
- case 19:
- return RS2::Lightyear;
- break;
- case 20:
- return RS2::Parsec;
- break;
- }
-
- return RS2::None;
-}
-
-
-
-/**
- * Converst a unit enum into a DXF unit number e.g. for INSUNITS.
- */
-int FilterDXF::unitToNumber(RS2::Unit unit) {
- switch (unit) {
- default:
- case RS2::None:
- return 0;
- break;
- case RS2::Inch:
- return 1;
- break;
- case RS2::Foot:
- return 2;
- break;
- case RS2::Mile:
- return 3;
- break;
- case RS2::Millimeter:
- return 4;
- break;
- case RS2::Centimeter:
- return 5;
- break;
- case RS2::Meter:
- return 6;
- break;
- case RS2::Kilometer:
- return 7;
- break;
- case RS2::Microinch:
- return 8;
- break;
- case RS2::Mil:
- return 9;
- break;
- case RS2::Yard:
- return 10;
- break;
- case RS2::Angstrom:
- return 11;
- break;
- case RS2::Nanometer:
- return 12;
- break;
- case RS2::Micron:
- return 13;
- break;
- case RS2::Decimeter:
- return 14;
- break;
- case RS2::Decameter:
- return 15;
- break;
- case RS2::Hectometer:
- return 16;
- break;
- case RS2::Gigameter:
- return 17;
- break;
- case RS2::Astro:
- return 18;
- break;
- case RS2::Lightyear:
- return 19;
- break;
- case RS2::Parsec:
- return 20;
- break;
- }
-
- return 0;
-}
-
-
-
-/**
- * Checks if the given variable is two-dimensional (e.g. $LIMMIN).
- */
-bool FilterDXF::isVariableTwoDimensional(const QString& var) {
- if (var=="$LIMMIN" ||
- var=="$LIMMAX" ||
- var=="$PLIMMIN" ||
- var=="$PLIMMAX" ||
- var=="$GRIDUNIT" ||
- var=="$VIEWCTR") {
-
- return true;
- } else {
- return false;
- }
-}
-
-// EOF
-