diff --git a/toonz/sources/include/tools/inputmanager.h b/toonz/sources/include/tools/inputmanager.h index 7d9a58d..323dba1 100644 --- a/toonz/sources/include/tools/inputmanager.h +++ b/toonz/sources/include/tools/inputmanager.h @@ -47,104 +47,6 @@ typedef TSmartPointerT<TInputModifier> TInputModifierP; //***************************************************************************************** -// TInputSavePoint definition -//***************************************************************************************** - -class DVAPI TInputSavePoint { -public: - class DVAPI Holder { - private: - TInputSavePoint *m_savePoint; - bool m_lock = false; - - public: - inline explicit Holder(TInputSavePoint *savePoint = NULL, bool lock = true): - m_savePoint(), m_lock() - { set(savePoint, lock); } - inline Holder(const Holder &other): - m_savePoint(), m_lock() - { *this = other; } - inline ~Holder() - { reset(); } - - inline Holder& operator= (const Holder &other) - { set(other.m_savePoint, other.m_lock); return *this; } - - inline operator bool () const - { return assigned(); } - - inline void set(TInputSavePoint *savePoint, bool lock) { - if (m_savePoint != savePoint) { - if (m_savePoint) { - if (m_lock) m_savePoint->unlock(); - m_savePoint->release(); - } - m_savePoint = savePoint; - m_lock = lock; - if (m_savePoint) { - m_savePoint->hold(); - if (m_lock) savePoint->lock(); - } - } else - if (m_lock != lock) { - if (m_savePoint) { - if (lock) m_savePoint->lock(); - else m_savePoint->unlock(); - } - m_lock = lock; - } - } - - inline void reset() - { set(NULL, false); } - inline void setLock(bool lock) - { set(m_savePoint, lock); } - inline void lock() - { setLock(true); } - inline void unlock() - { setLock(false); } - - inline TInputSavePoint* savePoint() const - { return m_savePoint; } - inline bool assigned() const - { return savePoint(); } - inline bool locked() const - { return m_savePoint && m_lock; } - inline bool available() const - { return m_savePoint && m_savePoint->available; } - inline bool isFree() const - { return !m_savePoint || m_savePoint->isFree(); } - }; - - typedef std::vector<Holder> List; - -private: - int m_refCount; - int m_lockCount; - - inline void hold() - { ++m_refCount; } - inline void release() - { if ((--m_refCount) <= 0) delete this; } - inline void lock() - { ++m_lockCount; } - inline void unlock() - { --m_lockCount; } - -public: - bool available; - - inline explicit TInputSavePoint(bool available = false): - m_refCount(), m_lockCount(), available(available) { } - inline bool isFree() const - { return m_lockCount <= 0; } - - static inline Holder create(bool available = false) - { return Holder(new TInputSavePoint(available)); } -}; - - -//***************************************************************************************** // TInputModifier definition //***************************************************************************************** @@ -164,11 +66,9 @@ public: virtual void modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ); virtual void modifyTracks( const TTrackList &tracks, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ); virtual void modifyHover( @@ -221,30 +121,11 @@ public: virtual void inputHoverEvent(const TInputManager &manager); - /*! paint single track-point at the top painting level */ - virtual void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack); - - /*! create new painting level and return true, or do nothing and return false - was: ------O-------O------ - become: ------O-------O------O */ - virtual bool inputPaintPush() { return false; } - /*! paint several track-points at the top painting level - was: ------O-------O------ - become: ------O-------O------------ */ + virtual void inputPaintTracksBegin() { } + virtual void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack, bool preview); + virtual void inputPaintTracksEnd() { } virtual void inputPaintTracks(const TTrackList &tracks); - /*! try to merge N top painting levels and return count of levels that actually merged - was: ------O-------O------O------ - become (N = 2): ------O--------------------- */ - virtual int inputPaintApply(int count) { return 0; } - /*! reset top level to initial state - was: ------O-------O------O------ - become: ------O-------O------O */ - virtual void inputPaintCancel() { } - /*! cancel and pop N painting levels - was: ------O-------O------O------ - become (N = 2): ------O------- */ - virtual void inputPaintPop(int count) { } - + virtual void inputInvalidateRect(const TRectD &bounds) { } virtual TTool* inputGetTool() { return nullptr; }; @@ -256,26 +137,15 @@ public: //***************************************************************************************** class DVAPI TInputManager { -public: - class TrackHandler: public TTrackHandler { - public: - std::vector<int> saves; - TrackHandler(TTrack &original, int keysCount = 0): - TTrackHandler(original), saves(keysCount, 0) - { } - }; - private: TTimerTicks m_lastTicks; TInputHandler *m_handler; TInputModifier::List m_modifiers; std::vector<TTrackList> m_tracks; std::vector<THoverList> m_hovers; - TInputSavePoint::List m_savePoints; TRectD m_prevBounds; TRectD m_nextBounds; bool m_started; - int m_savePointsSent; static TInputState::TouchId m_lastTouchId; @@ -294,8 +164,6 @@ private: return m_lastTicks = ticks; } - void paintRollbackTo(int saveIndex, TTrackList &subTracks); - void paintApply(int count, TTrackList &subTracks); void paintTracks(); int trackCompare( diff --git a/toonz/sources/include/tools/modifiers/modifierassistants.h b/toonz/sources/include/tools/modifiers/modifierassistants.h index 3dcd35d..0ba8059 100644 --- a/toonz/sources/include/tools/modifiers/modifierassistants.h +++ b/toonz/sources/include/tools/modifiers/modifierassistants.h @@ -29,7 +29,6 @@ public: class DVAPI Modifier: public TTrackModifier { public: bool initialized; - TInputSavePoint::Holder savePoint; TGuidelineList guidelines; Modifier(TTrackHandler &handler); @@ -52,7 +51,6 @@ public: void modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) override; TRectD calcDrawBounds(const TTrackList &tracks, const THoverList &hovers) override; diff --git a/toonz/sources/include/tools/modifiers/modifierline.h b/toonz/sources/include/tools/modifiers/modifierline.h index a6966a2..495f711 100644 --- a/toonz/sources/include/tools/modifiers/modifierline.h +++ b/toonz/sources/include/tools/modifiers/modifierline.h @@ -33,14 +33,12 @@ public: bool fixAngle; double maxPressure; - TInputSavePoint::Holder savePoint; - + TTrackPoint calcPoint(double originalIndex) override; }; void modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) override; }; diff --git a/toonz/sources/include/tools/modifiers/modifiersegmentation.h b/toonz/sources/include/tools/modifiers/modifiersegmentation.h index af4278c..a979c8b 100644 --- a/toonz/sources/include/tools/modifiers/modifiersegmentation.h +++ b/toonz/sources/include/tools/modifiers/modifiersegmentation.h @@ -38,7 +38,6 @@ public: void modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) override; }; diff --git a/toonz/sources/include/tools/modifiers/modifiertangents.h b/toonz/sources/include/tools/modifiers/modifiertangents.h index 8ead779..a7e6232 100644 --- a/toonz/sources/include/tools/modifiers/modifiertangents.h +++ b/toonz/sources/include/tools/modifiers/modifiertangents.h @@ -31,17 +31,15 @@ public: explicit Modifier(TTrackHandler &handler): TTrackModifier(handler) { } - TInputSavePoint::Holder savePoint; TTrackTangentList tangents; TTrackPoint calcPoint(double originalIndex) override; }; - TTrackTangent calcLastTangent(const TTrack &track) const; + TTrackTangent calcTangent(const TTrack &track, int index) const; void modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) override; }; diff --git a/toonz/sources/include/tools/modifiers/modifiertest.h b/toonz/sources/include/tools/modifiers/modifiertest.h index 91911af..e410547 100644 --- a/toonz/sources/include/tools/modifiers/modifiertest.h +++ b/toonz/sources/include/tools/modifiers/modifiertest.h @@ -50,7 +50,6 @@ public: TModifierTest(int count, double radius); void modifyTrack(const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks) override; }; diff --git a/toonz/sources/include/tools/track.h b/toonz/sources/include/tools/track.h index eb12057..aee3ae5 100644 --- a/toonz/sources/include/tools/track.h +++ b/toonz/sources/include/tools/track.h @@ -183,10 +183,12 @@ public: mutable TTrackToolHandlerP toolHandler; mutable int pointsRemoved; mutable int pointsAdded; + mutable int fixedPointsAdded; private: TTrackPointList m_points; const TTrackPoint m_none; + int m_pointsFixed; public: @@ -208,7 +210,7 @@ public: inline TTimerTicks ticks() const { return keyHistory.ticks(); } inline bool changed() const - { return pointsAdded != 0 || pointsRemoved != 0; } + { return pointsRemoved || pointsAdded || fixedPointsAdded; } const TTrack* root() const; int level() const; @@ -236,6 +238,10 @@ public: inline int size() const { return (int)m_points.size(); } + inline int fixedSize() const + { return m_pointsFixed; } + inline int previewSize() const + { return size() - fixedSize(); } inline bool empty() const { return m_points.empty(); } inline const TTrackPoint& front() const @@ -244,6 +250,8 @@ public: { return point(size() - 1); } inline bool finished() const { return !m_points.empty() && back().final; } + inline bool fixedFinished() const + { return finished() && !previewSize(); } inline const TTrackPoint& operator[] (int index) const { return point(index); } inline const TTrackPointList& points() const @@ -253,14 +261,21 @@ public: { pointsRemoved = 0; } inline void resetAdded() const { pointsAdded = 0; } + inline void resetFixedAdded() const + { fixedPointsAdded = 0; } inline void resetChanges() const - { resetRemoved(); resetAdded(); } + { resetRemoved(); resetAdded(); resetFixedAdded(); } - void push_back(const TTrackPoint &point); + void push_back(const TTrackPoint &point, bool fixed); void pop_back(int count = 1); + void fix_points(int count = 1); inline void truncate(int count) { pop_back(size() - count); } + inline void fix_to(int count) + { fix_points(count - fixedSize()); } + inline void fix_all() + { fix_to(size()); } inline const TTrackPoint& current() const { return point(size() - pointsAdded); } diff --git a/toonz/sources/tnztools/assistant.cpp b/toonz/sources/tnztools/assistant.cpp index 5e0ec9c..2807468 100644 --- a/toonz/sources/tnztools/assistant.cpp +++ b/toonz/sources/tnztools/assistant.cpp @@ -85,7 +85,7 @@ TGuideline::calcTrackWeight(const TTrack &track, const TAffine &toScreen, bool & prev = p; if (sumLength >= maxLength) - { outLongEnough = true; break; } + { outLongEnough = i < track.fixedSize(); break; } } return sumWeight > TConsts::epsilon ? sumDeviation/sumWeight diff --git a/toonz/sources/tnztools/fullcolorbrushtool.cpp b/toonz/sources/tnztools/fullcolorbrushtool.cpp index cdc7a4c..8b4b7d2 100644 --- a/toonz/sources/tnztools/fullcolorbrushtool.cpp +++ b/toonz/sources/tnztools/fullcolorbrushtool.cpp @@ -312,11 +312,11 @@ bool FullColorBrushTool::preLeftButtonDown() { m_inputmanager.addModifier(TInputModifierP(m_modifierTangents.getPointer())); m_inputmanager.addModifier( TInputModifierP(m_modifierAssistants.getPointer())); - m_inputmanager.addModifier( - TInputModifierP(m_modifierSegmentation.getPointer())); #ifndef NDEBUG m_inputmanager.addModifier(TInputModifierP(m_modifierTest.getPointer())); #endif + m_inputmanager.addModifier( + TInputModifierP(m_modifierSegmentation.getPointer())); touchImage(); @@ -505,9 +505,13 @@ void FullColorBrushTool::inputSetBusy(bool busy) { void FullColorBrushTool::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, - bool firstTrack) { + bool firstTrack, + bool preview) +{ // get raster - if (!m_started || !getViewer()) return; + if (!m_started || !getViewer() || preview) + return; + TRasterImageP ri = (TRasterImageP)getImage(true); if (!ri) return; TRasterP ras = ri->getRaster(); diff --git a/toonz/sources/tnztools/fullcolorbrushtool.h b/toonz/sources/tnztools/fullcolorbrushtool.h index 239ea92..cdb8450 100644 --- a/toonz/sources/tnztools/fullcolorbrushtool.h +++ b/toonz/sources/tnztools/fullcolorbrushtool.h @@ -81,7 +81,7 @@ public: const TInputState &state) override; void inputSetBusy(bool busy) override; void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, - bool firstTrack) override; + bool firstTrack, bool preview) override; void inputInvalidateRect(const TRectD &bounds) override; TTool *inputGetTool() override { return this; }; diff --git a/toonz/sources/tnztools/inputmanager.cpp b/toonz/sources/tnztools/inputmanager.cpp index bc00bb9..efc0754 100644 --- a/toonz/sources/tnztools/inputmanager.cpp +++ b/toonz/sources/tnztools/inputmanager.cpp @@ -29,7 +29,6 @@ TInputModifier::setManager(TInputManager *manager) { void TInputModifier::modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) { if (!track.handler) { @@ -51,7 +50,8 @@ TInputModifier::modifyTrack( TTrack &subTrack = **ti; subTrack.truncate(start); for(int i = start; i < track.size(); ++i) - subTrack.push_back( subTrack.modifier->calcPoint(i) ); + subTrack.push_back( subTrack.modifier->calcPoint(i), false ); + subTrack.fix_to(track.fixedSize()); } track.resetChanges(); } @@ -60,11 +60,10 @@ TInputModifier::modifyTrack( void TInputModifier::modifyTracks( const TTrackList &tracks, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) { for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) - modifyTrack(**i, savePoint, outTracks); + modifyTrack(**i, outTracks); } @@ -127,9 +126,9 @@ TInputModifier::draw(const TTrackList &tracks, const std::vector<TPointD> &hover bool TInputHandler::inputKeyEvent( bool press, - TInputState::Key key, + TInputState::Key, QKeyEvent *event, - const TInputManager &manager ) + const TInputManager& ) { return press && event && inputKeyDown(event); } @@ -138,7 +137,7 @@ TInputHandler::inputKeyEvent( void TInputHandler::inputButtonEvent( bool press, - TInputState::DeviceId device, + TInputState::DeviceId, TInputState::Button button, const TInputManager &manager ) { @@ -155,8 +154,8 @@ TInputHandler::inputHoverEvent(const TInputManager &manager) { void -TInputHandler::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack) { - if (firstTrack) { +TInputHandler::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack, bool preview) { + if (firstTrack && !preview) { if (track.pointsAdded == track.size()) inputLeftButtonDown(point, track); else @@ -164,14 +163,25 @@ TInputHandler::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &trac inputLeftButtonUp(point, track); else inputLeftButtonDrag(point, track); - } + } } void TInputHandler::inputPaintTracks(const TTrackList &tracks) { + // prepare tracks counters + for(TTrackList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) { + (*i)->pointsAdded = (*i)->fixedPointsAdded + (*i)->previewSize(); + (*i)->resetRemoved(); + } + + // begin paint + bool preview = false; + bool paintStarted = false; + // paint track points in chronological order while(true) { + // find earlier not painted point TTrackP track; TTimerTicks minTicks = 0; double minTimeOffset = 0.0; @@ -187,10 +197,27 @@ TInputHandler::inputPaintTracks(const TTrackList &tracks) { } } } - if (!track) break; - inputPaintTrackPoint(track->current(), *track, track == tracks.front()); + + if (!track) + break; // all tracks are painted + + if (track->pointsAdded <= track->previewSize()) + preview = true; + if (!paintStarted) + { inputPaintTracksBegin(); paintStarted = true; } + inputPaintTrackPoint(track->current(), *track, track == tracks.front(), preview); + + // update counters --track->pointsAdded; + if (!preview) { + assert(track->fixedPointsAdded > 0); + --track->fixedPointsAdded; + } } + + // end paint + if (paintStarted) + inputPaintTracksEnd(); } @@ -205,162 +232,53 @@ TInputManager::TInputManager(): m_tracks(1), m_hovers(1), m_started(), - m_savePointsSent(), drawPreview() { } void -TInputManager::paintRollbackTo(int saveIndex, TTrackList &subTracks) { - if (saveIndex >= (int)m_savePoints.size()) - return; - - int level = saveIndex + 1; - if (level <= m_savePointsSent) { - if (m_handler) { - if (level < m_savePointsSent) - m_handler->inputPaintPop(m_savePointsSent - level); - m_handler->inputPaintCancel(); - } - m_savePointsSent = level; - } - - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { - TTrack &track = **i; - if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) { - handler->saves.resize(level); - int cnt = handler->saves[saveIndex]; - track.resetRemoved(); - track.pointsAdded = track.size() - cnt; - } - } - for(int i = level; i < (int)m_savePoints.size(); ++i) - m_savePoints[i].savePoint()->available = false; - m_savePoints.resize(level); -} - - -void -TInputManager::paintApply(int count, TTrackList &subTracks) { - if (count <= 0) - return; - - int level = (int)m_savePoints.size() - count; - bool resend = true; - - if (level < m_savePointsSent) { - // apply - int applied = m_handler ? m_handler->inputPaintApply(m_savePointsSent - level) : false; - applied = std::max(0, std::min(m_savePointsSent - level, applied)); - m_savePointsSent -= applied; - if (m_savePointsSent == level) resend = false; - } - - if (level < m_savePointsSent) { - // rollback - if (m_handler) m_handler->inputPaintPop(m_savePointsSent - level); - m_savePointsSent = level; +TInputManager::paintTracks() { + // run modifiers + for(int i = 0; i < (int)m_modifiers.size(); ++i) { + m_tracks[i+1].clear(); + m_modifiers[i]->modifyTracks(m_tracks[i], m_tracks[i+1]); } + TTrackList &subTracks = m_tracks.back(); - // remove keypoints - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { - TTrack &track = **i; - if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) { - if (resend) { - track.resetRemoved(); - track.pointsAdded = track.size() - handler->saves[m_savePointsSent]; - } - handler->saves.resize(level); - } + + // begin painting if need + bool changed = false; + for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) + if ((*i)->changed()) + { changed = true; break; } + if (!m_started && changed) { + m_started = true; + if (m_handler) m_handler->inputSetBusy(true); } - for(int i = level; i < (int)m_savePoints.size(); ++i) - m_savePoints[i].savePoint()->available = false; - m_savePoints.resize(level); -} - -void -TInputManager::paintTracks() { + + // paint tracks + if (changed && m_handler) + m_handler->inputPaintTracks(subTracks); + + + // end painting if all tracks are finished bool allFinished = true; for(TTrackList::const_iterator i = m_tracks.front().begin(); i != m_tracks.front().end(); ++i) - if (!(*i)->finished()) + if (!(*i)->fixedFinished()) { allFinished = false; break; } - - while(true) { - // run modifiers - TInputSavePoint::Holder newSavePoint = TInputSavePoint::create(true); - for(int i = 0; i < (int)m_modifiers.size(); ++i) { - m_tracks[i+1].clear(); - m_modifiers[i]->modifyTracks(m_tracks[i], newSavePoint, m_tracks[i+1]); - } - TTrackList &subTracks = m_tracks.back(); - - // is paint started? - if (!m_started && !subTracks.empty()) { - m_started = true; - if (m_handler) m_handler->inputSetBusy(true); - } - - // create handlers + if (allFinished) for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) - if (!(*i)->handler) - (*i)->handler = new TrackHandler(**i, (int)m_savePoints.size()); - - if (!m_savePoints.empty()) { - // rollback - int rollbackIndex = (int)m_savePoints.size(); - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) { - TTrack &track = **i; - if (track.pointsRemoved > 0) { - int count = track.size() - track.pointsAdded; - if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) - while(rollbackIndex > 0 && (rollbackIndex >= (int)m_savePoints.size() || handler->saves[rollbackIndex] > count)) - --rollbackIndex; - } - } - paintRollbackTo(rollbackIndex, subTracks); - - // apply - int applyCount = 0; - while(applyCount < (int)m_savePoints.size() && m_savePoints[(int)m_savePoints.size() - applyCount - 1].isFree()) - ++applyCount; - paintApply(applyCount, subTracks); + if (!(*i)->fixedFinished()) + { allFinished = false; break; } + + if (allFinished) { + if (m_started) { + if (m_handler) m_handler->inputSetBusy(false); + m_started = false; } - - // send to handler - if (m_savePointsSent == (int)m_savePoints.size() && !subTracks.empty() && m_handler) - m_handler->inputPaintTracks(subTracks); - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) - (*i)->resetChanges(); - - // is paint finished? - newSavePoint.unlock(); - if (newSavePoint.isFree()) { - newSavePoint.savePoint()->available = false; - if (allFinished) { - paintApply((int)m_savePoints.size(), subTracks); - // send to tool final - if (!subTracks.empty()) { - if (m_handler) m_handler->inputPaintTracks(subTracks); - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) - (*i)->resetChanges(); - } - for(std::vector<TTrackList>::iterator i = m_tracks.begin(); i != m_tracks.end(); ++i) - i->clear(); - if (m_started) { - if (m_handler) m_handler->inputSetBusy(false); - m_started = false; - } - } - break; - } - - // create save point - if (m_handler && m_handler->inputPaintPush()) ++m_savePointsSent; - m_savePoints.push_back(newSavePoint); - for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) - if (TrackHandler *handler = dynamic_cast<TrackHandler*>((*i)->handler.getPointer())) - handler->saves.push_back((*i)->size()); + for(int i = 0; i < (int)m_tracks.size(); ++i) + m_tracks[i].clear(); } } @@ -444,14 +362,16 @@ TInputManager::addTrackPoint( double time, bool final ) { - track->push_back( TTrackPoint( - position, - pressure, - tilt, - (double)track->size(), - time, - 0.0, // length will calculated inside of TTrack::push_back - final )); + track->push_back( + TTrackPoint( + position, + pressure, + tilt, + (double)track->size(), + time, + 0.0, // length will calculated inside of TTrack::push_back + final ), + true ); } @@ -502,15 +422,9 @@ TInputManager::finishTracks() { void TInputManager::reset() { - // forget about handler paint stack + // forget about handler busy state // assuime it was already reset by outside m_started = false; - m_savePointsSent = 0; - - // reset save point - for(int i = 0; i < (int)m_savePoints.size(); ++i) - m_savePoints[i].savePoint()->available = false; - m_savePoints.clear(); // reset tracks for(int i = 0; i < (int)m_tracks.size(); ++i) @@ -660,16 +574,15 @@ TInputManager::calcDrawBounds() { for(int i = 0; i < (int)m_modifiers.size(); ++i) bounds += m_modifiers[i]->calcDrawBounds(m_tracks[i], m_hovers[i]); - if (m_savePointsSent < (int)m_savePoints.size()) { + if ( debugInputManager || drawPreview ) { for(TTrackList::const_iterator ti = getOutputTracks().begin(); ti != getOutputTracks().end(); ++ti) { TTrack &track = **ti; - if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) { - int start = handler->saves[m_savePointsSent] - 1; - if (start < 0) start = 0; - if (start + 1 < track.size()) - for(int i = start + 1; i < track.size(); ++i) - bounds += boundingBox(track[i-1].position, track[i].position); - } + int painted = track.fixedSize() - track.fixedPointsAdded; + if (painted < 0) painted = 0; + int start = debugInputManager ? 0 : painted; + if (start + 1 < track.size()) + for(int i = start + 1; i < track.size(); ++i) + bounds += boundingBox(track[i-1].position, track[i].position); } } @@ -685,8 +598,8 @@ TInputManager::draw() { m_prevBounds = m_nextBounds; m_nextBounds = TRectD(); - // paint not sent sub-tracks - if ( debugInputManager || (drawPreview && m_savePointsSent < (int)m_savePoints.size()) ) { + // paint not fixed parts of tracks + if ( debugInputManager || drawPreview ) { glPushAttrib(GL_ALL_ATTRIB_BITS); tglEnableBlending(); tglEnableLineSmooth(true, 1.0); @@ -695,38 +608,35 @@ TInputManager::draw() { double colorWhite[4] = { 1.0, 1.0, 1.0, 1.0 }; for(TTrackList::const_iterator ti = getOutputTracks().begin(); ti != getOutputTracks().end(); ++ti) { TTrack &track = **ti; - if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) { - int start = debugInputManager ? 0 : handler->saves[m_savePointsSent] - 1; - if (start < 0) start = 0; - if (start + 1 < track.size()) { - //int level = m_savePointsSent; - //colorBlack[3] = (colorWhite[3] = 0.8); - double radius = 2.0; - for(int i = start + 1; i < track.size(); ++i) { - //while(level < (int)handler->saves.size() && handler->saves[level] <= i) - // colorBlack[3] = (colorWhite[3] *= 0.8), ++level; - - const TPointD &a = track[i-1].position; - const TPointD &b = track[i].position; - TPointD d = b - a; - - double k = norm2(d); - if (k > TConsts::epsilon*TConsts::epsilon) { - k = 0.5*pixelSize/sqrt(k); - d = TPointD(-k*d.y, k*d.x); - glColor4dv(colorWhite); - tglDrawSegment(a - d, b - d); - glColor4dv(colorBlack); - tglDrawSegment(a + d, b + d); - radius = 2.0; - } else { - radius += 2.0; - } - - if (debugInputManager) { - glColor4d(0.0, 0.0, 0.0, 0.25); - tglDrawCircle(b, radius*pixelSize); - } + int painted = track.fixedSize() - track.fixedPointsAdded; + if (painted < 0) painted = 0; + int start = debugInputManager ? 0 : painted; + if (start + 1 < track.size()) { + double radius = 2.0; + for(int i = start + 1; i < track.size(); ++i) { + //if (i >= painted) + // colorBlack[3] = colorWhite[3] = 0.8; + + const TPointD &a = track[i-1].position; + const TPointD &b = track[i].position; + TPointD d = b - a; + + double k = norm2(d); + if (k > TConsts::epsilon*TConsts::epsilon) { + k = 0.5*pixelSize/sqrt(k); + d = TPointD(-k*d.y, k*d.x); + glColor4dv(colorWhite); + tglDrawSegment(a - d, b - d); + glColor4dv(colorBlack); + tglDrawSegment(a + d, b + d); + radius = 2.0; + } else { + radius += 2.0; + } + + if (debugInputManager) { + glColor4d(0.0, 0.0, 0.0, 0.25); + tglDrawCircle(b, radius*pixelSize); } } } diff --git a/toonz/sources/tnztools/modifiers/modifierassistants.cpp b/toonz/sources/tnztools/modifiers/modifierassistants.cpp index 1a62e44..208bb64 100644 --- a/toonz/sources/tnztools/modifiers/modifierassistants.cpp +++ b/toonz/sources/tnztools/modifiers/modifierassistants.cpp @@ -113,64 +113,68 @@ TModifierAssistants::scanAssistants( 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); - if (!drawOnly) - scanAssistants(&track[0].position, 1, &modifier->guidelines, false, true); - 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->inputGetTool()) - if (TToolViewer *viewer = tool->getViewer()) { - TAffine trackToScreen = tool->getMatrix(); - if (tool->getToolType() & TTool::LevelTool) - if (TObjectHandle *objHandle = TTool::getApplication()->getCurrentObject()) - if (!objHandle->isSpline()) - trackToScreen *= TScale(viewer->getDpiScale().x, viewer->getDpiScale().y); - trackToScreen *= 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; - } - } - modifier->savePoint.setLock(!longEnough); - } else { - modifier->savePoint.reset(); - } + if (!track.changed()) + return; + Modifier *modifier = dynamic_cast<Modifier*>(subTrack.modifier.getPointer()); + if (!modifier) + return; + + // remove points + int start = track.size() - track.pointsAdded; + if (start < 0) start = 0; + + if (!drawOnly && start <= 0) { + modifier->guidelines.clear(); + scanAssistants(&track[0].position, 1, &modifier->guidelines, false, true); + } + + bool fixed = subTrack.fixedSize() || modifier->guidelines.size() <= 1; - // add points - subTrack.truncate(start); - for(int i = start; i < track.size(); ++i) - subTrack.push_back( modifier->calcPoint(i) ); + // select guideline + if (!fixed) + if (TInputManager *manager = getManager()) + if (TInputHandler *handler = manager->getHandler()) + if (TTool *tool = handler->inputGetTool()) + if (TToolViewer *viewer = tool->getViewer()) { + TAffine trackToScreen = tool->getMatrix(); + if (tool->getToolType() & TTool::LevelTool) + if (TObjectHandle *objHandle = TTool::getApplication()->getCurrentObject()) + if (!objHandle->isSpline()) + trackToScreen *= TScale(viewer->getDpiScale().x, viewer->getDpiScale().y); + trackToScreen *= viewer->get3dViewMatrix().get2d().inv(); + TGuidelineP guideline = TGuideline::findBest(modifier->guidelines, track, trackToScreen, fixed); + 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; + } } + + // add points + subTrack.truncate(start); + for(int i = start; i < track.size(); ++i) + subTrack.push_back( modifier->calcPoint(i), false ); + + // fix points + if (fixed) { + subTrack.fix_to(track.fixedSize()); + } else + if (track.fixedSize()) { + subTrack.fix_to(1); + } + track.resetChanges(); } diff --git a/toonz/sources/tnztools/modifiers/modifierline.cpp b/toonz/sources/tnztools/modifiers/modifierline.cpp index ed923ce..e678914 100644 --- a/toonz/sources/tnztools/modifiers/modifierline.cpp +++ b/toonz/sources/tnztools/modifiers/modifierline.cpp @@ -31,12 +31,10 @@ TTrackPoint TModifierLine::Modifier::calcPoint(double originalIndex) { } void TModifierLine::modifyTrack(const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks) { if (!track.handler) { track.handler = new TTrackHandler(track); Modifier *modifier = new Modifier(*track.handler); - modifier->savePoint = savePoint; track.handler->tracks.push_back(new TTrack(modifier)); } @@ -66,7 +64,6 @@ void TModifierLine::modifyTrack(const TTrack &track, } modifier->maxPressure = maxPressure; modifier->fixAngle = fixAngle; - if (track.finished()) modifier->savePoint.reset(); subTrack.truncate(0); @@ -75,7 +72,7 @@ void TModifierLine::modifyTrack(const TTrack &track, p.originalIndex = 0; p.pressure = maxPressure; p.tilt = TPointD(); - subTrack.push_back(p); + subTrack.push_back(p, false); } if (track.size() > 1) { @@ -84,8 +81,11 @@ void TModifierLine::modifyTrack(const TTrack &track, p.pressure = maxPressure; p.tilt = TPointD(); if (fixAngle) calcFixedAngle(subTrack.front(), p); - subTrack.push_back(p); + subTrack.push_back(p, false); } + if (track.fixedFinished()) + subTrack.fix_all(); + track.resetChanges(); } diff --git a/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp b/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp index 447c9e4..1fdf154 100644 --- a/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp +++ b/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp @@ -31,7 +31,7 @@ TModifierSegmentation::addSegments( TPointD d = p1.position - p0.position; if (level >= maxRecursion || (fabs(d.x) <= m_step.x && fabs(d.y) <= m_step.y)) { - track.push_back(p1); + track.push_back(p1, false); return; } @@ -44,7 +44,6 @@ TModifierSegmentation::addSegments( void TModifierSegmentation::modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) { if (!track.handler) { @@ -77,5 +76,10 @@ TModifierSegmentation::modifyTrack( p0 = p1; } + // fix points + if (track.fixedSize()) + subTrack.fix_to( + subTrack.floorIndex(subTrack.indexByOriginalIndex(track.fixedSize() - 1)) + 1 ); + track.resetChanges(); } diff --git a/toonz/sources/tnztools/modifiers/modifiertangents.cpp b/toonz/sources/tnztools/modifiers/modifiertangents.cpp index f71c56e..531778c 100644 --- a/toonz/sources/tnztools/modifiers/modifiertangents.cpp +++ b/toonz/sources/tnztools/modifiers/modifiertangents.cpp @@ -22,11 +22,20 @@ TModifierTangents::Modifier::calcPoint(double originalIndex) { const TTrackPoint &p1 = original[i1]; TTrackTangent t0 = i0 < (int)tangents.size() ? tangents[i0] : TTrackTangent(); TTrackTangent t1 = i1 < (int)tangents.size() ? tangents[i1] : TTrackTangent(); - double l = fabs(p1.length - p0.length); + double l = p1.length - p0.length; + t0.position.x *= l; t0.position.y *= l; + t0.pressure *= l; + t0.tilt.x *= l; + t0.tilt.y *= l; + t1.position.x *= l; t1.position.y *= l; + t1.pressure *= l; + t1.tilt.x *= l; + t1.tilt.y *= l; + p = TTrack::interpolationSpline(p0, p1, t0, t1, frac); } p.originalIndex = originalIndex; @@ -40,25 +49,33 @@ TModifierTangents::Modifier::calcPoint(double originalIndex) { TTrackTangent -TModifierTangents::calcLastTangent(const TTrack &track) const { +TModifierTangents::calcTangent(const TTrack &track, int index) const { if (track.size() < 2) return TTrackTangent(); - const TTrackPoint &p0 = track[track.size() - 2]; - const TTrackPoint &p1 = track.back(); - - // calculate tangent (with normalized position) - // with valid points time normalization does not required - double dl = p1.length - p0.length; + const TTrackPoint &p0 = track[index-1]; + const TTrackPoint &p1 = track[index]; + const TTrackPoint &p2 = track[index+1]; + + // calculate tangent length by time + // for that we need know time of actual user input + // instead of time when message dispatched + //double dt = p2.time - p0.time; + //double k = dt > TConsts::epsilon ? (p1.time - p0.time)/dt : 0.0; + ////if (&p0 == &p1 || &p1 == &p2) k *= 2.0; + + // calculate tangent without time (based on length) + double k = p2.length - p0.length; + k = k > TConsts::epsilon ? 1/k : 0; + return TTrackTangent( - dl > TConsts::epsilon ? (p1.position - p0.position)*(1.0/dl) : TPointD(), - p1.pressure - p0.pressure, - p1.tilt - p0.tilt ); + (p2.position - p0.position)*k, + (p2.pressure - p0.pressure)*k, + (p2.tilt - p0.tilt)*k ); } void TModifierTangents::modifyTrack( const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks ) { if (!track.handler) { @@ -77,83 +94,31 @@ TModifierTangents::modifyTrack( return; outTracks.push_back(track.handler->tracks.front()); - - if ( !track.changed() - && track.size() == subTrack.size() - && track.size() == (int)modifier->tangents.size() ) - return; - - if (!track.changed() && subTrack.size() == track.size() - 1) { - // add temporary point - modifier->tangents.push_back(calcLastTangent(track)); - subTrack.push_back(track.back()); - } else { - // apply permanent changes - - // remove points - int start = track.size() - track.pointsAdded; - if (start < 0) start = 0; - if (start > 1) --start; - subTrack.truncate(start); - TTrackTangent lastTangent = - start < (int)modifier->tangents.size() ? modifier->tangents[start] - : modifier->tangents.empty() ? TTrackTangent() - : modifier->tangents.back(); - modifier->tangents.resize(start, lastTangent); - - // add first point - int index = start; - if (index == 0) { - modifier->tangents.push_back(TTrackTangent()); - subTrack.push_back(track.back()); - ++index; - } - - // add points with tangents - if (track.size() > 2) { - while(index < track.size() - 1) { - const TTrackPoint &p0 = track[index-1]; - const TTrackPoint &p1 = track[index]; - const TTrackPoint &p2 = track[index+1]; - - // calculate tangents length by time - // for that we need read time of user input - // instead of time when message dispatched - //double dt = p2.time - p0.time; - //double k = dt > TConsts::epsilon ? (p1.time - p0.time)/dt : 0.0; - //TTrackTangent tangent( - // (p2.position - p0.position)*k, - // (p2.pressure - p0.pressure)*k, - // (p2.tilt - p0.tilt)*k ); - - // calculate tangent (with normalized position) - TPointD d = p2.position - p0.position; - double k = norm2(d); - k = k > TConsts::epsilon*TConsts::epsilon ? 1.0/sqrt(k) : 0.0; - TTrackTangent tangent( - d*k, - (p2.pressure - p0.pressure)*0.5, - (p2.tilt - p0.tilt)*0.5 ); - - modifier->tangents.push_back(tangent); - subTrack.push_back(p1); - ++index; - } - } - - track.resetChanges(); - - // release previous key point - modifier->savePoint.reset(); - - if (track.finished()) { - // finish - modifier->tangents.push_back(calcLastTangent(track)); - subTrack.push_back(track.back()); - } else { - // save key point - modifier->savePoint = savePoint; - } + if (!track.changed()) + return; + + // update subTrack + int start = track.size() - track.pointsAdded; + if (start < 0) start = 0; + subTrack.truncate(start); + for(int i = start; i < track.size(); ++i) + subTrack.push_back(track[i], false); + + // update tangents + int tangentsStart = start - 1; + if (tangentsStart < 0) tangentsStart = 0; + modifier->tangents.resize(tangentsStart); + for(int i = tangentsStart; i < subTrack.size(); ++i) + modifier->tangents.push_back(calcTangent(subTrack, i)); + + // fix points + if (track.fixedFinished()) { + subTrack.fix_all(); + } else + if (track.fixedSize()) { + subTrack.fix_to(std::max(track.fixedSize() - 1, 1)); } + + track.resetChanges(); } diff --git a/toonz/sources/tnztools/modifiers/modifiertest.cpp b/toonz/sources/tnztools/modifiers/modifiertest.cpp index 2033a2b..7801f3b 100644 --- a/toonz/sources/tnztools/modifiers/modifiertest.cpp +++ b/toonz/sources/tnztools/modifiers/modifiertest.cpp @@ -52,7 +52,6 @@ TModifierTest::TModifierTest(int count, double radius) : count(count), radius(radius) {} void TModifierTest::modifyTrack(const TTrack &track, - const TInputSavePoint::Holder &savePoint, TTrackList &outTracks) { const double segmentSize = 2.0 * M_PI / 10.0; @@ -68,7 +67,7 @@ void TModifierTest::modifyTrack(const TTrack &track, Handler *handler = dynamic_cast<Handler *>(track.handler.getPointer()); if (!handler) { - TInputModifier::modifyTrack(track, savePoint, outTracks); + TInputModifier::modifyTrack(track, outTracks); return; } @@ -124,14 +123,19 @@ void TModifierTest::modifyTrack(const TTrack &track, double end = 1.0 - 0.5 * step; for (double frac = step; frac < end; frac += step) subTrack.push_back( - subTrack.modifier->calcPoint((double)i - 1.0 + frac)); + subTrack.modifier->calcPoint((double)i - 1.0 + frac), false); } } - subTrack.push_back(subTrack.modifier->calcPoint(i)); + subTrack.push_back(subTrack.modifier->calcPoint(i), false); } + + // fix points + if (track.fixedSize()) + subTrack.fix_to( + subTrack.floorIndex(subTrack.indexByOriginalIndex(track.fixedSize() - 1)) + 1 ); } track.resetChanges(); } -#endif \ No newline at end of file +#endif diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.cpp b/toonz/sources/tnztools/toonzrasterbrushtool.cpp index 61148f5..ad71c14 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.cpp +++ b/toonz/sources/tnztools/toonzrasterbrushtool.cpp @@ -1176,10 +1176,10 @@ bool ToonzRasterBrushTool::preLeftButtonDown() { m_inputmanager.clearModifiers(); m_inputmanager.addModifier(TInputModifierP(m_modifierTangents.getPointer())); m_inputmanager.addModifier(TInputModifierP(m_modifierAssistants.getPointer())); - m_inputmanager.addModifier(TInputModifierP(m_modifierSegmentation.getPointer())); #ifndef NDEBUG m_inputmanager.addModifier(TInputModifierP(m_modifierTest.getPointer())); #endif + m_inputmanager.addModifier(TInputModifierP(m_modifierSegmentation.getPointer())); touchImage(); if (m_isFrameCreated) { @@ -1369,8 +1369,8 @@ void ToonzRasterBrushTool::inputSetBusy(bool busy) { //-------------------------------------------------------------------------------------------------- -void ToonzRasterBrushTool::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack) { - if (!m_painting.active) +void ToonzRasterBrushTool::inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, bool firstTrack, bool preview) { + if (!m_painting.active || preview) return; TImageP img = getImage(true); diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.h b/toonz/sources/tnztools/toonzrasterbrushtool.h index d2adfef..b2e3cda 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.h +++ b/toonz/sources/tnztools/toonzrasterbrushtool.h @@ -160,7 +160,7 @@ public: const TInputState &state) override; void inputSetBusy(bool busy) override; void inputPaintTrackPoint(const TTrackPoint &point, const TTrack &track, - bool firstTrack) override; + bool firstTrack, bool preview) override; void inputInvalidateRect(const TRectD &bounds) override { invalidate(bounds); } TTool *inputGetTool() override { return this; }; diff --git a/toonz/sources/tnztools/track.cpp b/toonz/sources/tnztools/track.cpp index 8d048d1..5af347a 100644 --- a/toonz/sources/tnztools/track.cpp +++ b/toonz/sources/tnztools/track.cpp @@ -42,7 +42,9 @@ TTrack::TTrack( hasPressure(hasPressure), hasTilt(hasTilt), pointsRemoved(), - pointsAdded() + pointsAdded(), + fixedPointsAdded(), + m_pointsFixed() { } TTrack::TTrack(const TTrackModifierP &modifier): @@ -55,7 +57,9 @@ TTrack::TTrack(const TTrackModifierP &modifier): hasTilt(modifier->original.hasTilt), modifier(modifier), pointsRemoved(), - pointsAdded() + pointsAdded(), + fixedPointsAdded(), + m_pointsFixed() { } const TTrack* @@ -82,7 +86,7 @@ TTrack::floorIndex(double index, double *outFrac) const { } void -TTrack::push_back(const TTrackPoint &point) { +TTrack::push_back(const TTrackPoint &point, bool fixed) { m_points.push_back(point); if (size() > 1) { const TTrackPoint &prev = *(m_points.rbegin() + 1); @@ -100,12 +104,14 @@ TTrack::push_back(const TTrackPoint &point) { p.length = prev.length + sqrt(d.x*d.x + d.y*d.y); } ++pointsAdded; + if (fixed) fix_all(); } void TTrack::pop_back(int count) { if (count > size()) count = size(); if (count <= 0) return; + assert(size() - count >= m_pointsFixed); m_points.resize(size() - count); if (pointsAdded > count) { pointsAdded -= count; return; } @@ -114,6 +120,15 @@ TTrack::pop_back(int count) { pointsRemoved += count; } +void +TTrack::fix_points(int count) { + count = std::min(count, previewSize()); + assert(count >= 0); + if (count <= 0) return; + m_pointsFixed += count; + fixedPointsAdded += count; +} + TTrackPoint TTrack::calcPoint(double index) const {