da847a
da847a
#include <tools replicator.h=""></tools>
da847a
da847a
#include <tools tool.h=""></tools>
da847a
da847a
#include <toonz tapplication.h=""></toonz>
da847a
#include <toonz txsheet.h=""></toonz>
da847a
#include <toonz txsheethandle.h=""></toonz>
da847a
#include <toonz txshlevelhandle.h=""></toonz>
da847a
#include <toonz tframehandle.h=""></toonz>
da847a
#include <toonz tobjecthandle.h=""></toonz>
da847a
#include <toonz dpiscale.h=""></toonz>
6cb657
#include <toonz toonzscene.h=""></toonz>
6cb657
#include <toonz sceneproperties.h=""></toonz>
da847a
da847a
#include <tgl.h></tgl.h>
6cb657
#include <tpixelutils.h></tpixelutils.h>
da847a
da847a
da847a
da847a
const int TReplicator::multiplierSoftLimit = 32;
da847a
const int TReplicator::multiplierLimit = 256;
da847a
da847a
da847a
//************************************************************************
da847a
//    TReplicator implementation
da847a
//************************************************************************
da847a
da847a
TReplicator::TReplicator(TMetaObject &object):
d9135c
  TAssistantBase(object),
d9135c
  m_idSkipFirst("skipFirst"),
d9135c
  m_idSkipLast("skipLast")
d9135c
{
d9135c
  addProperty( createSpinProperty(m_idSkipFirst, getSkipFirst(), 0) );
d9135c
  addProperty( createSpinProperty(m_idSkipLast, getSkipLast(), 0) );
d9135c
}
d9135c
d9135c
//---------------------------------------------------------------------------------------------------
d9135c
d9135c
void
d9135c
TReplicator::updateTranslation() const {
d9135c
  TAssistantBase::updateTranslation();
d9135c
  setTranslation(m_idSkipFirst, tr("Skip First Tracks"));
d9135c
  setTranslation(m_idSkipLast, tr("Skip Last Tracks"));
d9135c
}
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
int
da847a
TReplicator::getMultipler() const
da847a
  { return 1; }
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
void
da847a
TReplicator::getModifiers(const TAffine&, TInputModifier::List&) const
da847a
  { }
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
void
da847a
TReplicator::getPoints(const TAffine&, PointList&) const
da847a
  { }
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
TIntProperty*
da847a
TReplicator::createCountProperty(const TStringId &id, int def, int min, int max) {
da847a
  if (min < 0) min = 0;
da847a
  if (def < min) def = min;
da847a
  if (max <= 0) max = multiplierSoftLimit;
da847a
  return createSpinProperty(id, def, min, max);
da847a
}
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
void
d9135c
TReplicator::transformPoints(const TAffine &aff, PointList &points, int i0, int i1) {
d9135c
  int cnt = (int)points.size();
d9135c
  if (i0 < 0) i0 = 0;
d9135c
  if (i1 > cnt) i1 = cnt;
d9135c
  if (i0 >= i1) return;
d9135c
  points.reserve(points.size() + i1 - i0);
d9135c
  for(int i = i0; i < i1; ++i)
da847a
    points.push_back(aff*points[i]);
da847a
}
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
void
da847a
TReplicator::drawReplicatorPoints(const TPointD *points, int count) {
6cb657
  TPixelD color = (drawFlags & DRAW_ERROR) ? colorError : colorBase;
6cb657
  color.m *= 0.3;
6cb657
  TPixelD colorBack = makeContrastColor(color);
da847a
  
da847a
  glPushAttrib(GL_ALL_ATTRIB_BITS);
da847a
  tglEnableBlending();
da847a
  tglEnableLineSmooth(true, 1.0 * lineWidthScale);
da847a
  
da847a
  double pixelSize = sqrt(tglGetPixelSize2());
da847a
  TPointD a(5*pixelSize, 0), da(0, 0.5*pixelSize);
da847a
  TPointD b(0, 5*pixelSize), db(0.5*pixelSize, 0);
da847a
  
da847a
  for(int i = 0; i < count; ++i) {
da847a
    const TPointD &p = points[i];
6cb657
    tglColor(colorBack);
da847a
    tglDrawSegment(p - a - da, p + a - da);
da847a
    tglDrawSegment(p - b - db, p + b - db);
6cb657
    tglColor(color);
da847a
    tglDrawSegment(p - a + da, p + a + da);
da847a
    tglDrawSegment(p - b + db, p + b + db);
da847a
  }
da847a
da847a
  glPopAttrib();
da847a
}
da847a
da847a
//---------------------------------------------------------------------------------------------------
da847a
da847a
int
da847a
TReplicator::scanReplicators(
da847a
  TTool *tool,
da847a
  PointList *inOutPoints,
da847a
  TInputModifier::List *outModifiers,
da847a
  bool draw,
da847a
  bool enabledOnly,
da847a
  bool markEnabled,
da847a
  bool drawPoints,
da847a
  TImage *skipImage )
