Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/strokesdata.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/rasterimagedata.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/trasterimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int findStroke(const TVectorImageP &img, TStroke *stroke, const TAffine &aff) {
Shinya Kitaoka 120a6e
  TRectD strokeBBox = aff * stroke->getBBox();
Shinya Kitaoka 120a6e
  int count         = img->getStrokeCount();
Shinya Kitaoka 120a6e
  for (int i = 0; i < count; i++) {
Shinya Kitaoka 120a6e
    TStroke *s  = img->getStroke(i);
Shinya Kitaoka 120a6e
    TRectD bbox = s->getBBox();
Shinya Kitaoka 120a6e
    if (tdistance2(bbox.getP00(), strokeBBox.getP00()) +
Shinya Kitaoka 120a6e
            tdistance2(bbox.getP11(), strokeBBox.getP11()) >
Shinya Kitaoka 120a6e
        0.001)
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    return i;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine findOffset(const TVectorImageP &srcImg, const TVectorImageP &img) {
Shinya Kitaoka 120a6e
  TAffine offset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP tarImg = img;
Shinya Kitaoka 120a6e
  if (!tarImg) return offset;
Shinya Kitaoka 120a6e
  if (tarImg->getStrokeCount() == 0 || srcImg->getStrokeCount() == 0)
Shinya Kitaoka 120a6e
    return offset;
Shinya Kitaoka 120a6e
  bool done = false;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  while (!done)
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)srcImg->getStrokeCount(); i++) {
Shinya Kitaoka 120a6e
      TStroke *stroke = srcImg->getStroke(i);
Shinya Kitaoka 120a6e
      assert(stroke);
Shinya Kitaoka 120a6e
      if (findStroke(tarImg, stroke, offset) >= 0) {
Shinya Kitaoka 120a6e
        offset = offset * TTranslation(10, -10);
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      done = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  return offset;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke getStrokeByRect(TRectD r) {
Shinya Kitaoka 120a6e
  TStroke stroke;
Shinya Kitaoka 120a6e
  if (r.isEmpty()) return stroke;
Shinya Kitaoka 120a6e
  vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
  points.push_back(r.getP00());
Shinya Kitaoka 120a6e
  points.push_back((r.getP00() + r.getP01()) * 0.5);
Shinya Kitaoka 120a6e
  points.push_back(r.getP01());
Shinya Kitaoka 120a6e
  points.push_back((r.getP01() + r.getP11()) * 0.5);
Shinya Kitaoka 120a6e
  points.push_back(r.getP11());
Shinya Kitaoka 120a6e
  points.push_back((r.getP11() + r.getP10()) * 0.5);
Shinya Kitaoka 120a6e
  points.push_back(r.getP10());
Shinya Kitaoka 120a6e
  points.push_back((r.getP10() + r.getP00()) * 0.5);
Shinya Kitaoka 120a6e
  points.push_back(r.getP00());
Shinya Kitaoka 120a6e
  stroke.reshape(&(points[0]), points.size());
Shinya Kitaoka 120a6e
  stroke.setSelfLoop(true);
Shinya Kitaoka 120a6e
  return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// StrokesData
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokesData::setImage(TVectorImageP image, const std::set<int> &indices) {</int>
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  if (indices.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // indices e' un set; splitImage si aspetta un vector
Shinya Kitaoka 120a6e
  vector<int> indicesV(indices.begin(), indices.end());</int>
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  m_image = image->splitImage(indicesV, false);
Shinya Kitaoka 120a6e
  if (m_image->getPalette() == 0) {
Shinya Kitaoka 120a6e
    // nel caso lo stroke sia un path (e quindi senza palette)
Shinya Kitaoka 120a6e
    m_image->setPalette(new TPalette());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StrokesData::getImage(TVectorImageP image, std::set<int> &indices,</int>
Shinya Kitaoka 120a6e
                           bool insert) const {
Shinya Kitaoka 120a6e
  if (!m_image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP srcImg = m_image;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
  if (insert) {
Shinya Kitaoka 120a6e
    TAffine offset    = findOffset(srcImg, image);
Shinya Kitaoka 120a6e
    UINT oldImageSize = image->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    image->mergeImage(srcImg, offset, false);
Shinya Kitaoka 120a6e
    UINT newImageSize = image->getStrokeCount();
Shinya Kitaoka 120a6e
    indices.clear();
Shinya Kitaoka 120a6e
    for (UINT sI = oldImageSize; sI < newImageSize; sI++) indices.insert(sI);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    std::vector<int> indicesToInsert(indices.begin(), indices.end());</int>
Shinya Kitaoka 120a6e
    if (indicesToInsert.empty()) return;
Shinya Kitaoka 120a6e
    image->insertImage(srcImg, indicesToInsert);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToonzImageData *StrokesData::toToonzImageData(
Shinya Kitaoka 120a6e
    const TToonzImageP &imageToPaste) const {
Shinya Kitaoka 120a6e
  double dpix, dpiy;
Shinya Kitaoka 120a6e
  imageToPaste->getDpi(dpix, dpiy);
Shinya Kitaoka 120a6e
  assert(dpix != 0 && dpiy != 0);
Shinya Kitaoka 120a6e
  TScale sc(dpix / Stage::inch, dpiy / Stage::inch);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox = sc * m_image->getBBox();
Shinya Kitaoka 120a6e
  bbox.x0     = tfloor(bbox.x0);
Shinya Kitaoka 120a6e
  bbox.y0     = tfloor(bbox.y0);
Shinya Kitaoka 120a6e
  bbox.x1     = tceil(bbox.x1);
Shinya Kitaoka 120a6e
  bbox.y1     = tceil(bbox.y1);
Shinya Kitaoka 120a6e
  TDimension size(bbox.getLx(), bbox.getLy());
Shinya Kitaoka 120a6e
  TToonzImageP app = ToonzImageUtils::vectorToToonzImage(
Shinya Kitaoka 120a6e
      m_image, sc, m_image->getPalette(), bbox.getP00(), size, 0, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<trectd> rects;</trectd>
Shinya Kitaoka 120a6e
  vector<tstroke> strokes;</tstroke>
Shinya Kitaoka 120a6e
  TStroke stroke = getStrokeByRect(bbox);
Shinya Kitaoka 120a6e
  strokes.push_back(stroke);
Shinya Kitaoka 120a6e
  ToonzImageData *data = new ToonzImageData();
Shinya Kitaoka 120a6e
  data->setData(app->getRaster(), m_image->getPalette(), dpix, dpiy,
Shinya Kitaoka 120a6e
                TDimension(), rects, strokes, strokes, TAffine());
Shinya Kitaoka 120a6e
  return data;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FullColorImageData *StrokesData::toFullColorImageData(
Shinya Kitaoka 120a6e
    const TRasterImageP &imageToPaste) const {
Shinya Kitaoka 120a6e
  double dpix, dpiy;
Shinya Kitaoka 120a6e
  imageToPaste->getDpi(dpix, dpiy);
Shinya Kitaoka 120a6e
  assert(dpix != 0 && dpiy != 0);
Shinya Kitaoka 120a6e
  TScale sc(dpix / Stage::inch, dpiy / Stage::inch);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox = sc * m_image->getBBox();
Shinya Kitaoka 120a6e
  bbox.x0     = tfloor(bbox.x0);
Shinya Kitaoka 120a6e
  bbox.y0     = tfloor(bbox.y0);
Shinya Kitaoka 120a6e
  bbox.x1     = tceil(bbox.x1);
Shinya Kitaoka 120a6e
  bbox.y1     = tceil(bbox.y1);
Shinya Kitaoka 120a6e
  TDimension size(bbox.getLx(), bbox.getLy());
Shinya Kitaoka 120a6e
  TRasterImageP app = TRasterImageUtils::vectorToFullColorImage(
Shinya Kitaoka 120a6e
      m_image, sc, m_image->getPalette(), bbox.getP00(), size, 0, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<trectd> rects;</trectd>
Shinya Kitaoka 120a6e
  vector<tstroke> strokes;</tstroke>
Shinya Kitaoka 120a6e
  TStroke stroke = getStrokeByRect(bbox);
Shinya Kitaoka 120a6e
  strokes.push_back(stroke);
Shinya Kitaoka 120a6e
  FullColorImageData *data = new FullColorImageData();
Shinya Kitaoka 120a6e
  data->setData(app->getRaster(), m_image->getPalette(), dpix, dpiy,
Shinya Kitaoka 120a6e
                TDimension(), rects, strokes, strokes, TAffine());
Shinya Kitaoka 120a6e
  return data;
Toshihiro Shimizu 890ddd
}