9cf8be
9cf8be
9cf8be
#include <tools modifierassistants.h="" modifiers=""></tools>
9cf8be
9cf8be
// TnzTools includes
9cf8be
#include <tools tool.h=""></tools>
9cf8be
9cf8be
// TnzLib includes
9cf8be
#include <toonz tapplication.h=""></toonz>
9cf8be
#include <toonz txshlevelhandle.h=""></toonz>
9cf8be
#include <toonz txsheethandle.h=""></toonz>
9cf8be
#include <toonz txsheet.h=""></toonz>
9cf8be
#include <toonz tframehandle.h=""></toonz>
8a3cf9
#include <toonz tobjecthandle.h=""></toonz>
9f0c16
#include <toonz dpiscale.h=""></toonz>
9cf8be
9cf8be
// TnzCore includes
362052
#include <tgl.h></tgl.h>
9cf8be
#include <tmetaimage.h></tmetaimage.h>
9cf8be
9cf8be
9cf8be
//*****************************************************************************************
9cf8be
//    TModifierAssistants::Modifier implementation
9cf8be
//*****************************************************************************************
9cf8be
9cf8be
9cf8be
TModifierAssistants::Modifier::Modifier(TTrackHandler &handler):
9cf8be
  TTrackModifier(handler),
9cf8be
  initialized()
9cf8be
{ }
9cf8be
9cf8be
9cf8be
TTrackPoint
9cf8be
TModifierAssistants::Modifier::calcPoint(double originalIndex) {
9cf8be
  TTrackPoint p = TTrackModifier::calcPoint(originalIndex);
9cf8be
  return guidelines.empty() > 0 ? p : guidelines.front()->transformPoint(p);
9cf8be
}
9cf8be
9cf8be
9cf8be
//*****************************************************************************************
9cf8be
//    TModifierAssistants implementation
9cf8be
//*****************************************************************************************
9cf8be
9cf8be
362052
TModifierAssistants::TModifierAssistants(bool drawOnly):
362052
  drawOnly(drawOnly),
9cf8be
  sensitiveLength(50.0) { }
9cf8be
9cf8be
362052
bool
362052
TModifierAssistants::scanAssistants(
362052
  const TPointD *positions,
362052
  int positionsCount,
362052
  TGuidelineList *outGuidelines,
362052
  bool draw ) const
362052
{
362052
  bool found = false;
9cf8be
  if (TInputManager *manager = getManager())
9cf8be
  if (TInputHandler *handler = manager->getHandler())
362052
  if (TTool *tool = handler->inputGetTool())
9cf8be
  if (TToolViewer *viewer = tool->getViewer())
9cf8be
  if (TApplication *application = tool->getApplication())
9f0c16
  if (TXshLevelHandle *levelHandle = application->getCurrentLevel())
9f0c16
  if (TXshLevel *level = levelHandle->getLevel())
9f0c16
  if (TXshSimpleLevel *simpleLevel = level->getSimpleLevel())
9cf8be
  if (TFrameHandle *frameHandle = application->getCurrentFrame())
9cf8be
  if (TXsheetHandle *XsheetHandle = application->getCurrentXsheet())
9cf8be
  if (TXsheet *Xsheet = XsheetHandle->getXsheet())
9cf8be
  {
9f0c16
    TPointD dpiScale = getCurrentDpiScale(simpleLevel, tool->getCurrentFid());
362052
    bool findGuidelines = (positions && positionsCount > 0 && outGuidelines);
362052
    bool doSomething = findGuidelines || draw;
362052
9cf8be
    int frame = frameHandle->getFrame();
9cf8be
    int count = Xsheet->getColumnCount();
a501ed
    TAffine worldToTrack;
9f0c16
    worldToTrack.a11 /= dpiScale.x;
9f0c16
    worldToTrack.a22 /= dpiScale.y;
9cf8be
9cf8be
    for(int i = 0; i < count; ++i)
9cf8be
      if (TImageP image = Xsheet->getCell(frame, i).getImage(false))
9cf8be
      if (image->getType() == TImage::META)
9cf8be
      if (TMetaImage *metaImage = dynamic_cast<tmetaimage*>(image.getPointer()))</tmetaimage*>
9cf8be
      {
9f0c16
        TAffine imageToTrack = worldToTrack * tool->getColumnMatrix(i);
362052
        if (draw) { glPushMatrix(); tglMultMatrix(imageToTrack); }
9cf8be
362052
        TMetaImage::Reader reader(*metaImage);
9cf8be
        for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i)
9cf8be
          if (*i)
9cf8be
          if (const TAssistant *assistant = (*i)->getHandler<tassistant>())</tassistant>
362052
          {
362052
            found = true;
362052
            if (findGuidelines)
362052
              for(int i = 0; i < positionsCount; ++i)
362052
                assistant->getGuidelines(positions[i], imageToTrack, *outGuidelines);
362052
            if (draw) assistant->draw(viewer);
362052
            if (!doSomething) return true;
362052
          }
362052
362052
        if (draw) glPopMatrix();
9cf8be
      }
9cf8be
  }
362052
  return found;
9cf8be
}
9cf8be
9cf8be
9cf8be
void
9cf8be
TModifierAssistants::modifyTrack(
9cf8be
  const TTrack &track,
9cf8be
  const TInputSavePoint::Holder &savePoint,
9cf8be
  TTrackList &outTracks )