da847a
{
da847a
  bool outOfLimit = false;
da847a
  long long multiplier = 0;
da847a
  int inputPoints = inOutPoints ? (int)inOutPoints->size() : 0;
da847a
  
da847a
  if (tool)
da847a
  if (TToolViewer *viewer = tool->getViewer())
da847a
  if (TApplication *application = tool->getApplication())
da847a
  if (TXshLevelHandle *levelHandle = application->getCurrentLevel())
da847a
  if (TXshLevel *level = levelHandle->getLevel())
da847a
  if (TXshSimpleLevel *simpleLevel = level->getSimpleLevel())
da847a
  if (TFrameHandle *frameHandle = application->getCurrentFrame())
da847a
  if (TXsheetHandle *XsheetHandle = application->getCurrentXsheet())
da847a
  if (TXsheet *Xsheet = XsheetHandle->getXsheet())
da847a
  {
6cb657
    ToonzScene *scene = Xsheet->getScene();
6cb657
    TSceneProperties *props = scene ? scene->getProperties() : nullptr;
da847a
    TPointD dpiScale = getCurrentDpiScale(simpleLevel, tool->getCurrentFid());
da847a
    int frame = frameHandle->getFrame();
da847a
    int count = Xsheet->getColumnCount();
da847a
    TAffine worldToTrack;
da847a
    if ( tool->getToolType() & TTool::LevelTool
da847a
      && !application->getCurrentObject()->isSpline() )
da847a
    {
da847a
      worldToTrack.a11 /= dpiScale.x;
da847a
      worldToTrack.a22 /= dpiScale.y;
da847a
    }
da847a
6cb657
    for(int i = 0; i < count; ++i) {
da847a
      if (TXshColumn *column = Xsheet->getColumn(i))
da847a
      if (column->isCamstandVisible())
da847a
      if (column->isPreviewVisible())
da847a
      if (TImageP image = Xsheet->getCell(frame, i).getImage(false))
da847a
      if (image != skipImage)
da847a
      if (image->getType() == TImage::META)
da847a
      if (TMetaImage *metaImage = dynamic_cast<tmetaimage*>(image.getPointer()))</tmetaimage*>
da847a
      {
6cb657
        TPixelD origColor = TAssistantBase::colorBase;
da847a
        TAffine imageToTrack = worldToTrack * tool->getColumnMatrix(i);
6cb657
        if (draw) {
6cb657
          if (props)
6cb657
            TAssistantBase::colorBase = toPixelD(props->getColorFilterColor( column->getColorFilterId() ));
6cb657
          TAssistantBase::colorBase.m *= column->getOpacity()/255.0;
6cb657
          glPushMatrix();
6cb657
          tglMultMatrix(imageToTrack);
6cb657
        }
da847a
da847a
        TMetaImage::Reader reader(*metaImage);
6cb657
        for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i) {
da847a
          if (*i)
da847a
          if (const TReplicator *replicator = (*i)->getHandler<treplicator>())</treplicator>
da847a
          if (!enabledOnly || replicator->getEnabled())
da847a
          {
da847a
            if (!multiplier) multiplier = 1;
da847a
            bool enabled = replicator->getEnabled();
da847a
            
da847a
            if (enabled) {
da847a
              int m = replicator->getMultipler();
da847a
              if (m <= 0) m = 1;
da847a
              if (multiplier*m > multiplierLimit) {
da847a
                outOfLimit = true;
da847a
              } else {
da847a
                multiplier *= m;
da847a
                if (inOutPoints)
da847a
                  replicator->getPoints(imageToTrack, *inOutPoints);
da847a
                if (outModifiers)
da847a
                  replicator->getModifiers(imageToTrack, *outModifiers);
da847a
              }
da847a
            }
da847a
            
da847a
            if (draw) {
da847a
              unsigned int oldFlags = TReplicator::drawFlags;
da847a
              if (enabled && outOfLimit) TReplicator::drawFlags |= TReplicator::DRAW_ERROR;
da847a
              replicator->draw(viewer, enabled && markEnabled);
da847a
              TReplicator::drawFlags = oldFlags;
da847a
            }
da847a
          }
6cb657
        } // for each meta object
6cb657
        
6cb657
        if (draw) {
6cb657
          glPopMatrix();
6cb657
          TAssistantBase::colorBase = origColor;
6cb657
        }
da847a
      }
6cb657
    } // for each column
da847a
  }
da847a
  
da847a
  
da847a
  if (drawPoints && inOutPoints && (int)inOutPoints->size() > inputPoints)
da847a
    drawReplicatorPoints(
da847a
      inOutPoints->data() + inputPoints,
da847a
      (int)inOutPoints->size() - inputPoints );
da847a
  
da847a
  return (int)multiplier;
da847a
}
da847a