From d390360f9e78357739aef324e7d3b423cd7fcced Mon Sep 17 00:00:00 2001 From: jingyuc Date: Wed, 14 Jul 2021 20:01:50 -0400 Subject: [PATCH] clean up kinematic test setup --- examples/ReducedDeformableDemo/BasicTest.cpp | 102 ++++++++++-------- examples/SoftDemo/K_r_diag_mat.bin | Bin 100 -> 676 bytes examples/SoftDemo/M_r_diag_mat.bin | Bin 100 -> 676 bytes examples/SoftDemo/eigenvalues.bin | Bin 100 -> 676 bytes examples/SoftDemo/modes.bin | Bin 8068 -> 56452 bytes .../btDeformableBackwardEulerObjective.cpp | 9 +- .../btDeformableMultiBodyDynamicsWorld.cpp | 4 +- src/BulletSoftBody/btSoftBody.h | 2 +- src/BulletSoftBody/btSoftBodyHelpers.cpp | 39 +++++-- src/BulletSoftBody/btSoftBodyHelpers.h | 4 +- 10 files changed, 96 insertions(+), 64 deletions(-) diff --git a/examples/ReducedDeformableDemo/BasicTest.cpp b/examples/ReducedDeformableDemo/BasicTest.cpp index 3072cebd4..db2469380 100644 --- a/examples/ReducedDeformableDemo/BasicTest.cpp +++ b/examples/ReducedDeformableDemo/BasicTest.cpp @@ -42,45 +42,53 @@ class BasicTest : public CommonDeformableBodyBase // btDeformableLinearElasticityForce* m_linearElasticity; btDeformableMassSpringForce* m_massSpring; - unsigned int m_nReduced; + static const unsigned int m_startMode = 6; // actual mode# should +1 + static const unsigned int m_nReduced = 1; + static const unsigned int selected_mode = 0; unsigned int m_nFull; + btScalar sim_time; bool first_step; - btScalar sim_time = 0; // compute reduced degree of freedoms - void mapToReducedDofs(const btAlignedObjectArray >& modes, - const btAlignedObjectArray& full_mass, - const tNodeArray& full_nodes, - btAlignedObjectArray& reduced_dof, - btAlignedObjectArray& reduced_vel) + void mapToReducedDofs(btSoftBody* psb) { - btAssert(reduced_dof.size() == m_nReduced); - for (int j = 0; j < 1; ++j) - for (int i = 0; i < m_nFull; ++i) - for (int k = 0; k < 3; ++k) - { - int idx_f = 3 * i + k; - reduced_dof[j] = modes[j][idx_f] * full_mass[idx_f] * full_nodes[i].m_x[k]; - reduced_vel[j] = modes[j][idx_f] * full_mass[idx_f] * full_nodes[i].m_v[k]; - } + btAssert(psb->m_reducedDofs.size() == m_nReduced); + for (int j = 0; j < m_nReduced; ++j) { + if (j == selected_mode) + psb->m_reducedDofs[j] = sin(psb->m_eigenvalues[j] * sim_time); + else + psb->m_reducedDofs[j] = 0; + } + // for (int j = 0; j < m_nReduced; ++j) + // { + // // if (j != selected_mode) + // // continue; + // for (int i = 0; i < m_nFull; ++i) + // for (int k = 0; k < 3; ++k) + // { + // int idx_f = 3 * i + k; + // psb->m_reducedNodes[j] = psb->m_modes[j][idx_f] * (psb->m_nodes[i].m_x[k] - psb->m_x0[idx_f]); + // psb->m_reducedVelocity[j] = psb->m_modes[j][idx_f] * psb->m_nodes[i].m_v[k]; + // } + // } } // compute full degree of freedoms - void mapToFullDofs(const btAlignedObjectArray& m_x0, - const btAlignedObjectArray >& modes, - const btAlignedObjectArray& reduced_dof, - const btAlignedObjectArray& reduced_vel, - tNodeArray& full_nodes) + void mapToFullDofs(btSoftBody* psb) { - btAssert(full_nodes.size() == m_nFull); - for (int j = 0; j < 1; ++j) + btAssert(psb->m_nodes.size() == m_nFull); + for (int j = 0; j < m_nReduced; ++j) + { + // if (j != selected_mode) + // continue; for (int i = 0; i < m_nFull; ++i) for (int k = 0; k < 3; ++k) { int idx_f = 3 * i + k; - full_nodes[i].m_x[k] = m_x0[idx_f] + modes[j][idx_f] * reduced_dof[j]; - full_nodes[i].m_v[k] = m_x0[idx_f] + modes[j][idx_f] * reduced_vel[j]; + psb->m_nodes[i].m_x[k] = psb->m_x0[idx_f] + psb->m_modes[j][idx_f] * psb->m_reducedDofs[j]; + psb->m_nodes[i].m_v[k] = psb->m_modes[j][idx_f] * psb->m_reducedVelocity[j]; } + } } // get deformed shape @@ -97,8 +105,8 @@ public: { // m_linearElasticity = 0; m_massSpring = nullptr; - m_nReduced = 0; m_nFull = 0; + sim_time = 0; first_step = true; } virtual ~BasicTest() @@ -135,27 +143,31 @@ public: void stepSimulation(float deltaTime) { - // TODO: remove this. very hacky way of adding initial deformation btSoftBody* psb = static_cast(m_dynamicsWorld)->getSoftBodyArray()[0]; - if (first_step && !psb->m_bUpdateRtCst) { + + // TODO: remove this. very hacky way of adding initial deformation + if (first_step && !psb->m_bUpdateRtCst) + { getDeformedShape(psb, 0); - first_step = false; } // compute reduced dofs - psb->m_reducedNodes.resize(m_nReduced); + psb->m_reducedDofs.resize(m_nReduced); psb->m_reducedVelocity.resize(m_nReduced); - mapToReducedDofs(psb->m_modes, psb->m_M, psb->m_nodes, psb->m_reducedNodes, psb->m_reducedVelocity); - sim_time += deltaTime; - psb->m_reducedNodes[1] = sin(psb->m_eigenvalues[1] * sim_time); - + // std::cout << psb->m_eigenvalues[0] << "\t" << sim_time << "\t" << deltaTime << "\t" << sin(psb->m_eigenvalues[0] * sim_time) << "\n"; + mapToReducedDofs(psb); + float internalTimeStep = 1. / 60.f; m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep); + // for (int i = 0; i < m_nReduced; ++i) + // std::cout << psb->m_reducedDofs[i] << "\t"; + // std::cout << "\n"; + // map reduced dof back to full - mapToFullDofs(psb->m_x0, psb->m_modes, psb->m_reducedNodes, psb->m_reducedVelocity, psb->m_nodes); + mapToFullDofs(psb); } virtual void renderScene() @@ -203,25 +215,23 @@ void BasicTest::initPhysics() m_nFull = psb->m_nodes.size(); // read in eigenmodes, stiffness and mass matrices - unsigned int buffer_n_modes = 0; - - // TODO: save all modes, but only use the selected ones here - std::string eigenvalues_file("../../../examples/SoftDemo/eigenvalues.bin"); - btSoftBodyHelpers::readBinary(psb->m_eigenvalues, buffer_n_modes, eigenvalues_file.c_str()); - m_nReduced = buffer_n_modes; + btSoftBodyHelpers::readBinary(psb->m_eigenvalues, m_startMode, m_nReduced, 3 * m_nFull, eigenvalues_file.c_str()); std::string Kr_file("../../../examples/SoftDemo/K_r_diag_mat.bin"); - btSoftBodyHelpers::readBinary(psb->m_Kr, buffer_n_modes, Kr_file.c_str()); + btSoftBodyHelpers::readBinary(psb->m_Kr, m_startMode, m_nReduced, 3 * m_nFull, Kr_file.c_str()); std::string Mr_file("../../../examples/SoftDemo/M_r_diag_mat.bin"); - btSoftBodyHelpers::readBinary(psb->m_Mr, buffer_n_modes, Mr_file.c_str()); + btSoftBodyHelpers::readBinary(psb->m_Mr, m_startMode, m_nReduced, 3 * m_nFull, Mr_file.c_str()); std::string modes_file("../../../examples/SoftDemo/modes.bin"); - btSoftBodyHelpers::readBinaryMat(psb->m_modes, 3 * psb->m_nodes.size(), buffer_n_modes, modes_file.c_str()); // default to 3D + btSoftBodyHelpers::readBinaryMat(psb->m_modes, m_startMode, m_nReduced, 3 * m_nFull, modes_file.c_str()); // default to 3D - std::string M_file("../../../examples/SoftDemo/M_diag_mat.bin"); - btSoftBodyHelpers::readBinary(psb->m_M, buffer_n_modes, M_file.c_str()); + // for (int i = 0; i < 3*m_nFull; ++i) + // std::cout << psb->m_modes[0][i] << '\n'; + + // std::string M_file("../../../examples/SoftDemo/M_diag_mat.bin"); + // btSoftBodyHelpers::readBinary(psb->m_M, buffer_n_modes, M_file.c_str()); // get rest position psb->m_x0.resize(3 * psb->m_nodes.size()); diff --git a/examples/SoftDemo/K_r_diag_mat.bin b/examples/SoftDemo/K_r_diag_mat.bin index af8b7d78eafda5504669cf18a14959dce1b38983..f3f0e69222944afb2be5eaf5b01f23120cefb99f 100644 GIT binary patch literal 676 zcmV;V0$cr50002iHC>C4B7(f)1%^p(URFFMtLg}SB!E19BA6+U+g3a$>MTyPLX5mH zvFE2p7BW0cl~Y+0N{~OVxMzFC50gJXIA-)mouoet#&H~t?yWzY1!{^y?XW+H;fb5s zK)XL?ThRwTalJplLbjT!;K4r{?@!6eIKw}c+01Dx_r*VhUwSI$+QvVQ8=Z`-8p%IG z>iqbtF3UgX|CmMirqVwFhFWkjKhr-{+bjcrb<;m2BQXU3!_+^AP_H}2 z^wmE~l%yW}mexP_QCN?^gxWuZq|gr(Gu%I^$5~mkIo?0pSvsRM8{a?aA5rka%ilj` z6iO3CfZ#tux^^>?G~z$TW)GU^q~kxeGP6i)L*zeeFkaMwMdm+PpwnyQX68R6;F%gF zBIrMReC~e9KN~CsMeRRHcJRvNaPL3c z1^P+v4)8yWLhhe3PVhfDY$g-pneaaaF2}ZiPw_uQtBI#oM)E%!@M!TrFY`Y=Brfi+ z$@4!=2BgaiX!Jj-GUt{0HT6G@FG9NV{q;XRp6mme(Dpwn`lAMfoA*EEU}x02ruRPt zdX^^FD)>J-YOT`Y$M`?bufqwITKPY~(hLvO#`!-d4h0A2PWnIWkKIZj$ofA&sQm?U zcKbhB^_8WN#`{0lHHod#4g5dwoi6>jTl_!&(0g0+HT^$!iKnf(_WeKA{YJQ@QvW~g zsn||&g8x5lp5dJQ)&D=OO8tALF91O8QIBi5K>$GAR7&*OjQ~Iwt<2w-Pys-RljFDf z+W|n?Yx}~Ulmb91(PV_@1Oq?^+89d=8w5ahD{qJ5cmzN&aOp&Y$pk=9(&IG0lm$S> Khgdgl3w6x)DThD3y*xaA$J_&^$GfMGdpqZ+uRXo}BYHjX x&&lOy5A);0S5M!WzdgRm&wt$}7r*a&4?c3~O+C9GOlQ({d`K_({)^tH>=$+2M#KOB delta 28 ecmZ3&n!>`vz`!ukBtYQLe-LWmaZm}U|B*b4+y;JX zEs{J}0a+{3P`o^m1Ymza>iqbtF3Ugc|CmMirqVzEg<5biKhr-`+bjcr zb<;l{BQXU3!_+^6P_H}2^wmE|l%yW}mexQ1QCN?^gxWuaq|gr(Gu%I>$5~mkIo?0j zSvsRM8{a?PA5rka%ilj>6iO3CfZ#twx^^>?G~z$SW)GU^q~m`-xiYgzYeVEea4=rf zfkoy&TA(j6{Xf`vz`!ukBmn>oyaGc2 diff --git a/examples/SoftDemo/modes.bin b/examples/SoftDemo/modes.bin index b2d19ef74b1668f7f8f1ca349c02c20d4f8107bb..5ff7d8e5424ef287969703d4d23ae07e664a2f91 100644 GIT binary patch delta 48807 zcmYJ4cRbe7`~QhZD5;cHQmM!+mC%JkG|?bZDM=y84BbYuvSshR_g)vb+unPRBCBLZ zyWjo!xIf>YKcDBE*Xz38?#DUrbDi^k18<6H2;Q7jRHPFDwdH|rFqU^CU;gn&h}38x zd~++savJ-lbm@`*B?{Udr(bUHhO8*WDciiX?B1^G< z3}u>?v)8g@qpc3_vD0S0VzQ-YSGZ3g=0s zHf&$1EE~(bD<#9&04x-pKtsQj@X7aO(Od-q@#0+sh@u#G2hcqT*dAP__dt4k>ZgJK zifHf9~94 z2C>_0pmNE3HDwO+E>k;K4g>j(U zvB8f~45%sn{ro$uJx>h_ZLDQC7@Rn{^Vq% zf3QIXW>Nw&p>PSZ(0_D#DF#NAjBitP8Yuxipzt(`j!Q%r;lCLuP#P{=`0zQvp%>Nt zHJ{u%kPqk11~?6VO+g;wGf{aU;&RZODa)xq)T8j4Exoe}%-QhB_=$?Jb|qe=aP3b~ z%nAt|P~>sKKdh$(A5!@ET=7$>;er3-uWJZ1qBeW7q!hPv3wtlugDyqrNuWv9*u9uC zDwEKc&f*@}L@^euuV0o-tdz2}_2!lhZboxTp#S@kE{*KWm*g(Nx#pDTb3Ad-yUk37 z%cl@NvNZ(#mPqp^KgXOuMJlDJ7;`R-L%ZF?p71XzbK84#jZ5T{b`qwk>)|U|)hgGKy{p*ze zga%532*tpWy)GkXxfQzi4w254v;iB%U`y4l-ay4ln7lmxK)SmYeo-jy3yr?oogkDNOf8T6mmiJKm{_vM5Sfm7`P2mf+*>-hfdHBD8rYVowpQ0m9(TD#g zOi0H@oeiO(jflXI@+3Y|g#MQS_wdHQK!!=NSavc2O=J@p!<=hi+>oJtQ*$(&=a=r@ zHJJ^>Z81jShOKbKXoJJNr`+N2I>O8=qv^WD(azNmgOmmr zu1c*j$wv4^;jF>4Rmn$ooqOyWxyAKBArw=Du7yvA|A$Wn(njZW24Nw^SV`e@WFnbU zfA&89qNWNRDS?(;5FYyv=ec8^!o$}IPoLb8C)_;Ii~O86DT+H%A?}T2tRkTU^vMnX z;cYbe5zfyZ0Xt;?p?vaG?5A!#U>#r3>zD-Dl>X)ve(_J4vAV7d9w9nLT!(o+)S6I!Zowde%(X9mkU_HC$0;bKCB zjfV5P?R)-yYQ`ao@llGukyHf?ZDQf~43)lLYoVpiu@>qLuam3@Xs9e(SaW z&r>J{R!#pIAc@nuxtGZSVJF4lTocYT|0MivXO`ZZmJ3G~4m3p!c0*Y3I4RhQ0|KHGmm1H8zz44N!Du)Z# zX=YfO&W0dAh418EUanm~iMQrPE|7Iln8L;3*>i&aNdyYNYH-T>((7KhuAu%c#)<u2ULx1b=lF=5WC+im@z(b1ilykk(Ja3?)z*3V*CQwf2&>4XXR{(wMjl;3|s= zotk(N>J*BNfvN-MQh4k#Er<7sSNM$5Ur(FH+pzy5FcM5eX+C_-Lw3r5N0bJ)Z~q+t z8Qi*yUKaImh)?plW$Oge?$|K68PTzWr#=IZQh4OThCvvmzYo{TgoiEV_>`hwPU#;? z;XD3p=o5AsZeFhEXau`w%)=9E!^lK2Ae6J0(|#Wx@#8N%)o$5a;4XW{!v3Xw@^Kv7ZtU&&me3?+X1rEf;`slz=v`Zg6Xg&NM~8c6}pb zS-uS&oBswxXoc|&AxQ1s5Lz4B$iSY$t4^?)_lc3$bJnJdI~LmDR8%%X5jdGQy=l^Q^Ty+vT2qo<`<@#sbELE_bo2I!f48KKh7zdO( z90_#}EYlGd|3Yuzg@-AD{%XL8`QPC8eXKs_vqZM&RY7Kbq} zuV&N|V$`tuUHd_wX(IR>tDV2ISOt*r#qv^p7V2MHe7iFu4W;)BnQb$EhYnmFtKygd za&fESnSQ}suc`~#lt@7`lg*pf^ocN^S!Es&z~t^m!ioVc9h z-Hgp^Q@@oBzF?`}t#1Cu&oSk4hAZK?M=s3U=-DUFR)giPsp5Ly8rqfId3w3n-FAPA&SVto$L2`Byp#`iiKSPoF%tO=w8yWo zS>njtmPl2DObB>9^>7RVKr)?GblPdM+k*r#+D+*n*5Uy6CGEM^-31jR zPfk8&E5eH!PgR@P3W4QRV{4XiFZ>!36PPGV0H;lZGI!ZiQL`iJIODf=Pz_MXGJ0Kt z_VXsU)+3vcT0D2@j$9E8Chr+qrHh3;g6NZ~D=Z`sj}VM?GAhKq3^&dF*rMQf(5E7v zs$$e~`gacC_O>9qBp|;^8 zO^uzon8nQFQ_dF-1zWA-ho6;0V(!V>C519zze1O8ddUrc{yuapO0^OQn%TJ{jLZ!n z>ip<}pPUW~;<(&=pDtM3mbKlsP>zvbAFS-q2u0gThJa7JB{2QDPo8GJ6smuoRK9E< zj?L4f!8J|3;V~mng-BpC!)wqn-Fc6!zjeHOD zwSyXEkN%O%l>|5y@_PBR`8)hTHFvXBA{i@Z9(8n@wc_wfzN>MBC0?RBbI8d!6rzd! z1oMy*40i5Q+xIUGjUO{IbUltmj~D07&e?VWeY(H0%k?Pe3;njeJIfE1kIBe}E6pP} z{ej~5T8)rpDssz1BnqPv+TQ7@f5j_tEh)A!#alG61w~-kvObOxbJvsVi>4TGTcfbgx6u} z)`=xup9IMAa@+CcRTuUh3{pM7UV;Mh;kr^xY4A#wT3_o!6v{9kCGNBBM8_XNzx1-Q z5yB4oD{db}7L_Xv9SfXkDc-*P;0tdOPQZ9mGF;%nRS~MJ=ea6H%>{$~j{p9PF-j671{l`oNp8rFl_QnA=pcKEaJ_iPMIzE}A>rxFZInMy9W zM5CFYZ*hE5w%9SUHk7AX0j__27u^3SMvEJ}_g6b@{k?@Xbg=VJKV;mS_%0%0`Czy`)X#cS9}= z=eSDj1nx8UqTKGpAt5{6`@LB;>~&S*52~5~&Q)Xem)+Gs=z8}eJl}QIUKs@eKHdkb7eCr4k*`bC{Z;nV}SSoI5{!=O7^#%t9n~6Ov3(F{L85v^NWCZQFjIjVMF8L}9VV zP6*0ZI&1e>)Zkko{qOfR2k~*SUxkEm8PKFk2Ps>=#hXVxB3Ww3fvNYwo;j^z%vFBl zwj7oRIt53|%1_q9w&!!^LESZIQrpMXR22y_uGJG+olV%x(tfywpjd)m%Sl^fUl)ML z`PUP)Un+2qF6oFoM>P!0b>$Q!R-mfKWBMVZZlHe1{`%<6S~#a5mS`N&f&2D7l$)*| z13uV#vCKaJE%RAT9bR=}Mor`i6~;u^ye4<-OKv52b$#OWpvi}VeIG5;{d@5IwqlnH zQE50UXTOPXGPV*&Kddf!(q*I5$!~vF>jIJG)BY3m0)==%viauqG9sSe!MWqAn>YRw zoOy4b-vY*4u4je{=76nLP2ZXM_pn7Pt>uUy5d`C(Upf4?6*861G!!cZ0nsXKH*ZZN z?$dD-yVY0)iRCN7bCNlbnxwI^UAqZmN6iQiO!C!0O{<`=Dy{|8JJS$^VVtGK|({rXK!c+ym<^Z zxit;=zLL7ppSBYCSS~iJicjOvU8?XI>s~x!87=gAUpra~?igDX3jqHYgk$_AYJT7^ zd185wSw4Q&x_W@^NIqzqf34$}^Z>8OhgsxmEX4ZGh8JFpha&^kp;0~N7qy4j{NR}Z*wrYQ&cbaow_ z=FWuKkY#15brQ4?c%{F+%&0-dyO9NLb|2wk({kItvUVW<97A)c|qLOzd-D6C^FQr0xD02WD!Llasn-7@1|#bviZ*WBVr+g4d#e>D8ox z#`zeGZThq+tECzhEn}2NlhPsNpHI)N?Q{6achJB6S~Hrxb&-X0dHD4$ZNu4|ZUQic zq<;On><)aFUS-#|=i&>kbK;)9O~66-^MnQKdtlvrPtWXFJ_P$Fn!2=F!=C42>-Nb$ zK&3IX=h@>|cvk3x+33d{Fx6SRKR;lGPD{?5zh#|4s*C@n@v#t$IHzO==5}bSqIZk; zjW75I*OM|5s?ey=2kNK@QYhUSIYws@32J@)L+<3?z|O@Br;~j%P-?9AiaZ^86`P9U zo8QrgSu=}WJ3ZQvHea=MGQ1ESe&U>JT{}8?b(Mrw#N)Z9)R^5nn;^POhN$LI1HTIH zBqwK^B4hsFym(R-Rt;wPC{`At`&KngjfgymB1O3UBSg32UX`w;mFhkio?KUcD@g>6 zMADk~aw!Nzye;V5GL8h{okTuBb2ak`?7DwylV-??xF1ptw zxb-gi4E6I)q`RpaC=yfwxtje8%IQfk1#^FYCUnAr?Ola?iq)X^PJ#LKiFOowdXGdn zZ_xoyze-$Wld3?rf5{4#y;1l*gYk*s-%%7d7LkeWh{o|kMrB|w0YY4k3Se@5bA+VefxLZx{-zT z-Iw-l*_w-C&r`VX~Y5(bl(2^O)SO`>TrJR@j9$M#(%nfrU(Mt zXgRo+qW_E(iCadvtzKcTbqf=R_@5*58UDH4u7d@2RTK{dmFl$y{#rAcQZN3N4Eg320!?o<3RJh|wW& z34Twe(fdd?Pkdt==B5_Z%}Gzf`}6i*eaiW8>->d@QX^;VS>L%AV;n6NLq6%8=}{efND}AmqLl zlo*F>8V1{hZA2WRS74?iFURW)Z~OicEZ#w%+)B)Y&KiW=fP#^nCU}3XyOX`A4~lp@ zkCdquLr}3SZSL+Yc)t2B%BMd91(N=TOqW)Zi%f@UGD>ty&v?SwQ)VJN!%YELD; z;55~9Bo?9UX?t7x;Q^#!*1WerGXMl{Z(r0c$^iCUHs**rRg9k~ks&bVy@ZBm*Is*; zd*b6J{@EqJW>8@Ps<3&ht$i&#p196`2I+C za=I-QlP#nOK8?cF_*|Q~B}tBio_C))mMUlCqn!^UZZ&&Cr`Ee~0kR+p^riRS;ijQwuh_Pr8!3BBHaN4^fFWuBYf&m^Ia=le4BlXTg*6(ie$hN!S(W*>0ajg8IEXsk#1Sg4UF!q9jub76z%1{#qvBA|WP-(8!kw z|5SE;ZNB;ztJX=11sV-N{5#7cu9Shpkuu+jr@~-Tqppmwr4K~piVoBzk~bP_{UxdM zfp9|bg|6ZFD9(I~NYEB2L2=vB9}N~}nAyhqAlJSV)=g@@eBh{n!(!iQ=pNSM=Ey%h z`)6uVqDnPl=}Q(6M%$~lZ`s^{qDR<$X!$>4f04NMWz}prv30zJO}Z4v2cI6jb!`T( zWbLMYal8}-dKe!wHr2z#+O9`}*Q>zxEZuDrw{|oZG!LTIO9y#5FN?;6WMB}^KdAOE zA5~P^OuWr2;okm<_GN=={2lO=l`EtOgzns}uhh&ZK*D^%&2jSC&Wl3Qbiz#{aE_na zceAJbXVT!{e~I4r&>HS@o~Qp_|5M<~au=*zLu*^%i#v9u(Q{$FD>P zMWUBQv)IQ#DCpYzSDGpS&4XGFWu7PDmCwbrW9u=XCU#j!A*TUGhA-gO1G(f)DAOwu zy-e&LFF4X=l?Ww)>#mb*S(tfd;!RwCB9a&tLL;e%;MD~OkNaw+c*J*qiSM2a+*hBN zkybK-^h3!k>dw{R?`I$&P7u#VW)1(suDMd+NKaL*U`xWN`?ndngNQKTZ`3cOTZ_N* zM>rl{AYnD*lfdUaMXkKe@W=~r~0j}Z6mZyY+G5` zk_T6VtQZGrs&F>+#lJj{DjX9y?{ZH&2hQ!w9a8op;l-mDUkmfL!LL`H<@`=0%zLX; zWJH&N-ZE!?J?JG@w;hhjZOP37XHSLfZ-OQ0%iXk#=TIMNgmwuM4pxAQ6kC_m>kjk_ zxK22DgMJ)-E65n{W=G_&?OEtTa z3n%SFuDAx8;l7>94D_S|2wbXhSoN$1Uv_<^wnMHM_9sbPxw-}nt#)1cbz~BU7K=ta z*~;K_wxOOVu?+Hl*tBHaXvOCpguV4FFLWPwUWX&8n{wCNJt_SP~qxekV+*VSWXj+H+ z=Hw!}ZECRR;e+y%#|z=tbMES=%|yJt&eB#QQV&zV-P~?YWTG=+K(1Cop%bi1T>E?t zvf;I-r@{!+SDU1Y>h-%2{OMH!;0|1nd9FRt}2M}tGN+x zngeB7XBp}47D2s$R$WI_6Yl;%B;U{@*Z;OXyS?SikxY0Y{Pg7k>1cQ;ww#nNI}A7c z{EU2^>fn3n@3p&sy3s`><(a5MJo4?)O#k@477LUXUWHdafJsNTKQ^4zsKI42zLS}V zM|HJNowqCk+Y^=_Tgcn>ynN>D4vtc&%@MAWOOMA{z1up^W?p0Nu*o0Izl1z&T}d(P zKNEw~W3Rkl)McSo7fZRRP%NtL3zz>yK7bGq9FiBjIf!2@`MB0^WdcF!!ifg;GSD6f zTR7bQ2_Bu4RQOd=gS_fOwJ%EQA?3uy$2kq%aQP#FyQj4VYn4iAmF|=P`K7M@+2=m2 zU4~a~CRNyG1lFd6Yuyl(Vq%>|o|B!Ud!Nvo64ChLyUQ+*y1@MVrOj%O{m_#7$mXs; zweZTptK!zNWUOFdst(TRM9JuF5lnj`F>MFcCe2GZ=(wZ5g6?G=mK>_S&>0bqb4SgH zPHsV1q5q`x)~^(p4wc0tHydD+obZX`o%J~Q^CmOl05$;Ec=48fq!<_&)wleiSA%BD z8B!O58d3bayvJMV5@fhO7JY)e-9BRP==j{N2&2E|8$Vzx!N#puwTnc0;2Fz|toWf0 zi2Lwlq^Bes8YOtlS!ev9hF4USq+EdAv^B>MN|!>A^T}nUoEnUGXE}M~0TCA41PJw8 zx>8X2p#Kfl{p8c?YtFn=;rTecZ8)weFb>Vn(n$r#kgv_;oTrZaSqw>5(ifT`6pmOM zwYCIi0af;`u)g&ouxg^d);{J2$1)o`^q-LMC+o3763u&%wrvilx|9Gv`pW4AnC(zi zMa-a=wFcfLYQCe*3xyRD!SR*|RI6OZVJeL4(yIDdCI#N*a#9u7HCryJo`fj^na>=^t^UYP7!?2`L}SVE*c)g2tbIc)98C z){HCppcTeb#BOr~f;C5m`CG^r6?OW?w3U;vWnx&F`?V>I3G%OfOew?#&BmdQlJ{_X zu4(AUmRK;neoKzVr4X;tR3$}+R1rX`s*CenU^A{HEGR1PZiCS+qwYs8)}n9ysvXTv zghqRo{Kan-7*rQ|Sirv)>iPUX`g}vw%yxgf#jOLU*iIgJe>N7*zcZJXt&W27@h{mt zH7PJx;5{}Gg}|M9iiwfB2J1y>e$5@vL&GzPU41ph_+{Dt&YsPLD(La%y*4J?4%s5_ zF7J8W2uA%kTfGM>(1N7*EJ`&V?uq@QzI)FDBv>6}kGXb3&wGw-`v;=n??>fA{s#$= zcz8hO)6Zt8Jn?zPxIP_-7fX)m3?;yE8KLLq9DX47W6ohHqYe z(JP6?FoU354>^O6Z!4)3AQML@=gXf15X3v0c#I|sCpq>tlt`!IsM0p+vB(a5R&97q zEUyfNY!g@R^pTv~tHw2U8DHg080T9E=AFi)ng|f}Dzuz>}V#F-o3Zfndq0is9 zTGrHqInTPE+mauc`-kZHekua>6t8;(CRTf_ZFFx7VU0oJ%E9XO6QlTL7w4E8Up11J zxkOeS>!E#0{czNk28c7^i`%AEgeR1*>GRMj>;Y9ikY zIDK5@t^L6dsQmY7l~7W~`uTCKS5_ZUj%uAv`F%GSH&zn18i{w~FYZs> z;iA=WCO9v42lDUnvGN<@C>5)xzDWO!e(Q$rq3= zm|8f6v_kxlxDtnOE6S`(UA;k`aQdU8RNg43ga7k}&bn_TeA=5dG;rku7J52}*qv{} z0ZlhsSurAB^CpPohLcaZzefs}39%M|wPkF&QE(k(D7l@YwsHs6JvnlRG{|#(tIwU_ z?Ui_eSH$O!Tm+u}{?CNnI1Y8rIx2X*O~gFXbkp}|#lT;%Z^kgR7g;`UDU*9O2+tkE z6;rcI5&Q{BM2T4P^&WfuevKyd?_g27vpWT{2%2g~z=e)doWB%UxEWg^#>usk_UdRrV2IDa+W zG2LAZS5>0+jHcG({o~so7WoB(Ka)s}>u?)(n>sMj1mA)CZG8#(hIT00wuvRjaTrYa z3KlLx5L$_H)_)+qL}Jv4wq0T!xY*2|a!yZ&2KTnRudjwcXyr4JySvEMv#{$$^vXo6 zhzRRijGsSuCSE_+@IwLt{Z1)urAbc)&*S@OZnKxe$c&}=j`1iErWI#wlB|Yf`4b9j zp5%)NZbbSMt63oOM4;dpRV-HRFM2@|eur<8me1s8I$>5`=@7@w0W6tO_x^da5RwD4 zD?6+*@l%pw#aj3T-20ZXheY3m5+ApBc_n9Hgv4!qwgN&23ht_^&}7Vke~D8o&BC7e z%HQhq&814bb~Cu?1bsTVj-1}9|0^4MZVQoa?HI-HYEuK7zLbH{7F$wJY8LKWOxYp2 zw+?j6+Q+hJ9pQjwg-`aqN-W1PYF)l@82)>7N0E3L%+U0-6e&; z+k`8F*cg18x>G&^l9)9QS@TSQQM%BRTCoPuD2utYay$uU$=_#ujcCW=owfU4#@AxZ zZ6?4#eE<4xJFmuOXfyp!ZIxpurNA@%Q_7F7k+&?W*CDyT`$MeM1Ar7Z ztPqq0JI*9!EWgyn-P-LT*5tLI!iHhZ&xC{uRsPbWQ{(uG`741x=YBO-@V{ZA8LYu< z$D_lV5>4Q~qUC&^hlnZ1)SY?u6Uj4Rs*DFmJQ8GC)$biF1^E~%?|%)&7*Xrz%49JC z)Gu#H{l51A^wVuV%*B#t**HT8^;Ez>p#z>Ws_?|tm7s6*Q-JHVNyWM%})H4bStL$W;Iy94|>7% zFCDBbSnsM%^rGNZt|=ZuCD`((zM0Ciz{EvU4;_g*^uNEzP|cqOy+wu@O?O&xi@Vj> z$+cwga@*tj+Se9bIF-|?%rY@h@tk4F4i8+8zE4#-ME>^U%6SQ!1MiXW$)jtu<4g^B zFdyx$86-kZxL}T5TRN}^xi+4C{SoL7TZW-y7a00J`H*&|5msZV#8UX0AUiwYxBBf~ z_}QI1by#i$wtuv7`OTGw-yFK0aLkpU${-!})!A;;CzirJ8^F(Zmug|5J62^Z#IDv5GSS4Q{!&OrC(wWDYdJqKfT7#6_6T4S zjK9@=U=h>~#`S!8yaMrP6C1AU?vM)G8onOp5X?oPL>&cvuUa^oE_mkAmI5f|I2Qb1 zW*YoBXWzAQR${fNO4<(hQiv7~@Opls497jrU6>EgfRx^vU2W2pSg6Tx<`f~Y3Z%+L z?!9I1MD~ed;nykIm~cA0=f2!HifTQ$reY@tYo{bsUg){tzON(MkIvWQLsK_?-dE*t zT`yFpE+QFkZr0@ND$2rtKPzHA*NS1^-iB85gXJhDIon&!>jNt6CvQ1848!?wj&550 z6euh8`#fDzh$Z1-dk9K>y};-H(tt0s0`pHReMLBSq$ZtU3s5(nzLO`pNdOycNDETBsl5Wb1e20W6;Qllz4{pz{mvcFJg2$On;+G9mNJ&aIDu=ubF&HjcJ&(v*k+ye%4!cFz<0i@HD-$ z7+3}ug7+zZEHA=>`};nT!ivGi=-p;snLs>S^>SP7>sqkQ_iZ+GEym}sigp~FP=?wI znFFi>pTL0_Ru((v4S<&}&|LIIl}ZuMKEVd;%(~q^n>+x7xHg77dGN*4CB_g;uG4vP zKd!u3(GF)UI$ntzKY(@R2*D9@MMTz=@kgXA5moh7_kPM(0gtvF($l-kkmbFC_79~@ zRswsN z(_dch5P0$LPe)|dDCYY4n)n?|0V3BSUL#TwT#}LWpgvFwa{Fl?&Hc*7!3v@0lSe9X zXT6QU?%op?>L@RB39 z{(gjE>q06=19Rvs==tXwQ3iCMYECGKR-@+9Y<$@|x#;wH5o)%?!M7{dBSnlp;Kbz+ ztv?!Rc$g$p)sR+#E0LS;9B3dHp>nEIZ__m(_0%bk8v*3gvTs-atq}akQ|4Yig#fAs z2&R#F@N_l=rK}wMImk1fmZ#9(K&J}iA6KV6&>H}=WA}q~wicmG;QE#OJ4mQv*tuxBa=3DBd?IdHU7K8xP7ck6T=!(We86 z!KUWNZ;_yBuH)CKp+@u){Uzy~Tn!#N7bR4S6VZZotMkfQ4lW!>jChn)hPlztTVJe| z!mmx`PHds$kbcqNg(X!z7(8xqv^j;4F!hZv!6?#(`u3h4+xG^;Ut&_8rbaY`t$L!Y z7-H+p@U>7=5=LCsTif|Y7gcWSKJg=0$Le^8bEPWVk)CR}f)tzsd}?_X>*P}b?2)fw zV)h4xUUQy1*JB`gm&R&%VHe!_PWt=sZZ6Cnxa0qtGai3MwpMZ|O=Hj>f^VI#TM6>5 z7QN4jjzIR&oXu33Ex6h1!#UgIAEBF$g;R^S0#3m>p46Nid_2O?Sv^d?I+c5N=ZR!v zxDoaKN#=!^^3_y%2pXiF~#zLF7JT&zlGeze*F0$sZbc`G&XtEQms@ z*>7TN+U;1SQhMA;zXFEVsdt-QNy7WdyUMRqH=}yC=Pq|53EGzU!}pG5p{bKhn9lEd zyv}up#WS!3>p>)#I3nP($) zma5>v_?4wMSqpF|KXuKXMwKr66rr+8`{)PB7>{9UvLXQkb9Wp9%R zphjDMuBx>M8IvS4o^+Jp`h!EH924@}?7;^Qq@_C0bZy(VH;M$v*Dc~3;PyjJspXWX z)X``+6Q;_1!4Fc`whxV|hv6ODm9M+Wl}{?p<5%k&LP5Yfxl*Sn4u#XxOy>7BVF$;g zuzg%TZoTj9a`#RUtWdr5>X{&n!{4Zh!hzISII9{w_WWum8r^QTIC1|CB#vthmz@kn z9*dm!ORIyput3ev>s^cXg+ICCRCCd*@E+sr+YhKo^L+D6Y71s%%6v%sUW^M#mqjeK zYT<9OCX@L6DhP7j^~NrYgqy{$DDEu$0C|IhH#YHpK(j8tTmizF9OPQo{BWmw5`$d0 zba>h7QM=Ipv)G|1jPCuzK;Y~|UHz7fd#aO=q8`58{SSGa|II5$cYhcg4b%Gmwq(E+ zeZ^D`jxf~nG!1phE(NPy-#y#O*YQd^V&{_-vv5hT*L-!V0mcj-xvPf_pae_YTL~&# ztc7>5>BVyFA-l>^p?;7yI1vaCh} z?&O@Dq#g=_>Ez3YPmZL+{toJSj)HXXP_*Y=+)lm=#w6V=Ej$RR!)XWR;^SdhD6g$- zdjiC=F<+HF)eN#b{NB5dXF~95cFJb8DsYQx?47ksflpyndp0{1U{DSrDL?*rDR{7p zg;cF20QdUSnSUvzpqkg|6XqKaMPjbC%r}bR{dG2iDya^mJ2F{VPZxo_q)zbIlruKI z^A?DVsE3F^LHYgevGAkN|Mxl#3051lv@f(aW847!;IAVI5T&!Dvnitnd{;;UAEeqr z*em#i&TBiEC8YoAdhA8M`|Z-~_|v-{SCd%n|ILvPm%I($}|Tza+hTwpE{iAlFR8tEuS>dzA0muF3l2hda80_iulK z>IP-^T*WL9w(xU?T6_F{oKf%Oi$3sCrHNQIuExfvW>>i8+@NvG9ol2$*KT_rFmL+V zi0LKU&sSz+{*2RCxo&XK)*gRJUd8H6 zSd&T$h#*oCxOweJ0p!btKHmCU2Qnr9iMhEKcK@}$IQgCT{W?1G~0nw=zsrM|+VCTR-M#d%*YOS1Xeqh{!cK(5) z)(2n1R#&lr%jK1zzcXmh-AhAgAb-8k*D4S#_Pd?wAY_yRZ8bs1PsAAyY3kHvG7w?^ zWyVHz@`b_Z*}<8KvkhoOOGlJ{69MPa2M!cjb>U{&n};0oyP(*Vw|yMZ$YPM!K4$3LqicfU&(W>jo$)E7EP7?9|l+bbUh#-87IF&L)6 z=VyjLjf``lU?D+BFEACTedi6WOvzulKR15SyJrwtd^!)XWMn|aaxOt(ZyqkP4ZpG6 z{}Qh~_AB7K(bUyN8vnVGFS-B|6LCO`W)YmD)hk;t9FsER29b7 zOU!s4Y=kSly?o`3M9e%;CSd)Qh${Wcw{@=9!&YaFz=*w-=qV@L#QwdIfDagFKEA9Y zpZlv#u(&_yg{g*{?}M46AY+)1mq#@nMXh-zC$l=pyIDzgDd7^(YJRd%)>ehDso6GL zPBg%lES3wAO8M|YU7$FXP(nUE>$iM%z6PH5da??y)Icl59=0a5po}F;4eQ-LaIup; z!FjA0I=_AImqT!XmI z{IM>iIeIbmD0%THJa*oA&zF8ksQeXw_Rb(4=OWq;jl9FJiFSLat*f!7swyJYst@4V zlk(9i^4t%iT_xx2y@yi|ITDvMk_W6Pq?IzH5o4~JT{2-mY? zAlJxjCG}k~e6YzlU39e?R6I&E7RG~+McOc-A}9g`oT{!F9~#F9>GW-^U%k*i@>|23 zZwLl$@>bt^>LEN-oN$7Hhy|;!>ZNpjP{ma08UN30SYVJoDn|YSQyPU86z6MD(B(s^ zXKoUl+ZHVO&ov88a$XWdoT3_GKYRZmtuy&{np@YY#7E>gI!Y-+S-l)Xjo!*_G3&vI zfajG7S4*+|mLRwK=4_}q;F`rQkPGL|@mSlCKesy)=D3HYB?-4j>>s*Q+zZ-VYbS`r zYIywj=|PEW74YEqky!uF^*H~!n<_%17XSP|iq6BI>h}%fWh5n~Aq}G>i82$VZbGDl zLLs|sg%B0To@H;c_dfQ%?Y;Nj5h}iwwEaH6f8e~%IiJt-Joj_m*Y&<1yZYbWl>$Pc zBpdF`xO`A5coVx#Dn%~VoFmtKFXMp_ZQ*l!iy=5p;{mH*1vc8~YzWqb!r_i1bUk97 z@UdcQ^y!s6pkX23V$5m9+@jBLW4j;a%r8|&gdFxgA)>O3a5~JyhRL%zfaqK2?odJvuL*3= zk+T{@6_2$~H>8KK{6rA1!8c+r-smwCMD-=dNs`E|8eBB zb;WUmUw3ZihoIcgQ-kXsfw*?-$Wq`!GgcbypNT20#&a9B97#dL*tc5YAK*k7p0_*< zEGT+NFp)UNDop5n{@!Y_Y6Wdr9(j7-hG-1L|s=tfh2k-h-hi(ZYPY(i!AH@_p@7J z`*D+=!_Ek}a%0L&lst+PcRs(T2p}ZYuS*8?IT!Aum`!7xTw*V(mi_%s?KlcyIuz9c zX{p3Ju(f~&lUQ`YEBRteA<#&Xv#Ha_5YHpC5Tn`$UnL?9EX>&qJArzcx8|GMZ-os8KtHE}PZmpY8(x+>oUGE77R`c-&8nH0KC|9hnnuzbio3 z-R6|;HUbSNoWHrid@1CuxR^4|?>fzcj`<=W6jOr$tskFjkq@O}09Da{N_ z`AfQZd7}dRF86B=5KafNd4{r?T*7*3{Oe(ZR0;SVIyYr@qY@J;J07M93_#f0noj@e z7C1*`^Np0)UyNEJ{WJ;d#5KG2Oh>*}Bgkeq?`tO%j&~IO|Fsc;gY8GxPgn$$fISa$ zB$>VnCtMi3PTe1adyE2NTaHmclfUzG0>O-mxKwYo^gIjxFmE-y-}?@4+#^xg*o@=C z8b%AOl_P_S`{#{)WYlnumtxcG!@o}JBu_@madh?>9Bg?)M&9h|5&h79_}IPlAZ1rM z=D%=0dPTVm(v4dWW~8(29%IJ5_oa4 z3BSYgLc#T9FyhSo$FgGy-3IF)SOtcFo^oONUeA6UpkDZNWPTEyhY1GI`$L}a=DiP< zTtpr4{Bn49=e-w%e;gfEeozRnWXb}#`{MDNPT`englYVmxExdP>s(x)svfo8*$#3eMirinKOO#yXx$T}+y#XnXjI+3>X86cu3NbnIQ9Uoec>>vee8 z4dBk!rf<%hO{hj|sbS7c#)~WBBNgNbSgGo}V?Nu8`!8bJt?WYTexGWP%n9y2J zsWepuZ|lf4bWI~@85x)*CF~1}w>F>nFE)bo1uJjcw}@#9?^65@_MxppCOHR-(8KZD z>wN`{aOdi4+hvMEoOLT?t#q@-$~4nWiy!R}8y^@nSu=$s@o8@wLiH{&I-+)vSWQfO z(6nY}985DwR6EX-$iQ>oVdTJ~3+8z|#ORy`I55&{uqhA=)@3CkO|nJsd{p!T=LTme~Yd-i@jLk2jq@z1U& zA1O6jg46c5<1>$jP}YTPlwc^8O?%S{eDcyirb&LY=yFWBbq`^q|D)sWmll)>nj^^! z_s`D2;N;xu##5qK%cFbwpokw9SVk|u)E)r+f6cu~a!rtId9HTobP9gvqFvX9MBKQq z7JlVHJ0VJ!y02vj1BZnX<$1AgjJ4GGX0TC?&u=~N8#(I%oEI9GnM-uX}oy? zP%`y=n}-3a+D}ERIfXTQx#{x;+d;*NiEITW3ljHH)kIP zRePRsmnj2Ar^^3?{<(pFQVHKKz30eXN1G7vX9SGJ97|puO#qPC5zT4Xh8-@a9UR%4 z@ubMDOLPYtA*z#02K~yAqPAw8YibxNV+u@ecSd1A5Gl7!HGoJ`Dh~SUYNaBTu%8z{ zM<7;P&6+;b>w%%zph=IHvrsE`j&{#%3{)RW3M_Gng89=I_Lb|j!C1@Be8qiva4hKO zvHRtSl{T}vzbSjMl6Cb-#Np?-sn8Yw(XtFptHM5rZV96Q&0gg&VMLB7ZP`BUREQ## zAKd<`*al*?83m?iN@0)i;BPLgUc9s*u+UODhHuG9jLCf{ zDpNK0in9bym+rWH;07VdT<4Q^V4Q?cWWA3J-~Avln~BGqV*&p2rk-UB&&PIQ4YoJe zJ7JY$Mj1thkXxN@DAREqNnBPer-NB@L9R_hwY|IrUfZN7_fWTB)uXF(UEL)Zcb4i= zqmu>Fhcj;0x`cyKmqC7FX*T8<$5b19M08SrXL)>Q9mq6(u62(k@_h=9_U!5-aBttc zCHeeen1a!PC*JYE(o1IiR^A2OHD?uM?6QF^Og&`v6Vd+{X!gigWq5(hkrWpmf9L=_ zW|Ug@pARsMF-P_dRl#*(sh>xQ^P5@s_Sx!zmnf!j#pB4ocKl+>6vsh!1;hQdl*O;B zflLHjMI@*2-nX&|dhZIfG_m-%{;(dDICQK6geu|Y0hPIs=i}({}iR>L!K>rS)N~T2q|eYzw$v(5tc6NW%+DbZyH2h*E2GH*>P{3$z5T z^Vk2?L!-25xYW^n`1+4oz=%|h*dBB9+`Y(Z)IvHo`{6QJthj7yL>@#vE9-*#t!N}s zt0Z|5HC(4`0o5PZS*UJJlHmDV1ELiVXwSV$N7j?)458a|J7J{&p}mtl!AzQoLNWGt)&pCld|6LcDV)r4bfDF z#E&9t$!gfoyf?UJ6;}G|Qwv5|R+lQrBm=93v&2wE5p3y*Ajp*fbxIsryFgd>)??78JYS^r0Ph>%JHd2Vc4$2x8pM0#Z!ecpX2X}u>NB8=J`*kkXLayjv zEwK#~98s}i^=%zO=JRwb64JzRE|GhzzMk;^<}zd&^DP!Z4Illlsg--d)XPSxN zF^Ti!)&Cw<;?@tb_hIs(I5zox`B{5EY$x;GkAE8vM&Avt9-OKHuCZHVXHSqifiJL& zvGPqkJbQR)>x7Xv?&VLqvHRKt`uxNR!JknW_V(vc8o3A6SeEP3KMmk-q3_;zOyXh3 z0S4En8$EbCIwN@XYb2y!o7tC@Vh{Gm_1MMp@*%vDh0&<89vydG_ouR}!jz;*;j%}G zke0(R+uYHMU9P{4El5vd!Sek-kHMN|bg8`f)BJc2mQc~(Ouy8I=k*yDDX-4}M|;E< zxrr`_OI2lK5%0r?m)5FPTc)7vzulWsZ^^J#eSNI?&pY7HVSUN+J{}az^Bote$RIMy zWM=DGgQ2EFv^*?C>OIR1tQT706&VZXT|`kLKR=D6#@mV#n^plOHdWa4OhWv>q-t2O z=G+Q5oJ3U{?O~UTeV}zAT1mRM3raI>Cj9t{alX9%*_k)Zkh*echS!Wpzg*2~ow+bX zM6UD1Vgh?mXXIYTJ%^Y0l|?Sgv#1TF#U`4(2+5_h;eF|=rg}6pRFi*wAOooXJ5IW+ z@~jMhR$4Zv-3~(&9o=j(?m2MQv~iC#n#R?|4br$xC1^f7tbA)@1cV&AIe!R8;lf$* zgbce%yujXnVDu581?>i>}3qKYYt+#RS3ND(AHo#u{X{do4_vQU-6Gl+&yj zo3N*CrLQ5l1FLs9%Rl8WCwj$iGGwOIkj_-)R1hhk77oaG*lH(L4KI5 zQZ)*{yEPeysL1fJ`E|?ncYVP3eUT!^DjB>!c0G<9tUyhYxq8c8es83ZwtX~fPz^t* z6mN?em*K6}+6@}1EckhuwAy`U5ahI18ISHSL5YHNX~wguz*~Dy<+R}tkhwB1=4jVr z#fiP?%CwHq!sa^l+eJH4cj&Q6KDXIJ ztQO(VC$2h`^}_6AbHnGLa4d5>^|IW$7kvggzf%hpfy5b&HTwcZ%s;iR_($FkvQ>um z$vfp^=lo5#H#b@_^FABh(ftSxL%%L5)%9alQttB5z9!H(Xa7<9b^+X~y~F6@Nd%3S z!W7kod*I{y#}k%)X=w7toVwv#83``ugn?bCEBZNoQ`EmZgTd1)7k{!4shFEbAM^a? zhM?`=0*zhSI4l0f)nB^`;=hjSDisvN(C;zci0m?89iG{UFs%oUqRd2YwzMs`f%Dl?mzS6h+DM%*#$BK5b!V5Lv zpX4@XA`!*lO{OR(Z^2j)n^JffwWAv0*iFh`;*CJDv*Y{`uQzxzOvlT}vmFoav$Okc zH3;liX@w2eI@*M;u3;~CAgh|QlpKp(rmF(IMR%gKkc93uXt9*$uwA5}e1`7{fouT*s&q0WU1(|d)bISJ}* zlaFRYb1<~OGBoPZE&$0TlWuvsOq6}H{R-1sRnT};ouZ~MI5+4Nxi*#?DzU5c4H(R9S2N?FtIWWIDHs;y;`)X*qCuDqbsrj^xWl`gQ(@eC-k=p z<&#w0+(VK`cFd}UXQJNUCi{or{DRj;+{YedXb^0%d`t9#r1f?-ELT7!Z-sl$&U&0Z z@cG^l5F5dx{&bgnl1RR^&AZdvei?*xYCPeH*a z`!MlP0(-4@5rzbRPob$x0%HcAqeI-$m_3^RVNSLOOPQ!CUN=^QknW2!7Rv*0kp9QD)6JupBA$GA;7l$Q z2mVWVq+SbAKkI3mJm#SPXQ^r$AxQRNMKDkk{vQ#k;k)uwK^Ue|KYmE710P1xa?I<_ z5tWOR>|lKvjDC{dv8qrDbt|)XUL=g*^t1bFKNR{=sru+ut~-G+R{C^00X%MR2ocVjZy)k0C#^xoMHOy8DO--=5LSFmo zQwK>KU#xbz)`KX;3)n0wMn!EJz0O-jp!4(38$p5#uxI{nM|^7s#vfXu_gF3kr5qx- z_NoXLPM*9LuGNSf$}ug89h30Ars~yQt}J-j|D3d+k)seb&OGPZCQK)5Rg%vRa`!(iP+2-oB9)r}j3LYt`@A=tQPKl*yHC#R|drt>Fh@;W8hE|>1#-C zUI;`~{^%C`TZ|(W#X|QFH^R|~e6E!+G2R6@?+R#3HX;N+QjinC4PV&}2#VX`XC+SrwC&QwFcw^gqoY(5{ZXqt1I<4w_AbVD9rb~Kq9mlp5H9wE<-A-P2EXSe-8khJi1WRfKMNm4P#h2 zHXW{S4A)oruDLcRHVR9+BzO?W$In@S2t|b?jiPJFJ&Go4au~mPofwFu) zVnh1OF}QkDkQ#hX&r?bGOe zwa~bOwHCgpIJ!{mCZrgT9V8E(KtftM<8X^<<2f*_Y}Lk!g;--sOznuS5O?I3&K;C1#|oI{4t-2(h_{+8$fz^m3H4o z6JDDWF&v{o{6L=?MSdR?8~$vM}r^aM-gT!U#-W z>JJ8Qmx8GCYri#KL)V$!HwIPS8~PHZ1mBbEt_MhSyfJ{tpR-ll=GA zz`ey4$bNYBmau6lifbD!em<0jhd#Dn@VOEKDig)vNzK}I%l zJJzCQ3nE%WZ>ORj*~r7>Dsise9UPb3!vR=|5$b-$JxjFN#FpsKSyzZ!f782jX>G zmdOQ1e~9mXTIANB08(UokLc&#bF`Lk8fE(h8C3i}vFu~#cN!xLP|9fQj zVP=(~A&64BV8PJegO`gvrfR=Uz>?|w`&Yla!7t-KTb`YbcyRCu)!oV@_}F>wVcSA6 z^c}OG7jm~Z3dh9Nonfy?`b4I)Xydd=;{dvtPnQjE5vo*2<2QYeP`%maqf@fsMhB!&bZd7ylf+q zr#qL+6DpzAOqHI~q#yheK6p=54dRb0#^2wIH^AOi8hSpnQt)1qap?EZK=C#>DQ-d?&o)Iwzm#DaXQ3!#7`lbvI)==|FGuPM#4MS)k|5IoF4B zI)az4mzH3w?iF{|k0lV=G5<*MP!Y07k0y6Aj-XFVK~rzQr1{kTUNk8A+) z7`q(S?Hz+2FU|fOD963r@!#(XwUcoFapwY40kmY~MH069ajaom^si1PrnH~uIjhr%n*%-1cjos&;%2BF zYd{YCO%dy*&TherX9sS-B|06CZ@=t2OZWqyzf^fLGS`NbwGZWY$&)Ja#V`0|IN%F< zocdL#DAVxUAyzIQi7aeQYN^>*s){y8?vD7qs)0YL>cPE)^3gGnrcc+D0A4#&={HBy z(eo0E2%|gk#oi_S9Xy?nhe--MU(I*JEg$16u{(<3hcDlaCnh6k)Vbe}H7OZyyWikQ z)^3KN<5dbdq%YN&DA^)>rltws>*+bzviCvQ(;DVLjaC#FU}`%*&<=s$N%R5z9nkpa z-RldU^}u$Mw(fXcA}U)bs*O{$fr#{jH$}w(;9x51s`{n?l;rbQoK?%g?o)H;nc!Mn zoJ|=YxY7d=f#>(+(G`HH*Lf3T@-Udq?Fb=l{~192h0HtAd)vX~M7``I$vXIyrg$Ta zuvXa5M0oh>WTWJ=$nCZt&5%f1lTFm`2LJARVKcwl;EjG`nXh;Y?5N2cQ;+P$`JP?> z>Fv3KJJz453tmpg11p-8nZ@NGOA@Nu+gbJ13)C)1Lb-{RnCrSSo)f9g8 ziFXV+NnkiETibUYD8und4yyFH3GCReSeW`&k8a)`%P)!ORIJCzV6&6mXu9{KNSSmY z-WAVV|b)iK;O+^{yi z{R)qleC6~b6jLI9_UM7+4uW=NX4PW%ybcR#sLqT(ZAOm(+P~4&1W35_TCllp54>ZR zA9&V*pmfi;{Yuy{+PbnF=KfWIGO9nzQhc*f)lg%(&$R<(H`&IRnR}6H(ktT4@lH^i zJ9jRiEf9Xk{4;TQTMw1YCxZ)!Xt&V!Qz@@DvtXQ5&#HHCvmL$mzx%0s;W=D-kf)*{ zTaWQKnbfG`V&JJa%ZVqg_3-7-PNn^OLSf?C!V-URHbBU!=@;HN;Y5_xGZ$teHP>F; z<|&Yc<*Wu$i4pm5tYrr$-zQ@0_0weMji@2mlDks8`3VqNrC9AMVjJ=6iK-akc|{Xiqnp4|IX!ZG*eEN89nATh}8wkqF#zw%8<^ zIth2D#J2W2)u zy&#o`gU9{Gz}LE!cy!l{cCm3UJaAF$(~->w1-l1({!>fBW(%7aISfTeQSEeljJp=Q zdzY8oXzB>G%6qcLP$<~do9PE>B|zzo*?^n#HJE5o$=#jMh#!J1glOry!2OG*q8X6| zTdxQ`Cs7`NI?llqGzW+A*=y~yq`Q?h_+>oWDqbU;#gufNO1b(Is;cWoJ^xQT{P7|!0|)n-do6Pv9&j%k#(=ohTDd65li}2R_Fe5#wYcxh z!TOd@iO_t8LzX9$;03HjOSh*q!hfAE9XPSzYFIr4t<| z#+rXDR6<_2U(?VVH~9GF7MX$)QJOC6g#N>F)LHQV7?)Fu{9iKkWAz5`Y~SI%2ONlh z#7Vd2w_z&5fKVzY4SXF0GwDgrkESUoS*kK(Zd{9fQq~~}%5%6q#F70*p&rQ8&x_yf z&%_$12W`)bYau~wAIGos2;6#gty5yX9jjb+8>+<2fX73roV-1K@Ny=Z(xDN-Cpd(b zn`;Icek3ee@Q(wdMeXTxJZT`SyzyswWg3%%c}euAYvNI%+)=QlKLX?^*W8NZ^N|q@ z7-R$rFs?RV(NsMH6rQhF#7)u?RLriQi8QtNgn~@2a3X zlKcDHLrtKgv7Lh)Zd+n3e%12`wbf(`kk_!h=DOh0jWL7gA*+nmu z9y)|K+T@OCy=j0#k1olJ5d%=4#TId5Pb09DG5g(<$%-vx5LJ@I$#!; zHSy1<4nxp~C64f(PLqzh9a1$YL*@pzi`VxT zuyaon1FF@dz1`;uuElt)I#;^T-O>Q96#UM4!i3kG%ID$$Um@zcHydo7Xvb5%2kvLk zkn#LjyW=`zA>6iUvwTCL*)6VLRj z%ntfixc~WjLEHX9yr09lm%TX};(1M*)ep=e`$@n(BaB2<&AOyrf1HwIx?x*SsSTZ2v-J{$9SD zfODdDBcvOIfEYKGpF?NV2P(HtKWyzLPaPedH+RhSqI#%?ml^dCLAth-Hh1n8w{L@9mXTXJCd@% zKd{zZ0U}#)=WbgFtbJObyPX^cY293;Z(QGtpj@bEL-bn=mg@1AWS(z>zQMf2ON3}_ zoKg`i`?(Mwx+KZB-VBA4)6suN{}mI<@(8ON&*=ZJR-IeJap zh(M$2oN3Yk7`RCXh=vs6UV*(UZ?i_=Viwcu3D!9^TuJ{-TGj{g220Vm zpI0k@SKi7{#QYtS1Ae{|^BV+KrZ1vF0!`>>^Gh=Nsw=2}oqO{8Umax5xO@m-N`|8% zpTF%|R>uay`HyV{b?8vF~lTaR;tHuHlC9| zw+8X3)413#{w^$8uo{0PQh@IZRV#ImbYPyc`7syaHq@|=VOJo6O2(1xPp;jm1`Ykn zCe5K(Xg1MYdZ*t7_gxNtFHKB>@4NM08Y*=l>7SY@r!|4qV7j*Rg$Qj6X!~&K>nQC>8B|QokNQWd<;cCKciSe_NHAbj^4wV@1gO2z%Wn}n7e0b<`? z^uvqh-)1Tzw@{U_C96$b>F=ek2_>-Q#aP*yuF&88R-ep47M+dXB@7<>EK?2!iS@9 z{Tcr$qZ|F0+0MS=7#a!hUApBI{D^rzocs$J#Aw#v=SdFskDFlIXD;&K=PX!eF1j4@ zD-hog)Kv#@>miqq=hiGY8MHWxHqA5gVYfjsjo3gAUbV2_YrEzL-KOtnzs`4}_>1ow zr0hLj@OI|~DN%2P2Pa)W$H$E0iRBExppq)A3p=IhqZ$d4%P&re?X5u7QjP`7OL_R~ z*biOJSB*fwvzBi9G32?bPmWR zMmP4z(8mN2gA6|(IjT(bkb*Qw@?Cj(*m}a60Nmw3K=-xMm}p{BnUGMFx_B8{nZ(i1 zkkat4n(3E2&6D_qStfa_X#%*oW!7~0+Tfy32B#{~<1KrTo*s9%7c0KG?abO8g!^4R z&DUs~VVxYJs@d2Ka@aNBo#B5NpGp zkGsC}y?ysz3??;On4eN^0U^c%F3-(+z~@wjS2W@ONfS8mIlLqk{fYF(MhxNLzm#!! zP_P#CNx6jGZgUnrD;K_KJS$~bUrNi17SRKwHe9j97$7C`Bp5VH9B2IR9! z`WM8|4x+b;#ug;!Fv*G6hI%;^kCd$BcGdM_USUt7-iaX?c)qpq(x?@?`5WfOKV;)V zz2bJ0@-&d#d&`UV#GyA22YY;2Ad;pdg%MM|?2 zGU)UC=ObmC2}`mC>b5hTD4gPagP#~W@!8)yI5EB&zC8Qz=B&#E2~)i<&dY9BpqTXj zNrhB0q3iWIKkRD+4YyEr`to?7556SEuHgzho$pI3OK*!v$Cp zFQ_YC?EpWe^h@EibIylhwEWu2X`Lwi*ifPx&0YgR zRQLEpC`hg7?Cj-!#=jajv>RG4DOclzf0vYpk_l|?9d}^zbHj6vwat}bkzi*hY**`1 z3kp`dZMcuW1+_({5=WsJn5uj%u_{r4BIf&lCpV|zcEffFURiE=C-Ax3MH=evTly1n?ci`Q$Q6q%rPs$99dIA-- zdfy>ph}03gpO!BA`Gl3CX>(s}C|d56Jz_vKodhSP?2T`y0R7eU$cXALczeR`+{0)6 zxb*ON$OWTrm>Fl8%YRt_(i2y5_$0fDvv;JrMdKX=MKWC+@@~fd6S1=-al29U_)5~@ z=xheHdh&k$p=#XPeAq%_o&`5MGt(30!FcAiOUC6trFi~cz(?=(aZIb#lf2^52og!N zcAQ@c3}?3Q=`&~RAlx$M2Hn#U)MKKl95<;#RG_8Hlm39_{XNZ4*? zGi}^scYNCN<+@B=8$#MOT~?(I7`$jCNa+*{ta0bGwckDjxz8+N5=1v!s~h@X7sW%f zYu@tepAsC~b-<#dfeb<9o8MT43xV}x{;$lTHXPf{b$)Cm0AGFTRAeAT?NXA~(X~;T z_n=Wb)pg@S6(*?p&Uf+qq3~G^g+m^(=mxM}Cl;)|Dl|le9)k@%LoJl&eQ0eX+mG^~xGeQ>D&&q(U@N^tKRVSqI zbbYs0YK1MoD|AzN13)@x7*cg>iwtL3kFR%&)*}n2lD%GiH_G{(bYphyhI^?KgDt1Y zII`>WOZS~bfnxK$*Ppu?Pdrw5Rp3v?7@Z@!?ee)WzhnPctbG&yMvr5Uew0AGx_ZK! zLtSXmrxoG9Ld1IyXZ%(m9F~9I7)OR_E}>Uu*UOVb#QZO+3x!m->kz7LR4y}po`=y| ze)iK_2z;+{qIHfFk?LDb)ijPX$gwD>7eUtqj`lrU3G#h7MMY;-wXq1Ahkut{>~AI< zV-W{7SiA7~f2eo*5;1(@ykO^W3ek%Fz3A9G)`;e*76QI%DcE<1w9zF;46~u4eR7zO z)C?6jn-;SDhQMAh!nISN8tBXtIobvq;j2Ohy~UXUT-t7AEZk2doi_~=Yfq&i^+>Mx zZbvJKj^}(>I1`4hPV&E99%Mtc*d)&aO*(|1%&fU;)d-J{AJ}u|Fc~z)dyv<22zVI` zWhMUg!bxVjT3sVDO02tO>5x*J;nod5z9&Y+EVjLRFMrTfpceNP?zOW-3bu$VUAegf znuz$|`wJNmF3Y4uKb40m3LZhEqGmL$vo4mr;s!M3k4CxHa$!jb?1wLw61soNnXu4u z?0sroXcpoHY8Q@K9dYXhWydIULBj~Nyk^>3jURDF5lc`J&ER2|Je5R1wsb*9)&)Wd>op^WTxH*w9C3nAZS;7bN=4nvaoA-t2FK60H!A~T=~iv0o`wxPk3z*B6Qj-t?Pss{U6PsP+nyM zDw~>lWo}pEaBUZRLg6r`JigalDR3X=>l4Zz`{ZCh)6n-w%Tz4-YStE|Sqg4s7gC9L z9kOZ8@eWK815OV)co-(Mz+NkoCpa{qW)?CZY5G)37p_K+XCG zjsK~PLF09K&mHr%*u0wPX;3@{)}eWHbv0GEMsFRrP@aPS*;TO3?-_@>1C8=Dv}Jhe z>F%}ig)->>!LI8;H%XN5)cW6N%khC&^g)cNgPnuFV-1Q2A&11h=OJ(EeSEto%>Cy*J_ez@5SNG!W7Xd$a zTXuuu=XT8?oe5MX1|S$36yoK4r_}gYL&$&HBHZ9g6wD;d49g`KqSN7UjhbJ@kaAk+ zveG)i{}ny9@lS}R7?Ny$vMc;-h44x~j(g|Z(fVcT58<$UxbJiOha@q0pv_m9_s&cY zjCUVX^b(3E3Kd^#Guv{Qi1ZOV%Tx}B71`83j1;1J--(a+3ENjVO108Ck_1`bIQ7rGBWSc)$waQ6uvGqf3G9_*FulVa zxS~dwN#7f?{&`*s=eLeqety)B?-Lh~oyeWQ>6*Ql6*tPD^uwgYl#e?E?QN^7BH}h* zD;n>!TPC8V{fFQ5RWD!{$4*5|On!Fh%QZksy+waTl zO~U7=H@~oW#=y3jSFyN38rbS&-E)3V#^Kc){>@UvKlAy+`~Tchz{u2@&TEJa*>%^~ zqYe#W-qxj-DZT>O8SR>>8<+qOu5PVU)6WBBcx;}&8;&aqKmO))6ZwGK{crzQ(Rs&X z{kCDak`PL%C?ly9mHL$t(M6FWBW0veRwN^ZqI!&si0r-h-g{j<_THO>BrPSOLht?l z=|7)meee6a&ht19ZmxhcH8uh*&C$3T@rJTM`JM>b8UN^%YxB`QD3PTjEe3gXmoyGi z{ZKER?PLG{zXe>Z&!rE?;0?k`@l17t+pD#4zc#mkj-#_BXp?o?{h_;+pF5%2jhjwj zx)14vc{d4348oMOg4oL)CFtyYtwBw?8o#7hINH#*!ySdKtT)GtA)__(3&m2FFj-)K z<8n?H(u?i1%WQZE2Y;_$>t~HeKHVE0GsNMv9yho{m@@`zZ@9NOeju+zf^FzhFoO9u zT8)|at++YsbPe6{=YYNE?ZH{2(b@hSe3oL8ke=KfF@Wc{?RJt2Si}wq&>t%Ex8{XMOjlbj?;2 z;rU=bd8!QK?(L5>m9YZ*(6gvTf&^4=lUp~t$U|v=(U8E66!c-@;>Sn581i(xz(yR! z%ZrXq`b7m0c7y%RwpdT-t?FK&c#mShmw!)>{w%^hM>NJSe6Pfg6iV&-jb0R|j9C3? za*6`0i_u=ixzRwsm|?o&+l+@_O+b;34?J5|lzZ4xfH|74geW!*$eT;up39N}Kc;@U z^c$C$Uo5hJ>4iS}&b{ZJHbUF+@c==; zOyp_KzQJ^F7M82N$Q*g&3AKUZ7BZPBWDt4L;M3;!6f#KIU^-J$iFa&Q)|Td}FmN&4 z=>_c!9zS&ZR`7pCIHv(`sgIg5(~{m6#b&|t#rVn`M;AD12pHuJ6@tPimF1gqwcxJZ z&+%V%6VmNm4T`xIPQ1VW4c=17#sj~?CtTH2K>NP{Lj$QS=%PuvV5QNIZ!~s%<{YEM zBaQXl&97;TQLxsJRe}%@jkJz>38)Ymov5Xr@T)w0%OUlOu`C~(d-serKdXW6Uu8Tp z=EUziKB78j9SuEw24xw0JRmZbF4BkgAu3+sQ@C;~40DTS9|~L{;nQl}xO1$vNPkA7 zPGqSYHnAyLG_*Nj&AYC{Arwj}7R7G*YVAJ&Gn_S!8t$>cctt34RV)g39}Apy=xp zhGM+GYcH*}#{_CIB+qe^uy}qw)nSxathJ8(t>S6#!X*0T!(E|yxaja7=hZi_@szKb z!ohwbDwc9D`;p>?-`6Or?_VVX>$d583LhOntMo6$^~OGEZYmQr$)$xt7D z)Ct1hZ24svb3yO;%Rzo!Tbz4Oy~mY;u-FX!z!yg5?iq(3Kn`(fG(zi5kmg)LUJKzqONAc4C&5(9SSXt9`?2p^8CFNVwM*v7#Z9NvY*MCUNE*8S zOb)FxP^ZNk$!=4cNWXS4zm3+jDgmLlea6OqVK}jTx9Dj^ zA8y^hcZryLAfc|O(`!oxns;~yt6j{Y;0K#lr8ifd@aRt7+s%pX*ex6}yx#pnY!g@{9@T|JR*eQ<~Il z0t>eso!xCyaOxTd@1a9U820pq&Q79c3#?uELi=bCw0FE~^FQH&SBEU_KVq!GhL^6P zNfu5h{K9ZIJ+mi{q#}=56=BC0Jl|>XqX%xe*c>X!NW?sLS;Nom#bE!9e?yl;7ZiTG z{IjP!21>_l$9GW3o?f4BWO#Q7V0`4s;3AP$5XgC>Eo7gM9Vgi~K8@+ah+o%+XLeGN z^W&{fGv;=Da6ZuV>8U<6PiHIe=t+e0;i{s7zAezDVdU~LuLhR?sl7ar5P|&1RLu|c z_`$#%cFGNcc5xlP8M{8^f-^oj0>xSJIP-Usg~IbQ2X>97L~~a4z&|ywG0EYNaL%LP zV4Q*!vfN_7Csa|7C3g?^J!BfhCj+JrDql3i((92eue%8&?t&$4K<`K73*BRABr}9x zhAt2DR(Aq#JB!Bf_K(nf+$nrcv=gL9x)~Za)u7|Zar64W%~&xaC*Jv@1=|!eC_AGj zjG?8|XVt@~3Ev!|;kNQ6W}}NmxN#%|xqe@DWcLpR^@lsn7NSSNWZB@+@?0cwLehTX zzLkN8WCYVYH>RR}WZwsEr4ZaXan5B&ga@b0C;ZGUk~UD!LUNgWzo|4IylDSu(8Fj9(7x*`ew=LwrI#}(dW@l;1jDxr>DN!e5 z^AU`skGp;HK~~yliD=Ub;f#zA@Ig8V{wpa+ok)PKlv(H9CW+OUuxUK2POcpur({Rn z$;`*rwYGAm3zfK%5fg160`t)e0& z?6jcuZ3$mQXR~|O50l`C;mEp%V=)d$o^W|~I2*)*sRK8}o)7`qVGS12;r7l`I@SGy zijv!?vBj-s0!=8+r6TWY-$ucrhf?_`HS3{KS)tLTCmxs;kFtNgR0C629#shCmf=e; zmxSnua%5QKt8`c!2AX~@dH%Y7?B#j&&UuB3q3`SHLrAkx*DJiAxxXGf&ZZsz5KUrv zB^KhUH0^laPt+~CumD$=_CJc?Ig8E%BL*exF`#<%E!U@9N;!yJ`bp3D!V69`YJFZN zf9J=RJqjHlrEw|Y+<31Zd@QMu&vdSesMAL0`P^L~dz*l{(T+&eG}g%ogBRFCRpGen zUI?PDV#VScI>5xl`ou%0CY~T!R>r@gLm3TIT1x&zMPr>(rO1#^652Z$N0g?f;G(_vd!4Fal$+l>GryP* zJWr1ejOR4KR~zvzh4p?|pm-%w1hYs|$_jExy$m$m6F3D0y4pdbYgI@eFik16xRMNAoo4J=b+zDQ zG7=*@l!k_WkBm7})6ipSi^SKDBs!&h=K7Ri4xHfHJ9o_y@vO_2jFp#@c<6>yd&84z zP^ar5sWvKh*KSbnAZ<92XRfK|&h)~%ibRu3Kt29?uT!dvO?)c z^69@oG1pS89l{dM=AS9rZLnYNZ;Hsz5=dm-60#as2MM2z)IU0s5?TL$IU8Nt;lE=C zY4`n1N3MyX@v#hIKJ*i7Q9s;;LrxN}N9vtnuUB}3d&UqPbsP@nPydJ~4=+c47#T+w zC7N)TAu7hwUKDt~Zw!`OgLKa9DS;Q12uA*ul`4F>xVi}Zx!AA^g3?_Y(BQgKf7(l8 zK#1rHI!TsP@>}aB&WPjz$K^oTZ>N&sB*n63Dzg?+*S>b8^pb~7(R1rhQe*}5B&dQd zx*hl*?e^MZ(Fi$nsZ{nC2x%S-md)%4vmqB5?%c=)#zSh$DtC&I(xlKZIl@M$_VLC> zvsxuYHYZi$?OBe=9Y32d%=ZvauY=0$g%ms=A|I+?9*T^HR(f4xo#eXBvSrT&5?tP9 ztjk9d6i)Z_vUnB=(^cWZU9+YXVr4uvUZW+!5MAcImH5yS^V*2i$pAh zC*9g^)LBl!t>)Ly#T7)NS5`2EwcZmKHc!(xWfC9QJ~!6p>pl4Ncfl!@Tb0P6#TflM zvk$M|w^tE3+Ye0>c?_>ii{a$H4@w1k^{BquRMwzIE+lH_wfEDcL(oCR3#zsx%sMH1 zgZJk<;1W8oYGxCR(_-B1QWjMZQqsJ0yBx&_9LldZvulo zgX2P3n#vSe>9)H*t56{;-18fs_${ZwmDep>@&xKI{pjOIZAwL0e`BweF{QR1PdPq) zy0oJR=Y3;2oDYrS2VQqFsVTrqO7VA+4%R?}clLEon_5UbIZ&QLuntSdDQopJrT8zx zigCr?fyC`{DqG*x!}Vib`Wx&>IYm*^?erf+vwSJtjkzWG$IOIXTdx5d(=g+odJSAs z55K9XO#~#1TTf87s?9=3t8P=r!XVtZ@I-R!wnX?UJ175Q^CipvU-0$qo)LU%8O=jeTntV3auNp!z_6p@G37vZ<|N2X$?cTZEC$(t!X%@G8jv*4 z)9ogN(&C#k-8L2l_?woSX{N3kOqmvD48lv$>DNk+!(%rzTil(>|BCQDuHEvt+Dxu! zL0eO32HoMZ-S46SJwnI7*yU&7mj`p7<8C#+O^57n2jn|$X91JNGt=gOQ=nW<(S6-R z_Iiq$IZa*`9T=-+C`zv|jn63%Zl{w63;*?rwimXb*q!yISji+<8_x775DrDz&m}+U z95Z1o!=rrZPZV0#XRB=rqQIKu#9@2BBvg!C{$+5m9@CaD%*L%d!ext7`^Lwr@Xs4f zW{Z(>_|kB`THK@!KT_xi9zF7Jg74qni5Q<8h4d>NslxxIfxs*$V?lQ@sBQ0?;yCMq zg*y&}Cy+CsbYqIF@n8t@jY-`5v{Z&mdDGW6(-5Vq5TUc&jDy6DIrl0*_ zc8Oek`qA-QOLzdhRaKSHC;4Dt$i8*&XdRyZBM^N5HW3uEo4i)P{1|RFtVFq|x*@|@ z$Hu#Tc~H2|cZXd?CsuUsOm(L(gL5Y0$M=@SBTt&{nRqvE^vIr;x%fH)H9|xCOt!RA z;D++$8Z+H)*umPC9(_L*^VK~PX-P>$npf?BFFWZ4x<&N_WRwGQ>gs`4s4n;qd z$?LQB~`H}}PNppqs@4j%z4qZ&orKy8} z0LgEq-)k_@HYDQgg+d%jHmi1i8wSo9w}$>^SHKtZAw8+U9AJ|X_kY%w0}nIxD=$4K z$k1Q)SDuqASS8P&GjJNDpZ#5XQTv~ zBfs?r%y*;YXFZ9|pb}UK-tpF4zYpdOjrF)9tD!W4Ke6CXH+X&j@2JA|aggxjZlsl} z2UZi;`u5r?$V%Be(zmY>zN%cKR0<3EfZWw_Vf#I#AXFI3oA!xHWHI`xCkyRCAs|=g zLg4@J1!bQq>C%vO$VXjr8e!wYgGdJMWLRGwKkYo+4Mp7?DZ!RiD9@ZesT`J!PfItL zzq9X$^MSS{9rvoS)3!O%o;eWg&(43Vb;yC_l$-6vV*y0%L|NKcQ=R}$GEqGZ8VDgc6=+h9PR%__LCCMyReD=YHh& zJSwln3&&da9JVRMxjvPi3yH)9XD8QB=a+#Sj-GedTgZX-;|{+61ROxtliO25l5AG4 zM{@6TD~7|h#*>HQI+3WR!)2)XNEy$MlyBIZ4t&naACkxkCGU{s`@6*9mN*oovt`Z$ z*x$5z@JuZa zoc$CPueOap8%AMv4sV0>H%Q$+@$4~cKJZ7`E~a;sLVo1eA98^OsHmRoDO^Yeu48jP zG`{cPW?|gwneFMwq-itQ&qr|tMGoz?w2w8{yo3yfOS*3#9y$JILfiA)w ztkwDz)d;Q9%#p>ib?C58pEydM6(4PjY=f(6fGY63?!`Kpoc?Eg;>mqPX`Lbe+-n86 z_=PFVz^4oj&2txg2qszY_?3UbM7{oA`Ao@b)Fd>7>@Hk>;f~HoX_>8{-qdx-)nyc}ymS(swK?Yq@vE((PV>S&1Pz_c3o7U`k^ zLeX>IGk$ptO%-Eh=ytY3PkCML@uR~y>qt4quPPA(1(X=k0r89$Klw)y;e!ra^dxpD>etdA-Ga#lg0LYYr(s1 zI+Be=r7-mVQL|!I6RtgE6;|I@kFOM-o)gDCVk>dq1L zO6lW*%dTCxS2%9DsN(-7grDZ4B;|UlUBzav3l&Nk!s6??+A$*Sdc0a~4er{Hof_JN z7w*x)tjXAd6zik8U#ItGW7UUEwxXTYfCc@w7WW&F(Po&>WIC6uPCp=iRQc6vt2A(@K)HF^zna5NR!d9eburC)fEq1 zc{xXzkJDE!ezS;$f|Y-C4vuvY?ch+7@qhpC!OeOm>NL%`ZjJ2*cH{8IRX?mQW)Qd1 zvKLM_58%JqEuuLK&8WxqF!aV@QpFldDA-Sm$?09E4=<9+#@ww)rI6J&bbZeKyP~-m zf9mcrGLCA2f(q9^DiQ6FDt*T?@=7b2#Fz#hi8V)kv5MQi!le+ZYI!Z@FC`!QE^Oeg z6>Em8lDg6E4|-v2&W7$iAt3k6F|aJnC1W%P^O)2DQX=QwFZYqF4B`(m1poM31%YFS zV=`??StY3aa$*2+$gV$I+sqyZTSAMC*$Qj%Q8yz?pi&h&wIqsBNlgEs-l^nggNe90 zVJANP#usi?c4Y)nXq!M?r1apy1FguqWn<4X^HFTpSD%tK$bz-JnN8{n{kT$-#dgl6 z2Ol06`!mc?3F%*lBIcUXarc5=`?yd8#0MTTm9ox2{ySn%zrQVjsJC@4Eo>gJ(vaWO z_k*xt8fLje#B0g+JorP{!B)^_I^tz;u^5v}(vMI+aRh+i*D#;kBZxgd_lN1Wk*Cu2 zU~@bDm#`X4dtUv?7-_W(I`02gf(h{oYI#i6urjPd_dxkA+_(C4G~AP9$JSYoDhtO! z_@lmooU3gpAND3+T7in29#(xlxt@(_4;ZvvZui0COI|k^EK^~m>&qtj2T`cNbciz6 zrP+_OrNzsehpD*ZqUEROB93_B()%=n-vcm}E?MI$){HR^ET|kZX}B|QvLb$>AIm3c zY7T#lMddVsUp9IH5G4>I&Two9&gmH|y$^hXnqN22Pbd!Ha>>Fz&VhKW`l58onWYpX z?0>1Ua`(Z9AsGv4fl9P|L}`7|9YTc{*?FOkR(+`P^a-W^Y%OLUzPwC-(*=)lO`g)% z8UTUPS}*p_66{;OD<+iC1Ud&DWSuUOHVc(bZc|((I&tjwHZm&$r%Pob^zH3vLpzz{ z=#qqQ_Ex408a5-_r3)rvlxjHiGjwYtsbtVSO=WANCEXH=`uW2`gGDHQJHs|Ph;YBn zCgDzN6}S(jZQknN0^AX2bZ!1P!uDGn&u?D~#YcSGmzGEy&dkmDvyFH^aPE97{+V1f z+N`dyZbaPZDXv~{*|mKo2Fmz#KXHom;Vg|yVLWdaO6pG^W^io=mqr_vLqOC)`jJZmpsQ*~n;KS(S)%$(zsXybaP0fO6ZM1WYshJ! zb=wCn2yV<5qL{m*!Ph%9D%Uz;yYaMMrF<_ocRtA%?Ilz@e_f3U)dmzhIGz@^DIX4= zJaj3$APg?F(#w10roltOFHd+lQa~L=?9cp1FnpQOe}aX2VQcquOZmMo(U><74iJ#|=N* zAg@g$G1p-dX3l%FAKje`a*U2TS{{i1k|Ql#Y)L-wwZ+Yu6EX1My7njEp9L_^C6S{) z*aKM!eOXL)L7<&Psg`F54ZAcJ2aJo6neoAW=AKG>)V=C?EXMx ze6>_meK7{ao^z{h`&$HeVy;lG}j z&TU(N`WhZ&cPZ8KG=aydq)0WEUgZ7br0uHS3ti5u&Q`?tbA{0$XViNLv@Th)j(zQd ztmA#FMiQxD!pM@J6rK+2n|bpOucm{8=BjFuT|NlVrN>s-kzcq9Ba`PpT86=@E=a?4 zHWv-f=qrShr(SnWm#wsF^(<{=jjr)|G)oSH(;aWRj~k7;07_blw6EQ#Yd zN?tof85_W*J2yL*t(;-`!Py;c7M{>}iB6QVu?>n>)jtb=uf_8H&(*(nw81~GQ;)81 zAaqO?59R-4t3g4m>z^!HI12L3bKi{W1>c2;@P|}8j2qi+yIb8Ec-BWNY$j*$+PG@Z zdFNy_e59e*l9h{o#*HuRJsaUaxhK&S&e3l8V#I#nRX{a9=S!?Rs@?$k^p(3$<>o<$ zi}<%hu2`aAPN@0uBM}9v(sv7e&Byk8i}_E!1!1G_4f+4P2`!_4DEfoh7#5ZX{D;9* zyyrW;?W$-1#1`3CsV)?tjO*@ip?XAeZLJU;KU58G)7Q5AHR{AAMJCGh(aZ#7w^Nc2 zch5o!XQ)udd4!{9vN&>T65wHz(EZiCVz^%sBvfKM04*zJSrOTJ*y2(vI8;}RiMu-o z88?;V$K=de7Ku9aJ(pwk+0!5Sx$XWM-tEItzIZ;Fk7TRXwz=oRWCd2nJr8)SGz_dP zD^BJNV|e8UWpc~;#ZFYcr1j+M^B%~s*{Z8FHvoq!UbN5s9KhAnH^MzVMzC;3OPn&_ zftzmSowH2nhLcSV2d*2|qRQ`&(Z}f9z-jvw$0=PG7`Qs-6I4G0xqUuQ-9y^ZWnj)O zf3X&3oIm_w6s~||np0C2{|JU(`Ss$D&Jx&2@jKL`awGzc98|T}w^U&=1V~uOT0(P0 zvWejDI%pI2v$FLsfT6+r&eiFq_{(2~?)XAJ9{jvavun~6-Hh zOv@Ador1-VCxjd}`vc{sX655w zyk!`>;mqs!K@0pfd^TjpsDYe{1$Ay-Y#@hClgkUKL(p0+M57ng09{ct5(YD*+!>Q| zS&6qB<%Fkx3$G-Blb@``8)v@M$1f{Et!O8OB$jo{*k~gwbS4J zObN>GE8Fu}s~0~W(+MhP4uORST)ARoq+6=*^tWq(GK544JLrd3@>vbD2rJ^r zs^YMe0MU5AnR}d?%k{<9;OI9C}tn5z9r;oPnhw3LEv@|Q;!Ru4|6Sq>x zMME5R493{?;of6f1{FsKz+~i?rKo%=rpMp&WtMgTpTsGND?@p>YV^e{zQz~nPsl78 z)%%0zPS%@jcStl_r`_adOD*jE@W)M>p$InLi$Cl4sR!Ftt=UpS;^5>$=rbmrBD~`L zAN<>2jZ1>;59O??p|QtdhBCR67>Rf8?Qsw80<{Az%}r!3FFomEz&P3qQ1L@EDs~jk zTFWbCFc$&cZTkCcUB!^Xq(BAXHjo{9dq92m-;S4FmZJ zh)!X>m?bNqe7-=M*sFMr2H`zFQ9dj^m>kdkCW>FPvR(sD;zMhEV%sB^S z64PPY`dZFAy+%lk^6$13E{Dh;OovY<)FLf0!zeGk!-cY4yW-WgaAW=%^_{Y*_}#tC zV=X-mC%zjVITsvD^ct3)I!V<~`T2+Y-m~Md$fC1dMy41RVst(pO{~MT@3$Ci56qwh zBc*;&-ti64i8nj4$A@4?OV(P{1fk$u5D0X0DnJum8J(&hap>OR=NuB+2jMS|PZeJz z$)?crQ)yO2Ivtw**=$=O>3|C<@yhli>mI#rwG~vLUK2DeBuvFDmbOn<3d?}=s;A$J z*&3%n*ez%J#M;s(crV1qEP~4SikJ|pP+RS#{QfL zazCAdQ_U7$^wGrS!jN*WL@pcdS+}}AJ6i}j#>oDUBN?39tlY$e2>;{ok(Z|j>o8PF zK2k@Z1Qx&i@jIcP3S)yEibdzis8%&q+0d~YgDkfl;d}oOC|?!VgjUME$a>sP$M=s*g39+emhV8VTrB{H zRjJSeR#cGRnU!#0brP<357+A?Q3(6db&@Api!6_Bp7gDECmpcO%H?sd?q-S$&Lwa8V6WE#M&1QwRSt=0S+$Q*RU`sxbtd`E z&Xz-ajf+!$X&Re0=B6mRz@F zeA&D(zqjofs14I0!={hmv-Ku@^Q%~V|4IEIzd!~gb-P->-8YML0v}XFjrPv z$2UvE9>D!~dG+lZNrT$!X4!k}!Hjx)ign!aQtVARCG(P;W@i`F%7gjiz&l@vTjWMB zbg#3m?}{tO+rrd7C#igRX*#zj4cei5XY!UWxm0KwmRq_sUkraA^Ass|j=_7b1AMzQ zyD{KzwUoALE6_)-O7Q=iz_zm!?;YL^fQPC5$+^RQfRkD042*j)wtzD92={j2iMLKS zEuvaspEI5N=dKYH6fRJ%Ai$xnJo>zy9z8I4ukGNX4k;Mc41bU2Y=u;lKT$usYk~J# z67{pd5ID~W6f>tcVhR6D_S=($^O+MM(AnDz{sysZ6HSfqyI|*24#J3y>aXC6c4`l%CF8+EZo$cu&Nd;@xfeoN)guRx7THmbNy zJbrJ#bl_x13GB-_DK_z-1~i(U-kJKEgi+s?3q*%2J@nl+}X1>;y}^bP}9qy1iBF^>d=(+qoDo{towNu5LfND;Lc^m0#zfNdWUn zZU5D4U2sU(OYM2!byThU`b)An9;S_%`5uy~+MoEhQ_sI=z^=&X>2~)ztiMxuQSZqV zCfxgEr0wemU!;fr$z)UF@cb|%Fy)i|+7A&`%`%ebnK+@zndE@W`j74NdR<7oZa{y5 zKNKXyp1|p;WQe7?Yb=`359&4q&!$ldCkn%rE$B*dR0e zCxwWyv))B!)mSoS%H+Sd4bNE0|CRh*18XKrI;Sb}mFULsNpG`$7f4?k5~JfIQOum~ zP0VQxIA!PhH!6|}f|8t^by;Mn{JrPlmi}7oj!=L6GHL{wCncJ0jx?ebqwU^(8+*Zd zGuPo&jULqJO0L^h*$RHt7F}-RR?u4TQ1x9M1~-)ri(z4{D08<;hWlL;EDnpLP&QSQ z0b%s%n(NG6px_WQmwC>i~C-lQJRimhAlnq@+hf=y-@p9_xf{(UHdQil;2U!J{7 z<^#OhvTm&;kgO#(!}Y1Y3Y;z+Z+49K6Y1d|6Z<>)*}v3ZNg?H7)*Fwdi? z;p|R4K~LUf>nZTa9bsSG`l@3Sm04`qMqZGI;y*%+rwY za>#lf9HdH;N(mLnGqtD8Au+`hQl_%m<5E*{JW{Y|A#=;3GGy+RSU9>Lp` z6fHCDez5;2-4)250>N9e6p|D3(JC~qGP7hHl`@KxZ%O-u%F%p!kBUl|yUC%uA>bX1 zQJxjTr6X4fDxqa}w@D+O65gj)qBn#85~Y@o^95nFVdv@nNjW&W|AEhTmtivH7VqkM z`wE7|r21+!$-4dJqv!*aVYr&Q>A!~(K6v%pqQ9DQ0?N4y2Qf|eqKBGyi{!0bOs=gq z;+su@7px~w!RbD@FYa_mcPb4ie1hAitVAl{EFaA;534R{5gJ|(Dk_0b89x~Pj}{^S zEDm_@ZvX=xPML|^LYQ|8bFDEf!S60cmHUmUct>s6>E`A_*spukTehVFew1=5?~?3C zt&9D^PY73#VejMPeX{wO#P+@lHdg>PjyP02=W!4sSXD#aA&F1n$WP}l$#VYNq$ z{{|sHt03dm`799IdMQ^(4AJtqYWF__Vk~w_Y*_KBCP`*-=Jw`pRPtiJRVJQkhRL3}m;!vx$h=`!o5mA2g&C2)G7Nv3sU`{)iN5{YncpDTbz&Wb}PW>1GPD?4TjOva7==A zQwqj!b>lGDQ3Sdb?g_*D$Dm`ZMyr#;o&<^h>!#m7XQPm+bzU~_FuFfwHe}LGA$FRJ zvW&b%(8Tq6$1qI5^pgvPJqy+-sdQ*lY{z5Ns}~G@6#fzOea8I5$Af{vC#>&POBRMG zH?9ze9$fsdA~crZJKC753}?S3L3{VXL{AwX*l_St(Ec~1>?)D%OL6*?j8b`<-5uWN zpor##llh(|RN5DozroN3nY_fVxmKE@8Lh1G-+Ns!pz%hOwecP+55LeMOZdI|fj?`u17~=uDHKOlD7pJW!{dE8aA(^FFVuH{2#2kQ ow5%!?4AgLW@O{dJs{xmItxxwOH)EJ*s|zt9Ti&Xiq{iU?0EES+00000 delta 13 UcmZqK$=qVk^nrQvA^s+L03~(>9smFU diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 9a634f710..10c9fb25a 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -173,7 +173,7 @@ void btDeformableBackwardEulerObjective::applyForce(TVStack& force, bool setZero { if (m_reducedModel) { - // // get reduced force + // get reduced force // btAlignedObjectArray reduced_force; // reduced_force.resize(psb->m_reducedNodes.size()); // for (int r = 0; r < psb->m_reducedNodes.size(); ++r) @@ -183,8 +183,13 @@ void btDeformableBackwardEulerObjective::applyForce(TVStack& force, bool setZero // for (int r = 0; r < psb->m_reducedNodes.size(); ++r) // TODO: reduced soft body // { // btScalar mass_inv = (psb->m_Mr[r] == 0) ? 0 : 1.0 / psb->m_Mr[r]; - // psb->m_reducedVelocity[r] += m_dt * mass_inv * reduced_force[r]; + // // btScalar delta_v = m_dt * mass_inv * reduced_force[r]; + // btScalar delta_v = 1.0; + + // psb->m_reducedVelocity[r] += delta_v; + // std::cout << psb->m_reducedVelocity[r] << "\t"; // } + // std::cout << "\n"; } else { diff --git a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp index 2cc44eb0d..97bec6062 100644 --- a/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp @@ -308,8 +308,8 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) btSoftBody* psb = m_softBodies[i]; if (m_reducedModel) { - for (int r = 0; r < psb->m_reducedNodes.size(); ++r) - psb->m_reducedNodes[r] += timeStep * psb->m_reducedVelocity[r]; + for (int r = 0; r < psb->m_reducedDofs.size(); ++r) + psb->m_reducedDofs[r] += timeStep * psb->m_reducedVelocity[r]; } else { diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index ca904c83b..7e91dde3b 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -855,7 +855,7 @@ public: btScalar m_restLengthScale; - btAlignedObjectArray m_reducedNodes; // Reduced degree of freedom + btAlignedObjectArray m_reducedDofs; // Reduced degree of freedom btAlignedObjectArray m_reducedVelocity; // Reduced velocity array btAlignedObjectArray m_x0; // Rest position btAlignedObjectArray m_eigenvalues; // eigenvalues of the reduce deformable model diff --git a/src/BulletSoftBody/btSoftBodyHelpers.cpp b/src/BulletSoftBody/btSoftBodyHelpers.cpp index fd6d5920b..dd2d8a684 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.cpp +++ b/src/BulletSoftBody/btSoftBodyHelpers.cpp @@ -1488,40 +1488,57 @@ void btSoftBodyHelpers::writeObj(const char* filename, const btSoftBody* psb) } // read in binary files -void btSoftBodyHelpers::readBinary(btAlignedObjectArray& vec, unsigned int& size, const char* file) +void btSoftBodyHelpers::readBinary(btAlignedObjectArray& vec, + const unsigned int n_start, // starting index + const unsigned int n_modes, // #entries read + const unsigned int n_full, // array size + const char* file) { std::ifstream f_in(file, std::ios::in | std::ios::binary); // first get size + unsigned int size; f_in.read((char*)&size, sizeof(uint32_t)); + btAssert(size == n_full); // read data - vec.resize(size); + vec.resize(n_modes); double temp; - for (int i = 0; i < size; i++) { + for (unsigned int i = 0; i < n_start + n_modes; ++i) + { f_in.read((char*)&temp, sizeof(double)); - vec[i] = btScalar(temp); + if (i >= n_start) + vec[i - n_start] = btScalar(temp); } f_in.close(); } -void btSoftBodyHelpers::readBinaryMat(btAlignedObjectArray >& mat, const unsigned int n_row, const unsigned int n_col, const char* file) +void btSoftBodyHelpers::readBinaryMat(btAlignedObjectArray >& mat, + const unsigned int n_start, // starting mode index + const unsigned int n_modes, // #modes, outer array size + const unsigned int n_full, // inner array size + const char* file) { std::ifstream f_in(file, std::ios::in | std::ios::binary); // first get size unsigned int v_size; f_in.read((char*)&v_size, sizeof(uint32_t)); - btAssert(v_size == n_row * n_col); + btAssert(v_size == n_full * n_full); // read data - mat.resize(n_col); - for (int i = 0; i < n_col; ++i) + mat.resize(n_modes); + for (int i = 0; i < n_start + n_modes; ++i) { - mat[i].resize(n_row); - for (int j = 0; j < n_row; ++j) + for (int j = 0; j < n_full; ++j) { double temp; f_in.read((char*)&temp, sizeof(double)); - mat[i][j] = btScalar(temp); + + if (i >= n_start) + { + if (mat[i - n_start].size() != n_full) + mat[i - n_start].resize(n_full); + mat[i - n_start][j] = btScalar(temp); + } } } f_in.close(); diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h index c3a4309cf..59c959ec3 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.h +++ b/src/BulletSoftBody/btSoftBodyHelpers.h @@ -145,9 +145,9 @@ struct btSoftBodyHelpers static btSoftBody* CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file); // read in a binary vector - static void readBinary(btAlignedObjectArray& vec, unsigned int& size, const char* file); + static void readBinary(btAlignedObjectArray& vec, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); // read in a binary matrix (must provide matrix size) - static void readBinaryMat(btAlignedObjectArray >& mat, const unsigned int n_row, const unsigned int n_col, const char* file); + static void readBinaryMat(btAlignedObjectArray >& mat, const unsigned int n_start, const unsigned int n_modes, const unsigned int n_full, const char* file); static void writeObj(const char* file, const btSoftBody* psb);