b52c5a
b52c5a
#include <tools replicator.h=""></tools>
b52c5a
b52c5a
#include <tools tool.h=""></tools>
b52c5a
b52c5a
#include <toonz tapplication.h=""></toonz>
b52c5a
#include <toonz txsheet.h=""></toonz>
b52c5a
#include <toonz txsheethandle.h=""></toonz>
b52c5a
#include <toonz txshlevelhandle.h=""></toonz>
b52c5a
#include <toonz tframehandle.h=""></toonz>
b52c5a
#include <toonz tobjecthandle.h=""></toonz>
b52c5a
#include <toonz dpiscale.h=""></toonz>
b52c5a
b52c5a
#include <tgl.h></tgl.h>
b52c5a
b52c5a
b52c5a
b52c5a
const int TReplicator::multiplierSoftLimit = 32;
b52c5a
const int TReplicator::multiplierLimit = 256;
b52c5a
b52c5a
b52c5a
//************************************************************************
b52c5a
//    TReplicator implementation
b52c5a
//************************************************************************
b52c5a
b52c5a
TReplicator::TReplicator(TMetaObject &object):
b52c5a
  TAssistantBase(object) { }
b52c5a
b52c5a
//---------------------------------------------------------------------------------------------------
b52c5a
b52c5a
int
b52c5a
TReplicator::getMultipler() const
b52c5a
  { return 1; }
b52c5a
b52c5a
//---------------------------------------------------------------------------------------------------
b52c5a
b52c5a
void
b52c5a
TReplicator::getModifiers(const TAffine&, TInputModifier::List&) const
b52c5a
  { }
b52c5a
b52c5a
//---------------------------------------------------------------------------------------------------
b52c5a
370a7e
void
370a7e
TReplicator::getPoints(const TAffine&, PointList&) const
370a7e
  { }
370a7e
370a7e
//---------------------------------------------------------------------------------------------------
370a7e
12df32
TIntProperty*
12df32
TReplicator::createCountProperty(const TStringId &id, int def, int min, int max) {
12df32
  if (min < 0) min = 0;
12df32
  if (def < min) def = min;
850a0b
  if (max <= 0) max = multiplierSoftLimit;
00b1a0
  return createSpinProperty(id, def, min, max);
12df32
}
12df32
12df32
//---------------------------------------------------------------------------------------------------
12df32
370a7e
void
370a7e
TReplicator::transformPoints(const TAffine &aff, PointList &points, int count) {
370a7e
  points.reserve(points.size() + count);
370a7e
  for(int i = 0; i < count; ++i)
370a7e
    points.push_back(aff*points[i]);
370a7e
}
370a7e
370a7e
//---------------------------------------------------------------------------------------------------
370a7e
370a7e
void
370a7e
TReplicator::drawReplicatorPoints(const TPointD *points, int count) {
370a7e
  double colorBlack[4] = { 0.0, 0.0, 0.0, 0.3 };
370a7e
  double colorWhite[4] = { 1.0, 1.0, 1.0, 0.3 };
370a7e
  
370a7e
  glPushAttrib(GL_ALL_ATTRIB_BITS);
370a7e
  tglEnableBlending();
370a7e
  tglEnableLineSmooth(true, 1.0 * lineWidthScale);
370a7e
  
370a7e
  double pixelSize = sqrt(tglGetPixelSize2());
370a7e
  TPointD a(5*pixelSize, 0), da(0, 0.5*pixelSize);
370a7e
  TPointD b(0, 5*pixelSize), db(0.5*pixelSize, 0);
370a7e
  
370a7e
  for(int i = 0; i < count; ++i) {
370a7e
    const TPointD &p = points[i];
370a7e
    glColor4dv(colorWhite);
370a7e
    tglDrawSegment(p - a - da, p + a - da);
370a7e
    tglDrawSegment(p - b - db, p + b - db);
370a7e
    glColor4dv(colorBlack);
370a7e
    tglDrawSegment(p - a + da, p + a + da);
370a7e
    tglDrawSegment(p - b + db, p + b + db);
370a7e
  }
370a7e
370a7e
  glPopAttrib();
370a7e
}
370a7e
370a7e
//---------------------------------------------------------------------------------------------------
370a7e
b52c5a
int
b52c5a
TReplicator::scanReplicators(
b52c5a
  TTool *tool,
370a7e
  PointList *inOutPoints,
b52c5a
  TInputModifier::List *outModifiers,
b52c5a
  bool draw,
b52c5a
  bool enabledOnly,
b52c5a
  bool markEnabled,
370a7e
  bool drawPoints,
b52c5a
  TImage *skipImage )