9cf8be
{
9cf8be
  if (!track.handler) {
9cf8be
    track.handler = new TTrackHandler(track);
9cf8be
    Modifier *modifier = new Modifier(*track.handler);
362052
    if (!drawOnly)
362052
      scanAssistants(&track[0].position, 1, &modifier->guidelines, false);
9cf8be
9cf8be
    track.handler->tracks.push_back(new TTrack(modifier));
9cf8be
9cf8be
    if ((int)modifier->guidelines.size() > 1) {
9cf8be
      modifier->savePoint = savePoint;
9cf8be
      outTracks.push_back(track.handler->tracks.front());
9cf8be
      return;
9cf8be
    }
9cf8be
  }
9cf8be
9cf8be
  outTracks.push_back(track.handler->tracks.front());
9cf8be
  TTrack &subTrack = *track.handler->tracks.front();
9cf8be
  if (!track.changed()) return;
9cf8be
  if (Modifier *modifier = dynamic_cast<modifier*>(subTrack.modifier.getPointer())) {</modifier*>
9cf8be
    // remove points
9cf8be
    int start = track.size() - track.pointsAdded;
9cf8be
    if (start < 0) start = 0;
9cf8be
9cf8be
    if ((int)modifier->guidelines.size() > 1 && modifier->savePoint.available()) {
9cf8be
      // select guideline
9cf8be
      bool longEnough = false;
1c557b
      if (TInputManager *manager = getManager())
1c557b
      if (TInputHandler *handler = manager->getHandler())
362052
      if (TTool *tool = handler->inputGetTool())
1c557b
      if (TToolViewer *viewer = tool->getViewer()) {
8a3cf9
        TAffine trackToScreen = tool->getMatrix();
8a3cf9
        if (tool->getToolType() & TTool::LevelTool)
8a3cf9
          if (TObjectHandle *objHandle = TTool::getApplication()->getCurrentObject())
8a3cf9
            if (!objHandle->isSpline())
8a3cf9
              trackToScreen *= TScale(viewer->getDpiScale().x, viewer->getDpiScale().y);
8a3cf9
        trackToScreen *= viewer->get3dViewMatrix().get2d().inv();
1c557b
        TGuidelineP guideline = TGuideline::findBest(modifier->guidelines, track, trackToScreen, longEnough);
1c557b
        if (guideline != modifier->guidelines.front())
1c557b
          for(int i = 1; i < (int)modifier->guidelines.size(); ++i)
1c557b
            if (modifier->guidelines[i] == guideline) {
1c557b
              std::swap(modifier->guidelines[i], modifier->guidelines.front());
1c557b
              start = 0;
1c557b
              break;
1c557b
            }
9cf8be
      }
8a3cf9
      modifier->savePoint.setLock(!longEnough);
9cf8be
    } else {
9cf8be
      modifier->savePoint.reset();
9cf8be
    }
9cf8be
9cf8be
    // add points
9cf8be
    subTrack.truncate(start);
9cf8be
    for(int i = start; i < track.size(); ++i)
9cf8be
      subTrack.push_back( modifier->calcPoint(i) );
9cf8be
  }
9cf8be
  track.resetChanges();
9cf8be
}
9cf8be
9cf8be
362052
TRectD
362052
TModifierAssistants::calcDrawBounds(const TTrackList&, const THoverList&) {
362052
  if (scanAssistants(NULL, 0, NULL, false))
362052
    return TConsts::infiniteRectD;
362052
  return TRectD();
9cf8be
}
9cf8be
9cf8be
9cf8be
void
9cf8be
TModifierAssistants::drawTrack(const TTrack &track) {
9cf8be
  if (!track.handler) return;
9cf8be
  TTrack &subTrack = *track.handler->tracks.front();
9cf8be
  if (Modifier *modifier = dynamic_cast<modifier*>(subTrack.modifier.getPointer())) {</modifier*>
9cf8be
    const TGuidelineList &guidelines = modifier->guidelines;
9cf8be
    if (!guidelines.empty()) {
9cf8be
      guidelines.front()->draw(true);
9cf8be
      for(TGuidelineList::const_iterator i = guidelines.begin() + 1; i != guidelines.end(); ++i)
9cf8be
        (*i)->draw();
9cf8be
    }
9cf8be
  }
9cf8be
}
362052
362052
362052
void
362052
TModifierAssistants::draw(const TTrackList &tracks, const THoverList &hovers) {
362052
  THoverList allHovers;
362052
  allHovers.reserve(hovers.size() + tracks.size());
362052
  allHovers.insert(allHovers.end(), hovers.begin(), hovers.end());
362052
  for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i)
362052
    if ((*i)->handler && !(*i)->handler->tracks.empty() && !(*i)->handler->tracks.front()->empty())
362052
      allHovers.push_back( (*i)->handler->tracks.front()->back().position );
362052
  
362052
  // draw assistants
362052
  TGuidelineList guidelines;
362052
  scanAssistants(
362052
    allHovers.empty() ? NULL : &allHovers.front(),
362052
    (int)allHovers.size(),
362052
    &guidelines,
362052
    true );
362052
362052
  // draw guidelines
362052
  for(TGuidelineList::const_iterator i = guidelines.begin(); i != guidelines.end(); ++i)
362052
    (*i)->draw();
362052
362052
  // draw tracks
362052
  TInputModifier::drawTracks(tracks);
362052
}