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