Seamly2D
Code documentation
vbank.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ** @file vbank.cpp
3  ** @author Douglas S Caskey
4  ** @date Dec 27, 2022
5  **
6  ** @copyright
7  ** Copyright (C) 2017 - 2022 Seamly, LLC
8  ** https://github.com/fashionfreedom/seamly2d
9  **
10  ** @brief
11  ** Seamly2D is free software: you can redistribute it and/or modify
12  ** it under the terms of the GNU General Public License as published by
13  ** the Free Software Foundation, either version 3 of the License, or
14  ** (at your option) any later version.
15  **
16  ** Seamly2D is distributed in the hope that it will be useful,
17  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  ** GNU General Public License for more details.
20  **
21  ** You should have received a copy of the GNU General Public License
22  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
23  **************************************************************************/
24 
25 /************************************************************************
26  **
27  ** @file vbank.cpp
28  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
29  ** @date 11 1, 2015
30  **
31  ** @brief
32  ** @copyright
33  ** This source code is part of the Valentina project, a pattern making
34  ** program, whose allow create and modeling patterns of clothing.
35  ** Copyright (C) 2013-2015 Valentina project
36  ** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
37  **
38  ** Valentina is free software: you can redistribute it and/or modify
39  ** it under the terms of the GNU General Public License as published by
40  ** the Free Software Foundation, either version 3 of the License, or
41  ** (at your option) any later version.
42  **
43  ** Valentina is distributed in the hope that it will be useful,
44  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
45  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46  ** GNU General Public License for more details.
47  **
48  ** You should have received a copy of the GNU General Public License
49  ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
50  **
51  *************************************************************************/
52 
53 #include "vbank.h"
54 
55 #include <climits>
56 
57 #include "../vmisc/diagnostic.h"
58 #include "../vmisc/logging.h"
59 #include "vlayoutpiece.h"
60 
61 QT_WARNING_PUSH
62 QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
63 QT_WARNING_DISABLE_INTEL(1418)
64 
65 Q_LOGGING_CATEGORY(lBank, "layout.bank")
66 
68 
69 // An annoying char define, from the Windows team in <rpcndr.h>
70 // #define small char
71 // http://stuartjames.info/Journal/c--visual-studio-2012-vs2012--win8--converting-projects-up-some-conflicts-i-found.aspx
72 #if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
73 #pragma push_macro("small")
74 #undef small
75 #endif
76 
77 //---------------------------------------------------------------------------------------------------------------------
79  : pieces(QVector<VLayoutPiece>())
80  , unsorted(QHash<int, qint64>())
81  , big(QHash<int, qint64>())
82  , middle(QHash<int, qint64>())
83  , small(QHash<int, qint64>())
84  , layoutWidth(0)
85  , caseType(Cases::CaseDesc)
86  , prepare(false), diagonal(0)
87 {}
88 
89 //---------------------------------------------------------------------------------------------------------------------
90 qreal VBank::GetLayoutWidth() const
91 {
92  return layoutWidth;
93 }
94 
95 //---------------------------------------------------------------------------------------------------------------------
96 void VBank::SetLayoutWidth(const qreal &value)
97 {
98  layoutWidth = value;
99  Reset();
100 }
101 
102 //---------------------------------------------------------------------------------------------------------------------
104 {
105  this->pieces = pieces;
106  Reset();
107 }
108 
109 //---------------------------------------------------------------------------------------------------------------------
111 {
112  if (prepare == false)
113  {
114  return -1;
115  }
116 
117  if (LeftArrange() == 0)
118  {
119  if (unsorted.isEmpty())
120  {
121  return -1;
122  }
123  else
124  {
125  PrepareGroup();
126  }
127  }
128 
129  switch (caseType)
130  {
132  return GetNextThreeGroups();
133  case Cases::CaseTwoGroup:
134  return GetNextTwoGroups();
135  case Cases::CaseDesc:
136  return GetNextDescGroup();
137  default:
138  return -1;
139  }
140 }
141 
142 //---------------------------------------------------------------------------------------------------------------------
144 {
145  if (i >= 0 && i < pieces.size())
146  {
147  return pieces.at(i);
148  }
149  else
150  {
151  return VLayoutPiece();
152  }
153 }
154 
155 //---------------------------------------------------------------------------------------------------------------------
156 void VBank::Arranged(int i)
157 {
158  if (big.contains(i))
159  {
160  big.remove(i);
161  return;
162  }
163 
164  if (middle.contains(i))
165  {
166  middle.remove(i);
167  return;
168  }
169 
170  if (small.contains(i))
171  {
172  small.remove(i);
173  }
174 }
175 
176 //---------------------------------------------------------------------------------------------------------------------
178 {
179  if (big.contains(i))
180  {
181  unsorted.insert(i, big.value(i));
182  big.remove(i);
183  return;
184  }
185 
186  if (middle.contains(i))
187  {
188  unsorted.insert(i, middle.value(i));
189  middle.remove(i);
190  return;
191  }
192 
193  if (small.contains(i))
194  {
195  unsorted.insert(i, small.value(i));
196  small.remove(i);
197  }
198 }
199 
200 //---------------------------------------------------------------------------------------------------------------------
202 {
203  if (layoutWidth <= 0)
204  {
205  qCDebug(lBank, "Preparing data for layout error: Layout paper sheet <= 0");
206  prepare = false;
207  return prepare;
208  }
209 
210  if (pieces.isEmpty())
211  {
212  qCDebug(lBank, "Preparing data for layout error: List of pieces is empty");
213  prepare = false;
214  return prepare;
215  }
216 
217  diagonal = 0;
218  for (int i=0; i < pieces.size(); ++i)
219  {
220  pieces[i].SetLayoutWidth(layoutWidth);
221  pieces[i].SetLayoutAllowancePoints();
222 
223  const qreal d = pieces.at(i).Diagonal();
224  if (d > diagonal)
225  {
226  diagonal = d;
227  }
228 
229  const qint64 square = pieces.at(i).Square();
230  if (square <= 0)
231  {
232  qCDebug(lBank, "Preparing data for layout error: Detail squere <= 0");
233  prepare = false;
234  return prepare;
235  }
236  unsorted.insert(i, square);
237  }
238 
239  PrepareGroup();
240 
241  prepare = true;
242  return prepare;
243 }
244 
245 //---------------------------------------------------------------------------------------------------------------------
247 {
248  prepare = false;
249  unsorted.clear();
250  big.clear();
251  middle.clear();
252  small.clear();
253  diagonal = 0;
254 }
255 
256 //---------------------------------------------------------------------------------------------------------------------
257 void VBank::SetCaseType(Cases caseType)
258 {
259  this->caseType = caseType;
260 }
261 
262 //---------------------------------------------------------------------------------------------------------------------
264 {
265  return unsorted.count() + big.count() + middle.count() + small.count();
266 }
267 
268 //---------------------------------------------------------------------------------------------------------------------
270 {
271  return big.count() + middle.count() + small.count();
272 }
273 
274 //---------------------------------------------------------------------------------------------------------------------
276 {
277  return diagonal;
278 }
279 
280 //---------------------------------------------------------------------------------------------------------------------
282 {
283  return pieces.size() - allPieceCount();
284 }
285 
286 //---------------------------------------------------------------------------------------------------------------------
288 {
289  switch (caseType)
290  {
293  break;
294  case Cases::CaseTwoGroup:
296  break;
297  case Cases::CaseDesc:
299  break;
300  default:
301  break;
302  }
303 }
304 
305 //---------------------------------------------------------------------------------------------------------------------
307 {
308  qint64 sMax = LLONG_MIN;
309  qint64 sMin = LLONG_MAX;
310 
311  SqMaxMin(sMax, sMin);
312 
313  const qint64 s1 = sMax - (sMax - sMin)/3;
314  const qint64 s2 = sMin + (sMax - sMin)/3;
315 
317  while (i != unsorted.constEnd())
318  {
319  if (i.value() > s1)
320  {
321  big.insert(i.key(), i.value());
322  }
323  else if (s1 >= i.value() && i.value() > s2)
324  {
325  middle.insert(i.key(), i.value());
326  }
327  else
328  {
329  small.insert(i.key(), i.value());
330  }
331  ++i;
332  }
333  unsorted.clear();
334 }
335 
336 //---------------------------------------------------------------------------------------------------------------------
338 {
339  qint64 sMax = LLONG_MIN;
340  qint64 sMin = LLONG_MAX;
341 
342  SqMaxMin(sMax, sMin);
343 
344  const qint64 s = (sMax + sMin)/2;
346  while (i != unsorted.constEnd())
347  {
348  if (i.value() >= s)
349  {
350  big.insert(i.key(), i.value());
351  }
352  else
353  {
354  small.insert(i.key(), i.value());
355  }
356  ++i;
357  }
358  unsorted.clear();
359 }
360 
361 //---------------------------------------------------------------------------------------------------------------------
363 {
364  big = unsorted;
365  unsorted.clear();
366 }
367 
368 //---------------------------------------------------------------------------------------------------------------------
370 {
371  if (big.isEmpty() == false)
372  {
373  QHash<int, qint64>::const_iterator i = big.constBegin();
374  return i.key();
375  }
376 
377  if (middle.isEmpty() == false)
378  {
380  return i.key();
381  }
382 
383  if (small.isEmpty() == false)
384  {
385  QHash<int, qint64>::const_iterator i = small.constBegin();
386  return i.key();
387  }
388 
389  return -1;
390 }
391 
392 //---------------------------------------------------------------------------------------------------------------------
394 {
395  if (big.isEmpty() == false)
396  {
397  QHash<int, qint64>::const_iterator i = big.constBegin();
398  return i.key();
399  }
400 
401  if (small.isEmpty() == false)
402  {
403  QHash<int, qint64>::const_iterator i = small.constBegin();
404  return i.key();
405  }
406 
407  return -1;
408 }
409 
410 //---------------------------------------------------------------------------------------------------------------------
412 {
413  int index = -1;
414  qint64 sMax = LLONG_MIN;
415 
416  QHash<int, qint64>::const_iterator i = big.constBegin();
417  while (i != big.constEnd())
418  {
419  if (i.value() > sMax)
420  {
421  sMax = i.value();
422  index = i.key();
423  }
424 
425  ++i;
426  }
427 
428  return index;
429 }
430 
431 //---------------------------------------------------------------------------------------------------------------------
432 void VBank::SqMaxMin(qint64 &sMax, qint64 &sMin) const
433 {
434  sMax = LLONG_MIN;
435  sMin = LLONG_MAX;
436 
438  while (i != unsorted.constEnd())
439  {
440  if (i.value() < sMin)
441  {
442  sMin = i.value();
443  }
444 
445  if (i.value() > sMax)
446  {
447  sMax = i.value();
448  }
449  ++i;
450  }
451 
452 }
453 
454 #if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
455 #pragma pop_macro("small")
456 #endif
void PrepareThreeGroups()
Definition: vbank.cpp:306
bool prepare
Definition: vbank.h:110
int LeftArrange() const
Definition: vbank.cpp:269
void SetCaseType(Cases caseType)
Definition: vbank.cpp:257
QVector< VLayoutPiece > pieces
Definition: vbank.h:100
void SetLayoutWidth(const qreal &value)
Definition: vbank.cpp:96
int GetNextThreeGroups() const
Definition: vbank.cpp:369
int ArrangedCount() const
Definition: vbank.cpp:281
int allPieceCount() const
Definition: vbank.cpp:263
VBank()
Definition: vbank.cpp:78
VLayoutPiece getPiece(int i) const
Definition: vbank.cpp:143
QHash< int, qint64 > middle
Definition: vbank.h:104
void setPieces(const QVector< VLayoutPiece > &pieces)
Definition: vbank.cpp:103
QHash< int, qint64 > big
Definition: vbank.h:103
qreal GetLayoutWidth() const
Definition: vbank.cpp:90
QHash< int, qint64 > unsorted
Definition: vbank.h:101
void PrepareGroup()
Definition: vbank.cpp:287
qreal layoutWidth
Definition: vbank.h:107
void PrepareDescGroup()
Definition: vbank.cpp:362
int GetTiket()
Definition: vbank.cpp:110
void Arranged(int i)
Definition: vbank.cpp:156
qreal diagonal
Definition: vbank.h:111
void Reset()
Definition: vbank.cpp:246
QHash< int, qint64 > small
Definition: vbank.h:105
void PrepareTwoGroups()
Definition: vbank.cpp:337
qreal GetBiggestDiagonal() const
Definition: vbank.cpp:275
int GetNextTwoGroups() const
Definition: vbank.cpp:393
int GetNextDescGroup() const
Definition: vbank.cpp:411
Cases caseType
Definition: vbank.h:109
bool Prepare()
Definition: vbank.cpp:201
void NotArranged(int i)
Definition: vbank.cpp:177
void SqMaxMin(qint64 &sMax, qint64 &sMin) const
Definition: vbank.cpp:432
Cases
Definition: vbank.h:71
@ CaseDesc
@ CaseThreeGroup
@ CaseTwoGroup