From c4ca41aa8370d08d3be88d8b40fd681c1ad0ea3f Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sun, 27 Mar 2016 19:00:08 +0300 Subject: [PATCH] Fixed issue #463. Wrong export to DXF format. (grafted from a2df4c627d50fcd0225cc63d924c065063af326f) --HG-- branch : develop --- ChangeLog.txt | 1 + src/app/valentina/mainwindowsnogui.cpp | 31 +++++- src/libs/vdxf/vdxfengine.cpp | 136 +++++++++++++++---------- src/libs/vdxf/vdxfengine.h | 7 +- src/libs/vdxf/vdxfpaintdevice.cpp | 12 +-- src/libs/vdxf/vdxfpaintdevice.h | 4 +- src/libs/vmisc/def.h | 20 ++-- 7 files changed, 137 insertions(+), 74 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index ac1d854dc..cff3f0e87 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -14,6 +14,7 @@ - [#385] Add 'Open Recent' option in Tape.exe, 'File' dropdown menu. # Version 0.4.4 +- [#463] Wrong export to DXF format. - Fixed issue with deleting detail nodes. - [#458] Issue with segment of curve. - Fixed disappearing curve if start and finish points of a segment are equal. diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 936e9e771..e5137b537 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -693,15 +693,38 @@ void MainWindowsNoGUI::ObjFile(const QString &name, int i) const } //--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_CC_GNU) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wswitch-default" +#endif + void MainWindowsNoGUI::DxfFile(const QString &name, int i) const { QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(i)); if (paper) { - VDxfPaintDevice generator; + VDxfPaintDevice generator; generator.setFileName(name); generator.setSize(paper->rect().size().toSize()); - generator.setResolution(static_cast(PrintDPI)); + generator.setResolution(PrintDPI); + + switch (*pattern->GetPatternUnit()) + { + case Unit::Cm: + generator.setInsunits(VarInsunits::Centimeters); + break; + case Unit::Mm: + generator.setInsunits(VarInsunits::Millimeters); + break; + case Unit::Inch: + generator.setInsunits(VarInsunits::Inches); + break; + case Unit::Px: + case Unit::LAST_UNIT_DO_NOT_USE: + Q_UNREACHABLE(); + break; + } + QPainter painter; painter.begin(&generator); scenes.at(i)->render(&painter, paper->rect(), paper->rect(), Qt::IgnoreAspectRatio); @@ -709,6 +732,10 @@ void MainWindowsNoGUI::DxfFile(const QString &name, int i) const } } +#if defined(Q_CC_GNU) + #pragma GCC diagnostic pop +#endif + //--------------------------------------------------------------------------------------------------------------------- QVector MainWindowsNoGUI::AllSheets() const { diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index 55a130517..7d32c7792 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -114,6 +114,14 @@ bool VDxfEngine::begin(QPaintDevice *pdev) dw->dxfString(9, "$INSUNITS"); dw->dxfInt(70, static_cast(varInsunits)); + dw->dxfString(9, "$DIMSCALE"); + dw->dxfReal(40, 1.0); + + // Official documentation says that initial value is 1.0, however LibreCAD has trouble if not set this value + // explicitly. + dw->dxfString(9, "$DIMLFAC"); + dw->dxfReal(40, 1.0); + QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz"); dateTime.chop(1);// we need hundredths of a second dw->dxfString(9, "$TDCREATE"); @@ -256,7 +264,9 @@ void VDxfEngine::drawPath(const QPainterPath &path) for (int i=0; i < polygon.count(); ++i) { - dxf->writeVertex(*dw, DL_VertexData(polygon.at(i).x(), getSize().height() - polygon.at(i).y(), 0, 0)); + dxf->writeVertex(*dw, + DL_VertexData(FromPixel(polygon.at(i).x(), varInsunits), + FromPixel(getSize().height() - polygon.at(i).y(), varInsunits), 0, 0)); } dxf->writePolylineEnd(*dw); @@ -268,18 +278,17 @@ void VDxfEngine::drawLines(const QLineF * lines, int lineCount) { for (int i = 0; i < lineCount; ++i) { - QPointF p1 = matrix.map(lines[i].p1()); - QPointF p2 = matrix.map(lines[i].p2()); + const QPointF p1 = matrix.map(lines[i].p1()); + const QPointF p2 = matrix.map(lines[i].p2()); - dxf->writeLine( - *dw, - DL_LineData(p1.x(), // start point - getSize().height() - p1.y(), - 0.0, - p2.x(), // end point - getSize().height() - p2.y(), - 0.0), - DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); + dxf->writeLine(*dw, + DL_LineData(FromPixel(p1.x(), varInsunits), // start point + FromPixel(getSize().height() - p1.y(), varInsunits), + FromPixel(0.0, varInsunits), + FromPixel(p2.x(), varInsunits), // end point + FromPixel(getSize().height() - p2.y(), varInsunits), + FromPixel(0.0, varInsunits)), + DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); } } @@ -305,8 +314,10 @@ void VDxfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawM for (int i = 0; i < pointCount; ++i) { - QPointF p = matrix.map(points[i]); - dxf->writeVertex(*dw, DL_VertexData(p.x(), getSize().height() - p.y(), 0, 0)); + const QPointF p = matrix.map(points[i]); + dxf->writeVertex(*dw, + DL_VertexData(FromPixel(p.x(), varInsunits), + FromPixel(getSize().height() - p.y(), varInsunits), 0, 0)); } dxf->writePolylineEnd(*dw); @@ -321,8 +332,8 @@ void VDxfEngine::drawPolygon(const QPoint *points, int pointCount, QPaintEngine: //--------------------------------------------------------------------------------------------------------------------- void VDxfEngine::drawEllipse(const QRectF & rect) { - QRectF newRect = matrix.mapRect(rect); - double rotationAngle = atan(matrix.m12()/matrix.m11()); + const QRectF newRect = matrix.mapRect(rect); + const double rotationAngle = atan(matrix.m12()/matrix.m11()); double majorX, majorY; // distanse between center and endpoint of the major axis double ratio; // ratio of minor axis to major axis @@ -342,18 +353,18 @@ void VDxfEngine::drawEllipse(const QRectF & rect) // major axis * sin(rotation angle) * y-scale-factor ratio = rect.height()/rect.width(); } - dxf->writeEllipse( - *dw, - DL_EllipseData(newRect.center().x(), // center X - getSize().height() - newRect.center().y(), // center Y - 0, // center Z - majorX, - majorY, - 0, - ratio, - 0,6.28 // startangle and endangle of ellipse in rad - ), - DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); + + dxf->writeEllipse(*dw, + DL_EllipseData(FromPixel(newRect.center().x(), varInsunits), // center X + FromPixel(getSize().height() - newRect.center().y(), varInsunits), // center Y + FromPixel(0, varInsunits), // center Z + FromPixel(majorX, varInsunits), + FromPixel(majorY, varInsunits), + FromPixel(0, varInsunits), + FromPixel(majorY, varInsunits), + 0, 6.28 // startangle and endangle of ellipse in rad + ), + DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); } //--------------------------------------------------------------------------------------------------------------------- @@ -365,29 +376,28 @@ void VDxfEngine::drawEllipse(const QRect & rect) //--------------------------------------------------------------------------------------------------------------------- void VDxfEngine::drawTextItem(const QPointF & p, const QTextItem & textItem) { - QPointF startPoint = matrix.map(p); - double rotationAngle = atan(matrix.m12()/matrix.m11()); + const QPointF startPoint = matrix.map(p); + const double rotationAngle = atan(matrix.m12()/matrix.m11()); const QFont f = textItem.font(); - int textSize = f.pixelSize() == -1 ? f.pointSize() : f.pixelSize(); - dxf->writeText( - *dw, - DL_TextData(startPoint.x(), - getSize().height() - startPoint.y(), - 0, - startPoint.x(), - getSize().height() - startPoint.y(), - 0, - textSize * matrix.m11(), - 1, // relative X scale factor - 0, // flag (0 = default, 2 = Backwards, 4 = Upside down) - 0, // Horizontal justification (0 = Left (default), 1 = Center, 2 = Right,) - 0, // Vertical justification (0 = Baseline (default), 1 = Bottom, 2 = Middle, 3= Top) - textItem.text().toUtf8().constData(), // text data - f.family().toUtf8().constData(), // font - -rotationAngle - ), - DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); + const int textSize = f.pixelSize() == -1 ? f.pointSize() : f.pixelSize(); + dxf->writeText(*dw, + DL_TextData(FromPixel(startPoint.x(), varInsunits), + FromPixel(getSize().height() - startPoint.y(), varInsunits), + FromPixel(0, varInsunits), + FromPixel(startPoint.x(), varInsunits), + FromPixel(getSize().height() - startPoint.y(), varInsunits), + FromPixel(0, varInsunits), + textSize * matrix.m11(), + 1, // relative X scale factor + 0, // flag (0 = default, 2 = Backwards, 4 = Upside down) + 0, // Horizontal justification (0 = Left (default), 1 = Center, 2 = Right,) + 0, // Vertical justification (0 = Baseline (default), 1 = Bottom, 2 = Middle, 3= Top) + textItem.text().toUtf8().constData(), // text data + f.family().toUtf8().constData(), // font + -rotationAngle + ), + DL_Attributes("0", getPenColor(), -1, getPenStyle(), 1.0)); } //--------------------------------------------------------------------------------------------------------------------- @@ -419,13 +429,13 @@ void VDxfEngine::setSize(const QSize &value) } //--------------------------------------------------------------------------------------------------------------------- -int VDxfEngine::getResolution() const +double VDxfEngine::getResolution() const { return resolution; } //--------------------------------------------------------------------------------------------------------------------- -void VDxfEngine::setResolution(int value) +void VDxfEngine::setResolution(double value) { Q_ASSERT(not isActive()); resolution = value; @@ -554,3 +564,27 @@ void VDxfEngine::setInsunits(const VarInsunits &var) Q_ASSERT(not isActive()); varInsunits = var; } + +//--------------------------------------------------------------------------------------------------------------------- +#if defined(Q_CC_GNU) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wswitch-default" +#endif + +double VDxfEngine::FromPixel(double pix, const VarInsunits &unit) const +{ + switch (unit) + { + case VarInsunits::Millimeters: + return pix / resolution * 25.4; + case VarInsunits::Centimeters: + return pix / resolution * 25.4 / 10.0; + case VarInsunits::Inches: + return pix / resolution; + } + return 0; +} + +#if defined(Q_CC_GNU) + #pragma GCC diagnostic pop +#endif diff --git a/src/libs/vdxf/vdxfengine.h b/src/libs/vdxf/vdxfengine.h index 217fb044d..2b51485a3 100644 --- a/src/libs/vdxf/vdxfengine.h +++ b/src/libs/vdxf/vdxfengine.h @@ -59,8 +59,8 @@ public: QSize getSize() const; void setSize(const QSize &value); - int getResolution() const; - void setResolution(int value); + double getResolution() const; + void setResolution(double value); QString getFileName() const; void setFileName(const QString &value); @@ -74,7 +74,7 @@ public: private: Q_DISABLE_COPY(VDxfEngine) QSize size; - int resolution; + double resolution; QString fileName; QMatrix matrix; DL_Dxf* dxf; @@ -82,6 +82,7 @@ private: VarMeasurement varMeasurement; VarInsunits varInsunits; + double FromPixel(double pix, const VarInsunits &unit) const Q_REQUIRED_RESULT; }; #endif // VDXFENGINE_H diff --git a/src/libs/vdxf/vdxfpaintdevice.cpp b/src/libs/vdxf/vdxfpaintdevice.cpp index b406fd8fa..476072001 100644 --- a/src/libs/vdxf/vdxfpaintdevice.cpp +++ b/src/libs/vdxf/vdxfpaintdevice.cpp @@ -88,13 +88,13 @@ void VDxfPaintDevice::setSize(const QSize &size) } //--------------------------------------------------------------------------------------------------------------------- -int VDxfPaintDevice::getResolution() const +double VDxfPaintDevice::getResolution() const { return engine->getResolution(); } //--------------------------------------------------------------------------------------------------------------------- -void VDxfPaintDevice::setResolution(int dpi) +void VDxfPaintDevice::setResolution(double dpi) { engine->setResolution(dpi); } @@ -123,9 +123,9 @@ int VDxfPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmHeight: return engine->getSize().height(); case QPaintDevice::PdmDpiX: - return engine->getResolution(); + return static_cast(engine->getResolution()); case QPaintDevice::PdmDpiY: - return engine->getResolution(); + return static_cast(engine->getResolution()); case QPaintDevice::PdmHeightMM: return qRound(engine->getSize().height() * 25.4 / engine->getResolution()); case QPaintDevice::PdmWidthMM: @@ -133,9 +133,9 @@ int VDxfPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmNumColors: return static_cast(0xffffffff); case QPaintDevice::PdmPhysicalDpiX: - return engine->getResolution(); + return static_cast(engine->getResolution()); case QPaintDevice::PdmPhysicalDpiY: - return engine->getResolution(); + return static_cast(engine->getResolution()); #if QT_VERSION > QT_VERSION_CHECK(5, 0, 2) case QPaintDevice::PdmDevicePixelRatio: return 1; diff --git a/src/libs/vdxf/vdxfpaintdevice.h b/src/libs/vdxf/vdxfpaintdevice.h index a69a35541..dd9d13b18 100644 --- a/src/libs/vdxf/vdxfpaintdevice.h +++ b/src/libs/vdxf/vdxfpaintdevice.h @@ -48,8 +48,8 @@ public: QSize getSize(); void setSize(const QSize &size); - int getResolution() const; - void setResolution(int dpi); + double getResolution() const; + void setResolution(double dpi); void setMeasurement(const VarMeasurement &var); void setInsunits(const VarInsunits &var); diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index b3960019a..8d49efcd5 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -588,23 +588,23 @@ void RestoreOverrideCursor(const QString & pixmapPath); extern const qreal PrintDPI; -double ToPixel(double val, const Unit &unit); -double FromPixel(double pix, const Unit &unit); +double ToPixel(double val, const Unit &unit) Q_REQUIRED_RESULT; +double FromPixel(double pix, const Unit &unit) Q_REQUIRED_RESULT; -qreal UnitConvertor(qreal value, const Unit &from, const Unit &to); +qreal UnitConvertor(qreal value, const Unit &from, const Unit &to) Q_REQUIRED_RESULT; void CheckFactor(qreal &oldFactor, const qreal &Newfactor); -QStringList SupportedLocales(); -QStringList AllGroupNames(); +QStringList SupportedLocales() Q_REQUIRED_RESULT; +QStringList AllGroupNames() Q_REQUIRED_RESULT; -QString StrippedName(const QString &fullFileName); -QString RelativeMPath(const QString &patternPath, const QString &absoluteMPath); -QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath); +QString StrippedName(const QString &fullFileName) Q_REQUIRED_RESULT; +QString RelativeMPath(const QString &patternPath, const QString &absoluteMPath) Q_REQUIRED_RESULT; +QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath) Q_REQUIRED_RESULT; -QSharedPointer DefaultPrinter(); +QSharedPointer DefaultPrinter() Q_REQUIRED_RESULT; -QPixmap darkenPixmap(const QPixmap &pixmap); +QPixmap darkenPixmap(const QPixmap &pixmap) Q_REQUIRED_RESULT; static inline bool VFuzzyComparePossibleNulls(double p1, double p2) Q_REQUIRED_RESULT; static inline bool VFuzzyComparePossibleNulls(double p1, double p2)