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
//*****************************************************************************************
fa009d
//    TModifierAssistants::Interpolator implementation
9cf8be
//*****************************************************************************************
9cf8be
9cf8be
9cf8be
TTrackPoint
fa009d
TModifierAssistants::Interpolator::interpolate(double index) {
fa009d
  TTrackPoint p = track.original ? track.calcPointFromOriginal(index)
fa009d
                                 : track.interpolateLinear(index);
fa009d
  return guidelines.empty() ? p : guidelines.front()->smoothTransformPoint(p, magnetism);
9cf8be
}
9cf8be
9cf8be
9cf8be
//*****************************************************************************************
9cf8be
//    TModifierAssistants implementation
9cf8be
//*****************************************************************************************
9cf8be
9cf8be
fa009d
TModifierAssistants::TModifierAssistants(double magnetism):
fa009d
  magnetism(magnetism),
9cf8be
  sensitiveLength(50.0) { }
9cf8be
9cf8be
362052
bool
362052
TModifierAssistants::scanAssistants(
362052
  const TPointD *positions,
362052
  int positionsCount,
362052
  TGuidelineList *outGuidelines,
3d32e2
  bool draw,
fa009d
  bool enabledOnly,
fa009d
  bool drawGuidelines ) const
362052
{
9cf8be
  if (TInputManager *manager = getManager())
9cf8be
  if (TInputHandler *handler = manager->getHandler())
fa009d
    return TAssistant::scanAssistants(
fa009d
      handler->inputGetTool(),
fa009d
      positions,
fa009d
      positionsCount,          
fa009d
      outGuidelines,
fa009d
      draw,
fa009d
      enabledOnly,
fa009d
      magnetism > 0,
fa009d
      drawGuidelines,
fa009d
      nullptr );
fa009d
  return false;
9cf8be
}
9cf8be
9cf8be
9cf8be
void
9cf8be
TModifierAssistants::modifyTrack(
9cf8be
  const TTrack &track,
9cf8be
  TTrackList &outTracks )
9cf8be
{
9cf8be
  if (!track.handler) {
fa009d
    Handler *handler = new Handler();
fa009d
    track.handler = handler;
fa009d
    handler->track = new TTrack(track);
fa009d
    new Interpolator(*handler->track, magnetism);
9cf8be
  }
fa009d
  
fa009d
  Handler *handler = dynamic_cast<handler*>(track.handler.getPointer());</handler*>
fa009d
  if (!handler)
fa009d
    return;
fa009d
  
fa009d
  outTracks.push_back(handler->track);
fa009d
  TTrack &subTrack = *handler->track;
fa009d
  Interpolator *intr = dynamic_cast<interpolator*>(subTrack.getInterpolator().getPointer());</interpolator*>
fa009d
  if (!intr)
f278a5
    return;
fa009d
  
fa009d
  if (!track.changed())
f278a5
    return;
fa009d
  
f278a5
  // remove points
f278a5
  int start = track.size() - track.pointsAdded;
f278a5
  if (start < 0) start = 0;
f278a5
fa009d
  if (intr->magnetism && start <= 0) {
fa009d
    intr->guidelines.clear();
fa009d
    scanAssistants(&track[0].position, 1, &intr->guidelines, false, true, false);
9cf8be
  }
f278a5
  
fa009d
  bool fixed = subTrack.fixedSize() || intr->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();
fa009d
    TGuidelineP guideline = TGuideline::findBest(intr->guidelines, track, trackToScreen, fixed);
fa009d
    if (guideline != intr->guidelines.front())
fa009d
      for(int i = 1; i < (int)intr->guidelines.size(); ++i)
fa009d
        if (intr->guidelines[i] == guideline) {
fa009d
          std::swap(intr->guidelines[i], intr->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)
fa009d
    subTrack.push_back( intr->interpolate(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&) {
fa009d
  if (scanAssistants(NULL, 0, NULL, false, false, false))
362052
    return TConsts::infiniteRectD;
362052
  return TRectD();
9cf8be
}
9cf8be
9cf8be
9cf8be
void
9cf8be
TModifierAssistants::drawTrack(const TTrack &track) {
fa009d
  Handler *handler = dynamic_cast<handler*>(track.handler.getPointer());</handler*>
fa009d
  if (!handler) return;
fa009d
  
fa009d
  TTrack &subTrack = *handler->track;
fa009d
  Interpolator *intr = dynamic_cast<interpolator*>(subTrack.getInterpolator().getPointer());</interpolator*>
fa009d
  if (!intr) return;
fa009d
  
fa009d
  const TGuidelineList &guidelines = intr->guidelines;
fa009d
  if (guidelines.empty())
fa009d
    return;
fa009d
  
fa009d
  guidelines.front()->draw(true);
fa009d
  for(TGuidelineList::const_iterator i = guidelines.begin() + 1; i != guidelines.end(); ++i)
fa009d
    (*i)->draw();
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)
fa009d
    if (Handler *handler = dynamic_cast<handler*>((*i)->handler.getPointer()))</handler*>
fa009d
      allHovers.push_back( handler->track->back().position );
362052
  
fa009d
  // draw assistants and guidelines
362052
  scanAssistants(
362052
    allHovers.empty() ? NULL : &allHovers.front(),
362052
    (int)allHovers.size(),
fa009d
    nullptr,
3d32e2
    true,
fa009d
    false,
fa009d
    true );
362052
362052
  // draw tracks
362052
  TInputModifier::drawTracks(tracks);
362052
}