From 1cd9715e882a60215473f298ba4cbe95f3a8f4f1 Mon Sep 17 00:00:00 2001 From: debloip-adsk <145056365+debloip-adsk@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:05:53 -0500 Subject: [PATCH] HYDRA-747 : Filtering scene index example can have prims get unfiltered at the wrong location (#42) * HYDRA-747 : Working fix * HYDRA-747 : Cleanup, add comments and handle GetChildPrimPaths * HYDRA-747 : Implement ctor and use cached filtering state instead of doing full check * HYDRA-747 : Filter out child prim paths * HYDRA-747 : Simplify code as _GetInputSceneIndex is always valid * HYDRA-787 : Add unit test for renderer switching * HYDRA-747 : Add comment on child paths --- .../samples/fvpFilteringSceneIndexExample.cpp | 120 ++++++++++++++++-- .../samples/fvpFilteringSceneIndexExample.h | 33 ++--- ...dThenBackToStorm_MovedSphereUnFiltered.png | Bin 0 -> 8628 bytes .../render/mayaToHydra/testFlowViewportAPI.py | 8 ++ 4 files changed, 131 insertions(+), 30 deletions(-) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/FlowViewportAPITest/filter_VP2AndThenBackToStorm_MovedSphereUnFiltered.png diff --git a/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.cpp b/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.cpp index ef8cced189..68b384cd96 100644 --- a/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.cpp +++ b/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.cpp @@ -22,12 +22,14 @@ #include #include +#include + PXR_NAMESPACE_OPEN_SCOPE namespace { //As an example, we use a filtering scene index to filter mesh primitives which have more than 10 000 vertices. - bool IsFiltered(const HdSceneIndexPrim& sceneIndexPrim) + bool ShouldBeFiltered(const HdSceneIndexPrim& sceneIndexPrim) { static bool _hideCameras = false; static bool _hideSimpleLights = false; @@ -64,20 +66,120 @@ namespace } namespace FVP_NS_DEF { +bool FilteringSceneIndexExample::IsFiltered(const SdfPath& primPath) const +{ + return _filteredPrims.find(primPath) != _filteredPrims.end(); +} + +void FilteringSceneIndexExample::UpdateFilteringStatus(const SdfPath& primPath) +{ + if (ShouldBeFiltered(_GetInputSceneIndex()->GetPrim(primPath))) { + _filteredPrims.insert(primPath); + } else { + _filteredPrims.erase(primPath); + } +} + +FilteringSceneIndexExample::FilteringSceneIndexExample(const HdSceneIndexBaseRefPtr& inputSceneIndex) + : ParentClass(inputSceneIndex) +{ + std::stack primPathsToTraverse({ SdfPath::AbsoluteRootPath() }); + while (!primPathsToTraverse.empty()) { + SdfPath currPrimPath = primPathsToTraverse.top(); + primPathsToTraverse.pop(); + UpdateFilteringStatus(currPrimPath); + for (const auto& childPath : inputSceneIndex->GetChildPrimPaths(currPrimPath)) { + primPathsToTraverse.push(childPath); + } + } +} -//This is the function where we filter prims HdSceneIndexPrim FilteringSceneIndexExample::GetPrim(const SdfPath& primPath) const { - if (_GetInputSceneIndex()){ - const HdSceneIndexPrim prim = _GetInputSceneIndex()->GetPrim(primPath); - - const bool isThisPrimFiltered = IsFiltered(prim); - if ( ! isThisPrimFiltered){ - return prim;//return only non filtered prims + return IsFiltered(primPath) ? HdSceneIndexPrim() : _GetInputSceneIndex()->GetPrim(primPath); +} + +SdfPathVector FilteringSceneIndexExample::GetChildPrimPaths(const SdfPath& primPath) const { + // A filtered prim should not exist from the point of view of downstream scene indices, + // so return an empty vector if the current prim is filtered. This case should normally + // not be reached during scene index hierarchy traversal, as its parent should not even + // return it when GetChildPrimPaths is called on it (see other comment in this method.) + if (IsFiltered(primPath)) { + return SdfPathVector(); + } + + // If the current prim is not filtered, we still do not want to return a path + // to a filtered child prim, as a filtered prim should not exist at all (and + // we might have sent a PrimsRemoved notification prior). Thus, remove all + // child paths to filtered prims before returning. + SdfPathVector childPaths = _GetInputSceneIndex()->GetChildPrimPaths(primPath); + childPaths.erase( + std::remove_if( + childPaths.begin(), + childPaths.end(), + [this](const SdfPath& childPath) -> bool { return IsFiltered(childPath); }), + childPaths.end()); + return childPaths; +} + +void FilteringSceneIndexExample::_PrimsAdded( + const HdSceneIndexBase& sender, + const HdSceneIndexObserver::AddedPrimEntries& entries) +{ + HdSceneIndexObserver::AddedPrimEntries unfilteredEntries; + for (const auto& entry : entries) { + // We only want to forward the notifications for prims that don't get filtered out + UpdateFilteringStatus(entry.primPath); + if (!IsFiltered(entry.primPath)) { + unfilteredEntries.push_back(entry); } } + _SendPrimsAdded(unfilteredEntries); +} - return HdSceneIndexPrim(); +void FilteringSceneIndexExample::_PrimsRemoved( + const HdSceneIndexBase& sender, + const HdSceneIndexObserver::RemovedPrimEntries& entries) +{ + for (const auto& entry : entries) { + // We don't need to update or check the filtering status, since the prim is getting removed either way + _filteredPrims.erase(entry.primPath); + } + _SendPrimsRemoved(entries); +} + +void FilteringSceneIndexExample::_PrimsDirtied( + const HdSceneIndexBase& sender, + const HdSceneIndexObserver::DirtiedPrimEntries& entries) +{ + // There are three potential scenarios here for a given prim : + // 1. Its filtering status did NOT change -> forward the PrimsDirtied notification as-is + // 2. Its filtering status DID change : + // 2a. If the prim was previously filtered -> it is now unfiltered, so send a PrimsAdded notification + // 2b. If the prim was previously unfiltered -> it is now filtered, so send a PrimsRemoved notification + HdSceneIndexObserver::AddedPrimEntries newlyUnfilteredEntries; + HdSceneIndexObserver::RemovedPrimEntries newlyFilteredEntries; + HdSceneIndexObserver::DirtiedPrimEntries dirtiedEntries; + for (const auto& entry : entries) { + bool wasPreviouslyFiltered = IsFiltered(entry.primPath); + UpdateFilteringStatus(entry.primPath); + if (wasPreviouslyFiltered == IsFiltered(entry.primPath)) { + // Filtering status did not change, forward notification as-is + dirtiedEntries.push_back(entry); + } + else { + // Filtering status changed, send a different notification instead + if (wasPreviouslyFiltered) { + newlyUnfilteredEntries.emplace_back( + entry.primPath, _GetInputSceneIndex()->GetPrim(entry.primPath).primType); + } else { + newlyFilteredEntries.emplace_back(entry.primPath); + } + } + } + _SendPrimsAdded(newlyUnfilteredEntries); + _SendPrimsRemoved(newlyFilteredEntries); + _SendPrimsDirtied(dirtiedEntries); } }//end of namespace FVP_NS_DEF diff --git a/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.h b/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.h index e5c34292c7..32b3e2df46 100644 --- a/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.h +++ b/lib/flowViewport/API/samples/fvpFilteringSceneIndexExample.h @@ -46,41 +46,32 @@ class FilteringSceneIndexExample : public HdSingleInputFilteringSceneIndexBase } // From HdSceneIndexBase - HdSceneIndexPrim GetPrim(const SdfPath& primPath) const override;//Is the useful function where we do filtering + HdSceneIndexPrim GetPrim(const SdfPath& primPath) const override; - SdfPathVector GetChildPrimPaths(const SdfPath& primPath) const override{//We leave this function with no filtering for simplicity - if (_GetInputSceneIndex()){ - return _GetInputSceneIndex()->GetChildPrimPaths(primPath); - } - - return {}; - } + SdfPathVector GetChildPrimPaths(const SdfPath& primPath) const override; ~FilteringSceneIndexExample() override = default; protected: - FilteringSceneIndexExample(const HdSceneIndexBaseRefPtr& inputSceneIndex) : ParentClass(inputSceneIndex) {} + FilteringSceneIndexExample(const HdSceneIndexBaseRefPtr& inputSceneIndex); void _PrimsAdded( const HdSceneIndexBase& sender, - const HdSceneIndexObserver::AddedPrimEntries& entries) override final - { - _SendPrimsAdded(entries); - } + const HdSceneIndexObserver::AddedPrimEntries& entries) override; void _PrimsRemoved( const HdSceneIndexBase& sender, - const HdSceneIndexObserver::RemovedPrimEntries& entries) override - { - _SendPrimsRemoved(entries); - } + const HdSceneIndexObserver::RemovedPrimEntries& entries) override; void _PrimsDirtied( const HdSceneIndexBase& sender, - const HdSceneIndexObserver::DirtiedPrimEntries& entries) override - { - _SendPrimsDirtied(entries); - } + const HdSceneIndexObserver::DirtiedPrimEntries& entries) override; + + bool IsFiltered(const SdfPath& primPath) const; + + void UpdateFilteringStatus(const SdfPath& primPath); + + SdfPathSet _filteredPrims; }; }//end of namespace FVP_NS_DEF diff --git a/test/lib/mayaUsd/render/mayaToHydra/FlowViewportAPITest/filter_VP2AndThenBackToStorm_MovedSphereUnFiltered.png b/test/lib/mayaUsd/render/mayaToHydra/FlowViewportAPITest/filter_VP2AndThenBackToStorm_MovedSphereUnFiltered.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d9f5b34ba617e15991e9fc6e393c9e3d2e7bc4 GIT binary patch literal 8628 zcmeHt`6JZd_y35us6?a95`#fP${;Z`F*IY#z7$E;K}q&4Br%n3EM<>|GPdkXmR_Y9 zJ6S_WV_&mQ_U|39_v`b1e}DLX{(|ohv)p^ndE9f)J?A{{J?Dwn)w#iTg!>2t0%5~q z(E1PvLp1%v!VG$X>g8I&&v9E*tev*@1@ITbLjQt55~eE5zz?g7y1Lsz2mNdCLU}s` z0)t@D*A2Z>7KS@qcqqdZSA`S5QJ0sH-NYH+mSf247oG*MbR(Pg0b=2Q1R zx+`#HtxwZ`KI>m-6Nlu|nJjIUs%z9ka(DHNZ}Z$_g5!37i@VJ)J9v6|R(@Qy9xV*| zLpZ5caLmSDIVCX_acyUe{V=5SjGxQ=!ZYP(=EyT!5Xc*+Shra1*`4)ctW2o%XjGEw zA%;$#48Qp*BPdJINHpi@p7{3dj3}Wqa1KZqGp3)N-!{p?{(j{e~|A)$MQL$lGOftwmWy(Fslc2bg+#dbTBCZ z=0gWNQB6s^O`rN-&;z34Gu7|XoIpooTFP%z#x5jXT$W+$j(h?NViP3`TY!NvzU`oB z6y(!U#D~G_|2@@w42s?nEjuF_wwN<@3k!o3i-;=r1(k*{9fJ8~_{~-s1Hil@W}*_9 z-OQSw1IhyNwqiE+0|NeMZf@3t@qr`5svWiTi8XcH^B8dKK=KV0T8~>kU>>-~hWSY6 z`l<{A&EKDo<$1;cQgL^7C7K2hLXwM7kH&Qr#|OB|`xXlp-Vc%UBjz4`^rx*v`tT_8 zMvjZr3(2~7D8~cxAn2@3PI7jl)8MYbwW#5|ziPy2Q)Z$ioj(K^P>&P%FGgKR8`AS? zC9BKIbTu|&Z>OIUS^B1ynq7E*Q>*vxG^IfFNIFe47=nV7+Xzi!ulN>ol#@G<&wQXP zY%CBs%H<(3Cgz!nkxv1s=!0H&3eZi^tw{^f)t%m4lVpX{5R{7XQsLg8P^mkWl49z@ ziG{=agHc&J>HG7m`&&B%e@Rb2@9i7*_43<^aCW*@AUdtCJa$$Lkd)U{2^kpVC$47C zJ!|_nDtXskHxQ+$2KscZilqmT<~|Cwp8mEqwf-(XGF6ubN_%UM`hC=&DC>S^E3-SS zol_+%{W2I5M0S=KA0OSY*Pz}*>SShEojx5jLLmQIvfSU^#|Q~j)VeH1M0W65R_~5h z1iITjw1chB@2Bo+5!8~6_K`V+hvV|ZX4l=th0)zY-le^*y^SgRYxTrPudN;~ABihI z=>_|{bW0RK7qk4Og(v|QB17NGn3?RrKqdcT7QJ;iHQB+uo9;HAX=YZn4m%Hver_r& zrVZQCCW>hn>&cJ7mJ7~M69dGvMH`x)7)NEVx8Q0K`Rt{X8-sK09kZbW+vCO^Jp0Ej zm3L`++nJSgi*2qkd0nQV^z|(3+n3HCCLUR-a~TMNejTdf?-|xfQ%wo>Qofor8^b48 z`Q@!7QgqH51-h6~1&)eNcv25v;aezNa-mz7+Q#*$N3T9*p0wUJvyg?Vp9{|gt(@D@NXGlF!6E+e{ zcMCSVyB;s-7#V)!0l9ST!-C!E9Y?#wj}Hqi(W61*lawCd{E`4$f;UaE=5+OqkqSEV zzxsmQqv*8X78wbybjm}B57jroNJOX7N*z78NkpR#I%+zVmh0%=KHkI{AqyK83Wi|P z@)%;c|G`4`1wEw)3*-ia0I8U*(}M{?L=^FFE}4IG zfhLHp(f>372)+3~AVdHH&@sl-eBPttKo!N~Xfk*7Ltur3e*y=0^oRd$9?Lsuo~k}P zau7!(pcqr2CM@C3!+$^s<8T0SK-QoP8>8bAOc|l{NJIF3814@ggMlJGe5S9t>-X5h zlmB4Jcu2=y_aLLIL4=Mjod|0Ys>&a>7#gT7bKPATZc%&``!w?o=l_J@G<`b{#Q5^~ z6QFWGUyYb#4Y8Gy9*VvS-!(8*VMISgGTDyQ$HM+yx<=f`x#nWXs%b~71k;%gy}6P` zj5yVCnFEpP9;e^af1mWNGt``&u2ChN{Km-eP&`o}f-?R&Pt>B~PLeP*UUwv^w|8Kb zjrQBtUp2tU)(LqM%EHlTBRx-XX+);*f=ggxW)o4_wV%Oat)gDfBA?(WEcV}(}ZcV?9QXbqL8r>`3 z?XTZkAK&N*+;i)$*`2f8SEy?02;3eTU2I-z1o5W7ek7izfV8>gaLgv}SI>9yCm~#` zL0eJWi(B_{xHZiJcD8D1**IK6(zsX8(y6^+IL8~ME(fjHuVwW+6H-Gfrde!NVq3e? z7b2#Oh69(sp1Dz2yD@lthIsq0u4ht+REhQnr=A^-I&(v3u5BV@LT`F5I0hA6w(MQA zPPw+{s;M7B44X>xd+>W_wS%45tj*1~TeoLgKf@NeFg2?roYiQLl@^FE)#Q#KljW)l zCQX}#D@F|hr$#Dho<<5+H?OiXIkfNX?e&EmW|y0Q7o_hPHDAirk5@75y2PK1Ll58a zoym$tOYkgg%wQ$Ze72<8YkVgDw%(JN zI}d3l^;^A*fBp5B-E?3wFYiUISn{iGzTa!(KKfDb*8Sm4nJvD&7k#2p(dV$|q{&uk zouQHeuW2o5oOWB6(n})n@3;3iI|6kcjQ$~CDVMT*jC{xcSfifSPl0Yl>#h~WLBywk z08iF_XDy%SE;+Ap{PRXiM9Wfw@JTMw80$Feg>imi>rf?XC{8I!I93@Rr&&_(GByx+ z_}f?6VhjwEeYGHg>m0$bO626aVx{*-L^N(uSn<*&w$@uVfC41GIOm2Vo; zlX00|?;b3_ZDB8e@{*MzA0n}_k_FokvBjNTwzOfbb^bX1twiwjng^o8U#C~L?g%|_ zV`Dh;9g*gTDe(oI;nglY>?eGW=wZi!Mnteg^mKfGs>n%7gH;#hTATs?OPFvL*r{Vx zyiMtQYob$R)u|-Z+ElKceU*%^t@XvpKjH8gKicB`t(~DY?GNkh7Vwi%4SI2?9>-nv z0@iYQd5;JwC<_5rl0Uuzo3zC=b4QU13*EKbK6fqkCnjd;hkGy8(sl&(*qLs^j7}dV z9qnka(q|>c^ymdMJ%Kl_=NVG<H`%w2v>DI|o;h)9zSwu5{H*P7>U zu}(Prc2>FiK+1KxNwuEab;ue#?9n%~=T1vP^SD3sISm91Q3Wr~sMcG`@w8|OI7T!& z71oklC0@b650E$KMWINQbY>w zPchE2&e$Hlc~)B_F1x@s%T8Oe{FMwasjiWckplDRha+p>438v=2E4yjreRV4;I!Cy zPG5fzQ3UntQVfbi63f5;hjLA>#ZFqRfc4(UN$Hzg=eNy=+z2Y;bBgb-EHIccLXp=S zbQwjC1Dy%XsB&{~Ax$h7fNl8mF!VQA`4udhvWShFHAMx=*t&AGoeIOk!U=g{@(K!r zJyI`C8{SR1D4WQU^?P+Ud0))AY8=@dkG+WzKc{P(p!(65w%q=f;X4U58k~9R3#Ku#-Myei%uMi*BI*KEL&Hx^;VLH0#O|0plDIl3(=D$7S{EtNys%`JX@E zcp-|26+G4Nv;p{|j|P(?{AyHaIi;Z27TK_Kq0NI0(>-^6O?*}3kPkKDif@IWg^qC^ z!-2dxvqc}*rsw?C2l~}7;)yfVPq=wTs0&?60;*?^-_{8+$;Eit$tY9LS?qeCa~-*? zIx-lu;B?4pN9Yc4R!ScaEwRbaq6v!(2_k5?1!Mm(o*&Euf7^#D~_Y+%!&G%j5yRkH@o3WKAyw z`>*$!ge(Q_Z`W3HO92T1u%S)#_pE*k8IJq8lWyg%p_x;p$9LS39z0QkTlQ>WU-ZU~ zBEZ#~zQ+uKf4=aSlc~$)^Q`)%#~Wx0rq7qYhvi5FOh_%nItr_iSRgJbT@o$T8+_rwSKHEE@HEN_n`;Y_YfKQ5E+iVh2 zqT8gN{jr7`7r%KDo=HDJWzFes({5cvU?cW9m#M2zFigRvZga9c<&s)2q{LU-tZdke zYxUvgd@(Iop`7##{a$^1;*}-e=KhOpaN$nYICTBqIAcO7|{D+b{YwFPZy z9v%eDw|*U4S_@fujk2Z2BOHLK^<21B*cZqG#q0owjr8xgj7P!Mm$qG52L_;e@P8gVNomWU8Q7_ehCWxP;6)khLu)n(D z$#Miz*al>AlgBs}pz5Q!?&upOVVE>Io zL&Hf^ZQI~@L6ttO?_S^jI?NGmGjTP7f`i9;gA9va?8%iT(e#v;p^bSG>A9;3!%}_) zTHj1=O$L;ZwlB_5hrLFH1LV02qbhWuP0MS4xlX^Gp+k#^q4SS^qcHoE)tzetzfLLL zU$Py!lG_roHm1WJS?fjfq?nM0LcZcUyzdVp>g01@jQLG_iU|y$+@TPuOeS=%u;28le zFs~|pdvRurfJUdne_Mb96 zv1#;fr0@sU#Gf;l|?!5iS*d`l;tf=BSo1E=((kd4_?%sR| z`K>7x|HWvi$tFpGSX5ly-DO`6L>_O<)+koFy;M6VYV+#k&t#bY=-cxin54{Q`2{jr z#x=!B-nFu?oX}J{_PR#a@7mB5U)ar)aE`TS@R*R0kk5%`D)ohYb4FJ>dcE6#>nN`k z4g=k(P_3e4yJHhEF9s!v*7;lT*y5fHUY|NI6mUCDLU>A0)|tYN&PP~bZ6e2z-@xKf zq-NwRpxoHB#m}WWH}hf-m-s591i6rWx!we=1V=dM{k*p;ZWtJfwmAH;LJUWAX7~8k zV2UwXxs+S&a(v?^&vEXkLmlvFK`}VztDX!^XZrOi8fk_Qz}eW^+S+Iesv*jqoiv*5 zumg9TGEu`V=ZQan~yf+8zc&<*Buhx`|mFXfvE1>^gSF7%~|mtf$PicS!wdAKq+}$4|_WQ zIL@1rHMI!xkt+NR{uo$e0yj@g@(&Z-b^h4*8lq}VpZ(bbJZfZkFSvGk|G|~M%Of<5dVIAvLm1{RBh1VS@*F#k!fpT3(;6KMbQ}pn?9u!|2{coXTk@E zB=z|>et%x$DF=H@kiqb@In^Gnz56mTWeJw}-prb{fCkbHvePq9HFLe*l`!cO^OvC= zJp!+MOPEcm8<5%yV(>!fwEyY)oH!i*8xKA51`I0O;r#bFe z`(iBiFu0$)XAZM}5lw8p+IMhfoHN3&$1gEZ3_!9Wle601;Vt+Nd02;E4E%eXApDQs)=xkwVgBtjMJek|YyL z|16=vVCYZ8hkFl;vS{~luhc-!#Q_~7p<-C(f=M=EGd5v;a48We3Y}5G+Td05meoy! z6VRNOUtlB{Snwi;2QKxd;!PH+V_Or3<3I24D1}vyXFA+r_x4U&oh&{ zSOE6*Sl*|#B0|#NQ~p$1Rqm$-)0({i%Nqkl$+ab~%MUhCm;QLTI9gkS@R#Qe zUDPuGL{MQ-k;FbtK`bL6kfG;=;W5rX1}iV-pq2O!9^ep6qjx}!N97}L>HBLV&dmengy^?F+B54I6PR&S?swk@7CHIw5)-% zSP8t1hbQkNf6577dcs_19PUm)p1!>mq?WxTo%irO^zW- z%V5Hn3vNQ#BVaXVu7igGx!|O>uv(L9lQ%saL6{5%y6+=mjxq0*RM==u+{3PbrJ@vd z?C#e7s@f1*lgAp(>Pp|)2S;)U6Sa4>cVqmqbW6?*dd2v<;J1FSxY~}-@VRwW2Wol!}{;Fh0Y0YFW4k`4Y|8n59iGhzi2U7c0!ey#WOM6Y&1 zb>R3Q!0Hsy{%J+lMR3Mv1>7(o3TLXP=2I~?39ppPp<7E}HPf+wmu-%3r+GCA$FwFY zJYx?N%K5gt;6@)cpH6eL67;#G37_;OFdHZE7w|oZER3j797-pKfTU_?PP_fxO?^BO zuY`VHke<~S30Fv?udb?7$^IRwFShk#agB35N7*&3gkKeKfd+|0rY@#_aoUB94Obfa zZ^|hhQp;lj?S-3wGg|TLGLt1^SLh42I+KPRu>Lo08Gh~gMr8(8xBaSa$oYYM?;C_( z0Ryh<*PC5&h8uC1f3NJvt^0oLUWk}H;J0h&Lc6>8i%>jEoW{X0Qfxd9Lu5{>rPr4d zM}#?&tDRK+-T!9hM4o8S?Uk(<9Q+dSMwn1xhbKl1+%5#Kz8Hd$y0!@d>-!(b)}Ym{Ow+`o7>ZDg1uDocO`b4{hj2u0NIi zoE8RXz?-I-5FaKvR4){nkN&-mwciGL8U3+&gO)deV60cU&VigYSsue!tp%T5)w)5K z!R&D*^47WMI;Kx7DyR~0tJ_HlYvImhl*A!zps23gISVLWj@nF5 z*!yn1%IB)2ZDVQd{NxG9$NR`SPlNfBWf-<`Jt2R*SLZ>b7KCC?|eY$rwB z_)X-%(lhuv22{>2@9$|Yipxa0gDYyATj#!C=8z6r+OE4wPwD6NrWOfXhF}>DH@L~y z_&`>>@m6Z?-g6T9?L2MU7_7%P>wHWloPB-!Wgrp+s!s88w4gaRyRdu5wFJ6}J3W$? zc{h__wL=vHcz1HUz0YU(?Oit9YzEZ?h-@^9FP0gYDJ1gV^d?2$wiU!@NaX9__16c5 z703%u`GOSDx-X>O=?9>ygdarzdQi9&T_EbM+wC?m2)KESdj6(5MQXrQC zLFS;l$ja~{qfMSRSp-0;>M%}u1Zco_L39etH3fX>? z2B!b!UmhC*_%agQR>uDs>?Y&{-ii%h)%8Q2o83bX3rNu@OI2u#h8qtK2{1Ww3Me;7cIGo{ z=eX#ci3NpQPPcIntoJ}20V3FMC+NyW({0`TNgu2#hvMfd=|L~3K{f_6`_k`yhYT%* zUT?gYgn@f-vuAYFfr1uFWVS#c=N3ST1UD>DcPwaEhF=tK(^gvoRhppIlfncAM1gzx zngEa>nrle5e73!^_%dhXs!8FU)TvzvKqH? z=Sj1<47nr)#O_U{cP88%kf3;(li(WW(tHo?<4><{uB5;@azNQKNS`EdnUfV1PCwxj zF{f4dIUq1e>7$wtT0b9xcxNyG=>O&G36Wh9yhk8He;43?r~Ln;n}KF7o66na%Gtq7 T6#ws+Eg)Dm9dv=p-6#JCzCwOA literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/testFlowViewportAPI.py b/test/lib/mayaUsd/render/mayaToHydra/testFlowViewportAPI.py index 83994b7450..f0a38ac2b9 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/testFlowViewportAPI.py +++ b/test/lib/mayaUsd/render/mayaToHydra/testFlowViewportAPI.py @@ -186,6 +186,14 @@ def test_FilteringPrimitives(self): self.setHdStormRenderer() self.assertSnapshotClose("filter_VP2AndThenBackToStorm.png", self.IMAGE_DIFF_FAIL_THRESHOLD, self.IMAGE_DIFF_FAIL_PERCENT) + #Test unfiltering the sphere after switching renderers (HYDRA-747) + self.setViewport2Renderer() + cmds.xform(sphereNode, translation=[0,5,0], scale=[4,4,4]) + self.setHdStormRenderer() + cmds.setAttr(sphereShape + '.subdivisionsAxis', 30) #Unfilter the prim + cmds.refresh() + self.assertSnapshotClose("filter_VP2AndThenBackToStorm_MovedSphereUnFiltered.png", self.IMAGE_DIFF_FAIL_THRESHOLD, self.IMAGE_DIFF_FAIL_PERCENT) + #Finish by a File New command cmds.file(new=True, force=True)