diff --git a/toonz/sources/include/tools/modifiers/modifierclone.h b/toonz/sources/include/tools/modifiers/modifierclone.h index 214e70f..763d28c 100644 --- a/toonz/sources/include/tools/modifiers/modifierclone.h +++ b/toonz/sources/include/tools/modifiers/modifierclone.h @@ -44,12 +44,21 @@ public: public: bool keepOriginals; TTrackTransformList transforms; + int skipFirst; + int skipLast; - TModifierClone(bool keepOriginals = true); + explicit TModifierClone( + bool keepOriginals = true, + int skipFirst = 0, + int skipLast = 0 ); void modifyTrack( const TTrack &track, TTrackList &outTracks ) override; + + void modifyTracks( + const TTrackList &tracks, + TTrackList &outTracks ) override; }; #endif diff --git a/toonz/sources/include/tools/modifiers/modifierjitter.h b/toonz/sources/include/tools/modifiers/modifierjitter.h index 2f048e4..d67994d 100644 --- a/toonz/sources/include/tools/modifiers/modifierjitter.h +++ b/toonz/sources/include/tools/modifiers/modifierjitter.h @@ -41,11 +41,13 @@ public: double period; double amplitude; int skipFirst; + int skipLast; - TModifierJitter( + explicit TModifierJitter( double period = 30, double amplitude = 10, - int skipFirst = 0 ); + int skipFirst = 0, + int skipLast = 0 ); void modifyTrack( const TTrack &track, diff --git a/toonz/sources/include/tools/replicator.h b/toonz/sources/include/tools/replicator.h index 0556802..e0b159f 100644 --- a/toonz/sources/include/tools/replicator.h +++ b/toonz/sources/include/tools/replicator.h @@ -27,16 +27,26 @@ class DVAPI TReplicator : public TAssistantBase { public: typedef std::vector PointList; + const TStringId m_idSkipFirst; + const TStringId m_idSkipLast; + static const int multiplierSoftLimit; static const int multiplierLimit; TReplicator(TMetaObject &object); + void updateTranslation() const override; + + inline int getSkipFirst() const + { return std::max(0, (int)data()[m_idSkipFirst].getDouble()); } + inline int getSkipLast() const + { return std::max(0, (int)data()[m_idSkipLast].getDouble()); } + virtual int getMultipler() const; virtual void getPoints(const TAffine &toTool, PointList &points) const; virtual void getModifiers(const TAffine &toTool, TInputModifier::List &outModifiers) const; - static void transformPoints(const TAffine &aff, PointList &points, int count); + static void transformPoints(const TAffine &aff, PointList &points, int i0, int i1); static void drawReplicatorPoints(const TPointD *points, int count); //! return summary multiplier, or 0 is no replicators found @@ -51,6 +61,11 @@ public: TImage *skipImage ); protected: + inline void setSkipFirst(int x) + { if (getSkipFirst() != (double)x) data()[m_idSkipFirst].setDouble((double)x); } + inline void setSkipLast(int x) + { if (getSkipLast() != (double)x) data()[m_idSkipLast].setDouble((double)x); } + TIntProperty* createCountProperty(const TStringId &id, int def = 1, int min = 1, int max = 0); }; diff --git a/toonz/sources/tnztools/assistants/replicatoraffine.cpp b/toonz/sources/tnztools/assistants/replicatoraffine.cpp index f637c90..02c36cc 100644 --- a/toonz/sources/tnztools/assistants/replicatoraffine.cpp +++ b/toonz/sources/tnztools/assistants/replicatoraffine.cpp @@ -249,6 +249,8 @@ public: void getPoints(const TAffine &toTool, PointList &points) const override { points.reserve(points.size() * getMultipler()); int pointsCount = (int)points.size(); + int i0 = getSkipFirst(); + int i1 = pointsCount - getSkipLast(); TAffine aff = getAffine(toTool); struct { @@ -262,7 +264,7 @@ public: TAffine a; for(int j = 0; j < t[i].count; ++j) { a = t[i].aff * a; - transformPoints(a, points, pointsCount); + transformPoints(a, points, i0, i1); } } } @@ -285,7 +287,7 @@ public: { getCountInv(), aff.inv(), pressureInv }, }; - TModifierClone *modifier = new TModifierClone(); + TModifierClone *modifier = new TModifierClone(true, getSkipFirst(), getSkipLast()); for(int i = 0; i < 2; ++i) { TTrackTransform tt; for(int j = 0; j < t[i].count; ++j) { diff --git a/toonz/sources/tnztools/assistants/replicatorgrid.cpp b/toonz/sources/tnztools/assistants/replicatorgrid.cpp index b276024..7928f2f 100644 --- a/toonz/sources/tnztools/assistants/replicatorgrid.cpp +++ b/toonz/sources/tnztools/assistants/replicatorgrid.cpp @@ -177,6 +177,8 @@ public: void getPoints(const TAffine &toTool, PointList &points) const override { points.reserve(points.size() * getMultipler()); int pointsCount = (int)points.size(); + int i0 = getSkipFirst(); + int i1 = pointsCount - getSkipLast(); TPointD c = toTool*m_center.position; TPointD da = toTool*m_a.position - c; @@ -212,22 +214,22 @@ public: transformPoints( TAffine( 1, 0, o.x, 0, 1, o.y ), - points, pointsCount ); + points, i0, i1 ); if (mirrorA) transformPoints( TAffine( ma.a11, ma.a12, ma.a13 + o.x, ma.a21, ma.a22, ma.a23 + o.y ), - points, pointsCount ); + points, i0, i1 ); if (mirrorB) transformPoints( TAffine( mb.a11, mb.a12, mb.a13 + o.x, mb.a21, mb.a22, mb.a23 + o.y ), - points, pointsCount ); + points, i0, i1 ); if (mirrorA && mirrorB) transformPoints( TAffine( mc.a11, mc.a12, mc.a13 + o.x, mc.a21, mc.a22, mc.a23 + o.y ), - points, pointsCount ); + points, i0, i1 ); } } @@ -263,7 +265,7 @@ public: int a0 = -getCountAInv(); int b0 = -getCountBInv(); - TModifierClone *modifier = new TModifierClone(); + TModifierClone *modifier = new TModifierClone(true, getSkipFirst(), getSkipLast()); for(int ib = b0; ib < b1; ++ib) for(int ia = a0; ia < a1; ++ia) { TPointD o = da*ia + db*ib; diff --git a/toonz/sources/tnztools/assistants/replicatorjitter.cpp b/toonz/sources/tnztools/assistants/replicatorjitter.cpp index befb329..4daeb4b 100644 --- a/toonz/sources/tnztools/assistants/replicatorjitter.cpp +++ b/toonz/sources/tnztools/assistants/replicatorjitter.cpp @@ -16,7 +16,6 @@ class TReplicatorJitter final : public TReplicator { Q_DECLARE_TR_FUNCTIONS(TReplicatorJitter) public: - const TStringId m_idSkipFirst; const TStringId m_idPeriod; const TStringId m_idAmplitude; @@ -26,13 +25,10 @@ protected: public: TReplicatorJitter(TMetaObject &object): TReplicator(object), - m_idSkipFirst("skipFirst"), m_idPeriod("period"), m_idAmplitude("m_idAmplitude"), m_center( addPoint("center", TAssistantPoint::CircleCross) ) { - addProperty( createSpinProperty(m_idSkipFirst, getSkipFirst(), 0) ); - TDoubleProperty *p; p = new TDoubleProperty(m_idPeriod.str(), 0.0, 1000, getPeriod()); @@ -51,22 +47,17 @@ public: void updateTranslation() const override { TReplicator::updateTranslation(); - setTranslation(m_idSkipFirst, tr("Skip First Tracks")); setTranslation(m_idPeriod, tr("Period")); setTranslation(m_idAmplitude, tr("Amplitude")); } - inline int getSkipFirst() const - { return (int)data()[m_idSkipFirst].getDouble(); } inline double getPeriod() const { return data()[m_idPeriod].getDouble(); } inline double getAmplitude() const { return data()[m_idAmplitude].getDouble(); } protected: - inline void setSkipFirst(int x) - { if (getSkipFirst() != (double)x) data()[m_idSkipFirst].setDouble((double)x); } inline void setPeriod(double x) { if (getPeriod() != x) data()[m_idPeriod].setDouble(x); } inline void setAmplitude(double x) @@ -95,19 +86,22 @@ protected: public: void getPoints(const TAffine &toTool, PointList &points) const override { - int skipFirst = getSkipFirst(); - if (skipFirst < 0) skipFirst = 0; - if (skipFirst >= (int)points.size()) return; + int pointsCount = (int)points.size(); + int i0 = getSkipFirst(); + int i1 = pointsCount - getSkipLast(); + if (i0 < 0) i0 = 0; + if (i1 > pointsCount) i1 = pointsCount; + if (i0 >= i1) return; double scale = getScale(toTool); double period = getPeriod()*scale; double amplitude = getAmplitude()*scale; - if (!(period > TConsts::epsilon && amplitude > TConsts::epsilon)) { + if (period > TConsts::epsilon && amplitude > TConsts::epsilon) { int seedX = 0; int seedY = 7722441; - for(PointList::iterator i = points.begin() + skipFirst; i != points.end(); ++i) { - i->x += TModifierJitter::func(seedX, 0)*amplitude; - i->y += TModifierJitter::func(seedY, 0)*amplitude; + for(int i = i0; i < i1; ++i) { + points[i].x += TModifierJitter::func(seedX, 0)*amplitude; + points[i].y += TModifierJitter::func(seedY, 0)*amplitude; ++seedX, ++seedY; } } @@ -122,7 +116,8 @@ public: outModifiers.push_back(new TModifierJitter( getPeriod()*scale, getAmplitude()*scale, - getSkipFirst() )); + getSkipFirst(), + getSkipLast() )); } diff --git a/toonz/sources/tnztools/assistants/replicatormirror.cpp b/toonz/sources/tnztools/assistants/replicatormirror.cpp index 0c608c8..04ad2cb 100644 --- a/toonz/sources/tnztools/assistants/replicatormirror.cpp +++ b/toonz/sources/tnztools/assistants/replicatormirror.cpp @@ -117,15 +117,19 @@ public: { return 2; } - void getPoints(const TAffine &toTool, PointList &points) const override - { transformPoints(getAffine(toTool), points, (int)points.size()); } + void getPoints(const TAffine &toTool, PointList &points) const override { + int pointsCount = (int)points.size(); + int i0 = getSkipFirst(); + int i1 = pointsCount - getSkipLast(); + transformPoints(getAffine(toTool), points, i0, i1); + } void getModifiers( const TAffine &toTool, TInputModifier::List &outModifiers ) const override { - TModifierClone *modifier = new TModifierClone(); + TModifierClone *modifier = new TModifierClone(true, getSkipFirst(), getSkipLast()); modifier->transforms.push_back(TTrackTransform( getAffine(toTool), getPressure() )); outModifiers.push_back(modifier); diff --git a/toonz/sources/tnztools/assistants/replicatorstar.cpp b/toonz/sources/tnztools/assistants/replicatorstar.cpp index f9821d7..e60f10b 100644 --- a/toonz/sources/tnztools/assistants/replicatorstar.cpp +++ b/toonz/sources/tnztools/assistants/replicatorstar.cpp @@ -116,6 +116,8 @@ public: void getPoints(const TAffine &toTool, PointList &points) const override { points.reserve(points.size() * getMultipler()); int pointsCount = (int)points.size(); + int i0 = getSkipFirst(); + int i1 = pointsCount - getSkipLast(); int count = getCount(); bool mirror = getMirror(); @@ -131,12 +133,12 @@ public: TAffine t0 = t1.inv(); TRotation r(360.0/getCount()); - + for(int i = 0; i < count; ++i) { if (i) - transformPoints(t1*t0, points, pointsCount); + transformPoints(t1*t0, points, i0, i1); if (mirror) { - transformPoints(t2*t0, points, pointsCount); + transformPoints(t2*t0, points, i0, i1); t2 *= r; } t1 *= r; @@ -163,7 +165,7 @@ public: TAffine t0 = t1.inv(); TRotation r(360.0/getCount()); - TModifierClone *modifier = new TModifierClone(); + TModifierClone *modifier = new TModifierClone(true, getSkipFirst(), getSkipLast()); for(int i = 0; i < count; ++i) { if (i) modifier->transforms.push_back(TTrackTransform(t1*t0)); diff --git a/toonz/sources/tnztools/modifiers/modifierclone.cpp b/toonz/sources/tnztools/modifiers/modifierclone.cpp index 05d96b8..52db00a 100644 --- a/toonz/sources/tnztools/modifiers/modifierclone.cpp +++ b/toonz/sources/tnztools/modifiers/modifierclone.cpp @@ -16,8 +16,8 @@ TTrackPoint TModifierClone::Interpolator::interpolate(double index) // TModifierClone implementation //***************************************************************************************** -TModifierClone::TModifierClone(bool keepOriginals): - keepOriginals(keepOriginals) { } +TModifierClone::TModifierClone(bool keepOriginals, int skipFirst, int skipLast): + keepOriginals(keepOriginals), skipFirst(skipFirst), skipLast(skipLast) { } void TModifierClone::modifyTrack(const TTrack &track, TTrackList &outTracks) @@ -73,3 +73,15 @@ void TModifierClone::modifyTrack(const TTrack &track, track.resetChanges(); } +void TModifierClone::modifyTracks( + const TTrackList &tracks, + TTrackList &outTracks ) +{ + int cnt = (int)tracks.size(); + int i0 = skipFirst; + int i1 = cnt - skipLast; + for(int i = 0; i < cnt; ++i) + if (i0 <= i && i < i1) modifyTrack(*tracks[i], outTracks); + else TInputModifier::modifyTrack(*tracks[i], outTracks); +} + diff --git a/toonz/sources/tnztools/modifiers/modifierjitter.cpp b/toonz/sources/tnztools/modifiers/modifierjitter.cpp index 292bb82..0a8eee5 100644 --- a/toonz/sources/tnztools/modifiers/modifierjitter.cpp +++ b/toonz/sources/tnztools/modifiers/modifierjitter.cpp @@ -109,8 +109,8 @@ TTrackPoint TModifierJitter::Interpolator::interpolate(double index) //***************************************************************************************** -TModifierJitter::TModifierJitter(double period, double amplitude, int skipFirst): - period(period), amplitude(amplitude), skipFirst(skipFirst) { } +TModifierJitter::TModifierJitter(double period, double amplitude, int skipFirst, int skipLast): + period(period), amplitude(amplitude), skipFirst(skipFirst), skipLast(skipLast) { } void TModifierJitter::modifyTrack(const TTrack &track, @@ -154,15 +154,15 @@ void TModifierJitter::modifyTrack(const TTrack &track, void TModifierJitter::modifyTracks( - const TTrackList &tracks, - TTrackList &outTracks ) + const TTrackList &tracks, + TTrackList &outTracks ) { - int cnt = std::min( std::max(0, skipFirst), (int)tracks.size() ); - TTrackList::const_iterator split = tracks.begin() + cnt; - for(TTrackList::const_iterator i = tracks.begin(); i != split; ++i) - TInputModifier::modifyTrack(**i, outTracks); - for(TTrackList::const_iterator i = split; i != tracks.end(); ++i) - modifyTrack(**i, outTracks); + int cnt = (int)tracks.size(); + int i0 = skipFirst; + int i1 = cnt - skipLast; + for(int i = 0; i < cnt; ++i) + if (i0 <= i && i < i1) modifyTrack(*tracks[i], outTracks); + else TInputModifier::modifyTrack(*tracks[i], outTracks); } diff --git a/toonz/sources/tnztools/replicator.cpp b/toonz/sources/tnztools/replicator.cpp index 6e63cb6..b7c9d27 100644 --- a/toonz/sources/tnztools/replicator.cpp +++ b/toonz/sources/tnztools/replicator.cpp @@ -24,7 +24,22 @@ const int TReplicator::multiplierLimit = 256; //************************************************************************ TReplicator::TReplicator(TMetaObject &object): - TAssistantBase(object) { } + TAssistantBase(object), + m_idSkipFirst("skipFirst"), + m_idSkipLast("skipLast") +{ + addProperty( createSpinProperty(m_idSkipFirst, getSkipFirst(), 0) ); + addProperty( createSpinProperty(m_idSkipLast, getSkipLast(), 0) ); +} + +//--------------------------------------------------------------------------------------------------- + +void +TReplicator::updateTranslation() const { + TAssistantBase::updateTranslation(); + setTranslation(m_idSkipFirst, tr("Skip First Tracks")); + setTranslation(m_idSkipLast, tr("Skip Last Tracks")); +} //--------------------------------------------------------------------------------------------------- @@ -57,9 +72,13 @@ TReplicator::createCountProperty(const TStringId &id, int def, int min, int max) //--------------------------------------------------------------------------------------------------- void -TReplicator::transformPoints(const TAffine &aff, PointList &points, int count) { - points.reserve(points.size() + count); - for(int i = 0; i < count; ++i) +TReplicator::transformPoints(const TAffine &aff, PointList &points, int i0, int i1) { + int cnt = (int)points.size(); + if (i0 < 0) i0 = 0; + if (i1 > cnt) i1 = cnt; + if (i0 >= i1) return; + points.reserve(points.size() + i1 - i0); + for(int i = i0; i < i1; ++i) points.push_back(aff*points[i]); }