From 6016308d589ada7f3097204b65a8d41d707eb815 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Thu, 27 Dec 2018 15:54:29 +0200 Subject: [PATCH] Resolved issue #651. Improve feature: Layout orientation according to grainline. --HG-- branch : develop --- ChangeLog.txt | 1 + dist/OBS_debian/debian.valentina.1 | 4 +- dist/debian/valentina.1 | 4 +- src/app/valentina/core/vcmdexport.cpp | 6 + .../dialogs/dialoglayoutsettings.cpp | 16 +++ .../valentina/dialogs/dialoglayoutsettings.h | 3 + .../valentina/dialogs/dialoglayoutsettings.ui | 31 ++++- src/libs/vlayout/vlayoutgenerator.cpp | 16 +++ src/libs/vlayout/vlayoutgenerator.h | 4 + src/libs/vlayout/vlayoutpaper.cpp | 15 ++- src/libs/vlayout/vlayoutpaper.h | 3 + src/libs/vlayout/vlayoutpaper_p.h | 10 +- src/libs/vlayout/vlayoutpiece.cpp | 24 +++- src/libs/vlayout/vlayoutpiece.h | 3 + src/libs/vlayout/vlayoutpiece_p.h | 10 ++ src/libs/vlayout/vposition.cpp | 114 ++++++++++++------ src/libs/vlayout/vposition.h | 22 +++- src/libs/vmisc/commandoptions.cpp | 5 +- src/libs/vmisc/commandoptions.h | 1 + src/libs/vmisc/vsettings.cpp | 19 +++ src/libs/vmisc/vsettings.h | 4 + 21 files changed, 263 insertions(+), 52 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index c194ac798..44a85edb1 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,6 +3,7 @@ - [#894] Quick way to disable a passmark. - [#895] Improve path validation. Do not allow repeat the same curve twice. - Improve UI. Make placeholder menu scrollable. +- [#651] Improve feature: Layout orientation according to grainline. # Version 0.6.2 (unreleased) - [#903] Bug in tool Cut Spline path. diff --git a/dist/OBS_debian/debian.valentina.1 b/dist/OBS_debian/debian.valentina.1 index fc4097ca0..483916188 100644 --- a/dist/OBS_debian/debian.valentina.1 +++ b/dist/OBS_debian/debian.valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "18 July, 2018" "valentina man page" +.TH valentina 1 "27 December, 2018" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -179,6 +179,8 @@ The path to output destination folder. By default the directory at which the app .RB "Page bottom margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." .IP "-r, --rotate " .RB "Rotation in degrees (one of predefined, " "export mode" "). Default value is " "180" ". 0 is no-rotate. Valid values: 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90, 180. Each value show how many times details will be rotated. For example 180 mean two times (360/180=2) by 180 degree." +.IP "--followGrainline" +.RB "Order detail to follow grainline direction (" "export mode" "). .IP "-c, --crop" .RB "Auto crop unused length (" "export mode" ")." .IP "-u, --unite" diff --git a/dist/debian/valentina.1 b/dist/debian/valentina.1 index fc4097ca0..483916188 100644 --- a/dist/debian/valentina.1 +++ b/dist/debian/valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "18 July, 2018" "valentina man page" +.TH valentina 1 "27 December, 2018" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -179,6 +179,8 @@ The path to output destination folder. By default the directory at which the app .RB "Page bottom margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." .IP "-r, --rotate " .RB "Rotation in degrees (one of predefined, " "export mode" "). Default value is " "180" ". 0 is no-rotate. Valid values: 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90, 180. Each value show how many times details will be rotated. For example 180 mean two times (360/180=2) by 180 degree." +.IP "--followGrainline" +.RB "Order detail to follow grainline direction (" "export mode" "). .IP "-c, --crop" .RB "Auto crop unused length (" "export mode" ")." .IP "-u, --unite" diff --git a/src/app/valentina/core/vcmdexport.cpp b/src/app/valentina/core/vcmdexport.cpp index 1bbd0bbcb..938bbb646 100644 --- a/src/app/valentina/core/vcmdexport.cpp +++ b/src/app/valentina/core/vcmdexport.cpp @@ -227,6 +227,11 @@ void VCommandLine::InitOptions(VCommandLineOptions &options, QMap "60, 72, 90, 180"), translate("VCommandLine", "Angle"))); + optionsIndex.insert(LONG_OPTION_FOLLOW_GRAINLINE, index++); + options.append(new QCommandLineOption(QStringList() << LONG_OPTION_FOLLOW_GRAINLINE, + translate("VCommandLine", + "Order detail to follow grainline direction (export mode)."))); + optionsIndex.insert(LONG_OPTION_CROP, index++); options.append(new QCommandLineOption(QStringList() << SINGLE_OPTION_CROP << LONG_OPTION_CROP, translate("VCommandLine", "Auto crop unused length (export mode)."))); @@ -568,6 +573,7 @@ VLayoutGeneratorPtr VCommandLine::DefaultGenerator() const } } diag.SetFields(margins); + diag.SetFollowGrainline(parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_FOLLOW_GRAINLINE)))); diag.DialogAccepted(); // filling VLayoutGenerator diff --git a/src/app/valentina/dialogs/dialoglayoutsettings.cpp b/src/app/valentina/dialogs/dialoglayoutsettings.cpp index 6324c1572..2276c738c 100644 --- a/src/app/valentina/dialogs/dialoglayoutsettings.cpp +++ b/src/app/valentina/dialogs/dialoglayoutsettings.cpp @@ -232,6 +232,18 @@ void DialogLayoutSettings::SetRotate(bool state) ui->groupBoxRotate->setChecked(state); } +//--------------------------------------------------------------------------------------------------------------------- +bool DialogLayoutSettings::GetFollowGrainline() const +{ + return ui->checkBoxFollowGrainline->isChecked(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutSettings::SetFollowGrainline(bool state) +{ + ui->checkBoxFollowGrainline->setChecked(state); +} + //--------------------------------------------------------------------------------------------------------------------- int DialogLayoutSettings::GetIncrease() const { @@ -564,6 +576,7 @@ void DialogLayoutSettings::DialogAccepted() generator->SetPaperWidth(GetPaperWidth()); generator->SetShift(static_cast(qFloor(GetShift()))); generator->SetRotate(GetRotate()); + generator->SetFollowGrainline(GetFollowGrainline()); generator->SetRotationIncrease(GetIncrease()); generator->SetAutoCrop(GetAutoCrop()); generator->SetSaveLength(IsSaveLength()); @@ -655,6 +668,7 @@ void DialogLayoutSettings::RestoreDefaults() SetShift(VSettings::GetDefLayoutShift()); SetGroup(VSettings::GetDefLayoutGroup()); SetRotate(VSettings::GetDefLayoutRotate()); + SetFollowGrainline(VSettings::GetDefLayoutFollowGrainline()); SetIncrease(VSettings::GetDefLayoutRotationIncrease()); SetFields(GetDefPrinterFields()); SetIgnoreAllFields(VSettings::GetDefIgnoreAllFields()); @@ -1004,6 +1018,7 @@ void DialogLayoutSettings::ReadSettings() const qreal height = UnitConvertor(settings->GetLayoutPaperHeight(), Unit::Px, LayoutUnit()); SheetSize(QSizeF(width, height)); SetGroup(settings->GetLayoutGroup()); + SetFollowGrainline(settings->GetLayoutFollowGrainline()); SetRotate(settings->GetLayoutRotate()); SetIncrease(settings->GetLayoutRotationIncrease()); SetAutoCrop(settings->GetLayoutAutoCrop()); @@ -1031,6 +1046,7 @@ void DialogLayoutSettings::WriteSettings() const settings->SetLayoutPaperWidth(GetPaperWidth()); settings->SetLayoutShift(GetShift()); settings->SetLayoutRotate(GetRotate()); + settings->SetLayoutFollowGrainline(GetFollowGrainline()); settings->SetLayoutRotationIncrease(GetIncrease()); settings->SetLayoutAutoCrop(GetAutoCrop()); settings->SetLayoutSaveLength(IsSaveLength()); diff --git a/src/app/valentina/dialogs/dialoglayoutsettings.h b/src/app/valentina/dialogs/dialoglayoutsettings.h index 204507873..d8ed76e9d 100644 --- a/src/app/valentina/dialogs/dialoglayoutsettings.h +++ b/src/app/valentina/dialogs/dialoglayoutsettings.h @@ -76,6 +76,9 @@ public: bool GetRotate() const; void SetRotate(bool state); + bool GetFollowGrainline() const; + void SetFollowGrainline(bool state); + int GetIncrease() const; bool SetIncrease(int increase); diff --git a/src/app/valentina/dialogs/dialoglayoutsettings.ui b/src/app/valentina/dialogs/dialoglayoutsettings.ui index f3bb1c0c2..143f0090a 100644 --- a/src/app/valentina/dialogs/dialoglayoutsettings.ui +++ b/src/app/valentina/dialogs/dialoglayoutsettings.ui @@ -6,8 +6,8 @@ 0 0 - 600 - 533 + 601 + 600 @@ -326,6 +326,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -416,6 +429,20 @@ + + + + Qt::Horizontal + + + + + + + Follow grainline + + + diff --git a/src/libs/vlayout/vlayoutgenerator.cpp b/src/libs/vlayout/vlayoutgenerator.cpp index 192f4cd88..8b0f832f7 100644 --- a/src/libs/vlayout/vlayoutgenerator.cpp +++ b/src/libs/vlayout/vlayoutgenerator.cpp @@ -55,6 +55,7 @@ VLayoutGenerator::VLayoutGenerator(QObject *parent) state(LayoutErrors::NoError), shift(0), rotate(true), + followGrainline(false), rotationIncrease(180), autoCrop(false), saveLength(false), @@ -140,6 +141,7 @@ void VLayoutGenerator::Generate() paper.SetLayoutWidth(bank->GetLayoutWidth()); paper.SetPaperIndex(static_cast(papers.count())); paper.SetRotate(rotate); + paper.SetFollowGrainline(followGrainline); paper.SetRotationIncrease(rotationIncrease); paper.SetSaveLength(saveLength); do @@ -347,6 +349,7 @@ void VLayoutGenerator::GatherPages() paper.SetLayoutWidth(bank->GetLayoutWidth()); paper.SetPaperIndex(static_cast(i)); paper.SetRotate(rotate); + paper.SetFollowGrainline(followGrainline); paper.SetRotationIncrease(rotationIncrease); paper.SetSaveLength(saveLength); paper.SetDetails(nDetails.at(i)); @@ -412,6 +415,7 @@ void VLayoutGenerator::UnitePages() paper.SetLayoutWidth(bank->GetLayoutWidth()); paper.SetPaperIndex(static_cast(i)); paper.SetRotate(rotate); + paper.SetFollowGrainline(followGrainline); paper.SetRotationIncrease(rotationIncrease); paper.SetSaveLength(saveLength); paper.SetDetails(nDetails.at(i)); @@ -533,6 +537,18 @@ void VLayoutGenerator::SetRotate(bool value) rotate = value; } +//--------------------------------------------------------------------------------------------------------------------- +bool VLayoutGenerator::GetFollowGrainline() const +{ + return followGrainline; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutGenerator::SetFollowGrainline(bool value) +{ + followGrainline = value; +} + //--------------------------------------------------------------------------------------------------------------------- qreal VLayoutGenerator::GetPaperWidth() const { diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h index 86a4c7903..83b7ec2b0 100644 --- a/src/libs/vlayout/vlayoutgenerator.h +++ b/src/libs/vlayout/vlayoutgenerator.h @@ -90,6 +90,9 @@ public: bool GetRotate() const; void SetRotate(bool value); + bool GetFollowGrainline() const; + void SetFollowGrainline(bool value); + int GetRotationIncrease() const; void SetRotationIncrease(int value); @@ -132,6 +135,7 @@ private: LayoutErrors state; quint32 shift; bool rotate; + bool followGrainline; int rotationIncrease; bool autoCrop; bool saveLength; diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index 57fe0bc48..f2537f09f 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -143,6 +143,18 @@ void VLayoutPaper::SetRotate(bool value) d->localRotate = d->globalRotate; } +//--------------------------------------------------------------------------------------------------------------------- +bool VLayoutPaper::GetFollowGrainline() const +{ + return d->followGrainline; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutPaper::SetFollowGrainline(bool value) +{ + d->followGrainline = value; +} + //--------------------------------------------------------------------------------------------------------------------- int VLayoutPaper::GetRotationIncrease() const { @@ -242,8 +254,7 @@ bool VLayoutPaper::AddToSheet(const VLayoutPiece &detail, std::atomic_bool &stop for (int i=1; i<= detailEdgesCount; ++i) { VPosition *thread = new VPosition(d->globalContour, j, detail, i, &stop, d->localRotate, - d->localRotationIncrease, - d->saveLength); + d->localRotationIncrease, d->saveLength, d->followGrainline); //Info for debug #ifdef LAYOUT_DEBUG thread->setPaperIndex(d->paperIndex); diff --git a/src/libs/vlayout/vlayoutpaper.h b/src/libs/vlayout/vlayoutpaper.h index baebdc800..80724885d 100644 --- a/src/libs/vlayout/vlayoutpaper.h +++ b/src/libs/vlayout/vlayoutpaper.h @@ -78,6 +78,9 @@ public: bool GetRotate() const; void SetRotate(bool value); + bool GetFollowGrainline() const; + void SetFollowGrainline(bool value); + int GetRotationIncrease() const; void SetRotationIncrease(int value); diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h index 5a4555366..24391c84e 100644 --- a/src/libs/vlayout/vlayoutpaper_p.h +++ b/src/libs/vlayout/vlayoutpaper_p.h @@ -53,7 +53,8 @@ public: localRotate(true), globalRotationIncrease(180), localRotationIncrease(180), - saveLength(false) + saveLength(false), + followGrainline(false) {} VLayoutPaperData(int height, @@ -67,7 +68,8 @@ public: localRotate(true), globalRotationIncrease(180), localRotationIncrease(180), - saveLength(false) + saveLength(false), + followGrainline(false) {} VLayoutPaperData(const VLayoutPaperData &paper) @@ -81,7 +83,8 @@ public: localRotate(paper.localRotate), globalRotationIncrease(paper.globalRotationIncrease), localRotationIncrease(paper.localRotationIncrease), - saveLength(paper.saveLength) + saveLength(paper.saveLength), + followGrainline(paper.followGrainline) {} ~VLayoutPaperData() {} @@ -100,6 +103,7 @@ public: int globalRotationIncrease; int localRotationIncrease; bool saveLength; + bool followGrainline; private: VLayoutPaperData& operator=(const VLayoutPaperData&) Q_DECL_EQ_DELETE; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 65f62e197..fff3ceeda 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -673,6 +673,10 @@ void VLayoutPiece::SetGrainline(const VGrainlineData& geom, const VContainer* pa return; } + d->grainlineEnabled = true; + d->grainlineArrowType = geom.GetArrowType(); + d->grainlineAngle = qRadiansToDegrees(dAng); + QPointF pt2(pt1.x() + dLen * qCos(dAng), pt1.y() - dLen * qSin(dAng)); const qreal dArrowLen = ToPixel(0.5, *pattern->GetPatternUnit()); @@ -709,6 +713,24 @@ QVector VLayoutPiece::GetGrainline() const return Map(d->grainlinePoints); } +//--------------------------------------------------------------------------------------------------------------------- +bool VLayoutPiece::IsGrainlineEnabled() const +{ + return d->grainlineEnabled; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VLayoutPiece::GrainlineAngle() const +{ + return d->grainlineAngle; +} + +//--------------------------------------------------------------------------------------------------------------------- +ArrowType VLayoutPiece::GrainlineArrowType() const +{ + return d->grainlineArrowType; +} + //--------------------------------------------------------------------------------------------------------------------- QTransform VLayoutPiece::GetMatrix() const { @@ -1195,7 +1217,7 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const { SCASSERT(parent != nullptr) - if (d->grainlinePoints.count() < 2) + if (not d->grainlineEnabled || d->grainlinePoints.count() < 2) { return; } diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index 34fe5de9d..5a55a15dd 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -104,6 +104,9 @@ public: void SetGrainline(const VGrainlineData& geom, const VContainer *pattern); QVector GetGrainline() const; + bool IsGrainlineEnabled() const; + qreal GrainlineAngle() const; + ArrowType GrainlineArrowType() const; QTransform GetMatrix() const; void SetMatrix(const QTransform &matrix); diff --git a/src/libs/vlayout/vlayoutpiece_p.h b/src/libs/vlayout/vlayoutpiece_p.h index 1ebdaaec9..f4207e284 100644 --- a/src/libs/vlayout/vlayoutpiece_p.h +++ b/src/libs/vlayout/vlayoutpiece_p.h @@ -61,6 +61,9 @@ public: detailLabel(), patternInfo(), grainlinePoints(), + grainlineArrowType(ArrowType::atFront), + grainlineAngle(0), + grainlineEnabled(false), m_tmDetail(), m_tmPattern(), m_placeLabels() @@ -79,6 +82,9 @@ public: detailLabel(detail.detailLabel), patternInfo(detail.patternInfo), grainlinePoints(detail.grainlinePoints), + grainlineArrowType(detail.grainlineArrowType), + grainlineAngle(detail.grainlineAngle), + grainlineEnabled(detail.grainlineEnabled), m_tmDetail(detail.m_tmDetail), m_tmPattern(detail.m_tmPattern), m_placeLabels(detail.m_placeLabels) @@ -118,6 +124,10 @@ public: /** @brief grainlineInfo line */ QVector grainlinePoints; + ArrowType grainlineArrowType; + qreal grainlineAngle; + bool grainlineEnabled; + /** @brief m_tmDetail text manager for laying out detail info */ VTextManager m_tmDetail; diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp index c8d59617a..f47597012 100644 --- a/src/libs/vlayout/vposition.cpp +++ b/src/libs/vlayout/vposition.cpp @@ -51,7 +51,7 @@ //--------------------------------------------------------------------------------------------------------------------- VPosition::VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, std::atomic_bool *stop, - bool rotate, int rotationIncrease, bool saveLength) + bool rotate, int rotationIncrease, bool saveLength, bool followGainline) : QRunnable(), bestResult(VBestSquare(gContour.GetSize(), saveLength)), gContour(gContour), @@ -65,7 +65,8 @@ VPosition::VPosition(const VContour &gContour, int j, const VLayoutPiece &detail stop(stop), rotate(rotate), rotationIncrease(rotationIncrease), - angle_between(0) + angle_between(0), + followGrainline(followGainline) { if ((rotationIncrease >= 1 && rotationIncrease <= 180 && 360 % rotationIncrease == 0) == false) { @@ -81,32 +82,39 @@ void VPosition::run() return; } - // We should use copy of the detail. - VLayoutPiece workDetail = detail; - - int dEdge = i;// For mirror detail edge will be different - if (CheckCombineEdges(workDetail, j, dEdge)) + if (not followGrainline || not detail.IsGrainlineEnabled()) { - #ifdef LAYOUT_DEBUG - # ifdef SHOW_CANDIDATE_BEST - DrawDebug(gContour, workDetail, frame+2, paperIndex, detailsCount, details); - # endif - #endif + // We should use copy of the detail. + VLayoutPiece workDetail = detail; - SaveCandidate(bestResult, workDetail, j, dEdge, BestFrom::Combine); - } - frame = frame + 3; + int dEdge = i;// For mirror detail edge will be different + if (CheckCombineEdges(workDetail, j, dEdge)) + { + #ifdef LAYOUT_DEBUG + # ifdef SHOW_CANDIDATE_BEST + DrawDebug(gContour, workDetail, frame+2, paperIndex, detailsCount, details); + # endif + #endif - if (rotate) - { - Rotate(rotationIncrease); - } - else - { - if (gContour.GetContour().isEmpty()) + SaveCandidate(bestResult, workDetail, j, dEdge, BestFrom::Combine); + } + frame = frame + 3; + + if (rotate) { Rotate(rotationIncrease); } + else + { + if (gContour.GetContour().isEmpty()) + { + Rotate(rotationIncrease); + } + } + } + else + { + FollowGrainline(); } } @@ -351,14 +359,14 @@ bool VPosition::CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge) } //--------------------------------------------------------------------------------------------------------------------- -bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, int angle) const +bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, qreal angle) const { const QLineF globalEdge = gContour.GlobalEdge(j); bool flagSquare = false; if (detail.IsForceFlipping()) { - detail.Mirror(globalEdge); + detail.Mirror(not followGrainline ? globalEdge : QLineF(10, 10, 10, 100)); } RotateEdges(detail, globalEdge, dEdge, angle); @@ -391,6 +399,26 @@ bool VPosition::CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, int a return flagSquare; } +//--------------------------------------------------------------------------------------------------------------------- +void VPosition::RotateOnAngle(qreal angle) +{ + // We should use copy of the detail. + VLayoutPiece workDetail = detail; + + if (CheckRotationEdges(workDetail, j, i, angle)) + { + #ifdef LAYOUT_DEBUG + # ifdef SHOW_CANDIDATE_BEST + ++frame; + DrawDebug(gContour, workDetail, frame, paperIndex, detailsCount, details); + # endif + #endif + + SaveCandidate(bestResult, workDetail, j, i, BestFrom::Rotation); + } + ++frame; +} + //--------------------------------------------------------------------------------------------------------------------- VPosition::CrossingType VPosition::Crossing(const VLayoutPiece &detail) const { @@ -449,7 +477,7 @@ void VPosition::CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, con } //--------------------------------------------------------------------------------------------------------------------- -void VPosition::RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, int angle) const +void VPosition::RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, qreal angle) const { QLineF detailEdge; if (gContour.GetContour().isEmpty()) @@ -487,21 +515,31 @@ void VPosition::Rotate(int increase) return; } - // We should use copy of the detail. - VLayoutPiece workDetail = detail; + RotateOnAngle(angle); + } +} - if (CheckRotationEdges(workDetail, j, i, angle)) - { - #ifdef LAYOUT_DEBUG - # ifdef SHOW_CANDIDATE_BEST - ++frame; - DrawDebug(gContour, workDetail, frame, paperIndex, detailsCount, details); - # endif - #endif +//--------------------------------------------------------------------------------------------------------------------- +void VPosition::FollowGrainline() +{ + if (stop->load()) + { + return; + } - SaveCandidate(bestResult, workDetail, j, i, BestFrom::Rotation); - } - ++frame; + QLineF detailGrainline(10, 10, 100, 10); + detailGrainline.setAngle(detail.GrainlineAngle()); + + const qreal angle = detailGrainline.angleTo(FabricGrainline()); + + if (detail.GrainlineArrowType() == ArrowType::atFront) + { + RotateOnAngle(angle); + } + + if (detail.GrainlineArrowType() == ArrowType::atRear) + { + RotateOnAngle(angle+180); } } diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h index f764d514e..5b0326352 100644 --- a/src/libs/vlayout/vposition.h +++ b/src/libs/vlayout/vposition.h @@ -44,7 +44,7 @@ class VPosition : public QRunnable { public: VPosition(const VContour &gContour, int j, const VLayoutPiece &detail, int i, std::atomic_bool *stop, bool rotate, - int rotationIncrease, bool saveLength); + int rotationIncrease, bool saveLength, bool followGainline); virtual ~VPosition() override{} quint32 getPaperIndex() const; @@ -83,6 +83,7 @@ private: * @brief angle_between keep angle between global edge and detail edge. Need for optimization rotation. */ qreal angle_between; + bool followGrainline; enum class CrossingType : char { @@ -103,19 +104,34 @@ private: void SaveCandidate(VBestSquare &bestResult, const VLayoutPiece &detail, int globalI, int detJ, BestFrom type); bool CheckCombineEdges(VLayoutPiece &detail, int j, int &dEdge); - bool CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, int angle) const; + bool CheckRotationEdges(VLayoutPiece &detail, int j, int dEdge, qreal angle) const; + + void RotateOnAngle(qreal angle); CrossingType Crossing(const VLayoutPiece &detail) const; bool SheetContains(const QRectF &rect) const; void CombineEdges(VLayoutPiece &detail, const QLineF &globalEdge, const int &dEdge); - void RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, int angle) const; + void RotateEdges(VLayoutPiece &detail, const QLineF &globalEdge, int dEdge, qreal angle) const; static QPainterPath ShowDirection(const QLineF &edge); static QPainterPath DrawContour(const QVector &points); static QPainterPath DrawDetails(const QVector &details); void Rotate(int increase); + void FollowGrainline(); + + QLineF FabricGrainline() const; }; +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VPosition::FabricGrainline return fabric gainline accoding to paper orientation + * @return fabric gainline line + */ +inline QLineF VPosition::FabricGrainline() const +{ + return gContour.GetHeight() >= gContour.GetWidth() ? QLineF(10, 10, 10, 100) : QLineF(10, 10, 100, 10); +} + #endif // VPOSITION_H diff --git a/src/libs/vmisc/commandoptions.cpp b/src/libs/vmisc/commandoptions.cpp index 6051fe298..1ea4650c2 100644 --- a/src/libs/vmisc/commandoptions.cpp +++ b/src/libs/vmisc/commandoptions.cpp @@ -127,6 +127,8 @@ const QString LONG_OPTION_TILED_PDF_TOP_MARGIN = QStringLiteral("tiledtmargin const QString LONG_OPTION_TILED_PDF_BOTTOM_MARGIN = QStringLiteral("tiledbmargin"); const QString LONG_OPTION_TILED_PDF_LANDSCAPE = QStringLiteral("tiledLandscape"); +const QString LONG_OPTION_FOLLOW_GRAINLINE = QStringLiteral("followGrainline"); + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AllKeys return list with all command line keys (short and long forms). Used for testing on conflicts. @@ -175,7 +177,8 @@ QStringList AllKeys() << LONG_OPTION_TILED_PDF_RIGHT_MARGIN << LONG_OPTION_TILED_PDF_TOP_MARGIN << LONG_OPTION_TILED_PDF_BOTTOM_MARGIN - << LONG_OPTION_TILED_PDF_LANDSCAPE; + << LONG_OPTION_TILED_PDF_LANDSCAPE + << LONG_OPTION_FOLLOW_GRAINLINE; return list; } diff --git a/src/libs/vmisc/commandoptions.h b/src/libs/vmisc/commandoptions.h index d32caa64f..41bc678e1 100644 --- a/src/libs/vmisc/commandoptions.h +++ b/src/libs/vmisc/commandoptions.h @@ -123,6 +123,7 @@ extern const QString LONG_OPTION_TILED_PDF_RIGHT_MARGIN; extern const QString LONG_OPTION_TILED_PDF_TOP_MARGIN; extern const QString LONG_OPTION_TILED_PDF_BOTTOM_MARGIN; extern const QString LONG_OPTION_TILED_PDF_LANDSCAPE; +extern const QString LONG_OPTION_FOLLOW_GRAINLINE; QStringList AllKeys(); diff --git a/src/libs/vmisc/vsettings.cpp b/src/libs/vmisc/vsettings.cpp index 04cadabb8..548672818 100644 --- a/src/libs/vmisc/vsettings.cpp +++ b/src/libs/vmisc/vsettings.cpp @@ -85,6 +85,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutPaperHeight, (QLatin1Strin Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutPaperWidth, (QLatin1String("layout/paperWidth"))) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutShift, (QLatin1String("layout/shift"))) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutRotate, (QLatin1String("layout/Rotate"))) +Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutFollowGrainline, (QLatin1String("layout/followGrainline"))) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutRotationIncrease, (QLatin1String("layout/rotationIncrease"))) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutAutoCrop, (QLatin1String("layout/autoCrop"))) Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutSaveLength, (QLatin1String("layout/saveLength"))) @@ -370,6 +371,24 @@ void VSettings::SetLayoutRotate(bool value) setValue(*settingLayoutRotate, value); } +//--------------------------------------------------------------------------------------------------------------------- +bool VSettings::GetLayoutFollowGrainline() const +{ + return value(*settingLayoutFollowGrainline, GetDefLayoutFollowGrainline()).toBool(); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VSettings::GetDefLayoutFollowGrainline() +{ + return false; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VSettings::SetLayoutFollowGrainline(bool value) +{ + setValue(*settingLayoutFollowGrainline, value); +} + //--------------------------------------------------------------------------------------------------------------------- int VSettings::GetLayoutRotationIncrease() const { diff --git a/src/libs/vmisc/vsettings.h b/src/libs/vmisc/vsettings.h index 3894565db..66385f899 100644 --- a/src/libs/vmisc/vsettings.h +++ b/src/libs/vmisc/vsettings.h @@ -97,6 +97,10 @@ public: static bool GetDefLayoutRotate(); void SetLayoutRotate(bool value); + bool GetLayoutFollowGrainline() const; + static bool GetDefLayoutFollowGrainline(); + void SetLayoutFollowGrainline(bool value); + int GetLayoutRotationIncrease() const; static int GetDefLayoutRotationIncrease(); void SetLayoutRotationIncrease(int value);