b52c5a
{
d9b9f4
  bool outOfLimit = false;
b52c5a
  long long multiplier = 0;
370a7e
  int inputPoints = inOutPoints ? (int)inOutPoints->size() : 0;
b52c5a
  
b52c5a
  if (tool)
b52c5a
  if (TToolViewer *viewer = tool->getViewer())
b52c5a
  if (TApplication *application = tool->getApplication())
b52c5a
  if (TXshLevelHandle *levelHandle = application->getCurrentLevel())
b52c5a
  if (TXshLevel *level = levelHandle->getLevel())
b52c5a
  if (TXshSimpleLevel *simpleLevel = level->getSimpleLevel())
b52c5a
  if (TFrameHandle *frameHandle = application->getCurrentFrame())
b52c5a
  if (TXsheetHandle *XsheetHandle = application->getCurrentXsheet())
b52c5a
  if (TXsheet *Xsheet = XsheetHandle->getXsheet())
b52c5a
  {
b52c5a
    TPointD dpiScale = getCurrentDpiScale(simpleLevel, tool->getCurrentFid());
b52c5a
    int frame = frameHandle->getFrame();
b52c5a
    int count = Xsheet->getColumnCount();
b52c5a
    TAffine worldToTrack;
b52c5a
    if ( tool->getToolType() & TTool::LevelTool
b52c5a
      && !application->getCurrentObject()->isSpline() )
b52c5a
    {
b52c5a
      worldToTrack.a11 /= dpiScale.x;
b52c5a
      worldToTrack.a22 /= dpiScale.y;
b52c5a
    }
b52c5a
b52c5a
    for(int i = 0; i < count; ++i)
b52c5a
      if (TXshColumn *column = Xsheet->getColumn(i))
b52c5a
      if (column->isCamstandVisible())
b52c5a
      if (column->isPreviewVisible())
b52c5a
      if (TImageP image = Xsheet->getCell(frame, i).getImage(false))
b52c5a
      if (image != skipImage)
b52c5a
      if (image->getType() == TImage::META)
b52c5a
      if (TMetaImage *metaImage = dynamic_cast<tmetaimage*>(image.getPointer()))</tmetaimage*>
b52c5a
      {
b52c5a
        TAffine imageToTrack = worldToTrack * tool->getColumnMatrix(i);
b52c5a
        if (draw) { glPushMatrix(); tglMultMatrix(imageToTrack); }
b52c5a
b52c5a
        TMetaImage::Reader reader(*metaImage);
b52c5a
        for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i)
b52c5a
          if (*i)
b52c5a
          if (const TReplicator *replicator = (*i)->getHandler<treplicator>())</treplicator>
b52c5a
          if (!enabledOnly || replicator->getEnabled())
b52c5a
          {
b52c5a
            if (!multiplier) multiplier = 1;
b52c5a
            bool enabled = replicator->getEnabled();
b52c5a
            
b52c5a
            if (enabled) {
b52c5a
              int m = replicator->getMultipler();
b52c5a
              if (m <= 0) m = 1;
d9b9f4
              if (multiplier*m > multiplierLimit) {
d9b9f4
                outOfLimit = true;
d9b9f4
              } else {
d9b9f4
                multiplier *= m;
370a7e
                if (inOutPoints)
370a7e
                  replicator->getPoints(imageToTrack, *inOutPoints);
d9b9f4
                if (outModifiers)
d9b9f4
                  replicator->getModifiers(imageToTrack, *outModifiers);
d9b9f4
              }
b52c5a
            }
b52c5a
            
d9b9f4
            if (draw) {
d9b9f4
              unsigned int oldFlags = TReplicator::drawFlags;
d9b9f4
              if (enabled && outOfLimit) TReplicator::drawFlags |= TReplicator::DRAW_ERROR;
d9b9f4
              replicator->draw(viewer, enabled && markEnabled);
d9b9f4
              TReplicator::drawFlags = oldFlags;
d9b9f4
            }
b52c5a
          }
b52c5a
b52c5a
        if (draw) glPopMatrix();
b52c5a
      }
b52c5a
  }
b52c5a
  
370a7e
  
370a7e
  if (drawPoints && inOutPoints && (int)inOutPoints->size() > inputPoints)
370a7e
    drawReplicatorPoints(
370a7e
      inOutPoints->data() + inputPoints,
370a7e
      (int)inOutPoints->size() - inputPoints );
370a7e
  
b52c5a
  return (int)multiplier;
b52c5a
}
b52c5a