mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-07 20:34:14 +02:00
c3ed2daca8
With "DXF : symboles en blocs" ticked in the export dialog, or --dxf-blocks on the command line, each symbol definition a folio uses is written once as a DXF block and every placed symbol as an INSERT of it. A CAD program then selects, counts and replaces a symbol as one object. The block is drawn by the same code as a symbol drawn in full, as if the symbol sat unturned at the folio's origin, which is DXF (0, sheetHeight): that is the block's base point, so the INSERT carries the symbol's position and quarter-turn and nothing else. Blocks have to come before any entity, so the export collects them first and dxfBegin() writes them in its BLOCKS section. Entities in a block keep their own layers. Off by default; with it off the file is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1217 lines
38 KiB
C++
1217 lines
38 KiB
C++
/*
|
|
Copyright 2006-2026 The QElectroTech Team
|
|
This file is part of QElectroTech.
|
|
|
|
QElectroTech 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.
|
|
|
|
QElectroTech 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 QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "createdxf.h"
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QMessageBox>
|
|
#include <QString>
|
|
#include "dxfexport.h"
|
|
|
|
#include <QtMath>
|
|
#include <cmath>
|
|
|
|
|
|
const double Createdxf::sheetWidth = 4000;
|
|
const double Createdxf::sheetHeight = 2700;
|
|
|
|
double Createdxf::xScale = 1;
|
|
|
|
namespace {
|
|
/// @p text on one line. A DXF value ends at the line break, so a break
|
|
/// inside a text would shift every group code after it by one line and
|
|
/// a reader would take values for codes (FINDINGS F052). Callers that
|
|
/// mean several lines split them first; this is the safety net.
|
|
QString singleLine(QString text)
|
|
{
|
|
text.replace(QLatin1String("\r\n"), QLatin1String(" "));
|
|
text.replace(QLatin1Char('\r'), QLatin1Char(' '));
|
|
text.replace(QLatin1Char('\n'), QLatin1Char(' '));
|
|
return text;
|
|
}
|
|
|
|
/// Colour code of an entity. 0 is BYBLOCK, which means nothing outside a
|
|
/// block and so fell back to the default colour; it is also what black
|
|
/// maps to (RGBcodeTable[0]). BYLAYER (256) looks the same, the layers
|
|
/// being colour 7, and lets a CAD user recolour a whole layer at once
|
|
/// (discussion #1071). Real colours are kept.
|
|
int entityColour(int colour)
|
|
{
|
|
return colour == 0 ? 256 : colour;
|
|
}
|
|
}
|
|
double Createdxf::yScale = 1;
|
|
QString Createdxf::layer = QStringLiteral("0");
|
|
|
|
Createdxf::Createdxf()
|
|
{
|
|
}
|
|
|
|
Createdxf::~Createdxf()
|
|
{
|
|
}
|
|
|
|
/* Header section of every DXF file.
|
|
@param layers : the layers the entities will be written on, declared in
|
|
the LAYER table beside layer "0", which every DXF has. */
|
|
/**
|
|
@brief Createdxf::dxfBegin
|
|
Write the header, the tables with @a layers, and the BLOCKS section,
|
|
then open the ENTITIES section. @a writeBlocks, if given, is called
|
|
inside the BLOCKS section to write the block definitions
|
|
(dxfBlockBegin(), the entities, dxfBlockEnd()): a block has to be
|
|
defined before any entity, so before anything is drawn.
|
|
*/
|
|
void Createdxf::dxfBegin (const QString& fileName, const QStringList &layers,
|
|
const std::function<void()> &writeBlocks)
|
|
{
|
|
layer = QStringLiteral("0");
|
|
|
|
// Creation of an output stream object in text mode.
|
|
// Header section of every dxf file.
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::WriteOnly)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setIcon(QMessageBox::Warning);
|
|
errorFileOpen.setText("Error: "+fileName+" Could Not be Opened.");
|
|
errorFileOpen.setInformativeText("Close all Files and Try Again.");
|
|
errorFileOpen.exec();
|
|
exit(0);
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
To_Dxf << 999 << "\r\n";
|
|
To_Dxf << "QET" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SECTION" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "HEADER" << "\r\n";
|
|
To_Dxf << 9 << "\r\n";
|
|
To_Dxf << "$ACADVER" << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << "AC1006" << "\r\n";
|
|
To_Dxf << 9 << "\r\n";
|
|
To_Dxf << "$INSBASE" << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 9 << "\r\n";
|
|
|
|
To_Dxf << "$EXTMIN" << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 9 << "\r\n";
|
|
To_Dxf << "$EXTMAX" << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << "4000.0" << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << "4000.0" << "\r\n";
|
|
|
|
To_Dxf << 9 << "\r\n";
|
|
To_Dxf << "$LIMMIN" << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << "0.0" << "\r\n";
|
|
To_Dxf << 9 << "\r\n";
|
|
To_Dxf << "$LIMMAX" << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << "4000.0" << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << "4000.0" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDSEC" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SECTION" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "TABLES" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "TABLE" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
|
|
To_Dxf << "VPORT" << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "VPORT" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "*ACTIVE" << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 11 << "\r\n";
|
|
To_Dxf << 1.0 << "\r\n";
|
|
To_Dxf << 21 << "\r\n";
|
|
To_Dxf << 1.0 << "\r\n";
|
|
To_Dxf << 12 << "\r\n";
|
|
To_Dxf << 2000 << "\r\n";
|
|
To_Dxf << 22 << "\r\n";
|
|
To_Dxf << 1350 << "\r\n";
|
|
To_Dxf << 13 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 23 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 14 << "\r\n";
|
|
To_Dxf << 1.0 << "\r\n";
|
|
To_Dxf << 24 << "\r\n";
|
|
To_Dxf << 1.0 << "\r\n";
|
|
To_Dxf << 15 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 25 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 16 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 26 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 36 << "\r\n";
|
|
To_Dxf << 1.0 << "\r\n";
|
|
To_Dxf << 17 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 27 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 37 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << 2732.5 << "\r\n";
|
|
To_Dxf << 41 << "\r\n";
|
|
To_Dxf << 2.558 << "\r\n";
|
|
To_Dxf << 42 << "\r\n";
|
|
To_Dxf << 50.0 << "\r\n";
|
|
To_Dxf << 43 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 44 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 51 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 71 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 72 << "\r\n";
|
|
To_Dxf << 100 << "\r\n";
|
|
To_Dxf << 73 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << 74 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << 75 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 76 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 77 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 78 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDTAB" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "TABLE" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
|
|
To_Dxf << "LTYPE" << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "LTYPE" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "CONTINUOUS" << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 64 << "\r\n";
|
|
To_Dxf << 3 << "\r\n";
|
|
To_Dxf << "Solid Line" << "\r\n";
|
|
To_Dxf << 72 << "\r\n";
|
|
To_Dxf << 65 << "\r\n";
|
|
To_Dxf << 73 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << 0.00 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
|
|
To_Dxf << "ENDTAB" << "\r\n";
|
|
|
|
// Layers: "0" plus the ones the entities use, all white/black
|
|
// (colour 7) and continuous, so a file looks the same as before
|
|
// until the user changes a layer.
|
|
QStringList all_layers{QStringLiteral("0")};
|
|
for (const QString &name : layers) {
|
|
if (!all_layers.contains(name))
|
|
all_layers << name;
|
|
}
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "TABLE" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "LAYER" << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << all_layers.size() << "\r\n";
|
|
for (const QString &name : std::as_const(all_layers)) {
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "LAYER" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << name << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << 7 << "\r\n";
|
|
To_Dxf << 6 << "\r\n";
|
|
To_Dxf << "CONTINUOUS" << "\r\n";
|
|
}
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDTAB" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDSEC" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SECTION" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "BLOCKS" << "\r\n";
|
|
file.close();
|
|
}
|
|
if (writeBlocks)
|
|
writeBlocks();
|
|
QFile entities(fileName);
|
|
if (entities.open(QFile::Append)) {
|
|
QTextStream To_Dxf(&entities);
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDSEC" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SECTION" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << "ENTITIES" << "\r\n";
|
|
entities.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::dxfBlockBegin
|
|
Start the definition of block @a name, with its base point at @a x,
|
|
@a y. Only inside dxfBegin()'s writeBlocks; every entity written until
|
|
dxfBlockEnd() belongs to the block.
|
|
@param hasAttributes : the block has attribute definitions
|
|
*/
|
|
void Createdxf::dxfBlockBegin(const QString &fileName,
|
|
const QString &name,
|
|
double x,
|
|
double y,
|
|
bool hasAttributes)
|
|
{
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append))
|
|
return;
|
|
QTextStream To_Dxf(&file);
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "BLOCK" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << "0" << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << name << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << (hasAttributes ? 2 : 0) << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << x << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n";
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
file.close();
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::dxfBlockEnd
|
|
End the block started by dxfBlockBegin().
|
|
*/
|
|
void Createdxf::dxfBlockEnd(const QString &fileName)
|
|
{
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append))
|
|
return;
|
|
QTextStream To_Dxf(&file);
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDBLK" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << "0" << "\r\n";
|
|
file.close();
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawInsert
|
|
Place block @a name at @a x, @a y, turned counter-clockwise by
|
|
@a rotation degrees, on the current layer, followed by its
|
|
@a attributes.
|
|
*/
|
|
void Createdxf::drawInsert(const QString &fileName,
|
|
const QString &name,
|
|
double x,
|
|
double y,
|
|
double rotation,
|
|
const QList<Attribute> &attributes)
|
|
{
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append))
|
|
return;
|
|
QTextStream To_Dxf(&file);
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "INSERT" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n";
|
|
if (!attributes.isEmpty()) {
|
|
To_Dxf << 66 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
}
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << name << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << x << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n";
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << rotation << "\r\n";
|
|
for (const Attribute &attribute : attributes) {
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ATTRIB" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n";
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(attribute.colour) << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << attribute.x << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << attribute.y << "\r\n";
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n";
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << attribute.height << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << singleLine(attribute.text) << "\r\n";
|
|
To_Dxf << 2 << "\r\n";
|
|
To_Dxf << attribute.tag << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << (attribute.invisible ? 1 : 0) << "\r\n";
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << attribute.rotation << "\r\n";
|
|
To_Dxf << 41 << "\r\n";
|
|
To_Dxf << attribute.xScaleW << "\r\n";
|
|
}
|
|
if (!attributes.isEmpty()) {
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SEQEND" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n";
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::blockName
|
|
@return @a name as a block or attribute name an R10 reader accepts:
|
|
upper case, only A-Z, 0-9, _, - and $, at most 31 characters
|
|
*/
|
|
QString Createdxf::blockName(const QString &name)
|
|
{
|
|
QString result;
|
|
for (const QChar c : name.toUpper()) {
|
|
const ushort u = c.unicode();
|
|
const bool ok = (u >= 'A' && u <= 'Z') || (u >= '0' && u <= '9')
|
|
|| u == '_' || u == '-' || u == '$';
|
|
result += ok ? c : QChar('_');
|
|
}
|
|
return result.left(31);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::dxfEnd
|
|
End Section of every DXF File
|
|
@param fileName
|
|
*/
|
|
void Createdxf::dxfEnd(const QString& fileName)
|
|
{
|
|
layer = QStringLiteral("0");
|
|
// Creation of an output stream object in text mode.
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ENDSEC" << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "EOF";
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawCircle
|
|
draw circle in dxf format
|
|
@param fileName
|
|
@param radius
|
|
@param x
|
|
@param y
|
|
@param colour
|
|
*/
|
|
void Createdxf::drawCircle(
|
|
const QString& fileName,
|
|
double radius,
|
|
double x,
|
|
double y,
|
|
int colour)
|
|
{
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the circle
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "CIRCLE" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(colour) << "\r\n"; // Colour Code
|
|
To_Dxf << 10 << "\r\n"; // XYZ is the Center point of circle
|
|
To_Dxf << x << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << radius << "\r\n"; // radius of circle
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawLine
|
|
draw line in DXF Format
|
|
@param fileName
|
|
@param x1
|
|
@param y1
|
|
@param x2
|
|
@param y2
|
|
@param colour
|
|
*/
|
|
void Createdxf::drawLine (
|
|
const QString &fileName,
|
|
double x1,
|
|
double y1,
|
|
double x2,
|
|
double y2,
|
|
const int &colour)
|
|
{
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the Line
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "LINE" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(colour) << "\r\n"; // Colour Code
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << x1 << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y1 << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 11 << "\r\n";
|
|
To_Dxf << x2 << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 21 << "\r\n";
|
|
To_Dxf << y2 << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 31 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
long Createdxf::RGBcodeTable[255]
|
|
{
|
|
0x000000, 0xff0000, 0xffff00, 0x00ff00, 0x00ffff,
|
|
0x0000ff, 0xff00ff, 0xffffff, 0x414141, 0x808080,
|
|
0xff0000, 0xffaaaa, 0xbd0000, 0xbd7e7e, 0x810000,
|
|
0x815656, 0x680000, 0x684545, 0x4f0000, 0x4f3535,
|
|
0xff3f00, 0xffbfaa, 0xbd2e00, 0xbd8d7e, 0x811f00,
|
|
0x816056, 0x681900, 0x684e45, 0x4f1300, 0x4f3b35,
|
|
0xff7f00, 0xffd4aa, 0xbd5e00, 0xbd9d7e, 0x814000,
|
|
0x816b56, 0x683400, 0x685645, 0x4f2700, 0x4f4235,
|
|
0xffbf00, 0xffeaaa, 0xbd8d00, 0xbdad7e, 0x816000,
|
|
0x817656, 0x684e00, 0x685f45, 0x4f3b00, 0x4f4935,
|
|
0xffff00, 0xffffaa, 0xbdbd00, 0xbdbd7e, 0x818100,
|
|
0x818156, 0x686800, 0x686845, 0x4f4f00, 0x4f4f35,
|
|
0xbfff00, 0xeaffaa, 0x8dbd00, 0xadbd7e, 0x608100,
|
|
0x768156, 0x4e6800, 0x5f6845, 0x3b4f00, 0x494f35,
|
|
0x7fff00, 0xd4ffaa, 0x5ebd00, 0x9dbd7e, 0x408100,
|
|
0x6b8156, 0x346800, 0x566845, 0x274f00, 0x424f35,
|
|
0x3fff00, 0xbfffaa, 0x2ebd00, 0x8dbd7e, 0x1f8100,
|
|
0x608156, 0x196800, 0x4e6845, 0x134f00, 0x3b4f35,
|
|
0x00ff00, 0xaaffaa, 0x00bd00, 0x7ebd7e, 0x008100,
|
|
0x568156, 0x006800, 0x456845, 0x004f00, 0x354f35,
|
|
0x00ff3f, 0xaaffbf, 0x00bd2e, 0x7ebd8d, 0x00811f,
|
|
0x568160, 0x006819, 0x45684e, 0x004f13, 0x354f3b,
|
|
0x00ff7f, 0xaaffd4, 0x00bd5e, 0x7ebd9d, 0x008140,
|
|
0x56816b, 0x006834, 0x456856, 0x004f27, 0x354f42,
|
|
0x00ffbf, 0xaaffea, 0x00bd8d, 0x7ebdad, 0x008160,
|
|
0x568176, 0x00684e, 0x45685f, 0x004f3b, 0x354f49,
|
|
0x00ffff, 0xaaffff, 0x00bdbd, 0x7ebdbd, 0x008181,
|
|
0x568181, 0x006868, 0x456868, 0x004f4f, 0x354f4f,
|
|
0x00bfff, 0xaaeaff, 0x008dbd, 0x7eadbd, 0x006081,
|
|
0x567681, 0x004e68, 0x455f68, 0x003b4f, 0x35494f,
|
|
0x007fff, 0xaad4ff, 0x005ebd, 0x7e9dbd, 0x004081,
|
|
0x566b81, 0x003468, 0x455668, 0x00274f, 0x35424f,
|
|
0x003fff, 0xaabfff, 0x002ebd, 0x7e8dbd, 0x001f81,
|
|
0x566081, 0x001968, 0x454e68, 0x00134f, 0x353b4f,
|
|
0x0000ff, 0xaaaaff, 0x0000bd, 0x7e7ebd, 0x000081,
|
|
0x565681, 0x000068, 0x454568, 0x00004f, 0x35354f,
|
|
0x3f00ff, 0xbfaaff, 0x2e00bd, 0x8d7ebd, 0x1f0081,
|
|
0x605681, 0x190068, 0x4e4568, 0x13004f, 0x3b354f,
|
|
0x7f00ff, 0xd4aaff, 0x5e00bd, 0x9d7ebd, 0x400081,
|
|
0x6b5681, 0x340068, 0x564568, 0x27004f, 0x42354f,
|
|
0xbf00ff, 0xeeaaff, 0x8d00bd, 0xad7ebd, 0x600081,
|
|
0x765681, 0x4e0068, 0x5f4568, 0x3b004f, 0x49354f,
|
|
0xff00ff, 0xffaaff, 0xbd00bd, 0xbd7ebd, 0x810081,
|
|
0x815681, 0x680068, 0x684568, 0x4f004f, 0x4f354f,
|
|
0xff00bf, 0xffaaea, 0xbd008d, 0xbd7ead, 0x810060,
|
|
0x815676, 0x68004e, 0x68455f, 0x4f003b, 0x4f3549,
|
|
0xff007f, 0xffaad4, 0xbd005e, 0xbd7e9d, 0x810040,
|
|
0x81566b, 0x680034, 0x684556, 0x4f0027, 0x4f3542,
|
|
0xff003f, 0xffaabf, 0xbd002e, 0xbd7e8d, 0x81001f,
|
|
0x815660, 0x680019, 0x68454e, 0x4f0013, 0x4f353b,
|
|
0x333333, 0x505050, 0x696969, 0x828282, 0xbebebe
|
|
};
|
|
|
|
/**
|
|
@brief Createdxf::getcolorCode
|
|
This function returns the ACI color which is the "nearest" color to
|
|
the color defined by the red, green and blue (RGB) values passed
|
|
in argument.
|
|
@param red
|
|
@param green
|
|
@param blue
|
|
*/
|
|
int Createdxf::getcolorCode (const long red, const long green, const long blue)
|
|
{
|
|
long acirgb, r,g,b;
|
|
long mindst = 2147483647L;
|
|
long dst = 0;
|
|
int minndx = 0;
|
|
for ( int i = 0; i < 254; i++ )
|
|
{
|
|
acirgb = RGBcodeTable[i];
|
|
b = ( acirgb & 0xffL );
|
|
g = ( acirgb & 0xff00L ) >> 8;
|
|
r = acirgb >> 16;
|
|
dst = abs ( r-red) + abs ( g -green) + abs (b-blue);
|
|
if ( dst < mindst )
|
|
{
|
|
minndx = i;
|
|
mindst = dst;
|
|
}
|
|
}
|
|
return minndx;
|
|
}
|
|
|
|
int Createdxf::dxfColor(QColor color) {
|
|
return Createdxf::getcolorCode(color.red(), color.green(), color.blue());
|
|
}
|
|
|
|
int Createdxf::dxfColor(QPen pen) {
|
|
return Createdxf::dxfColor(pen.color());
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawArcEllipse
|
|
Draw an arc of an ellipse, or a whole ellipse, in DXF units.
|
|
@param x, y : top left of the ellipse's bounding rect (y is the top, the
|
|
DXF Y axis going up)
|
|
@param w, h : width and height of that rect
|
|
@param startAngle, spanAngle : in degrees, as QPainter::drawArc() takes
|
|
them: counter-clockwise from 3 o'clock
|
|
@param hotspot_x, hotspot_y, rotation_angle : the whole shape is turned
|
|
clockwise by rotation_angle degrees around the hotspot, as a rotated
|
|
symbol is
|
|
A circle, or an arc of one, is written as one exact CIRCLE or ARC. R10,
|
|
the version this file declares, has no ELLIPSE entity, so a true
|
|
ellipse is written as a polyline through points of the curve, one every
|
|
5 degrees. It used to be four ARCs fitted through a point between the
|
|
curve and its chord, which drew every circle as a flattened diamond
|
|
(issue #1339).
|
|
*/
|
|
void Createdxf::drawArcEllipse(
|
|
const QString &file_path,
|
|
qreal x,
|
|
qreal y,
|
|
qreal w,
|
|
qreal h,
|
|
qreal startAngle,
|
|
qreal spanAngle,
|
|
qreal hotspot_x,
|
|
qreal hotspot_y,
|
|
qreal rotation_angle,
|
|
const int &colorcode)
|
|
{
|
|
if (qFuzzyIsNull(spanAngle) || w <= 0 || h <= 0)
|
|
return;
|
|
|
|
const qreal a = w/2;
|
|
const qreal b = h/2;
|
|
const QPointF center = DxfExport::rotation_transformed(
|
|
x + a, y - b, hotspot_x, hotspot_y, rotation_angle);
|
|
const bool full_turn = qAbs(spanAngle) >= 360;
|
|
|
|
if (qAbs(a - b) <= 1e-6 * qMax(a, b))
|
|
{
|
|
if (full_turn) {
|
|
drawCircle(file_path, a, center.x(), center.y(), colorcode);
|
|
return;
|
|
}
|
|
//A DXF ARC always runs counter-clockwise from 50 to 51.
|
|
qreal start = startAngle - rotation_angle;
|
|
if (spanAngle < 0)
|
|
start += spanAngle;
|
|
start = std::fmod(start, 360.0);
|
|
if (start < 0)
|
|
start += 360;
|
|
drawArc(file_path, center.x(), center.y(), a,
|
|
start, start + qAbs(spanAngle), colorcode);
|
|
return;
|
|
}
|
|
|
|
const qreal span = full_turn ? 360 : spanAngle;
|
|
const int steps = qMax(2, qCeil(qAbs(span) / 5));
|
|
QPolygonF poly;
|
|
poly.reserve(steps + 1);
|
|
for (int i = 0 ; i <= steps ; ++i)
|
|
{
|
|
const qreal theta = qDegreesToRadians(startAngle + span * i / steps);
|
|
poly << DxfExport::rotation_transformed(
|
|
x + a + a*std::cos(theta),
|
|
y - b + b*std::sin(theta),
|
|
hotspot_x, hotspot_y, rotation_angle);
|
|
}
|
|
drawPolyline(file_path, poly, colorcode, true);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
@brief Createdxf::drawRectangle
|
|
draw rectangle in dxf format
|
|
@param fileName
|
|
@param x1
|
|
@param y1
|
|
@param width
|
|
@param height
|
|
@param colour
|
|
*/
|
|
void Createdxf::drawRectangle (
|
|
const QString &fileName,
|
|
double x1,
|
|
double y1,
|
|
double width,
|
|
double height,
|
|
const int &colour)
|
|
{
|
|
QRectF rect(x1,y1,width,height);
|
|
QPolygonF poly(rect);
|
|
drawPolyline(fileName,poly,colour,true);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
@brief Createdxf::drawArc
|
|
draw arc in dx format
|
|
@param fileName
|
|
@param x
|
|
@param y
|
|
@param rad
|
|
@param startAngle
|
|
@param endAngle
|
|
@param color
|
|
*/
|
|
void Createdxf::drawArc(
|
|
const QString& fileName,
|
|
double x,
|
|
double y,
|
|
double rad,
|
|
double startAngle,
|
|
double endAngle,
|
|
int color)
|
|
{
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the arc
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "ARC" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(color) << "\r\n"; // Colour Code
|
|
To_Dxf << 10 << "\r\n"; // XYZ is the Center point of circle
|
|
To_Dxf << x << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << rad << "\r\n"; // radius of arc
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << startAngle<< "\r\n"; // start angle
|
|
To_Dxf << 51 << "\r\n";
|
|
To_Dxf << endAngle << "\r\n"; // end angle
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawText
|
|
draw simple text in dxf format without any alignment specified
|
|
@param fileName
|
|
@param text
|
|
@param x
|
|
@param y
|
|
@param height
|
|
@param rotation
|
|
@param colour
|
|
@param xScaleW = 1
|
|
*/
|
|
void Createdxf::drawText(
|
|
const QString& fileName,
|
|
const QString& text,
|
|
double x,
|
|
double y,
|
|
double height,
|
|
double rotation,
|
|
int colour,
|
|
double xScaleW)
|
|
{
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the text
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "TEXT" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(colour) << "\r\n"; // Colour Code
|
|
To_Dxf << 10 << "\r\n"; // XYZ
|
|
To_Dxf << x << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << height << "\r\n"; // Text Height
|
|
To_Dxf << 41 << "\r\n";
|
|
To_Dxf << xScaleW << "\r\n"; // X Scale
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << singleLine(text) << "\r\n"; // Text Value
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << rotation << "\r\n"; // Text Rotation
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* draw aligned text in DXF Format */
|
|
// leftAlign flag added. If the alignment requested is 'fit to width' and the text length is very small,
|
|
// then the text is either centered or left-aligned, depnding on the value of leftAlign.
|
|
void Createdxf::drawTextAligned(
|
|
const QString& fileName,
|
|
const QString& text,
|
|
double x,
|
|
double y,
|
|
double height,
|
|
double rotation,
|
|
double oblique,
|
|
int hAlign,
|
|
int vAlign,
|
|
double xAlign,
|
|
double xScaleW,
|
|
int colour)
|
|
{
|
|
drawTextAligned(fileName, text, x, y, height, rotation, oblique,
|
|
hAlign, vAlign, xAlign, y, xScaleW, colour);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawTextAligned
|
|
As above, with the second alignment point given in full (@a xAlign,
|
|
@a yAlign) instead of on the same horizontal line as the insertion
|
|
point, which is what a rotated aligned text needs.
|
|
*/
|
|
void Createdxf::drawTextAligned(
|
|
const QString& fileName,
|
|
const QString& text,
|
|
double x,
|
|
double y,
|
|
double height,
|
|
double rotation,
|
|
double oblique,
|
|
int hAlign,
|
|
int vAlign,
|
|
double xAlign,
|
|
double yAlign,
|
|
double xScaleW,
|
|
int colour)
|
|
{
|
|
if (!fileName.isEmpty()) {
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+fileName+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the circle
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "TEXT" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(colour) << "\r\n"; // Colour Code
|
|
To_Dxf << 10 << "\r\n"; // XYZ
|
|
To_Dxf << x << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 40 << "\r\n";
|
|
To_Dxf << height << "\r\n"; // Text Height
|
|
To_Dxf << 41 << "\r\n";
|
|
To_Dxf << xScaleW << "\r\n"; // X Scale
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << singleLine(text) << "\r\n"; // Text Value
|
|
To_Dxf << 50 << "\r\n";
|
|
To_Dxf << rotation << "\r\n"; // Text Rotation
|
|
#if 0
|
|
// If "Fit to width", then check if width of text < width specified then change it "center align or left align"
|
|
if (hAlign == 5) {
|
|
int xDiff = xAlign - x;
|
|
int len = text.length();
|
|
int t = xDiff/height;
|
|
if (text.length() < xDiff/height && !leftAlign) {
|
|
hAlign = 1;
|
|
xAlign = x+ (xAlign / 2);
|
|
} else if (text.length() < xDiff/height && leftAlign) {
|
|
hAlign = 0;
|
|
xAlign = x;
|
|
// file.close();
|
|
// return;
|
|
}
|
|
}
|
|
#endif
|
|
To_Dxf << 51 << "\r\n";
|
|
To_Dxf << oblique << "\r\n"; // Text Obliqueness
|
|
To_Dxf << 72 << "\r\n";
|
|
To_Dxf << hAlign << "\r\n"; // Text Horizontal Alignment
|
|
To_Dxf << 73 << "\r\n";
|
|
To_Dxf << vAlign << "\r\n"; // Text Vertical Alignment
|
|
|
|
if ((hAlign) || (vAlign)) { // Enter Second Point
|
|
To_Dxf << 11 << "\r\n"; // XYZ
|
|
To_Dxf << xAlign << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 21 << "\r\n";
|
|
To_Dxf << yAlign << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 31 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
}
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawPolyline
|
|
Convenience function for draw polyline
|
|
@param filepath
|
|
@param poly
|
|
@param colorcode
|
|
@param preScaled
|
|
*/
|
|
void Createdxf::drawPolyline(const QString &filepath,
|
|
const QPolygonF &poly,
|
|
const int &colorcode, bool preScaled)
|
|
{
|
|
qreal x,y;
|
|
if (!filepath.isEmpty()) {
|
|
QFile file(filepath);
|
|
if (!file.open(QFile::Append)) {
|
|
// error message
|
|
QMessageBox errorFileOpen;
|
|
errorFileOpen.setText("Error: File "+filepath+" was not written correctly.");
|
|
errorFileOpen.setInformativeText("Close all Files and Re-Run");
|
|
errorFileOpen.exec();
|
|
} else {
|
|
QTextStream To_Dxf(&file);
|
|
// Draw the Line
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "POLYLINE" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 62 << "\r\n";
|
|
To_Dxf << entityColour(colorcode) << "\r\n"; // Colour Code
|
|
To_Dxf << 66 << "\r\n";
|
|
To_Dxf << 1 << "\r\n";
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0 << "\r\n";
|
|
foreach(QPointF p, poly)
|
|
{
|
|
if(preScaled) {
|
|
x = p.x();
|
|
y = p.y();
|
|
} else {
|
|
x = p.x() * xScale;
|
|
y = sheetHeight - (p.y() * yScale);
|
|
}
|
|
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "VERTEX" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
To_Dxf << 70 << "\r\n";
|
|
To_Dxf << 32 << "\r\n";
|
|
To_Dxf << 10 << "\r\n";
|
|
To_Dxf << x << "\r\n"; // X in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 20 << "\r\n";
|
|
To_Dxf << y << "\r\n"; // Y in UCS (User Coordinate System)coordinates
|
|
To_Dxf << 30 << "\r\n";
|
|
To_Dxf << 0.0 << "\r\n"; // Z in UCS (User Coordinate System)coordinates
|
|
}
|
|
|
|
To_Dxf << 0 << "\r\n";
|
|
To_Dxf << "SEQEND" << "\r\n";
|
|
To_Dxf << 8 << "\r\n";
|
|
To_Dxf << layer << "\r\n"; // Layer name
|
|
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ================================================
|
|
* Majority of calls above here are must be passed
|
|
* parameters pre=scaled to DXF units
|
|
* Calls below use Qt scaling, and re-scale them to DXF
|
|
* ================================================
|
|
*/
|
|
/**
|
|
@brief Createdxf::drawCircle
|
|
draw circle in qt format
|
|
@param fileName
|
|
@param center
|
|
@param radius
|
|
@param colour
|
|
*/
|
|
void Createdxf::drawCircle(
|
|
const QString& fileName,
|
|
QPointF center,
|
|
double radius,
|
|
int colour)
|
|
{
|
|
qreal x = center.x() * xScale;
|
|
qreal y = sheetHeight - center.y() * yScale;
|
|
qreal r = radius * xScale;
|
|
drawCircle(fileName,r,x,y,colour);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawLine
|
|
Convenience function to draw line
|
|
@param filepath
|
|
@param line
|
|
@param colorcode
|
|
*/
|
|
void Createdxf::drawLine(
|
|
const QString &filepath,
|
|
const QLineF &line,
|
|
const int &colorcode)
|
|
{
|
|
drawLine(filepath, line.p1().x() * xScale,
|
|
sheetHeight - (line.p1().y() * yScale),
|
|
line.p2().x() * xScale,
|
|
sheetHeight - (line.p2().y() * yScale),
|
|
colorcode);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawEllipse
|
|
Conveniance function for draw ellipse
|
|
@param filepath
|
|
@param rect
|
|
@param colorcode
|
|
*/
|
|
void Createdxf::drawEllipse(
|
|
const QString &filepath,
|
|
const QRectF &rect,
|
|
const int &colorcode)
|
|
{
|
|
drawArcEllipse(
|
|
filepath,
|
|
rect.topLeft().x() * xScale,
|
|
sheetHeight - (rect.topLeft().y() * yScale),
|
|
rect.width() * xScale,
|
|
rect.height() * yScale,
|
|
0, 360, 0, 0, 0, colorcode);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawRectangle
|
|
Convenience function for draw rectangle
|
|
@param filepath
|
|
@param rect
|
|
@param colorcode
|
|
*/
|
|
void Createdxf::drawRectangle(
|
|
const QString &filepath,
|
|
const QRectF &rect,
|
|
const int &colorcode) {
|
|
//QPolygonF poly(scaleRect(rect));
|
|
QPolygonF poly(rect);
|
|
drawPolyline(filepath,poly,colorcode);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawPolygon
|
|
Convenience function for draw polygon
|
|
@param filepath
|
|
@param poly
|
|
@param colorcode
|
|
*/
|
|
void Createdxf::drawPolygon(
|
|
const QString &filepath,
|
|
const QPolygonF &poly,
|
|
const int &colorcode)
|
|
{
|
|
QPolygonF pg = poly;
|
|
if(!poly.isClosed()) {
|
|
pg << poly.at(0); // Close it
|
|
}
|
|
drawPolyline(filepath,pg,colorcode);
|
|
}
|
|
|
|
/**
|
|
@brief Createdxf::drawText
|
|
draw simple text in dxf format without any alignment specified
|
|
@param fileName
|
|
@param text
|
|
@param point
|
|
@param height
|
|
@param rotation
|
|
@param colour
|
|
@param xScaleW = 1
|
|
*/
|
|
void Createdxf::drawText(
|
|
const QString& fileName,
|
|
const QString& text,
|
|
QPointF point,
|
|
double height,
|
|
double rotation,
|
|
int colour,
|
|
double xScaleW)
|
|
{
|
|
qreal x = point.x() * xScale;
|
|
qreal y = sheetHeight - (point.y() * yScale);
|
|
drawText(fileName,text,x,y,height * yScale,rotation,colour,xScaleW);
|
|
}
|
|
void Createdxf::drawArcEllipse(
|
|
const QString &file_path,
|
|
QRectF rect,
|
|
qreal startAngle,
|
|
qreal spanAngle,
|
|
QPointF hotspot,
|
|
qreal rotation_angle,
|
|
const int &colorcode)
|
|
{
|
|
qreal x = rect.x() * xScale;
|
|
qreal y = sheetHeight - rect.y() * yScale;
|
|
qreal w = rect.width() * xScale;
|
|
qreal h = rect.height() * yScale;
|
|
qreal hotspot_x = hotspot.x() * xScale;
|
|
qreal hotspot_y = sheetHeight - hotspot.y() * yScale;
|
|
drawArcEllipse(file_path,x,y,w,h,startAngle,spanAngle,hotspot_x,hotspot_y,rotation_angle,colorcode);
|
|
}
|
|
|
|
/*
|
|
* Utility functions
|
|
*/
|
|
//static QRectF scaleRect(QRectF rect)
|
|
//{
|
|
// QRectF ro(rect.bottomLeft().x() * Createdxf::xScale,
|
|
// Createdxf::sheetHeight - (rect.bottomLeft().y() * Createdxf::yScale),
|
|
// rect.width() * Createdxf::xScale,
|
|
// rect.height() * Createdxf::yScale);
|
|
// return ro;
|
|
//}
|