#include <tools/modifiers/modifierassistants.h>
// TnzTools includes
#include <tools/tool.h>
// TnzLib includes
#include <toonz/tapplication.h>
#include <toonz/txshlevelhandle.h>
#include <toonz/txsheethandle.h>
#include <toonz/txsheet.h>
#include <toonz/tframehandle.h>
// TnzCore includes
#include <tmetaimage.h>
//*****************************************************************************************
// TModifierAssistants::Modifier implementation
//*****************************************************************************************
TModifierAssistants::Modifier::Modifier(TTrackHandler &handler):
TTrackModifier(handler),
initialized()
{ }
TTrackPoint
TModifierAssistants::Modifier::calcPoint(double originalIndex) {
TTrackPoint p = TTrackModifier::calcPoint(originalIndex);
return guidelines.empty() > 0 ? p : guidelines.front()->transformPoint(p);
}
//*****************************************************************************************
// TModifierAssistants implementation
//*****************************************************************************************
TModifierAssistants::TModifierAssistants():
sensitiveLength(50.0) { }
void
TModifierAssistants::findGuidelines(const TPointD &position, TGuidelineList &outGuidelines) const {
if (TInputManager *manager = getManager())
if (TInputHandler *handler = manager->getHandler())
if (TTool *tool = handler->getTool())
if (TToolViewer *viewer = tool->getViewer())
if (TApplication *application = tool->getApplication())
if (TFrameHandle *frameHandle = application->getCurrentFrame())
if (TXsheetHandle *XsheetHandle = application->getCurrentXsheet())
if (TXsheet *Xsheet = XsheetHandle->getXsheet())
{
int frame = frameHandle->getFrame();
int count = Xsheet->getColumnCount();
TAffine worldToTrack = viewer->getViewMatrix();
for(int i = 0; i < count; ++i)
if (TImageP image = Xsheet->getCell(frame, i).getImage(false))
if (image->getType() == TImage::META)
if (TMetaImage *metaImage = dynamic_cast<TMetaImage*>(image.getPointer()))
{
TAffine imageToTrack = tool->getColumnMatrix(i)
* worldToTrack;
TMetaImage::Reader reader(*metaImage);
for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i)
if (*i)
if (const TAssistant *assistant = (*i)->getHandler<TAssistant>())
assistant->getGuidelines(position, imageToTrack, outGuidelines);
}
}
}
void
TModifierAssistants::modifyTrack(
const TTrack &track,
const TInputSavePoint::Holder &savePoint,
TTrackList &outTracks )
{
if (!track.handler) {
track.handler = new TTrackHandler(track);
Modifier *modifier = new Modifier(*track.handler);
findGuidelines(track[0].position, modifier->guidelines);
track.handler->tracks.push_back(new TTrack(modifier));
if ((int)modifier->guidelines.size() > 1) {
modifier->savePoint = savePoint;
outTracks.push_back(track.handler->tracks.front());
return;
}
}
outTracks.push_back(track.handler->tracks.front());
TTrack &subTrack = *track.handler->tracks.front();
if (!track.changed()) return;
if (Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer())) {
// remove points
int start = track.size() - track.pointsAdded;
if (start < 0) start = 0;
if ((int)modifier->guidelines.size() > 1 && modifier->savePoint.available()) {
// select guideline
bool longEnough = false;
if (TInputManager *manager = getManager())
if (TInputHandler *handler = manager->getHandler())
if (TTool *tool = handler->getTool())
if (TToolViewer *viewer = tool->getViewer()) {
TAffine trackToScreen = manager->toolToWorld()
* viewer->get3dViewMatrix().get2d().inv();
TGuidelineP guideline = TGuideline::findBest(modifier->guidelines, track, trackToScreen, longEnough);
if (guideline != modifier->guidelines.front())
for(int i = 1; i < (int)modifier->guidelines.size(); ++i)
if (modifier->guidelines[i] == guideline) {
std::swap(modifier->guidelines[i], modifier->guidelines.front());
start = 0;
break;
}
}
if (longEnough) modifier->savePoint.unlock(); else modifier->savePoint.lock();
} else {
modifier->savePoint.reset();
}
// add points
subTrack.truncate(start);
for(int i = start; i < track.size(); ++i)
subTrack.push_back( modifier->calcPoint(i) );
}
track.resetChanges();
}
void
TModifierAssistants::drawHover(const TPointD &hover) {
TGuidelineList guidelines;
findGuidelines(hover, guidelines);
for(TGuidelineList::const_iterator i = guidelines.begin(); i != guidelines.end(); ++i)
(*i)->draw();
}
void
TModifierAssistants::drawTrack(const TTrack &track) {
if (!track.handler) return;
TTrack &subTrack = *track.handler->tracks.front();
if (Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer())) {
const TGuidelineList &guidelines = modifier->guidelines;
if (!guidelines.empty()) {
guidelines.front()->draw(true);
for(TGuidelineList::const_iterator i = guidelines.begin() + 1; i != guidelines.end(); ++i)
(*i)->draw();
}
}
}