From 394440ff2055e79a9858920b96a5e3eecf361805 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 12 Oct 2012 12:17:09 +0200 Subject: [PATCH 01/20] Fix WiX module for Ship workbench --- src/WindowsInstaller/FreeCAD.wxs | 19 +++++++++++++++++++ src/WindowsInstaller/ModShip.wxi | 10 +++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/WindowsInstaller/FreeCAD.wxs b/src/WindowsInstaller/FreeCAD.wxs index 05a5d19fd..8a3a8833c 100644 --- a/src/WindowsInstaller/FreeCAD.wxs +++ b/src/WindowsInstaller/FreeCAD.wxs @@ -161,6 +161,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/WindowsInstaller/ModShip.wxi b/src/WindowsInstaller/ModShip.wxi index 274c0fc78..6472b3fa8 100644 --- a/src/WindowsInstaller/ModShip.wxi +++ b/src/WindowsInstaller/ModShip.wxi @@ -80,7 +80,7 @@ - + @@ -137,11 +137,11 @@ - + - - - + + + From 793d678053de5af713eab7ed3bb1f75cefcac959 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 13 Oct 2012 12:00:30 +0200 Subject: [PATCH 02/20] Fix icons location of Ship module --- src/WindowsInstaller/ModShip.wxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WindowsInstaller/ModShip.wxi b/src/WindowsInstaller/ModShip.wxi index 6472b3fa8..029fe06c3 100644 --- a/src/WindowsInstaller/ModShip.wxi +++ b/src/WindowsInstaller/ModShip.wxi @@ -38,7 +38,7 @@ - + From b59044a515a799b7cb7d83f0bdb688a62d31cdb5 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 13 Oct 2012 12:58:12 +0200 Subject: [PATCH 03/20] Fix issue in configure file --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4f94456af..dfdbf8524 100644 --- a/configure.ac +++ b/configure.ac @@ -193,7 +193,7 @@ fc_py_ac_save_ldflags=$LDFLAGS fc_py_ac_save_libs=$LIBS CPPFLAGS="$CPPFLAGS -I$fc_py_incs" LDFLAGS="$LDFLAGS -L$fc_py_libs" -LIBS="-lpython$PYTHON_VERSION" +LIBS="-lpython$PYTHON_VERSION -lpthread -ldl -lutil -lm" dnl Small test program that only works with Python 2.5 and higher fc_cv_lib_py_avail=no From 69be5d4386fa587634325bccc18103e0d865b4ca Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sun, 14 Oct 2012 21:16:49 -0300 Subject: [PATCH 04/20] Added Ship module to the StartPage --- src/Mod/Start/StartPage/CMakeLists.txt | 3 +++ src/Mod/Start/StartPage/Makefile.am | 5 ++++- src/Mod/Start/StartPage/Ship.png | Bin 0 -> 838 bytes src/Mod/Start/StartPage/Ship.py | 3 +++ src/Mod/Start/StartPage/ShipExample.png | Bin 0 -> 48138 bytes src/Mod/Start/StartPage/StartPage.py | 10 ++++++++++ 6 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Start/StartPage/Ship.png create mode 100644 src/Mod/Start/StartPage/Ship.py create mode 100644 src/Mod/Start/StartPage/ShipExample.png diff --git a/src/Mod/Start/StartPage/CMakeLists.txt b/src/Mod/Start/StartPage/CMakeLists.txt index 7a798c98e..b4233676a 100644 --- a/src/Mod/Start/StartPage/CMakeLists.txt +++ b/src/Mod/Start/StartPage/CMakeLists.txt @@ -26,6 +26,9 @@ SET(StartPage_DATA web.png blank.png complete.jpg + Ship.py + Ship.png + ShipExample.png ) INSTALL(FILES ${StartPage_SRCS} diff --git a/src/Mod/Start/StartPage/Makefile.am b/src/Mod/Start/StartPage/Makefile.am index 57ffd74ee..c23b289a9 100644 --- a/src/Mod/Start/StartPage/Makefile.am +++ b/src/Mod/Start/StartPage/Makefile.am @@ -30,7 +30,10 @@ data_DATA = \ ArchExample.png \ web.png \ blank.png \ - complete.jpg + complete.jpg \ + Ship.py \ + Ship.png \ + ShipExample.png EXTRA_DIST = \ $(data_DATA) $(python_DATA) diff --git a/src/Mod/Start/StartPage/Ship.png b/src/Mod/Start/StartPage/Ship.png new file mode 100644 index 0000000000000000000000000000000000000000..533b3fcc535527c6de27a7fa5772b384a73dbcb8 GIT binary patch literal 838 zcmV-M1G)T(P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00OQ_L_t(I%cW9FPZMDjJ>SgG z(&1%Wpam;h11ZuV7K}#2TZ|eZF%g%>2XXHYu*O9G1BnZ_#EsSkFCj!sjS0l~AWcgI z0f9cIOgjv1r|mHFxj_Ur#CSI6oO{nr?oBT67X$zUfZg>B0K;w_`}hEueVPK$cNsj- z>xZ)RkFeQn2Rjajg9C68KrQ|OUaxm=trK-F*PB~?z0PP%{yaMBf1gYSM|2&c%T@oV zx!KcESXjslg79l@Zf-^pgc$(e_uqBN`o=Q_)m2>xh0KUX$8?@wQ3nR@8+pDM zs;a_ZFd!5P!RPZqmgVPuzyB!%!00xa?lzxt7Nm0ej@c}rp({$S7F|Vdm&=iI7cs#IGRinJJlBAUkq;!lDFofk; zM8aWOR9sBs@i;R(I~xoH0u!9I!qL*w(bd@1)d?w?U??GkrIf~gE+Lalq9B_EQ8LIY z3jGw0pyS3(W^!tJ%jfgm1F*s>8F}5rBx;Y9mDZUE$I>lJ(VJLnntXmNG#C^ z-3~60`0^6@CM*VDza8raFb@Fa!61DZ6NHNJm!aN=^%7bw1nJErwgmwxK|m%JLspV7 zB5i|hYKG)`_QP?m@12&W$)-*%NS?gPcms=38Vr|2sE_{Vi*#LtqvXY9` zj0x*@NA6_LwH=GKwumJfG#yx;Cx`xb=gVZ&hJz@PMQC;>4CV%G#O(N31c=8M zQC?=tU7jB1?&P!R!~bB3<}d7-$1jGC9QZ)pF literal 0 HcmV?d00001 diff --git a/src/Mod/Start/StartPage/Ship.py b/src/Mod/Start/StartPage/Ship.py new file mode 100644 index 000000000..371ca2d69 --- /dev/null +++ b/src/Mod/Start/StartPage/Ship.py @@ -0,0 +1,3 @@ +import FreeCADGui +FreeCADGui.activateWorkbench("ShipWorkbench") +App.newDocument() diff --git a/src/Mod/Start/StartPage/ShipExample.png b/src/Mod/Start/StartPage/ShipExample.png new file mode 100644 index 0000000000000000000000000000000000000000..be89b2f74aaa25a785b88e9e7c3d61930325e363 GIT binary patch literal 48138 zcmXt91yodB+Z}r70ft681*E$hq>=8HmXPi)Y3UB>mM-aTl`1d05r4;yvXeuuw33~hQPhMw9 z67UYPqpXe#2!zr9-(Q$yMhs%$O{A}Kic(0cC>Z#NEC)Zh6+j?zkesBLy2tWKr@M## zfh*lVfo3I{^G+;saBVykt)erk^#jcnnmQ0(H6U(IYF@Dc_9lFd# zooBtFI_OG03Qb}`KWrj73@r5wIN&hmu)9HT@|DdcJa`L@HIF_jk#(vsJWb%f>%Q~c z`|MokzZzMN% zcCOX8#M2dm!=#Ri zbtsjOGKl6=Q2ay3?Uc-cgd`X~W%GKXXKys5U@_m?Z@B(lahU`}@~{n2N0W`~4`%xs zoRpKPlM{+tI}$1?j;!1WTmmT4fkKmgI$1Vad#rKBzotQ)7PGy%c>?)KszOknvda3$ zK@oKWHMK{zc>~8sQ-nbxt_4ZoHhaSea9DoNL1w54gdr;W)Qx9wD4ZNj-e+uXvB#Ex zJjdA^AcZAnu%}}c%BC;(Q%4R*RufM%6Q`@MY2nIlq)VXg^zz;CXZEXbjmo4(tGa|& zl%R;CBNz~T937IqeNBGb6RW{5Ka`$4%=B~%K@JY^ocZWTS%}G@Ae+-W!*ixqeL`by zPvblUTwHJ2g8uiK>@3f^hTDy$>lK}~4WqtRG51}13)R1Qbo)Aw4DJN*ShaM)nkTvR zqk@9Y?_4tjGBQf0XJ^GbJ4+r8{LVZ-%Db33u?2kbeSV`0{J81%nY|m@Szmpb?udVI z>ac$A(5!fVMdF3O6DT04dSfVjf}1!opK}=C#kRgHo;n(;ikQfHb} zzUTeaMUBm!8M*JRlN_0++QiAI)^@3f0&qIR3+Ve;gPQs9fP3k-%aHDUY+MmC5l-5= zG{5TYg(3%$1;9yCrhc~@8kQyV>=cv5cCoa?`?{uVZH+)q$*l+nV&OnuV2`j(_c*pU z7K@ji`xj3=0L!d2?N=mZNengLwUZ?2N~FJ8L0MoIoxTN8%jwJ;9_sExtVykdVd6&usM-8? z@L3X(14|CfeQwE!r+Er?E~Z`u|8mbuB$`_)N}T^Od2qn!p|SCC@E};>KJPsqDpA!} zK@9q`1WWRhbnrT_YB02)Sl&?V1CD2qXAHY9l08mjL4S1g+^(}lt%;TSgn2!xvQ-9y zmtWz*Dc)1aq*;O9`MYo$wv3edTae5M%+RVC4W`*|A@OKc_j`fTD&G(;W=Mh)C01~7 zYCb*2?yh>^Qf*FJpDmuAV%V7s2z-6r*WvQ{{oiAe$aBAYd)Zk}pFKvS-Jl?!hQ`J% zBoPn7HpB69T4{e7~n)`M4YU;xjEEsTb%@m#Tt=F`^iR0!$es#-jcw#&{ZEm^MVq3!ifWQ}w%X2CcbH&#){~dHG#1m>fH0ZODcN zq8&7`4+~OI#uSIrKwzRwgNqSBpf=L}F!X1v-i~-jxx^sjX(SC-(S=~APO~8L4@u9{ zlHho1Lccd`yQXQEegR7ZMmhGcLSQk7Nd_XdTqK`z_rHJC)kY%Grz^RECWl+zs1PZ_ z;<6sjiD3fPOmb}F!*3l8G_u%c^Ci8f(-)~m!f{80Vef4n>Ay%|dQdon&S256UllqY zJ5?iGTnK)%Y-8qH>Sq%4mmS}-8TQ6S_$tE&_0V+O&Wliq_)`rIw$=K-;ggTq%;u;` z)%Bel1u(6^u%bzXldE{Ff2(c!B0c#@gAR>~GdIdKe5x6w;o8l4JKP!*voRon`2q_p zP5|Y?`zW|#Yx1I2>a%G2_wg18Kv|HM5vX%L9_k@+t|kb>m_wsvtbi8K%d8`*LaCO& zlgp}VDtc5>MY{r(Nn)iaXv@}l@EBpO7nE!uLjF1#U_k?F5Ms*Ip@J01{J=j$(mL1H3G*-zYRYV}*! z%+p(aMuQ_sZ=&UY;W_$_v!xU#Oq7&ay8nC2!JQj6P-?yN*^@Q%_xv3Z60G4@x31vP zQ6UIC*2DyhgzCxR5uZ$)&>b!(_v;rD{u?Pgc*+`g44|6@y7@&u4V?@tT_%~pa*u2V zp`lYAlbgW=<>8bO$yZV|+K?E1@eg_Lzu#<(_hrYdOzf)>spKRc>`d9Pps#vINCCaE zmlycFE^bssH>k80FT{QZ`aq`OMSX@EePb3`}!jtZ?-k3fI!q*yHUVca#%FJKe)y{ z1=tW7;A7m{IZEp;z2m77fVEp}JpKe8`QAESgew&}nf)w0Rv-1_hxL2VOKlWT~k8N8#uMtPb-1AFIN#*6|c>Q0E5>mA!3JbGKYedA;(+3hl zIc{1IX+IYqs<|+BTwgE#dIP0uIdpFx(lbPT`&puNJ(z)h@!UxbwrLm;7mw&PIwF&5 zz!ZZ}4Qc*5n-?*_G`-%Z8Xl_%GdZ;FdQGViG=C~B$2pjKV0R$+5uN*&mem1c zfN2Z_(dKkMi-~Cgeh_)Vk3EZ%)kh|`GarneJp3Th<~5^4=*?YD_)2zUwm|Lx5J2!) zK!I63LnGn6Kma03ayTow*8Bb%ymU&ji*D`w{_gCBb9NSmmDQ22GJUNryqte#_6o;t z?TPyC%opaJeb~_NDxVi${y8OXWYc9#?gV7>nTojDAZ2U za2?U3^ZM}ER^0D(uy(xKr;3{4@cc^{Q@FVmu&TWP1SAJvJnpjsVRVrDX7)XqE3f$; z_QZ_`gY1>E$=(|qpXC)2h9wC^6p#}%P`vs4UvJn7bCSLgAtbkBFp#9+2F(?I}?X zF0{r*lRGsI>DYHehli}y`mI6LAAmLWebla+G{M5dFXKa|EWbCwwzf$} z0zW-! z>#@Du1ajjkA{*mi6FyA6u_H=wTr{#2)opwUS_~Np89!1wBcxtr4MN)Gc&PaD_8ztv zRVsa{!dY7q_R+_M1Pu|{IE5OwtjrUu)pXv3fIkhr=`i~_vkxVKsjd2w_{%@^cf1#K zCyqt&)_<`GdC-`1JconGO`R@je-!PC&xu$6tFM1&%$;v7Y`1hp{qL0~#Ud0okR~VX zu&2(G=*WXty-riQ;^RSZYcJJIgPNjRRdZ8 zPyaC(En!>0O)$E7{fQP9hULq~D;fy~CUgKs45AJF;rJ``f+HR4N3R+^wVY{qpG06l zDsCodDH%2M6CJW}5tMZB-iU8dd48XK(R!Pr9mxgmMZ05WYR$ktO+`cD?2YiZ{YLkW zubJ^DSV@Ee>Z@|v{OaS2#}9eM#iYg7v%9-oH+Qiv!wu{d;3JTlY|6Xg(f46YD|yE- z1k$YII9O?lyd`Cq25HLnvc+^{ur3}q1c}8jcL9nE%hb-DDS!J-S z`m_D>k9hb_jgX#Bfz!C=If-Rp_%r`w;k zyHUdfl4TGno*%`QKZlZ}GWK`kQ?>I5N=AGkyhMrD9G|=7m4$9IRWy(ueNc@N8KThf zKXilu`2tk?W(K5ugc``p3-emEttb3c-dcLW_Q9*OY2o&zKw^^ z!@;32jwo_Her^oB`%d7_-D5YwsNp*zB`hjz0`&;fn8R>Adbv&bT>5{#86H-iRWTS3 z&!N}EJ&B_NdPGdt8$*l`-+)!?kH&zYJQG>%bkb}zq<+29!OM=|B3IcR zILy_m{|N=s4haLx2hs1}&Rfv8Z=boRF#MxJp%l3PeS5>s09Ok^RMf*^loA{-Y0$c@7bbb)`{(MG`&`@NIdxgpj>S($pFcXvr1k9#6R>z%n_YagTp z!!&czs3O|hWG;5d-afDYhjOtVVOPwPlp0bmd+JHy(GkQ9hJsz$XYJj_Cy`psSR=x) zMQL!*g5}i|ZWRA&gUy2|0%gOg%UYavn53m?fg~e?VXfC*s`dK&wao(nyA3V8Q9W;MECL`THBhww zs|E}NH&^=;GW2vMi8OLOF~k$}j4J@OK@$tNCTe2BJTV!&y_fn%Qb3=dzlCGG&zk;j zW|u+aSJ-Du>C0fUe=uo1K#f%_D|_@f$o{eg^t_;o^1GQLAe=r6QRtN?2&ix&httR1k-wuFnmbIy;@i(VpI~L zq{Qv90D2{GTK)PptM@*2C;_GF%qOH^uIQM--3?v^$T*wlN@@B8-J zVkN>!F)Gd@kg1F^&T{f#OZa3(=<3aIGho1ta>J6A($NiZAY(&T-1B z+5v^$)q;DAyWGV(ZJX!J=0|J!W zK@eW?+J*J7urzhf3)$1^@O@~|cGFJ##>;y$zAMHpVFB4hbt~Nft_fw3w(5zwCn*;* zD02e$QrsqkEQq|W_>p|fEzttEjdas^8WTm1TkqxO89#CfEpsG#{yg3S_vIz^aeo44 zxo*cAKG?5Goa0|x$hptf3OV=Ehjc44wCNwmey?lilXDxdS<$(ROx?d-O@3;4-yi@fL=K_Jj`^k_a|v38%{&Rn1DaCSd0zzLMXbgevoq) z7flFQ@X%^o5CH(-U;}^Dj(E2_caPU9_|0)bz#fFgrRBi@TFloMKLBc`8@nQ0Pu@bJ z0iq}cp(_=^O}&X#5q)ee(#lv{bprh;P!ZD5;bGSg9U~79!D>)}=mLdtTA&nw`YEQi zC`amhC1KNxd&>V(Gj_>BB-=b)Kwo~nFn3(^E?@y2_S^_993HD6Cn-IhpqL9AU^0Wg zeIxy|31ee7B^UWc1T^}D+86?xzRvcW{5u0l=k4@3$>2s5^GQbX!Q`Ew#a@?cgR7gQ$g(< z1>nZ4bRE;pn6XpHBdlz_ldi9AS=q3zPVn&;%$)1VLPLp7n%mjfoZvov3O2U<{YQu( z(jOl5RF?bnqJi{Xc5ri3)#oxgcc8bIvQoR)gGdv$iqVvN*^c|}5wEPd88ap(HIE)) zcyt+*${6a~73!D;^)=?KeD?UGFW(fgA}l7+3pZfzINBA@K&pnt0G<58u0x9gl4EuB zab)Z$jz(7aFHSgiuJ&>)g0N7W4MhFl5L)z?=s!4gCo|S;yX2y_ZhZdyIscfy+UQqo zR1}I^tNyNYD=QDr5NTYvrKKe=9UT%54$khS$L6gU@ZX%Boq-=BmCVK7-Ps-({T^6p(W z0V!$N#<`5DD%Rl8ker6bmf!W7I^Y3i6kv+RupjVv2M@>sczDGs`W<{ed@?d^bg7tQM+yUnrP2KS)p-S` zaK~+3;|A~A2k2t=artB*@a&2>e!t=bb2tUB$ALx$-rOE=`8_k!&%i)T&+(Ibw7nq* z6ZKp|m`RGA7a1n5&D|Gddg@thF z=;*%}7l$7oABQIT%PadmC1l`+gy6viHDb$@aNB|u;eI+zK;AtSt%(dR*VS{rEHZ)Y_y$TF=T{M<1LV@swP@|T2m$2QsqB3 zb#n&eO*K}VtVy8T#@I^=>ouvPNWxYd5O2rE?${BCm6v&@N$d*aa8wd-;lW2L%x$Km z6nZ=zb(WTvin9`gm=MHUq@(p28!Yr)1_&1w7mFuS!v~9{70aQbqRJ{Oe^!O&TkEzc z21=@$E6$OF#TOYF3V;0qa+vwzQJ?<(GOSKYUp^M{r>#m`ZFikM-P3oGON;(19g=XG z*d*X2CINtSdN1RB!!BnX(=m$Du{`FL3Btx|vMYmtHm~+b@ubpS zg=DpAx+a&FlE3HvVnD+t*|Scrt!0g@&{8&CsE*-vG!}sk1nE%_q@=1q;JMM@R7oXJ zr1XgE3W#b+RQK*#KPn@|pW9=L- zKbK5Avd|nKiF1EkucRIu>zey4@+@Nus#M8}o!H-=oRmIU(GuO;(>S?*W*EGSE-_)o z={j8e<`Il_hgZimMnFcEzhLMctkD<*NMyZH@{#M%Rt)WXBx9H{7{)BaQ1hip9GnGf zt5WpPP`&unW*FfOA6|Ir{_$}LK)tsMp;A=em>BBn)^k@3{g^Zrk4Rw-nGq{jjW+53 zWYxSrOPwO(vtdn@+pd~zAn>d72Ny_yms#M>cTv{c8Vv#vaVAiw}Zl-LHk|e z#`&*`0Nfc!x=98=eiU8B5F6b5ttd&z?o9q!ABD`y*I?xEuJ(+sd%2@k9~3Y@zYaEL z(<{yh+S=j2c+TrQY%!4b&}A9mHsKAdsyoXw*?TR8wkD6xOqi! zZjQ(4<`9`cni~bhCZ8UKlewFXP-q_J*bh`W<^Ou@uD&l1p}x5@EUK&oaiDr^N77kY zTQg8H*>2Tp{;Vn7{xWR&bL(nP-seb-hn?LfAz1^3QX1-5<)VGg7>-L;3rSW`g-GJT zC-4g>v;P#+&_MDuF@Z%zy$QB~#~@Fy}Sr6;7P zM>aHYJ{|vhwJj|tLVj(}R@hk)WEfYN87gcdqrUNjhlTk)KffbyzG2n@6cecpXhhmr>2JF3=PGOG3 zh!vLsiZvuT`Bc*Vo`HzOj!LH~fgB8Fr?9YFX+qz4804`sF@Z^>R#l&7r%9~xaK>Y{ z-P$PJi-i{>uUU|9ZAG~0MV*>`eE}xS8(J@K7BL8QRFr^%bc$87XCc@4i;ZEkd1uJE zbQst@#VA*^C)xbD?nJn+JJAX123SxX7fj@z(iw zPIt?c`Cc&aBm>=|sDQRj!PN-Xs__da^Lt>Uq|6fZOtiJNwZ1=F>u6{&_w>-@L^iP( zM4v-Zg@28@{w%c|UC?c2*7xb+2gs z5BMVYt1i==F$#0v)`svHwGv*!>jEbj^?#l$N$B|pR99m-*qsy?6r9S+kBO1j_Dh<6 z?YeXAZqo|5^72sz4i2OqV@OO)%*j{&qoa~sjC00WQ?62t z(;aw0$%Yg>`Mh4spEJLIQ|Ai%V)PjECns~UCLs4sGrUJ$#-*%;-=gt8PZ?r zm-&r5Wdby`@L?+%wdP^9$2R_`OkOeA*!yN@E4_1d)ieIN#Ky@PQlV9|J)JMH*zV5q z=p&p~+-fJL&v?|e+@ejC!88W2zK4f1JRa5~!GHgDg2oT+@Q(v-4dLcffBpOHZjQYU z8v)TGAL9n-#E`&1>F?jo>&N!;&(4ks-o2CZ^%e3zF(aeOopP7YFy)pR%J3T-`#K=h zh4#<%`2!f1j|3x2$QyuAg~KCd5^iozMFomqrK(($F3!?JK>5|xOlaD^b%wn~iY4*- z$kb!+rKQ_i8gFsSD=PN0vV4GLp1wU^;N#&*&GEUCYtjE8A6=4WyxYQ#oqV~~M80qC zp_Mr?*w+VlGp~2BXvrw8vt(I6OGc*?VzWlw@hRzI%;=Tn9HrLb9cJFF0Y^G(}FXYyi%ZjE=f> zAAJqSshHt6UUS7j9Ro2+_q7F!m!qkE*M>;`J?rWg-f;b%nmX6tub7jYOP4zpe!9{O zD5SoEA|lEusZX8oOqQ0wBmqS@JMD~hIjC0k@?u6odEYy77UJ6NRRcQy?0@F~Gha0) zscPBB3J7+B(1Gxg5$mQaDGLjWOR6|Q@vQ)r{^&xvL3x5Hd7RI#F&=()+yZ#`pPl}y zQ{mwo0Dck@j2>3LjCKPc=g?~_f2Er*4GM2yOG{_SY2fogrmelah)Cm*{C?%;di`bi zC?^-VaSnKcoT%2cuCZzPxbXsjK5NWfT2+OsRTEp-;e(&0q}&qqtp!8dow)XO?bq{l zJDT?VIqgV2PEyjlv~=s80Vy&zI2|1w0D3FMiM;Y&U0-8?;S&)n7keU+!)3wRGyNTF z4nxDkl>K z8ymd6y*)uTHnGOW#>FOk;+ z1qJAut?d2O#sA$OOl9ud<2`n*1K&Bd9FPRftgO?cLF8&WI)t-xb8M`v0R;t=euw$t z|IHO_GXd_BZ89zxjK0)zh(CKulz#>Hh>0}Wc~a}E_x*P{+BGbRwqHB}7Vna%i3bOl zXa3ycu`n~MT3Zu3yST9N@r{(1&jQao8D^rLaONJ`_mSFPvptAhR2ACL$W_?diiwN+ zoRE=0n2lu$Ko)4N-xmI>Y2*EqgAW0SAqozVv>!*43*lL#qN0G#jhs3b%BWR+Q5Yxu zQA$b*EW=U553XahY!IbAh}?FprbYlf8vtXR+ih7PX|dPjsJm7=-FU&u5o3@Tz^X;m*69VDpJts{uFBT zAm8O4+#PR0%)&e|I}k0>4@m4NsL}DMso_^w&Rx!XD4v~$|7{zv&7m9T2N&!0EddSK z#sevMQNpB{ztadEnu*ue-toHr6}-B>&#SE^5#HGTxO>EJJOER|(#YlS47~+@{yd~&(1{fq z8ag~S1_#pb@W2AnuEG7>(9%--D9xyN1c<={9!MNgLrS-Pk z9ViOm#3?pD@Y=NM2m_Z^p*v}tbhia}&lH^#bL`VD**Q4a3w^Ar8fq;sN0gGvM_{9& zK{!1 zw)cXTm-n)wMXfE?VQ4!!+>QPE_qGN%D|9KNYDYkNw%fe%ilL$DAnNBQe6Y8d(6c=~jOo+uq27guMFOd4;PQM?+FYyyY@16VQBf1q4YE-i z?h7 zT%UQ}x+jN(vk~l_^FcdI^$B2YJfM%fsg8=E{nS z;FU^}PTd6l`H3_(G&o92Bc86d;%u$1*De1pH$kuHcyNM=PN#^XRM!CPLt2iP+Zs^( zb7@sou9TGhG}(w|cE6(L{onH`AutthvCaGBax7aPcjT$Du^tBS-x%51)#&Ny@Bwst z;UQSNateVDTv=HeIlni1zB>h|gZdz)B+o!>SWRrDykQRj9}tm|4P5TfZ8?6=uRbFO zJ_C~U>b)j!1vCHa?cU!NQ|`VWlXmR=e>pr;=pQ#e&S`F8k)M|rAVi9}WXH`*f}x_)fr0JGq1kBlnN&tt5MMBGUjrnjJSWFpLiz*W`8=E6T)Y>Y?O*fhnM; z9IZ5@Tl2rwdRy^@(VllwMBN51FQ$RMyNB!O=ElvJt<NDKj8L5>ASr)6nYnJ?YQxmmz7M7HwA$z4K$j852?{=pFRO2 zFJP_i+Y;5&BbJty_5d>Rdv0!=F>4xq`_VfmZN_mK$)wNRkBtk4L$it5fO#lO@lzpv z_>{~7^}kWAE~i`=JhtwlawYwi3o}FQmcXDOZ0GhhU|ksWWs?xZ$Tc)Pt*w!P>hU8h zi-bhjhd}e_3YT4OusUtVFv|k#_Hw(+wCg8*l=;sxD|>q}TU(aV(K|;&Lk0v`c`_Xg z+nvGf+Em9)-@V#xYm4%~qVDcE4y(N3z{LQbki2~@_U7gWY&BAk23r07TM`&eFh%~c zj@2u)RS!8A{fEBhYE3OZ1R@UAGnu)$WvqMbP`9sHG^u-zHQZ<3!opT zIP$f&Kf^vf6PJ~ihGZ+zS(uvxz_gw|iaLrCH3$%6tW8Z}OO$g5*E_vc4Gi9uS*Ob4 zD#L5HBX1oCy8TS-z30RTA?5N!7*8iYMcTy+RzVq z7H2m%ydNbceWz|R+Xou~L{TrvJo&F^K;auU8A#lsDA0pY`yE&L7gaLx%+9i78KN<_ znyNxaI2AnvNpEg%^IKa91>8)Vo71uGhH9emB^)7oNWBs7-jU=;;l^1nbRdyoTDz88|mu{23mj|VEz`fKBArH z6bWrI19-sm)G*w&DHXx*3ikFxJ%XX*<0Js3ETN$h(&&yY#byfIrvE{|%ZJd+%*^Lv zQ|zO>{EjgzL27tZ^Jdkc$$*Xa3@1WwW{rhT*wn$E*^pAAiO2Nx1sH_WR_&x9wuM;| zc1!&0ve^<=EY?s@gP~^jLWVCyT%A6$+eL*sv1D_QXHUAv84IT~!<8 zl4~^faK_Mo;HNOAh?Jrr?CyQ<(wMkkuiNjvdc*$bj}$EEs~d)H!kM<%qLxAP-~#QJyHLiGk{sHUdhV#!1%1_lIF_4R{|r*$DXqX*f;5SmsG zlTZW?X5$uiJK?Dv6@kt#aPh{DZM=cSKe62<8~ND7|0$)I8~n;c^3xn~h!D$H%atXy11 zSF~^uSpBbqq;?+6ZF~Bh-J#$l5@k9xts)Q>Hc7?9gIQKq1|TEqG4^ntkDtbaA_fMe zNJRWdxVX3$yL^F8?azrs#2}R_D-nlK` zgtEP~q{Hv?zzS5`rGsk<;CO*)N9YJ-Pfj^(pbj1VcIW0OT3x*%T3)_l>vl5SmaZCZ z{ux=Df={&$a4X2C8cM3F!lata``!75a&mIA zAPVXDQxU}TjB4X>!RIE z)=UlLo|DTprm9N3gpLkh?UJ2}2A3&OnARZp%a8K+0Far?;tT%%9eT3#6Dg{o7MG1I zu20uOL&1y1q`{M14jV9BIek7La65S*SUrQH!28slU18e6{z4}f5BT$k>mi5kq8*s8 z*v=`zlppjTc--2h-qX_utvP(ooUok1s0|qVIKvEv1qMz)>_x-G+%Y42CJ-dW^by{$ z4|)1XqRE8c7WO&RI^)EV*UC5#e<&_@s8|ux+36Ayg*oD8Ypd4pxcPMmNuf`79bczu z>*naZX9r6~O--r1yuQ3Vo;osu-jq~&3lV?5>ohqT=FeH7O}v z0TPVidWEP0$3<@fn50ruc)OoV(=#)HU0uRJ@goC}2pBPVOre(-YZ94`M^)o5eD6p; zl-muc#Cdgfgj`&h6gRrQHF%0>7;$pv-xxaQZSgF7y; zN>q@Gz@?6u;kP`Pl*smL&xLF`HEkSq6iq;U2A0W;{{5&FV9k+B?2jtY4)JNw8q|#e zA_s88nwe2?D*iuRAO?}0YiQ~J_ud4f;+6E=NA-IiJ+@M|7gACZEnwZI)A zT8ae528gk%JLZ5F@_9uUtyybC!8c>pfXT_`e0o19ZnC&4bhsW(O4R{1xmBpfThDyM z*3dAg5y$LDZMY=BhM6;zr!j?dYgDxOb)p_j8TCzOEB73IrC?e)Petn#cznvK^zm6I#1HLjzNnrT|E zPo88&D=I3=tEq|mVAv6%n8|(FWWO?eeoyt@@3=ZGBvOqNj$A6?ak-K4>)t5qf5B;? zLur8NCkl!-1x1To1mI$@(@+M!yh_>FdS_o>b0lPDVgk1wRUkF^$&N{rH=cky6J0nL z^St941E^RR09Xx(fSg{m64RP|3u|JM`U%AT@Gu1E8Zm3_B9Y_c`d5!BydNXm-(Zg2 z{qMIsyF%5gBD9TXexd>bS99?@L`2YMFsH&>EIV_B$ zffeetF2CHy%Nyyi@M7`l>kD&6M!{<=3$lLrf1L&kK;PD zL{$0TVKG4N#S;?x6q)9}KAqM2G_|Km>s~i3p zgoGbP$H#*TN+VEwMLCtdwt5l1CnuW#sI{%y1(>?|1q9gm`9ER`KLC?p3agM%48Vkq zPfY=&N=)B@8Zh3uySvZrPh@KSy{~7Yy0l@Cej}Z2LUg*?P_}Bw!dr@ z0X`g5**<2t-n0LCHFP4GA}$g>cPjezl@{Dfd37BPkmCg!k0FFq%zk508;KT#GO;9q z)yGcJ_?3b526g<0}^JQZ+l*m)AXpKWHa z`H(zBl9dAysm9bKA74spz>(iz3{TQ_#`|&rf9ujiMO_{EV5B})R&MUFurNeUE-n)v z9}++XmjVn0x_Wv5Ll^n<-i?xl+T>rQGw@ZmKldUGoZ?KZ8gPX)tE&fdguDSafXYqv3vQ4|ss>?fU$|6FP+bKTsC%onuwtfgN5{T;AP0SZ)hk##4NLfeTgJPmX~!wn*f4~&e;Sk1LZX}&57!RYhTHTIS81C zWNXWE)0Y52=HUUn?pZ?E?k+OHo%ylYdOeqDp6p+bh;J!Z<>J1iYFIG>U_eH!Kamg< zgE?`NkxY)u*j!ot6GTqVzcvhD!8+e(H-LoimUvsRsan9AsgqNHJp`EQ9iJMJ0$_LG0gQ@5GO2b8Q^pydwaz_1j`bp!+;k>B_%9L zk%tg42p}@jva<(TT@K=tlS8ZYngQt@koq;Dp_Sj-Dt_1)cIHMh!3@q6esOfV6fQ3< z4P6k(wF0k;pdVwtUFeY^qcdu{YC?(k4@##0xF)(ds{y0}vW})KbYK`S<8Y)gNj`%WDhM<#-(I$n}3KqgMU*{RIQ zlvhAmWO93hHZ)K3PsK)CThmY>2w15#U%dJgDKRmuwzf6^`hEl8k>rnxNL~*nouAI- z0Pg}QAda@SjDP?BwdxB)w<8F{CH5c|!KD&lw9$70*)F*%l|-}X^UANS@jMPEOeI?X zjaXKAd9~FxdR}f8{%Y8Z`-G>M<1A}t3Rs3sO}B}FQDn=Jmtu@v=SL1xU=$+Zm`{Ts zYdzBrK-2=N;eQoma&pp;t={v8V%_Dot*QP>0=GRkv6pxI%<5`1l}uNFs4>I(^y+nO z7_c`zv$et`Cg^g_iWIXMvQS)7;^QBemyCj3TwyW9JQU2#%-H=T#O5~0I-HyIQ9&sw zctk`*+vvpH#{a35*N?nt8Y&TdXh}xp`{9tloJ?Zz>;w+_HUQ&%XE&=RNdTB zkjY^rHp03d%hp2I-DzA_7_Mywau9H)S-;aO2;L+C6(wqfa?kAkn^b1Z3@p_cJAeg% zp-yMP)yB$db9PouS6e&ccWZklk>*$0DADdXe4~F9fTQ!L3N#e0&%=nX(yIH3-cdVp z86t%YOfD#{ImqM!EE5Hdd!iv`A_rmY`^=n>N7wJm#mji$U z*S0@0u-0aCmIG;PXm~yDkrk9$v6Po{|D0-u%;#^&pdTL_y&c3Ag@vXurAr3TkN!8k z56d#jseup>Xqck%e>co?sp@M{Pk=#yFJ&C9eQgpjrvNm@!1y>CfXd^5M;M=+?4{H) z(`pg`IzJybpy-qR+cZ+u??A=Hy#)@!f?)EYRQL7jLirtn%AkPt^%?E%r)gX5x+z*P zrBSOh9wDJ8aJ(ja8VmJ6|GKlD=ZNUjOP|v+rp~G+iL&T?atta3AjfBeQbuM%1}6{snXGV> zMLve;?@#fhq@9100{Bk5!}vXwp{a&#bhH#8b@km)#oifAgUv(T&J;;NQbFb=0gfM_ zP_f0sivuiHRs;5G*AqLHdT{Jc6lZ6Q>6w?$2b}qux-|w45AiK-$$( zSC6;O(0mCB2`sF0hMq5Zc#dL2u%ZhBa{uje0S5-Yxj3W9&cSXCzj<3>zaHgQ!)f|- z*Q>i?WfcE69MICXCFJHtcXarmHl)z({oK|~gob#`7lU$AruFF z2Xx8ZERk7P)L=?f*o#?t5ujV;7XAK>hViAd1u39$mAb<}T4j~E8>Q1?W^ccea~U>5 z@*mmVy1;1cbsNsVwVK(ncZLT6XVP#nXplgdZxDu$>Us1dDKukZW^te0eJ7XOUEDg4 zDyJr^-!8uinT_N$e)gF+i^HJN!GO}tnZ^TzgD4hX0yqYdKi|cRPrdC~Mx)bj?eOg0 zkViIXw!-Dl(R7tjQMO$d5Rhi*?hs*UL_nkjY005$=u}d=y9H#BkQ9(E z>F)0C7U@y}sqcE;wZ1p59a7D-MR-vg;jcw}@{N<4r>mR5dX?-FqK-E|U~K_><8kE8iKysKqvTFLs$h=+b2vCX?cdm-|9HIA+w6YI${1vmMiO|!@#zUy0(aJUKRDq6577>M z(KBY2Bwk1){#*F{vj6SZS&6G!+7ks5Y2CXS771N;2Gx9GS_L0%g~=d{QZ}()UU=FS znctS{*Wc*t^Uu$}WF*E)+++9R%x!@UzSthDbEt!2gC9{~Lmk~~?dnR*#Kd&B5sYto zI9F!AEO>F_gPd)Q*Tju2xh}b)b)>aar@ZM%&fR`DjuGyCJ&_ZyCYWw?LW?LNSMdG$ zI$~yeT0sU2+pctt3VC%{t))dWJB3~JW8-|C{Sl7La{S?=KeR&0^fevr{o-0u}1K&8TMV$d5}Ssp;rp)p*&ATTOr{%fh$?n_#ll(8`#74ZR3lkF)B!KmLTyKUGL`thl zr~JrWA=bYt`2+ji^!JxnoZm%Kk_V7sNUrY&Ul%0StXgBf4zEMLTzGtPXq7rQfSH3Vrq-NQK!hCEQnB@{< zCMOTcY1>8$QosHEix(mVZ}|3Ek+f%bvWKw*8-VM!wpjBO#^KEJK(QJQNc&ok8p7On z<~&N=1=9<*`?)uWvaU(U-}=cD1vith9PQf>$Y7O3!IKeFUz6nHe_2MrV`} z3W1j|U6=_OlrKrhRa)Pvt)c98;cGJUgKM{Y>Dh97(mY_!_us$}WQozJ+)u-UFv4y< zE^J!j%_}<~ZsMLyU~0#L!PJO%8k@=gH&fFFw?g@Jju5h{+)rf@z@oYc} zV`z8E<8t)U;DFksfMgq9%906w1KJTGXH5)ugBTU%!bKgG`lePfYkl*4kl9NcsL z)`zn7_f*M3<0Yo+$M-;8?rsdf4}Uznf`z)x6VEXcZ@BLMQDfwd&&lCv@Vzy}3%{S4 ztQvG7Ntsykcur8BYih|lEs%3Krd$uj1}Ga~c2NR$E3MC&XS()52J=$^eith3a%x$6`n>%7&^I|eB%6hb z?5D4zqf_C!q)OAjvoYfOw_OkCIKQbsKU%JjcRyN?%u)TW`mmjhNLJSwQHo;Ro+(QD zUa=m!w)T|=$G5gE=1@b&|Ki!BYH#J5HvMc+@xM>wdq8Rvn)UEI3lcj=Pg%D2?;pDJ zn|Vc~cifuCaKfhYZUJTTFk~1kL5`URyh1wAuz~_s(VLy5P&}^TMOE$L`tvlSmb(kP z{{)FrY{VfJsT|7gz1iN{+Wg2JXJ?uuuKrnlgZ99`1cKSKT_fcC?*)$)cufPs!uq6w zT%2Uy@}d#)lT~lyb_Zyj*@FRfNMT_iCX(3wz6ujLPS@TgXT?Or8@T7i;ovM79}?hw z=#8VfYBW!Bb>}Iq@V}=kCY>{^tDLJw3hKmozuxvAv-t9;v|C+QTU$0qmAo2CHpKuP z*2^_$d0ZR%ekejj07M4=#W+=1@)gLMpxH{yWjhMIk?}NC)N)lRdLE?&1c7`XkG;}f zy?U9X;jC6$d18odx9fBZ?oB?S>;4p`(!0NT9L%A>?sp8B+`@Un3Y1g zIY`29-fq^~phsW35?r^lfJ358;iXj;MM-3|YMWw6Ill?wNsy?%S> zpV$v~X0u)Y0$x64cB3>jYWl4Kyi6Fg;^BvL4vM)FGGD)A-+FT7!^zP~hIw#yEqoJW%*?i34%1$>E>r9hN*15> z{>B|6g+v@(EvNIXWpbdNGk3;XU48w%q=ft1iU&dO)<3D!T2LR7qkCTD9|Hbxq0{A0 zW$8RMFl012U2BC7^Q9K-ZyIvUG1;bpH%T%k&hl(V!#E_#M1iWN^5M4%c$B*rBO)cD zayzT-zo|QAh}|=No94$r)pT`rh3B_W;a{=$F}fOt!^wdRrp|$hG#c*Zl?Fs1HuL3% z3)L3bP0h^!sZO$U<8+dw*{Y+Dqw#)HXBb_W`HyjGzlY|hzvtB_#B*pldnvvgoKsKv zU1v2JgQ)+5GH@B`5YYH_e9Qrj$h7wqN)CtVB4pM~e+>c{PmVR|OIB9@*%{B(pFe8u z?k~aFq&qhn%X~H2!y*Fz$U%?&*tlIR0=HTC8}D+!Rvsb-v0~ zDnqWv+Wv^N{b~*K;sy{;4%PJawRNfhQlBWOy4HrUsIt%<*mcevjPntTkBr1jOG`5~ zoOfFHy@G?2BgR2bP{>CL=PHD#W1*r5@bLl4qp;6`hOs1LRR?V{9{YEeqXS#QxURJF zIYK`PE(R@5Q*@s;B&F${q9QdB@4wGfiLnC%0L6b4B2@_;27Pbq0T$OmoDtH#OCz=S z@xYhVXRNH&mX`l1bHCTulYv?Z3Eg&R@AI~lC(q+oP}>$8ddNaOl?oah z5Y$?c#a;j8I7+vCUz0%~z?8(0nNWkAu08JOPf}1TEV2Z02!wGeB(SN@LkRYp#z3^Y z&okf(A5P&8PHoJ~3qEOo^aB;cUqYQwh#d14D1@=^8prQRp~Gw^x$22duG0mq+HmDZ z1OB)*MXZwR);$zkJtQEM6v|Rj^?!UWARqu*?abg#h$p>oRmm?wID@4n18Qo);7JgM zcHj5*cDhJulmt1{aD2MA`uh3|+iQ`kd_dvMCjRdix0-{)*OU@iTi3r!asR5~$`iFv z*j;U~nY@n97a9LY&ymqso`k^i@=@?mtwv;_q!0u}AB+st^cl27x5$}+0F;_a(d4v^ z4sIOK5r%^Njhi*TS0Jl%w`A9Uwy)wp8Y`-2(HPQ;RdPVM=8aY2k;L36QS$NOPG63> zK$w&&FEi7qyr_tUAtXilbW+3{o6)n;h-(dG?Zom!&>6_(s{`V^h;t+L$CH&vK%>iR zZKY{6z)LGQALeeCy8Y{m^7ZR$M~~VeO&$Mpvh@n^j2Xd6WXW0BqOgXmZw_W%8r%*U z7eAuM#^O>(&M*>2eoFsiP+4hUOEoS~m`k03(vhab>iO{_0^phxi;Izf$NXQiQ=aa? z=5CQw5x+k)(AQT)SX{FIZU~JRc}0bW6cab5Niz4kyi&F2v7ngpOJ`CNlj~-ee#Uq| z8}UV6P7W9bC74FHNnGqnkekYTg_IwL>h;+RMuSEQFj(HG5rZlO4w$tD+S-bs#OI@= ztlRDglod)D?m8A~t?T-y^0@yL=9N11UPPf3UFXT^bN383C+I?*a#XGqM&$H9a~!R2 zf@u}z%v_kqFhUFq{f(k6S+sClbpK9hm0?MAC`3S9d>q{QCr_TttgVd!TsVi{YV0EC z%{U`<9B7Dpk4I8Q(bTN0m`I+N)_(R(HYyO!@3)94G%!Q58>}Q7QG ze_%T}wEN!N{1n7ABT`+1g!)l4CMQmABngqP1?GH_fq}@NN$}f>WC8$V(D-~L%`3db zax2B@;k&)ZyI@$h ztSD{&%na(f`}+3p-_yp<=?0~KqrZVPSbdh|4x=%|u5={yDp2A}g|T>ijg_%1&v#W> z*=J9K8Mv>)qMB-n86}PGa|=sb%r%zl7~~0`M|A}Uzj3|TQMq~PxBV!=tR8KlgdbX# z*X@M)VLh|xEv7gh7u@FN&kYK|xAL&b)^_&yC6}tq$iN}hiO~|7s}%PPFxouK1AB#o zduJ4+FaTo_0N-LCk8puraBsiu7O$JgH>kK6YC0 zg$i5}w%0~7ZNqMuYH^AUb7GAK=(V-Dcjxi`XpII4ZbL6@CZ=v{dwXd%;y&lbi=h!w zJ4M7U%47O6K5~IgZc!2D>({N;c88YBbqE(1&PLM4fkY0gyQm3YarXW9D>th8#emg-yg}O?sS>{o&^b;B zl<}~>Y>LR`nrD_zoIgTBSV&F_fF^^*>sOA|mk7h&9~TX;Jze~3=4w?j51;C!7kDyN ztHy=aW}0a`J0$B^Y3BHt#r8IR#;FKXL8%-RxGZHOe0{y~OejfybE}u=OIlOt&!6bh zjBcTs;qP4&kcdk;E3N`%vp_0(D=X_^%MNUJKBi@6N+>JS6spV5%*-?)=Lm&&zmUr( zlm;9+@lsPA@$`nCL{rUY$C7!AiLP+K9Y_`Z>b3|K~hOP>EL z)yfaE(ZF)ldtq`?B2H0AzYIK~W;(k%-T+V-CzD`L?${j`mw^h#WM+_97$Iz;j3E+z2HlwcNNwqpy%`^nS@(s^Ig_ z+2tn-Fh6wO7E+XRJP zUVeT|%k=QD_ge|FnT$Ytgmwj52yz4d2)z323Pjm}v^qj@;OwhI318yhFWf;_D42e%4^pToIb zG1B~VG(W_4N<|pa=V*>Hx3Br-g)72(*v&f19p7Vo=P9pjuR^rFPbp@bGV_*}ynO!F zv`40;ak?JN*Z|I0Acc`InkQOx6l0CeLGPU&$Jg}NZ4HcfQ72t*4DERl(d(ZR6P$x+ zsDwYV@M#}BIHNghV?OBN2{z4noUm=Ub9x>vxgi1e>?6~KCmrxbp)+%J{noMf)2TJJ zAkz2tZ*Hv{k#Uo2RNLeI2ga{)-6h|7a8~ox_}Eg06D@RMDQA0~EIpKy+Lo+_xux-)rr{t393a z>O}!!na=iWvd1TVeQ(c3KlssXR))#a`QmVLmW3K0c;N*~U>HAK_=B10@b#tm;}dG( z3*Dnd7xAt0o34Kn>vuox3<~nqB01_2AB{>hO=``|NbGWFJlIFOyC~a@9pZ*)^o#7? zqBk$yzH^B87J$RP!%`w*sQ4Zba^&9+Iyqz|HmJtrnaT~lxCTdd`^#i*{jb8 zt9|*JNPDqrJ}Dd)XQx#hQuevlsNDXum+^j0wYk4#`oUrPSyI+rfU*C*jKGUoCSoiz zTlP5r`-(@TMuWP_n(@8|86fsM%=9E!a_Z=zV{Jb%i4a$y;xq=%C zdsnvAnq3(%wfNw!2+zUEGku+meqxF-P(70NvpbqwEI!5PpCHgH>Ha&=_D`SQCyvN) z_GJ77A$$@-W^`?b8qDBxk<^a#-_KcgAAR6>3|x({s8oZOy3Ss29RI?fk8j$(ODkw} zGr380#3h(mI$$e}j1>MDvF&HMcW~cS5Ie9I{=7Na1H$DH8?yd*|A;;=ddVVs|C>xufdKijrjzrt&LO(OHCM2$lo+9LGy4+qtBE?WY{jAwf$ z@vWdF^~LKEMlOnt9v;`M0Az7LyBU9^tb4y2Y0g*mts<9M_=m#p;}4JDiYtq;4$GfI zk!F@CS;o7XhWRvLI^r5w!;ALIrt*o;iK8}VwI2yyelY5;8Gqn&cm1u(M`1i=6W(_D zb-o0vM9oj9nN)P;7%cdtBa4Hv1#&pl)px z@Mc5yGH*$glw!6%Jp4TTb-Wr_nB|98q>1u-^^~@(;6cC!>k@7+}l3E;PXm5~DM=HFHZvccVMQ&UI=eJxTx5d}HupWWPj zsxYD{Zwi5>R6c{^^fC6wQ+s&*wf6slw4# zNu0GI9{P&J@Y;robR;J&RpFZ{#z>KC6sH9C`63Oj3`+$xAyM3imDai>Z$ zn>k-_-kqF2P=dK9!2NBMRK`vA#temAA0;1J*ERMRChN}+?Dnp=dKplIl~sv@mfffw z7buIB+2(}CWvek|(C~*TuR`I=0p(U3mBKuUk<5yTq2^No@SRR2rJd5WL}tW>PVeKq z>d#qLV!9kwVit4n(R22wpv6V_zp?cPw7&N$n>QbP)9XJh$MyBGO6TDYSh)QXPRjDR zz!bf@u>!?yi1>A|_*Nit*f`laUia^Pl}B#z`pCSI0OseF4rZh47@I#L>m7(j1T#?H z^^Q_B+Lin@q^NjmE~43Ys6zch+2l|QGn{U%8(~AV@xu}e-GZ4&BzQw`f*A)VW@DvM zfH;(#Uc{p^9tm9J2V3K=EB_3-zQ&gKlh6<)ghjTiSRo3GrpsmAm)iT|>058vr+~`N z^IAAC{pG)#jVJhOvW3&syVv^t41c|tS#e21lst%I6#Db z-X*_JWCo^=5&!CYly{$btHFXvEwiD<@oG&QT(!8{( zIS3e%QlBEBqPQvc{dBZdeD7UOn2nAs4Mvnc7@HAwdBRe*gTzC1m_xqr>iKoTV2{D>_R5p13{~P}3*F80^AZ5Mb%_~g^N`9D;_v`} z;l4nLZ;qn6S~{>7A5O5gkx)fMf-pkg_}uki-d!qkOCl`HYji8ngaHPm#2ReC_0({_ zv4o>5?!|$LPFxAb=TAwocTTCNH(VLsvu6D1KEOg*YJU0?v)bQtb6r!|?7|?gvzR+o zqSUm{CyU6h>w|1fvM0Vto;Oy0{t@F@k78Y$-(SY<-j?${HE9 zcuR8XPU*K&MGyCxofn}~`vTMmeWCFs*(w29*gXJI+I!0lRdRB2ut6pA2z&~B*{<}! zsB5u?n~~5a2x`YA+!n*3Z4_Q^HM!70kuG@LxwC^*Zg7Jsz!^|fL}hKWA3RRhwLi_> zS;tu)>vcr^|6G9A^&Q8{DV;b_Xbc17doO|$ADP~u^&k4hjQ}NO)5K!q9v&HAQY75| z2n%?PQWw}rsA*=rzI}4E{zzfa{1KP-} zDqNBoK3&iXtg!Z7aZ6wZjRjLxT6a+{nF%rK4L&5EVy(EZK-&|RI z2gChS=rH&n?!Y&fFBxf4f=QhqUvl~YQFFKA;~n9hn0N@puZJ2t)8|oiR%0yzu3nuif>7>g$wbYVIHSI!BOYdXU?`^|g@6IS6T;fs;|9mg ztV)+X4eJlH6v%;w3RKySvGNfew~3w#n_^XW49&W107~ef<@iM~kO9 zg?oM>Qh&%P8Y5Cu8LoXK?U(yhyERaWu2IriH(a}{a$g}11=QMz~Uw{!yg~UO>Ga}=D2|wPH<#oNyBN|I5@75{W9Pr za5GTHZJliz_Z=^vn!@3wXFRWhj@bq$Cx<^-;HHkC;4pz+mH|v#sr~#hfWig_W&mb> zeyCCyz$zH1ufsa*C1Jim+-niit@iuR>!1?tb+!h!q8aGlqZ?*G#Ai&>4S)bVKKOf? z1DIjZ1?OJ#iu%x2EeHXik!)hAi3a>_$R{L77d*S1D?*bG6NWek12)D4IY!dx&AY|R zU%!5J^hT2<%wGcFJXMLbAmNQ&iGL*awc6)0=SOp001IM*YxI^))A;Wng~XuLRDE(v zk?8wd@!+s9E`!DkbRhZ$Iqkm)C*=AoI^yjso)>OUh={b$f917@No131SJ29cW%bR> zAb|<59gi~2n>SXSBfk#4QHu`%sU-`j#yXFVAa7;4x2pR6XcFXz)_kvC3|xF2kFcNs ze?}a&)$M!bixnt=TfNBK*S7|U&HlJxG-|R@2$AaQ=y-0w^n(l>tD|EXTvjQJ9#bNq z;Cu!?N)Fzky|LDaH{op&hRvB$P(fryNIb~3$Gi0=$ev$l!S!pP~Ine!(Wp&vt)}3vlql;$Ow|3 z9(jX7f%FCe15IIWFUv5ydXcbnp5ep~q^`}k7z}W~2SMjXRCM$;Nx^iGcF1!l$E1ci zbP@2hcl~Da>WCE|ORBQ6SAe%2)Tt+z7y{NSFemYYOB`;%1(dVAGxP2pb!5K2{d|lg zBP)Oz`#|P%x7{9_2FNz1ASm#Y)3nC;h{fLA@Cpe2MWUa_a;E*_;e*xMiZ2Dbx3>NT zioQw*B4y=t;6^5u!`3plE;SIhA;*Wq6t0~9*VOS03ebBM5Xqh{*S-FE(exx;F!a;# zE`3Olj%eIdS`VZYE+fEidJ5NLHLcR=9P&Oat9M*)yX~l)SRn74Auc0fF|gd{gGOV2 ziCAV{NapWqwY?|8H0R@ui81H^_4EfYveZd{3SIS86?mc@D)jyS&FT8_Bn*P$;IKRi z!a!I8h|5kJ9WEH*dEf@Vd9z0lt-Lj>-Hx|hm(2#?a)!h|Y%mD* zYnv1nG(ut+3=q6| zChGS9q#@cmw}Bux8ejomlfvtjy$AP&I?Q%)z#w^jy@~$_oYB7ud7QbJ)G>r0rQ-|= z(3Gkm)geKbgII_{%q7MtCTc|Jkp?U2L(s6}o=I}`v>+7a-u=K_XsX5YYnK|4U^Syp zof#ymEGiNpnM`X6daDU{{hljm9JN&lY$YR(m+A7pz7h{pVh!Bf#9nCn!vjY7zkXTR zeptt}wChC*-yT|2C8py`4VB`q1<@y_sp+Evvn3Y(;}i)dmr=gwP@Z+^i8370p-LP} z>#;!wMxVjv&gck>PcAJo6Y8)h-$20ua!qD)hyLF-K+rFp8{ZTPOTeN;-D`1 z+cCG$7f2`oT}D_q2jP(ljK*u)#xcuZ6eNZ~j`ne`{3;GsQg zjV|IH`HB@&ATXnvWEaUx@}(jZs9DKAeF@mXK;Z}m?EkqQtTwp;Jo@vXxrr_*Un9;U zBDP5+^hK6ZbjSVB)p$|~0zpqniSqvTS>K&cU3Tf#xoEX+9?vP)d+kzGcALvuI8E&l za$!*svNU5XKuN^uvs6GUlqckKono>~3bG6%P%Jf5g3-SSjd z>%ULLpn?JvSB6^ znX>uHBLB(Cmqa5|>&s!a`U&0_&Nykx{p0%fZZ|gvV2+&2B>TXk#E;L|RiyDa0PqjV zp}lDiooHd;Owa81Z~8R1wiX}UX|b%X`zwFsXYYK%b0IL5Ss(E z%KM?@m+&;<9cTFr@yBs$tXU!ggI(6_LyEDzY1ha5ti7aXkD0lX?_y#NK@ffvxxFXQ zBZZrG5Y&~I-#Xr1U#?8oWB~zLH!!WNpP8t{G&7rb+!^=)^szKM&dyfjwW`xPI2ybvGgeL~d&(FJTpgkXUx%Zg5?zwjge8Qh4$SG~EG}1Y0 zOj|1ClLF^_4PeIW=8F31T_HS8(0kos!fw6EaG$?GbF;QzxOc4eo$#74s8tPxi$P4< zv1{IzsBz-h}M!{w!Imz4!KOJ`wS>_uQ_)H<$Od zFE)tnXFo@;rk$yiBXnR-n1?Cj==^DEXqq9hAGelj>#xC+@kUDSza$bCrfi?)DVHc+ z=g_gQhWVu+Ff;QWq>K@;f=0IR6SXDNKk?k708Rg;)Wua*oNw6L&j&@$0~ zIE0n!e@P!UHDwHymI}83vCQT*d>!T@mBCZW?-XZR)nVVv@dI_aZVu@+$rsBtH%{M5 zXt&!l2SBMyBSo!&dB`END`ZVz-%^CVVJ~3A+iQF&Ugyy40m(kpwbtuUep0C=H~uN= zry4Qp$D6jW1dfI-kU}6RO_^v35{8CUAfHizQsfc?)z(m^v%GgNRuQEJw|f92X}QF$ zrYRBP-lvSn!_}2`DN#z6q;<#NIEf#1>u`0Qou~M8`?^Tlc^$ci{f!DKeQ#7Bs!KH#-@ zAM6~S7Z*VinVC`)xf{ubEol1zEnF9%srO#Gn7VKV;wlZhc~960)8Fksyd zRqJ^eX;G=1ws6kW3Y`?dJXkYAL$SCD;X8&`>J9ygIc&fa2~QqLBbBE~ z@WUG+XlM1}sFN#{6Q68yuRSqdr-&ZQS42@d1Q{@ZW4W3?{e@=oJ zEsXLgDfOCH>h+J7DHE6BOHHFHOpft0a}0h5_V1{<>0WlI_l;SiQmAs z)dwcazEJEZ!~Cl$D=G{flh%n~8*DIzq2Y%BGI!_@{m{@5QD#Xe`V*qFOMu&DU3h zV0Ez`;}kwwa=K4Bn$NSN-23C+^0G*vRpsoI+o>R3UfAhwFV z#f0^Y6^Wwrp~Kebzdh%?ttl(Ob_#5 zqgw(m*uYn>noZKeIJ9>fLwgJ|26~4tn+NI^IV!_)G19WeFMhis-pVE&O>9gg{@Ox$xjDqiL2%U((Hv zM$>wptm;i9LImxbfg4=?=GEA=rNRy!>4a*yC@%cNu>{>LnH;e?|s9ye? zoSPf_^XCsB*$|O8X?)LsP3ZHIadM&XCmaX7XC4k|YZF;(O6KKFC>R{XDO3-$n<85Y zRxc5QePOIhlhNerR}s#FP1P1?KKrH4;rM)-&cZ~8<7>(1e7FA7sMsA6bxQMl$T?;xyg9I8N$!c z1x81AH*^il4U&h$VUZcIu0Jr$2N{wf_vhFcEIU4VtF?;x$;937MvxA=-yM9O_o@Hx z;VX^=9paVzy}v``Uoa87cXef)A)w|ntrA6lN;F`u zB$vqcj5D`sHIGzFSf3v9mJ!5mCmdW{fP^TcHR>6hk)Eq@?~TheA_frd@8W4lkZkQ< z%*@)z6)NN4u|nbxxh~OQy9cyOh=b_l`Y2*jlWqYfz%F6v5z>T7vJr>b=naQNrr?I8 zlr=>U6$>RysTstiQIgzVy`)c=;N?q{5`Aw{#Z%w3dW(fk@*LWMp3OkYZ?b&(<;$nZ zr6s&+fs}#S3)fbe-d+x9l#vJ)*#@?9Ql*{t>nWQj)6=>!@vjVw>E719b<WNH#EpuV9QcA~L2ZyJutnc&kx&gX^-QJE~-SS0K@5s5F zRl9faRLTRJjf7Nz`kn6Ejy$nCBMpUiX^RP5nz0gDv3|$?uqDW+p+6h5yY7OsVxkIDY+Qza1EQA&8hY=7y3L>B} z`lOVG)(cB6i~ph6;QFG*fkWC0!`z-v243Nr+aHT$l$6diPUWqKO@6;GUcOEIMb z;9t&e1jx|=+qT2Ld#@zWB9+z<(-YCcq5Z?Y>Jlr@Mz~F@#abaz<8}~gfE`1CF|bh0 z5}?%A^~;*Jk$Sos?fiZHS@G|eKk$SLu*Nm^U7YGO)021NhSYR+g~Je_9Y$hc-f@-? z6^oW*#*&#dSwHtUbg<8d~-#-FVDQcqL ztnhPf{>!qNo?#f4#9)w|M^i6CTd0dQshorH#KC@8J46P#?MY|ZpvBm;crv9t8{+C} zK($ZLwvjN-qC0PhT&|Brsnc6MQBJ9p#(#xEuLiZ`S4#w&M5#g`vSt0mv9v-?`seX7OIkWVulR?~ zy2V2|&0|HKe?mI_*V+#8^_^`YD2t_GN_{_Fz2fxr?Eshn{rhCO)vu0Wm6Y|vtWWQpSTf+M>6?6HWD+~MK}yH z+ZJMBv~4IvR%XkRH_{e@H=Y<)^!%;J*PWl1B)GWB)EKA$V2$(e$viyBMf*o5D`u}l zN*`iUSZUOdMaIKvWRA9LT5S7w&0DC5Npa1)QdWOv;k%;%`*cr8p!t+h-N0Ja2JDs) zVTo0w+18)~hiz$Js*_2mLJJtbj%8Qz0w)4eP%6W1ZONqr)=!_VNWsEMk_HJ-7?(d1 zCk|Ka4iQZ=t|Nk-JkiSI95IDrP)EwW<)Z^ilo1v+xezZefv8@kk+CJ7QI;sX+H?)h zQC)9Qi_bryO=cX@jzv9>run^z(gT(-5b8YMzyBoo;r(`89PP;1J5@%4ZO4YWXuc#! zQ0qM2G_;!~!<@{%&{SrZ3y`Slg*u*K)C&xJ+(mpD2y@Wy!Etr{K45O2md2OD9bsWe zRh%!(25&9<=hvOxe5HqA;Q{?NAE0}`ZT{#W<$Y^8GOFBF4P}cuAUxuviRO^*u_r^d zn{>U>WDHJ?5|xfm87ASDq)*(?Jb8sR!XRQM%}8i#%gjtD$oj0z)T9losa+-ewz^{| z49RxSXi%=u&hcP|UhqS?q^#_#t#ePl7;4aYlXkkXca@OZG$BmwT0#Qe+Xy&S{mYee z3LMznbrz&T^nSAmIe8z-M?pnI6pB^_4*HmV>&07|9IBm&r2Br)ef=wwZd(*!dN8Fc zH;!Z+&|nQ4u0}miF*qQ=e}YWbBK24EOS32+SPc9&)3N!Qe7SDh&&z^hvr>Xh`pef^ zg6KuAugWCdP0Qq3yq+eLcUmG99HH(I96?i80U%09TByoPA(6>3;KFSeM~%NN1|90o z!0xo(l2vvCv%O6!dGkqj_p4Ks^OFm<#>ER#etun2ooQ4r@5n7Ds_E&!iDuforB`I# zOP@k(l^O<4E0A4q<7i$*o}91(x8$xmPB0=M+kl=Vyp@@~8XMC2Tp|ICSvjxoYH!EDny4a>5jQSV2o zdV0#2lVSeNR;>G8Q@imV_jFFI@Gb4cj26!2zl;)b8$*0~wXp1hFy2?#FM}Eh;#v;0 zp!&&V;@VBA*0xJgnzqQm<*yIH*&6YdqSK_~SOIEqkhe>|w8hw%A>Q6VZO^-zEZXv; zGD~OcN)68Yn?A<+v#JIY&ns+mK3HSZ^78HXN`v@y!T$h2gK`3}!A{oK7X!TX-%Fyq z_FR^%UnygpK!e%F{ET~kG<8)P@I1+46VO7+pp?nN|Md%r5VNbR zYfC|Y^(66NNrF~uaQBlkYVZpTRNB6U1vg-4062XAX>EMOp5b;`Ftz6OSnkdn3=sTq zXqZc`-MS`AMx;0ng?`3RIj^lFoU$?T%gi~{EbH;0Bi4Ej4OeWy;rKUfl&6-(-7z}) z6zsGRv9wwTW)$y1hXHS2e+t|NhE0VMGK2DWntXc{gH;IuO3PjR>*t_A;3BjEk@@G8 zX1p4TpJBzV*E4cd7W3kT1RFCX{z;^C&LH&cL7h1zZMs=9p@lFkl<&k$*ao*HDsjs~ ztqb-%akxd$=w>Cl+}~{b8l$A19hE#;@?{h9of-F#`B2VV3=)< zX&FdVg>ro&=5WrD(iN+3rQ_y$?~H1jK4o_$oqgqEY-sevx3ol`1m9h=2+f^*3m*Q4 zB7E@GdwS5Y)KypXcg&W9r}#{%8E6t1=ynN8V_X97GT6l8kZr|Ly8-M2%7liOHXlYe%0R&j;%`I48Kpry`gkJY&$CHhwH z+lln|`uezvi)^}fc651&0OwFP4;Pdw>abb}rMq59GcIxD!eM5{V9(@4Wh9cLs2J|E zZC&?eH~uJ>cdZXTYqr09PJ6$TY3tOVBNwr|C}Mw7K#oLBfS2yGw$VAX4WaQ4k9M;+ zkCJJPcjqc-jaX#g>Sg;2&u!|>$p9+@U{h_qH>P6h`kUF(vOp+ZSwmoHATWTgxLDmu zxdfYoIMED@ZlQ{@hK8@0<)uVu%otU%(uXZ*U!IUVnTqt^bJ>vv`A~fzkh<@t&&RI=^8qy(h|YN zx7R@c!x{sGrtBAR*?`8&)zF|!j~!()F}eMwWdr-&~9-RGSSB8 zR8?UnG6Uf0joJq{vqw;B>{mGFL`WjE)LU*#vrIn551A>uC;! z!%R&P=`S_E@d7KI-SYCMK*b|(&PQRL7Jqp|&6uD!W}dk7WluMxyEbDG14tX~1u zJ;Sgcsg#L_2V{C$LrEI&RHHcc|6RwvTBSN*gpM#F2K}OUvThC2%fC9scD9{ zm*8|VM@nN=RV3K2qBET_kUzdBD?}Y=L2&0s6%oG!#hc_n_c1 zSH&HLwFwEM;Y+J>I~vMSKfk#T1R zkM9-k?>`qBEYk(c?tnSMvYIhnC=gD3=CYDB@7V^$vQD&riC)?h$o<%<&vvF9p&BtR z6VoXJEuFNtH+BT{N9~{L-0#4XpD>aFh(EHpF&M%791K;&2t8mJt{(o#ZU*jZYpXs` z9fg9g0v8QrZ(zIOA&Nfz1MAKph1)oQSsv`2ka_cl>3_oL|J;vL%y-FNPC72B18w0{ z)VE;RO9&`|qLDTZX5kN&6tBRB>XjALzJBhU{CwI(^PD0ZB9uTL0p&M*`;D<~Jjzc- zNI`_jofHJiPaTD@7)|{A@Dk*3Lm*)EAqvhPT%Ty5p-^QD(XU6JSXn_q0>bDH;0t|r zRAU@qu?UWks)P=*5)fZ_^v?7qF`=4}hlHY0gsHg^X(v~#->-__(@Pg?Vn&#q3}VH` z8NKm;)c_#1LEp;@a!zw;{YCP;y1uGiiyPq5*i|DlugI7GZ?N;BWAxCp$CQtcqRJ@0b~8dg zwBPvjW(Zj)<*rT#zG{)GOZGLIS-7+TXd53*frSb971+}wlG8p=`Jk4ctqF3k3kv#x zrWYfW5omGL#InMRZ7ZQQ0fCt5U#f+&+64O2= z=r~NLLz#`z?@2G8Ql!R&NJ}-OUeQIAmXfVC>Tk2Zj5vFE7FYfgulzUFFyF+|QnZH; zCE!!x0u;lq9cx+u42M9{1A^(;!9h&m7Q&b`*dgEm?tVc5DUhQ8T{R)l`aB0fwg_w5~ zT8(A&lpA{U2)JT{GK`e;CqX=Sc23TJx(Z&bqna6M|g`RU)k9nAT_^q8<3ngA^QBBckb?ST@=NastT z^^b(TpO#L44w`|^4!eCl-ccxq=vkbTnHdovqJu}BM^rQdm@0w#<43*w)>rp9;4cp1 z8zW)SW>wWPJ<8TOd1&{Gj8V(|yBq!pX=*=i?xeM9rTTB(CHllT0a6T9QC$;mn01^B z7RQEmcu{*0j*(FXmyqN=`&sXx7i-!c#)uf3S|>8+N=i!G#}5HKFH^2xk{A&w#5iy^ z>L0&uzR{YQ`GGlK{#BZ7Cg$d`y_Neg7CJa~`)-BhDpcRu>R9p0RhgTAb$ilUYnW;H zlR1STeK$8c&h^vl!SM$IKOUU+g)n#rg6{Vg3<0;Z^a3)8)oFd0n>N|JUPIEL!3m+$ z9R$#b6Xp4mdQB~AKTG5k^9_zPXT%8Yy;{F%J0`(E9^1Y6Jh-#rDa>;?TCr#^@%-%P zPmvet${v~hH$ItSH#;xCq^5SSt%+5XLMLxe9}|JG_zSlD0Vji_Bm3=|alc?&H{!fJ zv;WBLS%Bt3iDcsGNdP2H!^6?mf>fg7{+L>(^4vNZzZQvvO<2cviK}&GoS-@iPE(Dh z0f&>PS9c8_`DT8WpKiUUytA$!$rf0SFqf(zcu~FV#?60O%gWb!wT)j(lK1)iIl#rp zSspn4NQJa;X#m`XXh6cUV9eGmp18Pp^KifZ$mDag>-%{a=J#iI9&Dil-tshbzQ64d z>QnCRx4!oFr7n#I?}kFJ)*lt`fPou>o!bm#dmEs@)uo>q8A6V^oN5*W4x8u+HQ6*7 zLQI}xwpCc0GD?^1n)t7qF`lS%U6;(Vh-xw3NHvA@yES)JhJuyDbQ=%%?L7|~x3@PNu`}?R3)*f_RdC`;=^q;U&(wc?b9Yw;=yTpw>1=@AI7c z^ThpJx29&9Y5mR0iincZ=opx~Fh8Hs_5h&6e7$80xu$!hdxeF>Iq8e50at^3=PyZ! zlK{((C=O%CQl0nV|I>{VC~c<%AulTs>ODd$M~yGrQ))Ug}6V z$e$TFq4<{Rb|`{p(}enOgy$a#@LsHJnE`2*jXO2^h-FHxJ}}|{IrMWg!3U|iQ`ah- zh-j7Ct0|O|4Bh-zur>T*Y>*)TNd*uYPf)3W;uvfu)HoO!om`~CL2;5iR_(&6<>?Ya zLRS3sQwvOl4Skm-i|!T?)zQft4p#h!e7O-)A@|Mjx%)$6#5PwR421RopPVAF;MXlJ zy)Bxznmp{g7aKl1BHVa*`haNz!t$LqJ4y1SZDU(o((J4QhU}i7l;gRt?8JmnotQ^7 zR^4e>%(h6GlJG=whu3+qHRjw_-FFwRDS7yu;az&*BsNe|#3 z!hylC4aaMKTZiNk!yY$5-!g)7dp9S7NWqrL&T%dVqx2V4PJ@pjoZtyMEFz`=9&XO; zZ_2dE`PS6?|NRphY)JC%vQUZs-LjoIPKXsr4u?yXs>opcfR^oy8`ppoF7YX&QmQ znEy4qN2FO7%FZZ|wCwoNa%O-LWV$vKn*2g-J?J`&0ZWP7{$2$kE}eR~eH+bfVGaCA zN^93bGQMz1z}~?NU0NU|osX6EAZ0r1&%;&pw?$SJHL~7IIj;B<9qbJblD*D4iujp* zW9U?V+N^3tHnnnz)tg9ed_^b&2E$m=jdc?$2^P!uWuI-h=tD3X!nf5Lro4BSRxl3Z zW!YLG#e&CS3}Rv|@R_;Ka@eUYp`x<@4@WA^e;DXsYFQ4<>2aA~*%H$c>3k436%Hj5 z)bwexS(mnLzg`C6ztX!tc!`83J_9H6;AT47r6yYOg6?mrvv%XKrCPe(ogp*I&IEK0 zn;#;Wvdk5|!gbYbt8X=uD|xaZX;A= z5JVJ*x@)ZHmuwp za6b(+c$6Cr)E+*f^+P~d7UY9qYTv>v>rcvk>sTQ7-GXm4L7`JKEd`=X>1s?XzXKsk zR`_+N17K>wya4-_Tym;B#WEe}P&B?9Z1mmpb(XYp88{S}IHzl8jUaA z9UU3zTDb%4C#^(nX#wrP0PfMN_cz)8~THPGNZqJ-N|_jz^4Iee984_H+=i27)N(grpPH zlOg;qsAGLl+T{j3eQ9}l;4S!Y>eIsm44+p@D$KGZ6cC#NYD&()K8U*w2^AFpZGG{o zsre1Pz5Ne3;mdxjc9 z==nLW9w!rfRyAOJmt91sNK#9ml_x{cP7vNcyE0NB-WU1$()UUXIDi5>f+T0gUq9Oe z{@h7q>n72&3m2Ixav(?*3cktflc^QL=U{@}iSYIZlTO5=cSJip?$9Pi%OXFPhZI#E zX!z84J`h4F~d)ah(ipyF1;v%f@66ljz@xJ|*5q)@OH3OL; zeX=HPa^@y5eVi$(wF!9AQ>H(T-2*rdY^M=+8mKHe8Ze=V4Fxy$^n?MRm>Oxrh?+%S z|9$@JeJoOGU%F3uUyhf!wgv|VxVPG`(4?M@UUzESf*}K8HLv56VA(({uq!}s zELH|@Z*6Mo>w$QdA#P1&BI2n___rNS!C#}0YyRo5>L8a(JDMQfObz|vFP~eu3=AKs z{tvaC7>#XI7<>NRA7eP3fN&tNx9iL)3LF$(wwR{T&%!XTmY0X1iPzi-ED&(4^I&D z>UjRm@AfOP!G=WPt!KnQX>~b_ge0vUKm%H~@gc(0$NRB0g)Y0^^EZqxL7I z3RE^kIchG90oFRtz+-8=wR5yx5he206LhnC$0V^&wrX8uS?*-mn z=ZPs()Z#o9Dk?`n*XKiTld!s4Eh4faUnOX%r+MVJnbibcmVP~a{ciSMuJ4-v<@rL@ z1N`%}@bCukIsEE-TD!#n1$W*m7fG2^vSayvKEb-!fJ+0@`oP`6n!ZW?X}uCtRgqtr z(wurOXH#fborWrp%7o+~V~U^+e2*%#YI>@+T8U8sN|U9@O*L~&MY?Kd{u0thwI8QX z<%V}CdHXF!6ewZpPxma?I|iTd<|ff?#EQZ0tAa}e(jWXNZdZeVs+HHxK|Vq#{Qje; z4eg`Ep3M`Vi3mu^-xRGVMQ{w=EN>^8ggs3akG{xmd_^6j7Q&S^h1Q9ZvgS+T`dsTxrxrJSc^!5f^l0P_W zI&Y2#vGCR|Bj&hA4jFg^R4{$7gv_Sf!~f#Ejd;I;6EC)8&b$4!T!S@Q+~=PVt;7S% zAa6e)5Z)DGRsT=L2lIWJfn$)PR@RR~Z;ls6XNJmjQ-hN`8i)mzu5Q+jpVZ0SI}};s z+9ldw`{1}z0x&fjg^}{C9$ihkcN>v)mueMF!u2C*;FfH4MkEN&P~M>H+vjKQi%!>E zW0epVr`{=q>q4w2Z{D}equm>cv_b+Y(!+CeP~YbVLd_4;{WlW2rI^)5>fQni@z@iL z=6M|H_R#ejb>t@vIDEYU+opm)mL031>1IWRHG@ELjVjJC3>axcU-^uV5m!b~_rXai z3__6HSh+YRBGk$Ssor`dTol&7y88NxE0E^HDJR1(TlriQYU3SbP8!h@4)w7M_h2>pO%ENCJLmYSX-N#ji| z3v!RMMATR72a{x|;i801*Xl3jlfAY~E^l{vno;Nw)l{wX;EqeNse`}4B>{m?b$z{y7|iUu1eR7$~h&mJ*#lrCyCP zTPva_?-zKiQ+n$|UqFMkBl8Pm@iXpYAnF&|pg8}YB%s3*;V4?!eUhC=Zs(z(WADa; zUVy9P86=z$2L#syQSbKLQ6UzgJw5Ld5;f&RuUua@`bP8m;L5(2c9)jH-e|;3Z<@Q2 zyj$CL;1m)jCd2#dJ_OB_=C)_f&f5o6m&{wPNKANgBzE=TQ2amt0$y?3NH=9|nxk|( zL*?Oak;SrtC4QkBf19sj=f&`k=fdygv7&p=G7N( zxRh+TSh~Ao<>gV~AmnKLpDEPX(h@0xr^8P2csvhP9nBn^>im%kstRMjZr_-?XR;VN zd5N+31|IT{Agz3 z;*#mn(VfV(q!*b)8AFg%BJ|DLB5lt0lT3?P)ZN|tg;Q~A6zAb9Vg!_}X&tK&Y{$Lb z^^k`z4Y&J}+?i_ReV!2jw|mC)ACWA<_KE8Ygl_YN{L_b}u;I5Z@$jV?HV5?t{a`eKz~&<`_9M zu;NCL!s!*N^hSZS^X&XQXCzAnL+I?enY5jLI)10q3q=;s;;0~!n>SuVeog6yJ|*;uO# zw}y@id}h91%DPAn=50N*7GBVpTY7I21PE>5X1JTm=c{ zIRch&azc50)RY#aEN=@cbPzR^5K*Q|PmVll35iB7G+piOvId`n|Q_cy0m1u zcXaAoW+_fFm3d?*fp0=e;flV ztEi=7WO1aC6}q!~F~4E&6VUWuJKyWn{gpWKw?H(B9uggS`HYZt~Yu6#Wo!_974^s^)T5bCWaZWLgO zvYbeW;-`>eC-A~>PPEH%OyvD48t3XIxz(e~OY8xJPk9UW8bHD-WmJncIywq$R01DX z9^YfPI$Ab`r)$)mvbq|(E`&Au(SJhGa}wnvXoYwRa!(DhZ(&h-S&}H`gq=6}5&NVsxy*%D}qb3Kx9yh`G0--Pqh!;W}qD-Sb+I!X0 zUbVB5JA)6(+d-U4+#mZFtG5PDPE6judsn8PCsU#gIqZlYn<~f#Q=jWkO}L@TW;zmp zF&bNtxIcvUB-B+9f5-9q?KdG9WrcQ6gXmU=V;wg}?IbtKSNe>hf!*ntJ5=~l&M}z} z0<-!jE1&0mr|Ous-J+N{%YYXXNxWC{x?koTDk1)Vs@dgz@@7PT-@YWJ$G>#9 zr4vp95a2St2C``NK)&4ekFk!ZSS zALCp< zhHeD$2o?FR9}`llbWE_-{DtT1R|ig$dEU1OSaJIBVVe*uVB7@WOVuc!0qi*w0i}s2a+7Q4&$)P09E50JfCav zzgu9EK|&-w+UNwUm;-L=7Uch`5C;)+5+-aPgw~PreEG+}!k)CPn%vfK+qJ~gU!vu=_%)PEcZtFTv{v-hhD*F&LW6S_mHnYK!D>7xPo76WEZ2pE?5m6-O;#OlRj%a z&xyulm59q>`0+Muj28kE+ukK-q!?QD!`ZRvk0gvbCA6M!D#o-;8)@Pulr^$5L`XJ8 z`}|DQJ&IS|1C7D9N=||%>-^ZRaC^7zTPlLXd%xE9Xnslv6w6PfBcBeXSf(~BkZL2v!CCXs|_>s*Cb`A&}NRE3@Ub6 zee+S0wtpQ1qX3X1Qp!Y02|suI$U&*^i?a$iGfAk1k@U6U!vsmlEbs0H!oF*T4Uy*e zc!|gzCB&l?GlQ@{rgjiFKgT&zN*I$P?sK{M6v+(}?(U+Hkf+Dh3o0oo#FP=_T#NkL z${9fKd#-N>-vx~AU(1I%nxuzrfoZCU{p1Q9LQZB|N(ze)I11_u>m3Fia3cpXgoMc& zo0`I}u5^yBXwgI8AfCCXt(ow}m7p7d+AXoBHxn92en1G#@vQVR%4#S&_5R&((`ejz>#TN_kM`z|_@s(g^2&+M5AU6_ zo?ok`={d3}=&HXkR-FpD&Hj-J3F$X=-t1 zM!+aOa6-)K=Eh4kjynfDrvbtm}8*ZI1|rauiyxDz)Eo^;L38v5uAohC-0;(&VY1@PLQ zCuIY)W*g3JYv&qfI2(c9hc=7$K~qzgHBFKGkoBj>udCI{8*^KJYuVO>_l(*6UY&EpF&HbOS^z|<+ z9UU>#(ul_n)q47PZ*priuW`6W)>~Xg;1To2DNowY6*U3KCi$ z5&3YgWqp9dLP3n{Nm?gDXxS8>G<(cAo-9hgbK9TpT=fp9uPn=uRBkmgPjt$ zlZr6#jW$<fYG~x)qiU=j*%!PSr<^H&YWaxUU)l_%)~Q>& zXitYL>5z@ib>;QThO=k+_RJpI);#u<@pC2&H6DcJ(yUT-Ut?pM`+FQcxpbHpaZF01PirV5Mwey z_zxt=Ocp^k>bsU4C#tI>DrZvhSmfITq#Bu;;&O$l8*}ESViKk_(NF?E1)aZ<+Z8;h z`0B1i(S8OB-t3*w?zQ6lWG0TD4P%(d@X87^w@GJY$c^hi)ZV*VAQXfGjpOLU$Foi? zMw0BcoS)uqZ`CR2TMbi9&Wx8czi6ygpx1OIsyvubQZX@gRP%A0AoXX)EZs87u4WH_ zka9E%U?R%kd^`BR_R!hl5rxQK@9@TW**LE++81*_q;T%eZLc=w`e@ zs|bkkFK!HTE)Fw(Dr?vLnWuXW3Vi(u5=WFpsnlYn z!G>bW6OOcb z#*UKO7$6GdnUhF^(_RB&fv-_Kb;BGiJ0l~RFZtdpqhn(zy)RE++?-D_H(&Sc3_d+0 zHD%S8Xj38{{;0a*PU$B|0?IC4FrJZME1 zV&n`=$9Sx4m_XOof(TH7;))`7mU?GILEeT%=ck@`TqNHrtOO^XJ(E|gp^UOsGEkEZf@K(wm%;|<%ld4+ zzYB+yDTkhQU|Dq!;xS{yVQ4LcpYEq7Ht0Ghucmw5CI38Qh~qT(E`-}2RZ=p@k9oEY z*i_*bm|aSs+Z$$b<9z@4^|)E=v3*TcvUaR0v~@JYxGKTIau@39))0@5FBM8a__6v8 z&_!<@)@4LjgJJM`A2y(9i|g7)FeX_IH$qOu{se7#!ehj<)!F2eK|hv^K`LF@UUnwl zJMlYyUDQx->-O!(3_EOstP0EPz!&DFm6oE!Tgz)AArnir< zgQH_2Kr-V_O!_REXUq+i6WQx@D)&%~`&nn=pPlp0YXGaS#mM%09aG#GG#lQYKLZ0MiQLcf)Vd9e^G;ZX2N zyon%*K%tMJFC!?cP$QeNtwvh^ZxOdVDUr6xv^gD6C|nuCI0qX1k6iF|R96@tD%K}D zyBV}_tEBEzXT)T`^4ARKbixJ1Zpw8Qb|WM6=sOb&3UF)cd9H!i9?)gzRDk$k6ocuI z)+VU_hs}fo_FAUWp5x*-8sY-+aw5MOs^a#1vtir`xi!Z?k9cVJ=1@?CvjlQeKRm1)$@AA z)6o2v(0!3}x$^Mm^ucz!*y#@(R9jT{Aa4|URRm6rI2BUliO3aorzO-Ey$V@F1 z3g8I`uM`p6R?wB0t@wk3vRakRUb|X!KE-qevxIjFB~fM9yP?jtX_MTGpg=9@`T}2< zDscYoVWE5B68xP~1%Din2(O(BEiLr|jRQ`8is=8BLHvT%_C7E_WP?jsUueVU=zD_< zsQ9Ya7i(Kati6Ejt{8*hAe;KeBfy+Hv_qzf<|@Y)Gr&Xu=gquiqAD$AnYu&geLK|7 zw(}nRR)nP$bg8WUw!~6()fi9u@w^Y{ryrGl*n*bT)6#pBGo{VzvFpnw$qUs{GZ13a z$tlqzPk1ON=n*T>ATHL-TUQ}DP~5ETk*OV*xNu~I5oOm>HxndL5dOH0CKXMBfHDq8 zJ?RDw2k|mxOelYnnu*N)6uo)7gK4l~5%hT5cq__Q5u#U}MO0_{f~GjDd3I5Ev%3qx zdP?;;0Zcni;b9ug_qXA<7#ig+*;B;{)drpdLqn)T#!AX6AwA;=h_fe=vV*EL{dXN} zvs?@-AD8}jB*wdhCI}nWLjeo6A6^s0#D=bD&{I0vaIp8+{1B5pbmSrhhB+vdp8C8b z+!wLDxUN@!xw~=ynoswhPP@)%|Eh|@+5?c*KgiK98Ixl;ul>xNm|$jidEcPT?N+B9 zo}QX6yIf(NCaE)b)+ixv8xBg1MKRPhVn88QWFE%jdhczp1UI(DjHVn?Lr&30Ip6g& zPzLA9(%Ehj$PtW=Rsz@~OgLP8WzA?P0^O`wdkm1=E@<3}t1iz}u6yT0xkYIHk*0Qx z@Zt~;A=f5jMXqL~$3;U)HqJpXlGzok&bz%;RFED$>_jjO&sm zD5nn1AKrQ5t*C^BbJIg01nUUjj{t*bZJ0GPN z{LOa%$*wty2!wTSu-e?t*MuKu%c2d;%tqJN4*zel)o4J!d^b>|qQ?LH_PpCtais>O z36p=$Wr@$IR){iDUrxo#1ie$E`GI^T*CtyrJ`_U%<~gD8kAD81E#s7@U43OB5)Yp3 z>4S+LayifiaTtq8iV(%?+iJXWhBa-tFr-cHEG4?m6nxwoTq|SgeO?)i{#t4hHY>jM%LL^^80m>7eA;7--AGcMocL{Qk- zSyV7EOEr1FgpK*L2Re5_l)FSZ%sSFNu19Fc{e1efDJ)h-_x7kOD-RF}q+XvT1u4aW z2$D}n9fI_(alt-Zp2J3hjHZc8EQS#skcr#_Ro+nBCZL4}v@24#mN%69ElG^Z)R9(@ zW_|I`YwJH`H3Wb~w8*b_`DQM@XlKg6ZBl@{_b{hn0HsANamj){8c9*a7nBG zHRU|u#;1$Hht*GY^i(MxLFVN;WlA)cqGjvT;S0`lSJv2hoZ$UTF3T7vA9&v-J<=9V z2Q;M1$p?Y0JjWMZ@qA*oGdis67FV#4oC~ny+f5E z0IBXyr>WY(r&1>E4%A{42DO97FtVB~#G%3DgaZWVl}{m*DNYVSM#`-Jv_6DRhs4rm zUrJxUSFS2uUMNqt0;DKqhLBQZZa^B)04?}wy)Ba4=jAptqjAD3*AtAu;F(huk$@BW zxv@@DLLR)FW>?v74jv)p#L8h8i6KK-aqfZt=^2C?u)A_X*|G zCwzeU87@~6`ne^}vN4BVG|wL$d0&0NK+VxX}9`%LZw@hWL~wH|Z85eo+2dPN4*OA>((9HeAf zI#ub~Z%K8k^t7w=WcHXV2j$w8Dn23~R}js7Zqcj}&6JM;x{OO*43xT3WJcn1G|e>qlfjUL6$c}q zK&m@U0b$kZQ(2JbcuLDBF^R+p?fBt9IR@G>?#`d{JC)@3p96ivPFk`nw_F{W5H23p-qhT6z0mQW$Wd%L8TvP=MxY?8pc{pLCzh{QNvS36`x+xDJCV z3R)tXyyzAwzNmfm>EkLS{{PUe2nQ3ICI^NyMg6ef1>5z>Tp=N0L+KPN$8~{th2f zFx%%&{MeL}9o(aZvp>eD&ogD}D-@3>RV-hmcDuGt!6yL}eG0U6Mdh)v4$bTD02Qw5 zL)n+$h(IZIVb@JylU7OinDCxfokBO7Nrga;B8h%m=y8k`h6DTr}l1W3+=>lT_Dm|bm#?8?X+Ce@!iwB-O8RoC`J~`y0>D79g}eJ` zXbB#$S;nA*%lP2VU(RwIl4PTbO-ad+0IlMKG?_h%Wlw2L&k(-hS&L5%b6?o8`X_+$ z5FSuKNt~Q~ANY3_h(i-CKYvC`Dua##|0z3+7l%NxF_vQvDFTvChsgF&0&9;cZK%JY z^*56D3EJZF>T9<;j`%IiysSwdw+48auxGe1B-LB^J7btC&ABbX9 zOFEdWd**Y&h~&M%VVSO`tNQ1ztsURam}WF7Y4b3?^nHGy#8B&uI)y9-AR@#Q5CA$C ze+l}Y7SY>19e|JXz_IWsvF*p5JINZ}kEI8U+jBW)GxopL0YvTDJ3sZJOY|KZpqZ@| z%T*^k6hra4jt#x5KVlJ82!$#fHr~Y#-gB(RE>G5lk5ARhTu`)9+u6K9;KlvPH z*@&|21w5Od1t~Fxk}DuNT;&S#<7*ii<4tGqM^Die4;OytKW_ld zS{mvFQ4Az(F702@q0WJ}{4Bt4k<7mTAvGDX$ErTS<+6K!oIN|27 ze90V+zD`Bpmwc z+U^kJIE8VP7Vv--LL;_r5dPKn+ftWmnB5TeA zTI2_gK14DfPyjkCE}+ra-;e&L-}Frn%PpTD@~v!RXg6vAEMfyn z#`pYNvo**MhJ|2jOG>{_EhMz0T`xVbVt@)9Iq2wc`xYdiNmenpUlMvr_QXno-_o7% zvl66#_t!iJ|I1Hm4~au|9xH*EBvV4K=>weIGnpXc`CzXlILFYJ^#4fX4Gh{Nd2t+k zeDWggOAX#8!`cJg+>$j8d}@Y?Uasc1!*0pk$7)Z&3Eeo{3Z|@H8ViYbcRV~ESkGXi z{2LCIU3zVl<7^8J&B;bkvA$!``ni{0^&8*94|o1F7Ub7EW{ZuAU*)vPZ2ptRIKI{X zbNl1_a$sVT=JO2?ruafbot0l^s+;!ugWan47lu-?*m$=N2}RkNK|s7O@ukYBb{hyf z=rIsg+Fh0~ItuVU(*A0gG9oIxlET#^`a99!302#cs6F`*du6(zO8E!wVamcF86c6y zhi<#)&hpDv{oArIy+Wv3MS@b9YOOxk)$DD8zz6BreMM2}`%~WE$)n{_&5LP1eoxy66E3Y>t;kcQ_nqGZ zkb)|7^`yEtq215eOIJ+{aKt}iH$AGQgmg{C=I}}Ogo-4YhE6WWdd8KU65*jKvjfOy z;K~>(hX4MRzeu>Jwz#K*ugc?go-X}JBj=`;)bHgDf19Rfjns>TZPC& z8|`Y72+&myX-x^t0#!Ct`X4MrO?E~s)^TzA@b+dc_R=ex*c-1npl|s$$JgMig~wMj zD%f$k&F3fgNzu198&FXbc6=_3wTFNAAy^zN>J;;QW~5TE9$#D9CBDY@=@K;p!NHcX z&>9(LH1MP-=@2E-GJsfa7WofWs6^9_U?e|SN2jv&Omc?6W(+@+b3D4~v_OzxzLTIC zWr>=44~=7*JO0r~ww>#dz2tT#iYHlHGOc*t(SD#^6i>Y4R7vs@Y>_l?CgyM@>X_-_ zL^|jA{U5}`E`PIj2y?)jR6aRPEb)bUUiHv@?NO(QV#$xuXu+-FWX*;xfWE!I2dE`<-%71iHpL++nA1>EPmxhMm`B3GhOs zx~z4~P@)++%^Y5qDl09XzOvc$h}bY~>;70w3&fmWe;=*Ye)yt|uf>`6m~biC;HY(I zRB)uO@^$zgeD6(vv#vY!SU&j$oxLc4=G0-8(Jf}_&+-@D0iDym33Ship Design module offers several tools to help ship designers to view, model and calculate profiles and other specific properties of ship hulls.") # here is the html page skeleton @@ -366,6 +369,13 @@ def getWorkbenches(): onMouseout="show('')" href="ArchDesign.py">""" + text25 + """ +
  •   + \ +

    """ + text54 + """

    """ + text21 + """ \ + :

    ')" + onMouseout="show('')" + href="Ship.py">""" + text52 + """
    +
  •   \

    """ + text27 + """

    """ + text28 + """

    ')" From 4d58b7fd486616d882479bd712c5ad4563da67f0 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 15 Oct 2012 13:34:06 +0200 Subject: [PATCH 05/20] Fix issue with Python and cmake version 2.8.9 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6513b1773..8e7c5d8c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,6 +170,7 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X) # -------------------------------- Python -------------------------------- + set(Python_ADDITIONAL_VERSIONS "2.3" "2.4" "2.5" "2.6" "2.7" "2.8" "2.9") find_package(PythonLibs REQUIRED) find_package(PythonInterp REQUIRED) From a677bf140e427b9ceb2bd3d43b8d9fd07945eb92 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 15 Oct 2012 09:38:46 -0300 Subject: [PATCH 06/20] Updated Start module's win installer files --- src/WindowsInstaller/FreeCADData.wxs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/WindowsInstaller/FreeCADData.wxs b/src/WindowsInstaller/FreeCADData.wxs index 5244bf9a2..2f52bf207 100644 --- a/src/WindowsInstaller/FreeCADData.wxs +++ b/src/WindowsInstaller/FreeCADData.wxs @@ -92,6 +92,9 @@ + + + From ad8039027a8b457568c04d2f73d01f0176c54363 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 15 Oct 2012 16:14:45 +0200 Subject: [PATCH 07/20] 0000855: Start page ship stuff not correctly installed --- src/Mod/Start/Gui/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Mod/Start/Gui/CMakeLists.txt b/src/Mod/Start/Gui/CMakeLists.txt index 339c9ad50..b3f9a9836 100644 --- a/src/Mod/Start/Gui/CMakeLists.txt +++ b/src/Mod/Start/Gui/CMakeLists.txt @@ -56,6 +56,9 @@ SET(StartPage_Resources StartPage/web.png StartPage/blank.png StartPage/complete.jpg + StartPage/Ship.py + StartPage/Ship.png + StartPage/ShipExample.png ) add_library(StartGui SHARED ${StartGui_SRCS}) From 7a69c834d1de3f3f6885532a545b73225e20b4dc Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 15 Oct 2012 20:09:40 +0200 Subject: [PATCH 08/20] Add virtual method onSettingDocument() to do some delayed construction --- src/App/DocumentObject.cpp | 9 +++++---- src/App/DocumentObject.h | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index c0ac0f154..a48fac413 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -109,11 +109,11 @@ const char* DocumentObject::getStatusString(void) const const char *DocumentObject::getNameInDocument(void) const { - // Note: It can happen that we query the internal name of an object even if it is not - // part of a document (anymore). This is the case e.g. if we have a reference in Python - // to an object that has been removed from the document. In this case we should rather + // Note: It can happen that we query the internal name of an object even if it is not + // part of a document (anymore). This is the case e.g. if we have a reference in Python + // to an object that has been removed from the document. In this case we should rather // return 0. - //assert(pcNameInDocument); + //assert(pcNameInDocument); if (!pcNameInDocument) return 0; return pcNameInDocument->c_str(); } @@ -171,6 +171,7 @@ App::Document *DocumentObject::getDocument(void) const void DocumentObject::setDocument(App::Document* doc) { _pDoc=doc; + onSettingDocument(); } void DocumentObject::onBeforeChange(const Property* prop) diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 70a91ffe1..50d5b60b0 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -183,6 +183,8 @@ protected: virtual void onDocumentRestored() {} /// get called after duplicating an object virtual void onFinishDuplicating() {} + /// get called after setting the document + virtual void onSettingDocument() {} /// python object of this class and all descendend protected: // attributes From c5f683b094b32c0d775449b0f4cad0d5d2423f45 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 18 Oct 2012 10:31:04 +0200 Subject: [PATCH 09/20] Fix initialization error --- src/Gui/Application.cpp | 1 - src/Main/MainGui.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index b969ffb98..53dec5681 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1403,7 +1403,6 @@ static void init_resources() void Application::initApplication(void) { try { - Base::Interpreter().replaceStdOutput(); initTypes(); new Base::ScriptProducer( "FreeCADGuiInit", FreeCADGuiInit ); init_resources(); diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 288bc3df2..03407c52d 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -225,6 +225,7 @@ int main( int argc, char ** argv ) // Inits the Application App::Application::init(argc,argv); Gui::Application::initApplication(); + Base::Interpreter().replaceStdOutput(); } catch (const Base::UnknownProgramOption& e) { QApplication app(argc,argv); From 858ad6b2079a2250f7d619e6e41a8a4310ee6837 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Sun, 21 Oct 2012 16:57:44 +0200 Subject: [PATCH 10/20] PartDesign: Be more helpful if user clicks on a Sketchbased feature icon without having selected any sketch --- src/Mod/PartDesign/Gui/Command.cpp | 257 ++++++++++++++++------------- 1 file changed, 141 insertions(+), 116 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index cd584a3f0..1145dd8e6 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -54,6 +54,63 @@ using namespace std; #include "FeaturePickDialog.h" +namespace Gui { +//=========================================================================== +// Common utility functions +//=========================================================================== + +// Take a list of Part2DObjects and erase those which are not eligible for creating a +// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define +// a Subtractive feature +void validateSketches(std::vector& sketches, const bool supportRequired) +{ + std::vector::iterator s = sketches.begin(); + + while (s != sketches.end()) { + // Check whether this sketch is already being used by another feature + if ((*s)->getInList().size() != 0) { + // TODO: Display some information message that this sketch was removed? + s = sketches.erase(s); + continue; + } + + // Check whether the sketch shape is valid + Part::Part2DObject* sketch = static_cast(*s); + const TopoDS_Shape& shape = sketch->Shape.getValue(); + if (shape.IsNull()) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // count free wires + int ctWires=0; + TopExp_Explorer ex; + for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { + ctWires++; + } + if (ctWires == 0) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // Check for support + if (supportRequired) { + App::DocumentObject* support = sketch->Support.getValue(); + if (support == NULL) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + } + + // All checks passed - go on to next candidate + s++; + } +} +} // namespace Gui + //=========================================================================== // Part_Pad //=========================================================================== @@ -118,37 +175,30 @@ CmdPartDesignPad::CmdPartDesignPad() void CmdPartDesignPad::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Pad"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Pad"); openCommand("Make Pad"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pad\",\"%s\")",FeatName.c_str()); @@ -196,41 +246,30 @@ CmdPartDesignPocket::CmdPartDesignPocket() void CmdPartDesignPocket::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } - std::string FeatName = getUniqueObjectName("Pocket"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; - } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); - if (support == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No Support"), - QObject::tr("The sketch has to have a support for the pocket feature.\nCreate the sketch on a face.")); - return; - } + std::string FeatName = getUniqueObjectName("Pocket"); openCommand("Make Pocket"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pocket\",\"%s\")",FeatName.c_str()); @@ -272,37 +311,30 @@ CmdPartDesignRevolution::CmdPartDesignRevolution() void CmdPartDesignRevolution::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Revolution"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, false); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Revolution"); openCommand("Make Revolution"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Revolution\",\"%s\")",FeatName.c_str()); @@ -349,37 +381,30 @@ CmdPartDesignGroove::CmdPartDesignGroove() void CmdPartDesignGroove::activated(int iMsg) { - unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (n != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select a sketch or 2D object.")); - return; - } - - std::string FeatName = getUniqueObjectName("Groove"); - - std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Part::Part2DObject* sketch = static_cast(Sel.front()); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is empty.")); - return; - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The shape of the selected object is not a wire.")); - return; + // Get a valid sketch from the user + // First check selections + std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + Gui::validateSketches(sketches, true); + if (sketches.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid")); + return; + } + } + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected } + Part::Part2DObject* sketch = static_cast(sketches.front()); App::DocumentObject* support = sketch->Support.getValue(); + std::string FeatName = getUniqueObjectName("Groove"); openCommand("Make Groove"); doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Groove\",\"%s\")",FeatName.c_str()); From 2be5d3274b697461e6dd170639496f310832ba5c Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 11:19:23 +0200 Subject: [PATCH 11/20] fix import statement --- src/Mod/Surfaces/surfUtils/Geometry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Surfaces/surfUtils/Geometry.py b/src/Mod/Surfaces/surfUtils/Geometry.py index 687fe3cdd..eac10f5ed 100644 --- a/src/Mod/Surfaces/surfUtils/Geometry.py +++ b/src/Mod/Surfaces/surfUtils/Geometry.py @@ -25,7 +25,8 @@ import math # FreeCAD import FreeCAD, FreeCADGui from FreeCAD import Base -from FreeCAD import Part +#from FreeCAD import Part +import Part # FreeCAD ship from surfUtils import Math From d50fb2ba0641b8a429bad74d6122551424bf5d5f Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 14:06:29 +0200 Subject: [PATCH 12/20] Allow to use revolve tool on Draft objects --- src/App/DocumentObject.h | 2 +- src/Mod/Part/App/Part2DObject.cpp | 6 ++++++ src/Mod/Part/App/PartFeature.cpp | 14 ++++++++++++++ src/Mod/Part/App/PartFeature.h | 2 ++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 50d5b60b0..78616408c 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -102,7 +102,7 @@ public: /// returns true if this objects is currently restoring from file bool isRestoring() const {return StatusBits.test(4);} /// recompute only this object - App::DocumentObjectExecReturn *recompute(void); + virtual App::DocumentObjectExecReturn *recompute(void); /// return the status bits unsigned long getStatus() const {return StatusBits.to_ulong();} //@} diff --git a/src/Mod/Part/App/Part2DObject.cpp b/src/Mod/Part/App/Part2DObject.cpp index d9280bc46..bb59cde2a 100644 --- a/src/Mod/Part/App/Part2DObject.cpp +++ b/src/Mod/Part/App/Part2DObject.cpp @@ -193,6 +193,12 @@ int Part2DObject::getAxisCount(void) const Base::Axis Part2DObject::getAxis(int axId) const { + if (axId == H_Axis) { + return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0)); + } + else if (axId == V_Axis) { + return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0)); + } return Base::Axis(); } diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index 45e0076e9..b24a74854 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -30,6 +30,7 @@ # include # include # include +# include // includes for findAllFacesCutBy() # include # include @@ -71,6 +72,19 @@ short Feature::mustExecute(void) const return GeoFeature::mustExecute(); } +App::DocumentObjectExecReturn *Feature::recompute(void) +{ + try { + return App::GeoFeature::recompute(); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + App::DocumentObjectExecReturn* ret = new App::DocumentObjectExecReturn(e->GetMessageString()); + if (ret->Why.empty()) ret->Why = "Unknown OCC exception"; + return ret; + } +} + App::DocumentObjectExecReturn *Feature::execute(void) { return App::DocumentObject::StdReturn; diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index 5c08151bc..bd7beac3b 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -60,6 +60,8 @@ public: /** @name methods override feature */ //@{ /// recalculate the feature + /// recompute only this object + virtual App::DocumentObjectExecReturn *recompute(void); virtual App::DocumentObjectExecReturn *execute(void); virtual short mustExecute(void) const; //@} From ec3c79ad9c8f72a4d51dc79561c2ad031c3e648c Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 15:55:39 +0200 Subject: [PATCH 13/20] Compute parabola from three points --- src/Mod/Part/App/ParabolaPy.xml | 8 ++++++ src/Mod/Part/App/ParabolaPyImp.cpp | 45 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Mod/Part/App/ParabolaPy.xml b/src/Mod/Part/App/ParabolaPy.xml index 068a227f9..d08b5274e 100644 --- a/src/Mod/Part/App/ParabolaPy.xml +++ b/src/Mod/Part/App/ParabolaPy.xml @@ -14,6 +14,14 @@ Describes a parabola in 3D space + + + + compute(p1,p2,p3) + The three points must lie on a plane parallel to xy plane and must not be collinear + + + Returns 1. (which is the eccentricity of any parabola). diff --git a/src/Mod/Part/App/ParabolaPyImp.cpp b/src/Mod/Part/App/ParabolaPyImp.cpp index 7782c4254..191df05f4 100644 --- a/src/Mod/Part/App/ParabolaPyImp.cpp +++ b/src/Mod/Part/App/ParabolaPyImp.cpp @@ -60,6 +60,51 @@ int ParabolaPy::PyInit(PyObject* args, PyObject* /*kwd*/) return -1; } +PyObject* ParabolaPy::compute(PyObject *args) +{ + PyObject *p1, *p2, *p3; + if (!PyArg_ParseTuple(args, "O!O!O!", + &Base::VectorPy::Type,&p1, + &Base::VectorPy::Type,&p2, + &Base::VectorPy::Type,&p3)) + return 0; + Base::Vector3d v1 = Py::Vector(p1,false).toVector(); + Base::Vector3d v2 = Py::Vector(p2,false).toVector(); + Base::Vector3d v3 = Py::Vector(p3,false).toVector(); + Base::Vector3d c = (v1-v2) % (v3-v2); + double zValue = v1.z; + if (fabs(c.Length()) < 0.0001) { + PyErr_SetString(PyExc_Exception, "Points are collinear"); + return 0; + } + + Base::Matrix4D m; + Base::Vector3f v; + m[0][0] = v1.y * v1.y; + m[0][1] = v1.y; + m[0][2] = 1; + m[1][0] = v2.y * v2.y; + m[1][1] = v2.y; + m[1][2] = 1; + m[2][0] = v3.y * v3.y; + m[2][1] = v3.y; + m[2][2] = 1.0; + v.x = v1.x; + v.y = v2.x; + v.z = v3.x; + m.inverseGauss(); + v = m * v; + double a22 = v.x; + double a10 = -0.5; + double a20 = v.y/2.0; + double a00 = v.z; + Handle_Geom_Parabola curve = Handle_Geom_Parabola::DownCast(getGeometryPtr()->handle()); + curve->SetFocal(0.5*fabs(a10/a22)); + curve->SetLocation(gp_Pnt((a20*a20-a22*a00)/(2*a22*a10), -a20/a22, zValue)); + + Py_Return; +} + Py::Float ParabolaPy::getEccentricity(void) const { Handle_Geom_Parabola curve = Handle_Geom_Parabola::DownCast(getGeometryPtr()->handle()); From 642a3e509432816a4313aedb4792ac8ef79e5cdc Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 16:21:27 +0200 Subject: [PATCH 14/20] 0000856: Wrong inverse of a matrix --- src/Base/Matrix.h | 4 +++- src/Base/MatrixPyImp.cpp | 4 ++-- src/Mod/Test/BaseTests.py | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index b6aa5349d..63ac6db79 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -134,9 +134,11 @@ public: /// transform (move,scale,rotate) around a point void transform (const Vector3f& rclVct, const Matrix4D& rclMtrx); void transform (const Vector3d& rclVct, const Matrix4D& rclMtrx); + /// Matrix is expected to have a 3x3 rotation matrix. void inverse (void); - /// if matrix is orthogonal a special way of getting the inverse is used + /// Matrix is expected to have a 3x3 rotation matrix. void inverseOrthogonal(void); + /// Arbitrary, non-singular matrix void inverseGauss (void); void transpose (void); //@} diff --git a/src/Base/MatrixPyImp.cpp b/src/Base/MatrixPyImp.cpp index b7d594f54..5c7eda29c 100644 --- a/src/Base/MatrixPyImp.cpp +++ b/src/Base/MatrixPyImp.cpp @@ -342,7 +342,7 @@ PyObject* MatrixPy::invert(PyObject * args) PY_TRY { if (getMatrixPtr()->determinant() > DBL_EPSILON) - getMatrixPtr()->inverse(); + getMatrixPtr()->inverseGauss(); else { PyErr_SetString(PyExc_Exception, "Cannot invert singular matrix"); return 0; @@ -361,7 +361,7 @@ PyObject* MatrixPy::inverse(PyObject * args) PY_TRY { if (getMatrixPtr()->determinant() > DBL_EPSILON) { Base::Matrix4D m = *getMatrixPtr(); - m.inverse(); + m.inverseGauss(); return new MatrixPy(m); } else { diff --git a/src/Mod/Test/BaseTests.py b/src/Mod/Test/BaseTests.py index c6442ce05..97ceb4f6a 100644 --- a/src/Mod/Test/BaseTests.py +++ b/src/Mod/Test/BaseTests.py @@ -149,6 +149,11 @@ class ParameterTestCase(unittest.TestCase): self.TestPar.RemString("44") self.failUnless(self.TestPar.GetString("44","hallo") == "hallo","Deletion error at String") + def testMatrix(self): + m=FreeCAD.Matrix(4,2,1,0,1,1,1,0,0,0,1,0,0,0,0,1) + u=m.multiply(m.inverse()) + self.failUnless(u==FreeCAD.Matrix(),"Invalid inverse of matrix") + def testNesting(self): # Parameter testing #FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n") From 1c158ef924a5a178ccfd6773a8a52867c1f20310 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 16:49:24 +0200 Subject: [PATCH 15/20] View providers for sweep and loft --- src/Mod/Part/App/PartFeatures.h | 6 ++++ src/Mod/Part/Gui/AppPartGui.cpp | 2 ++ src/Mod/Part/Gui/ViewProviderMirror.cpp | 47 +++++++++++++++++++++++++ src/Mod/Part/Gui/ViewProviderMirror.h | 30 ++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/src/Mod/Part/App/PartFeatures.h b/src/Mod/Part/App/PartFeatures.h index ddaae9627..e891cee59 100644 --- a/src/Mod/Part/App/PartFeatures.h +++ b/src/Mod/Part/App/PartFeatures.h @@ -67,6 +67,9 @@ public: /// recalculate the feature App::DocumentObjectExecReturn *execute(void); short mustExecute() const; + const char* getViewProviderName(void) const { + return "PartGui::ViewProviderLoft"; + } //@} protected: @@ -91,6 +94,9 @@ public: /// recalculate the feature App::DocumentObjectExecReturn *execute(void); short mustExecute() const; + const char* getViewProviderName(void) const { + return "PartGui::ViewProviderSweep"; + } //@} protected: diff --git a/src/Mod/Part/Gui/AppPartGui.cpp b/src/Mod/Part/Gui/AppPartGui.cpp index fadff8744..48f979675 100644 --- a/src/Mod/Part/Gui/AppPartGui.cpp +++ b/src/Mod/Part/Gui/AppPartGui.cpp @@ -103,6 +103,8 @@ void PartGuiExport initPartGui() PartGui::ViewProviderFillet ::init(); PartGui::ViewProviderChamfer ::init(); PartGui::ViewProviderRevolution ::init(); + PartGui::ViewProviderLoft ::init(); + PartGui::ViewProviderSweep ::init(); PartGui::ViewProviderCustom ::init(); PartGui::ViewProviderCustomPython ::init(); PartGui::ViewProviderBoolean ::init(); diff --git a/src/Mod/Part/Gui/ViewProviderMirror.cpp b/src/Mod/Part/Gui/ViewProviderMirror.cpp index 841fb402b..b3c6d705a 100644 --- a/src/Mod/Part/Gui/ViewProviderMirror.cpp +++ b/src/Mod/Part/Gui/ViewProviderMirror.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -348,3 +349,49 @@ bool ViewProviderRevolution::onDelete(const std::vector &) return true; } + +// --------------------------------------- + +PROPERTY_SOURCE(PartGui::ViewProviderLoft, PartGui::ViewProviderPart) + +ViewProviderLoft::ViewProviderLoft() +{ + sPixmap = "Part_Loft"; +} + +ViewProviderLoft::~ViewProviderLoft() +{ +} + +std::vector ViewProviderLoft::claimChildren() const +{ + return static_cast(getObject())->Sections.getValues(); +} + +bool ViewProviderLoft::onDelete(const std::vector &) +{ + return true; +} + +// --------------------------------------- + +PROPERTY_SOURCE(PartGui::ViewProviderSweep, PartGui::ViewProviderPart) + +ViewProviderSweep::ViewProviderSweep() +{ + sPixmap = "Part_Sweep"; +} + +ViewProviderSweep::~ViewProviderSweep() +{ +} + +std::vector ViewProviderSweep::claimChildren() const +{ + return static_cast(getObject())->Sections.getValues(); +} + +bool ViewProviderSweep::onDelete(const std::vector &) +{ + return true; +} diff --git a/src/Mod/Part/Gui/ViewProviderMirror.h b/src/Mod/Part/Gui/ViewProviderMirror.h index 7e282b01a..aae6a79aa 100644 --- a/src/Mod/Part/Gui/ViewProviderMirror.h +++ b/src/Mod/Part/Gui/ViewProviderMirror.h @@ -108,6 +108,36 @@ public: bool onDelete(const std::vector &); }; +class ViewProviderLoft : public ViewProviderPart +{ + PROPERTY_HEADER(PartGui::ViewProviderLoft); + +public: + /// constructor + ViewProviderLoft(); + /// destructor + virtual ~ViewProviderLoft(); + + /// grouping handling + std::vector claimChildren(void)const; + bool onDelete(const std::vector &); +}; + +class ViewProviderSweep : public ViewProviderPart +{ + PROPERTY_HEADER(PartGui::ViewProviderSweep); + +public: + /// constructor + ViewProviderSweep(); + /// destructor + virtual ~ViewProviderSweep(); + + /// grouping handling + std::vector claimChildren(void)const; + bool onDelete(const std::vector &); +}; + } // namespace PartGui From 32628462c2cccfe65764298c115fa1c32ab40f50 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Mon, 22 Oct 2012 16:02:01 +0200 Subject: [PATCH 16/20] PartDesign, Transformed features: Improved intersection check --- src/Mod/Part/App/PartFeature.cpp | 35 ++++++++++++++++++- src/Mod/Part/App/PartFeature.h | 10 ++++++ src/Mod/PartDesign/App/FeatureTransformed.cpp | 30 ++++++---------- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index b24a74854..660146282 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -27,14 +27,16 @@ # include # include # include +# include # include # include # include # include -// includes for findAllFacesCutBy() # include # include # include // for Precision::Confusion() +# include +# include #endif @@ -333,3 +335,34 @@ std::vector Part::findAllFacesCutBy( return result; } + +const bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick) { + Bnd_Box first_bb, second_bb; + BRepBndLib::Add(first, first_bb); + first_bb.SetGap(0); + BRepBndLib::Add(second, second_bb); + second_bb.SetGap(0); + + // Note: Both tests fail if the objects are touching one another at zero distance! + if (first_bb.IsOut(second_bb)) + return false; // no intersection + //if (first_bb.Distance(second_bb) > Precision::Confusion()) + // return false; + if (quick) + return true; // assumed intersection + + // Try harder + BRepAlgoAPI_Common mkCommon(first, second); + // FIXME: Error in boolean operation, return true by default + if (!mkCommon.IsDone()) + return true; + if (mkCommon.Shape().IsNull()) + return true; + + TopExp_Explorer xp; + xp.Init(mkCommon.Shape(),TopAbs_SOLID); + if (xp.More()) + return true; + + return false; +} diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index bd7beac3b..d44272b65 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -135,6 +135,16 @@ PartExport std::vector findAllFacesCutBy(const TopoDS_Shape& shape, const TopoDS_Shape& face, const gp_Dir& dir); +/** + * Check for intersection between the two shapes. Only solids are guaranteed to work properly + * There are two modes: + * 1. Bounding box check only - quick but inaccurate + * 2. Bounding box check plus (if necessary) boolean operation - costly but accurate + * Return true if the shapes intersect, false if they don't + */ +PartExport +const bool checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick = true); + } //namespace Part diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index f871f89a0..574974a7a 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -30,8 +30,6 @@ # include # include # include -# include -# include # include # include #endif @@ -114,10 +112,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void) supportShape.setTransform(Base::Matrix4D()); TopoDS_Shape support = supportShape._Shape; - // Prepare a bounding box for intersection tests - Bnd_Box support_bb; - BRepBndLib::Add(support, support_bb); - // NOTE: It would be possible to build a compound from all original addShapes/subShapes and then // transform the compounds as a whole. But we choose to apply the transformations to each // Original separately. This way it is easier to discover what feature causes a fuse/cut @@ -162,9 +156,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) return new App::DocumentObjectExecReturn("Transformation failed", (*o)); // Check for intersection with support - Bnd_Box transformed_bb; - BRepBndLib::Add(mkTrf.Shape(), transformed_bb); - if (support_bb.Distance(transformed_bb) > Precision::Confusion()) { + if (!Part::checkIntersection(support, mkTrf.Shape(), false)) { Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument()); // Note: The removal happens in getSolid() after the fuse. If we remove here, // the histories get messed up and we get a crash @@ -193,11 +185,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void) } // Check for intersection of the original and the transformed shape - // Note: For performance reasons, we only check for intersection of bounding boxes - Bnd_Box original_bb; - BRepBndLib::Add(shape, original_bb); - original_bb.SetGap(0); - for (std::vector::const_iterator s = v_transformedShapes.begin(); s != v_transformedShapes.end(); s++) { // If there is only one transformed feature, this check is not necessary (though it might seem @@ -205,12 +192,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) if (v_transformedShapes.size() == 1) break; - Bnd_Box transformed_bb; - BRepBndLib::Add(*s, transformed_bb); - transformed_bb.SetGap(0); - if (!original_bb.IsOut(transformed_bb)) - // if (original_bb.Distance(transformed_bb) < Precision::Confusion()) - // FIXME: Both tests fail if the objects are touching one another at zero distance + if (Part::checkIntersection(shape, *s, false)) return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o)); // Note: This limitation could be overcome by fusing the transformed features instead of // compounding them, probably at the expense of quite a bit of performance and complexity @@ -220,6 +202,14 @@ App::DocumentObjectExecReturn *Transformed::execute(void) // features might overlap, even if the original and the first shape don't overlap! if (this->getTypeId() != PartDesign::MultiTransform::getClassTypeId()) break; + else { + // Check intersection with all other transformed shapes as well + std::vector::const_iterator s2 = s; + s2++; + for (; s2 != v_transformedShapes.end(); s2++) + if (Part::checkIntersection(*s, *s2, false)) + return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o)); + } } // Fuse/Cut the compounded transformed shapes with the support From 256cbd2842cc914db632c04685a8abc4fc5b18a0 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Mon, 22 Oct 2012 16:25:24 +0200 Subject: [PATCH 17/20] PartDesign: minor comment improvements --- src/Mod/PartDesign/App/FeatureTransformed.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index 574974a7a..bf005ac00 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -138,7 +138,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) BRep_Builder builder; TopoDS_Compound transformedShapes; builder.MakeCompound(transformedShapes); - std::vector v_transformedShapes; // collect all the transformed shapes for history building + std::vector v_transformedShapes; // collect all the transformed shapes for intersection testing std::list::const_iterator t = transformations.begin(); t++; // Skip first transformation, which is always the identity transformation @@ -158,8 +158,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) // Check for intersection with support if (!Part::checkIntersection(support, mkTrf.Shape(), false)) { Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument()); - // Note: The removal happens in getSolid() after the fuse. If we remove here, - // the histories get messed up and we get a crash + // Note: The removal happens in getSolid() after the fuse rejected.push_back(*t); } builder.Add(transformedShapes, mkTrf.Shape()); @@ -175,12 +174,10 @@ App::DocumentObjectExecReturn *Transformed::execute(void) BRepBndLib::Add(trfShape, transformed_bb); if (support_bb.Distance(transformed_bb) > Precision::Confusion()) { Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument()); - // Note: The removal happens in getSolid() after the fuse. If we remove here, - // the histories get messed up and we get a crash + // Note: The removal happens in getSolid() after the fuse } builder.Add(transformedShapes, trfShape); v_transformedShapes.push_back(trfShape); - */ } From a306c72993f90e89357f6e6ca6186692f1e61a73 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 22 Oct 2012 19:39:55 +0200 Subject: [PATCH 18/20] Fix documentation --- src/Base/Matrix.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index 63ac6db79..36444c667 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -134,9 +134,9 @@ public: /// transform (move,scale,rotate) around a point void transform (const Vector3f& rclVct, const Matrix4D& rclMtrx); void transform (const Vector3d& rclVct, const Matrix4D& rclMtrx); - /// Matrix is expected to have a 3x3 rotation matrix. + /// Matrix is expected to have a 3x3 rotation submatrix. void inverse (void); - /// Matrix is expected to have a 3x3 rotation matrix. + /// Matrix is expected to have a 3x3 rotation submatrix. void inverseOrthogonal(void); /// Arbitrary, non-singular matrix void inverseGauss (void); From b472ac77a0b6cd0676c1669304bf582f212a62f7 Mon Sep 17 00:00:00 2001 From: logari81 Date: Tue, 23 Oct 2012 13:09:53 +0200 Subject: [PATCH 19/20] PartDesign, FeatureGroove: fix copyright headers --- src/Mod/PartDesign/App/FeatureGroove.cpp | 42 +++++++++---------- src/Mod/PartDesign/App/FeatureGroove.h | 42 +++++++++---------- .../PartDesign/Gui/TaskGrooveParameters.cpp | 42 +++++++++---------- src/Mod/PartDesign/Gui/TaskGrooveParameters.h | 42 +++++++++---------- src/Mod/PartDesign/Gui/ViewProviderGroove.cpp | 42 +++++++++---------- src/Mod/PartDesign/Gui/ViewProviderGroove.h | 42 +++++++++---------- 6 files changed, 126 insertions(+), 126 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index baa60683e..1087809cd 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2010 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #include "PreCompiled.h" diff --git a/src/Mod/PartDesign/App/FeatureGroove.h b/src/Mod/PartDesign/App/FeatureGroove.h index ec13362d3..1bc7a151d 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.h +++ b/src/Mod/PartDesign/App/FeatureGroove.h @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2010 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #ifndef PARTDESIGN_Groove_H diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp index 79b0278fe..974e1e288 100644 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #include "PreCompiled.h" diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h index 8b82f0187..1c19bb6b6 100644 --- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h +++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #ifndef GUI_TASKVIEW_TaskGrooveParameters_H diff --git a/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp b/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp index 7b46d7681..981801c3f 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #include "PreCompiled.h" diff --git a/src/Mod/PartDesign/Gui/ViewProviderGroove.h b/src/Mod/PartDesign/Gui/ViewProviderGroove.h index 51b1adca4..6f02326e3 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderGroove.h +++ b/src/Mod/PartDesign/Gui/ViewProviderGroove.h @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2011 Juergen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ #ifndef PARTGUI_ViewProviderGroove_H From 8de40bc3a27ef081d5239d58c708158ea7d3a5fb Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Tue, 23 Oct 2012 13:20:59 +0200 Subject: [PATCH 20/20] PartDesign: move common properties to FeatureSketchBased and add some source documentation --- src/Mod/PartDesign/App/FeatureGroove.cpp | 6 +----- src/Mod/PartDesign/App/FeatureGroove.h | 10 +++++++--- src/Mod/PartDesign/App/FeaturePad.cpp | 4 ---- src/Mod/PartDesign/App/FeaturePad.h | 17 +++++++++++++---- src/Mod/PartDesign/App/FeaturePocket.h | 11 ++++++++++- src/Mod/PartDesign/App/FeatureRevolution.cpp | 6 +----- src/Mod/PartDesign/App/FeatureRevolution.h | 10 +++++++--- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 6 +++++- src/Mod/PartDesign/App/FeatureSketchBased.h | 5 +++++ 9 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp index 1087809cd..40309d496 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.cpp +++ b/src/Mod/PartDesign/App/FeatureGroove.cpp @@ -56,8 +56,6 @@ Groove::Groove() ADD_PROPERTY_TYPE(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)),"Groove", App::Prop_ReadOnly, "Axis"); ADD_PROPERTY_TYPE(Angle,(360.0),"Groove", App::Prop_None, "Angle"); ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Groove",(App::PropertyType)(App::Prop_None),"Reference axis of Groove"); - ADD_PROPERTY_TYPE(Midplane,(0),"Groove", App::Prop_None, "Mid plane"); - ADD_PROPERTY_TYPE(Reversed, (0),"Groove", App::Prop_None, "Reversed"); } short Groove::mustExecute() const @@ -66,9 +64,7 @@ short Groove::mustExecute() const ReferenceAxis.isTouched() || Axis.isTouched() || Base.isTouched() || - Angle.isTouched() || - Midplane.isTouched() || - Reversed.isTouched()) + Angle.isTouched()) return 1; return Subtractive::mustExecute(); } diff --git a/src/Mod/PartDesign/App/FeatureGroove.h b/src/Mod/PartDesign/App/FeatureGroove.h index 1bc7a151d..7e637e607 100644 --- a/src/Mod/PartDesign/App/FeatureGroove.h +++ b/src/Mod/PartDesign/App/FeatureGroove.h @@ -40,8 +40,6 @@ public: App::PropertyVector Base; App::PropertyVector Axis; App::PropertyAngle Angle; - App::PropertyBool Midplane; - App::PropertyBool Reversed; /** if this property is set to a valid link, both Axis and Base properties * are calculated according to the linked line @@ -50,7 +48,13 @@ public: /** @name methods override feature */ //@{ - /// recalculate the feature + /** Recalculate the feature + * Revolves the Sketch around the given Axis (with basepoint Base) + * The angle of the revolution is given by Angle. + * If Midplane is true, then the revolution will extend for half of Angle on both sides of the sketch plane. + * If Reversed is true then the direction of revolution will be reversed. + * The created material will be cut out of the sketch support + */ App::DocumentObjectExecReturn *execute(void); short mustExecute() const; /// returns the type name of the view provider diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index cc7f18ebe..ae037197b 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -59,8 +59,6 @@ Pad::Pad() ADD_PROPERTY(Type,((long)0)); Type.setEnums(TypeEnums); ADD_PROPERTY(Length,(100.0)); - ADD_PROPERTY(Reversed,(0)); - ADD_PROPERTY(Midplane,(0)); ADD_PROPERTY(Length2,(100.0)); ADD_PROPERTY(FaceName,("")); } @@ -69,8 +67,6 @@ short Pad::mustExecute() const { if (Placement.isTouched() || Length.isTouched() || - Midplane.isTouched() || - Reversed.isTouched() || Length2.isTouched() || FaceName.isTouched()) return 1; diff --git a/src/Mod/PartDesign/App/FeaturePad.h b/src/Mod/PartDesign/App/FeaturePad.h index 8c9787685..f70803df7 100644 --- a/src/Mod/PartDesign/App/FeaturePad.h +++ b/src/Mod/PartDesign/App/FeaturePad.h @@ -40,15 +40,24 @@ public: App::PropertyEnumeration Type; App::PropertyLength Length; - //App::PropertyEnumeration Side; - App::PropertyBool Reversed; - App::PropertyBool Midplane; App::PropertyLength Length2; App::PropertyString FaceName; /** @name methods override feature */ //@{ - /// recalculate the feature + /** Recalculate the feature + * Extrudes the Sketch in the direction of the sketch face normal + * If Type is "Length" then Length gives the extrusion length, the direction will be away from the support + * If Type is "UpToLast" then the extrusion will stop at the last face of the support + * that is cut by a line through the centre of gravite of the sketch + * If Type is "UpToFirst" then extrusion will stop at the first face of the support + * If Type is "UpToFace" then the extrusion will stop at FaceName in the support + * If Type is "TwoLengths" then the extrusion will extend Length in the direction away from the support + * and Length2 in the opposite direction + * If Midplane is true, then the extrusion will extend for half of the length on both sides of the sketch plane + * If Reversed is true then the direction of revolution will be reversed. + * The created material will be fused with the sketch support (if there is one) + */ App::DocumentObjectExecReturn *execute(void); short mustExecute() const; /// returns the type name of the view provider diff --git a/src/Mod/PartDesign/App/FeaturePocket.h b/src/Mod/PartDesign/App/FeaturePocket.h index cab10b16a..f3c65bf12 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.h +++ b/src/Mod/PartDesign/App/FeaturePocket.h @@ -43,7 +43,16 @@ public: /** @name methods override feature */ //@{ - /// recalculate the feature + /** Recalculate the feature + * Extrudes the Sketch in the direction of the sketch face normal + * If Type is "Length" then Length gives the extrusion length, the direction will be into the support + * If Type is "ThroughAll" then the extrusion length will be infinite + * If Type is "UpToFirst" then extrusion will stop at the first face of the support that is cut + * by a line through the centre of gravite of the sketch + * If Type is "UpToFace" then the extrusion will stop at FaceName in the support + * If Midplane is true, then the extrusion will extend for half of the length on both sides of the sketch plane + * The created material will be cut out of the sketch support + */ App::DocumentObjectExecReturn *execute(void); short mustExecute() const; /// returns the type name of the view provider diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp index 32acdb705..30501df24 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.cpp +++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp @@ -56,8 +56,6 @@ Revolution::Revolution() ADD_PROPERTY_TYPE(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)),"Revolution", App::Prop_ReadOnly, "Axis"); ADD_PROPERTY_TYPE(Angle,(360.0),"Revolution", App::Prop_None, "Angle"); ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Revolution",(App::Prop_None),"Reference axis of revolution"); - ADD_PROPERTY_TYPE(Midplane,(0),"Revolution", App::Prop_None, "Mid plane"); - ADD_PROPERTY_TYPE(Reversed, (0),"Revolution", App::Prop_None, "Reversed"); } short Revolution::mustExecute() const @@ -66,9 +64,7 @@ short Revolution::mustExecute() const ReferenceAxis.isTouched() || Axis.isTouched() || Base.isTouched() || - Angle.isTouched() || - Midplane.isTouched() || - Reversed.isTouched()) + Angle.isTouched()) return 1; return Additive::mustExecute(); } diff --git a/src/Mod/PartDesign/App/FeatureRevolution.h b/src/Mod/PartDesign/App/FeatureRevolution.h index 976f473d2..485c851f6 100644 --- a/src/Mod/PartDesign/App/FeatureRevolution.h +++ b/src/Mod/PartDesign/App/FeatureRevolution.h @@ -40,8 +40,6 @@ public: App::PropertyVector Base; App::PropertyVector Axis; App::PropertyAngle Angle; - App::PropertyBool Midplane; - App::PropertyBool Reversed; /** if this property is set to a valid link, both Axis and Base properties * are calculated according to the linked line @@ -50,7 +48,13 @@ public: /** @name methods override feature */ //@{ - /// recalculate the feature + /** Recalculate the feature + * Revolves the Sketch around the given Axis (with basepoint Base) + * The angle of the revolution is given by Angle. + * If Midplane is true, then the revolution will extend for half of Angle on both sides of the sketch plane. + * If Reversed is true then the direction of revolution will be reversed. + * The created material will be fused with the sketch support (if there is one) + */ App::DocumentObjectExecReturn *execute(void); short mustExecute() const; /// returns the type name of the view provider diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 3d1bcd092..1cb4ef1a4 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -75,11 +75,15 @@ PROPERTY_SOURCE(PartDesign::SketchBased, PartDesign::Feature) SketchBased::SketchBased() { ADD_PROPERTY(Sketch,(0)); + ADD_PROPERTY_TYPE(Midplane,(0),"SketchBased", App::Prop_None, "Extrude symmetric to sketch face"); + ADD_PROPERTY_TYPE(Reversed, (0),"SketchBased", App::Prop_None, "Reverse extrusion direction"); } short SketchBased::mustExecute() const { - if (Sketch.isTouched()) + if (Sketch.isTouched() || + Midplane.isTouched() || + Reversed.isTouched()) return 1; return 0; // PartDesign::Feature::mustExecute(); } diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index b99d6a15a..8c75d9724 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -40,7 +40,12 @@ class PartDesignExport SketchBased : public PartDesign::Feature public: SketchBased(); + /// Common properties for all sketch based features App::PropertyLink Sketch; + /// Reverse extrusion direction + App::PropertyBool Reversed; + /// Make extrusion symmetric to sketch plane + App::PropertyBool Midplane; short mustExecute() const;