1 /************************************************************************
2 **
3 ** @file vbestsquare.cpp
4 ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5 ** @date 21 1, 2015
6 **
7 ** @brief
8 ** @copyright
9 ** This source code is part of the Valentina project, a pattern making
10 ** program, whose allow create and modeling patterns of clothing.
11 ** Copyright (C) 2013-2015 Valentina project
12 ** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13 **
14 ** Valentina is free software: you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation, either version 3 of the License, or
17 ** (at your option) any later version.
18 **
19 ** Valentina is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ** GNU General Public License for more details.
23 **
24 ** You should have received a copy of the GNU General Public License
25 ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
26 **
27 *************************************************************************/
28
29 #include "vbestsquare.h"
30 #include "vbestsquare_p.h"
31 #include "../vgeometry/vgeometrydef.h"
32
33 #include <QMatrix>
34
35 namespace
36 {
37 //---------------------------------------------------------------------------------------------------------------------
Square(QSizeF size)38 Q_DECL_CONSTEXPR inline qint64 Square(QSizeF size)
39 {
40 return static_cast<qint64>(size.width()*size.height());
41 }
42 } // anonymous namespace
43
44 //---------------------------------------------------------------------------------------------------------------------
VBestSquare()45 VBestSquare::VBestSquare()
46 : d(new VBestSquareData())
47 {}
48
49 //---------------------------------------------------------------------------------------------------------------------
VBestSquare(QSizeF sheetSize,bool saveLength,bool isPortrait)50 VBestSquare::VBestSquare(QSizeF sheetSize, bool saveLength, bool isPortrait)
51 : d(new VBestSquareData(sheetSize, saveLength, isPortrait))
52 {}
53
54 //---------------------------------------------------------------------------------------------------------------------
VBestSquare(const VBestSquare & res)55 VBestSquare::VBestSquare(const VBestSquare &res)
56 : d(res.d)
57 {}
58
59 //---------------------------------------------------------------------------------------------------------------------
~VBestSquare()60 VBestSquare::~VBestSquare()
61 {}
62
63 //---------------------------------------------------------------------------------------------------------------------
operator =(const VBestSquare & res)64 VBestSquare &VBestSquare::operator=(const VBestSquare &res)
65 {
66 if ( &res == this )
67 {
68 return *this;
69 }
70 d = res.d;
71 return *this;
72 }
73
74 #ifdef Q_COMPILER_RVALUE_REFS
75 //---------------------------------------------------------------------------------------------------------------------
VBestSquare(const VBestSquare && res)76 VBestSquare::VBestSquare(const VBestSquare &&res) Q_DECL_NOTHROW
77 : d(res.d)
78 {}
79
80 //---------------------------------------------------------------------------------------------------------------------
operator =(VBestSquare && res)81 VBestSquare &VBestSquare::operator=(VBestSquare &&res) Q_DECL_NOTHROW
82 {
83 std::swap(d, res.d);
84 return *this;
85 }
86 #endif
87
88 //---------------------------------------------------------------------------------------------------------------------
NewResult(const VBestSquareResData & data)89 void VBestSquare::NewResult(const VBestSquareResData &data)
90 {
91 auto SaveResult = [this, data]()
92 {
93 d->valideResult = true;
94 d->data = data;
95 };
96
97 const qint64 candidateSquare = Square(data.bestSize);
98
99 if (candidateSquare > 0 && data.type >= d->data.type && candidateSquare <= Square(d->data.bestSize))
100 {
101 if (not HasValidResult())
102 {
103 SaveResult(); // First result
104 }
105 else
106 {
107 if (d->saveLength)
108 {
109 if (VFuzzyOnAxis(data.depthPosition, d->data.depthPosition)
110 && IsImprovedSidePosition(data.sidePosition))
111 {
112 SaveResult();
113 }
114 else if (data.depthPosition < d->data.depthPosition)
115 {
116 SaveResult();
117 }
118 }
119 else
120 {
121 if (IsImprovedSidePosition(data.sidePosition) || VFuzzyOnAxis(data.sidePosition, d->data.sidePosition))
122 {
123 SaveResult();
124 }
125 }
126 }
127 }
128 }
129
130 //---------------------------------------------------------------------------------------------------------------------
NewResult(const VBestSquare & best)131 void VBestSquare::NewResult(const VBestSquare &best)
132 {
133 if (best.d->isValid && best.HasValidResult() && d->saveLength == best.IsSaveLength())
134 {
135 NewResult(best.BestResultData());
136 }
137 }
138
139 //---------------------------------------------------------------------------------------------------------------------
BestSize() const140 QSizeF VBestSquare::BestSize() const
141 {
142 return d->data.bestSize;
143 }
144
145 //---------------------------------------------------------------------------------------------------------------------
GContourEdge() const146 int VBestSquare::GContourEdge() const
147 {
148 return d->data.globalI;
149 }
150
151 //---------------------------------------------------------------------------------------------------------------------
DetailEdge() const152 int VBestSquare::DetailEdge() const
153 {
154 return d->data.detJ;
155 }
156
157 //---------------------------------------------------------------------------------------------------------------------
Matrix() const158 QTransform VBestSquare::Matrix() const
159 {
160 return d->data.resMatrix;
161 }
162
163 //---------------------------------------------------------------------------------------------------------------------
HasValidResult() const164 bool VBestSquare::HasValidResult() const
165 {
166 return d->valideResult;
167 }
168
169 //---------------------------------------------------------------------------------------------------------------------
Mirror() const170 bool VBestSquare::Mirror() const
171 {
172 return d->data.resMirror;
173 }
174
175 //---------------------------------------------------------------------------------------------------------------------
Type() const176 BestFrom VBestSquare::Type() const
177 {
178 return d->data.type;
179 }
180
181 //---------------------------------------------------------------------------------------------------------------------
IsTerminatedByException() const182 bool VBestSquare::IsTerminatedByException() const
183 {
184 return d->terminatedByException;
185 }
186
187 //---------------------------------------------------------------------------------------------------------------------
ReasonTerminatedByException() const188 QString VBestSquare::ReasonTerminatedByException() const
189 {
190 return d->exceptionReason;
191 }
192
193 //---------------------------------------------------------------------------------------------------------------------
TerminatedByException(const QString & reason)194 void VBestSquare::TerminatedByException(const QString &reason)
195 {
196 d->valideResult = false;
197 d->terminatedByException = true;
198 d->exceptionReason = reason;
199 }
200
201 //---------------------------------------------------------------------------------------------------------------------
BestResultData() const202 VBestSquareResData VBestSquare::BestResultData() const
203 {
204 return d->data;
205 }
206
207 //---------------------------------------------------------------------------------------------------------------------
IsSaveLength() const208 bool VBestSquare::IsSaveLength() const
209 {
210 return d->saveLength;
211 }
212
213 //---------------------------------------------------------------------------------------------------------------------
IsImprovedSidePosition(qreal sidePosition) const214 bool VBestSquare::IsImprovedSidePosition(qreal sidePosition) const
215 {
216 const bool lessThan = d->data.sidePosition < sidePosition;
217 const bool greaterThan = d->data.sidePosition > sidePosition;
218
219 return IsPortrait() ? greaterThan : lessThan;
220 }
221
222 //---------------------------------------------------------------------------------------------------------------------
IsPortrait() const223 bool VBestSquare::IsPortrait() const
224 {
225 return d->isPortrait;
226 }
227