From 31d94c343ff4f773e8a883188f2440a6594b92f6 Mon Sep 17 00:00:00 2001 From: Merzlikin-Matvey Date: Sun, 10 Aug 2025 23:20:57 +0300 Subject: [PATCH 1/7] Add support for negative z-index in AnimationGroup --- manim/scene/scene.py | 27 +++++++++++++++++- .../negative_z_index_AnimationGroup.npz | Bin 0 -> 4070 bytes .../geometry/negative_z_index_LaggedStart.npz | Bin 0 -> 13083 bytes tests/test_graphical_units/test_geometry.py | 14 +++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz create mode 100644 tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz diff --git a/manim/scene/scene.py b/manim/scene/scene.py index 9ea3e31749..f173e1f042 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -885,6 +885,31 @@ def clear(self) -> Self: self.foreground_mobjects = [] return self + def recursively_unpack_animation_groups(self, *animations: Animation) -> list[Mobject]: + """ + Unpacks animations + Parameters + ---------- + *animations + The animations to unpack + Returns + ------ + list + The list of mobjects in animations + """ + # Imported inside the method to avoid cyclic import + from ..animation.composition import AnimationGroup + + mobjects = [] + for anim in animations: + if isinstance(anim, AnimationGroup): + for sub in anim.animations: + unpacked = self.recursively_unpack_animation_groups(sub) + mobjects.extend(unpacked) + else: + mobjects.append(anim.mobject) + return mobjects + def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]: """ Gets all moving mobjects in the passed animation(s). @@ -904,7 +929,7 @@ def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]: # as soon as there's one that needs updating of # some kind per frame, return the list from that # point forward. - animation_mobjects = [anim.mobject for anim in animations] + animation_mobjects = self.recursively_unpack_animation_groups(*animations) mobjects = self.get_mobject_family_members() for i, mob in enumerate(mobjects): update_possibilities = [ diff --git a/tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz b/tests/test_graphical_units/control_data/geometry/negative_z_index_AnimationGroup.npz new file mode 100644 index 0000000000000000000000000000000000000000..80ba71a0ebfd9addbc4f6fe2ddf469d3e5553b43 GIT binary patch literal 4070 zcmWIWW@gc4U|`??Vnqhd8j)B3p@5G;gdwdcF*h|nC9xz?FR!4IkwJjL;iNWDB?ChU zKbT^8d&e;QPN~fCk2|dH&e8PlbZXlyE+AvQLsO5>FDPe8^Nk6s+ymrWFQ5IcGf91d z`^D!IbZ_7P#}&CGqv`3t`M>Mp+4V0iYutUl{>Q$B7yf(?>tg-`~HhqR?#L|EHhl$IajS_uuR3=g*(N_wV22 z^ZtGF=IQzO`OV+=_v*{#>hAS&wx7O!Jb3UR3&gpjC^RpXMTJh#d;uS3s*x)6sv>PS|)|LVT=>}Rx@}k z4`o<#S&QM)&+P{omVB<)VIGdD~727j2Y`VKW>-yOluWK1^*yD(~OkhsL6S1UAzuPBy`)%2+95ZXtWJ`O~p;8_VCN^Bs8HbGx>> z+WPnN8?76IS2KL;M=Reck4&nTG3Y6UIKy`p?tcI7-LkJ$vG;DQ3}yJ8zB9(}`t|F% zJ$sAoi?N5@s3=AVRP;b9p0Z=_cFwnD;4iMIu;{&BwtMbg`P~L(eb;Z;e&5XgAn{%F z)u(0Ux48oxx8J^-tM9;iH?MsAUIx*U-FNSPV+y(Oc2sgO1j6_2)w}Qd%|5$q4>;eS zPTDwQuY9q@?&o#iFk*h-1svM;GX{7wGU+m)_R2y1ZBXBv56OuQ;Kl}OA3eaEl?|kX N5eRL7^b~ME9RQ&R@h{(RAf`GCbLI@BbZGBZ_OBLB< zNd*B3A(34ONo*lRc3FdgBuZEVA%*|}vVC{#JKxNl_rIC%ocZG|9Oa--o+r7V>-ufi z{akk5`LT(Lipu{1e~zg<{9Jp#;=jN4s~l1ZjlC8X0=<4M?%K)dTZubV4ydSP*@Gih zRPLYp@Iz&Ja&O~hM2YG91nOsrROsq~F;VkMzgif2_d2zXHvSr{{BSjN^SC(5veNpQspKDms&O#KiYeat}Ap#LrPQ z*N@z`yY8~`$^us$wLJgHUpjh=aYY9UHEnEaVrA_Z?N-N7JpQ8zix9_Ag&j80Lu}Px zBzoHO+|UnKSB#~5WOq*C*sgXz5 ztgtgwnUc%mVx9&!3Q{ zzw2<0_V9UdDkj#LqZ(>Mz3H*;I_DSqZKz+UQ|P%|Sm7}P3~HU{amoZ^K6omh$8lgS zc`k*@J^21c0wYF`ypP=XvhVeBFZ}L)ZH-#Lmgu$lPhLWuJdE~fSv|k*=|R7KVyywQ%y>vHbXyAFjRny7nW)MTGyDlL3bmvT+qLi0#GUAm(3UjMfF^sh+cK)horg z<{A`cEa^OWQQNAG8*BSZQB{&FxcK@di#!gYzOtH4leOY|;zPe<37~~Ygn6Z}{vdIZ zpddW&dEswvZZJ5=#A)PvsE`QB`uP@@#xMAgW^Aa2ey2KCWq!>ftHEBo+lhfqEp~8y z>T!>C_hxg4*uc_!!Tb8%JrPf(T^+Co=3rn{cU`n!huCT_ODm`AFurPSHQ--C7Lz; zv%~)TX2D(G(zCUlNgp^?+3zDRHYUvGD9sefMwau*)-SWIrqfE2RAt-i8M2MZn0o}+ z=DT}N04OwMi66awAKL%;utY#bN1O(YRNeO=Y@<$l2x~i*nzEm@yEzUsX*LcH?*XW>Xce?Uo;pZi15zJ`WXL^pE#n$kk zcfZ{+L-0mpvzB!M@M$H^JTOaKol&=mk6bLWf&~@F_88R7m!k5Jx%wq>SB?%QdO=eV zK9YrUO!QjVpZ?Op8!C4)4s5r|Gld4OR`sMm;?x4^aVUz}Xu$vE;E6}uRp)a~z=Sll z{7)m8jW<8lwYMd-&OK&k76BYAPME$wyE&8NnoZtd)@aS6C~q3Vr~;iXjIM52F{~?o zX`slG=uh&Ec>T*aL+y#80vlv>HyMbUE;G88d%eZHv0t-sl6Zx+FnI6>YPOV&ZMrho z(ZmS!^8@(QS8Uy|(T>mc#CyBd8<__S$l{YSAEOX-==o-PmZlfmBy?XMqu016MRP0K z%-lp&weokg+Fo#iXx!6|_deRIMUt-eawmc@S>v^SjDZILL@M#;aqZ^|kC}(|eTBFP z;DbZ-;I<-JV*ixYEdv!v- zO;+UjM~UpZS&qYO>itJsc}E}8Tj^hL4tfTAl;l7f#(OB+ z79Kqme?9nf&`=eoR0O|a&_0CKH`IsawH1aW_Tx$lAEUmF6`(?WWyT->`@Q|g8UE!J zm^iut`k}x)%%wPqS3T4aHmH8;`gi4=gDO||+pWF!CdEg^@kR{*3Q{-cEU8EL9x#t^ z#4I)$71JW0>CWMaWeUC=sj4E81@KR0m@qDaR3G@Qsg8Ngf^JoLTSP$TeXa?9^$N>N=%U9@d8 zdF=|G*o}o*B)Vtq(>;4yM=^jb6GfA9H+G5UXi*mHt{Ih=xSAN-&lxA7I<=22G2J;Q zXc?yM2M(&*;ERzR>kK+VSCL>%*{UoG>VeU7xkpDTX#tvN+66ju$uoK|NgHCa7NtlL z=SH+djvMR9x-5gFFJME>9yKonY*cSb+>OaIc>%Cp9 z9$x;biQSFGIdYh2t^ob+PDtd$&&TT43&W;)HH37QO+3CtuSO;QQhx+5kBfm&nps~) zlxaq%IfaK;M$W@1(3&n1V(AD3*Zp+I&fT4rkMX#<4c=JIS_`fkRi83oJ>SW<@EIdQ zsl(Jkd&wj2g`6ZRJ#4U4dnvpg7Y>EG=g%?`^UI#@lO9}4c0zDsOrb!nhN3%qeJl{g z9|Je=hr45qH%B(dTPRH|fiyVV`os#L*4Sdn1a*^UI-Z?%)cizgb@k0tT=_$MkEl7C z)y5JNZ7n5BY^P9}SDq=E74V_uBxFwc+^XOx=#otlt=LF`)E3jjtK6gk7lwmD9z^F=t|DURjB!;Le1##gQSV#^t9;kqz&G+ww?^Mw*W+G+C%zqh?{&?a4hZV5tC`GLt%{XF` zZVjLN7P#V|&a}_6Qe9OpTW>FvbHRV!2L_t1#8FeKG}ahONd{2;0>%vj@e|OnHH0?9 zBmjg;Id)h4a;Iu1=oG)nQXqZs{;jd#*gI;0>Hvq z6zQxfy&Pk&;c#!ii3l{0AFmNe>aNEY5oJI+Pu8M`&+F4#s4{-SY_8XI16CHPm9+4r zLXoDIop#vBvlDN}F*v(FT z4O!tw%Z5ygm?JFTmhiZH+FzfLGnR<-Nrg~X_`dX20v&#b5TfYVW+#h6kHh~E$xM-nU2qVr-KgZxLc62 zy*Ru16MW!4ow{BtW_66^2OLpN<;(fwGWm$B(_nm5xzpqsVR?RFdd>;m!zuAg>VDWH zL;LvIT(e)C=e;G>MP1h9Q$lwLJBx+gFr4m2Nx!_sxV*shMY%fFu zk}y}8Fb`3fpCsK#T^ux?@OGzPo!4#@2MW>bME$$#yu*XGTi5%nMSa7Nq=lb{IV~g6 z739dF3gLQxQSjv!f)E=+)n*v`e7@JTK+Q6+#ZWFoQjNAmRrS1a&6qSnX7(5(gRXYb9b?>Xl8*}bMvp4F0K8x*Yr`m4hQ5e zOH)7Taxpev0CA{A6!i$p%w62lpWitSI;tV(euOP=D( z-R(VCaHb59Ams@{EIG+=enO~6Xi%{78f>a;lA8PYL_`JP3L2>Spy8+IL+}73>kv!h z1-6N?-3=hb&9%Gj!<`9Co07Z+-ltx*42L~+FS>29a#Jp*LI+51f7*MYBz_7;KisOO zXI{TzH$%z9%Gatwurxqjhk?;EgcC?BZS^hOU|or~j~=~YE*v!K8<7|YvwZSOA{l^x zt`hW7;mh;DHFS$Z%N?`QckMm$$p7fq-@lCK7P^79jQ5Z2KHemlSQR{RvEQ00Q$qT9 zH`l%yJYM+e3Yoil^a^@+!>8c1TZ`hL~1OL|1f*0$+dtilGa7>N&s%C9o| zjeD86@RkV1$qm301;FAe9j5?AR}O{#`1((+z;kmTufNCxoeQ5I$fBf3x?Vld)0CB} z{1OXjzAHt{QUgK4eHgckRzsv{7tnTQyol^-@huPl&}Cu{)q#<~&9V#{edd-Wx7~3g!N(m`pvhfT-N65c`mc`N z>tr@XIJ079>kMUj5(H3L2=sTJKS&`1Y-MXBW)b7~0+3E5uh&4c=sGB4C2hpyCyuAhw1_@u8foq_1o~$61Zv* z3{tU4Pv8|{x~6lg#&=eMzZp5BiCrU+lgAo zYE!I9MX-wsHY|=BC>%kjTAZ{Aanyo5gGx7B=ch&37bh$CYac3#hN{u`E%?o~%SasB z9r`5@-THK+saZ0P`pfKXziwRI^z&a~ONX7g*uVsPfQ)2s`0Q*2q~UEHkp)GummTO% za`Rx~J7EueunUJ7Fp-66pRQbUJvv2gWCWlt*^+0`o%cJ$X<~MY6MYE6~8B&AxcJG)l$*2S}gmFN&B%vJ=CUc?%FMjBE~q5im;*0dg~3 z!cJPMRW}d4_;bm0#Q#8h5Cx^(-hcL4vZ-G~=%s%|dtibC!XM*v+mHes=vI$c(CSS02ecPX!3Sx| zBx`jUNUE<;yWwcm%AHqa)&3$&Q^}uk+XnE3JiqAs^H?;c*b*(5Ua7iNc&g$RS-tQ9 zLhugXFpv(F@w@=ugPW-R0q^a%x?S_g+Kd2Xz(3+W@UwYJyvIss^ecAvS*(_7NLoL7 zeQTBcW?`tDJM3&~(t7IF+n4+<^YTz&j(`NjrF_u&JqA^W0J|DBx#+l-oNbb3xm$RS zS#OCRI-k7n4xD+)-*i6kR29TvdNypXFf8xyI)A_I`UDT?0>(mO-I^idO_U}kDDP^rWPh!VluU?>xY!nV}PfTQy@nk0_s`aGTOg=n^#j8 zJKF=&YAzjv0ht`?9-%IIYjuG|LY6~Zft=}3g=hipua3eduXfh~0|1UygC@h2QXRMg zV5{{UvowBp1^E_ZVBDoNeHEwK7U&!Vj;%q5E>=j97mNa)Nc&Xy-$^2(|~MdT!#@o1bEn#ktPYV*-eXg4(1P5it1_atH~5ZsXHlB#)+fpA8?}T&K3{V2ecW zyyIW8g+x=bx+-V8`UUS7*|ZI`O^+~vzFsIApej&PN!x4xBg*m0(mX6qO-_`q&E`*& z#q10T!Ov~me6M_-p^LW@+^u$UlEe8=g1Jy=^05`)`sZsz`_Q08=$UxzFgv*eAzbBh zvTIazv;|~IwC!fKYgc71qce}{r-qhx=w48Q{`Q8N!ak6-9aor>D(8AlKNy_4(iL4C z@82#1)(I(SGbbE{RK{m3_Zl?a82ZA+hTq7H2W%V!@@8R=5fR9IkknA(+r5Z^$8(gE zM?m?tC6iRNVwls0SQ-v|aqF7x+G_{1g!gZUA@R!-|1I&SX&K5Cq=|1MXm7v=AYJAM zN+Rfjwk5(UyBG9b>C)sw&yo&8)A^QV)M~uCB#*X$)8LIpR;THdNMVH~yFEY2=;O9}iZI zW0I$Cln+IRx{&-w!-?)AswYpxPvdVEoNT?nc=*z8=h!e>!8r3NLlHZW06p~N<3ll@ zK;F?M#qd&5aYyTKScOQ=nY6At-+Bd%smjaBz5rtsEZw&${IHs7U?zx>W)eJod@z}o)|FNq8A^vpwZuc{l(STDl2 zR%exdVoxmY%k>J2D_YB=)$S`1K#cX3+Sv$<#tv0(x+g@Zhg4Kl(Bi>uD}Va*OTgJj zxLsMOx7vFDS#3KW=rXOP;WHA3%W}>AXwJ` zC60O)=1)zvQ@VWt*qczEAB*Ghcncs8h_;Mko}Tx;BYdFe)CKe(oDG;J?*=$87%qI} zQf&2r%UofRxS$Y~PDLpOwd|9vT(I`qz=QWI2c{21jZG1ZEEhMDpkriqq z(x04Uv9bK-V7U`!KnB!K7HFa_C7}tYX{|9}^b1>f{Y2^D!R*#zgFl%sel*8wh3jW) zS$_^#mMAvgwOOXls0faf^Ij&2F=%TGdxGrimGLo}>0tZkd(`9zSfn5mg7L#<*@-&S zrtD>`Fz)IiZo+oWSy+Q4(jxB3Et)@-#A*dLolaGB>$}yhbtiKw(2{G?`8vI=?W}y) zt|6*VE)hfY(-e^9%$=xbh8!J1v2_ZkO+fX~<`|fCr>?V`Hsv{-%vwFl=K?S4)*Jht zU;7n ztO;S(n~AHu-_K!O4+~J&cu&7ml%@n-m%6TN!Xo)CaD^xYohNC@QhzuJNlA(rl}ZW+ zOKptlFLA3?)1#H^uy_vpnPhE53oXBl-^T1T?IKZM{5=0<6E#^skVQ7f@C$`mn|vo- z+934o0awh?z+yem9m!@EH;2CjBXy5R%Nwu%ykE=eK)xw-fFDOj3fR*L0RG_@dBFYo zzqs|ps>KPT(@F&ac`G@HmTr}}dVOt$Wg}Jvt^%s|6tTjhgYb_FQg_;hTqY4Q#RE4P zgaDZI?XS1D$RU7NGE%@Ufb?SycSj|KAHBa}5jpWSsEjXuX^yS3FM1L^#=d@h!epp;}>G5d;=O%RnM>gqRD}3HD zDk_T5pl)^R`^KorGlOs15D^6aMB`2OK)tN0;u^Pd$JRL_fpC)1Ry991Iy$5Eb?t+V ztDJf8mU7rd`*durJPH1V+zY^!t!TQMg@Z9(UHBMo+NOC8r5q1j*FGEfs@0|Kq>)iC z6=s-uc(r(~6==l*kSFi7_IS8GtYNS}9!v(sO*cnQ0H;wR&JF*QyVStel2$)FJRC#< zjp}yg%I8WO50=sHefDSn%fa+N`|;nx7C2P2a-4bOq`x{q&OcK#ALpniHT@o!h(j;l!ek-wrujdms>qwIzmW3$W~u;kCbQf|mLfgPgWYX$OG7sY?(}Pqn1Vwyok8E?+FQwQh^& zYk+?2MO_fBOtl_#%GSEipKM_OC`fk86m09))iyq5ldVum$x><)tc7qgJar?yeQm}v zBUo`dA~xAya&1}N#;^sNLa}8hRv0$#lf+IXh<)2rH!Bi&5x2Puybz(p)&71*FEv*n zAs)fPB6%5mu;I_LlqHEm{bk2?@O_W- zTMO@mIVOq&x)hmbCyOK;i7JXkr|*i9&CE`xaEbztEON48P>i^Slg352oDfsrXMNJD zD0FjxlX!(uu-WCpuXIICT031K;y7u7=&qG`T3og=;tH2;In?py_b9B{651VG{p#98 z{nU-$kP1k4f3X&oyzbWS3H!Pf74$7E+k4l0+9=5S3&2LFI@T}W+_t*)_AmaFWb2lZ zb&x7%aKV^yz^vL8YYzjvm8PdavOFUP$UnQ0e%NRlOzVe8NWl~Y_{QXbpT}E~x*&7R z27swHDG>_>BRDoy0i<}E@b(_nIdPscS=mtL8FxQDdPSgw+Og-?I$p%{edR9IuPuRj zv_h`O$->P2ppPCj;Bnf!P3~ z*!ucYj87}KH?Hn|5U#6X8C|^e=Ra+^r#sBf&cYUlE0Q^2-$88Y8Q@}#$AX@!CxS8m zK#68kQ&a0e5ZLcE1QdvE*wT1yYjZG=$cb5}OJfPZa?d`dwzakSFO`;hxx44UUp6{2 z-BYkeDj1ifm@~jadAG)fWE+u_*4tuiY0tJq^K_g?O}b!WSnwpYuiya!Sn>I@i*0zk zv7)Q`YtL8k;rZ3s-r%{uLe-h8=XuT%Ppu}v$DU$<;IzOF70>p<8C(=ry`MVNd%@W` zgRk6ve*XM< Date: Sun, 10 Aug 2025 20:22:24 +0000 Subject: [PATCH 2/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- manim/scene/scene.py | 4 +++- tests/test_graphical_units/test_geometry.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/manim/scene/scene.py b/manim/scene/scene.py index f173e1f042..d3ddf9586e 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -885,7 +885,9 @@ def clear(self) -> Self: self.foreground_mobjects = [] return self - def recursively_unpack_animation_groups(self, *animations: Animation) -> list[Mobject]: + def recursively_unpack_animation_groups( + self, *animations: Animation + ) -> list[Mobject]: """ Unpacks animations Parameters diff --git a/tests/test_graphical_units/test_geometry.py b/tests/test_graphical_units/test_geometry.py index 4fac170e02..c74cbc457f 100644 --- a/tests/test_graphical_units/test_geometry.py +++ b/tests/test_graphical_units/test_geometry.py @@ -173,6 +173,7 @@ def test_ZIndex(scene): scene.play(ApplyMethod(circle.shift, UP)) scene.play(ApplyMethod(triangle.shift, 2 * UP)) + @frames_comparison(last_frame=False) def test_negative_z_index_AnimationGroup(scene): # https://github.com/ManimCommunity/manim/issues/3334 From c66bf557da050b71db8db6135fdee97e486cb87e Mon Sep 17 00:00:00 2001 From: Merzlikin-Matvey Date: Sun, 10 Aug 2025 23:26:25 +0300 Subject: [PATCH 3/7] Refactor animation unpacking logic for clarity --- manim/scene/scene.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manim/scene/scene.py b/manim/scene/scene.py index d3ddf9586e..e5ea4234ab 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -902,15 +902,15 @@ def recursively_unpack_animation_groups( # Imported inside the method to avoid cyclic import from ..animation.composition import AnimationGroup - mobjects = [] + unpacked_mobjects = [] for anim in animations: if isinstance(anim, AnimationGroup): for sub in anim.animations: unpacked = self.recursively_unpack_animation_groups(sub) - mobjects.extend(unpacked) + unpacked_mobjects.extend(unpacked) else: - mobjects.append(anim.mobject) - return mobjects + unpacked_mobjects.append(anim.mobject) + return unpacked_mobjects def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]: """ From c07c89ba154bb13855f1a9b1b6a46093e5cd0413 Mon Sep 17 00:00:00 2001 From: Merzlikin-Matvey Date: Sun, 10 Aug 2025 23:28:11 +0300 Subject: [PATCH 4/7] Fix unpacking logic to handle Mobject instances correctly --- manim/scene/scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manim/scene/scene.py b/manim/scene/scene.py index e5ea4234ab..598e33c658 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -908,7 +908,7 @@ def recursively_unpack_animation_groups( for sub in anim.animations: unpacked = self.recursively_unpack_animation_groups(sub) unpacked_mobjects.extend(unpacked) - else: + elif isinstance(anim, Mobject): unpacked_mobjects.append(anim.mobject) return unpacked_mobjects From 709f51cd029a89a235668148e6ac8c4f7af2bf21 Mon Sep 17 00:00:00 2001 From: Merzlikin-Matvey Date: Sun, 10 Aug 2025 23:48:24 +0300 Subject: [PATCH 5/7] Fix mypy check --- manim/scene/scene.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manim/scene/scene.py b/manim/scene/scene.py index 598e33c658..7a2910c856 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -887,7 +887,7 @@ def clear(self) -> Self: def recursively_unpack_animation_groups( self, *animations: Animation - ) -> list[Mobject]: + ) -> list[Mobject | OpenGLMobject]: """ Unpacks animations Parameters @@ -908,7 +908,7 @@ def recursively_unpack_animation_groups( for sub in anim.animations: unpacked = self.recursively_unpack_animation_groups(sub) unpacked_mobjects.extend(unpacked) - elif isinstance(anim, Mobject): + else: unpacked_mobjects.append(anim.mobject) return unpacked_mobjects From f97131f16bbce80b4269adec756ed9c6baf03e91 Mon Sep 17 00:00:00 2001 From: Merzlikin-Matvey Date: Mon, 11 Aug 2025 00:03:15 +0300 Subject: [PATCH 6/7] Fix tests --- .../geometry/negative_z_index_LaggedStart.npz | Bin 13083 -> 4490 bytes ...animation_groups_with_negative_z_index.npz | Bin 0 -> 3153 bytes tests/test_graphical_units/test_geometry.py | 10 +++++++--- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 tests/test_graphical_units/control_data/geometry/nested_animation_groups_with_negative_z_index.npz diff --git a/tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz b/tests/test_graphical_units/control_data/geometry/negative_z_index_LaggedStart.npz index 7158d6fc84add4c9857532add46775efe4ec9572..dd5e8344d97466a8070f184a7d7057fb2e709367 100644 GIT binary patch literal 4490 zcmWIWW@gc4U|`??Vnv3{d*j{zLjfOy2t!&?Vs2`DN@7W(US2^ZBZB|~L$4iBB?H3` zAQJ@MUNy{~?8w0OK*cSi+f`tt%0g8=H^XL6=__^JQUw#V^!WUQe2zHgcxH)-mYmRk z@!-5|vHincci6wn*sz!1{;l`^>Tdr0`}H|y*LvqS|4jN?X=(A6zwWODZ`3;_qZvtimM`CCqJJUe@LF~g-BT2wTA)F{eAVBPAyyT!}i-O+VBGa5OR1ts-$ zugm`bqV7f5`YyrG&)&&2m~7*sz8#|`f;ml6wbjcKH{BCaes=b*B|~P8=tvGun)?09?e24q zKaA^Q$SuMGw#Aw9PX4+~!Z82cIYy7<)iibPNH%=Iy?Zichpv7OG$gyas=8|8b8Yr$ z2}tW?)KFz@{i?10YT;;9AqRCs)i3@4Z$>6v2Go%g@R$g2e1s24aRaz5hB}TC;LXYg PQo;y?HbB}!5X1uj#f$Ym literal 13083 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 RRyL3lMj*5S(*MC-0su?lp?UxS literal 0 HcmV?d00001 diff --git a/tests/test_graphical_units/test_geometry.py b/tests/test_graphical_units/test_geometry.py index c74cbc457f..1bc66ba897 100644 --- a/tests/test_graphical_units/test_geometry.py +++ b/tests/test_graphical_units/test_geometry.py @@ -184,10 +184,14 @@ def test_negative_z_index_AnimationGroup(scene): @frames_comparison(last_frame=False) def test_negative_z_index_LaggedStart(scene): # https://github.com/ManimCommunity/manim/issues/3914 - text = Text("Some text", font_size=30) - line = Line(2 * LEFT, 2 * RIGHT, color=RED_D, z_index=-1) - scene.play(LaggedStart(FadeIn(text), FadeIn(line), lag_ratio=0.5)) + line_1 = Line(LEFT, RIGHT, color=BLUE) + line_2 = Line(UP + LEFT, UP + RIGHT, color=RED).set_z_index(-1) + scene.play(LaggedStart(FadeIn(line_1), FadeIn(line_2), lag_ratio=0.5)) +@frames_comparison(last_frame=False) +def test_nested_animation_groups_with_negative_z_index(scene): + line = Line(LEFT, RIGHT, color=BLUE).set_z_index(-1) + scene.play(AnimationGroup(AnimationGroup(AnimationGroup(FadeIn(line))))) @frames_comparison def test_Angle(scene): From fa52f04cf890433dcd54a2993f39a685ccbecb06 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Aug 2025 21:03:59 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_graphical_units/test_geometry.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_graphical_units/test_geometry.py b/tests/test_graphical_units/test_geometry.py index 1bc66ba897..9f9b6eda59 100644 --- a/tests/test_graphical_units/test_geometry.py +++ b/tests/test_graphical_units/test_geometry.py @@ -188,11 +188,13 @@ def test_negative_z_index_LaggedStart(scene): line_2 = Line(UP + LEFT, UP + RIGHT, color=RED).set_z_index(-1) scene.play(LaggedStart(FadeIn(line_1), FadeIn(line_2), lag_ratio=0.5)) + @frames_comparison(last_frame=False) def test_nested_animation_groups_with_negative_z_index(scene): line = Line(LEFT, RIGHT, color=BLUE).set_z_index(-1) scene.play(AnimationGroup(AnimationGroup(AnimationGroup(FadeIn(line))))) + @frames_comparison def test_Angle(scene): l1 = Line(ORIGIN, RIGHT)