mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-28 04:54:13 +02:00
Put the DXF export on named layers (#1071)
Everything in an exported DXF was on layer 0, and the file had no LAYER table: in a CAD program the border, title block, symbols, wires and texts could not be hidden, printed or recoloured separately. Each kind of content now has its own layer, declared in a LAYER table (white/black, continuous, so the file looks the same on opening): QET_BORDER, QET_TITLEBLOCK, QET_SYMBOLS, QET_SYMBOL_TEXTS, QET_TERMINALS, QET_WIRES, QET_WIRE_NUMBERS, QET_JUNCTIONS, QET_TEXTS, QET_XREFS, QET_SHAPES, QET_TABLES, QET_IMAGES Fixed, untranslated names, so layer filters and scripts work in any language. Createdxf gets a current layer beside its xScale/yScale; DxfExport sets it before each kind of content, and BorderTitleBlock switches to the title block layer itself. No DXF version change: layers exist in R10. Checked on the 24 example projects, 133 folios: with the layer values set back to 0 and the LAYER table removed, every file is byte-identical to before; no entity is on an undeclared layer or left on 0; ezdxf reads all of them with no audit errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "bordercelllabels.h"
|
||||
#include "createdxf.h"
|
||||
#include "dxfexport.h"
|
||||
#include "diagram.h"
|
||||
#include "diagramposition.h"
|
||||
#include "math.h"
|
||||
@@ -706,6 +707,7 @@ void BorderTitleBlock::drawDxf(
|
||||
|
||||
// render the titleblock, using the TitleBlockTemplate object
|
||||
if (display_titleblock_) {
|
||||
Createdxf::layer = DxfExport::Layer::TitleBlock;
|
||||
//qp -> translate(titleblock_rect_.topLeft());
|
||||
QRectF rect = titleBlockRect();
|
||||
m_titleblock_template_renderer -> renderDxf(rect,
|
||||
|
||||
+44
-10
@@ -42,6 +42,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
double Createdxf::yScale = 1;
|
||||
QString Createdxf::layer = QStringLiteral("0");
|
||||
|
||||
Createdxf::Createdxf()
|
||||
{
|
||||
@@ -51,9 +52,12 @@ Createdxf::~Createdxf()
|
||||
{
|
||||
}
|
||||
|
||||
/* Header section of every DXF file.*/
|
||||
void Createdxf::dxfBegin (const QString& fileName)
|
||||
/* 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. */
|
||||
void Createdxf::dxfBegin (const QString& fileName, const QStringList &layers)
|
||||
{
|
||||
layer = QStringLiteral("0");
|
||||
|
||||
// Creation of an output stream object in text mode.
|
||||
// Header section of every dxf file.
|
||||
@@ -223,6 +227,35 @@ void Createdxf::dxfBegin (const QString& fileName)
|
||||
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";
|
||||
@@ -248,6 +281,7 @@ void Createdxf::dxfBegin (const QString& 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);
|
||||
@@ -298,7 +332,7 @@ void Createdxf::drawCircle(
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "CIRCLE" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << colour << "\r\n"; // Colour Code
|
||||
To_Dxf << 10 << "\r\n"; // XYZ is the Center point of circle
|
||||
@@ -346,7 +380,7 @@ void Createdxf::drawLine (
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "LINE" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << colour << "\r\n"; // Colour Code
|
||||
To_Dxf << 10 << "\r\n";
|
||||
@@ -671,7 +705,7 @@ void Createdxf::drawArc(
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "ARC" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << color << "\r\n"; // Colour Code
|
||||
To_Dxf << 10 << "\r\n"; // XYZ is the Center point of circle
|
||||
@@ -727,7 +761,7 @@ void Createdxf::drawText(
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "TEXT" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << colour << "\r\n"; // Colour Code
|
||||
To_Dxf << 10 << "\r\n"; // XYZ
|
||||
@@ -780,7 +814,7 @@ void Createdxf::drawTextAligned(
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "TEXT" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << colour << "\r\n"; // Colour Code
|
||||
To_Dxf << 10 << "\r\n"; // XYZ
|
||||
@@ -861,7 +895,7 @@ void Createdxf::drawPolyline(const QString &filepath,
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "POLYLINE" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 62 << "\r\n";
|
||||
To_Dxf << colorcode << "\r\n"; // Colour Code
|
||||
To_Dxf << 66 << "\r\n";
|
||||
@@ -887,7 +921,7 @@ void Createdxf::drawPolyline(const QString &filepath,
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "VERTEX" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
To_Dxf << 70 << "\r\n";
|
||||
To_Dxf << 32 << "\r\n";
|
||||
To_Dxf << 10 << "\r\n";
|
||||
@@ -901,7 +935,7 @@ void Createdxf::drawPolyline(const QString &filepath,
|
||||
To_Dxf << 0 << "\r\n";
|
||||
To_Dxf << "SEQEND" << "\r\n";
|
||||
To_Dxf << 8 << "\r\n";
|
||||
To_Dxf << 0 << "\r\n"; // Layer number (default layer in autocad)
|
||||
To_Dxf << layer << "\r\n"; // Layer name
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
+5
-1
@@ -18,6 +18,7 @@
|
||||
#ifndef CREATEDXF_H
|
||||
#define CREATEDXF_H
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
|
||||
@@ -30,7 +31,7 @@ class Createdxf
|
||||
public:
|
||||
Createdxf();
|
||||
~Createdxf();
|
||||
static void dxfBegin (const QString&);
|
||||
static void dxfBegin (const QString&, const QStringList &layers = QStringList());
|
||||
static void dxfEnd(const QString&);
|
||||
// you can add more functions to create more drawings.
|
||||
static void drawCircle(
|
||||
@@ -159,6 +160,9 @@ class Createdxf
|
||||
static const double sheetHeight;
|
||||
static double xScale;
|
||||
static double yScale;
|
||||
/// Layer every entity is written on, "0" unless set; the
|
||||
/// layers themselves are declared by dxfBegin() (discussion #1071).
|
||||
static QString layer;
|
||||
};
|
||||
|
||||
#endif // CREATEDXF_H
|
||||
|
||||
+19
-1
@@ -81,8 +81,12 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
Createdxf::xScale = Createdxf::sheetWidth / double(width);
|
||||
Createdxf::yScale = Createdxf::sheetHeight / double(height);
|
||||
|
||||
Createdxf::dxfBegin(file_path);
|
||||
Createdxf::dxfBegin(file_path, Layer::all());
|
||||
|
||||
//Each kind of content on its own layer (discussion #1071). The
|
||||
//border's title block switches to Layer::TitleBlock itself, see
|
||||
//BorderTitleBlock::drawDxf().
|
||||
Createdxf::layer = Layer::Border;
|
||||
//Add project elements (lines, rectangles, circles, texts) to dxf file
|
||||
if (properties.draw_border) {
|
||||
QRectF rect(Diagram::margin,Diagram::margin,width,height);
|
||||
@@ -154,9 +158,11 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
|
||||
// Draw shapes
|
||||
Createdxf::layer = Layer::Shapes;
|
||||
foreach (QetShapeItem *qsi, list_shapes) qsi->toDXF(file_path, qsi->pen());
|
||||
|
||||
// Draw tables
|
||||
Createdxf::layer = Layer::Tables;
|
||||
foreach (QetGraphicsTableItem *gti, list_tables) {
|
||||
gti->toDXF(file_path);
|
||||
}
|
||||
@@ -171,6 +177,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
|
||||
ElementPictureFactory::primitives primitives = ElementPictureFactory::instance()->getPrimitives(elmt->location());
|
||||
|
||||
Createdxf::layer = Layer::SymbolTexts;
|
||||
for(QGraphicsSimpleTextItem *text : primitives.m_texts)
|
||||
{
|
||||
qreal fontSize = text->font().pointSizeF();
|
||||
@@ -200,6 +207,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
}
|
||||
|
||||
Createdxf::layer = Layer::Symbols;
|
||||
for (QLineF line : primitives.m_lines)
|
||||
{
|
||||
QTransform t = QTransform().translate(elem_pos_x,elem_pos_y).rotate(rotation_angle);
|
||||
@@ -249,6 +257,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
Createdxf::drawArcEllipse(file_path, r, startAngle, spanAngle, hotspot, rotation_angle, 0);
|
||||
}
|
||||
if (properties.draw_terminals) {
|
||||
Createdxf::layer = Layer::Terminals;
|
||||
// Draw terminals
|
||||
QList<Terminal *> list_terminals = elmt->terminals();
|
||||
QColor col("red");
|
||||
@@ -272,8 +281,10 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
poly << cond->pos()+segment->secondPoint();
|
||||
}
|
||||
Createdxf::layer = Layer::Wires;
|
||||
Createdxf::drawPolyline(file_path,poly,0);
|
||||
//Draw conductor text item
|
||||
Createdxf::layer = Layer::WireNumbers;
|
||||
ConductorTextItem *textItem = cond -> textItem();
|
||||
|
||||
if (textItem) {
|
||||
@@ -302,6 +313,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
|
||||
// Draw the junctions
|
||||
Createdxf::layer = Layer::Junctions;
|
||||
QList<QPointF> junctions_list = cond->junctions();
|
||||
if (!junctions_list.isEmpty()) {
|
||||
foreach(QPointF point, junctions_list) {
|
||||
@@ -312,6 +324,9 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
|
||||
//Draw text items
|
||||
foreach(DiagramTextItem *dti, list_texts) {
|
||||
//A free text, or a symbol's own text (its label and the like)
|
||||
Createdxf::layer = qgraphicsitem_cast<IndependentTextItem *>(dti)
|
||||
? Layer::Texts : Layer::SymbolTexts;
|
||||
qreal fontSize = dti -> font().pointSizeF();
|
||||
if (fontSize < 0)
|
||||
fontSize = dti -> font().pixelSize();
|
||||
@@ -344,6 +359,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
}
|
||||
|
||||
//Draw the slave cross-reference labels
|
||||
Createdxf::layer = Layer::Xrefs;
|
||||
for (QGraphicsTextItem *xref : std::as_const(list_xref_texts))
|
||||
{
|
||||
qreal fontSize = xref->font().pointSizeF();
|
||||
@@ -382,6 +398,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
//Draw the master-side cross-reference items (table/cross), replaying
|
||||
//their existing paint() unmodified through DxfPaintEngine instead of
|
||||
//hand-porting drawAsCross()/drawAsContacts()/drawAsPlcTable().
|
||||
Createdxf::layer = Layer::Xrefs;
|
||||
for (CrossRefItem *xref : std::as_const(list_master_xrefs))
|
||||
{
|
||||
DxfPaintDevice dxf_device(file_path);
|
||||
@@ -401,6 +418,7 @@ void DxfExport::write(Diagram *diagram, int width, int height,
|
||||
//actually turns the drawPixmap() call inside paint() into a
|
||||
//placeholder outline, since this DXF dialect has no raster image
|
||||
//entity to draw instead.
|
||||
Createdxf::layer = Layer::Images;
|
||||
for (DiagramImageItem *image : std::as_const(list_images))
|
||||
{
|
||||
DxfPaintDevice dxf_device(file_path);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <QPointF>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
class Diagram;
|
||||
class ExportProperties;
|
||||
@@ -32,6 +33,34 @@ class ExportProperties;
|
||||
*/
|
||||
namespace DxfExport
|
||||
{
|
||||
/// The layers of an exported folio (discussion #1071). Fixed and
|
||||
/// untranslated, so a CAD user's layer filters and scripts work
|
||||
/// whatever language QElectroTech runs in; prefixed so they sort
|
||||
/// together and do not clash with the recipient's own layers.
|
||||
namespace Layer
|
||||
{
|
||||
inline const QString Border = QStringLiteral("QET_BORDER");
|
||||
inline const QString TitleBlock = QStringLiteral("QET_TITLEBLOCK");
|
||||
inline const QString Symbols = QStringLiteral("QET_SYMBOLS");
|
||||
inline const QString SymbolTexts = QStringLiteral("QET_SYMBOL_TEXTS");
|
||||
inline const QString Terminals = QStringLiteral("QET_TERMINALS");
|
||||
inline const QString Wires = QStringLiteral("QET_WIRES");
|
||||
inline const QString WireNumbers = QStringLiteral("QET_WIRE_NUMBERS");
|
||||
inline const QString Junctions = QStringLiteral("QET_JUNCTIONS");
|
||||
inline const QString Texts = QStringLiteral("QET_TEXTS");
|
||||
inline const QString Xrefs = QStringLiteral("QET_XREFS");
|
||||
inline const QString Shapes = QStringLiteral("QET_SHAPES");
|
||||
inline const QString Tables = QStringLiteral("QET_TABLES");
|
||||
inline const QString Images = QStringLiteral("QET_IMAGES");
|
||||
|
||||
inline QStringList all()
|
||||
{
|
||||
return {Border, TitleBlock, Symbols, SymbolTexts, Terminals,
|
||||
Wires, WireNumbers, Junctions, Texts, Xrefs, Shapes,
|
||||
Tables, Images};
|
||||
}
|
||||
}
|
||||
|
||||
QSize folioSize(Diagram *diagram, const ExportProperties &properties);
|
||||
void write(Diagram *diagram, int width, int height,
|
||||
const QString &path, const ExportProperties &properties);
|
||||
|
||||
Reference in New Issue
Block a user