All Classes Namespaces Functions Variables Enumerations Properties Pages
pegbaraligner.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 */
17 #include "pegbaraligner.h"
18 
19 #include <QDebug>
20 #include <editor.h>
21 #include <pencilerror.h>
22 
23 #include <bitmapimage.h>
24 #include <layerbitmap.h>
25 #include <layermanager.h>
26 
27 PegStatus::PegStatus(ErrorCode code, QPoint point)
28  : Status(code), point(point)
29 {
30 }
31 
32 PegBarAligner::PegBarAligner(Editor* editor, QRect searchRect) :
33  mEditor(editor), mPegSearchRect(searchRect)
34 {
35 }
36 
37 
38 Status PegBarAligner::align(const QStringList& layers)
39 {
40  LayerBitmap* layerBitmap = static_cast<LayerBitmap*>(mEditor->layers()->currentLayer());
41  BitmapImage* img = layerBitmap->getBitmapImageAtFrame(mEditor->currentFrame());
42  PegStatus result = findPoint(*img);
43 
44  if (!result.ok())
45  {
46  return Status(Status::FAIL, tr("Peg hole not found!\nCheck selection, and please try again.", "PegBar error message"));
47  }
48 
49  const int pegX = result.point.x();
50  const int pegY = result.point.y();
51 
52  for (int i = 0; i < layers.count(); i++)
53  {
54  layerBitmap = static_cast<LayerBitmap*>(mEditor->layers()->findLayerByName(layers.at(i)));
55  for (int k = layerBitmap->firstKeyFramePosition(); k <= layerBitmap->getMaxKeyFramePosition(); k++)
56  {
57  if (!layerBitmap->keyExists(k)) { continue; }
58 
59  img = layerBitmap->getBitmapImageAtFrame(k);
60  img->enableAutoCrop(false);
61 
62  result = findPoint(*img);
63  if (!result.ok())
64  {
65  const QString errorDescription = tr("Peg bar not found at %2, %1").arg(k).arg(layerBitmap->name());
66  return Status(result.code(), errorDescription);
67  }
68  img->moveTopLeft(QPoint(img->left() + (pegX - result.point.x()), img->top() + (pegY - result.point.y())));
69 
70  mEditor->frameModified(img->pos());
71  }
72  }
73 
74  mEditor->deselectAll();
75 
76  return Status::OK;
77 }
78 
79 
80 PegStatus PegBarAligner::findPoint(const BitmapImage& image) const
81 {
82  QPoint point;
83  const int left = mPegSearchRect.left();
84  const int right = mPegSearchRect.right();
85  const int top = mPegSearchRect.top();
86  const int bottom = mPegSearchRect.bottom();
87  const int grayValue = mGrayThreshold;
88 
89  bool foundX = false;
90 
91  for (int x = left; x <= right && !foundX; x++)
92  {
93  for (int y = top; y <= bottom; y++)
94  {
95  const QRgb& scan = image.constScanLine(x,y);
96  if (qAlpha(scan) == 255 && qGray(scan) < grayValue)
97  {
98  foundX = true;
99  point.setX(x);
100 
101  break;
102  }
103  }
104  }
105 
106  bool foundY = false;
107  for (int y = top; y <= bottom && !foundY; y++)
108  {
109  for (int x = left; x <= right; x++)
110  {
111  const QRgb& scan = image.constScanLine(x,y);
112  if (qAlpha(scan) == 255 && qGray(scan) < grayValue)
113  {
114  foundY = true;
115  point.setY(y);
116 
117  break;
118  }
119  }
120  }
121 
122  if (foundX && foundY) {
123  return PegStatus(Status::OK, point);
124  }
125  return Status::FAIL;
126 }
int right() const const
const T & at(int i) const const
QTextStream & right(QTextStream &stream)
int x() const const
int y() const const
void frameModified(int frameNumber)
This should be emitted after modifying the frame content.
QTextStream & left(QTextStream &stream)
int count(const T &value) const const
int top() const const
int left() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int bottom() const const
void setX(int x)
void setY(int y)
Definition: editor.h:55