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);
3d32e2
  return guidelines.empty() ? p : guidelines.front()->smoothTransformPoint(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,
3d32e2
  bool draw,
3d32e2
  bool enabledOnly ) 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)
13dcb1
      if (TXshColumn *column = Xsheet->getColumn(i))
13dcb1
      if (column->isCamstandVisible())
13dcb1
      if (column->isPreviewVisible())
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);
57d357
        for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i)
9cf8be
          if (*i)
9cf8be
          if (const TAssistant *assistant = (*i)->getHandler<tassistant>())</tassistant>
3d32e2
          if (!enabledOnly || assistant->getEnabled())
362052
          {
362052
            found = true;
362052
            if (findGuidelines)
362052
              for(int i = 0; i < positionsCount; ++i)
362052
                assistant->getGuidelines(positions[i], imageToTrack, *outGuidelines);
8074a5
            if (draw) assistant->draw(viewer, !drawOnly);
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
  TTrackList &outTracks )
9cf8be
{
9cf8be
  if (!track.handler) {
9cf8be
    track.handler = new TTrackHandler(track);
9cf8be
    Modifier *modifier = new Modifier(*track.handler);
9cf8be
    track.handler->tracks.push_back(new TTrack(modifier));
9cf8be
  }
9cf8be
9cf8be
  outTracks.push_back(track.handler->tracks.front());
9cf8be
  TTrack &subTrack = *track.handler->tracks.front();
f278a5
  if (!track.changed())
f278a5
    return;
f278a5
  Modifier *modifier = dynamic_cast<modifier*>(subTrack.modifier.getPointer());</modifier*>
f278a5
  if (!modifier)
f278a5
    return;
f278a5
    
f278a5
  // remove points
f278a5
  int start = track.size() - track.pointsAdded;
f278a5
  if (start < 0) start = 0;
f278a5
f278a5
  if (!drawOnly && start <= 0) {
f278a5
    modifier->guidelines.clear();
f278a5
    scanAssistants(&track[0].position, 1, &modifier->guidelines, false, true);
9cf8be
  }
f278a5
  
f278a5
  bool fixed = subTrack.fixedSize() || modifier->guidelines.size() <= 1;
f278a5
f278a5
  // select guideline
f278a5
  if (!fixed)
f278a5
  if (TInputManager *manager = getManager())
f278a5
  if (TInputHandler *handler = manager->getHandler())
f278a5
  if (TTool *tool = handler->inputGetTool())
f278a5
  if (TToolViewer *viewer = tool->getViewer()) {
f278a5
    TAffine trackToScreen = tool->getMatrix();
f278a5
    if (tool->getToolType() & TTool::LevelTool)
f278a5
      if (TObjectHandle *objHandle = TTool::getApplication()->getCurrentObject())
f278a5
        if (!objHandle->isSpline())
f278a5
          trackToScreen *= TScale(viewer->getDpiScale().x, viewer->getDpiScale().y);
f278a5
    trackToScreen *= viewer->get3dViewMatrix().get2d();
f278a5
    TGuidelineP guideline = TGuideline::findBest(modifier->guidelines, track, trackToScreen, fixed);
f278a5
    if (guideline != modifier->guidelines.front())
f278a5
      for(int i = 1; i < (int)modifier->guidelines.size(); ++i)
f278a5
        if (modifier->guidelines[i] == guideline) {
f278a5
          std::swap(modifier->guidelines[i], modifier->guidelines.front());
f278a5
          start = 0;
f278a5
          break;
f278a5
        }
f278a5
  }
f278a5
f278a5
  // add points
f278a5
  subTrack.truncate(start);
f278a5
  for(int i = start; i < track.size(); ++i)
f278a5
    subTrack.push_back( modifier->calcPoint(i), false );
f278a5
  
f278a5
  // fix points
f278a5
  if (fixed || track.fixedFinished())
f278a5
    subTrack.fix_to(track.fixedSize());
f278a5
9cf8be
  track.resetChanges();
9cf8be
}
9cf8be
9cf8be
362052
TRectD
362052
TModifierAssistants::calcDrawBounds(const TTrackList&, const THoverList&) {
3d32e2
  if (scanAssistants(NULL, 0, NULL, false, 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());
8074a5
  if (tracks.empty()) // hide hovers if track exists
8074a5
    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,
3d32e2
    true,
3d32e2
    false );
362052
362052
  // draw guidelines
362052
  for(TGuidelineList::const_iterator i = guidelines.begin(); i != guidelines.end(); ++i)
8074a5
    (*i)->draw(false, !drawOnly);
362052
362052
  // draw tracks
362052
  TInputModifier::drawTracks(tracks);
362052
}