From 3a87ded0c5e831ec001aba59374d8f617ee25fab Mon Sep 17 00:00:00 2001 From: "qing.zhang" Date: Tue, 15 Aug 2023 16:46:19 +0800 Subject: [PATCH 001/240] FIX: no soild ironing if top or bottom shell is 0 fix the ironing be apply to the preview layer of bridge Signed-off-by: qing.zhang Change-Id: I53cb4e6ff80176953c2927c1d9dc5eecc590764c --- src/libslic3r/Fill/Fill.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 0206951dc..c06259fc8 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -662,7 +662,7 @@ void Layer::make_ironing() // Check whether there is any non-solid hole in the regions. bool internal_infill_solid = region_config.sparse_infill_density.value > 95.; for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces) - if ((! internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid) { + if ((!internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid || surface.surface_type==stInternalWithLoop) { // Some fill region is not quite solid. Don't iron over the whole surface. iron_completely = false; break; @@ -674,7 +674,7 @@ void Layer::make_ironing() polygons_append(polys, surface.expolygon); } else { for (const Surface &surface : ironing_params.layerm->slices.surfaces) - if (surface.surface_type == stTop || (iron_everything && surface.surface_type == stBottom)) + if ((surface.surface_type == stTop && region_config.top_shell_layers > 0) || (iron_everything && surface.surface_type == stBottom && region_config.bottom_shell_layers > 0)) // stBottomBridge is not being ironed on purpose, as it would likely destroy the bridges. polygons_append(polys, surface.expolygon); } From 53240ddc663632ded61c4d8e9ebd2790461f0724 Mon Sep 17 00:00:00 2001 From: "maosheng.wei" Date: Fri, 11 Aug 2023 11:25:39 +0800 Subject: [PATCH 002/240] FIX: [github 2259] Maintain development mode when reopening BBS Change-Id: I9cd6bddbc58f7841499665e21dc606b35c706afc (cherry picked from commit b0c313dc367c978b85853bb1317fb8f36f228034) --- src/slic3r/GUI/MainFrame.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 686d3dc32..b83c4affa 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -177,11 +177,11 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ set_miniaturizable(GetHandle()); #endif - //reset developer_mode to false and user_mode to comAdvanced - wxGetApp().app_config->set_bool("developer_mode", false); - if (wxGetApp().app_config->get("user_mode") == "develop") { - wxGetApp().app_config->set("user_mode", "advanced"); - } + if (!wxGetApp().app_config->has("user_mode")) { + wxGetApp().app_config->set("user_mode", "simple"); + wxGetApp().app_config->set_bool("developer_mode", false); + wxGetApp().app_config->save(); + } wxGetApp().app_config->set_bool("internal_developer_mode", false); From 4bffab0ef85a9aa5922f2cc564d2491f3da39e41 Mon Sep 17 00:00:00 2001 From: "maosheng.wei" Date: Tue, 15 Aug 2023 10:51:59 +0800 Subject: [PATCH 003/240] FIX: add small disc stl Change-Id: I5c6c8ca1d4a15fc1462fe47d2e5e37b459f9a9a6 (cherry picked from commit b240831ee664c825e0f7df08d3181263dc135606) --- resources/model/Disc.stl | Bin 0 -> 72084 bytes src/slic3r/GUI/GUI_Factories.cpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 resources/model/Disc.stl diff --git a/resources/model/Disc.stl b/resources/model/Disc.stl new file mode 100644 index 0000000000000000000000000000000000000000..f19bf81fff5a7924a7a9f129cc568673aa13dd47 GIT binary patch literal 72084 zcmb`Qef(}!S?1Tl&W{|m7+(TkCPaf70+Vn=vBTNm5uXU~K+4ov|bJjnzKcBsR z_qq4=z4yA#^Lu%o{c`V={{Jp--x}-LDy99FTvK|_x3(;=zjMR?jRpDrOYHwNg8ii?;pn)fe1;!2o7TNEP?dBVr}QajAVg{V%pGA6Ink1yM@y#0IhF(J$;Uu}@8^&x`!tv~hAT`&9JugE{=k%%hAoKKH{N|i{A zW9?(V=Wbb^`!Dn{AOZk1flWf0I5YggND_zaB-^`VhhVb-(qP z&6}_K)$Ah@QKgvk=@C$=5{YrFeSGz{wA}ye<@E@jvfh03)ds0rAKC}=A6}lg`Srhg zS@sc$s8XEkryc>7Dv=n++Q$KZo0dm^l|CkfIpwPjQnfxrF#neqowj+xE$3$+k%%hA zoKKH{N|i{AW9{SQPp9RcFVn|_FsFRAL8{h=2WK&46~ z#y)U@7(Mo5>cg?^XU;#sS=5CtbKg+)oFR}PtwPP zFsFR=-&aM|`VhhVrO$i)=I`y;k$prWsuXiRJpw9KA~BA&j~y>b%TuqRj|pK;`D%ky ztq&2*-}C>yY4i6Edr9^YiKtS{`Sb{=REfkm);=EhoV5IzkI=`2FsFRAL8{h=2WK&46~#a zBN9=inDg1MLqMfUB*wA!@x(`_<=!jlV?vlyzSq7+dkKgve%|kwWPWBOrs8Y=N z^a!X_iNrY8J}!K4T3&ZKeM|^*%2yktYJG@c{sC9~$>tXy{-3jtNJN!luk1^Yfabz5 zL;PDy?c*!=NXy~P^l@QJm@~fGAXV!_1oJoEdhO7O5UCQ0ajbn@ z^N)8fPJTUoObBzzR~w{ieTZQG9fw@E`2!z6JNt-4R4L|sdIVIeL}DCkANT+Gos0Wi zLLU>tobuHMsahW*n19@DJ|h+zKc=ij)w^ML1NACZVE#hg!%fJ&7}jAQNNQ#gm7z?Chf^;{QUN)!RA*W}-@n z<5K%L>w|YJ>^SPs8or>IMzPSJL`_c5r@*pgfORk zwLz-ZhY03h`m^_1-RHb#WFL`;D#e^nkAO;*NQ`6ccg?^XU;#sS=5CtbIId&+UuH-mx{G6Pys{l&>~O)%p;@{PGD0t$zL!CuJXz zh$_XLPmh2~l}LP zs8or>IMzPC^P$@ptFO_=gfORkwLz-ZhY04MeA>aQ8&5eQ`-ntTDdv271XQX-VjOE9 z=e^k2-FF8K@h(uH==6retRH{T`9BUstf93YY z{vW5031Lq8YJ*g*4-w42X*g_k%pWYWk4Qw7V$P>WK&46~#NU)`tk@-*?&Jt3!7U*+(RzN-^itBcM_x6609=_>rHueesZY)5nA`r+l?Rs@8`H z=AUrek*n8Ty)FBQL{ur}e0l^_szhQOYaj2u*X@gIeuq9LggND_4N|o}L@@u%V~<*W z_5H_YACZVE#hg!%fJ&7}jAQNN`kVJI?*D4~m=NZauQo{4`VhhVdCz~u>ho_oCi{p) zR4L|sdIVIeL}DCkA3Lw#yZG_*>0?5eQ@;Aoc~P}KL@@u*Hy*Rve$FGZk4Qw7V$P>W zK&46~#+VO~^vX4kam154PM?j@YB*wA! z@!Hq#UF4t}7ACZVE#hg!%fJ&7}jAQNNfBxv+#Xav!9}~iy^3?{ZS|1{qf8r@8tTs+R zIQxi1R4L|sdIVIeL}DCkAFsIE-o?}QqmKz;PWftsRILvY%)jWMC#^p5r3Ypok%%hA zoKKH{N|i{AW9{SH-`uk}?UoU#NW`zgfORkwLz-ZhY03h`Abh({r-FJn|(wgsuXiRJpw9KA~BA& zk1IdCXYtX`(8q)@r+l?Rs@8`H=0CdUsjFw)en9pSiKtS{`Sb{=REfkm);_kpbT|zw_v|AQQKgvk=@C$=5{YrFeZ1?1dloPs8or>IMzOPKXcC_8GTF$bIMm6q-uSLVE)Aa{_NFh z-`s~+~6T+PG)qh_VRqI0p^T&Sf^wlpsc&}dp z@4saN5mkzzNvTIbqe_V5Qu}z<5qlOlokAZI!kqKfzpsj_^&x_JKZmpOGc(yoB%(?& zXVfF0QY8}OSo_#GaL?jF$CvM`;3@0PM_+A_s`a6LF#q^_pSk)UFT5%Hh(uH=&h=A| zfJ&7}jAQNNNA9*~@$Y_;J|=`Y<*OfOD5}WK&46~ z#q7+dr~T0LRu6dbjoC*eqDnF6(<7i#B@*LU`*_+{ zb}ugbLHd{w=9I5CNY(lf!Te>nowa(%2{&XPk%%hAoKKH{N|i{AW9{Rj&+J}2^wzuO z_lXn2obuH_e-u^gLqy46d-m$QhhLX{L?Wsbb3XfZ2&hzv#5mSIp8t{EiwnL=9}~iy z^3?{ZS|1{qKl)WKSl#d2*JdA)h$_XLPmh2~l}L~O)%p;@{Bu5a&g#sk zd@%cnL{ur}e0l^_szhQOYai!dx_j}Fx6{XjFsFRAL8{h=2<8v{xfiXj_{NplMGRap&&ErI*sjgfORkwLz-ZhY04+_}GhAm+rVc`-ntTDdv271XQX- zVjOE9H=eV5vF%*?m=NZauYMm(QMEoqFz?sAuKY^Y>?0CUrI_>S5m2cTiE*rb9C_yM z#plnUj|pK;`D%kytq&2!$BrEDJ|h+saw|J>F0zHmwQ5s9c$T;|gupi-qmtiRMg?s4Mo#d{t}9}~hH^3?{Z zS|1{q_iOZ5e&v1k5s9c$%<1$9s8or>IMzPi`qC?$HfQx>+wnYm=NZauQo{4`VhhVgI@9S)nDKAAF_`~M3rLBr$<1gN+iay_VIrY z+P(O(575ViFsFRAL8{h=2@U1cl<7W zObBzzR~w{ieTZQG37^}!+PHFS_7RDwQq1}E2&hzv#5mSIHhyUL;<}6JV?vlyzWQ;7 zqH2AJVEzrKzG8LF-+kja>?;ycr5Ku&dIU78gg7p>kIlR9Ui`*6^f4jKIbUs%s`Vj) zdB10S<#%FdACZVE#hg)(fJ&7}jAQL%+lId{`A_sQAbIMm6q-uSLVE&EQT(COqs-v@yNJN!l&ZkE}rAj2mvG(!Y zw0m*#kI=`2FsFRAL8{h=2$&n-dQF4h(uH==8Sp-RpSivzkNnnY9FYJ-YDGG5LvF*1FF_XoNY>F zR##&us!M`(W6b>pBLBaS`xs}UN+eL5QSAe-GkT+7+k`;U;6tj`hY04&cS-gUiKtSH z((CUl5c%f-GeNDWQYC2eV&%(99eVI@{M?~83gQWYq``+&tq&2*m!H~Qpdt}ficvbH zK&)qiT2ZA+Bz!bR_3MG(gXoQdZ4&}XgAb`%A0n79zeTf;NJN!ll=gd6_?sF;{yTx0 zpjK3=5;S?S@}+t`@OKHlQLt@7AZhR+RqI0p^X0Ev_7RDwQjF3m1tS05#!OHvs#J-D zkH)BeJ@7sOy-~1jLLh1IAyw-`1oP!xM)nbjs8Wp5DFq_GkHSn)E2>n9gpbCk_JQ|p z=#7GH69P$t52;!oBA74l`m&EmM3rKcUcXPw-&b=4G|D5+iq7+d z2 zFcZ{@DpexkqcN&|;5ZC=qhQ;FK+@nts@8`H<`4PG%T^ya@WkvR5>cfXrBez-K2C+1 zpjK3=5(yuTQSAfA#n2lC+a?5(1|L$jK148o(^PNJN!ll=hx!Jdz3`AIHT^P%Elb z37WiE`BMGf#c^ZwM!~iTfuzBQRILvY%$K9i*+(RzN-;{O6o`CW9Wz0#s8S^oJ{qI? z^}um_^hUw934x@+hg7W(5zLqK2H8g>qDnDJ`@-`E`SqA1AWol+q3btD)1Oi(MTR4D@( zj8W|a*R7y83bsuMBn>{KYJG@czFhT^eMBOv6r*%XfymeOU?!*)RjNe7M`Kj`z;#6E zje>0x0!f1psahW*nE$q4h4i>1uFF0m5mky&+OJ(7iF} zM!~iTfuzBQRILvY%zH1H6*|O#ibPZ?MrpqnZ6xw_h?og#MU^U%@X;96K5*S5dZS?5 zgh0~ZL#oz?2|6r;4i6B>zpT_|RPT2ZA+Bz!bRwGUi}iry&LHX)ES z_>ijgA%gk;b>A~r+n;+=_7RDwQjF3m1tMRkicoP9(hsuZJiN`c7NO=Bjg6;-N4!bf9N`^eX6d$$;Dn-EAEd`Q*$5W)Ok ze)ja$iHGjZJ|YoSicvbHK=3+tp9yM3l`4_&(HPY}aNRt5qhQ;FK+@nts@8`H=Ktb1 zpS}9(&0GBaLb6Cim12}mDG>R-0?Y)pqDqxW_-Kr3AGnVJy-~1jLLh1IAyw-`1oMwO z;ndZ~S6j1>NJN!ll=hy2Ba!d(z)Vmps#J-DkH)C>f%{6(8wJ}Y1d;|HQnfxrFu(sd zPhLIhwRg`xA`w-JQQGg3ABlY54Q7H`QKd>Gd^AS258UU2-YD2MA&@lqkgD||g86cn zQ1%gts8Wp5-UF3)B7w;FL18AS6;-MPOcfXrBez-zHbvVL9M7#B@#XwquK}V6Gd+nY?}~B8hl9A`Vhf4-w4Y`Gd^AS&>w){I(HjNZCIpfOA5yhGL@;0O!p=S- z5mky&I;BA5`^+&D)QT!qBH^Pks(s+TcJxNUwh4ix!G~0>4-w4&!h060Z!HeXJ|YoS zicvbHK;--WF%#5^DpexkqcN&|pw9q$qhQ;FK+@nts@8`H=1=^{u=+ojAD(?gBB~Ul zv>$02iQI<)GeNDWQY8{T8l&0=`aYmH3bsuMBn>{KYJG@c{`sqIt0VsT$m}B$QKcBA z{fNLwq7+dSAX!>)l-i-D*K2;R4GPj z-{VN+J|&n5YDJYQk?_$N)jrS{1uM2q2qXn9 zgpbCk_JQw6yo%U1A&@lqkgD||f_Z#T;X4IXB%(?&N~aWv+*b)RL9M7#B@#XwquK|4 zL*St0 zn-EAEd`Q*$5W)NduQ+^l?jH@=M{KYJG@czH~{;J|YoSicvbHK;%Afmk%%hAD4kLua$j)F1ht|{l}Pw#jA|d~T+XAy>@Y4*kz)UL zs9GP|2lF^ajU&(87wck6R4HctKzL$GP&Ljl|J#_Yec+4(j?&K(NE%)bsahX#-~K7p z&l%uM0H~T6XD9-tDoHfC=34x@+hg7W(5zLn^|Jg?* zqDnDJ`w?Y6NdQECjsa$ZT2ZA+(B#F+7pKO*gE%9Hvslh-`GYn4-w3lr;=nJk%%hADDBrX@X06H z#~cBT@`&?d{KYJG@c9@hZi%s!|{M3rKcPAL%iIXIXJYDJYQ zk?_$N)!$dRq61e!VB3U1(%?g?)`tk@aZLuUv;Y-}s8Wp5eqL=P@^gtW6V!?-RU+Y| zF{*uB=vUa_suXOS5J(z)Tv$}C4-w3JFPTkT`2s2uQKi^5z62s&81@lW%0r(QD_^Sb zD_rq}tAw!a!r+No9}PaFYJG@czC6_``-ntTDNcC_M1F1;W`bH#rAj1xG)DF7fotJ# z)fTo*2qXYz zZ9*Vv@F7*}Lj?2QOJ);S>Vb+xR4GR3lmd~TYloSjR#d4H2_KD7?E_b6;;Ke$n-EAE zd`Q*$5W&3nlG((Slb|9IRfDHqDnDJrxb|%TvW^iwW3OuNcd=s>emBT_~WX0Y?}~B8hl9A`Vhfq7+d-b-c^9b!O5BB~Ul zbV`9pa|ATXBhHJJFO?76k%YT=ux&yhY49Oc>q7+d-b-c^9b!O5BB~UlwEz7WiTqq` z%mlTfN|i|XXpHLbE8HQ5yQ;8lLLh1IAyw-`1oPfYW)pXAfr>;_DMo2OuQn3-Ip>%O zYDJYQk?_$N)jn{?9`16(wh4ix!G~0>4-w3JFPTl;Ne3ztQKcBA{W^e=$j_a}Oi(MT zREdO-#;EpzJ1BA2A+}8jBn>{KYJG@c-h0Vx;?71;k%%hADDA(mMk37-&?t{MFIK+z ze#W13+*^ygK(TE?AZhR+RqI0p^WIBl6L*?|ibPZ?Mrps&b|lgq0gdvA^J3*oR|34x@+hg7W(5zKopnO*2q z04fqur5L4C3PhSCpiv%iUaWkne4s-Gx;kLngh0~ZL#oz?2*w_Z!fCWhlsV0ZN*2L67(d3`#=|+eGyQp5{WWe>jS-(^z$)GIB0`Z ztq&2*qeoHszDkjZD#e^nkAO;*NR-i9ALxCh-&eDQgEmOj`Vhf9dPbF>^Aw4wQq1}E z2&hzvL>aC1fnH?#`!P#6=*QuTs`Vj)dGzoqzjsq4qDnF6(<7i#B@$({)(3jS>F@b0 z;h^^^Dyr6p2nn z5>cg?^XU;#sS=4YTI&P76ZL*~mT=GpsahW*m`BgS@;)&|BB~T~K0N{|RU%PFYki=X zr9OYm5)RrRRqI0p^XLIt-nXYnM3rLBr$<1gN+il?tq=4T)#t%k!a?sFRaC7H5zM0} zXZakJA`w-JIiDT@l`4@aqqRQJ>s6o6X9)-WdY__deTZNlJyOf(+7yYXQq1}E2&hzv zL>aC1f!@11UNTEK=&wgnwLU~JkDj&VI75m=R4L|sdIVIeM52t=`Z&aUA?x_nEa9LH zQnfxrFz>x&wxdG~_7#b!QVdN>Jpvk4LcCtA^?}~hI-WR7IBJ7btq&2*doP*o=n#Xw zMIx#cLz7aEfJT)NuNP~5pjWt#@6HmA`up~xYJG@c9zC|vAqIPkL{uq;CLb5wCjpHr zAzm-m`ath?9dDl{9QF4lMb-Kc!904NqeBe#7Kx}*3{5^xy-xxfRYJU8to4Cj`a1tH zOE_wSRILvY%;z5TJa6Dvg0e2QM3rLBs7FAhN+il?tq(lgKnQa7ESn z5Wzg2DO0WkNRfyt#hg!%fJ&7}l+jurcvg|FFPSAAv_Y!YhY05Jj30D}!M-99Rf?fW zsYgJgN{H8swLb9dC|&O}OE_wSRILvY%;T9$?uF!jrAAuSi6dVrcyMZij$Il@PBNYklC^YPue7mT=StsahW*n8!28 z@T4*9EfP_s7@CxN1T?CIc)eKb1JAnC^@+2Dqc%v@`Vhf9o)L#9zhQ5Yh$_X<_|Hd& zfJT)NuNP~5;Ms$^UUZgl)CQ?qA0n8?GyCu)KI|&03hcow9t z-<>5KwLz-ZhY05J3`IN{5qpb7R4Ilgr5*u|Dj{Ak*80G+IdwhtEa9jPQnfxrFppL z72*Hz{)t7^`Vhf9p23SJ>w=F&R4L{@dPJ;5qKwx1z_XooKaTcY5&jSVdtOwn4-w4c znaFt3G5APCm16FrN5o1b%4n?*JZoF`M`_;`;s5aKGK#A8A%b~4qq^Kzlp+yTin)&- z0hKC|D5JGL@a%KluQp3KXoFO(4-w4cnc;X6IQA8Zs8S3~N<9J^RYJU8to3oaKZ{=X z56%*f+8|ZyLj?1F7u|pkG1yxqqDnC|`M$e-640m;;`L&!kEiXob*cL~X9-8W?_g22 zK14A8y5kQTe)QA%KFAb_s8Y-s^$4g`i9{K#^>NSpZe8mB+F8Ou8>DJ|h+y9DG9Ai& zsVNdsrI_>S5m2cTi85O2gqH2AJVE*%OIc7NT`MEDnibPZ?#{T?R zdWV2Ul@PBNYkfTA-CLLFdIH5P;dvXRYJG@c{;Tglc6jEoxld7wL{urp{!;1@(5MpP z^O)!T+A+?M-BrAS1TV(ia9vvvq*R0;8VvDU}_ zANQa0(vNJGaMb(a6jkd(1oMaP8iw~>miu_6NJN!l&ZtK~rAj2qXswS|->`Lwt|!<& zOL*P}sahW*m_OzZ76UrOpjITJN-;Dk^$2KG3GsTd*2n5=TbJm10>v!hc^jl^eTZQG zo|hayoc+azWFL`;D#h5JzX$9P(5MpP^Op%Bx z#n@j;Jpvk4LcCtA_3^5MHkRmm0>v!hc^jl^eTZP*KhqASPil%pR4K;(68fa>lYmB* z5U&?&eH?M<#u8mmpqM2*Z-Z2=4-w2?yZfobr|&o*e_ur+suW{?DfI|wR0;8VvDSzE z)v z-x14GhX;Hz_t{R7P+ic9u|NL~=n&AT65{n@t&dkeeZ#LqXaDwD!ciNfYJG@c{^`H{ z?BQ+S+LFJoA`w-JIinr{l`4@aqfLA~XJd)3C)hqqc;0;!RqI0p^H2Qq(}%Y`DEFaH zk%%hA*q>j^(;=WyCB*B+S|3NAy|F~s6DVd0&-?SEifZDc^5^Gp26Tu)tw^XYXvNUv z=K}1LfJT)NuNP~5?0m__61`ENm?b>##~F&M^&x`!GwyxnuzX>DPD6@BR4K;({O?DH zfJT)NuNP~5?0Ch-61`ENm?b>#{Q!!p^&x_Je+tG>o|};(5mkz@zx>>ceG<^965{n@ zt&jU$vav+h6DVd0&)XnX>q7+d{#25oJjWzOBB~T)fBrw$A)rwu#OuXcA1A+lV~MUO zP|OmZ_xo6is`VkF`1sCQ!{biP&y`7$h$_X{pZn+#(5MpP^s(tdIH5P;dvXRYJG@c-mh62 z&>;r3A`w-Jp~=s|+9v^xDj{Ak*82F|2R4@IdIH5P;dvXRYJG@c-mf7W&>;r3A`w-J zp~=rB+b02yDj{Ak*82FFk8CW_^#qDp!t*vr)%p;@ykFBdphFC5MIx#cLzABqw@(5Z zRYJU8to3o~H5*HGJ%M7D@Vxg)EvnXs2mKdRYJU8 zto3p4Pi`#H^#qDp!t*vr)%p;@ykGM=phFC5MIx#cLzADQxK9EaRYJU8to3pB^&3lc zJ%M7D@VpIDwLU}?A3Jso=n#Wik%%hA(B$V@?vsEN-;Dk^$2KG3GsTd*2kVNZ!FRE1d3V0^EOD;`Vhgq zU!y;uLkwy~BB~Talb`##PXZcMLcCtA^>Or9Hv!hc^jl^eTZP*@0l3TAqKS~ z5mkzz$q7+dC){%W@Rt|m=OU*_M3rLB zs7FAhN+il?t&f*~(|=!;=WWjt4%#49>q7+dU;nF@4If^fm|u@bM3rLBr$<1gN+il? zt&i8;w6R3j6KtO)Jnz@_6;q7+d58L_j;jp_Mo_$0jsuXiZJpw9KB2h+beO&t8jU{@cVEZiL zc|X2eRILvY%)jHPox>qdJ}~=;L{urp{!;1@(5MpP^cfX8h`wG zhk!yvxJf2=Rv4iA91$pPes{>>Vk+W#jIRD zN8Kd>l`4@K$Jz%zXQDUCEMcVh`5da&hxWmI`IMSxrMlP>Rf<`;M?j@YB*wA!fzSQu zjWSCZDIPC@s`a6LFkg-uWFM-FEm5VIm3stKszhQOYacic^I-2OGfNmL9>0RB^`U(* z|0{mn=l4%MG5b(mY>6txtlT4@QY8}OSo^?nG4w{6C5#l0CqmWw&_0;|ydQ@6txtlT4@QY8}O zSo^?nWAsLuC5#l0w?ozX&_0+i$EmXq)y0;mQq0Od0xDG^F^;tl9LGm*lv%<^@%#r= ztq<*k`EnK@`%qnMi7Lgc+#{e;B@*LU`@ne>^hTK_j1H^d3p3knI()AuV;X&^`U(*f5>Og z86LmwgV~4bVoOvhX5}6Ml`4@K$Jz(3lR$5jS;9#1`Vy#GAKC}=<+_aQLv^twsuZ(w zkAO;*NQ`6c1J|vfH_9wwq!btJ@M5tOH+6VLAOJ+ca z7*MKQKvJce-5mky=xko^yN+iay_JQky z(Hmu!FjBmp8miWZ_Q8C)4mtZ!U2KUe#jM;Tpi(6gm0w4X&*S_|j_c;p8)cTTLgf1mpqlsy zv-NinZ+!Ofpl@vPvkbgTKt#T#z5FjIX5}6cE0Gw-`t`tl4CswAOBgBM{{dC&L;nlR z|L$W?9p3%vt=Wg_VoOvhX5}6Ml`4@K$Hs@>kAvPQvxJf2{WwsyKC}LlzutMbfqoA7j2(w+^C6s-rZuSvWxF1LV zZ+!y$S0&D69P8Hu_gy{Ad&D zp?xra&Sy>9S#g?d2%*s6i zDpevejC?2kvV}Z<*> zxko^yN+iay_JO`ASZ4_%#eOnSwLY{D=F^*x8J_lnM`RzWi!D*5xXhJoZ>&@_{jyOx*(!T zF)R0oSc$|q);{o80ly1p2_waRWKgv};%xm%HvT&ozez!K&dW>s8YMJpIN=}fdk%&gHl}(QKgubdqk{6VjOE9 z_>_mwHnW70vO%iWN1UxciNHTY;gb=lNJN!lR_+n85{YrFeV}hCK5NbrMvDDjp=y1^ z*{1aS@4fHv%3pd)_My5UqDnC<_Xwy|iNrY8K5!HSpZ#YEBgOu^P_;g^59VL={R4(y zx#OwXhw5TWR4HcV9s!jqkr>C?2adtuSj;S8q}UG`s@8}0!Myj98PFjHlMJKUv6+!QsdnDAffKRf<`;N5o1b# zS-Ct1>n;hXREfkm);@489Iow}C5#lGuLf1?L;GMJ*O1}LFi@(CEm5VIm3u_2L}DCk zAGqoe*V@ezMvBk7gR1orXX|I={hB^psRv4RK}3~eR_+n85{YrFec&okT>Cgn7%4wL zSX8Z#I9q?>;V)ml9am0*ibPZ?X5}6cE0Gw-+6S)6#kHujgpuO&Afak~#M!Q&ikN+< zE{Ld7%*y4-i+4#trAj2mvG#$hq;YNVEMcVhd`_rZAKC}=<++x5R;r6FQKgubdjwRf zL}DCkAGm5A*J{raMvBi%g{t+TeK7C6WVYiEm5VIm3u_2L}DCkAGnJE*Urxp zMvBj`g{t)tXS;riYxbeKAfie!E0-t5-X#H*Dv=n++6V6Hz`YE!gpuO&grRDEXdld% z=kVrPsV=rem10)z5m2cTiE*rb;5o&(w`7(uQhdHMRILx~gL&^IvmG5`K&dXaM3rJz z?h&yPiE*rb;I1d!>oZFjDL!u-s@6xGZA#utW;;5>fKpu$QKgubdqk{6VjOE9xC;&U zUd<9liqAiXs`U|P>sLPi)?>Eg&Mi=?3nHo%vvQA!l}LDb5pdt}fidnfw#7ZQ_vG#$x%5g9CEMcT|6ti-Vh?Pi;W9AppendSeparator(); } - for (auto &item : {L("Cube"), L("Cylinder"), L("Sphere"), L("Cone")}) + for (auto &item : {L("Cube"), L("Cylinder"), L("Sphere"), L("Cone"), L("Disc")}) { append_menu_item(sub_menu, wxID_ANY, _(item), "", [type, item](wxCommandEvent&) { obj_list()->load_generic_subobject(item, type); }, "", menu); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2452dfb52..51e90d728 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2037,6 +2037,8 @@ static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf mesh = TriangleMesh(its_make_cube(bb.size().x() * 1.5, bb.size().y() * 1.5, bb.size().z() * 0.5)); else if (type_name == "Cone") mesh = TriangleMesh(its_make_cone(0.5 * side, side)); + else if (type_name == "Disc") + mesh.ReadSTLFile((Slic3r::resources_dir() + "/model/Disc.stl").c_str(), true, nullptr); else if (type_name == "Bambu Cube") mesh.ReadSTLFile((Slic3r::resources_dir() + "/model/Bambu_Cube.stl").c_str(), true, nullptr); else if (type_name == "Bambu Cube V2") From 468fc828d0d8cd8f1ff49defa2483e6e2f34f9b6 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 2 Aug 2023 17:52:46 +0800 Subject: [PATCH 004/240] ENH: CLI: support system preset passed to CLI Change-Id: I933d49e677c8610c3fe90bbe7d455f94d950ae96 --- src/BambuStudio.cpp | 156 ++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 43 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index db099d1aa..bfb35c4d2 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -559,6 +559,7 @@ int CLI::run(int argc, char **argv) std::vector upward_compatible_printers, new_print_compatible_printers, current_print_compatible_printers, current_different_settings; std::vector current_filaments_name, current_filaments_system_name, current_inherits_group; DynamicPrintConfig load_process_config, load_machine_config; + bool new_process_config_is_system = true, new_printer_config_is_system = true; std::string pipe_name; // Read input file(s) if any. @@ -784,8 +785,8 @@ int CLI::run(int argc, char **argv) } //} - auto load_system_config_file = [config_substitution_rule](const std::string& file, DynamicPrintConfig& config, std::string& config_type, - std::string& config_name, std::string& filament_id) { + auto load_config_file = [config_substitution_rule](const std::string& file, DynamicPrintConfig& config, std::string& config_type, + std::string& config_name, std::string& filament_id, std::string& config_from) { if (! boost::filesystem::exists(file)) { boost::nowide::cerr << __FUNCTION__<< ": can not find setting file: " << file << std::endl; return CLI_FILE_NOTFOUND; @@ -794,7 +795,7 @@ int CLI::run(int argc, char **argv) try { BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< ":load setting file "<< file << ", with rule "<< config_substitution_rule << std::endl; std::map key_values; - std::string reason, config_from; + std::string reason; config_substitutions = config.load_from_json(file, config_substitution_rule, key_values, reason); if (!reason.empty()) { @@ -807,7 +808,7 @@ int CLI::run(int argc, char **argv) if (from_iter != key_values.end()) { config_from = from_iter->second; } - if (config_from != "system") { + if ((config_from != "system")&&(config_from != "User")&&(config_from != "user")) { boost::nowide::cerr <<__FUNCTION__ << boost::format(":file %1%'s from %2% unsupported") % file % config_from; return CLI_CONFIG_FILE_ERROR; } @@ -857,8 +858,8 @@ int CLI::run(int argc, char **argv) // load config files supplied via --load for (auto const &file : load_configs) { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(file, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -871,9 +872,18 @@ int CLI::run(int argc, char **argv) flush_and_exit(CLI_CONFIG_FILE_ERROR); } new_printer_name = config_name; + if (config_from == "system") { + new_printer_system_name = new_printer_name; + new_printer_config_is_system = true; + } + else { + new_printer_system_name = config.option("inherits", true)->value; + new_printer_config_is_system = false; + } config.set("printer_settings_id", new_printer_name, true); //printer_inherits = config.option("inherits", true)->value; load_machine_config = std::move(config); + BOOST_LOG_TRIVIAL(info) << boost::format("loaded machine config %1%, type %2%, name %3%, inherits %4%")%file %config_name %config_from % new_printer_system_name; } else if (config_type == "process") { if (!new_process_name.empty()) { @@ -882,10 +892,19 @@ int CLI::run(int argc, char **argv) flush_and_exit(CLI_CONFIG_FILE_ERROR); } new_process_name = config_name; + if (config_from == "system") { + new_process_system_name = new_process_name; + new_process_config_is_system = true; + } + else { + new_process_system_name = config.option("inherits", true)->value; + new_process_config_is_system = false; + } config.set("print_settings_id", new_process_name, true); //print_inherits = config.option("inherits", true)->value; new_print_compatible_printers = config.option("compatible_printers", true)->values; load_process_config = std::move(config); + BOOST_LOG_TRIVIAL(info) << boost::format("loaded process config %1%, type %2%, name %3%, inherits %4%")%file %config_name %config_from % new_process_system_name; } PrinterTechnology other_printer_technology = get_printer_technology(config); @@ -905,9 +924,9 @@ int CLI::run(int argc, char **argv) std::vector load_filaments_index; std::vector load_filaments_config; std::vector load_filaments_id; - std::vector load_filaments_name; + std::vector load_filaments_name, load_filaments_inherit; int current_index = 0; - std::string default_load_fila_name, default_load_fila_id, default_filament_file; + std::string default_load_fila_name, default_load_fila_id, default_filament_file, default_filament_inherit; DynamicPrintConfig default_load_fila_config; if (use_first_fila_as_default) { //construct default filament @@ -915,8 +934,8 @@ int CLI::run(int argc, char **argv) const std::string& file = load_filaments[index]; if (default_filament_file.empty() && !file.empty()) { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(file, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -928,10 +947,16 @@ int CLI::run(int argc, char **argv) flush_and_exit(CLI_CONFIG_FILE_ERROR); } + if ((config_from == "User")||(config_from == "user")) { + default_filament_inherit = config.option("inherits", true)->value; + } + default_filament_file = file; default_load_fila_name = config_name; default_load_fila_id = filament_id; default_load_fila_config = std::move(config); + + BOOST_LOG_TRIVIAL(info) << boost::format("loaded default filament config %1%, type %2%, name %3%, inherits %4%")%file %config_from %config_name % default_filament_inherit; break; } } @@ -947,8 +972,8 @@ int CLI::run(int argc, char **argv) current_index++; if (!file.empty()) { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(file, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -969,10 +994,17 @@ int CLI::run(int argc, char **argv) record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]); flush_and_exit(CLI_INVALID_PRINTER_TECH); } + std::string inherits; + if ((config_from == "User")||(config_from == "user")) { + inherits = config.option("inherits", true)->value; + } + load_filaments_inherit.push_back(inherits); load_filaments_id.push_back(filament_id); load_filaments_name.push_back(config_name); load_filaments_config.push_back(std::move(config)); load_filaments_index.push_back(current_index); + + BOOST_LOG_TRIVIAL(info) << boost::format("loaded filament %1% from file %2%, type %3%, name %4%, inherits %5%")%(index+1) %file %config_from %config_name % inherits; } else { if (use_first_fila_as_default) { @@ -981,6 +1013,7 @@ int CLI::run(int argc, char **argv) load_filaments_name.push_back(default_load_fila_name); load_filaments_config.push_back(default_load_fila_config); load_filaments_index.push_back(current_index); + load_filaments_inherit.push_back(default_filament_inherit); } continue; } @@ -996,8 +1029,8 @@ int CLI::run(int argc, char **argv) { for (auto const &file : uptodate_configs) { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(file, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1048,8 +1081,8 @@ int CLI::run(int argc, char **argv) } else { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(system_printer_path, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1071,8 +1104,8 @@ int CLI::run(int argc, char **argv) } else { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(system_process_path, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1086,7 +1119,8 @@ int CLI::run(int argc, char **argv) fetch_compatible_values = true; } - if (load_filaments_config.empty() && !current_filaments_system_name.empty()) { + //20230802 lhwei: remove below codes, don't replace filament currently + /*if (load_filaments_config.empty() && !current_filaments_system_name.empty()) { for (int index = 0; index < current_filaments_system_name.size(); index++) { std::string system_filament_path = resources_dir() + "/profiles/BBL/filament_full/"+current_filaments_system_name[index]+".json"; current_index++; @@ -1095,8 +1129,8 @@ int CLI::run(int argc, char **argv) continue; } DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(system_filament_path, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(system_filament_path, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1106,8 +1140,13 @@ int CLI::run(int argc, char **argv) load_filaments_name.push_back(config_name); load_filaments_config.push_back(std::move(config)); load_filaments_index.push_back(current_index); + std::string inherits; + if ((config_from == "User")||(config_from == "user")) { + inherits = config.option("inherits", true)->value; + } + load_filaments_inherit.push_back(inherits); } - } + }*/ } else if (is_bbl_3mf){ fetch_upward_values = true; @@ -1125,8 +1164,8 @@ int CLI::run(int argc, char **argv) } else { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(system_printer_path, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(system_printer_path, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1147,8 +1186,8 @@ int CLI::run(int argc, char **argv) } else { DynamicPrintConfig config; - std::string config_type, config_name, filament_id; - int ret = load_system_config_file(system_process_path, config, config_type, config_name, filament_id); + std::string config_type, config_name, filament_id, config_from; + int ret = load_config_file(system_process_path, config, config_type, config_name, filament_id, config_from); if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1175,7 +1214,7 @@ int CLI::run(int argc, char **argv) if (!new_printer_name.empty()) { if (!new_process_name.empty()) { for (int index = 0; index < new_print_compatible_printers.size(); index++) { - if (new_print_compatible_printers[index] == new_printer_name) { + if (new_print_compatible_printers[index] == new_printer_system_name) { process_compatible = true; break; } @@ -1185,7 +1224,7 @@ int CLI::run(int argc, char **argv) } else { for (int index = 0; index < current_print_compatible_printers.size(); index++) { - if (current_print_compatible_printers[index] == new_printer_name) { + if (current_print_compatible_printers[index] == new_printer_system_name) { process_compatible = true; break; } @@ -1223,14 +1262,14 @@ int CLI::run(int argc, char **argv) if (!process_compatible && !new_printer_name.empty() && !current_printer_name.empty() && (new_printer_name != current_printer_name)) { if (upward_compatible_printers.size() > 0) { for (int index = 0; index < upward_compatible_printers.size(); index++) { - if (upward_compatible_printers[index] == new_printer_name) { + if (upward_compatible_printers[index] == new_printer_system_name) { process_compatible = true; machine_upwards = true; break; } } if (!process_compatible) { - BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1% : current 3mf file not support the new printer %2%")%__LINE__%new_printer_name; + BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1% : current 3mf file not support the new printer %2%, new_printer_system_name %3%")%__LINE__%new_printer_name %new_printer_system_name; record_exit_reson(outfile_dir, CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, 0, cli_errors[CLI_3MF_NEW_MACHINE_NOT_SUPPORTED]); flush_and_exit(CLI_3MF_NEW_MACHINE_NOT_SUPPORTED); } @@ -1251,6 +1290,7 @@ int CLI::run(int argc, char **argv) //create project embedded preset if needed Preset *new_preset = NULL; if (is_bbl_3mf && machine_upwards) { + //we need to update the compatible printer and create a new process here, or if we load the 3mf in studio, the process preset can not be loaded as not compatible Preset *current_preset = NULL; size_t project_presets_count = project_presets.size(); for (int index = 0; index < project_presets_count; index++) @@ -1266,13 +1306,13 @@ int CLI::run(int argc, char **argv) std::vector& compatible_printers = new_preset->config.option("compatible_printers", true)->values; bool need_insert = true; for (int index = 0; index < compatible_printers.size(); index++) { - if (compatible_printers[index] == new_printer_name) { + if (compatible_printers[index] == new_printer_system_name) { need_insert = false; break; } } if (need_insert) - compatible_printers.push_back(new_printer_name); + compatible_printers.push_back(new_printer_system_name); } else { //store a project-embedded preset @@ -1280,7 +1320,7 @@ int CLI::run(int argc, char **argv) new_preset->config.apply_only(m_print_config, process_keys); std::vector& compatible_printers = new_preset->config.option("compatible_printers", true)->values; compatible_printers = current_print_compatible_printers; - compatible_printers.push_back(new_printer_name); + compatible_printers.push_back(new_printer_system_name); if (current_process_system_name != current_process_name) { std::string& inherits = new_preset->config.option("inherits", true)->value; inherits = current_process_system_name; @@ -1296,9 +1336,9 @@ int CLI::run(int argc, char **argv) } //update seperate configs into full config - auto update_full_config = [](DynamicPrintConfig& full_config, const DynamicPrintConfig& config, std::set& diff_key_sets) { + auto update_full_config = [](DynamicPrintConfig& full_config, const DynamicPrintConfig& config, std::set& diff_key_sets, bool update_all = false) { for (const t_config_option_key &opt_key : config.keys()) { - if (!diff_key_sets.empty() && (diff_key_sets.find(opt_key) != diff_key_sets.end())) { + if (!update_all && !diff_key_sets.empty() && (diff_key_sets.find(opt_key) != diff_key_sets.end())) { //uptodate, diff keys, continue BOOST_LOG_TRIVIAL(info) << boost::format("keep key %1%")%opt_key; continue; @@ -1309,7 +1349,8 @@ int CLI::run(int argc, char **argv) boost::nowide::cerr << __FUNCTION__<<": can not found option " < different_keys_set(different_keys.begin(), different_keys.end()); BOOST_LOG_TRIVIAL(info) << boost::format("update printer config to newest, different size %1%")%different_keys_set.size(); - int ret = update_full_config(m_print_config, load_machine_config, different_keys_set); + + int ret; + if (new_printer_name.empty()) { + ret = update_full_config(m_print_config, load_machine_config, different_keys_set); + BOOST_LOG_TRIVIAL(info) << boost::format("no new printer, only update the different key, ret %1%")%ret; + } + else { + ret = update_full_config(m_print_config, load_machine_config, different_keys_set, true); + BOOST_LOG_TRIVIAL(info) << boost::format("load a new printer, update all the keys, ret %1%")%ret; + } + if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1379,14 +1434,28 @@ int CLI::run(int argc, char **argv) print_compatible_printers = std::move(current_print_compatible_printers); } else { + //todo: support system process preset different_settings[0] = ""; - inherits_group[0] = ""; + if (new_process_config_is_system) + inherits_group[0] = ""; + else + inherits_group[0] = new_process_system_name; print_compatible_printers = std::move(new_print_compatible_printers); } std::set different_keys_set(different_keys.begin(), different_keys.end()); BOOST_LOG_TRIVIAL(info) << boost::format("update process config to newest, different size %1%")%different_keys_set.size(); - int ret = update_full_config(m_print_config, load_process_config, different_keys_set); + + int ret; + if (new_process_name.empty()) { + ret = update_full_config(m_print_config, load_process_config, different_keys_set); + BOOST_LOG_TRIVIAL(info) << boost::format("no new process, only update the different key, ret %1%")%ret; + } + else { + ret = update_full_config(m_print_config, load_process_config, different_keys_set, true); + BOOST_LOG_TRIVIAL(info) << boost::format("load a new process, update all the keys, ret %1%")%ret; + } + if (ret) { record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); flush_and_exit(ret); @@ -1394,7 +1463,7 @@ int CLI::run(int argc, char **argv) } if (machine_upwards) { - print_compatible_printers.push_back(new_printer_name); + print_compatible_printers.push_back(new_printer_system_name); std::string old_setting = different_settings[0]; if (old_setting.empty()) @@ -1438,8 +1507,9 @@ int CLI::run(int argc, char **argv) opt_filament_ids->resize(filament_count, filament_id_setting); opt_filament_ids->set_at(filament_id_setting, filament_index-1, 0); + //todo: update different settings of filaments different_settings[filament_index] = ""; - inherits_group[filament_index] = ""; + inherits_group[filament_index] = load_filaments_inherit[index]; } else { std::string diff_settings; @@ -1455,7 +1525,7 @@ int CLI::run(int argc, char **argv) std::set different_keys_set(different_keys.begin(), different_keys.end()); BOOST_LOG_TRIVIAL(info) << boost::format("update filament %1%'s config to newest, different size %2%")%filament_index%different_keys_set.size(); for (const t_config_option_key &opt_key : config.keys()) { - if (!different_keys_set.empty() && (different_keys_set.find(opt_key) != different_keys_set.end())) { + if ((load_filament_count == 0) && !different_keys_set.empty() && (different_keys_set.find(opt_key) != different_keys_set.end())) { //uptodate, diff keys, continue BOOST_LOG_TRIVIAL(info) << boost::format("keep key %1%")%opt_key; continue; From db5ed655771c4acd4c859754b15813b0a2c64994 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Thu, 3 Aug 2023 16:22:00 +0800 Subject: [PATCH 005/240] ENH: CLI: add more logic to support repetitions 1. add identify_id for those clone objects 2. ensure succuss when copy multiple objects Change-Id: I8a92f485442577ce70b1f5c46449dae1ae07b713 --- src/BambuStudio.cpp | 780 ++++++++++++++++++++--------------- src/slic3r/GUI/PartPlate.cpp | 18 + 2 files changed, 460 insertions(+), 338 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index bfb35c4d2..6949de269 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1805,33 +1805,32 @@ int CLI::run(int argc, char **argv) partplate_list.set_shapes(current_printable_area, current_exclude_area, bed_texture, height_to_lid, height_to_rod); //plate_stride = partplate_list.plate_stride_x(); } - if (plate_data_src.size() > 0) - { - partplate_list.load_from_3mf_structure(plate_data_src); + + auto translate_models = [translate_old, shrink_to_new_bed, old_printable_width, old_printable_depth, old_printable_height, current_printable_width, current_printable_depth, current_printable_height] (Slic3r::GUI::PartPlateList& plate_list) { //BBS: translate old 3mf to correct positions if (translate_old) { //translate the objects - int plate_count = partplate_list.get_plate_count(); + int plate_count = plate_list.get_plate_count(); for (int index = 1; index < plate_count; index ++) { - Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index); + Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index); Vec3d cur_origin = cur_plate->get_origin(); - Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, old_printable_width, old_printable_depth); + Vec3d new_origin = plate_list.compute_origin_using_new_size(index, old_printable_width, old_printable_depth); cur_plate->translate_all_instance(new_origin - cur_origin); } BOOST_LOG_TRIVIAL(info) << boost::format("translate old 3mf, switch back to current bed size,{%1%, %2%, %3%}")%old_printable_width %old_printable_depth %old_printable_height; - partplate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, true, true); + plate_list.reset_size(old_printable_width, old_printable_depth, old_printable_height, true, true); } if (shrink_to_new_bed) { - int plate_count = partplate_list.get_plate_count(); + int plate_count = plate_list.get_plate_count(); for (int index = 0; index < plate_count; index ++) { - Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index); + Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index); Vec3d cur_origin = cur_plate->get_origin(); - Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, current_printable_width, current_printable_depth); + Vec3d new_origin = plate_list.compute_origin_using_new_size(index, current_printable_width, current_printable_depth); Vec3d cur_center_offset { ((double)old_printable_width)/2, ((double)old_printable_depth)/2, 0}, new_center_offset { ((double)current_printable_width)/2, ((double)current_printable_depth)/2, 0}; Vec3d cur_center = cur_origin + cur_center_offset; Vec3d new_center = new_origin + new_center_offset; @@ -1841,8 +1840,14 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1% translate offset: {%2%, %3%, %4%}")%(index+1) %offset[0] %offset[1] %offset[2]; } BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, shrink all the models to current bed size,{%1%, %2%, %3%}")%current_printable_width %current_printable_depth %current_printable_height; - partplate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true); + plate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true); } + }; + if (plate_data_src.size() > 0) + { + partplate_list.load_from_3mf_structure(plate_data_src); + + translate_models(partplate_list); } /*for (ModelObject *model_object : m_models[0].objects) @@ -1902,10 +1907,7 @@ int CLI::run(int argc, char **argv) record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); flush_and_exit(CLI_INVALID_PARAMS); } - BOOST_LOG_TRIVIAL(info) << "repetitions value " << repetitions_count << ", will copy model object first\n"; - Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); - //copy model objects and instances on plate - cur_plate->duplicate_all_instance(repetitions_count-1, need_skip, skip_maps); + BOOST_LOG_TRIVIAL(info) << "repetitions value " << repetitions_count << std::endl; need_arrange = true; duplicate_count = repetitions_count - 1; @@ -2154,345 +2156,447 @@ int CLI::run(int argc, char **argv) if (m_models.size() > 0) { Model &model = m_models[0]; + Model original_model; + std::set> backup_set; + bool finished_arrange = false, first_run = true; + Slic3r::GUI::PartPlate* cur_plate; + int low_duplicate_count = 0, up_duplicate_count = duplicate_count, arrange_count = 0; arrange_cfg.is_seq_print = false; - - //Step-1: prepare arrange polygons - if (duplicate_count == 0) - { - for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) - { - ModelObject* mo = model.objects[oidx]; - for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx) - { - ModelInstance* minst = mo->instances[inst_idx]; - ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config); - - //preprocess by partplate list - //remove the locked plate's instances, neither in selected, nor in un-selected - bool locked = partplate_list.preprocess_arrange_polygon(oidx, inst_idx, ap, true); - if (!locked) - { - ap.itemid = selected.size(); - if (minst->printable) - selected.emplace_back(ap); - else - unprintable.emplace_back(ap); - } - else - { - //skip this object due to be locked in plate - ap.itemid = locked_aps.size(); - locked_aps.emplace_back(ap); - boost::nowide::cout <<__FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx; - } - } - } - - if (m_print_config.has("print_sequence")) { - PrintSequence seq = m_print_config.option>("print_sequence")->value; - arrange_cfg.is_seq_print = (seq == PrintSequence::ByObject); - } - - //add the virtual object into unselect list if has - partplate_list.preprocess_exclude_areas(unselected); + if (duplicate_count > 0) { + original_model = model; } - else { - //only arrange current plate - Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); - PrintSequence curr_plate_seq = cur_plate->get_print_seq(); - if (curr_plate_seq == PrintSequence::ByDefault) { - auto seq_print = m_print_config.option>("print_sequence"); - if (seq_print && (seq_print->value == PrintSequence::ByObject)) { - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from global")%plate_to_slice; - arrange_cfg.is_seq_print = true; - } - } - else if (curr_plate_seq == PrintSequence::ByObject) { - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from plate self")%plate_to_slice; - arrange_cfg.is_seq_print = true; - } - partplate_list.lock_plate(plate_to_slice - 1, false); - partplate_list.select_plate(plate_to_slice-1); - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% set to selected")%plate_to_slice; - - for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) + while(!finished_arrange) + { + arrange_count++; + //step-0: duplicate model + if (duplicate_count > 0) { - ModelObject* mo = model.objects[oidx]; + //copy model objects and instances on plate + if (!first_run) { + BOOST_LOG_TRIVIAL(info) << boost::format("restore model object and plate, new duplicate_count %1%, arrange_count=%2%")%duplicate_count%arrange_count; + beds = get_bed_shape(m_print_config); + model.clear_objects(); + model.clear_materials(); + model = original_model; + partplate_list.load_from_3mf_structure(plate_data_src); - for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx) - { - ModelInstance* minst = mo->instances[inst_idx]; - bool in_plate = cur_plate->contain_instance(oidx, inst_idx) || cur_plate->intersect_instance(oidx, inst_idx); - ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config); - - ArrangePolygons& cont = mo->instances[inst_idx]->printable ? - (in_plate ? selected : unselected) : - unprintable; - bool locked = partplate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate); - BOOST_LOG_TRIVIAL(info) << boost::format("name %4% in_plate %1% printable %2%, locked %3%")%in_plate %mo->instances[inst_idx]->printable %locked % ap.name ; - if (!locked) - { - ap.itemid = cont.size(); - cont.emplace_back(std::move(ap)); - } - else - { - //skip this object due to be not in current plate, treated as locked - ap.itemid = locked_aps.size(); - locked_aps.emplace_back(std::move(ap)); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name; - } - } - } - if (selected.size() == (duplicate_count + 1)) - { - duplicate_single_object = true; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": found single object mode"); - } - - if (m_print_config.has("wipe_tower_x")) { - float x = dynamic_cast(m_print_config.option("wipe_tower_x"))->get_at(plate_to_slice-1); - float y = dynamic_cast(m_print_config.option("wipe_tower_y"))->get_at(plate_to_slice-1); - float w = dynamic_cast(m_print_config.option("prime_tower_width"))->value; - float a = dynamic_cast(m_print_config.option("wipe_tower_rotation_angle"))->value; - float v = dynamic_cast(m_print_config.option("prime_volume"))->value; - unsigned int filaments_cnt = plate_data_src[plate_to_slice-1]->slice_filaments_info.size(); - if ((filaments_cnt == 0) || need_skip) - { - // slice filaments info invalid - std::vector extruders = cur_plate->get_extruders_under_cli(true, m_print_config); - filaments_cnt = extruders.size(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid or need_skip, get from partplate: filament_count %1%")%filaments_cnt; - } - - if (filaments_cnt <= 1) - { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": not a multi-color object anymore, drop the wipe tower before arrange."); + selected.clear(); + unselected.clear(); + unprintable.clear(); + locked_aps.clear(); } else + first_run = false; + + cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); + cur_plate->duplicate_all_instance(duplicate_count, need_skip, skip_maps); + } + + //Step-1: prepare arrange polygons + if (duplicate_count == 0) + { + for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) { - float layer_height = 0.2; - ConfigOption* layer_height_opt = m_print_config.option("layer_height"); - if (layer_height_opt) - layer_height = layer_height_opt->getFloat(); - - float depth = v * (filaments_cnt - 1) / (layer_height * w); - - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", wipe_tower: x=%1%, y=%2%, width=%3%, depth=%4%, angle=%5%, prime_volume=%6%, filaments_cnt=%7%, layer_height=%8%") - %x %y %w %depth %a %v %filaments_cnt %layer_height; - - Vec3d plate_origin = cur_plate->get_origin(); - - ArrangePolygon wipe_tower_ap; - - Polygon ap({ - {scaled(x), scaled(y)}, - {scaled(x + w), scaled(y)}, - {scaled(x + w), scaled(y + depth)}, - {scaled(x), scaled(y + depth)} - }); - wipe_tower_ap.bed_idx = 0; - wipe_tower_ap.setter = NULL; // do not move wipe tower - - wipe_tower_ap.poly.contour = std::move(ap); - wipe_tower_ap.translation = {scaled(0.f), scaled(0.f)}; - wipe_tower_ap.rotation = a; - wipe_tower_ap.name = "WipeTower"; - wipe_tower_ap.is_virt_object = true; - wipe_tower_ap.is_wipe_tower = true; - ++wipe_tower_ap.priority; - unselected.emplace_back(std::move(wipe_tower_ap)); - } - } - - // add the virtual object into unselect list if has - partplate_list.preprocess_exclude_areas(unselected, plate_to_slice); - } - - - //Step-2:prepare the arrange params - arrange_cfg.allow_rotations = true; - arrange_cfg.allow_multi_materials_on_same_plate = true; - arrange_cfg.avoid_extrusion_cali_region = false; - arrange_cfg.min_obj_distance = scaled(22.0); - arrange_cfg.clearance_height_to_rod = height_to_rod; - arrange_cfg.clearance_height_to_lid = height_to_lid; - arrange_cfg.cleareance_radius = cleareance_radius; - arrange_cfg.printable_height = print_height; - - arrange_cfg.bed_shrink_x = 0; - arrange_cfg.bed_shrink_y = 0; - double skirt_distance = m_print_config.opt_float("skirt_distance"); - double brim_width = m_print_config.opt_float("brim_width"); - arrange_cfg.brim_skirt_distance = skirt_distance + brim_width; - BOOST_LOG_TRIVIAL(info) << boost::format("Arrange Params: brim_skirt_distance=%1%, min_obj_distance=%2%, is_seq_print=%3%\n") % arrange_cfg.brim_skirt_distance % arrange_cfg.min_obj_distance % arrange_cfg.is_seq_print; - - // Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt. - // So we can't do max but do adding instead. - arrange_cfg.bed_shrink_x += arrange_cfg.brim_skirt_distance; - arrange_cfg.bed_shrink_y += arrange_cfg.brim_skirt_distance; - - if (arrange_cfg.is_seq_print) - { - arrange_cfg.min_obj_distance = std::max(arrange_cfg.min_obj_distance, scaled(arrange_cfg.cleareance_radius + 0.001)); - float shift_dist = arrange_cfg.cleareance_radius / 2 - 5; - arrange_cfg.bed_shrink_x -= shift_dist; - arrange_cfg.bed_shrink_y -= shift_dist; - } - // shrink bed - beds[0] += Point(scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); - beds[1] += Point(-scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); - beds[2] += Point(-scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); - beds[3] += Point(scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); - - // do not inflate brim_width. Objects are allowed to have overlapped brim. - std::for_each(selected.begin(), selected.end(), [&](auto& ap) {ap.inflation = arrange_cfg.min_obj_distance / 2; }); - - { - BOOST_LOG_TRIVIAL(info) << "items selected before arranging: "; - for (auto selected : selected) - BOOST_LOG_TRIVIAL(info) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx - << ", trans: " << selected.translation.transpose(); - } - arrange_cfg.progressind= [](unsigned st, std::string str = "") { - boost::nowide::cout << "st=" << st << ", " << str << std::endl; - }; - - //Step-3:do the arrange - arrangement::arrange(selected, unselected, beds, arrange_cfg); - arrangement::arrange(unprintable, {}, beds, arrange_cfg); - - //Step-4:postprocess by partplate list&&apply the result - int bed_idx_max = 0; - if (duplicate_count == 0) - { - //clear all the relations before apply the arrangement results - partplate_list.clear(); - - // Apply the arrange result to all selected objects - for (ArrangePolygon &ap : selected) { - //BBS: partplate postprocess - partplate_list.postprocess_bed_index_for_selected(ap); - - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - boost::nowide::cout<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) << "\n"; - } - for (ArrangePolygon &ap : locked_aps) { - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - - partplate_list.postprocess_arrange_polygon(ap, false); - - ap.apply(); - } - - // Apply the arrange result to all selected objects - for (ArrangePolygon &ap : selected) { - //BBS: partplate postprocess - partplate_list.postprocess_arrange_polygon(ap, true); - - ap.apply(); - } - - // Move the unprintable items to the last virtual bed. - for (ArrangePolygon &ap : unprintable) { - ap.bed_idx += bed_idx_max + 1; - partplate_list.postprocess_arrange_polygon(ap, true); - - ap.apply(); - } - - //BBS: reload all objects due to arrange - partplate_list.rebuild_plates_after_arrangement(); - } - else { - //only for partplate case - partplate_list.clear(false, false, true, plate_to_slice-1); - - //BBS: adjust the bed_index, create new plates, get the max bed_index - - for (ArrangePolygon& ap : selected) { - if (ap.bed_idx != (plate_to_slice-1)) - { - // - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":arrange failed: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); - if (!duplicate_single_object) + ModelObject* mo = model.objects[oidx]; + for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx) { - BOOST_LOG_TRIVIAL(error) << "arrange failed when duplicate multiple objects." << std::endl; - record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); - flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); + ModelInstance* minst = mo->instances[inst_idx]; + ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config); + + //preprocess by partplate list + //remove the locked plate's instances, neither in selected, nor in un-selected + bool locked = partplate_list.preprocess_arrange_polygon(oidx, inst_idx, ap, true); + if (!locked) + { + ap.itemid = selected.size(); + if (minst->printable) + selected.emplace_back(ap); + else + unprintable.emplace_back(ap); + } + else + { + //skip this object due to be locked in plate + ap.itemid = locked_aps.size(); + locked_aps.emplace_back(ap); + boost::nowide::cout <<__FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx; + } + } + } + + if (m_print_config.has("print_sequence")) { + PrintSequence seq = m_print_config.option>("print_sequence")->value; + arrange_cfg.is_seq_print = (seq == PrintSequence::ByObject); + } + + //add the virtual object into unselect list if has + partplate_list.preprocess_exclude_areas(unselected); + } + else { + //only arrange current plate + //cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); + PrintSequence curr_plate_seq = cur_plate->get_print_seq(); + if (curr_plate_seq == PrintSequence::ByDefault) { + auto seq_print = m_print_config.option>("print_sequence"); + if (seq_print && (seq_print->value == PrintSequence::ByObject)) { + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from global")%plate_to_slice; + arrange_cfg.is_seq_print = true; + } + } + else if (curr_plate_seq == PrintSequence::ByObject) { + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from plate self")%plate_to_slice; + arrange_cfg.is_seq_print = true; + } + + partplate_list.lock_plate(plate_to_slice - 1, false); + partplate_list.select_plate(plate_to_slice-1); + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% set to selected")%plate_to_slice; + + for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) + { + ModelObject* mo = model.objects[oidx]; + + for (size_t inst_idx = 0; inst_idx < mo->instances.size(); ++inst_idx) + { + ModelInstance* minst = mo->instances[inst_idx]; + bool in_plate = cur_plate->contain_instance(oidx, inst_idx) || cur_plate->intersect_instance(oidx, inst_idx); + ArrangePolygon ap = get_instance_arrange_poly(minst, m_print_config); + + ArrangePolygons& cont = mo->instances[inst_idx]->printable ? + (in_plate ? selected : unselected) : + unprintable; + bool locked = partplate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate); + BOOST_LOG_TRIVIAL(info) << boost::format("name %4% in_plate %1% printable %2%, locked %3%")%in_plate %mo->instances[inst_idx]->printable %locked % ap.name ; + if (!locked) + { + ap.itemid = cont.size(); + cont.emplace_back(std::move(ap)); + } + else + { + //skip this object due to be not in current plate, treated as locked + ap.itemid = locked_aps.size(); + locked_aps.emplace_back(std::move(ap)); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name; + } + } + } + if (selected.size() == (duplicate_count + 1)) + { + duplicate_single_object = true; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": found single object mode"); + } + + if (m_print_config.has("wipe_tower_x")) { + float x = dynamic_cast(m_print_config.option("wipe_tower_x"))->get_at(plate_to_slice-1); + float y = dynamic_cast(m_print_config.option("wipe_tower_y"))->get_at(plate_to_slice-1); + float w = dynamic_cast(m_print_config.option("prime_tower_width"))->value; + float a = dynamic_cast(m_print_config.option("wipe_tower_rotation_angle"))->value; + float v = dynamic_cast(m_print_config.option("prime_volume"))->value; + unsigned int filaments_cnt = plate_data_src[plate_to_slice-1]->slice_filaments_info.size(); + if ((filaments_cnt == 0) || need_skip) + { + // slice filaments info invalid + std::vector extruders = cur_plate->get_extruders_under_cli(true, m_print_config); + filaments_cnt = extruders.size(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid or need_skip, get from partplate: filament_count %1%")%filaments_cnt; + } + + if (filaments_cnt <= 1) + { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": not a multi-color object anymore, drop the wipe tower before arrange."); + } + else + { + float layer_height = 0.2; + ConfigOption* layer_height_opt = m_print_config.option("layer_height"); + if (layer_height_opt) + layer_height = layer_height_opt->getFloat(); + + float depth = v * (filaments_cnt - 1) / (layer_height * w); + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", wipe_tower: x=%1%, y=%2%, width=%3%, depth=%4%, angle=%5%, prime_volume=%6%, filaments_cnt=%7%, layer_height=%8%") + %x %y %w %depth %a %v %filaments_cnt %layer_height; + + Vec3d plate_origin = cur_plate->get_origin(); + + ArrangePolygon wipe_tower_ap; + + Polygon ap({ + {scaled(x), scaled(y)}, + {scaled(x + w), scaled(y)}, + {scaled(x + w), scaled(y + depth)}, + {scaled(x), scaled(y + depth)} + }); + wipe_tower_ap.bed_idx = 0; + wipe_tower_ap.setter = NULL; // do not move wipe tower + + wipe_tower_ap.poly.contour = std::move(ap); + wipe_tower_ap.translation = {scaled(0.f), scaled(0.f)}; + wipe_tower_ap.rotation = a; + wipe_tower_ap.name = "WipeTower"; + wipe_tower_ap.is_virt_object = true; + wipe_tower_ap.is_wipe_tower = true; + ++wipe_tower_ap.priority; + unselected.emplace_back(std::move(wipe_tower_ap)); + } + } + + // add the virtual object into unselect list if has + partplate_list.preprocess_exclude_areas(unselected, plate_to_slice); + } + + + //Step-2:prepare the arrange params + arrange_cfg.allow_rotations = true; + arrange_cfg.allow_multi_materials_on_same_plate = true; + arrange_cfg.avoid_extrusion_cali_region = false; + arrange_cfg.min_obj_distance = scaled(22.0); + arrange_cfg.clearance_height_to_rod = height_to_rod; + arrange_cfg.clearance_height_to_lid = height_to_lid; + arrange_cfg.cleareance_radius = cleareance_radius; + arrange_cfg.printable_height = print_height; + + arrange_cfg.bed_shrink_x = 0; + arrange_cfg.bed_shrink_y = 0; + double skirt_distance = m_print_config.opt_float("skirt_distance"); + double brim_width = m_print_config.opt_float("brim_width"); + arrange_cfg.brim_skirt_distance = skirt_distance + brim_width; + BOOST_LOG_TRIVIAL(info) << boost::format("Arrange Params: brim_skirt_distance=%1%, min_obj_distance=%2%, is_seq_print=%3%\n") % arrange_cfg.brim_skirt_distance % arrange_cfg.min_obj_distance % arrange_cfg.is_seq_print; + + // Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt. + // So we can't do max but do adding instead. + arrange_cfg.bed_shrink_x += arrange_cfg.brim_skirt_distance; + arrange_cfg.bed_shrink_y += arrange_cfg.brim_skirt_distance; + + if (arrange_cfg.is_seq_print) + { + arrange_cfg.min_obj_distance = std::max(arrange_cfg.min_obj_distance, scaled(arrange_cfg.cleareance_radius + 0.001)); + float shift_dist = arrange_cfg.cleareance_radius / 2 - 5; + arrange_cfg.bed_shrink_x -= shift_dist; + arrange_cfg.bed_shrink_y -= shift_dist; + } + // shrink bed + beds[0] += Point(scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); + beds[1] += Point(-scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); + beds[2] += Point(-scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); + beds[3] += Point(scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); + + // do not inflate brim_width. Objects are allowed to have overlapped brim. + std::for_each(selected.begin(), selected.end(), [&](auto& ap) {ap.inflation = arrange_cfg.min_obj_distance / 2; }); + + { + BOOST_LOG_TRIVIAL(info) << boost::format("items selected before arranging: %1%")%selected.size(); + for (auto selected : selected) + BOOST_LOG_TRIVIAL(trace) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx + << ", trans: " << selected.translation.transpose(); + } + arrange_cfg.progressind= [](unsigned st, std::string str = "") { + //boost::nowide::cout << "st=" << st << ", " << str << std::endl; + }; + + //Step-3:do the arrange + BOOST_LOG_TRIVIAL(info) << boost::format("start %1% th arranging...")%arrange_count; + arrangement::arrange(selected, unselected, beds, arrange_cfg); + arrangement::arrange(unprintable, {}, beds, arrange_cfg); + BOOST_LOG_TRIVIAL(info) << boost::format("finished %1% th arranging...")%arrange_count; + + //Step-4:postprocess by partplate list&&apply the result + int bed_idx_max = 0; + if (duplicate_count == 0) + { + //clear all the relations before apply the arrangement results + partplate_list.clear(); + + // Apply the arrange result to all selected objects + for (ArrangePolygon &ap : selected) { + //BBS: partplate postprocess + partplate_list.postprocess_bed_index_for_selected(ap); + + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + BOOST_LOG_TRIVIAL(trace)<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) << "\n"; + } + for (ArrangePolygon &ap : locked_aps) { + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + + partplate_list.postprocess_arrange_polygon(ap, false); + + ap.apply(); + } + + // Apply the arrange result to all selected objects + for (ArrangePolygon &ap : selected) { + //BBS: partplate postprocess + partplate_list.postprocess_arrange_polygon(ap, true); + + ap.apply(); + } + + // Move the unprintable items to the last virtual bed. + for (ArrangePolygon &ap : unprintable) { + ap.bed_idx += bed_idx_max + 1; + partplate_list.postprocess_arrange_polygon(ap, true); + + ap.apply(); + } + + //BBS: reload all objects due to arrange + partplate_list.rebuild_plates_after_arrangement(); + } + else { + //only for partplate case + partplate_list.clear(false, false, true, plate_to_slice-1); + + //BBS: adjust the bed_index, create new plates, get the max bed_index + bool failed_this_time = false; + for (ArrangePolygon& ap : selected) { + if (ap.bed_idx != (plate_to_slice-1)) + { + // + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":arrange failed: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); + if (!duplicate_single_object) + { + BOOST_LOG_TRIVIAL(warning) << boost::format("arrange failed when duplicate multiple objects at count %1%, low_duplicate_count %2%, up_duplicate_count %3%")%duplicate_count %low_duplicate_count %up_duplicate_count; + + if (duplicate_count == 1) + { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": failed even on duplicate 1 copy, just print one original model"); + duplicate_count = 0; + } + else + { + if (duplicate_count == low_duplicate_count) + { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": previous success, but currently failed count %1%!!!")%duplicate_count; + up_duplicate_count = duplicate_count; + low_duplicate_count --; + duplicate_count --; + } + else { + up_duplicate_count = duplicate_count; + duplicate_count = (up_duplicate_count + low_duplicate_count)/2; + } + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": try new count %1%, low_duplicate_count %2%, up_duplicate_count %3%")%duplicate_count %low_duplicate_count %up_duplicate_count; + } + //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + //flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); + failed_this_time = true; + break; + } + } + else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":arrange success: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); + real_duplicate_count ++; + } + partplate_list.postprocess_bed_index_for_current_plate(ap); + + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": arrange selected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; + } + + if (failed_this_time) { + if (duplicate_count == 0) + { + //restore to the original + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": restore to the original model and plates"); + finished_arrange = true; + model = original_model; + partplate_list.load_from_3mf_structure(plate_data_src); + + translate_models(partplate_list); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); + } + continue; + } + + if (duplicate_single_object) + { + if (real_duplicate_count <= 0) { + BOOST_LOG_TRIVIAL(warning) << "no object can be placed under single object mode, restore to the original model and plates also" << std::endl; + //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + //flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); + finished_arrange = true; + model = original_model; + partplate_list.load_from_3mf_structure(plate_data_src); + + translate_models(partplate_list); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); + continue; } } else { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":arrange success: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); - real_duplicate_count ++; + //multiple objects case + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": multiple objects mode, arrange success on count %1%, low_duplicate_count %2%, up_duplicate_count %3%")%duplicate_count %low_duplicate_count %up_duplicate_count; + if ((duplicate_count == up_duplicate_count) || (duplicate_count == (up_duplicate_count - 1))) + { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": found the max arrangeable count %1%")%duplicate_count; + } + else { + low_duplicate_count = duplicate_count; + duplicate_count = (up_duplicate_count + low_duplicate_count)/2; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": try new count %1%, low_duplicate_count %2%, up_duplicate_count %3%")%duplicate_count %low_duplicate_count %up_duplicate_count; + continue; + } } - partplate_list.postprocess_bed_index_for_current_plate(ap); - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": arrange selected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; + //BBS: adjust the bed_index, create new plates, get the max bed_index + for (ArrangePolygon& ap : unselected) + { + if (ap.is_virt_object) + continue; + + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange unselected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; + } + + for (ArrangePolygon& ap : locked_aps) + { + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + + partplate_list.postprocess_arrange_polygon(ap, false); + + ap.apply(); + } + + // Apply the arrange result to all selected objects + for (ArrangePolygon& ap : selected) { + //BBS: partplate postprocess + partplate_list.postprocess_arrange_polygon(ap, true); + + ap.apply(); + } + + // Apply the arrange result to unselected objects(due to the sukodu-style column changes, the position of unselected may also be modified) + for (ArrangePolygon& ap : unselected) + { + if (ap.is_virt_object) + continue; + + //BBS: partplate postprocess + partplate_list.postprocess_arrange_polygon(ap, false); + + ap.apply(); + } + + // Move the unprintable items to the last virtual bed. + // Note ap.apply() moves relatively according to bed_idx, so we need to subtract the orignal bed_idx + for (ArrangePolygon& ap : unprintable) + { + ap.bed_idx = bed_idx_max + 1; + partplate_list.postprocess_arrange_polygon(ap, true); + + ap.apply(); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange m_unprintable: name: %4%, bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; + } + + partplate_list.rebuild_plates_after_arrangement(false, true, plate_to_slice-1); } - - if (duplicate_single_object && (real_duplicate_count <= 0)) - { - BOOST_LOG_TRIVIAL(error) << "no object can be placed under single object mode." << std::endl; - record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); - flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); - } - - //BBS: adjust the bed_index, create new plates, get the max bed_index - for (ArrangePolygon& ap : unselected) - { - if (ap.is_virt_object) - continue; - - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange unselected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; - } - - for (ArrangePolygon& ap : locked_aps) - { - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - - partplate_list.postprocess_arrange_polygon(ap, false); - - ap.apply(); - } - - // Apply the arrange result to all selected objects - for (ArrangePolygon& ap : selected) { - //BBS: partplate postprocess - partplate_list.postprocess_arrange_polygon(ap, true); - - ap.apply(); - } - - // Apply the arrange result to unselected objects(due to the sukodu-style column changes, the position of unselected may also be modified) - for (ArrangePolygon& ap : unselected) - { - if (ap.is_virt_object) - continue; - - //BBS: partplate postprocess - partplate_list.postprocess_arrange_polygon(ap, false); - - ap.apply(); - } - - // Move the unprintable items to the last virtual bed. - // Note ap.apply() moves relatively according to bed_idx, so we need to subtract the orignal bed_idx - for (ArrangePolygon& ap : unprintable) - { - ap.bed_idx = bed_idx_max + 1; - partplate_list.postprocess_arrange_polygon(ap, true); - - ap.apply(); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange m_unprintable: name: %4%, bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; - } - - partplate_list.rebuild_plates_after_arrangement(false, true, plate_to_slice-1); + finished_arrange = true; } + original_model.clear_objects(); + original_model.clear_materials(); } } @@ -3533,7 +3637,7 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", Finished" << std::endl; //record the duplicate here - if ((duplicate_count > 0) && duplicate_single_object) + if (duplicate_count > 0) { std::map key_values; key_values["sliced_count"] = std::to_string(real_duplicate_count); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 1a9cede80..636e00cbe 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2146,6 +2146,24 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, s } } + for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) + { + int obj_id = it->first; + int instance_id = it->second; + + if ((obj_id >= 0) && (obj_id < m_model->objects.size())) + { + ModelObject* object = m_model->objects[obj_id]; + ModelInstance* instance = object->instances[instance_id]; + + if (instance->printable) + { + instance->loaded_id = instance->id().id; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": set obj %1% instance %2%'s loaded_id to its id %3%, name %4%") % obj_id %instance_id %instance->loaded_id % object->name; + } + } + } + return; } From 34061f1fb7855ff4b2eb2a4c940aa38d1ed7a55c Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 4 Aug 2023 12:23:55 +0800 Subject: [PATCH 006/240] ENH: CLI: add time record for prepare/slice/export Change-Id: I4004a9af3823223c885f428f5a2f180f9d9074e5 --- src/BambuStudio.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 6949de269..d8dc40db7 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -349,7 +349,8 @@ static PrinterTechnology get_printer_technology(const DynamicConfig &config) return(ret);} #endif -void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, std::map key_values = std::map()) +void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, + size_t prepare_time = 0, std::vector sliced_time = std::vector(), size_t export_time = 0, std::map key_values = std::map()) { #if defined(__linux__) || defined(__LINUX__) std::string result_file; @@ -365,6 +366,9 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin j["plate_index"] = plate_id; j["return_code"] = code; j["error_string"] = error_message; + j["prepare_time"] = prepare_time; + j["slice_time"] = sliced_time; + j["export_time"] = export_time; for (auto& iter: key_values) j[iter.first] = iter.second; @@ -481,6 +485,9 @@ int CLI::run(int argc, char **argv) const std::vector &skip_objects = m_config.option("skip_objects", true)->values; std::map skip_maps; bool need_skip = (skip_objects.size() > 0)?true:false; + long long global_begin_time = 0, global_current_time; + std::vector sliced_time; + size_t prepare_time, export_time; if (start_gui) { BOOST_LOG_TRIVIAL(info) << "no action, start gui directly" << std::endl; @@ -545,7 +552,8 @@ int CLI::run(int argc, char **argv) } } - BOOST_LOG_TRIVIAL(info) << "start_gui="<< start_gui << std::endl; + global_begin_time = (long long)Slic3r::Utils::get_current_time_utc(); + BOOST_LOG_TRIVIAL(info) << boost::format("cli mode, begin at %1%")%global_begin_time; //BBS: add plate data related logic PlateDataPtrs plate_data_src; @@ -2513,7 +2521,7 @@ int CLI::run(int argc, char **argv) if (duplicate_single_object) { - if (real_duplicate_count <= 0) { + if (real_duplicate_count <= 1) { BOOST_LOG_TRIVIAL(warning) << "no object can be placed under single object mode, restore to the original model and plates also" << std::endl; //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); //flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); @@ -2522,9 +2530,11 @@ int CLI::run(int argc, char **argv) partplate_list.load_from_3mf_structure(plate_data_src); translate_models(partplate_list); + duplicate_count = 0; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); continue; } + duplicate_count = real_duplicate_count - 1; } else { //multiple objects case @@ -2616,6 +2626,12 @@ int CLI::run(int argc, char **argv) int max_slicing_time_per_plate = 0, max_triangle_count_per_plate = 0; std::vector plate_has_skips(partplate_list.get_plate_count(), false); std::vector> plate_skipped_objects(partplate_list.get_plate_count()); + + global_current_time = (long long)Slic3r::Utils::get_current_time_utc(); + prepare_time = (size_t) (global_current_time - global_begin_time); + global_begin_time = global_current_time; + sliced_time.resize(partplate_list.get_plate_count(), 0); + for (auto const &opt_key : m_actions) { if (opt_key == "help") { this->print_help(); @@ -3014,8 +3030,9 @@ int CLI::run(int argc, char **argv) flush_and_exit(ret); } } + end_time = (long long)Slic3r::Utils::get_current_time_utc(); + sliced_time[index] = end_time - start_time; if (max_slicing_time_per_plate != 0) { - end_time = (long long)Slic3r::Utils::get_current_time_utc(); long long time_cost = end_time - start_time; if (time_cost > max_slicing_time_per_plate) { BOOST_LOG_TRIVIAL(error) << boost::format("plate %1%'s slice time %2% exceeds the limit %3%, return error.") @@ -3083,6 +3100,7 @@ int CLI::run(int argc, char **argv) } } + global_begin_time = (long long)Slic3r::Utils::get_current_time_utc(); if (export_to_3mf) { //BBS: export as bbl 3mf std::vector thumbnails, top_thumbnails, pick_thumbnails; @@ -3635,16 +3653,19 @@ int CLI::run(int argc, char **argv) } //BBS: flush logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", Finished" << std::endl; + global_current_time = (long long)Slic3r::Utils::get_current_time_utc(); + export_time = (size_t) (global_current_time - global_begin_time); //record the duplicate here if (duplicate_count > 0) { std::map key_values; - key_values["sliced_count"] = std::to_string(real_duplicate_count); - record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], key_values); + key_values["sliced_count"] = std::to_string(duplicate_count+1); + record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], prepare_time, sliced_time, export_time, key_values); + } + else { + record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], prepare_time, sliced_time, export_time); } - else - record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0]); boost::nowide::cout.flush(); boost::nowide::cerr.flush(); From fca0d5b2395362ea46cb119e0cdddf4a28880518 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Mon, 7 Aug 2023 20:29:06 +0800 Subject: [PATCH 007/240] FIX: CLI: fix serveral bugs 1. bed index not correct issue 2. pick thumbnail not correct when repetitions Change-Id: Ie846432e29c596f95da30c7df199c252873504f3 --- src/BambuStudio.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index d8dc40db7..6c501ce6e 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2160,6 +2160,28 @@ int CLI::run(int argc, char **argv) { ArrangePolygons selected, unselected, unprintable, locked_aps; + for (int index = 0; index < partplate_list.get_plate_count(); index ++) + { + if ((plate_to_slice != 0) && (plate_to_slice != (index + 1))) { + continue; + } + + if (plate_data_src.size() > index) { + if (!plate_data_src[index]->thumbnail_file.empty()) { + BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded thumbnail %2%.")%(index+1)%plate_data_src[index]->thumbnail_file; + plate_data_src[index]->thumbnail_file.clear(); + } + if (!plate_data_src[index]->top_file.empty()) { + BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded top_thumbnail %2%.")%(index+1)%plate_data_src[index]->top_file; + plate_data_src[index]->top_file.clear(); + } + if (!plate_data_src[index]->pick_file.empty()) { + BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: clear loaded pick_thumbnail %2%.")%(index+1)%plate_data_src[index]->pick_file; + plate_data_src[index]->pick_file.clear(); + } + } + } + //for (Model &model : m_models) if (m_models.size() > 0) { @@ -2460,6 +2482,7 @@ int CLI::run(int argc, char **argv) //BBS: adjust the bed_index, create new plates, get the max bed_index bool failed_this_time = false; for (ArrangePolygon& ap : selected) { + partplate_list.postprocess_bed_index_for_current_plate(ap); if (ap.bed_idx != (plate_to_slice-1)) { // @@ -2498,7 +2521,6 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":arrange success: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); real_duplicate_count ++; } - partplate_list.postprocess_bed_index_for_current_plate(ap); bed_idx_max = std::max(ap.bed_idx, bed_idx_max); BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": arrange selected %4%: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; @@ -2808,7 +2830,7 @@ int CLI::run(int argc, char **argv) if (skip_maps.find(i->loaded_id) != skip_maps.end()) { skip_maps[i->loaded_id] = true; i->printable = false; - if (i->print_volume_state == ModelInstancePVS_Inside || need_arrange) { + if (i->print_volume_state == ModelInstancePVS_Inside) { skipped_count++; plate_has_skips[index] = true; plate_skipped_objects[index].emplace_back(i->loaded_id); From 990b0947e70f884a3b2ceded669a27a7509a458f Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Tue, 15 Aug 2023 13:04:37 +0800 Subject: [PATCH 008/240] FIX: CLI: add logic to allow use cached_data while printer size change when print profile created on small printers the cached data should also be used JIRA: MAK-1658 Change-Id: I31e801bd3116838baaeaef44f4aa6d53d65aa058 --- src/BambuStudio.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 6c501ce6e..013ca1b66 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2679,9 +2679,9 @@ int CLI::run(int argc, char **argv) } else if (shrink_to_new_bed) { - BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata when shrink_to_new_bed(switch printer from small to bigger." << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); - flush_and_exit(CLI_INVALID_PARAMS); + BOOST_LOG_TRIVIAL(warning) << "use load_slicedata when shrink_to_new_bed(switch printer from small to bigger." << std::endl; + //record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + //flush_and_exit(CLI_INVALID_PARAMS); } } else if (opt_key == "export_settings") { //FIXME check for mixing the FFF / SLA parameters. From f6ac8b60b71f11f2dbb1a2a41b2884ae67d027a2 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 18 Aug 2023 15:17:35 +0800 Subject: [PATCH 009/240] FIX: CLI: fix serveral issues of CLI 1. duplicate id issue, MAK-1702 2. shrink issue, STUDIO-4048 Change-Id: Ie952f1ecc5267a60f0ce3220c4a5ea31cf7199ff --- src/BambuStudio.cpp | 23 +++++++++++++++++++---- src/slic3r/GUI/PartPlate.cpp | 9 ++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 013ca1b66..18b5bb98e 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1814,7 +1814,7 @@ int CLI::run(int argc, char **argv) //plate_stride = partplate_list.plate_stride_x(); } - auto translate_models = [translate_old, shrink_to_new_bed, old_printable_width, old_printable_depth, old_printable_height, current_printable_width, current_printable_depth, current_printable_height] (Slic3r::GUI::PartPlateList& plate_list) { + auto translate_models = [translate_old, shrink_to_new_bed, old_printable_width, old_printable_depth, old_printable_height, current_printable_width, current_printable_depth, current_printable_height] (Slic3r::GUI::PartPlateList& plate_list, DynamicPrintConfig& print_config) { //BBS: translate old 3mf to correct positions if (translate_old) { //translate the objects @@ -1834,6 +1834,11 @@ int CLI::run(int argc, char **argv) if (shrink_to_new_bed) { int plate_count = plate_list.get_plate_count(); + ConfigOptionFloats *wipe_x_option = nullptr, *wipe_y_option = nullptr; + if (print_config.has("wipe_tower_x")) { + wipe_x_option = dynamic_cast(print_config.option("wipe_tower_x")); + wipe_y_option = dynamic_cast(print_config.option("wipe_tower_y")); + } for (int index = 0; index < plate_count; index ++) { Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)plate_list.get_plate(index); @@ -1845,6 +1850,16 @@ int CLI::run(int argc, char **argv) Vec3d offset = new_center - cur_center; cur_plate->translate_all_instance(offset); + if (wipe_x_option) { + BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1%: wipe tower src: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index); + ConfigOptionFloat wipe_tower_x(wipe_x_option->get_at(index) + offset(0)); + ConfigOptionFloat wipe_tower_y(wipe_y_option->get_at(index) + offset(1)); + + wipe_x_option->set_at(&wipe_tower_x, index, 0); + wipe_y_option->set_at(&wipe_tower_y, index, 0); + BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1% wipe tower changes to: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index); + } + BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1% translate offset: {%2%, %3%, %4%}")%(index+1) %offset[0] %offset[1] %offset[2]; } BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, shrink all the models to current bed size,{%1%, %2%, %3%}")%current_printable_width %current_printable_depth %current_printable_height; @@ -1855,7 +1870,7 @@ int CLI::run(int argc, char **argv) { partplate_list.load_from_3mf_structure(plate_data_src); - translate_models(partplate_list); + translate_models(partplate_list, m_print_config); } /*for (ModelObject *model_object : m_models[0].objects) @@ -2535,7 +2550,7 @@ int CLI::run(int argc, char **argv) model = original_model; partplate_list.load_from_3mf_structure(plate_data_src); - translate_models(partplate_list); + translate_models(partplate_list, m_print_config); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); } continue; @@ -2551,7 +2566,7 @@ int CLI::run(int argc, char **argv) model = original_model; partplate_list.load_from_3mf_structure(plate_data_src); - translate_models(partplate_list); + translate_models(partplate_list, m_print_config); duplicate_count = 0; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); continue; diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 636e00cbe..5aee315ed 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2137,7 +2137,7 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, s ModelObject* newObj = m_model->add_object(*object); newObj->name = object->name +"_"+ std::to_string(index+1); int new_obj_id = m_model->objects.size() - 1; - for ( size_t new_instance_id = 0; new_instance_id < object->instances.size(); new_instance_id++ ) + for ( size_t new_instance_id = 0; new_instance_id < newObj->instances.size(); new_instance_id++ ) { obj_to_instance_set.emplace(std::pair(new_obj_id, new_instance_id)); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": duplicate object into plate: index_pair [%1%,%2%], obj_id %3%") % new_obj_id % new_instance_id % newObj->id().id; @@ -2159,6 +2159,13 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, s if (instance->printable) { instance->loaded_id = instance->id().id; + if (need_skip) { + while (skip_objects.find(instance->loaded_id) != skip_objects.end()) + { + instance->loaded_id ++; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": duplicated id %1% with skip, try new one %2%") %instance->id().id % instance->loaded_id; + } + } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": set obj %1% instance %2%'s loaded_id to its id %3%, name %4%") % obj_id %instance_id %instance->loaded_id % object->name; } } From 064f3ee0aa33579368fc36fd23dd600bfab31620 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 9 Aug 2023 14:34:28 +0800 Subject: [PATCH 010/240] FIX: unify cli and GUI auto-arrange Make sure cli uses same params as GUI's auto-arrange. Previously cli uses wrong skirt_distance. Jira: BLPIOT-255 Change-Id: Iaccfb76acf7413ec614fff006feb770dcd6783cf --- src/BambuStudio.cpp | 51 +++++++--------------- src/libslic3r/Arrange.cpp | 69 ++++++++++++++++++++++++++++++ src/libslic3r/Arrange.hpp | 31 +++++++++++++- src/libslic3r/PrintConfig.cpp | 11 +++++ src/libslic3r/PrintConfig.hpp | 2 + src/slic3r/GUI/Jobs/ArrangeJob.cpp | 60 +++----------------------- src/slic3r/GUI/Jobs/ArrangeJob.hpp | 5 --- src/slic3r/GUI/Jobs/FillBedJob.cpp | 6 +-- 8 files changed, 136 insertions(+), 99 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 18b5bb98e..3872e9193 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2324,7 +2324,7 @@ int CLI::run(int argc, char **argv) //skip this object due to be not in current plate, treated as locked ap.itemid = locked_aps.size(); locked_aps.emplace_back(std::move(ap)); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format("arrange: skip locked instance, obj_id %1%, name %2%") % oidx % mo->name; } } } @@ -2346,12 +2346,12 @@ int CLI::run(int argc, char **argv) // slice filaments info invalid std::vector extruders = cur_plate->get_extruders_under_cli(true, m_print_config); filaments_cnt = extruders.size(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": slice filaments info invalid or need_skip, get from partplate: filament_count %1%")%filaments_cnt; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("arrange: slice filaments info invalid or need_skip, get from partplate: filament_count %1%")%filaments_cnt; } if (filaments_cnt <= 1) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": not a multi-color object anymore, drop the wipe tower before arrange."); + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format("arrange: not a multi-color object anymore, drop the wipe tower before arrange."); } else { @@ -2362,7 +2362,7 @@ int CLI::run(int argc, char **argv) float depth = v * (filaments_cnt - 1) / (layer_height * w); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", wipe_tower: x=%1%, y=%2%, width=%3%, depth=%4%, angle=%5%, prime_volume=%6%, filaments_cnt=%7%, layer_height=%8%") + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("arrange wipe_tower: x=%1%, y=%2%, width=%3%, depth=%4%, angle=%5%, prime_volume=%6%, filaments_cnt=%7%, layer_height=%8%") %x %y %w %depth %a %v %filaments_cnt %layer_height; Vec3d plate_origin = cur_plate->get_origin(); @@ -2404,39 +2404,20 @@ int CLI::run(int argc, char **argv) arrange_cfg.cleareance_radius = cleareance_radius; arrange_cfg.printable_height = print_height; - arrange_cfg.bed_shrink_x = 0; - arrange_cfg.bed_shrink_y = 0; - double skirt_distance = m_print_config.opt_float("skirt_distance"); - double brim_width = m_print_config.opt_float("brim_width"); - arrange_cfg.brim_skirt_distance = skirt_distance + brim_width; - BOOST_LOG_TRIVIAL(info) << boost::format("Arrange Params: brim_skirt_distance=%1%, min_obj_distance=%2%, is_seq_print=%3%\n") % arrange_cfg.brim_skirt_distance % arrange_cfg.min_obj_distance % arrange_cfg.is_seq_print; - - // Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt. - // So we can't do max but do adding instead. - arrange_cfg.bed_shrink_x += arrange_cfg.brim_skirt_distance; - arrange_cfg.bed_shrink_y += arrange_cfg.brim_skirt_distance; - - if (arrange_cfg.is_seq_print) - { - arrange_cfg.min_obj_distance = std::max(arrange_cfg.min_obj_distance, scaled(arrange_cfg.cleareance_radius + 0.001)); - float shift_dist = arrange_cfg.cleareance_radius / 2 - 5; - arrange_cfg.bed_shrink_x -= shift_dist; - arrange_cfg.bed_shrink_y -= shift_dist; - } - // shrink bed - beds[0] += Point(scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); - beds[1] += Point(-scaled(arrange_cfg.bed_shrink_x), scaled(arrange_cfg.bed_shrink_y)); - beds[2] += Point(-scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); - beds[3] += Point(scaled(arrange_cfg.bed_shrink_x), -scaled(arrange_cfg.bed_shrink_y)); - - // do not inflate brim_width. Objects are allowed to have overlapped brim. - std::for_each(selected.begin(), selected.end(), [&](auto& ap) {ap.inflation = arrange_cfg.min_obj_distance / 2; }); + arrangement::update_arrange_params(arrange_cfg, m_print_config, selected); + arrangement::update_selected_items_inflation(selected, &m_print_config, arrange_cfg); + arrangement::update_unselected_items_inflation(unselected, &m_print_config, arrange_cfg); + beds=get_shrink_bedpts(&m_print_config, arrange_cfg); { - BOOST_LOG_TRIVIAL(info) << boost::format("items selected before arranging: %1%")%selected.size(); - for (auto selected : selected) - BOOST_LOG_TRIVIAL(trace) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx - << ", trans: " << selected.translation.transpose(); + BOOST_LOG_TRIVIAL(debug)<< "Arrange full params: "<< arrange_cfg.to_json(); + BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items selected before arranging: %1%")%selected.size(); + for (auto item : selected) + BOOST_LOG_TRIVIAL(trace) << item.name << ", extruder: " << item.extrude_ids.back() << ", bed: " << item.bed_idx + << ", trans: " << item.translation.transpose(); + BOOST_LOG_TRIVIAL(info) << boost::format("arrange: items unselected before arranging: %1%") % unselected.size(); + for (auto item : unselected) + BOOST_LOG_TRIVIAL(trace) << item.name << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose(); } arrange_cfg.progressind= [](unsigned st, std::string str = "") { //boost::nowide::cout << "st=" << st << ", " << str << std::endl; diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 9b4f493ef..470340152 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -80,6 +80,75 @@ using ItemGroup = std::vector>; const double BIG_ITEM_TRESHOLD = 0.02; #define VITRIFY_TEMP_DIFF_THRSH 15 // bed temp can be higher than vitrify temp, but not higher than this thresh +void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig& print_cfg, const ArrangePolygons& selected) +{ + double skirt_distance = get_real_skirt_dist(print_cfg); + double brim_max = 0; + std::for_each(selected.begin(), selected.end(), [&](const ArrangePolygon& ap) { brim_max = std::max(brim_max, ap.brim_width); }); + // Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt. + // So we can't do max but do adding instead. + params.brim_skirt_distance = skirt_distance + brim_max; + params.bed_shrink_x = params.brim_skirt_distance; + params.bed_shrink_y = params.brim_skirt_distance; + // for sequential print, we need to inflate the bed because cleareance_radius is so large + if (params.is_seq_print) { + float shift_dist = params.cleareance_radius / 2 - 5; + params.bed_shrink_x -= shift_dist; + params.bed_shrink_y -= shift_dist; + } +} + +void update_selected_items_inflation(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params) { + // do not inflate brim_width. Objects are allowed to have overlapped brim. + Points bedpts = get_shrink_bedpts(print_cfg, params); + BoundingBox bedbb = Polygon(bedpts).bounding_box(); + std::for_each(selected.begin(), selected.end(), [&](ArrangePolygon& ap) { + ap.inflation = std::max(scaled(ap.brim_width), params.min_obj_distance / 2); + BoundingBox apbb = ap.poly.contour.bounding_box(); + auto diffx = bedbb.size().x() - apbb.size().x() - 5; + auto diffy = bedbb.size().y() - apbb.size().y() - 5; + if (diffx > 0 && diffy > 0) { + auto min_diff = std::min(diffx, diffy); + ap.inflation = std::min(min_diff / 2, ap.inflation); + } + }); +} + +void update_unselected_items_inflation(ArrangePolygons& unselected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params) +{ + if (params.is_seq_print) { + float shift_dist = params.cleareance_radius / 2 - 5; + // dont forget to move the excluded region + for (auto& region : unselected) { + if (region.is_virt_object) region.poly.translate(-scaled(shift_dist), -scaled(shift_dist)); + } + } + // For occulusion regions, inflation should be larger to prevent genrating brim on them. + // However, extrusion cali regions are exceptional, since we can allow brim overlaps them. + // 屏蔽区域只需要膨胀brim宽度,防止brim长过去;挤出标定区域不需要膨胀,brim可以长过去。 + // 以前我们认为还需要膨胀clearance_radius/2,这其实是不需要的,因为这些区域并不会真的摆放物体, + // 其他物体的膨胀轮廓是可以跟它们重叠的。 + double scaled_exclusion_gap = scale_(1); + std::for_each(unselected.begin(), unselected.end(), + [&](auto& ap) { ap.inflation = !ap.is_virt_object ? std::max(scaled(ap.brim_width), params.min_obj_distance / 2) + : (ap.is_extrusion_cali_object ? 0 : scaled_exclusion_gap); }); +} + +//it will bed accurate after call update_params +Points get_shrink_bedpts(const DynamicPrintConfig* print_cfg, const ArrangeParams& params) +{ + Points bedpts = get_bed_shape(*print_cfg); + // shrink bed by moving to center by dist + auto shrinkFun = [](Points& bedpts, double dist, int direction) { +#define SGN(x) ((x) >= 0 ? 1 : -1) + Point center = Polygon(bedpts).bounding_box().center(); + for (auto& pt : bedpts) pt[direction] += dist * SGN(center[direction] - pt[direction]); + }; + shrinkFun(bedpts, scaled(params.bed_shrink_x), 0); + shrinkFun(bedpts, scaled(params.bed_shrink_y), 1); + return bedpts; +} + // Fill in the placer algorithm configuration with values carefully chosen for // Slic3r. template diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index a9b7cc484..be3d67e97 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -2,7 +2,7 @@ #define ARRANGE_HPP #include "ExPolygon.hpp" - +#include "PrintConfig.hpp" namespace Slic3r { class BoundingBox; @@ -144,8 +144,37 @@ struct ArrangeParams { ArrangeParams() = default; explicit ArrangeParams(coord_t md) : min_obj_distance(md) {} + // to json format + std::string to_json() const{ + std::string ret = "{"; + ret += "\"min_obj_distance\":" + std::to_string(min_obj_distance) + ","; + ret += "\"accuracy\":" + std::to_string(accuracy) + ","; + ret += "\"parallel\":" + std::to_string(parallel) + ","; + ret += "\"allow_rotations\":" + std::to_string(allow_rotations) + ","; + ret += "\"do_final_align\":" + std::to_string(do_final_align) + ","; + ret += "\"allow_multi_materials_on_same_plate\":" + std::to_string(allow_multi_materials_on_same_plate) + ","; + ret += "\"avoid_extrusion_cali_region\":" + std::to_string(avoid_extrusion_cali_region) + ","; + ret += "\"is_seq_print\":" + std::to_string(is_seq_print) + ","; + ret += "\"bed_shrink_x\":" + std::to_string(bed_shrink_x) + ","; + ret += "\"bed_shrink_y\":" + std::to_string(bed_shrink_y) + ","; + ret += "\"brim_skirt_distance\":" + std::to_string(brim_skirt_distance) + ","; + ret += "\"clearance_height_to_rod\":" + std::to_string(clearance_height_to_rod) + ","; + ret += "\"clearance_height_to_lid\":" + std::to_string(clearance_height_to_lid) + ","; + ret += "\"cleareance_radius\":" + std::to_string(cleareance_radius) + ","; + ret += "\"printable_height\":" + std::to_string(printable_height) + ","; + return ret; + } + }; +void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig& print_cfg, const ArrangePolygons& selected); + +void update_selected_items_inflation(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params); + +void update_unselected_items_inflation(ArrangePolygons& unselected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params); + +Points get_shrink_bedpts(const DynamicPrintConfig* print_cfg, const ArrangeParams& params); + /** * \brief Arranges the input polygons. * diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b6f309449..0b18291cb 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5293,6 +5293,17 @@ Polygon get_bed_shape_with_excluded_area(const PrintConfig& cfg) if (!tmp.empty()) bed_poly = tmp[0]; return bed_poly; } +bool has_skirt(const DynamicPrintConfig& cfg) +{ + auto opt_skirt_height = cfg.option("skirt_height"); + auto opt_skirt_loops = cfg.option("skirt_loops"); + auto opt_draft_shield = cfg.option("draft_shield"); + return (opt_skirt_height && opt_skirt_height->getInt() > 0 && opt_skirt_loops && opt_skirt_loops->getInt() > 0) + || (opt_draft_shield && opt_draft_shield->getInt() != dsDisabled); +} +float get_real_skirt_dist(const DynamicPrintConfig& cfg) { + return has_skirt(cfg) ? cfg.opt_float("skirt_distance") : 0; +} } // namespace Slic3r #include diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 02f1718c3..3f1fa4a2a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1292,6 +1292,8 @@ Points get_bed_shape(const DynamicPrintConfig &cfg); Points get_bed_shape(const PrintConfig &cfg); Points get_bed_shape(const SLAPrinterConfig &cfg); Slic3r::Polygon get_bed_shape_with_excluded_area(const PrintConfig& cfg); +bool has_skirt(const DynamicPrintConfig& cfg); +float get_real_skirt_dist(const DynamicPrintConfig& cfg); // ModelConfig is a wrapper around DynamicPrintConfig with an addition of a timestamp. // Each change of ModelConfig is tracked by assigning a new timestamp from a global counter. diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 528ac10c6..320e8dc03 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -502,10 +502,10 @@ void ArrangeJob::process() partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); update_arrange_params(params, *m_plater, m_selected); - update_selected_items_inflation(m_selected, *m_plater, params); - update_unselected_items_inflation(m_unselected, *m_plater, params); + update_selected_items_inflation(m_selected, m_plater->config(), params); + update_unselected_items_inflation(m_unselected, m_plater->config(), params); - Points bedpts = get_shrink_bedpts(*m_plater,params); + Points bedpts = get_shrink_bedpts(m_plater->config(),params); double scaled_exclusion_gap = scale_(1); partplate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap); @@ -519,6 +519,7 @@ void ArrangeJob::process() }; { + BOOST_LOG_TRIVIAL(debug)<< "Arrange full params: "<< params.to_json(); BOOST_LOG_TRIVIAL(debug) << "items selected before arrange: "; for (auto selected : m_selected) BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx @@ -758,7 +759,7 @@ arrangement::ArrangeParams init_arrange_params(Plater *p) return params; } -//after get selected.call this to update bed_shrink +//after get selected call this to update bed_shrink void update_arrange_params(arrangement::ArrangeParams ¶ms, const Plater &p, const arrangement::ArrangePolygons &selected) { const GLCanvas3D::ArrangeSettings &settings = static_cast(p.canvas3D())->get_arrange_settings(); @@ -779,55 +780,4 @@ void update_arrange_params(arrangement::ArrangeParams ¶ms, const Plater &p, } } -//it will bed accurate after call update_params -Points get_shrink_bedpts(const Plater &plater, const arrangement::ArrangeParams ¶ms) -{ - Points bedpts = get_bed_shape(*plater.config()); - // shrink bed by moving to center by dist - auto shrinkFun = [](Points &bedpts, double dist, int direction) { -#define SGN(x) ((x) >= 0 ? 1 : -1) - Point center = Polygon(bedpts).bounding_box().center(); - for (auto &pt : bedpts) pt[direction] += dist * SGN(center[direction] - pt[direction]); - }; - shrinkFun(bedpts, scaled(params.bed_shrink_x), 0); - shrinkFun(bedpts, scaled(params.bed_shrink_y), 1); - return bedpts; -} - -void update_selected_items_inflation(arrangement::ArrangePolygons &selected, const Plater &p, const arrangement::ArrangeParams ¶ms) { - // do not inflate brim_width. Objects are allowed to have overlapped brim. - Points bedpts = get_shrink_bedpts(p, params); - BoundingBox bedbb = Polygon(bedpts).bounding_box(); - std::for_each(selected.begin(), selected.end(), [&](ArrangePolygon &ap) { - ap.inflation = std::max(scaled(ap.brim_width), params.min_obj_distance / 2); - BoundingBox apbb = ap.poly.contour.bounding_box(); - auto diffx = bedbb.size().x() - apbb.size().x() - 5; - auto diffy = bedbb.size().y() - apbb.size().y() - 5; - if (diffx > 0 && diffy > 0) { - auto min_diff = std::min(diffx, diffy); - ap.inflation = std::min(min_diff / 2, ap.inflation); - } - }); -} - -void update_unselected_items_inflation(arrangement::ArrangePolygons &unselected, const Plater &p, const arrangement::ArrangeParams ¶ms) -{ - if (params.is_seq_print) { - float shift_dist = params.cleareance_radius / 2 - 5; - // dont forget to move the excluded region - for (auto ®ion : unselected) { - if (region.is_virt_object) region.poly.translate(-scaled(shift_dist), -scaled(shift_dist)); - } - } - // For occulusion regions, inflation should be larger to prevent genrating brim on them. - // However, extrusion cali regions are exceptional, since we can allow brim overlaps them. - // 屏蔽区域只需要膨胀brim宽度,防止brim长过去;挤出标定区域不需要膨胀,brim可以长过去。 - // 以前我们认为还需要膨胀clearance_radius/2,这其实是不需要的,因为这些区域并不会真的摆放物体, - // 其他物体的膨胀轮廓是可以跟它们重叠的。 - double scaled_exclusion_gap = scale_(1); - std::for_each(unselected.begin(), unselected.end(), - [&](auto &ap) { ap.inflation = !ap.is_virt_object ? std::max(scaled(ap.brim_width), params.min_obj_distance / 2) - : (ap.is_extrusion_cali_object ? 0 : scaled_exclusion_gap); }); -} - }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index e4ec09b5e..ae56866ce 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -80,13 +80,8 @@ arrangement::ArrangeParams get_arrange_params(Plater *p); arrangement::ArrangeParams init_arrange_params(Plater *p); -Points get_shrink_bedpts(const Plater& plater,const arrangement::ArrangeParams& params); - void update_arrange_params(arrangement::ArrangeParams ¶ms, const Plater &p, const arrangement::ArrangePolygons &selected); -void update_selected_items_inflation(arrangement::ArrangePolygons &selected, const Plater &p, const arrangement::ArrangeParams ¶ms); - -void update_unselected_items_inflation(arrangement::ArrangePolygons &unselected, const Plater &p, const arrangement::ArrangeParams ¶ms); }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index c00968180..6e53d6183 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -206,7 +206,7 @@ void FillBedJob::process() static_cast(m_plater->canvas3D())->get_arrange_settings(); update_arrange_params(params, *m_plater, m_selected); - m_bedpts = get_shrink_bedpts(*m_plater, params); + m_bedpts = get_shrink_bedpts(m_plater->config(), params); auto &partplate_list = m_plater->get_partplate_list(); auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print(); @@ -214,8 +214,8 @@ void FillBedJob::process() if (params.avoid_extrusion_cali_region && global_config.opt_bool("scan_first_layer")) partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); - update_selected_items_inflation(m_selected, *m_plater, params); - update_unselected_items_inflation(m_unselected, *m_plater, params); + update_selected_items_inflation(m_selected, m_plater->config(), params); + update_unselected_items_inflation(m_unselected, m_plater->config(), params); bool do_stop = false; params.stopcondition = [this, &do_stop]() { From e1b3a5b6d5ffc010d0bcb550ab9ec4360bf171f5 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 16 Aug 2023 14:36:22 +0800 Subject: [PATCH 011/240] ENH: CLI: add a flag to allow minimum size save JIRA: STUDIO-3752 Change-Id: I0277c34d108185d10130630a72811122f8ee9ae2 --- src/BambuStudio.cpp | 14 +++++++++++--- src/BambuStudio.hpp | 2 +- src/libslic3r/PrintConfig.cpp | 6 ++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 3872e9193..87861ca91 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -559,7 +559,7 @@ int CLI::run(int argc, char **argv) PlateDataPtrs plate_data_src; int arrange_option; int plate_to_slice = 0, filament_count = 0, duplicate_count = 0, real_duplicate_count = 0; - bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true, duplicate_single_object = false, use_first_fila_as_default = false; + bool first_file = true, is_bbl_3mf = false, need_arrange = true, has_thumbnails = false, up_config_to_date = false, normative_check = true, duplicate_single_object = false, use_first_fila_as_default = false, minimum_save = false; Semver file_version; std::map orients_requirement; std::vector project_presets; @@ -588,6 +588,10 @@ int CLI::run(int argc, char **argv) if (load_defaultfila_option) use_first_fila_as_default = load_defaultfila_option->value; + ConfigOptionBool* min_save_option = m_config.option("min_save"); + if (min_save_option) + minimum_save = min_save_option->value; + ConfigOptionString* pipe_option = m_config.option("pipe"); if (pipe_option) { pipe_name = pipe_option->value; @@ -2692,6 +2696,8 @@ int CLI::run(int argc, char **argv) } } else if (opt_key == "uptodate") { //already processed before + } else if (opt_key == "min_save") { + //already processed before } else if (opt_key == "load_defaultfila") { //already processed before } else if (opt_key == "mtcpp") { @@ -3631,7 +3637,7 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "will export 3mf to " << export_3mf_file << std::endl; if (! this->export_project(&m_models[0], export_3mf_file, plate_data_list, project_presets, thumbnails, top_thumbnails, pick_thumbnails, - calibration_thumbnails, plate_bboxes, &m_print_config)) + calibration_thumbnails, plate_bboxes, &m_print_config, minimum_save)) { release_PlateData_list(plate_data_list); record_exit_reson(outfile_dir, CLI_EXPORT_3MF_ERROR, 0, cli_errors[CLI_EXPORT_3MF_ERROR]); @@ -3854,7 +3860,7 @@ bool CLI::export_models(IO::ExportFormat format) //BBS: add export_project function bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partplate_data, std::vector& project_presets, std::vector& thumbnails, std::vector& top_thumbnails, std::vector& pick_thumbnails, - std::vector& calibration_thumbnails, std::vector& plate_bboxes, const DynamicPrintConfig* config) + std::vector& calibration_thumbnails, std::vector& plate_bboxes, const DynamicPrintConfig* config, bool minimum_save) { //const std::string path = this->output_filepath(*model, IO::TMF); bool success = false; @@ -3871,6 +3877,8 @@ bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partpla store_params.calibration_thumbnail_data = calibration_thumbnails; store_params.id_bboxes = plate_bboxes; store_params.strategy = SaveStrategy::Silence|SaveStrategy::WithGcode|SaveStrategy::SplitModel|SaveStrategy::UseLoadedId|SaveStrategy::ShareMesh; + if (minimum_save) + store_params.strategy = store_params.strategy | SaveStrategy::SkipModel; success = Slic3r::store_bbs_3mf(store_params); diff --git a/src/BambuStudio.hpp b/src/BambuStudio.hpp index 71507738d..ba4fcf969 100644 --- a/src/BambuStudio.hpp +++ b/src/BambuStudio.hpp @@ -41,7 +41,7 @@ private: bool export_project(Model *model, std::string& path, PlateDataPtrs &partplate_data, std::vector& project_presets, std::vector& thumbnails, std::vector& top_thumbnails, std::vector& pick_thumbnails, std::vector& calibration_thumbnails, - std::vector& plate_bboxes, const DynamicPrintConfig* config); + std::vector& plate_bboxes, const DynamicPrintConfig* config, bool minimum_save); bool has_print_action() const { return m_config.opt_bool("export_gcode") || m_config.opt_bool("export_sla"); } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0b18291cb..650d7c61e 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4964,6 +4964,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->cli_params = "option"; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("min_save", coBool); + def->label = L("Minimum save"); + def->tooltip = L("export 3mf with minimum size."); + def->cli_params = "option"; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("mtcpp", coInt); def->label = L("mtcpp"); def->tooltip = L("max triangle count per plate for slicing."); From 2f51b0be97feeafe0f21629334a6745b53b2b27c Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 18 Aug 2023 20:25:53 +0800 Subject: [PATCH 012/240] FIX: CLI: fix a wipe tower position issue when arrange failed and restore to original we will compute the position of wipe tower again we should skip this case JIRA: STUDIO-4048 Change-Id: I19edc36dfa7ec5a9f6b5ba3a1c1e0767361b3e33 --- src/BambuStudio.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 87861ca91..3023f136e 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -1839,6 +1839,7 @@ int CLI::run(int argc, char **argv) { int plate_count = plate_list.get_plate_count(); ConfigOptionFloats *wipe_x_option = nullptr, *wipe_y_option = nullptr; + Vec3d wipe_offset; if (print_config.has("wipe_tower_x")) { wipe_x_option = dynamic_cast(print_config.option("wipe_tower_x")); wipe_y_option = dynamic_cast(print_config.option("wipe_tower_y")); @@ -1854,10 +1855,12 @@ int CLI::run(int argc, char **argv) Vec3d offset = new_center - cur_center; cur_plate->translate_all_instance(offset); + if (index == 0) + wipe_offset = offset; if (wipe_x_option) { BOOST_LOG_TRIVIAL(info) << boost::format("shrink_to_new_bed, plate %1%: wipe tower src: {%2%, %3%}")%(index+1) %wipe_x_option->get_at(index) %wipe_y_option->get_at(index); - ConfigOptionFloat wipe_tower_x(wipe_x_option->get_at(index) + offset(0)); - ConfigOptionFloat wipe_tower_y(wipe_y_option->get_at(index) + offset(1)); + ConfigOptionFloat wipe_tower_x(wipe_x_option->get_at(index) + wipe_offset(0)); + ConfigOptionFloat wipe_tower_y(wipe_y_option->get_at(index) + wipe_offset(1)); wipe_x_option->set_at(&wipe_tower_x, index, 0); wipe_y_option->set_at(&wipe_tower_y, index, 0); @@ -2534,8 +2537,7 @@ int CLI::run(int argc, char **argv) finished_arrange = true; model = original_model; partplate_list.load_from_3mf_structure(plate_data_src); - - translate_models(partplate_list, m_print_config); + partplate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); } continue; @@ -2550,8 +2552,7 @@ int CLI::run(int argc, char **argv) finished_arrange = true; model = original_model; partplate_list.load_from_3mf_structure(plate_data_src); - - translate_models(partplate_list, m_print_config); + partplate_list.reset_size(current_printable_width, current_printable_depth, current_printable_height, true, true); duplicate_count = 0; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": exit arrange process"); continue; From 731035b8b6cfda5b098243ae8892597503ca5ea8 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Mon, 21 Aug 2023 16:49:38 +0800 Subject: [PATCH 013/240] FIX: CLI: fix some issues 1. JIRA: MAK-1727, color of thumbnail not correct 2. JIRA: MAK-1723, model upload outside issue Change-Id: I1754d730021c9df8044248e931023899d410d8de --- src/BambuStudio.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 3023f136e..35c9a75bc 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -470,7 +470,7 @@ int CLI::run(int argc, char **argv) boost::algorithm::iends_with(boost::filesystem::path(argv[0]).filename().string(), "gcodeviewer"); #endif // _WIN32*/ - bool translate_old = false, regenerate_thumbnails = false, shrink_to_new_bed = false; + bool translate_old = false, regenerate_thumbnails = false, shrink_to_new_bed = false, filament_color_changed = false; int current_printable_width, current_printable_depth, current_printable_height; int old_printable_height = 0, old_printable_width = 0, old_printable_depth = 0; Pointfs old_printable_area, old_exclude_area; @@ -1620,6 +1620,14 @@ int CLI::run(int argc, char **argv) if (!selected_filament_colors[index].empty()) { BOOST_LOG_TRIVIAL(info) << boost::format("changed to new color %1%")%selected_filament_colors[index]; + unsigned char ori_rgb_color[4] = {}, new_rgb_color[4] = {}; + Slic3r::GUI::BitmapCache::parse_color4(project_filament_colors[index], ori_rgb_color); + Slic3r::GUI::BitmapCache::parse_color4(selected_filament_colors[index], new_rgb_color); + if ((ori_rgb_color[0] != new_rgb_color[0]) || (ori_rgb_color[1] != new_rgb_color[1]) || (ori_rgb_color[2] != new_rgb_color[2]) || (ori_rgb_color[3] != new_rgb_color[3])) + { + BOOST_LOG_TRIVIAL(info) << boost::format("found color changes, need to regenerate thumbnail"); + filament_color_changed = true; + } project_filament_colors[index] = selected_filament_colors[index]; } } @@ -2177,11 +2185,9 @@ int CLI::run(int argc, char **argv) orients_requirement.clear(); oriented_or_arranged |= need_arrange; - BOOST_LOG_TRIVIAL(info) << boost::format("before arrange, need_arrange=%1%, duplicate_count %2%")%need_arrange%duplicate_count; - if (need_arrange) + BOOST_LOG_TRIVIAL(info) << boost::format("before arrange, need_arrange=%1%, duplicate_count %2%, filament_color_changed %3%")%need_arrange %duplicate_count %filament_color_changed; + if (need_arrange || filament_color_changed) { - ArrangePolygons selected, unselected, unprintable, locked_aps; - for (int index = 0; index < partplate_list.get_plate_count(); index ++) { if ((plate_to_slice != 0) && (plate_to_slice != (index + 1))) { @@ -2203,6 +2209,11 @@ int CLI::run(int argc, char **argv) } } } + } + + if (need_arrange) + { + ArrangePolygons selected, unselected, unprintable, locked_aps; //for (Model &model : m_models) if (m_models.size() > 0) @@ -2742,8 +2753,6 @@ int CLI::run(int argc, char **argv) //BBS: slice 0 means all plates, i means plate i; plate_to_slice = m_config.option("slice")->value; bool pre_check = (plate_to_slice == 0)?true:false; - if (partplate_list.get_plate_count() == 1) - pre_check = false; bool finished = false; /*if (opt_key == "export_gcode" && printer_technology == ptSLA) { @@ -2937,7 +2946,7 @@ int CLI::run(int argc, char **argv) flush_and_exit(CLI_NO_SUITABLE_OBJECTS); } else { - if (pre_check) //continue to next plate directly + if (pre_check && (partplate_list.get_plate_count() > 1)) //continue to next plate directly continue; try { std::string outfile_final; @@ -3075,7 +3084,7 @@ int CLI::run(int argc, char **argv) } } } - if (pre_check) + if (pre_check&& (partplate_list.get_plate_count() > 1)) pre_check = false; else finished = true; From a15700e5def0bd61dc541117509ca5cb29424829 Mon Sep 17 00:00:00 2001 From: PavelMikus Date: Fri, 9 Sep 2022 12:50:10 +0200 Subject: [PATCH 014/240] FIX: short edge collapse algortihm so that it does not decimate all triangles on very high detailed models Relevant issue 8834 Access Error when slicing Github: #2283 Change-Id: I047361c88c561962ef4d3cf67bc0126402c41941 (cherry picked from commit f8aaa5c69d59c5fced4b7bb112376e4df94b5ddc) --- src/libslic3r/GCode/SeamPlacer.cpp | 7 ++++--- src/libslic3r/GCode/SeamPlacer.hpp | 3 ++- src/libslic3r/ShortEdgeCollapse.cpp | 6 +++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index c333abfe4..7d8bdf3e8 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -590,9 +590,10 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po, st BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather occlusion meshes: end"; - BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: decimate: start"; - its_short_edge_collpase(triangle_set, 25000); - its_short_edge_collpase(negative_volumes_set, 25000); + BOOST_LOG_TRIVIAL(debug) + << "SeamPlacer: decimate: start"; + its_short_edge_collpase(triangle_set, SeamPlacer::fast_decimation_triangle_count_target); + its_short_edge_collpase(negative_volumes_set, SeamPlacer::fast_decimation_triangle_count_target); size_t negative_volumes_start_index = triangle_set.indices.size(); its_merge(triangle_set, negative_volumes_set); diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp index 43727f173..0c431202e 100644 --- a/src/libslic3r/GCode/SeamPlacer.hpp +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -115,7 +115,8 @@ class SeamPlacer public: // Number of samples generated on the mesh. There are sqr_rays_per_sample_point*sqr_rays_per_sample_point rays casted from each samples static constexpr size_t raycasting_visibility_samples_count = 30000; - // square of number of rays per sample point + static constexpr size_t fast_decimation_triangle_count_target = 16000; + //square of number of rays per sample point static constexpr size_t sqr_rays_per_sample_point = 5; // snapping angle - angles larger than this value will be snapped to during seam painting diff --git a/src/libslic3r/ShortEdgeCollapse.cpp b/src/libslic3r/ShortEdgeCollapse.cpp index b36278c37..0c940cb47 100644 --- a/src/libslic3r/ShortEdgeCollapse.cpp +++ b/src/libslic3r/ShortEdgeCollapse.cpp @@ -97,7 +97,8 @@ void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_ //shuffle the faces and traverse in random order, this MASSIVELY improves the quality of the result std::shuffle(face_indices.begin(), face_indices.end(), generator); - + + int allowed_face_removals = int(face_indices.size()) - int(target_triangle_count); for (const size_t &face_idx : face_indices) { if (face_removal_flags[face_idx]) { // if face already removed from previous collapses, skip (each collapse removes two triangles [at least] ) @@ -130,10 +131,13 @@ void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_ // remove faces remove_face(face_idx, neighbor_to_remove_face_idx); remove_face(neighbor_to_remove_face_idx, face_idx); + allowed_face_removals-=2; // break. this triangle is done break; } + + if (allowed_face_removals <= 0) { break; } } // filter face_indices, remove those that have been collapsed From c97a88069b5ed4f64ab41d5381cde4367d7d8ee5 Mon Sep 17 00:00:00 2001 From: "wenjie.guo" Date: Mon, 21 Aug 2023 17:27:56 +0800 Subject: [PATCH 015/240] NEW: Z hop restriction Z hop will only come into effect when it is between retract_lift_above and retract_lift_below. Signed-off-by: wenjie.guo Change-Id: If43aea7024018eb8f532c6af5d8000973f2edee3 --- src/libslic3r/GCodeWriter.cpp | 5 ++++- src/libslic3r/Print.cpp | 2 ++ src/libslic3r/PrintConfig.cpp | 21 +++++++++++++++++++-- src/libslic3r/PrintConfig.hpp | 2 ++ src/slic3r/GUI/Tab.cpp | 2 ++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 8a9f3488b..57f9f1775 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -652,7 +652,10 @@ std::string GCodeWriter::lift(LiftType lift_type, bool spiral_vase) double target_lift = 0; { //BBS - target_lift = this->config.z_hop.get_at(m_extruder->id()); + double above = this->config.retract_lift_above.get_at(m_extruder->id()); + double below = this->config.retract_lift_below.get_at(m_extruder->id()); + if (m_pos.z() >= above && (below == 0 || m_pos.z() <= below)) + target_lift = this->config.z_hop.get_at(m_extruder->id()); } // BBS if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index de2f02a32..6761f5d9f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -135,6 +135,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "retract_restart_extra", "retract_restart_extra_toolchange", "retraction_speed", + "retract_lift_above", + "retract_lift_below", "slow_down_layer_time", "standby_temperature_delta", "machine_start_gcode", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 650d7c61e..3f09cd54f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2431,6 +2431,21 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionFloats { 0.4 }); + def = this->add("retract_lift_above", coFloats); + def->label = L("Z hop lower boundary"); + def->tooltip = L("Z hop will only come into effect when Z is above this value and is below the parameter: \"Z hop upper boundary\""); + def->sidetext = L("mm"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloats{0.}); + + def = this->add("retract_lift_below", coFloats); + def->label = L("Z hop upper boundary"); + def->tooltip = L("If this value is positive, Z hop will only come into effect when Z is above the parameter: \"Z hop lower boundary\" and is below this value"); + def->sidetext = L("mm"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloats{0.}); + + def = this->add("z_hop_types", coEnums); def->label = L("Z Hop Type"); def->tooltip = L(""); @@ -3435,7 +3450,7 @@ void PrintConfigDef::init_fff_params() // Declare retract values for filament profile, overriding the printer's extruder profile. for (const char *opt_key : { // floats - "retraction_length", "z_hop", "z_hop_types", "retraction_speed", "deretraction_speed", "retract_restart_extra", "retraction_minimum_travel", + "retraction_length", "z_hop", "z_hop_types", "retract_lift_above", "retract_lift_below","retraction_speed", "deretraction_speed", "retract_restart_extra", "retraction_minimum_travel", // BBS: floats "wipe_distance", // bools @@ -3482,7 +3497,7 @@ void PrintConfigDef::init_extruder_option_keys() // ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings m_extruder_option_keys = { "extruder_type", "nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset", - "retraction_length", "z_hop", "z_hop_types", "retraction_speed", "deretraction_speed", + "retraction_length", "z_hop", "z_hop_types", "retraction_speed", "retract_lift_above", "retract_lift_below","deretraction_speed", "retract_before_wipe", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance", "retract_when_changing_layer", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", "default_filament_profile" @@ -3491,6 +3506,8 @@ void PrintConfigDef::init_extruder_option_keys() m_extruder_retract_keys = { "deretraction_speed", "retract_before_wipe", + "retract_lift_above", + "retract_lift_below", "retract_restart_extra", "retract_when_changing_layer", "retraction_length", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 3f1fa4a2a..dee5c2bf1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -860,6 +860,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, retract_restart_extra)) ((ConfigOptionFloats, retract_restart_extra_toolchange)) ((ConfigOptionFloats, retraction_speed)) + ((ConfigOptionFloats, retract_lift_above)) + ((ConfigOptionFloats, retract_lift_below)) ((ConfigOptionString, machine_start_gcode)) ((ConfigOptionStrings, filament_start_gcode)) ((ConfigOptionBool, single_extruder_multi_material)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9b52351cd..eba32f616 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3465,6 +3465,8 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/) optgroup = page->new_optgroup(L("Retraction"), L"param_retraction"); optgroup->append_single_option_line("retraction_length", "", extruder_idx); optgroup->append_single_option_line("z_hop", "", extruder_idx); + optgroup->append_single_option_line("retract_lift_above", "", extruder_idx); + optgroup->append_single_option_line("retract_lift_below", "", extruder_idx); optgroup->append_single_option_line("z_hop_types", "", extruder_idx); optgroup->append_single_option_line("retraction_speed", "", extruder_idx); optgroup->append_single_option_line("deretraction_speed", "", extruder_idx); From 353c962c21dfea9ffd02ea15c99346c09f6c41c8 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Thu, 24 Aug 2023 15:35:37 +0800 Subject: [PATCH 016/240] ENH: add a device id parameter for hms wiki JIRA: STUDIO-4177 different printer may have different hms wiki page Change-Id: I0f4443580466ab1afc1fe16da6f5ed924e5d201d Signed-off-by: Stone Li --- src/slic3r/GUI/HMS.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/slic3r/GUI/HMS.cpp b/src/slic3r/GUI/HMS.cpp index 87c5257a9..2f24569a6 100644 --- a/src/slic3r/GUI/HMS.cpp +++ b/src/slic3r/GUI/HMS.cpp @@ -279,9 +279,22 @@ std::string get_hms_wiki_url(std::string error_code) std::string hms_host = wxGetApp().app_config->get_hms_host(); std::string lang_code = HMSQuery::hms_language_code(); std::string url = (boost::format("https://%1%/index.php?e=%2%&s=device_hms&lang=%3%") + % hms_host + % error_code + % lang_code).str(); + + DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) return url; + MachineObject* obj = dev->get_selected_machine(); + if (!obj) return url; + + if (!obj->dev_id.empty()) { + url = (boost::format("https://%1%/index.php?e=%2%&d=%3%&s=device_hms&lang=%4%") % hms_host % error_code + % obj->dev_id % lang_code).str(); + } return url; } From 7f642112d2b82c7179b743f2418e18243b306cb3 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 25 Aug 2023 10:19:47 +0800 Subject: [PATCH 017/240] ENH: CLI: add the re-arrange logic when the printer type change with different extruder_clearances JIRA: STUDIO-4214 Change-Id: I6a8862b4da9812d38522fba2235d5e02f421878b (cherry picked from commit 0d00660feb97fa0652c7984d92150aacd2746698) --- src/BambuStudio.cpp | 151 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 121 insertions(+), 30 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 35c9a75bc..07334c9a3 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -474,6 +474,7 @@ int CLI::run(int argc, char **argv) int current_printable_width, current_printable_depth, current_printable_height; int old_printable_height = 0, old_printable_width = 0, old_printable_depth = 0; Pointfs old_printable_area, old_exclude_area; + float old_max_radius = 0.f, old_height_to_rod = 0.f, old_height_to_lid = 0.f; std::string outfile_dir = m_config.opt_string("outputdir", true); const std::vector &load_configs = m_config.option("load_settings", true)->values; const std::vector &uptodate_configs = m_config.option("uptodate_settings", true)->values; @@ -751,7 +752,15 @@ int CLI::run(int argc, char **argv) old_printable_depth = (int)(old_printable_area[2].y() - old_printable_area[0].y()); } old_printable_height = (int)(config.opt_float("printable_height")); + + if (config.option("extruder_clearance_height_to_rod")) + old_height_to_rod = config.opt_float("extruder_clearance_height_to_rod"); + if (config.option("extruder_clearance_height_to_lid")) + old_height_to_lid = config.opt_float("extruder_clearance_height_to_lid"); + if (config.option("extruder_clearance_max_radius")) + old_max_radius = config.opt_float("extruder_clearance_max_radius"); BOOST_LOG_TRIVIAL(info) << boost::format("old printable size from 3mf: {%1%, %2%, %3%}")%old_printable_width %old_printable_depth %old_printable_height; + BOOST_LOG_TRIVIAL(info) << boost::format("old extruder_clearance_height_to_rod %1%, extruder_clearance_height_to_lid %2%, extruder_clearance_max_radius %3%}")%old_height_to_rod %old_height_to_lid %old_max_radius; } else { @@ -2183,6 +2192,42 @@ int CLI::run(int argc, char **argv) } //BBS: clear the orient objects lists orients_requirement.clear(); + + if ((plate_to_slice < 0) || (plate_to_slice > partplate_list.get_plate_count())) + { + BOOST_LOG_TRIVIAL(error) << boost::format("invalid plate id %1%, total %2%")%plate_to_slice %partplate_list.get_plate_count(); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + flush_and_exit(CLI_INVALID_PARAMS); + } + + if ((!need_arrange) && is_bbl_3mf && !shrink_to_new_bed && (plate_to_slice > 0)) + { + if (((old_height_to_rod != 0.f) && (old_height_to_rod != height_to_rod)) + || ((old_height_to_lid != 0.f) && (old_height_to_lid != height_to_lid)) + || ((old_max_radius != 0.f) && (old_max_radius != cleareance_radius))) + { + Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); + PrintSequence curr_plate_seq = cur_plate->get_print_seq(); + bool is_seq_print = false; + if (curr_plate_seq == PrintSequence::ByDefault) { + auto seq_print = m_print_config.option>("print_sequence"); + if (seq_print && (seq_print->value == PrintSequence::ByObject)) { + BOOST_LOG_TRIVIAL(info) << boost::format("Check whether need to arrange by print_sequence: plate %1% print by object, set from global")%plate_to_slice; + is_seq_print = true; + } + } + else if (curr_plate_seq == PrintSequence::ByObject) { + BOOST_LOG_TRIVIAL(info) << boost::format("Check whether need to arrange by print_sequence: plate %1% print by object, set from plate self")%plate_to_slice; + is_seq_print = true; + } + if (is_seq_print) { + need_arrange = true; + BOOST_LOG_TRIVIAL(info) << boost::format("old_height_to_rod %1%, old_height_to_lid %2%, old_max_radius %3%, current height_to_rod %4%, height_to_lid %5%, cleareance_radius %6%, need arrange!") + %old_height_to_rod %old_height_to_lid %old_max_radius %height_to_rod %height_to_lid %cleareance_radius; + } + } + } + oriented_or_arranged |= need_arrange; BOOST_LOG_TRIVIAL(info) << boost::format("before arrange, need_arrange=%1%, duplicate_count %2%, filament_color_changed %3%")%need_arrange %duplicate_count %filament_color_changed; @@ -2256,10 +2301,30 @@ int CLI::run(int argc, char **argv) cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); cur_plate->duplicate_all_instance(duplicate_count, need_skip, skip_maps); } + else if (plate_to_slice > 0) + { + cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); + } + + if (cur_plate) { + PrintSequence curr_plate_seq = cur_plate->get_print_seq(); + if (curr_plate_seq == PrintSequence::ByDefault) { + auto seq_print = m_print_config.option>("print_sequence"); + if (seq_print && (seq_print->value == PrintSequence::ByObject)) { + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from global")%plate_to_slice; + arrange_cfg.is_seq_print = true; + } + } + else if (curr_plate_seq == PrintSequence::ByObject) { + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from plate self")%plate_to_slice; + arrange_cfg.is_seq_print = true; + } + } //Step-1: prepare arrange polygons - if (duplicate_count == 0) + if ((duplicate_count == 0) && (plate_to_slice == 0)) { + //global arrange for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) { ModelObject* mo = model.objects[oidx]; @@ -2299,20 +2364,6 @@ int CLI::run(int argc, char **argv) } else { //only arrange current plate - //cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(plate_to_slice-1); - PrintSequence curr_plate_seq = cur_plate->get_print_seq(); - if (curr_plate_seq == PrintSequence::ByDefault) { - auto seq_print = m_print_config.option>("print_sequence"); - if (seq_print && (seq_print->value == PrintSequence::ByObject)) { - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from global")%plate_to_slice; - arrange_cfg.is_seq_print = true; - } - } - else if (curr_plate_seq == PrintSequence::ByObject) { - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% print by object, set from plate self")%plate_to_slice; - arrange_cfg.is_seq_print = true; - } - partplate_list.lock_plate(plate_to_slice - 1, false); partplate_list.select_plate(plate_to_slice-1); BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% set to selected")%plate_to_slice; @@ -2346,7 +2397,7 @@ int CLI::run(int argc, char **argv) } } } - if (selected.size() == (duplicate_count + 1)) + if ((duplicate_count > 0)&&(selected.size() == (duplicate_count + 1))) { duplicate_single_object = true; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": found single object mode"); @@ -2416,11 +2467,14 @@ int CLI::run(int argc, char **argv) arrange_cfg.allow_rotations = true; arrange_cfg.allow_multi_materials_on_same_plate = true; arrange_cfg.avoid_extrusion_cali_region = false; - arrange_cfg.min_obj_distance = scaled(22.0); arrange_cfg.clearance_height_to_rod = height_to_rod; arrange_cfg.clearance_height_to_lid = height_to_lid; arrange_cfg.cleareance_radius = cleareance_radius; arrange_cfg.printable_height = print_height; + if (arrange_cfg.is_seq_print) + arrange_cfg.min_obj_distance = std::max(arrange_cfg.min_obj_distance, scaled(arrange_cfg.cleareance_radius + 0.001)); // +0.001mm to avoid clearance check fail due to rounding error + else + arrange_cfg.min_obj_distance = scaled(22.0); arrangement::update_arrange_params(arrange_cfg, m_print_config, selected); arrangement::update_selected_items_inflation(selected, &m_print_config, arrange_cfg); @@ -2451,16 +2505,35 @@ int CLI::run(int argc, char **argv) int bed_idx_max = 0; if (duplicate_count == 0) { - //clear all the relations before apply the arrangement results - partplate_list.clear(); + if (plate_to_slice > 0) + { + //only for partplate case + partplate_list.clear(false, false, true, plate_to_slice-1); - // Apply the arrange result to all selected objects - for (ArrangePolygon &ap : selected) { - //BBS: partplate postprocess - partplate_list.postprocess_bed_index_for_selected(ap); + for (ArrangePolygon& ap : selected) { + partplate_list.postprocess_bed_index_for_current_plate(ap); + if (ap.bed_idx != (plate_to_slice-1)) + { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":arrange failed: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); + record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); + } + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + } + } + else + { + //clear all the relations before apply the arrangement results + partplate_list.clear(); - bed_idx_max = std::max(ap.bed_idx, bed_idx_max); - BOOST_LOG_TRIVIAL(trace)<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) << "\n"; + // Apply the arrange result to all selected objects + for (ArrangePolygon &ap : selected) { + //BBS: partplate postprocess + partplate_list.postprocess_bed_index_for_selected(ap); + + bed_idx_max = std::max(ap.bed_idx, bed_idx_max); + BOOST_LOG_TRIVIAL(trace)<< "after arrange: name=" << ap.name << boost::format(",bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) << "\n"; + } } for (ArrangePolygon &ap : locked_aps) { bed_idx_max = std::max(ap.bed_idx, bed_idx_max); @@ -2478,16 +2551,34 @@ int CLI::run(int argc, char **argv) ap.apply(); } - // Move the unprintable items to the last virtual bed. - for (ArrangePolygon &ap : unprintable) { - ap.bed_idx += bed_idx_max + 1; - partplate_list.postprocess_arrange_polygon(ap, true); + // Apply the arrange result to unselected objects(due to the sukodu-style column changes, the position of unselected may also be modified) + for (ArrangePolygon& ap : unselected) + { + if (ap.is_virt_object) + continue; + + //BBS: partplate postprocess + partplate_list.postprocess_arrange_polygon(ap, false); ap.apply(); } + // Move the unprintable items to the last virtual bed. + // Note ap.apply() moves relatively according to bed_idx, so we need to subtract the orignal bed_idx + for (ArrangePolygon& ap : unprintable) + { + ap.bed_idx = bed_idx_max + 1; + partplate_list.postprocess_arrange_polygon(ap, true); + + ap.apply(); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":arrange m_unprintable: name: %4%, bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale(ap.translation(X)) % unscale(ap.translation(Y)) % ap.name; + } + //BBS: reload all objects due to arrange - partplate_list.rebuild_plates_after_arrangement(); + if (plate_to_slice > 0) + partplate_list.rebuild_plates_after_arrangement(false, true, plate_to_slice-1); + else + partplate_list.rebuild_plates_after_arrangement(); } else { //only for partplate case From d5b9dcfbbeb0cbf762e0d8484e537cdef575160d Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 25 Aug 2023 15:28:44 +0800 Subject: [PATCH 018/240] FIX: CLI: fix the brim related issues 1. move the global functions to Model 2. set brim automation paremeters before process JIRA: STUDIO-4208 Change-Id: I3f75175ec74d214ca2a6d5f3ade56d08e0ecd4f3 (cherry picked from commit bcc88bc01ec396e8fb8af1186b47a75cd5116f3c) --- src/BambuStudio.cpp | 16 ++- src/libslic3r/Model.cpp | 91 ++++++++++++++++- src/libslic3r/Model.hpp | 3 + src/slic3r/GUI/Jobs/ArrangeJob.cpp | 13 ++- src/slic3r/GUI/Plater.cpp | 156 ++++++++--------------------- src/slic3r/GUI/Plater.hpp | 6 +- 6 files changed, 159 insertions(+), 126 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 07334c9a3..fe555ad94 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2875,12 +2875,14 @@ int CLI::run(int argc, char **argv) // is supplied); if any object has no instances, it will get a default one // and all instances will be rearranged (unless --dont-arrange is supplied). std::string outfile; - Print fff_print; + //Print fff_print; while(!finished) { //BBS: slice every partplate one by one PrintBase *print=NULL; + Print *print_fff = NULL; + Slic3r::GUI::GCodeResult *gcode_result = NULL; int print_index; for (int index = 0; index < partplate_list.get_plate_count(); index ++) @@ -2895,6 +2897,8 @@ int CLI::run(int argc, char **argv) //get the current partplate Slic3r::GUI::PartPlate* part_plate = partplate_list.get_plate(index); part_plate->get_print(&print, &gcode_result, &print_index); + + print_fff = dynamic_cast(print); /*if (outfile_config.empty()) { outfile = "plate_" + std::to_string(index + 1) + ".gcode"; @@ -3074,6 +3078,11 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("new_printer_name: %1%, current_printer_system_name %2%, is_bbl_vendor_preset %3%")%new_printer_name %current_printer_system_name %is_bbl_vendor_preset; } (dynamic_cast(print))->set_BBL_Printer(is_bbl_vendor_preset); + + //update information for brim + const PrintConfig& print_config = print_fff->config(); + Model::setExtruderParams(m_print_config, filament_count); + Model::setPrintSpeedTable(m_print_config, print_config); if (load_slicedata) { std::string plate_dir = load_slice_data_dir+"/"+std::to_string(index+1); int ret = print->load_cached_data(plate_dir); @@ -3098,12 +3107,13 @@ int CLI::run(int argc, char **argv) print->process(); } if (printer_technology == ptFFF) { - std::string conflict_result = dynamic_cast(print)->get_conflict_string(); + std::string conflict_result = print_fff->get_conflict_string(); if (!conflict_result.empty()) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": found slicing result conflict!"<< std::endl; record_exit_reson(outfile_dir, CLI_GCODE_PATH_CONFLICTS, index+1, cli_errors[CLI_GCODE_PATH_CONFLICTS]); flush_and_exit(CLI_GCODE_PATH_CONFLICTS); } + // The outfile is processed by a PlaceholderParser. //outfile = part_plate->get_tmp_gcode_path(); if (outfile_dir.empty()) { @@ -3114,7 +3124,7 @@ int CLI::run(int argc, char **argv) part_plate->set_tmp_gcode_path(outfile); } BOOST_LOG_TRIVIAL(info) << "process finished, will export gcode temporily to " << outfile << std::endl; - outfile = (dynamic_cast(print))->export_gcode(outfile, gcode_result, nullptr); + outfile = print_fff->export_gcode(outfile, gcode_result, nullptr); //outfile_final = (dynamic_cast(print))->print_statistics().finalize_output_path(outfile); //m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, [this](const ThumbnailsParams& params) { return this->render_thumbnails(params); }); }/* else { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index d123e0f34..e927a9d5d 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -2100,7 +2100,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, std::array plane_poi // Displacement (in instance coordinates) to be applied to place the upper parts Vec3d local_displace = Vec3d::Zero(); Vec3d local_dowels_displace = Vec3d::Zero(); - + for (ModelVolume *volume : volumes) { const auto volume_matrix = volume->get_matrix(); @@ -2125,7 +2125,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, std::array plane_poi } ModelObjectPtrs res; - + if (attributes.has(ModelObjectCutAttribute::CutToParts) && !upper->volumes.empty()) { reset_instance_transformation(upper, instance, cut_matrix); res.push_back(upper); @@ -2359,7 +2359,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects) { Vec3d shift = model_instance->get_transformation().get_matrix(true) * new_vol->get_offset(); model_instance->set_offset(model_instance->get_offset() + shift); - + //BBS: add assemble_view related logic Geometry::Transformation instance_transformation_copy = model_instance->get_transformation(); instance_transformation_copy.set_offset(-new_vol->get_offset()); @@ -3238,6 +3238,91 @@ void ModelInstance::transform_polygon(Polygon* polygon) const } //BBS +// BBS set print speed table and find maximum speed +void Model::setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConfig& print_config) { + //Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config(); + printSpeedMap.maxSpeed = 0; + if (config.has("inner_wall_speed")) { + printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed"); + if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed) + printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed; + } + if (config.has("outer_wall_speed")) { + printSpeedMap.externalPerimeterSpeed = config.opt_float("outer_wall_speed"); + printSpeedMap.maxSpeed = std::max(printSpeedMap.maxSpeed, printSpeedMap.externalPerimeterSpeed); + } + if (config.has("sparse_infill_speed")) { + printSpeedMap.infillSpeed = config.opt_float("sparse_infill_speed"); + if (printSpeedMap.infillSpeed > printSpeedMap.maxSpeed) + printSpeedMap.maxSpeed = printSpeedMap.infillSpeed; + } + if (config.has("internal_solid_infill_speed")) { + printSpeedMap.solidInfillSpeed = config.opt_float("internal_solid_infill_speed"); + if (printSpeedMap.solidInfillSpeed > printSpeedMap.maxSpeed) + printSpeedMap.maxSpeed = printSpeedMap.solidInfillSpeed; + } + if (config.has("top_surface_speed")) { + printSpeedMap.topSolidInfillSpeed = config.opt_float("top_surface_speed"); + if (printSpeedMap.topSolidInfillSpeed > printSpeedMap.maxSpeed) + printSpeedMap.maxSpeed = printSpeedMap.topSolidInfillSpeed; + } + if (config.has("support_speed")) { + printSpeedMap.supportSpeed = config.opt_float("support_speed"); + + if (printSpeedMap.supportSpeed > printSpeedMap.maxSpeed) + printSpeedMap.maxSpeed = printSpeedMap.supportSpeed; + } + + + //auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print(); + //auto print_config = print.config(); + //printSpeedMap.bed_poly.points = get_bed_shape(*(wxGetApp().plater()->config())); + printSpeedMap.bed_poly.points = get_bed_shape(config); + Pointfs excluse_area_points = print_config.bed_exclude_area.values; + Polygons exclude_polys; + Polygon exclude_poly; + for (int i = 0; i < excluse_area_points.size(); i++) { + auto pt = excluse_area_points[i]; + exclude_poly.points.emplace_back(scale_(pt.x()), scale_(pt.y())); + if (i % 4 == 3) { // exclude areas are always rectangle + exclude_polys.push_back(exclude_poly); + exclude_poly.points.clear(); + } + } + printSpeedMap.bed_poly = diff({ printSpeedMap.bed_poly }, exclude_polys)[0]; +} + +// find temperature of heatend and bed and matierial of an given extruder +void Model::setExtruderParams(const DynamicPrintConfig& config, int extruders_count) { + extruderParamsMap.clear(); + //Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config(); + // BBS + //int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + for (unsigned int i = 0; i != extruders_count; ++i) { + std::string matName = ""; + // BBS + int bedTemp = 35; + double endTemp = 0.f; + if (config.has("filament_type")) { + matName = config.opt_string("filament_type", i); + } + if (config.has("nozzle_temperature")) { + endTemp = config.opt_int("nozzle_temperature", i); + } + + // FIXME: curr_bed_type is now a plate config rather than a global config. + // Currently bed temp is not used for brim generation, so just comment it for now. +#if 0 + if (config.has("curr_bed_type")) { + BedType curr_bed_type = config.opt_enum("curr_bed_type"); + bedTemp = config.opt_int(get_bed_temp_key(curr_bed_type), i); + } +#endif + if (i == 0) extruderParamsMap.insert({ i,{matName, bedTemp, endTemp} }); + extruderParamsMap.insert({ i + 1,{matName, bedTemp, endTemp} }); + } +} + // update the maxSpeed of an object if it is different from the global configuration double Model::findMaxSpeed(const ModelObject* object) { auto objectKeys = object->config.keys(); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index ceb88148a..2353804d9 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1545,6 +1545,9 @@ public: static double getThermalLength(const ModelVolume* modelVolumePtr); static double getThermalLength(const std::vector modelVolumePtrs); static Polygon getBedPolygon() { return Model::printSpeedMap.bed_poly; } + //BBS static functions that update extruder params and speed table + static void setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConfig& print_config); + static void setExtruderParams(const DynamicPrintConfig& config, int extruders_count); // BBS: backup static Model read_from_archive( diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 320e8dc03..13c74c0bc 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -270,7 +270,7 @@ void ArrangeJob::prepare_wipe_tower() break; } } - + // if multile extruders have same bed temp, we need wipe tower // 允许不同材料落在相同盘,且所有选定对象中使用了多种热床温度相同的材料 if (params.allow_multi_materials_on_same_plate) { @@ -395,8 +395,13 @@ void ArrangeJob::prepare() params = init_arrange_params(m_plater); //BBS update extruder params and speed table before arranging - Plater::setExtruderParams(Model::extruderParamsMap); - Plater::setPrintSpeedTable(Model::printSpeedMap); + const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); + auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + + Model::setExtruderParams(config, numExtruders); + Model::setPrintSpeedTable(config, print_config); int state = m_plater->get_prepare_state(); if (state == Job::JobPrepareState::PREPARE_STATE_DEFAULT) { @@ -500,7 +505,7 @@ void ArrangeJob::process() const Slic3r::DynamicPrintConfig& global_config = wxGetApp().preset_bundle->full_config(); if (params.avoid_extrusion_cali_region && global_config.opt_bool("scan_first_layer")) partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); - + update_arrange_params(params, *m_plater, m_selected); update_selected_items_inflation(m_selected, m_plater->config(), params); update_unselected_items_inflation(m_unselected, m_plater->config(), params); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a638f4b05..f17de8a71 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -170,7 +170,7 @@ wxDEFINE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent); wxDEFINE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent); //BBS: change light/dark mode wxDEFINE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent); -//BBS: print +//BBS: print wxDEFINE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent); @@ -1065,7 +1065,7 @@ void Sidebar::update_all_preset_comboboxes() ; } - if(!url.empty()) + if(!url.empty()) { if(!url.Lower().starts_with("http")) url = wxString::Format("http://%s",url); @@ -1449,7 +1449,7 @@ std::map Sidebar::build_filament_ams_list(MachineObject void Sidebar::load_ams_list(std::string const &device, MachineObject* obj) { std::map filament_ams_list = build_filament_ams_list(obj); - + if (!obj) { p->ams_list_device = device; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " clear list"; @@ -2807,89 +2807,6 @@ void Plater::priv::select_view(const std::string& direction) assemble_view->select_view(direction); } } -// BBS set print speed table and find maximum speed -void Plater::setPrintSpeedTable(GlobalSpeedMap &printSpeedMap) { - Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config(); - printSpeedMap.maxSpeed = 0; - if (config.has("inner_wall_speed")) { - printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed"); - if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed) - printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed; - } - if (config.has("outer_wall_speed")) { - printSpeedMap.externalPerimeterSpeed = config.opt_float("outer_wall_speed"); - printSpeedMap.maxSpeed = std::max(printSpeedMap.maxSpeed, printSpeedMap.externalPerimeterSpeed); - } - if (config.has("sparse_infill_speed")) { - printSpeedMap.infillSpeed = config.opt_float("sparse_infill_speed"); - if (printSpeedMap.infillSpeed > printSpeedMap.maxSpeed) - printSpeedMap.maxSpeed = printSpeedMap.infillSpeed; - } - if (config.has("internal_solid_infill_speed")) { - printSpeedMap.solidInfillSpeed = config.opt_float("internal_solid_infill_speed"); - if (printSpeedMap.solidInfillSpeed > printSpeedMap.maxSpeed) - printSpeedMap.maxSpeed = printSpeedMap.solidInfillSpeed; - } - if (config.has("top_surface_speed")) { - printSpeedMap.topSolidInfillSpeed = config.opt_float("top_surface_speed"); - if (printSpeedMap.topSolidInfillSpeed > printSpeedMap.maxSpeed) - printSpeedMap.maxSpeed = printSpeedMap.topSolidInfillSpeed; - } - if (config.has("support_speed")) { - printSpeedMap.supportSpeed = config.opt_float("support_speed"); - - if (printSpeedMap.supportSpeed > printSpeedMap.maxSpeed) - printSpeedMap.maxSpeed = printSpeedMap.supportSpeed; - } - - - auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print(); - auto print_config = print.config(); - printSpeedMap.bed_poly.points = get_bed_shape(*(wxGetApp().plater()->config())); - Pointfs excluse_area_points = print_config.bed_exclude_area.values; - Polygons exclude_polys; - Polygon exclude_poly; - for (int i = 0; i < excluse_area_points.size(); i++) { - auto pt = excluse_area_points[i]; - exclude_poly.points.emplace_back(scale_(pt.x()), scale_(pt.y())); - if (i % 4 == 3) { // exclude areas are always rectangle - exclude_polys.push_back(exclude_poly); - exclude_poly.points.clear(); - } - } - printSpeedMap.bed_poly = diff({ printSpeedMap.bed_poly }, exclude_polys)[0]; -} - -// find temperature of heatend and bed and matierial of an given extruder -void Plater::setExtruderParams(std::map& extParas) { - extParas.clear(); - Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config(); - // BBS - int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); - for (unsigned int i = 0; i != numExtruders; ++i) { - std::string matName = ""; - // BBS - int bedTemp = 35; - double endTemp = 0.f; - if (config.has("filament_type")) { - matName = config.opt_string("filament_type", i); - } - if (config.has("nozzle_temperature")) { - endTemp = config.opt_int("nozzle_temperature", i); - } - - // FIXME: curr_bed_type is now a plate config rather than a global config. - // Currently bed temp is not used for brim generation, so just comment it for now. -#if 0 - if (config.has("curr_bed_type")) { - BedType curr_bed_type = config.opt_enum("curr_bed_type"); - bedTemp = config.opt_int(get_bed_temp_key(curr_bed_type), i); - } -#endif - if (i == 0) extParas.insert({ i,{matName, bedTemp, endTemp} }); - extParas.insert({ i + 1,{matName, bedTemp, endTemp} }); - } -} wxColour Plater::get_next_color_for_filament() { @@ -2955,8 +2872,13 @@ void Plater::priv::select_view_3D(const std::string& name, bool no_slice) else if (name == "Preview") { BOOST_LOG_TRIVIAL(info) << "select preview"; //BBS update extruder params and speed table before slicing - Plater::setExtruderParams(Slic3r::Model::extruderParamsMap); - Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap); + const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); + auto& print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + + Model::setExtruderParams(config, numExtruders); + Model::setPrintSpeedTable(config, print_config); set_current_panel(preview, no_slice); } else if (name == "Assemble") { @@ -4794,7 +4716,7 @@ unsigned int Plater::priv::update_restart_background_process(bool force_update_s } void Plater::priv::update_fff_scene() -{ +{ if (this->preview != nullptr) this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: @@ -6031,8 +5953,8 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) } } else { std::vector ptrs; - for (auto oid : message.second) - { + for (auto oid : message.second) + { const PrintObject *print_object = this->background_process.m_fff_print->get_object(ObjectID(oid)); if (print_object) { ptrs.push_back(print_object->model_object()); } } @@ -6244,8 +6166,13 @@ void Plater::priv::on_action_slice_plate(SimpleEvent&) if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice plate event\n" ; //BBS update extruder params and speed table before slicing - Plater::setExtruderParams(Slic3r::Model::extruderParamsMap); - Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap); + const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); + auto& print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + + Model::setExtruderParams(config, numExtruders); + Model::setPrintSpeedTable(config, print_config); m_slice_all = false; q->reslice(); q->select_view_3D("Preview"); @@ -6258,8 +6185,13 @@ void Plater::priv::on_action_slice_all(SimpleEvent&) if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice project event\n" ; //BBS update extruder params and speed table before slicing - Plater::setExtruderParams(Slic3r::Model::extruderParamsMap); - Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap); + const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); + auto& print = q->get_partplate_list().get_current_fff_print(); + auto print_config = print.config(); + int numExtruders = wxGetApp().preset_bundle->filament_presets.size(); + + Model::setExtruderParams(config, numExtruders); + Model::setPrintSpeedTable(config, print_config); m_slice_all = true; m_slice_all_only_has_gcode = true; m_cur_slice_plate = 0; @@ -6735,7 +6667,7 @@ wxString Plater::priv::get_project_filename(const wxString& extension) const } } -wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool only_filename, bool export_all) +wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool only_filename, bool export_all) { wxString curr_project_name = m_project_name; @@ -7634,10 +7566,10 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo // triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size. this->undo_redo_stack().release_least_recently_used(); //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) - get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) : this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); - get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? + get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) : this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); @@ -10926,24 +10858,24 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn) try { json j; switch (dlg.post_action()) { - case PrintHostPostUploadAction::None: - j["post_action"] = "Upload"; + case PrintHostPostUploadAction::None: + j["post_action"] = "Upload"; break; - case PrintHostPostUploadAction::StartPrint: - j["post_action"] = "StartPrint"; + case PrintHostPostUploadAction::StartPrint: + j["post_action"] = "StartPrint"; break; - case PrintHostPostUploadAction::StartSimulation: - j["post_action"] = "StartSimulation"; + case PrintHostPostUploadAction::StartSimulation: + j["post_action"] = "StartSimulation"; break; } PresetBundle *preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - j["gcode_printer_model"] = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle); + if (preset_bundle) { + j["gcode_printer_model"] = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle); } - if (physical_printer_config) { - j["printer_preset"] = physical_printer_config->opt_string("inherits"); + if (physical_printer_config) { + j["printer_preset"] = physical_printer_config->opt_string("inherits"); } NetworkAgent *agent = wxGetApp().getAgent(); @@ -11038,7 +10970,7 @@ void Plater::print_job_finished(wxCommandEvent &evt) p->enter_prepare_mode(); } - + Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); if (!dev) return; @@ -11173,7 +11105,7 @@ void Plater::on_filaments_change(size_t num_filaments) for (int i = 0; i < plate_list.get_plate_count(); ++i) { PartPlate* part_plate = plate_list.get_plate(i); part_plate->update_first_layer_print_sequence(num_filaments); - } + } for (ModelObject* mo : wxGetApp().model().objects) { for (ModelVolume* mv : mo->volumes) { @@ -11433,7 +11365,7 @@ void Plater::update_print_error_info(int code, std::string msg, std::string extr if (p->main_frame->m_calibration) p->main_frame->m_calibration->update_print_error_info(code, msg, extra); } - + wxString Plater::get_project_filename(const wxString& extension) const { return p->get_project_filename(extension); @@ -12248,7 +12180,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi if (!ret) { PlateNameEditDialog dlg(this, wxID_ANY, _L("Edit Plate Name")); PartPlate * curr_plate = p->partplate_list.get_curr_plate(); - + wxString curr_plate_name = from_u8(curr_plate->get_plate_name()); dlg.set_plate_name(curr_plate_name); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 878cfc890..97038a189 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -255,9 +255,7 @@ public: void update_all_plate_thumbnails(bool force_update = false); void invalid_all_plate_thumbnails(); void force_update_all_plate_thumbnails(); - //BBS static functions that update extruder params and speed table - static void setPrintSpeedTable(Slic3r::GlobalSpeedMap& printSpeedMap); - static void setExtruderParams(std::map& extParas); + static wxColour get_next_color_for_filament(); static wxString get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning); @@ -288,7 +286,7 @@ public: bool is_view3D_overhang_shown() const; void show_view3D_overhang(bool show); - + bool is_sidebar_collapsed() const; void collapse_sidebar(bool show); From a1e4975c8152e85c08a182c3d836b53f0af95f38 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Mon, 28 Aug 2023 11:20:07 +0800 Subject: [PATCH 019/240] FIX: CLI: fix the wipetower wrongly generated issue JIRA: MAK-xxx Change-Id: I6d6af58c7106df4dacb51e98dd607ff77c058c13 (cherry picked from commit 080c6ced15bf9eb6e490fbd3616667d66ecbff86) --- src/BambuStudio.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index fe555ad94..bcecf2da4 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2891,6 +2891,7 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "Skip plate " << index+1 << std::endl; continue; } + model.curr_plate_index = index; BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: pre_check %2%, start")%(index+1)%pre_check; long long start_time = 0, end_time = 0; start_time = (long long)Slic3r::Utils::get_current_time_utc(); From 24cb84e78f87fe2d8cf4705d21dd9b549331f1dc Mon Sep 17 00:00:00 2001 From: Stone Li Date: Wed, 23 Aug 2023 15:51:44 +0800 Subject: [PATCH 020/240] FIX: fix translation bug in third-party connection guide JIRA: STUDIO-4161 Change-Id: I689aa495fec87bd1a40ca74be03799acd4f2fc5e Signed-off-by: Stone Li --- resources/web/device/missing_connection.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/web/device/missing_connection.html b/resources/web/device/missing_connection.html index a66ea4561..64f14dfea 100644 --- a/resources/web/device/missing_connection.html +++ b/resources/web/device/missing_connection.html @@ -14,8 +14,8 @@
-

Printer Connection

-

Please set up your printer connection to view the device.

+

Printer Connection

+

Please set up your printer connection to view the device.

Printer connection setup demonstration
From f5f650eac4254d3f1afb9f7dfae4db413ffd77d8 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Wed, 23 Aug 2023 15:32:11 +0800 Subject: [PATCH 021/240] ENH: get thumbnail from task info JIRA: STUDIO-3975 Change-Id: Ic9ae120673098a4b62c4a00b515558fbef630890 Signed-off-by: Stone Li --- src/slic3r/GUI/DeviceManager.cpp | 32 +++++++++++++++++++++++++++++-- src/slic3r/Utils/NetworkAgent.cpp | 16 +++++++++++++++- src/slic3r/Utils/NetworkAgent.hpp | 3 +++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index c0a3fb500..980d9d083 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -4319,7 +4319,35 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil } else { if (subtask_id.compare("0") == 0) return; - m_agent->get_task_plate_index(subtask_id, &plate_index); + + std::string subtask_json; + unsigned http_code = 0; + std::string http_body; + if (m_agent->get_subtask_info(subtask_id, &subtask_json, &http_code, &http_body) == 0) { + try { + json task_j = json::parse(subtask_json); + if (task_j.contains("content")) { + std::string content_str = task_j["content"].get(); + json content_j = json::parse(content_str); + plate_index = content_j["info"]["plate_idx"].get(); + } + + if (task_j.contains("context") && task_j["context"].contains("plates")) { + for (int i = 0; i < task_j["context"]["plates"].size(); i++) { + if (task_j["context"]["plates"][i].contains("index") && task_j["context"]["plates"][i]["index"].get() == plate_index) { + slice_info->thumbnail_url = task_j["context"]["plates"][i]["thumbnail"]["url"].get(); + BOOST_LOG_TRIVIAL(trace) << "task_info: thumbnail url=" << slice_info->thumbnail_url; + } + } + } else { + BOOST_LOG_TRIVIAL(error) << "task_info: no context or plates"; + } + } + catch(...) { + } + } else { + BOOST_LOG_TRIVIAL(error) << "task_info: get subtask id failed!"; + } } if (plate_index >= 0) { @@ -4334,7 +4362,7 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil if (!j["weight"].is_null()) slice_info->weight = j["weight"].get(); if (!j["thumbnail"].is_null()) { - slice_info->thumbnail_url = j["thumbnail"]["url"].get(); + //slice_info->thumbnail_url = j["thumbnail"]["url"].get(); BOOST_LOG_TRIVIAL(trace) << "slice_info: thumbnail url=" << slice_info->thumbnail_url; } if (!j["filaments"].is_null()) { diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index d55d5d5d1..808dcec0d 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -89,6 +89,7 @@ func_get_printer_firmware NetworkAgent::get_printer_firmware_ptr = nul func_get_task_plate_index NetworkAgent::get_task_plate_index_ptr = nullptr; func_get_user_info NetworkAgent::get_user_info_ptr = nullptr; func_request_bind_ticket NetworkAgent::request_bind_ticket_ptr = nullptr; +func_get_subtask_info NetworkAgent::get_subtask_info_ptr = nullptr; func_get_slice_info NetworkAgent::get_slice_info_ptr = nullptr; func_query_bind_status NetworkAgent::query_bind_status_ptr = nullptr; func_modify_printer_name NetworkAgent::modify_printer_name_ptr = nullptr; @@ -241,6 +242,7 @@ int NetworkAgent::initialize_network_module(bool using_backup) get_task_plate_index_ptr = reinterpret_cast(get_network_function("bambu_network_get_task_plate_index")); get_user_info_ptr = reinterpret_cast(get_network_function("bambu_network_get_user_info")); request_bind_ticket_ptr = reinterpret_cast(get_network_function("bambu_network_request_bind_ticket")); + get_subtask_info_ptr = reinterpret_cast(get_network_function("bambu_network_get_subtask_info")); get_slice_info_ptr = reinterpret_cast(get_network_function("bambu_network_get_slice_info")); query_bind_status_ptr = reinterpret_cast(get_network_function("bambu_network_query_bind_status")); modify_printer_name_ptr = reinterpret_cast(get_network_function("bambu_network_modify_printer_name")); @@ -346,11 +348,12 @@ int NetworkAgent::unload_network_module() get_printer_firmware_ptr = nullptr; get_task_plate_index_ptr = nullptr; get_user_info_ptr = nullptr; + get_subtask_info_ptr = nullptr; get_slice_info_ptr = nullptr; query_bind_status_ptr = nullptr; modify_printer_name_ptr = nullptr; get_camera_url_ptr = nullptr; - get_design_staffpick_ptr = nullptr; + get_design_staffpick_ptr = nullptr; start_publish_ptr = nullptr; get_profile_3mf_ptr = nullptr; get_model_publish_url_ptr = nullptr; @@ -1070,6 +1073,17 @@ int NetworkAgent::request_bind_ticket(std::string* ticket) return ret; } +int NetworkAgent::get_subtask_info(std::string subtask_id, std::string* task_json, unsigned int* http_code, std::string* http_body) +{ + int ret = 0; + if (network_agent && get_subtask_info_ptr) { + ret = get_subtask_info_ptr(network_agent, subtask_id, task_json, http_code, http_body); + if (ret) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format("error: network_agent=%1%, ret=%2%") % network_agent % ret; + } + return ret; +} + int NetworkAgent::get_slice_info(std::string project_id, std::string profile_id, int plate_index, std::string* slice_json) { int ret; diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp index 2536ada99..1c600754d 100644 --- a/src/slic3r/Utils/NetworkAgent.hpp +++ b/src/slic3r/Utils/NetworkAgent.hpp @@ -69,6 +69,7 @@ typedef int (*func_get_printer_firmware)(void *agent, std::string dev_id, unsign typedef int (*func_get_task_plate_index)(void *agent, std::string task_id, int* plate_index); typedef int (*func_get_user_info)(void *agent, int* identifier); typedef int (*func_request_bind_ticket)(void *agent, std::string* ticket); +typedef int (*func_get_subtask_info)(void *agent, std::string subtask_id, std::string* task_json, unsigned int* http_code, std::string *http_body); typedef int (*func_get_slice_info)(void *agent, std::string project_id, std::string profile_id, int plate_index, std::string* slice_json); typedef int (*func_query_bind_status)(void *agent, std::vector query_list, unsigned int* http_code, std::string* http_body); typedef int (*func_modify_printer_name)(void *agent, std::string dev_id, std::string dev_name); @@ -163,6 +164,7 @@ public: int get_task_plate_index(std::string task_id, int* plate_index); int get_user_info(int* identifier); int request_bind_ticket(std::string* ticket); + int get_subtask_info(std::string subtask_id, std::string* task_json, unsigned int* http_code, std::string* http_body); int get_slice_info(std::string project_id, std::string profile_id, int plate_index, std::string* slice_json); int query_bind_status(std::vector query_list, unsigned int* http_code, std::string* http_body); int modify_printer_name(std::string dev_id, std::string dev_name); @@ -247,6 +249,7 @@ private: static func_get_task_plate_index get_task_plate_index_ptr; static func_get_user_info get_user_info_ptr; static func_request_bind_ticket request_bind_ticket_ptr; + static func_get_subtask_info get_subtask_info_ptr; static func_get_slice_info get_slice_info_ptr; static func_query_bind_status query_bind_status_ptr; static func_modify_printer_name modify_printer_name_ptr; From 5957912eaad0d698fd906e29e6f3e73e8f848a29 Mon Sep 17 00:00:00 2001 From: gerrit Date: Tue, 29 Aug 2023 10:45:41 +0800 Subject: [PATCH 022/240] ci: update network module based on commit 83a385c Change-Id: I1c5fd418646d8387dc6437157f9c609cf3019eb2 (cherry picked from commit 95442e564b2c1b238a56230322463e3213eb43d4) --- src/slic3r/Utils/bambu_networking.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/slic3r/Utils/bambu_networking.hpp b/src/slic3r/Utils/bambu_networking.hpp index 017cd713b..75795b500 100644 --- a/src/slic3r/Utils/bambu_networking.hpp +++ b/src/slic3r/Utils/bambu_networking.hpp @@ -68,6 +68,7 @@ namespace BBL { #define BAMBU_NETWORK_ERR_PRINT_SP_UPLOAD_3MF_TO_OSS_FAILED -3100 //failed to upload 3mf to oss #define BAMBU_NETWORK_ERR_PRINT_SP_PATCH_PROJECT_FAILED -3110 //failed to patch project #define BAMBU_NETWORK_ERR_PRINT_SP_POST_TASK_FAILED -3120 //failed to post task +#define BAMBU_NETWORK_ERR_PRINT_SP_WAIT_PRINTER_FAILED -3130 //failed to wait the ack from printer //start_local_print error #define BAMBU_NETWORK_ERR_PRINT_LP_FILE_OVER_SIZE -4010 //the size of the uploaded file cannot exceed 1 GB @@ -84,7 +85,7 @@ namespace BBL { #define BAMBU_NETWORK_LIBRARY "bambu_networking" #define BAMBU_NETWORK_AGENT_NAME "bambu_network_agent" -#define BAMBU_NETWORK_AGENT_VERSION "01.07.04.01" +#define BAMBU_NETWORK_AGENT_VERSION "01.07.06.01" //iot preset type strings #define IOT_PRINTER_TYPE_STRING "printer" @@ -114,6 +115,7 @@ typedef std::function GetCountryCodeFn; // print callbacks typedef std::function OnUpdateStatusFn; typedef std::function WasCancelledFn; +typedef std::function OnWaitFn; // local callbacks typedef std::function OnMsgArrivedFn; // queue call to main thread @@ -130,8 +132,9 @@ enum SendingPrintJobStage { PrintingStageWaiting = 2, PrintingStageSending = 3, PrintingStageRecord = 4, - PrintingStageFinished = 5, - PrintingStageERROR = 6, + PrintingStageWaitPrinter = 5, + PrintingStageFinished = 6, + PrintingStageERROR = 7, }; enum PublishingStage { From 6d5fad236e3f306ab9dfb129900ec44e5fb932f3 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Thu, 24 Aug 2023 22:05:19 +0800 Subject: [PATCH 023/240] ENH: refine the logic of extruder_clearance_radius 1. use extruder_clearance_max_radius instead 2. set the value of P1P/P1S to the same value of X1C JIRA: STUDIO-4214 Change-Id: I1ae5e4203db0933854b4388b5505dbf34b40edae (cherry picked from commit 19cb6a0fbad0192d39813e449baed090baa163c5) --- .../profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json | 3 +-- .../profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json | 1 - src/libslic3r/Print.cpp | 4 ++-- src/libslic3r/PrintConfig.cpp | 6 +++--- src/slic3r/GUI/Tab.cpp | 4 ++-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/resources/profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json index fd4c68463..2aabc6ccc 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab P1P 0.4 nozzle.json @@ -21,7 +21,6 @@ "Bambu PLA Basic @BBL X1" ], "default_print_profile": "0.20mm Standard @BBL P1P", - "extruder_clearance_max_radius": "56", "extruder_offset": [ "0x2" ], @@ -36,4 +35,4 @@ "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.4 nozzle" ] -} \ No newline at end of file +} diff --git a/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json index f7befe864..bbb73214f 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json @@ -17,7 +17,6 @@ "0x28" ], "default_print_profile": "0.20mm Standard @BBL X1C", - "extruder_clearance_max_radius": "56", "extruder_offset": [ "0x2" ], diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6761f5d9f..58efafed8 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -529,7 +529,7 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print auto tmp = offset(convex_hull_no_offset, // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. - float(scale_(0.5 * print.config().extruder_clearance_max_radius.value - EPSILON)), + float(scale_(0.5 * print.config().extruder_clearance_max_radius.value - 0.01)), jtRound, scale_(0.1)); if (!tmp.empty()) { // tmp may be empty due to clipper's bug, see STUDIO-2452 convex_hull = tmp.front(); @@ -736,7 +736,7 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print { auto inst = print_instance_with_bounding_box[k].print_instance; // 只需要考虑喷嘴到滑杆的偏移量,这个比整个工具头的碰撞半径要小得多 - auto bbox = print_instance_with_bounding_box[k].bounding_box.inflated(-scale_(0.5 * print.config().extruder_clearance_radius.value)); + auto bbox = print_instance_with_bounding_box[k].bounding_box.inflated(-scale_(0.5 * print.config().extruder_clearance_max_radius.value)); auto iy1 = bbox.min.y(); auto iy2 = bbox.max.y(); (const_cast(inst->model_instance))->arrange_order = k+1; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3f09cd54f..e8b94d4e8 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4321,7 +4321,7 @@ double min_object_distance(const ConfigBase &cfg) else { //BBS: duplicate_distance seam to be useless constexpr double duplicate_distance = 6.; - auto ecr_opt = cfg.option("extruder_clearance_radius"); + auto ecr_opt = cfg.option("extruder_clearance_max_radius"); auto co_opt = cfg.option>("print_sequence"); if (!ecr_opt || !co_opt) @@ -4744,8 +4744,8 @@ std::map validate(const FullPrintConfig &cfg, bool und } // extruder clearance - if (cfg.extruder_clearance_radius <= 0) { - error_message.emplace("extruder_clearance_radius", L("invalid value ") + std::to_string(cfg.extruder_clearance_radius)); + if (cfg.extruder_clearance_max_radius <= 0) { + error_message.emplace("extruder_clearance_max_radius", L("invalid value ") + std::to_string(cfg.extruder_clearance_max_radius)); } if (cfg.extruder_clearance_height_to_rod <= 0) { error_message.emplace("extruder_clearance_height_to_rod", L("invalid value ") + std::to_string(cfg.extruder_clearance_height_to_rod)); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index eba32f616..889bd5fab 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3074,7 +3074,7 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("machine_unload_filament_time"); optgroup = page->new_optgroup(L("Extruder Clearance")); - optgroup->append_single_option_line("extruder_clearance_radius"); + optgroup->append_single_option_line("extruder_clearance_max_radius"); optgroup->append_single_option_line("extruder_clearance_height_to_rod"); optgroup->append_single_option_line("extruder_clearance_height_to_lid"); @@ -3642,7 +3642,7 @@ void TabPrinter::toggle_options() // Disable silent mode for non-marlin firmwares. toggle_option("silent_mode", is_marlin_flavor); //BBS: extruder clearance of BBL printer can't be edited. - for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" }) + for (auto el : { "extruder_clearance_max_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" }) toggle_option(el, !is_BBL_printer); } From 321f1f38e0bf7a337c3fe4524918f4358d5fc80a Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Thu, 17 Aug 2023 15:55:36 +0800 Subject: [PATCH 024/240] ENH: add more 3rd party filaments Add Overture PLA, Matte PLA,PolyLite PETG,ABS,ASA jira: STUDIO-4044 Change-Id: I3e1954dae20b6695383d8abdf55eb4eeba3b5a08 --- resources/profiles/BBL.json | 110 +++++++++++++++++- ...verture Matte PLA @BBL P1P 0.2 nozzle.json | 14 +++ .../filament/Overture Matte PLA @BBL P1P.json | 34 ++++++ .../filament/Overture Matte PLA @BBL X1.json | 16 +++ ...verture Matte PLA @BBL X1C 0.2 nozzle.json | 16 +++ .../filament/Overture Matte PLA @BBL X1C.json | 16 +++ .../filament/Overture Matte PLA @base.json | 23 ++++ .../Overture PLA @BBL P1P 0.2 nozzle.json | 14 +++ .../BBL/filament/Overture PLA @BBL P1P.json | 22 ++++ .../BBL/filament/Overture PLA @BBL X1.json | 16 +++ .../Overture PLA @BBL X1C 0.2 nozzle.json | 16 +++ .../BBL/filament/Overture PLA @BBL X1C.json | 16 +++ .../BBL/filament/Overture PLA @base.json | 23 ++++ .../PolyLite ABS @BBL P1P 0.2 nozzle.json | 14 +++ .../BBL/filament/PolyLite ABS @BBL P1P.json | 31 +++++ .../PolyLite ABS @BBL X1C 0.2 nozzle.json | 16 +++ .../BBL/filament/PolyLite ABS @BBL X1C.json | 19 +++ .../BBL/filament/PolyLite ABS @base.json | 23 ++++ .../PolyLite ASA @BBL P1P 0.2 nozzle.json | 14 +++ .../BBL/filament/PolyLite ASA @BBL P1P.json | 25 ++++ .../PolyLite ASA @BBL X1C 0.2 nozzle.json | 16 +++ .../BBL/filament/PolyLite ASA @BBL X1C.json | 19 +++ .../BBL/filament/PolyLite ASA @base.json | 23 ++++ .../PolyLite PETG @BBL P1P 0.2 nozzle.json | 14 +++ .../BBL/filament/PolyLite PETG @BBL P1P.json | 31 +++++ .../PolyLite PETG @BBL X1C 0.2 nozzle.json | 16 +++ .../BBL/filament/PolyLite PETG @BBL X1C.json | 25 ++++ .../BBL/filament/PolyLite PETG @base.json | 56 +++++++++ 28 files changed, 677 insertions(+), 1 deletion(-) create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @BBL X1.json create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/Overture Matte PLA @base.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @BBL X1.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/Overture PLA @base.json create mode 100644 resources/profiles/BBL/filament/PolyLite ABS @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/PolyLite ABS @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite ABS @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/PolyLite ABS @base.json create mode 100644 resources/profiles/BBL/filament/PolyLite ASA @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite ASA @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/PolyLite ASA @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite ASA @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/PolyLite ASA @base.json create mode 100644 resources/profiles/BBL/filament/PolyLite PETG @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/PolyLite PETG @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/PolyLite PETG @base.json diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index d78ac1464..dec918000 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.07.00.12", + "version": "01.07.00.16", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ @@ -369,6 +369,14 @@ "name": "Bambu PLA Aero @base", "sub_path": "filament/Bambu PLA Aero @base.json" }, + { + "name": "Overture PLA @base", + "sub_path": "filament/Overture PLA @base.json" + }, + { + "name": "Overture Matte PLA @base", + "sub_path": "filament/Overture Matte PLA @base.json" + }, { "name": "Bambu TPU 95A @base", "sub_path": "filament/Bambu TPU 95A @base.json" @@ -401,6 +409,10 @@ "name": "Bambu PETG-CF @base", "sub_path": "filament/Bambu PETG-CF @base.json" }, + { + "name": "PolyLite PETG @base", + "sub_path": "filament/PolyLite PETG @base.json" + }, { "name": "Bambu ABS @base", "sub_path": "filament/Bambu ABS @base.json" @@ -409,6 +421,10 @@ "name": "Generic ABS @base", "sub_path": "filament/Generic ABS @base.json" }, + { + "name": "PolyLite ABS @base", + "sub_path": "filament/PolyLite ABS @base.json" + }, { "name": "Bambu PC @base", "sub_path": "filament/Bambu PC @base.json" @@ -425,6 +441,10 @@ "name": "Bambu ASA @base", "sub_path": "filament/Bambu ASA @base.json" }, + { + "name": "PolyLite ASA @base", + "sub_path": "filament/PolyLite ASA @base.json" + }, { "name": "Generic PVA @base", "sub_path": "filament/Generic PVA @base.json" @@ -737,6 +757,30 @@ "name": "Bambu PLA Aero @BBL P1P", "sub_path": "filament/P1P/Bambu PLA Aero @BBL P1P.json" }, + { + "name": "Overture PLA @BBL X1C", + "sub_path": "filament/Overture PLA @BBL X1C.json" + }, + { + "name": "Overture PLA @BBL X1", + "sub_path": "filament/Overture PLA @BBL X1.json" + }, + { + "name": "Overture PLA @BBL P1P", + "sub_path": "filament/Overture PLA @BBL P1P.json" + }, + { + "name": "Overture Matte PLA @BBL X1C", + "sub_path": "filament/Overture Matte PLA @BBL X1C.json" + }, + { + "name": "Overture Matte PLA @BBL X1", + "sub_path": "filament/Overture Matte PLA @BBL X1.json" + }, + { + "name": "Overture Matte PLA @BBL P1P", + "sub_path": "filament/Overture Matte PLA @BBL P1P.json" + }, { "name": "Bambu TPU 95A @BBL X1C", "sub_path": "filament/Bambu TPU 95A @BBL X1C.json" @@ -809,6 +853,14 @@ "name": "Bambu PETG-CF @BBL P1P 0.4 nozzle", "sub_path": "filament/P1P/Bambu PETG-CF @BBL P1P 0.4 nozzle.json" }, + { + "name": "PolyLite PETG @BBL X1C", + "sub_path": "filament/PolyLite PETG @BBL X1C.json" + }, + { + "name": "PolyLite PETG @BBL P1P", + "sub_path": "filament/PolyLite PETG @BBL P1P.json" + }, { "name": "Bambu ABS @BBL X1C", "sub_path": "filament/Bambu ABS @BBL X1C.json" @@ -845,6 +897,14 @@ "name": "Generic ABS @BBL P1P", "sub_path": "filament/P1P/Generic ABS @BBL P1P.json" }, + { + "name": "PolyLite ABS @BBL X1C", + "sub_path": "filament/PolyLite ABS @BBL X1C.json" + }, + { + "name": "PolyLite ABS @BBL P1P", + "sub_path": "filament/PolyLite ABS @BBL P1P.json" + }, { "name": "Bambu PC @BBL X1C", "sub_path": "filament/Bambu PC @BBL X1C.json" @@ -921,6 +981,14 @@ "name": "Bambu ASA @BBL X1C 0.4 nozzle", "sub_path": "filament/Bambu ASA @BBL X1C 0.4 nozzle.json" }, + { + "name": "PolyLite ASA @BBL X1C", + "sub_path": "filament/PolyLite ASA @BBL X1C.json" + }, + { + "name": "PolyLite ASA @BBL P1P", + "sub_path": "filament/PolyLite ASA @BBL P1P.json" + }, { "name": "Generic PVA @0.2 nozzle", "sub_path": "filament/Generic PVA @0.2 nozzle.json" @@ -993,6 +1061,38 @@ "name": "PolyLite PLA @BBL P1P 0.2 nozzle", "sub_path": "filament/P1P/PolyLite PLA @BBL P1P 0.2 nozzle.json" }, + { + "name": "Overture PLA @BBL X1C 0.2 nozzle", + "sub_path": "filament/Overture PLA @BBL X1C 0.2 nozzle.json" + }, + { + "name": "Overture PLA @BBL P1P 0.2 nozzle", + "sub_path": "filament/Overture PLA @BBL P1P 0.2 nozzle.json" + }, + { + "name": "Overture Matte PLA @BBL X1C 0.2 nozzle", + "sub_path": "filament/Overture Matte PLA @BBL X1C 0.2 nozzle.json" + }, + { + "name": "Overture Matte PLA @BBL P1P 0.2 nozzle", + "sub_path": "filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json" + }, + { + "name": "PolyLite PETG @BBL X1C 0.2 nozzle", + "sub_path": "filament/PolyLite PETG @BBL X1C 0.2 nozzle.json" + }, + { + "name": "PolyLite PETG @BBL P1P 0.2 nozzle", + "sub_path": "filament/PolyLite PETG @BBL P1P 0.2 nozzle.json" + }, + { + "name": "PolyLite ABS @BBL X1C 0.2 nozzle", + "sub_path": "filament/PolyLite ABS @BBL X1C 0.2 nozzle.json" + }, + { + "name": "PolyLite ABS @BBL P1P 0.2 nozzle", + "sub_path": "filament/PolyLite ABS @BBL P1P 0.2 nozzle.json" + }, { "name": "Bambu PC @BBL P1S", "sub_path": "filament/Bambu PC @BBL P1S.json" @@ -1016,6 +1116,14 @@ { "name": "Generic PC @BBL P1S", "sub_path": "filament/Generic PC @BBL P1S.json" + }, + { + "name": "PolyLite ASA @BBL X1C 0.2 nozzle", + "sub_path": "filament/PolyLite ASA @BBL X1C 0.2 nozzle.json" + }, + { + "name": "PolyLite ASA @BBL P1P 0.2 nozzle", + "sub_path": "filament/PolyLite ASA @BBL P1P 0.2 nozzle.json" } ], "machine_list": [ diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..8b51a32b0 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Overture Matte PLA @BBL P1P 0.2 nozzle", + "inherits": "Overture Matte PLA @BBL P1P", + "from": "system", + "setting_id": "GFSL05_04", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json new file mode 100644 index 000000000..634f7ef0a --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL P1P.json @@ -0,0 +1,34 @@ +{ + "type": "filament", + "name": "Overture Matte PLA @BBL P1P", + "inherits": "Overture Matte PLA @base", + "from": "system", + "setting_id": "GFSL05_03", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "slow_down_layer_time": [ + "10" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1.json new file mode 100644 index 000000000..4c1705b85 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL05_02", + "name": "Overture Matte PLA @BBL X1", + "from": "system", + "instantiation": "true", + "inherits": "Overture Matte PLA @base", + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.4 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..b0691683c --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL05_01", + "name": "Overture Matte PLA @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Overture Matte PLA @BBL X1C", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C.json b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C.json new file mode 100644 index 000000000..6b6c5386c --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @BBL X1C.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL05_00", + "name": "Overture Matte PLA @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "Overture Matte PLA @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture Matte PLA @base.json b/resources/profiles/BBL/filament/Overture Matte PLA @base.json new file mode 100644 index 000000000..e833c9ae3 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture Matte PLA @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "filament_id": "GFL05", + "name": "Overture Matte PLA @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pla", + "filament_cost": [ + "24.52" + ], + "filament_density": [ + "1.22" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_vendor": [ + "Overture" + ], + "slow_down_layer_time": [ + "6" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture PLA @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..f8de6aa19 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Overture PLA @BBL P1P 0.2 nozzle", + "inherits": "Overture PLA @BBL P1P", + "from": "system", + "setting_id": "GFSL04_04", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json b/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json new file mode 100644 index 000000000..d1d0e4af7 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @BBL P1P.json @@ -0,0 +1,22 @@ +{ + "type": "filament", + "name": "Overture PLA @BBL P1P", + "inherits": "Overture PLA @base", + "from": "system", + "setting_id": "GFSL04_03", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL X1.json b/resources/profiles/BBL/filament/Overture PLA @BBL X1.json new file mode 100644 index 000000000..5a786de0e --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @BBL X1.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL04_01", + "name": "Overture PLA @BBL X1", + "from": "system", + "instantiation": "true", + "inherits": "Overture PLA @base", + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Overture PLA @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..6068532d7 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL04_02", + "name": "Overture PLA @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Overture PLA @BBL X1C", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @BBL X1C.json b/resources/profiles/BBL/filament/Overture PLA @BBL X1C.json new file mode 100644 index 000000000..8ae45da9d --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @BBL X1C.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSL04_05", + "name": "Overture PLA @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "Overture PLA @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Overture PLA @base.json b/resources/profiles/BBL/filament/Overture PLA @base.json new file mode 100644 index 000000000..cf33af039 --- /dev/null +++ b/resources/profiles/BBL/filament/Overture PLA @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "filament_id": "GFL04", + "name": "Overture PLA @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pla", + "filament_cost": [ + "24.15" + ], + "filament_density": [ + "1.2" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_vendor": [ + "Overture" + ], + "slow_down_layer_time": [ + "6" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..e046dc124 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSB60_05", + "name": "PolyLite ABS @BBL P1P 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ABS @BBL P1P", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json new file mode 100644 index 000000000..e58c10107 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL P1P.json @@ -0,0 +1,31 @@ +{ + "type": "filament", + "setting_id": "GFSB60_04", + "name": "PolyLite ABS @BBL P1P", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ABS @base", + "fan_max_speed": [ + "20" + ], + "hot_plate_temp": [ + "100" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "textured_plate_temp": [ + "100" + ], + "textured_plate_temp_initial_layer": [ + "100" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.8 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.4 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..75e9e7d63 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSB60_02", + "name": "PolyLite ABS @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ABS @BBL X1C", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C.json new file mode 100644 index 000000000..19b036561 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ABS @BBL X1C.json @@ -0,0 +1,19 @@ +{ + "type": "filament", + "setting_id": "GFSB60_00", + "name": "PolyLite ABS @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ABS @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ABS @base.json b/resources/profiles/BBL/filament/PolyLite ABS @base.json new file mode 100644 index 000000000..fcbc279de --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ABS @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "filament_id": "GFB60", + "name": "PolyLite ABS @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_abs", + "filament_cost": [ + "26.9" + ], + "filament_density": [ + "1.03" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_vendor": [ + "Polymaker" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..a8b65e8e2 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSB61_05", + "name": "PolyLite ASA @BBL P1P 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ASA @BBL P1P", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P.json new file mode 100644 index 000000000..ee74fd0dc --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL P1P.json @@ -0,0 +1,25 @@ +{ + "type": "filament", + "setting_id": "GFSB61_04", + "name": "PolyLite ASA @BBL P1P", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ASA @base", + "hot_plate_temp": [ + "100" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "textured_plate_temp": [ + "100" + ], + "textured_plate_temp_initial_layer": [ + "100" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..dfd4ea99d --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSB61_01", + "name": "PolyLite ASA @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ASA @BBL X1C", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C.json new file mode 100644 index 000000000..0aef30b6a --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ASA @BBL X1C.json @@ -0,0 +1,19 @@ +{ + "type": "filament", + "setting_id": "GFSB61_00", + "name": "PolyLite ASA @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite ASA @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite ASA @base.json b/resources/profiles/BBL/filament/PolyLite ASA @base.json new file mode 100644 index 000000000..a01b2a5f2 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite ASA @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "filament_id": "GFB61", + "name": "PolyLite ASA @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_asa", + "filament_cost": [ + "23.6" + ], + "filament_density": [ + "1.02" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "13" + ], + "filament_vendor": [ + "Polymaker" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..b309d08c5 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSG60_03", + "name": "PolyLite PETG @BBL P1P 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite PETG @BBL P1P", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json new file mode 100644 index 000000000..2a39b32e9 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json @@ -0,0 +1,31 @@ +{ + "type": "filament", + "setting_id": "GFSG60_02", + "name": "PolyLite PETG @BBL P1P", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite PETG @base", + "filament_max_volumetric_speed": [ + "14" + ], + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "textured_plate_temp": [ + "80" + ], + "textured_plate_temp_initial_layer": [ + "80" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..b8e593992 --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "setting_id": "GFSG60_01", + "name": "PolyLite PETG @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite PETG @BBL X1C", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json new file mode 100644 index 000000000..43e409eeb --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json @@ -0,0 +1,25 @@ +{ + "type": "filament", + "setting_id": "GFSG60_00", + "name": "PolyLite PETG @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "PolyLite PETG @base", + "filament_max_volumetric_speed": [ + "14" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/PolyLite PETG @base.json b/resources/profiles/BBL/filament/PolyLite PETG @base.json new file mode 100644 index 000000000..22964406d --- /dev/null +++ b/resources/profiles/BBL/filament/PolyLite PETG @base.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "filament_id": "GFG60", + "name": "PolyLite PETG @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pet", + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_vendor": [ + "Polymaker" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "10%" + ], + "slow_down_min_speed": [ + "20" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ] +} \ No newline at end of file From 80b77a9c0124f9d3bed8c3731cbf716ff7a1ff50 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 29 Aug 2023 16:52:15 +0800 Subject: [PATCH 025/240] ENH: add filament PA6-CF As title. Also modify temperature_vitrification for PA-CF Signed-off-by: xun.zhang Change-Id: I8bc577267652be294ebe01f015b0502070c68dbe --- resources/profiles/BBL.json | 8 ++++ .../BBL/filament/Bambu PA-CF @base.json | 27 +++++++----- .../BBL/filament/Bambu PA6-CF @BBL X1C.json | 22 ++++++++++ .../BBL/filament/Bambu PA6-CF @base.json | 44 +++++++++++++++++++ .../profiles/BBL/filament/Generic PA-CF.json | 19 ++++---- 5 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 resources/profiles/BBL/filament/Bambu PA6-CF @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/Bambu PA6-CF @base.json diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index dec918000..bfa27b58f 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -481,6 +481,10 @@ "name": "Bambu Support For PA/PET @base", "sub_path": "filament/Bambu Support For PA PET @base.json" }, + { + "name": "Bambu PA6-CF @base", + "sub_path": "filament/Bambu PA6-CF @base.json" + }, { "name": "Generic HIPS @base", "sub_path": "filament/Generic HIPS @base.json" @@ -1037,6 +1041,10 @@ "name": "Bambu Support For PA/PET @BBL X1C", "sub_path": "filament/Bambu Support For PA PET @BBL X1C.json" }, + { + "name": "Bambu PA6-CF @BBL X1C", + "sub_path": "filament/Bambu PA6-CF @BBL X1C.json" + }, { "name": "Generic HIPS @BBL X1C", "sub_path": "filament/Generic HIPS @BBL X1C.json" diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @base.json b/resources/profiles/BBL/filament/Bambu PA-CF @base.json index 7d34ca507..98842dc10 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @base.json @@ -5,8 +5,8 @@ "from": "system", "instantiation": "false", "inherits": "fdm_filament_pa", - "filament_vendor": [ - "Bambu Lab" + "filament_cost": [ + "84.99" ], "filament_density": [ "1.09" @@ -14,22 +14,25 @@ "filament_flow_ratio": [ "0.96" ], - "nozzle_temperature_initial_layer": [ + "filament_type": [ + "PA-CF" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature": [ "280" ], - "overhang_fan_threshold": [ - "0%" + "nozzle_temperature_initial_layer": [ + "280" ], "overhang_fan_speed": [ "40" ], - "filament_type": [ - "PA-CF" + "overhang_fan_threshold": [ + "0%" ], - "filament_cost": [ - "84.99" - ], - "nozzle_temperature": [ - "280" + "temperature_vitrification": [ + "170" ] } \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X1C.json new file mode 100644 index 000000000..fd0b12425 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL X1C.json @@ -0,0 +1,22 @@ +{ + "type": "filament", + "setting_id": "GFSN05_02", + "name": "Bambu PA6-CF @BBL X1C", + "from": "system", + "instantiation": "true", + "inherits": "Bambu PA6-CF @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @base.json b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json new file mode 100644 index 000000000..8f3649efb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "filament_id": "GFN05", + "name": "Bambu PA6-CF @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pa", + "fan_cooling_layer_time": [ + "5" + ], + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "10" + ], + "filament_density": [ + "1.10" + ], + "filament_flow_ratio": [ + "0.96" + ], + "filament_type": [ + "PA-CF" + ], + "filament_vendor": [ + "Bambu" + ], + "nozzle_temperature": [ + "275" + ], + "nozzle_temperature_initial_layer": [ + "275" + ], + "overhang_fan_speed": [ + "40" + ], + "overhang_fan_threshold": [ + "0%" + ], + "temperature_vitrification": [ + "170" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Generic PA-CF.json b/resources/profiles/BBL/filament/Generic PA-CF.json index bebf3edb6..760586544 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF.json +++ b/resources/profiles/BBL/filament/Generic PA-CF.json @@ -6,8 +6,8 @@ "from": "system", "instantiation": "true", "inherits": "fdm_filament_pa", - "filament_type": [ - "PA-CF" + "fan_cooling_layer_time": [ + "5" ], "fan_max_speed": [ "30" @@ -15,17 +15,20 @@ "fan_min_speed": [ "10" ], - "overhang_fan_threshold": [ - "0%" + "filament_type": [ + "PA-CF" + ], + "full_fan_speed_layer": [ + "2" ], "overhang_fan_speed": [ "40" ], - "fan_cooling_layer_time": [ - "5" + "overhang_fan_threshold": [ + "0%" ], - "full_fan_speed_layer": [ - "2" + "temperature_vitrification": [ + "170" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", From 132e98c9c8c8c1467e6315712092b7991535c407 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 22 Aug 2023 15:51:52 +0800 Subject: [PATCH 026/240] ENH: lower filament max volumetric speed for petg Lower max volumetric speed for polyLite petg Signed-off-by: xun.zhang Change-Id: Id7a28dd8bd59e01934e60e926902deeea456c89a --- resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json | 2 +- resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json index 2a39b32e9..4f71a2642 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL P1P.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "PolyLite PETG @base", "filament_max_volumetric_speed": [ - "14" + "11" ], "hot_plate_temp": [ "80" diff --git a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json index 43e409eeb..d23903276 100644 --- a/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json +++ b/resources/profiles/BBL/filament/PolyLite PETG @BBL X1C.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "PolyLite PETG @base", "filament_max_volumetric_speed": [ - "14" + "11" ], "nozzle_temperature_range_high": [ "270" From 507addcd4c66be34c1b6556ee7bcf0319ad86bd4 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Thu, 24 Aug 2023 18:07:15 +0800 Subject: [PATCH 027/240] FIX: invalid filament vendor in PA6-CF jira:STUDIO-4212 Signed-off-by: xun.zhang Change-Id: Ie940cfb7ca3568e0fee04fa8a2bbcfad17040a15 --- resources/profiles/BBL/filament/Bambu PA6-CF @base.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @base.json b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json index 8f3649efb..ebef68146 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json @@ -24,7 +24,7 @@ "PA-CF" ], "filament_vendor": [ - "Bambu" + "Bambu Lab" ], "nozzle_temperature": [ "275" From 17621eb3e83473ddb777a3fea648e4cfda855923 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 29 Aug 2023 17:10:44 +0800 Subject: [PATCH 028/240] ENH: change PA6-CF filament type to PA6-CF PA6-CF is disabled in AMS jira:STUDIO-4196 Signed-off-by: xun.zhang Change-Id: Iff32388a15f32da6b28034130d5ddadd107a3185 --- resources/profiles/BBL/filament/Bambu PA6-CF @base.json | 2 +- src/libslic3r/PrintConfig.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @base.json b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json index ebef68146..5fdacfe59 100644 --- a/resources/profiles/BBL/filament/Bambu PA6-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @base.json @@ -21,7 +21,7 @@ "0.96" ], "filament_type": [ - "PA-CF" + "PA6-CF" ], "filament_vendor": [ "Bambu Lab" diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index e8b94d4e8..0a2fc4b9f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1317,6 +1317,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("PC"); def->enum_values.push_back("PA"); def->enum_values.push_back("PA-CF"); + def->enum_values.push_back("PA6-CF"); def->enum_values.push_back("PLA-CF"); def->enum_values.push_back("PET-CF"); def->enum_values.push_back("PETG-CF"); From 0b1c2cbe3a23fe9cdd49edeb3f2bc8011185bc4a Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Mon, 21 Aug 2023 18:09:49 +0800 Subject: [PATCH 029/240] ENH: Add Generic PLA High Speed jira:STUDIO-4205 Signed-off-by: xun.zhang Change-Id: I6132ad07968850c2136bc24b0702d0bf525a0b8f --- resources/profiles/BBL.json | 22 ++++++++++++- ...ic PLA High Speed @BBL P1P 0.2 nozzle.json | 14 +++++++++ .../Generic PLA High Speed @BBL P1P.json | 31 +++++++++++++++++++ ...ic PLA High Speed @BBL X1C 0.2 nozzle.json | 16 ++++++++++ .../Generic PLA High Speed @BBL X1C.json | 19 ++++++++++++ .../Generic PLA High Speed @base.json | 17 ++++++++++ 6 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json create mode 100644 resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C 0.2 nozzle.json create mode 100644 resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json create mode 100644 resources/profiles/BBL/filament/Generic PLA High Speed @base.json diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index bfa27b58f..d5e9c5882 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.07.00.16", + "version": "01.07.00.18", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ @@ -377,6 +377,10 @@ "name": "Overture Matte PLA @base", "sub_path": "filament/Overture Matte PLA @base.json" }, + { + "name": "Generic PLA High Speed @base", + "sub_path": "filament/Generic PLA High Speed @base.json" + }, { "name": "Bambu TPU 95A @base", "sub_path": "filament/Bambu TPU 95A @base.json" @@ -785,6 +789,14 @@ "name": "Overture Matte PLA @BBL P1P", "sub_path": "filament/Overture Matte PLA @BBL P1P.json" }, + { + "name": "Generic PLA High Speed @BBL X1C", + "sub_path": "filament/Generic PLA High Speed @BBL X1C.json" + }, + { + "name": "Generic PLA High Speed @BBL P1P", + "sub_path": "filament/Generic PLA High Speed @BBL P1P.json" + }, { "name": "Bambu TPU 95A @BBL X1C", "sub_path": "filament/Bambu TPU 95A @BBL X1C.json" @@ -1085,6 +1097,14 @@ "name": "Overture Matte PLA @BBL P1P 0.2 nozzle", "sub_path": "filament/Overture Matte PLA @BBL P1P 0.2 nozzle.json" }, + { + "name": "Generic PLA High Speed @BBL X1C 0.2 nozzle", + "sub_path": "filament/Generic PLA High Speed @BBL X1C 0.2 nozzle.json" + }, + { + "name": "Generic PLA High Speed @BBL P1P 0.2 nozzle", + "sub_path": "filament/Generic PLA High Speed @BBL P1P 0.2 nozzle.json" + }, { "name": "PolyLite PETG @BBL X1C 0.2 nozzle", "sub_path": "filament/PolyLite PETG @BBL X1C 0.2 nozzle.json" diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P 0.2 nozzle.json new file mode 100644 index 000000000..a96bb2613 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL P1P 0.2 nozzle", + "inherits": "Generic PLA High Speed @BBL P1P", + "from": "system", + "setting_id": "GFSL95_03", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json new file mode 100644 index 000000000..a1750a1a1 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL P1P.json @@ -0,0 +1,31 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL P1P", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_02", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1P 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C 0.2 nozzle.json new file mode 100644 index 000000000..b5312c39f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C 0.2 nozzle.json @@ -0,0 +1,16 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL X1C 0.2 nozzle", + "inherits": "Generic PLA High Speed @BBL X1C", + "from": "system", + "setting_id": "GFSL95_01", + "instantiation": "true", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json new file mode 100644 index 000000000..abf96d288 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json @@ -0,0 +1,19 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL X1C", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_00", + "instantiation": "true", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1S 0.8 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @base.json b/resources/profiles/BBL/filament/Generic PLA High Speed @base.json new file mode 100644 index 000000000..e3672f689 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @base.json @@ -0,0 +1,17 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "GFL95", + "instantiation": "false", + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "slow_down_layer_time": [ + "8" + ] +} \ No newline at end of file From 82791b0320ba54172c70c4386ccb77ddc1a41f9c Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Mon, 28 Aug 2023 17:10:26 +0800 Subject: [PATCH 030/240] ENH: update fan speed for Generic high speed jira:STUDIO-4205 Change-Id: I301b1995befaac5b2ae1af0dd383c4107e280c59 --- .../profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json index abf96d288..ca0e526bd 100644 --- a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL X1C.json @@ -5,6 +5,9 @@ "from": "system", "setting_id": "GFSL95_00", "instantiation": "true", + "slow_down_layer_time": [ + "4" + ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", From bf8ac4c436a0f8af62bcdf8bed557234c1b0b176 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 25 Aug 2023 16:58:36 +0800 Subject: [PATCH 031/240] ENH: CLI: optimize the logic for message 1. treat the critical slicing warnings as error 2. save more information into result including the triangle counts and the non-critical warnings JIRA: STUDIO-4217 Change-Id: I25b746d06c9a1ef2d642c67852577982a2986322 (cherry picked from commit 1d9707ed04cbb6dc12b440b70f3581c619136ac3) --- src/BambuStudio.cpp | 250 ++++++++++++++++++++++------------ src/libslic3r/PrintBase.cpp | 8 +- src/libslic3r/PrintBase.hpp | 15 +- src/libslic3r/PrintObject.cpp | 9 +- 4 files changed, 182 insertions(+), 100 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index bcecf2da4..ebcfbaf28 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -314,13 +314,46 @@ typedef struct _cli_callback_mgr { } }cli_callback_mgr_t; -cli_callback_mgr_t g_cli_callback_mgr; +typedef struct _sliced_plate_info{ + int plate_id{0}; + size_t sliced_time {0}; + size_t triangle_count{0}; + std::string warning_message; +}sliced_plate_info_t; +typedef struct _sliced_info { + int plate_count {0}; + int plate_to_slice {0}; + + std::vector sliced_plates; + size_t prepare_time; + size_t export_time; +}sliced_info_t; + + +cli_callback_mgr_t g_cli_callback_mgr; +std::vector g_slicing_warnings; void cli_status_callback(const PrintBase::SlicingStatus& slicing_status) { + if (slicing_status.warning_step != -1) { + g_slicing_warnings.push_back(slicing_status); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": percent=%1%, warning_step=%2%, message=%3%, message_type=%4%, flag=%5%") + %slicing_status.percent %slicing_status.warning_step %slicing_status.text %(int)(slicing_status.message_type) %slicing_status.flags; + } g_cli_callback_mgr.update(slicing_status.percent, slicing_status.text, slicing_status.warning_step); return; } + +void default_status_callback(const PrintBase::SlicingStatus& slicing_status) +{ + if (slicing_status.warning_step != -1) { + g_slicing_warnings.push_back(slicing_status); + } + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": percent=%1%, warning_step=%2%, message=%3%, message_type=%4%")%slicing_status.percent %slicing_status.warning_step %slicing_status.text %(int)(slicing_status.message_type); + + return; +} + #endif static PrinterTechnology get_printer_technology(const DynamicConfig &config) @@ -349,8 +382,7 @@ static PrinterTechnology get_printer_technology(const DynamicConfig &config) return(ret);} #endif -void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, - size_t prepare_time = 0, std::vector sliced_time = std::vector(), size_t export_time = 0, std::map key_values = std::map()) +void record_exit_reson(std::string outputdir, int code, int plate_id, std::string error_message, sliced_info_t& sliced_info, std::map key_values = std::map()) { #if defined(__linux__) || defined(__LINUX__) std::string result_file; @@ -366,9 +398,17 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin j["plate_index"] = plate_id; j["return_code"] = code; j["error_string"] = error_message; - j["prepare_time"] = prepare_time; - j["slice_time"] = sliced_time; - j["export_time"] = export_time; + j["prepare_time"] = sliced_info.prepare_time; + j["export_time"] = sliced_info.export_time; + for (size_t index = 0; index < sliced_info.sliced_plates.size(); index++) + { + json plate_json; + plate_json["id"] = sliced_info.sliced_plates[index].plate_id; + plate_json["sliced_time"] = sliced_info.sliced_plates[index].sliced_time; + plate_json["triangle_count"] = sliced_info.sliced_plates[index].triangle_count; + plate_json["warning_message"] = sliced_info.sliced_plates[index].warning_message; + j["sliced_plates"].push_back(plate_json); + } for (auto& iter: key_values) j[iter.first] = iter.second; @@ -487,8 +527,8 @@ int CLI::run(int argc, char **argv) std::map skip_maps; bool need_skip = (skip_objects.size() > 0)?true:false; long long global_begin_time = 0, global_current_time; - std::vector sliced_time; - size_t prepare_time, export_time; + sliced_info_t sliced_info; + std::map record_key_values; if (start_gui) { BOOST_LOG_TRIVIAL(info) << "no action, start gui directly" << std::endl; @@ -627,7 +667,7 @@ int CLI::run(int argc, char **argv) for (const std::string& file : m_input_files) { if (!boost::filesystem::exists(file)) { boost::nowide::cerr << "No such file: " << file << std::endl; - record_exit_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND]); + record_exit_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND], sliced_info); flush_and_exit(CLI_FILE_NOTFOUND); } Model model; @@ -657,7 +697,7 @@ int CLI::run(int argc, char **argv) if (!first_file) { BOOST_LOG_TRIVIAL(info) << "The BBL 3mf file should be placed at the first position, filename=" << file << "\n"; - record_exit_reson(outfile_dir, CLI_FILELIST_INVALID_ORDER, 0, cli_errors[CLI_FILELIST_INVALID_ORDER]); + record_exit_reson(outfile_dir, CLI_FILELIST_INVALID_ORDER, 0, cli_errors[CLI_FILELIST_INVALID_ORDER], sliced_info); flush_and_exit(CLI_FILELIST_INVALID_ORDER); } BOOST_LOG_TRIVIAL(info) << boost::format("the first file is a 3mf, version %1%, got plate count %2%") %file_version.to_string() %plate_data_src.size(); @@ -684,7 +724,7 @@ int CLI::run(int argc, char **argv) std::vector postprocess_values = postprocess_scripts->values; if (postprocess_values.size() > 0) { BOOST_LOG_TRIVIAL(error) << boost::format("normative_check: postprocess not supported, array size %1%")%postprocess_values.size(); - record_exit_reson(outfile_dir, CLI_POSTPROCESS_NOT_SUPPORTED, 0, cli_errors[CLI_POSTPROCESS_NOT_SUPPORTED]); + record_exit_reson(outfile_dir, CLI_POSTPROCESS_NOT_SUPPORTED, 0, cli_errors[CLI_POSTPROCESS_NOT_SUPPORTED], sliced_info); flush_and_exit(CLI_POSTPROCESS_NOT_SUPPORTED); } } @@ -780,7 +820,7 @@ int CLI::run(int argc, char **argv) } if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) { boost::nowide::cerr << "invalid printer_technology " < 0) && default_filament_file.empty()) { BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(": load_filament_count is %1%, but can not load a default filament") % load_filament_count; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } } @@ -996,13 +1036,13 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(file, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } if (config_type != "filament") { BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(": unknown config type %1% of file %2% in load-filaments") % config_type % file; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } @@ -1012,7 +1052,7 @@ int CLI::run(int argc, char **argv) } if ((printer_technology != other_printer_technology) && (other_printer_technology != ptUnknown)) { BOOST_LOG_TRIVIAL(error) << "invalid printer_technology " <("upward_compatible_machine", true)->values; @@ -1074,7 +1114,7 @@ int CLI::run(int argc, char **argv) else if (config_type == "process") { if ( config_name != current_process_system_name ) { BOOST_LOG_TRIVIAL(error) << boost::format("wrong process config file %1% loaded, current process config name %2% ")%config_name %current_process_system_name; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } current_print_compatible_printers = config.option("compatible_printers", true)->values; @@ -1087,7 +1127,7 @@ int CLI::run(int argc, char **argv) } else { BOOST_LOG_TRIVIAL(error) << boost::format("found invalid config type %1% from config %2% ")%config_type %file; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } } @@ -1105,7 +1145,7 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(system_printer_path, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } upward_compatible_printers = config.option("upward_compatible_machine", true)->values; @@ -1128,7 +1168,7 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(system_process_path, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } current_print_compatible_printers = config.option("compatible_printers", true)->values; @@ -1153,7 +1193,7 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(system_filament_path, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } @@ -1188,7 +1228,7 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(system_printer_path, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } upward_compatible_printers = config.option("upward_compatible_machine", true)->values; @@ -1210,7 +1250,7 @@ int CLI::run(int argc, char **argv) std::string config_type, config_name, filament_id, config_from; int ret = load_config_file(system_process_path, config, config_type, config_name, filament_id, config_from); if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } current_print_compatible_printers = config.option("compatible_printers", true)->values; @@ -1291,20 +1331,20 @@ int CLI::run(int argc, char **argv) } if (!process_compatible) { BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1% : current 3mf file not support the new printer %2%, new_printer_system_name %3%")%__LINE__%new_printer_name %new_printer_system_name; - record_exit_reson(outfile_dir, CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, 0, cli_errors[CLI_3MF_NEW_MACHINE_NOT_SUPPORTED]); + record_exit_reson(outfile_dir, CLI_3MF_NEW_MACHINE_NOT_SUPPORTED, 0, cli_errors[CLI_3MF_NEW_MACHINE_NOT_SUPPORTED], sliced_info); flush_and_exit(CLI_3MF_NEW_MACHINE_NOT_SUPPORTED); } } else { BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1%: current 3mf file not support upward_compatible_printers, can not change machine preset.")%__LINE__; - record_exit_reson(outfile_dir, CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, 0, cli_errors[CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE]); + record_exit_reson(outfile_dir, CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE, 0, cli_errors[CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE], sliced_info); flush_and_exit(CLI_3MF_NOT_SUPPORT_MACHINE_CHANGE); } } if (!process_compatible) { BOOST_LOG_TRIVIAL(error) <<__FUNCTION__ << boost::format(" %1%: process not compatible with printer.")%__LINE__; - record_exit_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE]); + record_exit_reson(outfile_dir, CLI_PROCESS_NOT_COMPATIBLE, 0, cli_errors[CLI_PROCESS_NOT_COMPATIBLE], sliced_info); flush_and_exit(CLI_PROCESS_NOT_COMPATIBLE); } @@ -1424,7 +1464,7 @@ int CLI::run(int argc, char **argv) } if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } } @@ -1478,7 +1518,7 @@ int CLI::run(int argc, char **argv) } if (ret) { - record_exit_reson(outfile_dir, ret, 0, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, 0, cli_errors[ret], sliced_info); flush_and_exit(ret); } } @@ -1559,7 +1599,7 @@ int CLI::run(int argc, char **argv) if (source_opt == nullptr) { // The key was not found in the source config, therefore it will not be initialized! BOOST_LOG_TRIVIAL(error) << boost::format("can not find %1% from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index]; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } if (source_opt->is_scalar()) { @@ -1592,7 +1632,7 @@ int CLI::run(int argc, char **argv) // opt_key does not exist in this ConfigBase and it cannot be created, because it is not defined by this->def(). // This is only possible if other is of DynamicConfig type. BOOST_LOG_TRIVIAL(error) << boost::format("can not create option %1% to config, from filament %2%: %3%")%opt_key%filament_index%load_filaments_name[index]; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } ConfigOptionVectorBase* opt_vec_dst = static_cast(opt); @@ -1656,7 +1696,7 @@ int CLI::run(int argc, char **argv) if (filament_is_support->size() != project_filament_count) { BOOST_LOG_TRIVIAL(error) << boost::format("filament_is_support's count %1% not equal to filament_colour's size %2%")%filament_is_support->size() %project_filament_count; - record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR]); + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); flush_and_exit(CLI_CONFIG_FILE_ERROR); } @@ -1753,7 +1793,7 @@ int CLI::run(int argc, char **argv) m_print_config.apply(fff_print_config, true); } else { boost::nowide::cerr << "invalid printer_technology " << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH]); + record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH], sliced_info); flush_and_exit(CLI_INVALID_PRINTER_TECH); /*assert(printer_technology == ptSLA); sla_print_config.filename_format.value = "[input_filename_base].sl1"; @@ -1773,7 +1813,7 @@ int CLI::run(int argc, char **argv) boost::nowide::cerr << "Param values in 3mf/config error: "<< std::endl; for (std::map::iterator it=validity.begin(); it!=validity.end(); ++it) boost::nowide::cerr << it->first <<": "<< it->second << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_VALUES_IN_3MF, 0, cli_errors[CLI_INVALID_VALUES_IN_3MF]); + record_exit_reson(outfile_dir, CLI_INVALID_VALUES_IN_3MF, 0, cli_errors[CLI_INVALID_VALUES_IN_3MF], sliced_info); flush_and_exit(CLI_INVALID_VALUES_IN_3MF); } @@ -1806,7 +1846,7 @@ int CLI::run(int argc, char **argv) { BOOST_LOG_TRIVIAL(error) << boost::format("old printable size {%1%, %2%, %3%} is larger than new printable size {%4%, %5%, %6%}, can not print") %old_printable_width %old_printable_depth %old_printable_height %current_printable_width %current_printable_depth %current_printable_height; - record_exit_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED]); + record_exit_reson(outfile_dir, CLI_PRINTABLE_SIZE_REDUCED, 0, cli_errors[CLI_PRINTABLE_SIZE_REDUCED], sliced_info); flush_and_exit(CLI_PRINTABLE_SIZE_REDUCED); } else if ((old_printable_width < current_printable_width) || (old_printable_depth < current_printable_depth)) @@ -1946,12 +1986,12 @@ int CLI::run(int argc, char **argv) else { if (plate_to_slice == 0) { BOOST_LOG_TRIVIAL(error) << "Invalid params: can not set repetitions when slice all." << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } else if (plate_to_slice > partplate_list.get_plate_count()) { BOOST_LOG_TRIVIAL(error) << boost::format("Invalid params:invalid plate %1% to slice, total %2%")%plate_to_slice %partplate_list.get_plate_count(); - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } BOOST_LOG_TRIVIAL(info) << "repetitions value " << repetitions_count << std::endl; @@ -2005,7 +2045,7 @@ int CLI::run(int argc, char **argv) } } catch (std::exception &ex) { boost::nowide::cerr << "error: " << ex.what() << std::endl; - record_exit_reson(outfile_dir, CLI_COPY_OBJECTS_ERROR, 0, cli_errors[CLI_COPY_OBJECTS_ERROR]); + record_exit_reson(outfile_dir, CLI_COPY_OBJECTS_ERROR, 0, cli_errors[CLI_COPY_OBJECTS_ERROR], sliced_info); flush_and_exit(CLI_COPY_OBJECTS_ERROR); } } @@ -2075,7 +2115,7 @@ int CLI::run(int argc, char **argv) const Vec3d &opt = m_config.opt(opt_key)->value; if (opt.x() <= 0 || opt.y() <= 0 || opt.z() <= 0) { boost::nowide::cerr << "--scale-to-fit requires a positive volume" << std::endl; - record_exit_reson(outfile_dir, CLI_SCALE_TO_FIT_ERROR, 0, cli_errors[CLI_SCALE_TO_FIT_ERROR]); + record_exit_reson(outfile_dir, CLI_SCALE_TO_FIT_ERROR, 0, cli_errors[CLI_SCALE_TO_FIT_ERROR], sliced_info); flush_and_exit(CLI_SCALE_TO_FIT_ERROR); } for (auto &model : m_models) @@ -2166,7 +2206,7 @@ int CLI::run(int argc, char **argv) // model.repair(); } else { boost::nowide::cerr << "error: option not implemented yet: " << opt_key << std::endl; - record_exit_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION]); + record_exit_reson(outfile_dir, CLI_UNSUPPORTED_OPERATION, 0, cli_errors[CLI_UNSUPPORTED_OPERATION], sliced_info); flush_and_exit(CLI_UNSUPPORTED_OPERATION); } } @@ -2196,7 +2236,7 @@ int CLI::run(int argc, char **argv) if ((plate_to_slice < 0) || (plate_to_slice > partplate_list.get_plate_count())) { BOOST_LOG_TRIVIAL(error) << boost::format("invalid plate id %1%, total %2%")%plate_to_slice %partplate_list.get_plate_count(); - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } @@ -2515,7 +2555,7 @@ int CLI::run(int argc, char **argv) if (ap.bed_idx != (plate_to_slice-1)) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":arrange failed: ap.name %1% ap.bed_idx %2%, plate index %3%")% ap.name % ap.bed_idx % (plate_to_slice-1); - record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED], sliced_info); flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); } bed_idx_max = std::max(ap.bed_idx, bed_idx_max); @@ -2616,7 +2656,7 @@ int CLI::run(int argc, char **argv) } BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": try new count %1%, low_duplicate_count %2%, up_duplicate_count %3%")%duplicate_count %low_duplicate_count %up_duplicate_count; } - //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED], sliced_info); //flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); failed_this_time = true; break; @@ -2649,7 +2689,7 @@ int CLI::run(int argc, char **argv) { if (real_duplicate_count <= 1) { BOOST_LOG_TRIVIAL(warning) << "no object can be placed under single object mode, restore to the original model and plates also" << std::endl; - //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED]); + //record_exit_reson(outfile_dir, CLI_OBJECT_ARRANGE_FAILED, 0, cli_errors[CLI_OBJECT_ARRANGE_FAILED], sliced_info); //flush_and_exit(CLI_OBJECT_ARRANGE_FAILED); finished_arrange = true; model = original_model; @@ -2753,9 +2793,8 @@ int CLI::run(int argc, char **argv) std::vector> plate_skipped_objects(partplate_list.get_plate_count()); global_current_time = (long long)Slic3r::Utils::get_current_time_utc(); - prepare_time = (size_t) (global_current_time - global_begin_time); + sliced_info.prepare_time = (size_t) (global_current_time - global_begin_time); global_begin_time = global_current_time; - sliced_time.resize(partplate_list.get_plate_count(), 0); for (auto const &opt_key : m_actions) { if (opt_key == "help") { @@ -2771,19 +2810,19 @@ int CLI::run(int argc, char **argv) load_slice_data_dir = m_config.opt_string(opt_key); if (export_slicedata) { BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } else if (duplicate_count > 0) { BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata when set repetitions." << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } else if (shrink_to_new_bed) { BOOST_LOG_TRIVIAL(warning) << "use load_slicedata when shrink_to_new_bed(switch printer from small to bigger." << std::endl; - //record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + //record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); //flush_and_exit(CLI_INVALID_PARAMS); } } else if (opt_key == "export_settings") { @@ -2811,14 +2850,14 @@ int CLI::run(int argc, char **argv) for (auto &model : m_models) model.add_default_instances(); if (! this->export_models(IO::STL)) { - record_exit_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR]); + record_exit_reson(outfile_dir, CLI_EXPORT_STL_ERROR, 0, cli_errors[CLI_EXPORT_STL_ERROR], sliced_info); flush_and_exit(CLI_EXPORT_STL_ERROR); } } else if (opt_key == "export_obj") { for (auto &model : m_models) model.add_default_instances(); if (! this->export_models(IO::OBJ)) { - record_exit_reson(outfile_dir, CLI_EXPORT_OBJ_ERROR, 0, cli_errors[CLI_EXPORT_OBJ_ERROR]); + record_exit_reson(outfile_dir, CLI_EXPORT_OBJ_ERROR, 0, cli_errors[CLI_EXPORT_OBJ_ERROR], sliced_info); flush_and_exit(CLI_EXPORT_OBJ_ERROR); } }/* else if (opt_key == "export_amf") { @@ -2837,7 +2876,7 @@ int CLI::run(int argc, char **argv) export_slice_data_dir = m_config.opt_string(opt_key); if (load_slicedata) { BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl; - record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS]); + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, 0, cli_errors[CLI_INVALID_PARAMS], sliced_info); flush_and_exit(CLI_INVALID_PARAMS); } } else if (opt_key == "slice") { @@ -2848,11 +2887,11 @@ int CLI::run(int argc, char **argv) /*if (opt_key == "export_gcode" && printer_technology == ptSLA) { boost::nowide::cerr << "error: cannot export G-code for an FFF configuration" << std::endl; - record_exit_reson(outfile_dir, 1, 0, cli_errors[1]); + record_exit_reson(outfile_dir, 1, 0, cli_errors[1], sliced_info); flush_and_exit(1); } else if (opt_key == "export_sla" && printer_technology == ptFFF) { boost::nowide::cerr << "error: cannot export SLA slices for a SLA configuration" << std::endl; - record_exit_reson(outfile_dir, 1, 0, cli_errors[1]); + record_exit_reson(outfile_dir, 1, 0, cli_errors[1], sliced_info); flush_and_exit(1); }*/ BOOST_LOG_TRIVIAL(info) << "Need to slice for plate "< plate_triangle_counts(partplate_list.get_plate_count(), 0); while(!finished) { @@ -2891,6 +2931,9 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "Skip plate " << index+1 << std::endl; continue; } + sliced_plate_info_t sliced_plate_info; + sliced_plate_info.plate_id = index+1; + model.curr_plate_index = index; BOOST_LOG_TRIVIAL(info) << boost::format("Plate %1%: pre_check %2%, start")%(index+1)%pre_check; long long start_time = 0, end_time = 0; @@ -2924,7 +2967,7 @@ int CLI::run(int argc, char **argv) if (count == 0) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume before apply." << std::endl; - record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]); + record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS], sliced_info); flush_and_exit(CLI_NO_SUITABLE_OBJECTS); } else if ((plate_to_slice != 0) || pre_check) { @@ -2965,10 +3008,10 @@ int CLI::run(int argc, char **argv) if (i->print_volume_state == ModelInstancePVS_Partly_Outside) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Found Object " << model_object->name <<" partly inside, can not be sliced." << std::endl; - record_exit_reson(outfile_dir, CLI_OBJECTS_PARTLY_INSIDE, index+1, cli_errors[CLI_OBJECTS_PARTLY_INSIDE]); + record_exit_reson(outfile_dir, CLI_OBJECTS_PARTLY_INSIDE, index+1, cli_errors[CLI_OBJECTS_PARTLY_INSIDE], sliced_info); flush_and_exit(CLI_OBJECTS_PARTLY_INSIDE); } - else if ((max_triangle_count_per_plate != 0) && (i->print_volume_state == ModelInstancePVS_Inside)) + else if (i->print_volume_state == ModelInstancePVS_Inside) { for (const ModelVolume* vol : model_object->volumes) { @@ -2976,10 +3019,10 @@ int CLI::run(int argc, char **argv) size_t volume_triangle_count = vol->mesh().facets_count(); triangle_count += volume_triangle_count; BOOST_LOG_TRIVIAL(info) << boost::format("volume triangle count %1%, total %2%")%volume_triangle_count %triangle_count; - if (triangle_count > max_triangle_count_per_plate) + if ((max_triangle_count_per_plate != 0) && (triangle_count > max_triangle_count_per_plate)) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": triangle count " << triangle_count <<" exceeds the limit:" << max_triangle_count_per_plate; - record_exit_reson(outfile_dir, CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT, index+1, cli_errors[CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT]); + record_exit_reson(outfile_dir, CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT, index+1, cli_errors[CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT], sliced_info); flush_and_exit(CLI_TRIANGLE_COUNT_EXCEEDS_LIMIT); } } @@ -2992,9 +3035,12 @@ int CLI::run(int argc, char **argv) if (printable_instances == 0) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, after skipping "<{%4%, %5%, %6%}, has %7% printables") % print_volume.min(0) % print_volume.min(1) @@ -3030,15 +3076,16 @@ int CLI::run(int argc, char **argv) validate_error = CLI_VALIDATE_ERROR; break; } - record_exit_reson(outfile_dir, validate_error, index+1, cli_errors[validate_error]); + record_exit_reson(outfile_dir, validate_error, index+1, cli_errors[validate_error], sliced_info); flush_and_exit(validate_error); } - else if (!warning.string.empty()) + else if (!warning.string.empty()) { BOOST_LOG_TRIVIAL(warning) << "got warnings: "<< warning.string << std::endl; + } if (print->empty()) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": Nothing to be sliced, Either the print is empty or no object is fully inside the print volume after apply." << std::endl; - record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS]); + record_exit_reson(outfile_dir, CLI_NO_SUITABLE_OBJECTS, index+1, cli_errors[CLI_NO_SUITABLE_OBJECTS], sliced_info); flush_and_exit(CLI_NO_SUITABLE_OBJECTS); } else { @@ -3062,6 +3109,10 @@ int CLI::run(int argc, char **argv) cli_status_callback(slicing_status); } } + else { + BOOST_LOG_TRIVIAL(info) << "set print's callback to default_status_callback."; + print->set_status_callback(default_status_callback); + } #endif //check whether it is bbl printer std::string& printer_model_string = new_print_config.opt_string("printer_model", true); @@ -3111,10 +3162,35 @@ int CLI::run(int argc, char **argv) std::string conflict_result = print_fff->get_conflict_string(); if (!conflict_result.empty()) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": found slicing result conflict!"<< std::endl; - record_exit_reson(outfile_dir, CLI_GCODE_PATH_CONFLICTS, index+1, cli_errors[CLI_GCODE_PATH_CONFLICTS]); + record_exit_reson(outfile_dir, CLI_GCODE_PATH_CONFLICTS, index+1, cli_errors[CLI_GCODE_PATH_CONFLICTS], sliced_info); flush_and_exit(CLI_GCODE_PATH_CONFLICTS); } + //check the warnings + if (!g_slicing_warnings.empty()) + { + for (unsigned int i = 0; i < g_slicing_warnings.size(); i++) + { + PrintBase::SlicingStatus& status = g_slicing_warnings[i]; + if ((status.warning_step != -1) && (status.message_type != PrintStateBase::SlicingDefaultNotification)) + { + sliced_plate_info.warning_message = status.text; + + if (status.warning_level == PrintStateBase::WarningLevel::NON_CRITICAL) { + BOOST_LOG_TRIVIAL(warning) << "plate "<< index+1<< ": found slicing warnings: "<get_tmp_gcode_path(); if (outfile_dir.empty()) { @@ -3137,7 +3213,7 @@ int CLI::run(int argc, char **argv) /*if (outfile != outfile_final) { if (Slic3r::rename_file(outfile, outfile_final)) { boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl; - record_exit_reson(outfile_dir, 1, index+1, cli_errors[1]); + record_exit_reson(outfile_dir, 1, index+1, cli_errors[1], sliced_info); flush_and_exit(1); } outfile = outfile_final; @@ -3162,26 +3238,29 @@ int CLI::run(int argc, char **argv) export_slicedata_error = true; if (fs::exists(plate_dir)) fs::remove_all(plate_dir); - record_exit_reson(outfile_dir, ret, index+1, cli_errors[ret]); + record_exit_reson(outfile_dir, ret, index+1, cli_errors[ret], sliced_info); flush_and_exit(ret); } } end_time = (long long)Slic3r::Utils::get_current_time_utc(); - sliced_time[index] = end_time - start_time; + sliced_plate_info.sliced_time = end_time - start_time; + if (max_slicing_time_per_plate != 0) { long long time_cost = end_time - start_time; if (time_cost > max_slicing_time_per_plate) { - BOOST_LOG_TRIVIAL(error) << boost::format("plate %1%'s slice time %2% exceeds the limit %3%, return error.") - %(index+1) %time_cost %max_slicing_time_per_plate; - record_exit_reson(outfile_dir, CLI_SLICING_TIME_EXCEEDS_LIMIT, index+1, cli_errors[CLI_SLICING_TIME_EXCEEDS_LIMIT]); + sliced_plate_info.warning_message = (boost::format("plate %1%'s slice time %2% exceeds the limit %3%, return error.")%(index+1) %time_cost %max_slicing_time_per_plate).str(); + BOOST_LOG_TRIVIAL(error) << sliced_plate_info.warning_message; + sliced_info.sliced_plates.push_back(sliced_plate_info); + record_exit_reson(outfile_dir, CLI_SLICING_TIME_EXCEEDS_LIMIT, index+1, cli_errors[CLI_SLICING_TIME_EXCEEDS_LIMIT], sliced_info); flush_and_exit(CLI_SLICING_TIME_EXCEEDS_LIMIT); } } + sliced_info.sliced_plates.push_back(sliced_plate_info); } catch (const std::exception &ex) { BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate "< 0) { - std::map key_values; - key_values["sliced_count"] = std::to_string(duplicate_count+1); - record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], prepare_time, sliced_time, export_time, key_values); + record_key_values["sliced_count"] = std::to_string(duplicate_count+1); + record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], sliced_info, record_key_values); } else { - record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], prepare_time, sliced_time, export_time); + record_exit_reson(outfile_dir, 0, plate_to_slice, cli_errors[0], sliced_info); } boost::nowide::cout.flush(); diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp index 4965e1e50..a2fbfaba6 100644 --- a/src/libslic3r/PrintBase.cpp +++ b/src/libslic3r/PrintBase.cpp @@ -110,11 +110,11 @@ void PrintBase::set_status(int percent, const std::string &message, unsigned in BOOST_LOG_TRIVIAL(debug) <m_status_callback) { - auto status = print_object ? SlicingStatus(*print_object, step, message, message_id) : SlicingStatus(*this, step, message, message_id); + auto status = print_object ? SlicingStatus(*print_object, step, message, message_id, warning_level) : SlicingStatus(*this, step, message, message_id, warning_level); m_status_callback(status); } else if (! message.empty()) @@ -122,12 +122,12 @@ void PrintBase::status_update_warnings(int step, PrintStateBase::WarningLevel /* } //BBS: add PrintObject id into slicing status -void PrintBase::status_update_warnings(int step, PrintStateBase::WarningLevel /* warning_level */, +void PrintBase::status_update_warnings(int step, PrintStateBase::WarningLevel warning_level, const std::string& message, PrintObjectBase &object, PrintStateBase::SlicingNotificationType message_id) { //BBS: add object it into slicing status if (this->m_status_callback) { - m_status_callback(SlicingStatus(object, step, message, message_id)); + m_status_callback(SlicingStatus(object, step, message, message_id, warning_level)); } else if (!message.empty()) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", PrintObject warning: %1%\n")% message.c_str(); diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 1343a6a2a..79e231a17 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -431,18 +431,18 @@ public: struct SlicingStatus { SlicingStatus(int percent, const std::string &text, unsigned int flags = 0, int warning_step = -1, - PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification) : - percent(percent), text(text), flags(flags), warning_step(warning_step), message_type(msg_type) + PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification, PrintStateBase::WarningLevel warning_level = PrintStateBase::WarningLevel::NON_CRITICAL) : + percent(percent), text(text), flags(flags), warning_step(warning_step), message_type(msg_type), warning_level(warning_level) { } SlicingStatus(const PrintBase &print, int warning_step, const std::string& text, - PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification) : - flags(UPDATE_PRINT_STEP_WARNINGS), warning_object_id(print.id()), text(text), warning_step(warning_step), message_type(msg_type) + PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification, PrintStateBase::WarningLevel warning_level = PrintStateBase::WarningLevel::NON_CRITICAL) : + flags(UPDATE_PRINT_STEP_WARNINGS), warning_object_id(print.id()), text(text), warning_step(warning_step), message_type(msg_type), warning_level(warning_level) { } SlicingStatus(const PrintObjectBase &print_object, int warning_step, const std::string& text, - PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification) : - flags(UPDATE_PRINT_OBJECT_STEP_WARNINGS), warning_object_id(print_object.id()), text(text), warning_step(warning_step), message_type(msg_type) + PrintStateBase::SlicingNotificationType msg_type = PrintStateBase::SlicingDefaultNotification, PrintStateBase::WarningLevel warning_level = PrintStateBase::WarningLevel::NON_CRITICAL) : + flags(UPDATE_PRINT_OBJECT_STEP_WARNINGS), warning_object_id(print_object.id()), text(text), warning_step(warning_step), message_type(msg_type), warning_level(warning_level) { } int percent { -1 }; @@ -466,6 +466,7 @@ public: int warning_step { -1 }; PrintStateBase::SlicingNotificationType message_type {PrintStateBase::SlicingDefaultNotification}; + PrintStateBase::WarningLevel warning_level {PrintStateBase::WarningLevel::NON_CRITICAL}; }; typedef std::function status_callback_type; // Default status console print out in the form of percent => message. @@ -532,7 +533,7 @@ protected: void status_update_warnings(int step, PrintStateBase::WarningLevel warning_level, const std::string &message, const PrintObjectBase* print_object = nullptr, PrintStateBase::SlicingNotificationType message_id = PrintStateBase::SlicingDefaultNotification); //BBS: add api to update printobject's warnings - void status_update_warnings(int step, PrintStateBase::WarningLevel /* warning_level */, + void status_update_warnings(int step, PrintStateBase::WarningLevel warning_level, const std::string& message, PrintObjectBase &object, PrintStateBase::SlicingNotificationType message_id = PrintStateBase::SlicingDefaultNotification); // If the background processing stop was requested, throw CanceledException. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index f76c0e0c6..9ae6843f6 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -477,7 +477,10 @@ void PrintObject::generate_support_material() {LargeOverhang,L("large overhangs")} }; std::string warning_message = format(L("It seems object %s has %s. Please re-orient the object or enable support generation."), this->model_object()->name, reasons[sntype]); - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + if (SharpTail == sntype) + this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + else + this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); } #if 0 @@ -795,7 +798,7 @@ bool PrintObject::invalidate_state_by_config_options( } else if ( opt_key == "bottom_shell_layers" || opt_key == "top_shell_layers") { - + steps.emplace_back(posPrepareInfill); const auto *old_shell_layers = old_config.option(opt_key); @@ -807,7 +810,7 @@ bool PrintObject::invalidate_state_by_config_options( if (value_changed && this->object_extruders().size() > 1) { steps.emplace_back(posSlice); - } + } else if (m_print->config().spiral_mode && opt_key == "bottom_shell_layers") { // Changing the number of bottom layers when a spiral vase is enabled requires re-slicing the object again. // Otherwise, holes in the bottom layers could be filled, as is reported in GH #5528. From 4eea84f24abbdc27dac491e7954a6974f6e20f07 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Tue, 29 Aug 2023 22:18:41 +0800 Subject: [PATCH 032/240] FIX: CLI: fix the compiling issue under windows JIRA: STUDIO-4217 Change-Id: Id937f921aa6d1f5cbc2300ba7395df71c3cd147a (cherry picked from commit 799faa7bbd270050bc8b04afba27021ebaf88933) --- src/BambuStudio.cpp | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index ebcfbaf28..56008e9b6 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -140,6 +140,23 @@ std::map cli_errors = { {CLI_GCODE_PATH_CONFLICTS, " G-code conflicts detected after slicing. Please make sure the 3mf file can be successfully sliced in the latest Bambu Studio."} }; +typedef struct _sliced_plate_info{ + int plate_id{0}; + size_t sliced_time {0}; + size_t triangle_count{0}; + std::string warning_message; +}sliced_plate_info_t; + +typedef struct _sliced_info { + int plate_count {0}; + int plate_to_slice {0}; + + std::vector sliced_plates; + size_t prepare_time; + size_t export_time; +}sliced_info_t; +std::vector g_slicing_warnings; + #if defined(__linux__) || defined(__LINUX__) #define PIPE_BUFFER_SIZE 512 @@ -314,25 +331,7 @@ typedef struct _cli_callback_mgr { } }cli_callback_mgr_t; -typedef struct _sliced_plate_info{ - int plate_id{0}; - size_t sliced_time {0}; - size_t triangle_count{0}; - std::string warning_message; -}sliced_plate_info_t; - -typedef struct _sliced_info { - int plate_count {0}; - int plate_to_slice {0}; - - std::vector sliced_plates; - size_t prepare_time; - size_t export_time; -}sliced_info_t; - - cli_callback_mgr_t g_cli_callback_mgr; -std::vector g_slicing_warnings; void cli_status_callback(const PrintBase::SlicingStatus& slicing_status) { if (slicing_status.warning_step != -1) { @@ -343,6 +342,7 @@ void cli_status_callback(const PrintBase::SlicingStatus& slicing_status) g_cli_callback_mgr.update(slicing_status.percent, slicing_status.text, slicing_status.warning_step); return; } +#endif void default_status_callback(const PrintBase::SlicingStatus& slicing_status) { @@ -354,7 +354,6 @@ void default_status_callback(const PrintBase::SlicingStatus& slicing_status) return; } -#endif static PrinterTechnology get_printer_technology(const DynamicConfig &config) { @@ -3113,6 +3112,9 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "set print's callback to default_status_callback."; print->set_status_callback(default_status_callback); } +#else + BOOST_LOG_TRIVIAL(info) << "set print's callback to default_status_callback."; + print->set_status_callback(default_status_callback); #endif //check whether it is bbl printer std::string& printer_model_string = new_print_config.opt_string("printer_model", true); From c00caad244c29c304c7361eed1421d3169002c10 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Tue, 29 Aug 2023 21:15:49 +0800 Subject: [PATCH 033/240] ENH: CLI: add support of rotate JIRA: STUDIO-4183 Change-Id: I091cc3142ce867d2ac75ba27b3cb2e4e569c9681 (cherry picked from commit 7eab9ba9f22dc8f00e13caf27c7cf72b8675562a) --- src/BambuStudio.cpp | 48 +++++++++++++++++++++++++---------- src/libslic3r/PrintConfig.cpp | 20 +++++++-------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 56008e9b6..bf385fce2 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -2012,18 +2012,35 @@ int CLI::run(int argc, char **argv) } } else if (opt_key == "orient") { - for (auto& model : m_models) - for (ModelObject* o : model.objects) - { - // coconut: always orient instance instead of object - for (ModelInstance* mi : o->instances) + //BBS: orient 0 means disable, 1 means force orient, others means auto + int orient_option = m_config.option("orient")->value; + + if (orient_option == 0) + { + orients_requirement.clear(); + for (auto& model : m_models) + for (ModelObject* o : model.objects) { - orientation::orient(mi); + orients_requirement.insert(std::pair(o->id().id, false)); + BOOST_LOG_TRIVIAL(info) << "object "<name <<", id :" << o->id().id << ", no need to orient when setting orient to 0\n"; } - BOOST_LOG_TRIVIAL(info) << "orient object, name=" << o->name <<",id="<id().id<id().id] = false; - } + } + else if (orient_option == 1) + { + //force orient + orients_requirement.clear(); + for (auto& model : m_models) + for (ModelObject* o : model.objects) + { + orients_requirement.insert(std::pair(o->id().id, true)); + BOOST_LOG_TRIVIAL(info) << "object "<name <<", id :" << o->id().id << ", need to orient when setting orient to 1\n"; + } + } + else + { + //auto arrange, keep the original logic + } + BOOST_LOG_TRIVIAL(info) << boost::format("orient_option %1%")%orient_option; } else if (opt_key == "copy") { for (auto &model : m_models) { @@ -2777,10 +2794,13 @@ int CLI::run(int argc, char **argv) // All transforms have been dealt with. Now ensure that the objects are on bed. // (Unless the user said otherwise.) //BBS: current only support models on bed, 0407 sinking supported - //if (m_config.opt_bool("ensure_on_bed")) - // for (auto &model : m_models) - // for (auto &o : model.objects) - // o->ensure_on_bed(); + if (m_config.opt_bool("ensure_on_bed")) + { + BOOST_LOG_TRIVIAL(info) << "ensure_on_bed: need to ensure each object on beds"; + for (auto &model : m_models) + for (auto &o : model.objects) + o->ensure_on_bed(); + } // loop through action options bool export_to_3mf = false, load_slicedata = false, export_slicedata = false, export_slicedata_error = false; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0a2fc4b9f..cfad2c210 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5094,12 +5094,12 @@ CLITransformConfigDef::CLITransformConfigDef() def->cli_params = "count"; def->set_default_value(new ConfigOptionInt(1)); - /*def = this->add("ensure_on_bed", coBool); + def = this->add("ensure_on_bed", coBool); def->label = L("Ensure on bed"); - def->tooltip = L("Lift the object above the bed when it is partially below. Enabled by default, use --no-ensure-on-bed to disable."); - def->set_default_value(new ConfigOptionBool(true)); + def->tooltip = L("Lift the object above the bed when it is partially below. Disabled by default"); + def->set_default_value(new ConfigOptionBool(false)); - def = this->add("copy", coInt); + /*def = this->add("copy", coInt); def->label = L("Copy"); def->tooltip =L("Duplicate copies of model"); def->min = 1; @@ -5119,18 +5119,18 @@ CLITransformConfigDef::CLITransformConfigDef() def->tooltip = L("Convert the units of model"); def->set_default_value(new ConfigOptionBool(false)); - def = this->add("orient", coBool); - def->label = L("Orient"); - def->tooltip = L("Orient the model"); + def = this->add("orient", coInt); + def->label = L("Orient Options"); + def->tooltip = L("Orient options: 0-disable, 1-enable, others-auto"); //def->cli = "orient|o"; - def->set_default_value(new ConfigOptionBool(false)); + def->set_default_value(new ConfigOptionInt(0)); /*def = this->add("repair", coBool); def->label = L("Repair"); def->tooltip = L("Repair the model's meshes if it is non-manifold mesh"); def->set_default_value(new ConfigOptionBool(false));*/ - /*def = this->add("rotate", coFloat); + def = this->add("rotate", coFloat); def->label = L("Rotate"); def->tooltip = L("Rotation angle around the Z axis in degrees."); def->set_default_value(new ConfigOptionFloat(0)); @@ -5143,7 +5143,7 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("rotate_y", coFloat); def->label = L("Rotate around Y"); def->tooltip = L("Rotation angle around the Y axis in degrees."); - def->set_default_value(new ConfigOptionFloat(0));*/ + def->set_default_value(new ConfigOptionFloat(0)); def = this->add("scale", coFloat); def->label = L("Scale"); From e7fcd330ba9a62be51004191cfc16c25dc4ba1ba Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Wed, 30 Aug 2023 11:06:20 +0800 Subject: [PATCH 034/240] FIX: the default value of flow rate calibration is the last value set Jira: 4147 Change-Id: If587d92aea872e8cfadb556b2912db402e0a6a86 (cherry picked from commit 2530a94827231181ac30fb6ade1eb99021be5f2a) --- src/slic3r/GUI/CalibrationWizardSavePage.cpp | 49 ++++++++++++-------- src/slic3r/GUI/CalibrationWizardSavePage.hpp | 9 +++- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.cpp b/src/slic3r/GUI/CalibrationWizardSavePage.cpp index 48831693f..315d55b3c 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.cpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.cpp @@ -1158,10 +1158,10 @@ void CalibrationFlowCoarseSavePage::create_page(wxWindow* parent) coarse_block_items.Add(std::to_string(-20 + (i * 5))); } m_optimal_block_coarse->Set(coarse_block_items); - auto coarse_calc_result_text = new Label(parent, ""); + m_coarse_calc_result_text = new Label(parent, ""); coarse_value_sizer->Add(coarse_value_text, 0, 0); coarse_value_sizer->Add(m_optimal_block_coarse, 0, 0); - coarse_value_sizer->Add(coarse_calc_result_text, 0); + coarse_value_sizer->Add(m_coarse_calc_result_text, 0); m_top_sizer->Add(coarse_value_sizer, 0, 0, 0); m_top_sizer->AddSpacer(FromDIP(20)); @@ -1169,16 +1169,16 @@ void CalibrationFlowCoarseSavePage::create_page(wxWindow* parent) checkBox_panel->SetBackgroundColour(*wxWHITE); auto cb_sizer = new wxBoxSizer(wxHORIZONTAL); checkBox_panel->SetSizer(cb_sizer); - auto checkBox_skip_calibration = new CheckBox(checkBox_panel); - cb_sizer->Add(checkBox_skip_calibration); + m_checkBox_skip_calibration = new CheckBox(checkBox_panel); + cb_sizer->Add(m_checkBox_skip_calibration); auto cb_text = new Label(checkBox_panel, _L("Skip Calibration2")); cb_sizer->Add(cb_text); - cb_text->Bind(wxEVT_LEFT_DOWN, [this, checkBox_skip_calibration](auto&) { - checkBox_skip_calibration->SetValue(!checkBox_skip_calibration->GetValue()); + cb_text->Bind(wxEVT_LEFT_DOWN, [this](auto&) { + m_checkBox_skip_calibration->SetValue(!m_checkBox_skip_calibration->GetValue()); wxCommandEvent event(wxEVT_TOGGLEBUTTON); - event.SetEventObject(checkBox_skip_calibration); - checkBox_skip_calibration->GetEventHandler()->ProcessEvent(event); + event.SetEventObject(m_checkBox_skip_calibration); + m_checkBox_skip_calibration->GetEventHandler()->ProcessEvent(event); }); m_top_sizer->Add(checkBox_panel, 0, 0, 0); @@ -1201,8 +1201,8 @@ void CalibrationFlowCoarseSavePage::create_page(wxWindow* parent) m_top_sizer->AddSpacer(FromDIP(20)); - checkBox_skip_calibration->Bind(wxEVT_TOGGLEBUTTON, [this, save_panel, checkBox_skip_calibration](wxCommandEvent& e) { - if (checkBox_skip_calibration->GetValue()) { + m_checkBox_skip_calibration->Bind(wxEVT_TOGGLEBUTTON, [this, save_panel](wxCommandEvent &e) { + if (m_checkBox_skip_calibration->GetValue()) { m_skip_fine_calibration = true; save_panel->Show(); m_action_panel->show_button(CaliPageActionType::CALI_ACTION_FLOW_COARSE_SAVE); @@ -1219,9 +1219,9 @@ void CalibrationFlowCoarseSavePage::create_page(wxWindow* parent) e.Skip(); }); - m_optimal_block_coarse->Bind(wxEVT_COMBOBOX, [this, coarse_calc_result_text](auto& e) { + m_optimal_block_coarse->Bind(wxEVT_COMBOBOX, [this](auto& e) { m_coarse_flow_ratio = m_curr_flow_ratio * (100.0f + stof(m_optimal_block_coarse->GetValue().ToStdString())) / 100.0f; - coarse_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_coarse_flow_ratio))); + m_coarse_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_coarse_flow_ratio))); }); m_action_panel = new CaliPageActionPanel(parent, m_cali_mode, CaliPageType::CALI_PAGE_COARSE_SAVE); @@ -1237,8 +1237,15 @@ void CalibrationFlowCoarseSavePage::set_save_img() { } } -void CalibrationFlowCoarseSavePage::set_default_name(const wxString& name) { +void CalibrationFlowCoarseSavePage::set_default_options(const wxString& name) { + m_optimal_block_coarse->SetSelection(-1); + m_coarse_calc_result_text->SetLabelText(""); + m_checkBox_skip_calibration->SetValue(false); m_save_name_input->GetTextCtrl()->SetValue(name); + + wxCommandEvent event(wxEVT_TOGGLEBUTTON); + event.SetEventObject(m_checkBox_skip_calibration); + m_checkBox_skip_calibration->GetEventHandler()->ProcessEvent(event); } bool CalibrationFlowCoarseSavePage::is_skip_fine_calibration() { @@ -1272,7 +1279,7 @@ bool CalibrationFlowCoarseSavePage::Show(bool show) { assert(curr_obj->selected_cali_preset.size() <= 1); if (!curr_obj->selected_cali_preset.empty()) { wxString default_name = get_default_name(curr_obj->selected_cali_preset[0].name, CalibMode::Calib_Flow_Rate); - set_default_name(default_name); + set_default_options(default_name); set_curr_flow_ratio(curr_obj->cache_flow_ratio); } } @@ -1337,10 +1344,10 @@ void CalibrationFlowFineSavePage::create_page(wxWindow* parent) fine_block_items.Add(std::to_string(-9 + (i))); } m_optimal_block_fine->Set(fine_block_items); - auto fine_calc_result_text = new Label(parent, ""); + m_fine_calc_result_text = new Label(parent, ""); fine_value_sizer->Add(fine_value_text, 0, 0); fine_value_sizer->Add(m_optimal_block_fine, 0, 0); - fine_value_sizer->Add(fine_calc_result_text, 0); + fine_value_sizer->Add(m_fine_calc_result_text, 0); m_top_sizer->Add(fine_value_sizer, 0, 0, 0); m_top_sizer->AddSpacer(FromDIP(20)); @@ -1354,9 +1361,9 @@ void CalibrationFlowFineSavePage::create_page(wxWindow* parent) m_top_sizer->AddSpacer(FromDIP(20)); - m_optimal_block_fine->Bind(wxEVT_COMBOBOX, [this, fine_calc_result_text](auto& e) { + m_optimal_block_fine->Bind(wxEVT_COMBOBOX, [this](auto& e) { m_fine_flow_ratio = m_curr_flow_ratio * (100.0f + stof(m_optimal_block_fine->GetValue().ToStdString())) / 100.0f; - fine_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_fine_flow_ratio))); + m_fine_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_fine_flow_ratio))); }); m_action_panel = new CaliPageActionPanel(parent, m_cali_mode, CaliPageType::CALI_PAGE_FINE_SAVE); @@ -1371,7 +1378,9 @@ void CalibrationFlowFineSavePage::set_save_img() { } } -void CalibrationFlowFineSavePage::set_default_name(const wxString& name) { +void CalibrationFlowFineSavePage::set_default_options(const wxString &name) { + m_optimal_block_fine->SetSelection(-1); + m_fine_calc_result_text->SetLabelText(""); m_save_name_input->GetTextCtrl()->SetValue(name); } @@ -1402,7 +1411,7 @@ bool CalibrationFlowFineSavePage::Show(bool show) { assert(curr_obj->selected_cali_preset.size() <= 1); if (!curr_obj->selected_cali_preset.empty()) { wxString default_name = get_default_name(curr_obj->selected_cali_preset[0].name, CalibMode::Calib_Flow_Rate); - set_default_name(default_name); + set_default_options(default_name); set_curr_flow_ratio(curr_obj->cache_flow_ratio); } } diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.hpp b/src/slic3r/GUI/CalibrationWizardSavePage.hpp index 7a3b01c95..a65465d82 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.hpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.hpp @@ -223,7 +223,7 @@ public: void create_page(wxWindow* parent); void set_save_img(); - void set_default_name(const wxString& name); + void set_default_options(const wxString &name); bool is_skip_fine_calibration(); @@ -239,6 +239,9 @@ protected: ComboBox* m_optimal_block_coarse; TextInput* m_save_name_input; + Label* m_coarse_calc_result_text; + CheckBox* m_checkBox_skip_calibration; + bool m_skip_fine_calibration = false; float m_curr_flow_ratio; float m_coarse_flow_ratio; @@ -252,7 +255,7 @@ public: void create_page(wxWindow* parent); void set_save_img(); - void set_default_name(const wxString& name); + void set_default_options(const wxString &name); void set_curr_flow_ratio(float value); @@ -266,6 +269,8 @@ protected: ComboBox* m_optimal_block_fine; TextInput* m_save_name_input; + Label* m_fine_calc_result_text; + float m_curr_flow_ratio; float m_fine_flow_ratio; }; From caac160c7f59e103539746fbe351e97c2df329a8 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 29 Aug 2023 11:33:13 +0800 Subject: [PATCH 035/240] FIX: Crash when switch to the calibration page after binding the printer in device page jira: 4080 Change-Id: I8e712389bf619b177255111766c271cb9f1bf66e (cherry picked from commit a012b3641713d7f1e3ae60688c2db8054d3cd731) --- src/slic3r/GUI/CalibrationPanel.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/CalibrationPanel.cpp b/src/slic3r/GUI/CalibrationPanel.cpp index 1681572cd..e8970dccc 100644 --- a/src/slic3r/GUI/CalibrationPanel.cpp +++ b/src/slic3r/GUI/CalibrationPanel.cpp @@ -526,6 +526,14 @@ void CalibrationPanel::update_all() { if (!dev) return; obj = dev->get_selected_machine(); + // check valid machine + if (obj && dev->get_my_machine(obj->dev_id) == nullptr) { + dev->set_selected_machine(""); + if (m_agent) m_agent->set_user_selected_machine(""); + show_status((int) MONITOR_NO_PRINTER); + return; + } + // update current wizard only int curr_selected = m_tabpanel->GetSelection(); @@ -543,15 +551,6 @@ void CalibrationPanel::update_all() { } } - // check valid machine - if (obj && dev->get_my_machine(obj->dev_id) == nullptr) { - dev->set_selected_machine(""); - if (m_agent) - m_agent->set_user_selected_machine(""); - show_status((int)MONITOR_NO_PRINTER); - return; - } - if (wxGetApp().is_user_login()) { dev->check_pushing(); try { From f250d6f5c7a19bbda39b7fdafd614a9e8df94574 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 30 Aug 2023 15:17:57 +0800 Subject: [PATCH 036/240] FIX: CLI: fix the thumbnail color not correct issue JIRA: MAK-1812 Change-Id: I61832ffeea75b9423d85ccd81d5602a3e7d288b8 --- src/BambuStudio.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index bf385fce2..8d9e6f8d2 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -3500,33 +3500,43 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "glewInit Sucess." << std::endl; GLVolumeCollection glvolume_collection; Model &model = m_models[0]; - int extruder_id = 1; + int obj_extruder_id = 1, volume_extruder_id = 1; for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model.objects.size(); ++ obj_idx) { const ModelObject &model_object = *model.objects[obj_idx]; const ConfigOption* option = model_object.config.option("extruder"); if (option) - extruder_id = (dynamic_cast(option))->getInt(); + obj_extruder_id = (dynamic_cast(option))->getInt(); + else + obj_extruder_id = 1; for (int volume_idx = 0; volume_idx < (int)model_object.volumes.size(); ++ volume_idx) { const ModelVolume &model_volume = *model_object.volumes[volume_idx]; option = model_volume.config.option("extruder"); - if (option) extruder_id = (dynamic_cast(option))->getInt(); + if (option) + volume_extruder_id = (dynamic_cast(option))->getInt(); + else + volume_extruder_id = obj_extruder_id; + + BOOST_LOG_TRIVIAL(debug) << boost::format("volume %1%'s extruder_id %2%")%volume_idx %volume_extruder_id; //if (!model_volume.is_model_part()) // continue; for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) { const ModelInstance &model_instance = *model_object.instances[instance_idx]; glvolume_collection.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, "volume", true, false, true); //glvolume_collection.volumes.back()->geometry_id = key.geometry_id; - std::string color = filament_color?filament_color->get_at(extruder_id - 1):"#00FF00FF"; + std::string color = filament_color?filament_color->get_at(volume_extruder_id - 1):"#00FF00FF"; + + BOOST_LOG_TRIVIAL(debug) << boost::format("volume %1%'s color %2%")%volume_idx %color; unsigned char rgb_color[4] = {}; Slic3r::GUI::BitmapCache::parse_color4(color, rgb_color); - glvolume_collection.volumes.back()->set_render_color( float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, float(rgb_color[3]) / 255.f); std::array new_color; new_color[0] = float(rgb_color[0]) / 255.f; new_color[1] = float(rgb_color[1]) / 255.f; new_color[2] = float(rgb_color[2]) / 255.f; new_color[3] = float(rgb_color[3]) / 255.f; + + glvolume_collection.volumes.back()->set_render_color( new_color[0], new_color[1], new_color[2], new_color[3]); glvolume_collection.volumes.back()->set_color(new_color); glvolume_collection.volumes.back()->printable = model_instance.printable; } From ef2cc4b65c999183d9173c1701f3ce0deff5055d Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 4 Aug 2023 10:49:14 +0800 Subject: [PATCH 037/240] ENH: add load_model_objects_and_custom_gcodes Add cmd line option to pass layer change gcode. This is useful for lithophane auto change colors. Cmd: --custom-gcode custom_gcode_toolchange.json Examples of the input json file can be found in the jira. Jira: STUDIO-4070 Change-Id: I5beb5ff7d6d81028e95013e79f955e498cd3ba30 (cherry picked from commit bed6152b95c965ea87958d94ec069d8c883a8037) --- src/BambuStudio.cpp | 53 +++++++++++++++++++++++++++++++++++ src/libslic3r/Config.cpp | 1 + src/libslic3r/CustomGCode.hpp | 37 ++++++++++++++++++++++++ src/libslic3r/PrintConfig.cpp | 6 ++++ 4 files changed, 97 insertions(+) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 8d9e6f8d2..744b72c78 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -655,6 +655,11 @@ int CLI::run(int argc, char **argv) } } + std::string custom_gcode_file; + ConfigOptionString* custom_gcode_option = m_config.option("load_custom_gcodes"); + if (custom_gcode_option) + custom_gcode_file = custom_gcode_option->value; + /*for (const std::string& file : m_input_files) if (is_gcode_file(file) && boost::filesystem::exists(file)) { start_as_gcodeviewer = true; @@ -845,6 +850,41 @@ int CLI::run(int argc, char **argv) } //} + //load custom gcode file + std::map custom_gcodes_map; + if (!custom_gcode_file.empty()) { + // parse the custom gcode json file + std::string file = custom_gcode_file; + if(!boost::filesystem::exists(file)) { + boost::nowide::cerr << __FUNCTION__ << ": can not find custom_gcode file: " << file << std::endl; + record_exit_reson(outfile_dir, CLI_FILE_NOTFOUND, 0, cli_errors[CLI_FILE_NOTFOUND], sliced_info); + flush_and_exit(CLI_FILE_NOTFOUND); + } + try { + nlohmann::json jj; + boost::nowide::ifstream ifs(file); + ifs >> jj; + ifs.close(); + + int plate_id = 0; + if (plate_to_slice == 0) + plate_id = 0; + else + plate_id = plate_to_slice-1; + + CustomGCode::Info info; + info.from_json(jj); + + custom_gcodes_map.emplace(plate_id, info); + BOOST_LOG_TRIVIAL(info) << boost::format("load custom_gcode from file %1% success, store custom gcodes to plate %2%")%file %(plate_id+1); + } + catch (std::exception &ex) { + boost::nowide::cerr << __FUNCTION__<< ":Loading custom-gcode file \"" << file << "\" failed: " << ex.what() << std::endl; + record_exit_reson(outfile_dir, CLI_CONFIG_FILE_ERROR, 0, cli_errors[CLI_CONFIG_FILE_ERROR], sliced_info); + flush_and_exit(CLI_CONFIG_FILE_ERROR); + } + } + auto load_config_file = [config_substitution_rule](const std::string& file, DynamicPrintConfig& config, std::string& config_type, std::string& config_name, std::string& filament_id, std::string& config_from) { if (! boost::filesystem::exists(file)) { @@ -1774,6 +1814,19 @@ int CLI::run(int argc, char **argv) m_models.emplace_back(std::move(m)); } + //load custom gcodes into model if needed + if ((custom_gcodes_map.size() > 0)&&(m_models.size() > 0)) + { + m_models[0].plates_custom_gcodes = custom_gcodes_map; + /*m_models[0].plates_custom_gcodes.clear(); + + for (auto& custom_gcode: custom_gcodes_map) + { + BOOST_LOG_TRIVIAL(info) << boost::format("insert custom_gocde %1% into plate %2%")%plate_id; + m_models[0].plates_custom_gcodes.emplace(custom_gcode.first, custom_gcode.second); + }*/ + } + // Apply command line options to a more specific DynamicPrintConfig which provides normalize() // (command line options override --load files) m_print_config.apply(m_extra_config, true); diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 1753318f2..69630c16a 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -756,6 +756,7 @@ int ConfigBase::load_from_json(const std::string &file, ConfigSubstitutionContex try { boost::nowide::ifstream ifs(file); ifs >> j; + ifs.close(); const ConfigDef* config_def = this->def(); if (config_def == nullptr) { diff --git a/src/libslic3r/CustomGCode.hpp b/src/libslic3r/CustomGCode.hpp index 5b21bb45e..7d8c7d998 100644 --- a/src/libslic3r/CustomGCode.hpp +++ b/src/libslic3r/CustomGCode.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace Slic3r { @@ -43,6 +44,24 @@ struct Item std::string extra; // this field is used for the extra data like : // - G-code text for the Type::Custom // - message text for the Type::PausePrint + void from_json(const nlohmann::json& j) { + std::string type_str; + j.at("type").get_to(type_str); + std::map str2type = { {"ColorChange", ColorChange }, + {"PausePrint",PausePrint}, + {"ToolChange",ToolChange}, + {"Template",Template}, + {"Custom",Custom}, + {"Unknown",Unknown} }; + type = Unknown; + if (str2type.find(type_str) != str2type.end()) + type = str2type[type_str]; + j.at("print_z").get_to(print_z); + j.at("color").get_to(color); + j.at("extruder").get_to(extruder); + if(j.contains("extra")) + j.at("extra").get_to(extra); + } }; enum Mode @@ -71,6 +90,24 @@ struct Info (rhs.gcodes == this->gcodes ); } bool operator!=(const Info& rhs) const { return !(*this == rhs); } + + void from_json(const nlohmann::json& j) { + std::string mode_str; + if (j.contains("mode")) + j.at("mode").get_to(mode_str); + if (mode_str == "SingleExtruder") mode = SingleExtruder; + else if (mode_str == "MultiAsSingle") mode = MultiAsSingle; + else if (mode_str == "MultiExtruder") mode = MultiExtruder; + else mode = Undef; + + auto j_gcodes = j.at("gcodes"); + gcodes.reserve(j_gcodes.size()); + for (auto& jj : j_gcodes) { + Item item; + item.from_json(jj); + gcodes.push_back(item); + } + } }; // If loaded configuration has a "colorprint_heights" option (if it was imported from older Slicer), diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index cfad2c210..b2d587ea0 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5247,6 +5247,12 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver."); def->min = 0;*/ #endif /* _MSC_VER */ + + def = this->add("load_custom_gcodes", coString); + def->label = L("Load custom gcode"); + def->tooltip = L("Load custom gcode from json"); + def->cli_params = "custom_gcode_toolchange.json"; + def->set_default_value(new ConfigOptionString()); } const CLIActionsConfigDef cli_actions_config_def; From b0e20ad68eace60f99a4fda802ff0c54373f4f17 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 25 Aug 2023 11:22:39 +0800 Subject: [PATCH 038/240] FIX: crash when multi-select connectors with different shape Jira: 3916 Change-Id: Ic011827e5d301f91f684039a85b228196be1ba98 (cherry picked from commit 53705d8541a6d97ada278ea9310ac6e5e1ac45c7) --- src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp index c851535d6..ba9780501 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp @@ -1710,7 +1710,8 @@ bool GLGizmoAdvancedCut::render_combo(const std::string &label, const std::vecto size_t selection_out = selection_idx; - if (ImGui::BBLBeginCombo(("##" + label).c_str(), lines[selection_idx].c_str(), 0)) { + const char* selected_str = (selection_idx >= 0 && selection_idx < int(lines.size())) ? lines[selection_idx].c_str() : ""; + if (ImGui::BBLBeginCombo(("##" + label).c_str(), selected_str, 0)) { for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) { ImGui::PushID(int(line_idx)); if (ImGui::Selectable("", line_idx == selection_idx)) From f78b0675254471c789c6d74d66bbc43ee248966b Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Wed, 30 Aug 2023 16:01:57 +0800 Subject: [PATCH 039/240] FIX: Text dragging of special file doesn't work Jira: 4271 Change-Id: I0b2e33ac0cf4919bea93732151529deac3b7e9ed (cherry picked from commit f1534363d63c5f8b8ddb00edb8edef6b0376b54d) --- src/slic3r/GUI/Gizmos/GLGizmoText.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp index 907848e50..553b477b3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp @@ -1002,8 +1002,9 @@ bool GLGizmoText::update_text_positions(const std::vector& texts) Vec3d temp_position = m_mouse_position_world; Vec3d temp_normal = m_mouse_normal_world; - Vec3d cut_plane = Vec3d::UnitY(); - if (temp_normal != Vec3d::UnitZ()) { + Vec3d cut_plane = Vec3d::UnitY(); + double epson = 1e-6; + if (!(abs(temp_normal.x()) <= epson && abs(temp_normal.y()) <= epson && abs(temp_normal.z()) > epson)) { // temp_normal != Vec3d::UnitZ() Vec3d v_plane = temp_normal.cross(Vec3d::UnitZ()); cut_plane = v_plane.cross(temp_normal); } @@ -1092,6 +1093,9 @@ bool GLGizmoText::update_text_positions(const std::vector& texts) MeshSlicingParams slicing_params; slicing_params.trafo = transfo * mi->get_transformation().get_matrix() /** volume->get_transformation().get_matrix()*/; + // for debug + // its_write_obj(slice_meshs.its, "D:/debug_files/mesh.obj"); + // generate polygons const Polygons temp_polys = slice_mesh(slice_meshs.its, click_point.z(), slicing_params); From 50226b8b234e347eb800563dc425b666f66dbcc7 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Thu, 31 Aug 2023 17:16:03 +0800 Subject: [PATCH 040/240] FIX: Incorrect exploded view after split to objects and modify the incorrect assemble view after cut Jira: 4182 Change-Id: I813a9179c54d544e745153186e09a4d82fc50dbc (cherry picked from commit f60762ddefcaa9ba6bd9d61fb328fc42f1a2c5d0) --- src/libslic3r/Model.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index e927a9d5d..aa120dba1 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -2051,6 +2051,9 @@ static void reset_instance_transformation(ModelObject* object, size_t src_instan const Transform3d &assemble_matrix = obj_instance->get_assemble_transformation().get_matrix(); const Transform3d &instance_inverse_matrix = instance_transformation_copy.get_matrix().inverse(); Transform3d new_instance_inverse_matrix = instance_inverse_matrix * obj_instance->get_transformation().get_matrix(true).inverse(); + if (place_on_cut) { // reset the rotation of cut plane + new_instance_inverse_matrix = new_instance_inverse_matrix * Transformation(cut_matrix).get_matrix(true, false, true, true).inverse(); + } Transform3d new_assemble_transform = assemble_matrix * new_instance_inverse_matrix; obj_instance->set_assemble_from_transform(new_assemble_transform); } @@ -2368,6 +2371,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects) Transform3d new_instance_inverse_matrix = instance_inverse_matrix * model_instance->get_transformation().get_matrix(true).inverse(); Transform3d new_assemble_transform = assemble_matrix * new_instance_inverse_matrix; model_instance->set_assemble_from_transform(new_assemble_transform); + model_instance->set_offset_to_assembly(new_vol->get_offset()); } new_vol->set_offset(Vec3d::Zero()); From 1426913752608d08790651eeaeb2895caf68d74c Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 1 Sep 2023 10:00:58 +0800 Subject: [PATCH 041/240] FIX: No progress bar is displayed during manual calibration Jira: 3789 Change-Id: I4d56839136f4590b6df384f2287e9565e5e61afa (cherry picked from commit ddb0c38fc0ed4b42bc5a132c2b2d907084576d41) --- src/slic3r/GUI/Jobs/PrintJob.cpp | 12 +++++++++++- src/slic3r/GUI/Jobs/PrintJob.hpp | 3 +++ src/slic3r/Utils/CalibUtils.cpp | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index 5760bf724..920b4270c 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -31,7 +31,8 @@ static wxString sending_over_cloud_str = _L("Sending print job through clou PrintJob::PrintJob(std::shared_ptr pri, Plater* plater, std::string dev_id) : PlaterJob{ std::move(pri), plater }, - m_dev_id(dev_id) + m_dev_id(dev_id), + m_is_calibration_task(false) { m_print_job_completed_id = plater->get_print_finished_event(); } @@ -280,6 +281,11 @@ void PrintJob::process() if (params.preset_name.empty() && m_print_type == "from_normal") { params.preset_name = wxString::Format("%s_plate_%d", m_project_name, curr_plate_idx).ToStdString(); } if (params.project_name.empty()) {params.project_name = m_project_name;} + if (m_is_calibration_task) { + params.project_name = m_project_name; + params.origin_model_id = ""; + } + wxString error_text; wxString msg_text; @@ -534,5 +540,9 @@ void PrintJob::connect_to_local_mqtt() this->update_status(0, wxEmptyString); } +void PrintJob::set_calibration_task(bool is_calibration) +{ + m_is_calibration_task = is_calibration; +} }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/PrintJob.hpp b/src/slic3r/GUI/Jobs/PrintJob.hpp index 97616f4af..8fa902f7d 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.hpp +++ b/src/slic3r/GUI/Jobs/PrintJob.hpp @@ -63,6 +63,8 @@ public: std::string m_print_type; std::string m_dst_path; + bool m_is_calibration_task = false; + int m_print_from_sdc_plate_idx = 0; bool m_local_use_ssl_for_mqtt { true }; @@ -106,6 +108,7 @@ public: void connect_to_local_mqtt(); wxString get_http_error_msg(unsigned int status, std::string body); std::string truncate_string(const std::string& str, size_t maxLength); + void set_calibration_task(bool is_calibration); }; diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index 9c0d8d380..fade099cc 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -980,6 +980,7 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, std::string &error_m CalibMode cali_mode = calib_info.params.mode; print_job->m_project_name = get_calib_mode_name(cali_mode, flow_ratio_mode); + print_job->set_calibration_task(true); print_job->has_sdcard = obj_->has_sdcard(); print_job->set_print_config(MachineBedTypeString[bed_type], true, false, false, false, true); From c5882a18276f2855bcda8503272a0ba2e8eb6a61 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 23 Aug 2023 09:35:19 +0800 Subject: [PATCH 042/240] FIX: prefer local tunnel for P1P liveview Change-Id: Ia4f52a8bd2b8bcf20740b2c7043e437d56a4a5b1 --- src/slic3r/GUI/MediaPlayCtrl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 33e41d31c..c7edab033 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -153,7 +153,7 @@ void MediaPlayCtrl::Play() m_button_play->SetIcon("media_stop"); NetworkAgent *agent = wxGetApp().getAgent(); std::string agent_version = agent ? agent->get_version() : ""; - if (m_lan_proto > 0 && (m_lan_mode ||!m_remote_support) && !m_disable_lan && !m_lan_ip.empty()) { + if (m_lan_proto > 0 && (m_lan_mode || m_lan_proto == 1 || !m_remote_support) && !m_disable_lan && !m_lan_ip.empty()) { m_disable_lan = m_remote_support && !m_lan_mode; // try remote next time if (m_lan_proto == 1) m_url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd + "&device=" + m_machine + "&version=" + agent_version; From 2b1712bb9d229cb86204cb3d5f68c7e371dbe373 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Mon, 7 Aug 2023 19:17:21 +0800 Subject: [PATCH 043/240] FIX: [STUDIO-3891] move printer image to profiles path Change-Id: I40755109fcab4532cfe7d2314accc7d9f61c249c (cherry picked from commit 0398a5c5d842629b7aedfc989602d78324a64934) --- .../BBL}/Bambu Lab P1P_cover.png | Bin .../BBL}/Bambu Lab P1S_cover.png | Bin .../BBL}/Bambu Lab X1 Carbon_cover.png | Bin .../printer => profiles/BBL}/Bambu Lab X1_cover.png | Bin 4 files changed, 0 insertions(+), 0 deletions(-) rename resources/{web/image/printer => profiles/BBL}/Bambu Lab P1P_cover.png (100%) rename resources/{web/image/printer => profiles/BBL}/Bambu Lab P1S_cover.png (100%) rename resources/{web/image/printer => profiles/BBL}/Bambu Lab X1 Carbon_cover.png (100%) rename resources/{web/image/printer => profiles/BBL}/Bambu Lab X1_cover.png (100%) diff --git a/resources/web/image/printer/Bambu Lab P1P_cover.png b/resources/profiles/BBL/Bambu Lab P1P_cover.png similarity index 100% rename from resources/web/image/printer/Bambu Lab P1P_cover.png rename to resources/profiles/BBL/Bambu Lab P1P_cover.png diff --git a/resources/web/image/printer/Bambu Lab P1S_cover.png b/resources/profiles/BBL/Bambu Lab P1S_cover.png similarity index 100% rename from resources/web/image/printer/Bambu Lab P1S_cover.png rename to resources/profiles/BBL/Bambu Lab P1S_cover.png diff --git a/resources/web/image/printer/Bambu Lab X1 Carbon_cover.png b/resources/profiles/BBL/Bambu Lab X1 Carbon_cover.png similarity index 100% rename from resources/web/image/printer/Bambu Lab X1 Carbon_cover.png rename to resources/profiles/BBL/Bambu Lab X1 Carbon_cover.png diff --git a/resources/web/image/printer/Bambu Lab X1_cover.png b/resources/profiles/BBL/Bambu Lab X1_cover.png similarity index 100% rename from resources/web/image/printer/Bambu Lab X1_cover.png rename to resources/profiles/BBL/Bambu Lab X1_cover.png From f66cb2bb690fa3661c858657d4e83954d263e50c Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 8 Aug 2023 14:05:50 +0800 Subject: [PATCH 044/240] FIX: [STUDIO-3891] check config update after sync Change-Id: I82e409f0d3649a371cbe0f8ee9a5f9ad1a267fc8 (cherry picked from commit a5bb7694cf874f125ee9d1169d20710fd4a27443) --- src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/Utils/PresetUpdater.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index ff4b36e98..819eaca2b 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -619,6 +619,7 @@ public: bool check_networking_version(); void cancel_networking_install(); void restart_networking(); + void check_config_updates_from_updater() { check_updates(false); } private: int updating_bambu_networking(); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index f49da0063..acc0ec4f7 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1293,8 +1293,14 @@ void PresetUpdater::sync(std::string http_url, std::string language, std::string this->p->sync_version(); if (p->cancel) return; - if (!vendors.empty()) + if (!vendors.empty()) { this->p->sync_config(http_url, std::move(vendors)); + if (p->cancel) + return; + GUI::wxGetApp().CallAfter([] { + GUI::wxGetApp().check_config_updates_from_updater(); + }); + } if (p->cancel) return; this->p->sync_plugins(http_url, plugin_version); From be19c137fed07130ff7a03bc69c7d57dfeb021c7 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Thu, 31 Aug 2023 11:12:56 +0800 Subject: [PATCH 045/240] NEW: generate small thumbnail size in 3mf JIRA: STUDIO-4282 Change-Id: I2f6e35bd643e950d15dcfacb9f6ecae8f8bd80fa Signed-off-by: Stone Li --- src/libslic3r/Format/bbs_3mf.cpp | 33 +++++++++++++++++++++++++++++--- src/libslic3r/Format/bbs_3mf.hpp | 4 ++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index dbc0563a4..e8a3a0b34 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -5215,7 +5215,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) bool _add_content_types_file_to_archive(mz_zip_archive& archive); - bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, const char* local_path, int index); + bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, const char* local_path, int index, bool generate_small_thumbnail = false); bool _add_calibration_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, int index); bool _add_bbox_file_to_archive(mz_zip_archive& archive, const PlateBBoxData& id_bboxes, int index); bool _add_relationships_file_to_archive(mz_zip_archive & archive, @@ -5460,9 +5460,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) { if (thumbnail_data[index]->is_valid()) { - if (!_add_thumbnail_file_to_archive(archive, *thumbnail_data[index], "Metadata/plate", index)) { + if (!_add_thumbnail_file_to_archive(archive, *thumbnail_data[index], "Metadata/plate", index, true)) { return false; } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" <<__LINE__ << boost::format(",add thumbnail %1%'s data into 3mf")%(index+1); thumbnail_status[index] = true; } @@ -5839,7 +5840,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return true; } - bool _BBS_3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, const char* local_path, int index) + bool _BBS_3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data, const char* local_path, int index, bool generate_small_thumbnail) { bool res = false; @@ -5856,6 +5857,32 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to add thumbnail file to archive\n"); } + if (generate_small_thumbnail && thumbnail_data.is_valid()) { + //generate small size of thumbnail + std::vector small_pixels; + small_pixels.resize(PLATE_THUMBNAIL_SMALL_WIDTH * PLATE_THUMBNAIL_SMALL_HEIGHT * 4); + /* step width and step height */ + int sw = thumbnail_data.width / PLATE_THUMBNAIL_SMALL_WIDTH; + int sh = thumbnail_data.height / PLATE_THUMBNAIL_SMALL_HEIGHT; + for (int i = 0; i < thumbnail_data.width; i += sw) { + for (int j = 0; j < thumbnail_data.height; j += sh) { + memcpy((void*)&small_pixels[4*(i / sw * PLATE_THUMBNAIL_SMALL_WIDTH + j / sh)], thumbnail_data.pixels.data() + 4*(i * thumbnail_data.width + j), 4); + } + } + size_t small_png_size = 0; + void* small_png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)small_pixels.data(), PLATE_THUMBNAIL_SMALL_WIDTH, PLATE_THUMBNAIL_SMALL_HEIGHT, 4, &small_png_size, MZ_DEFAULT_COMPRESSION, 1); + if (png_data != nullptr) { + std::string thumbnail_name = (boost::format("%1%_%2%_small.png") % local_path % (index + 1)).str(); + res = mz_zip_writer_add_mem(&archive, thumbnail_name.c_str(), (const void*)small_png_data, small_png_size, MZ_NO_COMPRESSION); + mz_free(small_png_data); + } + + if (!res) { + add_error("Unable to add small thumbnail file to archive"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to add small thumbnail file to archive\n"); + } + } + return res; } diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index 8b8a53a71..607e301ba 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -14,6 +14,10 @@ class Preset; struct FilamentInfo; struct ThumbnailData; + +#define PLATE_THUMBNAIL_SMALL_WIDTH 128 +#define PLATE_THUMBNAIL_SMALL_HEIGHT 128 + #define GCODE_FILE_FORMAT "Metadata/plate_%1%.gcode" #define THUMBNAIL_FILE_FORMAT "Metadata/plate_%1%.png" #define TOP_FILE_FORMAT "Metadata/top_%1%.png" From 9b20cad55e45c8f613abe43a61f752a996c5b362 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Tue, 1 Aug 2023 10:14:22 +0800 Subject: [PATCH 046/240] ENH: add support for chamber_temp and exhaust_fan Support controlling chamebr temperature and exhaust fan for air filtration Signed-off-by: xun.zhang Change-Id: I31627ce4f8acce99e132b0436ab7dcd0bcebf81d --- src/libslic3r/GCode.cpp | 42 ++++++++++++++++++++ src/libslic3r/GCode.hpp | 1 + src/libslic3r/GCode/GCodeProcessor.cpp | 50 +++++++++++++++++++++--- src/libslic3r/GCode/GCodeProcessor.hpp | 16 +++++++- src/libslic3r/GCodeWriter.cpp | 29 ++++++++++++++ src/libslic3r/GCodeWriter.hpp | 2 + src/libslic3r/Preset.cpp | 4 +- src/libslic3r/Print.cpp | 7 +++- src/libslic3r/PrintConfig.cpp | 54 ++++++++++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 7 ++++ src/slic3r/GUI/Tab.cpp | 30 +++++++++++++- 11 files changed, 232 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 223771568..857e35382 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -571,6 +571,15 @@ static std::vector get_path_of_change_filament(const Print& print) check_add_eol(start_filament_gcode_str); } + // deal exhaust fan speed + { + const bool activate_air_filtration = gcodegen.config().activate_air_filtration.get_at(new_extruder_id); + if (activate_air_filtration&&gcodegen.config().support_air_filtration.getBool()) { + start_filament_gcode_str += GCodeWriter::set_exhaust_fan(gcodegen.config().during_print_exhaust_fan_speed.get_at(new_extruder_id),false); + ((start_filament_gcode_str +=';')+=GCodeProcessor::reserved_tag(GCodeProcessor::ETags::During_Print_Exhaust_Fan)) += '\n'; + } + } + // Insert the end filament, toolchange, and start filament gcode into the generated gcode. DynamicConfig config; config.set_key_value("filament_end_gcode", new ConfigOptionString(end_filament_gcode_str)); @@ -1773,6 +1782,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); } + auto chamber_temp_vec = m_config.option("chamber_temperatures")->values; + int max_chamber_temp = *std::max_element(chamber_temp_vec.begin(), chamber_temp_vec.end()); { int curr_bed_type = m_config.curr_bed_type.getInt(); @@ -1815,6 +1826,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato if (print.config().gcode_flavor != gcfKlipper) { // Set bed temperature if the start G-code does not contain any bed temp control G-codes. this->_print_first_layer_bed_temperature(file, print, machine_start_gcode, initial_extruder_id, true); + if (m_config.option("chamber_temp_control")->getBool()) { + this->_print_chamber_temperature(file, print, machine_start_gcode,max_chamber_temp, true); + } // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, false); } @@ -1827,6 +1841,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_writer.set_current_position_clear(false); m_start_gcode_filament = GCodeProcessor::get_gcode_last_filament(machine_start_gcode); + // Process filament-specific gcode. /* if (has_wipe_tower) { // Wipe tower will control the extruder switching, it will call the filament_start_gcode. @@ -1837,6 +1852,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } */ this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, true); + + bool activate_air_filtration = *std::max_element(m_config.activate_air_filtration.values.begin(), m_config.activate_air_filtration.values.end()) && m_config.support_air_filtration.getBool(); + + if (activate_air_filtration && m_config.activate_air_filtration.get_at(initial_extruder_id)) { + file.write(m_writer.set_exhaust_fan(m_config.during_print_exhaust_fan_speed.get_at(initial_extruder_id), true)); + } + print.throw_if_canceled(); // Set other general things. @@ -2103,6 +2125,16 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write(m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% file.write(m_writer.postamble()); + file.write(m_writer.set_chamber_temperature(0, false)); //close chamber_temperature + + + if (activate_air_filtration) { + int complete_print_exhaust_fan_speed = 0; + for (size_t i = 0; i < m_config.activate_air_filtration.size(); ++i) + if (m_config.activate_air_filtration.get_at(i)) + complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(i)); + file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed,true)); + } // adds tags for time estimators file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str()); file.write_format("; EXECUTABLE_BLOCK_END\n\n"); @@ -2367,6 +2399,16 @@ int GCode::get_bed_temperature(const int extruder_id, const bool is_first_layer, return bed_temp_opt->get_at(extruder_id); } +void GCode::_print_chamber_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode,int chamber_temperature, bool wait) +{ + int temp_by_gcode = -1; + bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 141, 191, false, temp_by_gcode); + + std::string set_chamber_temp_gcode = m_writer.set_chamber_temperature(chamber_temperature, wait); + if (!temp_set_by_gcode) + file.write(set_chamber_temp_gcode); +} + // Write 1st layer bed temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. // M140 - Set Extruder Temperature diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 5f7b00154..6451af850 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -507,6 +507,7 @@ private: std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); void print_machine_envelope(GCodeOutputStream &file, Print &print); + void _print_chamber_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode,int chamber_temperature, bool wait); void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); // On the first printing layer. This flag triggers first layer speeds. diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 71e6c32af..cdb409617 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -57,7 +57,8 @@ const std::vector GCodeProcessor::Reserved_Tags = { "_GP_FIRST_LINE_M73_PLACEHOLDER", "_GP_LAST_LINE_M73_PLACEHOLDER", "_GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER", - "_GP_TOTAL_LAYER_NUMBER_PLACEHOLDER" + "_GP_TOTAL_LAYER_NUMBER_PLACEHOLDER", + "_DURING_PRINT_EXHAUST_FAN" }; const std::string GCodeProcessor::Flush_Start_Tag = " FLUSH_START"; @@ -362,6 +363,12 @@ void GCodeProcessor::TimeProcessor::reset() machine_limits = MachineEnvelopeConfig(); filament_load_times = 0.0f; filament_unload_times = 0.0f; + + exhaust_fan_info.activate = false; + exhaust_fan_info.print_end_exhaust_fan_speed = 0; + exhaust_fan_info.print_end_exhaust_fan_time = 0; + insert_fan_control_flag = false; + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { machines[i].reset(); } @@ -406,6 +413,14 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st return std::string(line_M73); }; + auto format_line_exhaust_fan_control = [](const std::string& mask,int fan_index,int percent) { + char line_fan[64] = { 0 }; + sprintf(line_fan,mask.c_str(), + std::to_string(fan_index).c_str(), + std::to_string(int((percent/100.0)*255)).c_str()); + return std::string(line_fan); + }; + auto format_time_float = [](float time) { return Slic3r::float_to_string_decimal_point(time, 2); }; @@ -516,7 +531,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st // add lines M73 to exported gcode auto process_line_move = [ // Lambdas, mostly for string formatting, all with an empty capture block. - time_in_minutes, format_time_float, format_line_M73_main, format_line_M73_stop_int, format_line_M73_stop_float, time_in_last_minute, + time_in_minutes, format_time_float, format_line_M73_main, format_line_M73_stop_int, format_line_M73_stop_float, time_in_last_minute,format_line_exhaust_fan_control, &self = std::as_const(*this), // Caches, to be modified &g1_times_cache_it, &last_exported_main, &last_exported_stop, @@ -535,6 +550,14 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st if (it != machine.g1_times_cache.end() && it->id == g1_lines_counter) { std::pair to_export_main = { int(100.0f * it->elapsed_time / machine.time), time_in_minutes(machine.time - it->elapsed_time) }; + + if (self.exhaust_fan_info.activate && !self.insert_fan_control_flag && machine.time - it->elapsed_time < self.exhaust_fan_info.print_end_exhaust_fan_time ) { + //insert fan + self.insert_fan_control_flag = true; + export_line += format_line_exhaust_fan_control("M106 P%s S%s ;open exhaust fan before print end \n", 3, self.exhaust_fan_info.print_end_exhaust_fan_speed); + ++exported_lines_count; + } + if (last_exported_main[i] != to_export_main) { export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(), to_export_main.first, to_export_main.second); @@ -629,6 +652,9 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st gcode_line.insert(gcode_line.end(), it, it_end); if (eol) { ++line_id; + // disable origin exhaust_fan_speed during print + if (insert_fan_control_flag&&gcode_line.find(reserved_tag(ETags::During_Print_Exhaust_Fan)) != std::string::npos) + gcode_line.clear(); gcode_line += "\n"; // replace placeholder lines @@ -962,6 +988,18 @@ void GCodeProcessor::apply_config(const PrintConfig& config) const ConfigOptionBool* spiral_vase = config.option("spiral_mode"); if (spiral_vase != nullptr) m_spiral_vase_active = spiral_vase->value; + + + for (size_t i = 0; i < config.activate_air_filtration.values.size(); ++i) { + if (config.activate_air_filtration.get_at(i)) { + m_exhaust_fan_info.print_end_exhaust_fan_speed = std::max(m_exhaust_fan_info.print_end_exhaust_fan_speed, config.end_print_exhaust_fan_speed.get_at(i)); + m_exhaust_fan_info.print_end_exhaust_fan_time = std::max(m_exhaust_fan_info.print_end_exhaust_fan_time, config.end_print_exhaust_fan_time.get_at(i)); + } + } + + const ConfigOptionBools* activate_air_filtration = config.option("activate_air_filtration"); + if (activate_air_filtration != nullptr) + m_exhaust_fan_info.activate = *std::max_element(activate_air_filtration->values.begin(), activate_air_filtration->values.end())&&config.support_air_filtration.getBool(); } void GCodeProcessor::apply_config(const DynamicPrintConfig& config) @@ -1459,9 +1497,11 @@ void GCodeProcessor::finalize(bool post_process) m_height_compare.output(); m_width_compare.output(); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING - - if (post_process) + if (post_process){ + //control chamber fan + m_time_processor.exhaust_fan_info = m_exhaust_fan_info; m_time_processor.post_process(m_result.filename, m_result.moves, m_result.lines_ends, m_layer_id); + } #if ENABLE_GCODE_VIEWER_STATISTICS m_result.time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - m_start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -1897,7 +1937,7 @@ template // Legacy conversion, which is costly due to having to make a copy of the string before conversion. try { assert(sv.size() < 1024); - assert(sv.data() != nullptr); + assert(sv.data() != nullptr); std::string str { sv }; size_t read = 0; if constexpr (std::is_same_v) diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 09e6d1164..90e009de2 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -253,7 +253,8 @@ namespace Slic3r { First_Line_M73_Placeholder, Last_Line_M73_Placeholder, Estimated_Printing_Time_Placeholder, - Total_Layer_Number_Placeholder + Total_Layer_Number_Placeholder, + During_Print_Exhaust_Fan }; static const std::string& reserved_tag(ETags tag) { return Reserved_Tags[static_cast(tag)]; } @@ -353,6 +354,12 @@ namespace Slic3r { float time() const; }; + struct ExhaustFanInfo { + bool activate{ false }; + int print_end_exhaust_fan_speed{0}; + int print_end_exhaust_fan_time{0}; + }; + private: struct TimeMachine { @@ -448,6 +455,11 @@ namespace Slic3r { // Additional load / unload times for a filament exchange sequence. float filament_load_times; float filament_unload_times; + + // start fan x second before print complete + ExhaustFanInfo exhaust_fan_info; + mutable bool insert_fan_control_flag{false}; + std::array(PrintEstimatedStatistics::ETimeMode::Count)> machines; void reset(); @@ -613,7 +625,7 @@ namespace Slic3r { private: GCodeReader m_parser; - + ExhaustFanInfo m_exhaust_fan_info; EUnits m_units; EPositioningType m_global_positioning_type; EPositioningType m_e_local_positioning_type; diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 57f9f1775..1cd448dd4 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -146,6 +146,25 @@ std::string GCodeWriter::set_bed_temperature(int temperature, bool wait) return gcode.str(); } +std::string GCodeWriter::set_chamber_temperature(int temperature, bool wait) +{ + std::string code, comment; + std::ostringstream gcode; + + if (wait) + { + gcode<<"M106 P2 S255 \n"; + gcode<<"M191 S"< s_Preset_filament_options { "temperature_vitrification", "reduce_fan_stop_start_freq", "slow_down_for_layer_cooling", "fan_min_speed", "fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "full_fan_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed", "filament_start_gcode", "filament_end_gcode", + //exhaust fan control + "activate_air_filtration","during_print_exhaust_fan_speed","end_print_exhaust_fan_speed","end_print_exhaust_fan_time","complete_print_exhaust_fan_speed", // Retract overrides "filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel", "filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe", @@ -850,7 +852,7 @@ static std::vector s_Preset_printer_options { "silent_mode", // BBS "scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode", - "nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", + "nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types","chamber_temp_control","support_air_filtration", //OrcaSlicer "host_type", "print_host", "printhost_apikey", "print_host_webui", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 58efafed8..099c5c298 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -163,7 +163,12 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "inner_wall_acceleration", "sparse_infill_acceleration", "exclude_object", - "use_relative_e_distances" + "use_relative_e_distances", + "activate_air_filtration", + "during_print_exhaust_fan_speed", + "end_print_exhaust_fan_speed", + "end_print_exhaust_fan_time", + "complete_print_exhaust_fan_speed" }; static std::unordered_set steps_ignore; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b2d587ea0..007645fb4 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -953,6 +953,47 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionString()); def->cli = ConfigOptionDef::nocli; + def = this->add("activate_air_filtration",coBools); + def->label = L("Activate air filtration"); + def->tooltip = L("Acivate for better air filtration"); + def->mode = comSimple; + def->set_default_value(new ConfigOptionBools{false}); + + def = this->add("during_print_exhaust_fan_speed", coInts); + def->label = L("Fan speed"); + def->tooltip=L("Speed of exhuast fan during printing.This speed will overwrite the speed in filament custom gcode"); + def->sidetext = L("%"); + def->min=0; + def->max=100; + def->mode = comSimple; + def->set_default_value(new ConfigOptionInts{60}); + + def = this->add("end_print_exhaust_fan_speed", coInts); + def->label = L("Fan speed"); + def->tooltip=L("Speed of exhuast fan before printing completes"); + def->sidetext = L("%"); + def->min=0; + def->max=100; + def->mode = comSimple; + def->set_default_value(new ConfigOptionInts{60}); + + + def = this->add("end_print_exhaust_fan_time", coInts); + def->label = L("Time"); + def->tooltip=L("open exhuast fan x seconds before printing completes"); + def->sidetext = L("s"); + def->mode = comSimple; + def->set_default_value(new ConfigOptionInts{300}); + + def = this->add("complete_print_exhaust_fan_speed", coInts); + def->label = L("Fan speed"); + def->sidetext = L("%"); + def->tooltip=L("Speed of exhuast fan after printing completes"); + def->min=0; + def->max=100; + def->mode = comSimple; + def->set_default_value(new ConfigOptionInts{80}); + def = this->add("close_fan_the_first_x_layers", coInts); def->label = L("No cooling for the first"); def->tooltip = L("Close all cooling fan for the first certain layers. Cooling fan of the first layer used to be closed " @@ -1704,6 +1745,19 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionBool(false)); + def =this->add("chamber_temp_control",coBool); + def->label=L("Support control chamber temperature"); + def->tooltip=L("Enable this option if machine support controlling chamber temperature"); + def->mode=comDevelop; + def->set_default_value(new ConfigOptionBool(false)); + def->readonly=false; + + def =this->add("support_air_filtration",coBool); + def->label=L("Support air filtration"); + def->tooltip=L("Decide whether support activating air filtration"); + def->mode=comDevelop; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("gcode_flavor", coEnum); def->label = L("G-code flavor"); def->tooltip = L("What kind of gcode the printer is compatible with"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index dee5c2bf1..59dec9f25 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -876,6 +876,8 @@ PRINT_CONFIG_CLASS_DEFINE( //BBS ((ConfigOptionEnum, nozzle_type)) ((ConfigOptionBool, auxiliary_fan)) + ((ConfigOptionBool, chamber_temp_control)) + ((ConfigOptionBool, support_air_filtration)) ((ConfigOptionBool, accel_to_decel_enable)) ((ConfigOptionPercent, accel_to_decel_factor)) ((ConfigOptionEnumsGeneric, extruder_type)) @@ -912,6 +914,11 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloat, default_acceleration)) ((ConfigOptionFloat, inner_wall_acceleration)) ((ConfigOptionFloatOrPercent, sparse_infill_acceleration)) + ((ConfigOptionBools, activate_air_filtration)) + ((ConfigOptionInts, during_print_exhaust_fan_speed)) + ((ConfigOptionInts, end_print_exhaust_fan_speed)) + ((ConfigOptionInts, end_print_exhaust_fan_time)) + ((ConfigOptionInts, complete_print_exhaust_fan_speed)) ((ConfigOptionInts, close_fan_the_first_x_layers)) ((ConfigOptionEnum, draft_shield)) ((ConfigOptionFloat, extruder_clearance_height_to_rod))//BBs diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 889bd5fab..36819b60f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2744,6 +2744,22 @@ void TabFilament::build() optgroup = page->new_optgroup(L("Auxiliary part cooling fan"), L"param_cooling_fan"); optgroup->append_single_option_line("additional_cooling_fan_speed"); + optgroup = page->new_optgroup(L("Exhaust fan")); + + optgroup->append_single_option_line("activate_air_filtration"); + + line = {L("During print"), L("")}; + line.append_option(optgroup->get_option("during_print_exhaust_fan_speed")); + optgroup->append_line(line); + + line = {L("End of print"), L("")}; + line.append_option(optgroup->get_option("end_print_exhaust_fan_speed")); + line.append_option(optgroup->get_option("end_print_exhaust_fan_time")); + optgroup->append_line(line); + + line = {L("Complete print"), L("")}; + line.append_option(optgroup->get_option("complete_print_exhaust_fan_speed")); + optgroup->append_line(line); //BBS add_filament_overrides_page(); #if 0 @@ -2851,6 +2867,14 @@ void TabFilament::toggle_options() bool has_enable_overhang_bridge_fan = m_config->opt_bool("enable_overhang_bridge_fan", 0); for (auto el : { "overhang_fan_speed", "overhang_fan_threshold" }) toggle_option(el, has_enable_overhang_bridge_fan); + bool support_air_filtration = this->m_preset_bundle->printers.get_selected_preset().config.opt_bool("support_air_filtration"); + //this->m_preset_bundle. + //toggle_line("activate_air_filtration",support_air_filtration); + //m_config; + for (auto elem : { "during_print_exhaust_fan_speed","end_print_exhaust_fan_speed","end_print_exhaust_fan_time","complete_print_exhaust_fan_speed" }) + //toggle_line(elem, m_config->opt_bool("activate_air_filtration",0)&&support_air_filtration); + toggle_line(elem, m_config->opt_bool("activate_air_filtration",0)); + } if (m_active_page->title() == "Filament") { @@ -2862,7 +2886,7 @@ void TabFilament::toggle_options() toggle_line("pressure_advance", true); toggle_option("pressure_advance", m_config->opt_bool("enable_pressure_advance", 0)); } - toggle_line("chamber_temperatures", !is_BBL_printer); + for (auto el : {"cool_plate_temp", "cool_plate_temp_initial_layer", "eng_plate_temp", "eng_plate_temp_initial_layer", "textured_plate_temp", "textured_plate_temp_initial_layer"}) toggle_line(el, is_BBL_printer); @@ -3081,6 +3105,8 @@ void TabPrinter::build_fff() optgroup = page->new_optgroup(L("Accessory") /*, L"param_accessory"*/); optgroup->append_single_option_line("nozzle_type"); optgroup->append_single_option_line("auxiliary_fan"); + optgroup->append_single_option_line("chamber_temp_control"); + optgroup->append_single_option_line("support_air_filtration"); const int gcode_field_height = 15; // 150 page = add_options_page(L("Machine gcode"), "cog"); @@ -3637,6 +3663,8 @@ void TabPrinter::toggle_options() toggle_option("gcode_flavor", !is_BBL_printer); toggle_option("use_relative_e_distances", !is_BBL_printer); + toggle_option("chamber_temp_control",!is_BBL_printer); + toggle_option("support_air_filtration",!is_BBL_printer); auto flavor = m_config->option>("gcode_flavor")->value; bool is_marlin_flavor = flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware; // Disable silent mode for non-marlin firmwares. From 8d2a5dedc1c32e2ff69d2edf7bd6ebf24171c920 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Mon, 14 Aug 2023 19:59:45 +0800 Subject: [PATCH 047/240] FIX: use extruder list to decide chamber temp As title.Use the same way to decide exhaust fan. Removes end print exhaust fan control. Signed-off-by: xun.zhang Change-Id: Id14f3d91171b81239b336ef879061c6de7d68edf --- .../BBL/machine/fdm_machine_common.json | 1 + src/libslic3r/GCode.cpp | 59 ++++++++----------- src/libslic3r/GCode.hpp | 1 - src/libslic3r/GCode/GCodeProcessor.cpp | 26 -------- src/libslic3r/GCode/GCodeProcessor.hpp | 10 ---- src/libslic3r/Preset.cpp | 4 +- src/libslic3r/Print.cpp | 3 - src/libslic3r/PrintConfig.cpp | 28 ++------- src/libslic3r/PrintConfig.hpp | 4 +- src/slic3r/GUI/Tab.cpp | 20 +++---- 10 files changed, 44 insertions(+), 112 deletions(-) diff --git a/resources/profiles/BBL/machine/fdm_machine_common.json b/resources/profiles/BBL/machine/fdm_machine_common.json index 4fb2bb4a0..032684e2f 100644 --- a/resources/profiles/BBL/machine/fdm_machine_common.json +++ b/resources/profiles/BBL/machine/fdm_machine_common.json @@ -3,6 +3,7 @@ "name": "fdm_machine_common", "from": "system", "instantiation": "false", + "support_chamber_temp_control": "0", "printer_technology": "FFF", "deretraction_speed": [ "40" diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 857e35382..5bf816760 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -571,15 +571,6 @@ static std::vector get_path_of_change_filament(const Print& print) check_add_eol(start_filament_gcode_str); } - // deal exhaust fan speed - { - const bool activate_air_filtration = gcodegen.config().activate_air_filtration.get_at(new_extruder_id); - if (activate_air_filtration&&gcodegen.config().support_air_filtration.getBool()) { - start_filament_gcode_str += GCodeWriter::set_exhaust_fan(gcodegen.config().during_print_exhaust_fan_speed.get_at(new_extruder_id),false); - ((start_filament_gcode_str +=';')+=GCodeProcessor::reserved_tag(GCodeProcessor::ETags::During_Print_Exhaust_Fan)) += '\n'; - } - } - // Insert the end filament, toolchange, and start filament gcode into the generated gcode. DynamicConfig config; config.set_key_value("filament_end_gcode", new ConfigOptionString(end_filament_gcode_str)); @@ -1782,12 +1773,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); } - auto chamber_temp_vec = m_config.option("chamber_temperatures")->values; - int max_chamber_temp = *std::max_element(chamber_temp_vec.begin(), chamber_temp_vec.end()); + int max_chamber_temp = 0; { int curr_bed_type = m_config.curr_bed_type.getInt(); - int max_chamber_temp = *std::max_element(m_config.chamber_temperatures.values.begin(), m_config.chamber_temperatures.values.end()); + for (const auto& extruder : m_writer.extruders()) + max_chamber_temp = std::max(max_chamber_temp, m_config.chamber_temperatures.get_at(extruder.id())); std::string first_layer_bed_temp_str; const ConfigOptionInts* first_bed_temp_opt = m_config.option(get_bed_temp_1st_layer_key((BedType)curr_bed_type)); @@ -1798,6 +1789,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("bed_temperature_initial_layer_single", new ConfigOptionInt(first_bed_temp_opt->get_at(initial_extruder_id))); m_placeholder_parser.set("bed_temperature_initial_layer_vector", new ConfigOptionString("")); m_placeholder_parser.set("chamber_temperature", new ConfigOptionInts({max_chamber_temp})); + m_placeholder_parser.set("chamber_temperatures", new ConfigOptionInts({ max_chamber_temp })); //support variables `first_layer_temperature` and `first_layer_bed_temperature` m_placeholder_parser.set("first_layer_bed_temperature", new ConfigOptionInts(*first_bed_temp_opt)); @@ -1805,6 +1797,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("max_print_height", new ConfigOptionInt(m_config.printable_height)); m_placeholder_parser.set("z_offset", new ConfigOptionFloat(0.0f)); m_placeholder_parser.set("plate_name", new ConfigOptionString(print.get_plate_name())); + + //add during_print_exhaust_fan_speed + std::vector during_print_exhaust_fan_speed_num; + during_print_exhaust_fan_speed_num.reserve(m_config.during_print_exhaust_fan_speed.size()); + for (const auto& item : m_config.during_print_exhaust_fan_speed.values) + during_print_exhaust_fan_speed_num.emplace_back((int)(item / 100.0 * 255)); + m_placeholder_parser.set("during_print_exhaust_fan_speed_num",new ConfigOptionInts(during_print_exhaust_fan_speed_num)); //BBS: calculate the volumetric speed of outer wall. Ignore pre-object setting and multi-filament, and just use the default setting { float filament_max_volumetric_speed = m_config.option("filament_max_volumetric_speed")->get_at(initial_non_support_extruder_id); @@ -1826,9 +1825,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato if (print.config().gcode_flavor != gcfKlipper) { // Set bed temperature if the start G-code does not contain any bed temp control G-codes. this->_print_first_layer_bed_temperature(file, print, machine_start_gcode, initial_extruder_id, true); - if (m_config.option("chamber_temp_control")->getBool()) { - this->_print_chamber_temperature(file, print, machine_start_gcode,max_chamber_temp, true); - } // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, false); } @@ -1853,9 +1849,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato */ this->_print_first_layer_extruder_temperatures(file, print, machine_start_gcode, initial_extruder_id, true); - bool activate_air_filtration = *std::max_element(m_config.activate_air_filtration.values.begin(), m_config.activate_air_filtration.values.end()) && m_config.support_air_filtration.getBool(); - - if (activate_air_filtration && m_config.activate_air_filtration.get_at(initial_extruder_id)) { + if (m_config.support_air_filtration.getBool() && m_config.activate_air_filtration.get_at(initial_extruder_id)) { file.write(m_writer.set_exhaust_fan(m_config.during_print_exhaust_fan_speed.get_at(initial_extruder_id), true)); } @@ -2128,13 +2122,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato file.write(m_writer.set_chamber_temperature(0, false)); //close chamber_temperature - if (activate_air_filtration) { - int complete_print_exhaust_fan_speed = 0; - for (size_t i = 0; i < m_config.activate_air_filtration.size(); ++i) - if (m_config.activate_air_filtration.get_at(i)) - complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(i)); - file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed,true)); - } // adds tags for time estimators file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str()); file.write_format("; EXECUTABLE_BLOCK_END\n\n"); @@ -2154,6 +2141,19 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato //if (print.m_print_statistics.total_toolchanges > 0) // file.write_format("; total filament change = %i\n", print.m_print_statistics.total_toolchanges); + bool activate_air_filtration = false; + for (const auto& extruder : m_writer.extruders()) + activate_air_filtration |= m_config.activate_air_filtration.get_at(extruder.id()); + activate_air_filtration &= m_config.support_air_filtration.getBool(); + + if (activate_air_filtration) { + int complete_print_exhaust_fan_speed = 0; + for (const auto& extruder : m_writer.extruders()) + if (m_config.activate_air_filtration.get_at(extruder.id())) + complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(extruder.id())); + file.write(m_writer.set_exhaust_fan(complete_print_exhaust_fan_speed, true)); + } + print.throw_if_canceled(); } @@ -2399,15 +2399,6 @@ int GCode::get_bed_temperature(const int extruder_id, const bool is_first_layer, return bed_temp_opt->get_at(extruder_id); } -void GCode::_print_chamber_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode,int chamber_temperature, bool wait) -{ - int temp_by_gcode = -1; - bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 141, 191, false, temp_by_gcode); - - std::string set_chamber_temp_gcode = m_writer.set_chamber_temperature(chamber_temperature, wait); - if (!temp_set_by_gcode) - file.write(set_chamber_temp_gcode); -} // Write 1st layer bed temperatures into the G-code. // Only do that if the start G-code does not already contain any M-code controlling an extruder temperature. diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 6451af850..5f7b00154 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -507,7 +507,6 @@ private: std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); void print_machine_envelope(GCodeOutputStream &file, Print &print); - void _print_chamber_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode,int chamber_temperature, bool wait); void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); // On the first printing layer. This flag triggers first layer speeds. diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index cdb409617..2ff3dc4ce 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -364,10 +364,6 @@ void GCodeProcessor::TimeProcessor::reset() filament_load_times = 0.0f; filament_unload_times = 0.0f; - exhaust_fan_info.activate = false; - exhaust_fan_info.print_end_exhaust_fan_speed = 0; - exhaust_fan_info.print_end_exhaust_fan_time = 0; - insert_fan_control_flag = false; for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { machines[i].reset(); @@ -551,13 +547,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st std::pair to_export_main = { int(100.0f * it->elapsed_time / machine.time), time_in_minutes(machine.time - it->elapsed_time) }; - if (self.exhaust_fan_info.activate && !self.insert_fan_control_flag && machine.time - it->elapsed_time < self.exhaust_fan_info.print_end_exhaust_fan_time ) { - //insert fan - self.insert_fan_control_flag = true; - export_line += format_line_exhaust_fan_control("M106 P%s S%s ;open exhaust fan before print end \n", 3, self.exhaust_fan_info.print_end_exhaust_fan_speed); - ++exported_lines_count; - } - if (last_exported_main[i] != to_export_main) { export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(), to_export_main.first, to_export_main.second); @@ -652,9 +641,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st gcode_line.insert(gcode_line.end(), it, it_end); if (eol) { ++line_id; - // disable origin exhaust_fan_speed during print - if (insert_fan_control_flag&&gcode_line.find(reserved_tag(ETags::During_Print_Exhaust_Fan)) != std::string::npos) - gcode_line.clear(); gcode_line += "\n"; // replace placeholder lines @@ -990,16 +976,6 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_spiral_vase_active = spiral_vase->value; - for (size_t i = 0; i < config.activate_air_filtration.values.size(); ++i) { - if (config.activate_air_filtration.get_at(i)) { - m_exhaust_fan_info.print_end_exhaust_fan_speed = std::max(m_exhaust_fan_info.print_end_exhaust_fan_speed, config.end_print_exhaust_fan_speed.get_at(i)); - m_exhaust_fan_info.print_end_exhaust_fan_time = std::max(m_exhaust_fan_info.print_end_exhaust_fan_time, config.end_print_exhaust_fan_time.get_at(i)); - } - } - - const ConfigOptionBools* activate_air_filtration = config.option("activate_air_filtration"); - if (activate_air_filtration != nullptr) - m_exhaust_fan_info.activate = *std::max_element(activate_air_filtration->values.begin(), activate_air_filtration->values.end())&&config.support_air_filtration.getBool(); } void GCodeProcessor::apply_config(const DynamicPrintConfig& config) @@ -1498,8 +1474,6 @@ void GCodeProcessor::finalize(bool post_process) m_width_compare.output(); #endif // ENABLE_GCODE_VIEWER_DATA_CHECKING if (post_process){ - //control chamber fan - m_time_processor.exhaust_fan_info = m_exhaust_fan_info; m_time_processor.post_process(m_result.filename, m_result.moves, m_result.lines_ends, m_layer_id); } #if ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 90e009de2..4ee1ce700 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -354,11 +354,6 @@ namespace Slic3r { float time() const; }; - struct ExhaustFanInfo { - bool activate{ false }; - int print_end_exhaust_fan_speed{0}; - int print_end_exhaust_fan_time{0}; - }; private: struct TimeMachine @@ -456,10 +451,6 @@ namespace Slic3r { float filament_load_times; float filament_unload_times; - // start fan x second before print complete - ExhaustFanInfo exhaust_fan_info; - mutable bool insert_fan_control_flag{false}; - std::array(PrintEstimatedStatistics::ETimeMode::Count)> machines; void reset(); @@ -625,7 +616,6 @@ namespace Slic3r { private: GCodeReader m_parser; - ExhaustFanInfo m_exhaust_fan_info; EUnits m_units; EPositioningType m_global_positioning_type; EPositioningType m_e_local_positioning_type; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 19cbda769..d4b7a3cc6 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -822,7 +822,7 @@ static std::vector s_Preset_filament_options { "fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "full_fan_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed", "filament_start_gcode", "filament_end_gcode", //exhaust fan control - "activate_air_filtration","during_print_exhaust_fan_speed","end_print_exhaust_fan_speed","end_print_exhaust_fan_time","complete_print_exhaust_fan_speed", + "activate_air_filtration","during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed", // Retract overrides "filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel", "filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe", @@ -852,7 +852,7 @@ static std::vector s_Preset_printer_options { "silent_mode", // BBS "scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode", - "nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types","chamber_temp_control","support_air_filtration", + "nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types","support_chamber_temp_control","support_air_filtration", //OrcaSlicer "host_type", "print_host", "printhost_apikey", "print_host_webui", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 099c5c298..c05960baf 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -166,8 +166,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "use_relative_e_distances", "activate_air_filtration", "during_print_exhaust_fan_speed", - "end_print_exhaust_fan_speed", - "end_print_exhaust_fan_time", "complete_print_exhaust_fan_speed" }; @@ -205,7 +203,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n osteps.emplace_back(posSlice); } else if ( opt_key == "print_sequence" - || opt_key == "chamber_temperatures" || opt_key == "filament_type" || opt_key == "nozzle_temperature_initial_layer" || opt_key == "filament_minimal_purge_on_wipe_tower" diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 007645fb4..4b27f0d53 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -968,23 +968,6 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionInts{60}); - def = this->add("end_print_exhaust_fan_speed", coInts); - def->label = L("Fan speed"); - def->tooltip=L("Speed of exhuast fan before printing completes"); - def->sidetext = L("%"); - def->min=0; - def->max=100; - def->mode = comSimple; - def->set_default_value(new ConfigOptionInts{60}); - - - def = this->add("end_print_exhaust_fan_time", coInts); - def->label = L("Time"); - def->tooltip=L("open exhuast fan x seconds before printing completes"); - def->sidetext = L("s"); - def->mode = comSimple; - def->set_default_value(new ConfigOptionInts{300}); - def = this->add("complete_print_exhaust_fan_speed", coInts); def->label = L("Fan speed"); def->sidetext = L("%"); @@ -1745,9 +1728,9 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionBool(false)); - def =this->add("chamber_temp_control",coBool); + def =this->add("support_chamber_temp_control",coBool); def->label=L("Support control chamber temperature"); - def->tooltip=L("Enable this option if machine support controlling chamber temperature"); + def->tooltip=L("This option is enabled if machine support controlling chamber temperature"); def->mode=comDevelop; def->set_default_value(new ConfigOptionBool(false)); def->readonly=false; @@ -3144,11 +3127,12 @@ void PrintConfigDef::init_fff_params() def = this->add("chamber_temperatures", coInts); def->label = L("Chamber temperature"); - def->tooltip = L("Target chamber temperature"); + def->tooltip = L("By opening chamber_temperature compensation, the heating components will operate to elevate the chamber temperature." + "This can help suppress or reduce warping for high-temperature materials and potentially lead to higher interlayer bonding strength"); def->sidetext = L("°C"); - def->full_label = L("Chamber temperature"); + def->full_label = L("Chamber temperature during print.0 means do not open compensation.Don't open it for low-temperature filaments like PLA, PETG, TPU"); def->min = 0; - def->max = 60; + def->max = 70; def->set_default_value(new ConfigOptionInts{0}); def = this->add("nozzle_temperature", coInts); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 59dec9f25..9d761e578 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -876,7 +876,7 @@ PRINT_CONFIG_CLASS_DEFINE( //BBS ((ConfigOptionEnum, nozzle_type)) ((ConfigOptionBool, auxiliary_fan)) - ((ConfigOptionBool, chamber_temp_control)) + ((ConfigOptionBool, support_chamber_temp_control)) ((ConfigOptionBool, support_air_filtration)) ((ConfigOptionBool, accel_to_decel_enable)) ((ConfigOptionPercent, accel_to_decel_factor)) @@ -916,8 +916,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloatOrPercent, sparse_infill_acceleration)) ((ConfigOptionBools, activate_air_filtration)) ((ConfigOptionInts, during_print_exhaust_fan_speed)) - ((ConfigOptionInts, end_print_exhaust_fan_speed)) - ((ConfigOptionInts, end_print_exhaust_fan_time)) ((ConfigOptionInts, complete_print_exhaust_fan_speed)) ((ConfigOptionInts, close_fan_the_first_x_layers)) ((ConfigOptionEnum, draft_shield)) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 36819b60f..d3d9f90d0 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2752,10 +2752,6 @@ void TabFilament::build() line.append_option(optgroup->get_option("during_print_exhaust_fan_speed")); optgroup->append_line(line); - line = {L("End of print"), L("")}; - line.append_option(optgroup->get_option("end_print_exhaust_fan_speed")); - line.append_option(optgroup->get_option("end_print_exhaust_fan_time")); - optgroup->append_line(line); line = {L("Complete print"), L("")}; line.append_option(optgroup->get_option("complete_print_exhaust_fan_speed")); @@ -2867,12 +2863,11 @@ void TabFilament::toggle_options() bool has_enable_overhang_bridge_fan = m_config->opt_bool("enable_overhang_bridge_fan", 0); for (auto el : { "overhang_fan_speed", "overhang_fan_threshold" }) toggle_option(el, has_enable_overhang_bridge_fan); + bool support_air_filtration = this->m_preset_bundle->printers.get_selected_preset().config.opt_bool("support_air_filtration"); - //this->m_preset_bundle. - //toggle_line("activate_air_filtration",support_air_filtration); - //m_config; - for (auto elem : { "during_print_exhaust_fan_speed","end_print_exhaust_fan_speed","end_print_exhaust_fan_time","complete_print_exhaust_fan_speed" }) - //toggle_line(elem, m_config->opt_bool("activate_air_filtration",0)&&support_air_filtration); + toggle_line("activate_air_filtration",support_air_filtration); + + for (auto elem : { "during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed" }) toggle_line(elem, m_config->opt_bool("activate_air_filtration",0)); } @@ -2887,6 +2882,9 @@ void TabFilament::toggle_options() toggle_option("pressure_advance", m_config->opt_bool("enable_pressure_advance", 0)); } + bool support_chamber_temp_control = this->m_preset_bundle->printers.get_selected_preset().config.opt_bool("support_chamber_temp_control"); + toggle_line("chamber_temperatures", support_chamber_temp_control); + for (auto el : {"cool_plate_temp", "cool_plate_temp_initial_layer", "eng_plate_temp", "eng_plate_temp_initial_layer", "textured_plate_temp", "textured_plate_temp_initial_layer"}) toggle_line(el, is_BBL_printer); @@ -3105,7 +3103,7 @@ void TabPrinter::build_fff() optgroup = page->new_optgroup(L("Accessory") /*, L"param_accessory"*/); optgroup->append_single_option_line("nozzle_type"); optgroup->append_single_option_line("auxiliary_fan"); - optgroup->append_single_option_line("chamber_temp_control"); + optgroup->append_single_option_line("support_chamber_temp_control"); optgroup->append_single_option_line("support_air_filtration"); const int gcode_field_height = 15; // 150 @@ -3663,7 +3661,7 @@ void TabPrinter::toggle_options() toggle_option("gcode_flavor", !is_BBL_printer); toggle_option("use_relative_e_distances", !is_BBL_printer); - toggle_option("chamber_temp_control",!is_BBL_printer); + toggle_option("support_chamber_temp_control",!is_BBL_printer); toggle_option("support_air_filtration",!is_BBL_printer); auto flavor = m_config->option>("gcode_flavor")->value; bool is_marlin_flavor = flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware; From caf30b21eae78296823f1a7e5668cf71804c4d0b Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Mon, 21 Aug 2023 11:28:39 +0800 Subject: [PATCH 048/240] ENH: rename chamber_temperatures in placeholder Signed-off-by: xun.zhang Change-Id: Id4d853d479cfb9b6c3fda177891f11a34f7d29e8 --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 5bf816760..e540727da 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1789,7 +1789,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("bed_temperature_initial_layer_single", new ConfigOptionInt(first_bed_temp_opt->get_at(initial_extruder_id))); m_placeholder_parser.set("bed_temperature_initial_layer_vector", new ConfigOptionString("")); m_placeholder_parser.set("chamber_temperature", new ConfigOptionInts({max_chamber_temp})); - m_placeholder_parser.set("chamber_temperatures", new ConfigOptionInts({ max_chamber_temp })); + m_placeholder_parser.set("overall_chamber_temperature", new ConfigOptionInt(max_chamber_temp)); //support variables `first_layer_temperature` and `first_layer_bed_temperature` m_placeholder_parser.set("first_layer_bed_temperature", new ConfigOptionInts(*first_bed_temp_opt)); From 1da049921c490de9ffe855c7ffd0a952cb5a3a1a Mon Sep 17 00:00:00 2001 From: gerrit Date: Tue, 5 Sep 2023 22:44:49 +0800 Subject: [PATCH 049/240] ci: update build version to 01.07.04.53 Change-Id: Ief5f21d2dd449125ecdbd2cc786d9669731488b2 --- version.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.inc b/version.inc index dd147739c..159325ebc 100644 --- a/version.inc +++ b/version.inc @@ -12,4 +12,4 @@ set(BBL_INTERNAL_TESTING "1") endif() # The build_version should start from 50 in master branch -set(SLIC3R_VERSION "01.07.04.52") +set(SLIC3R_VERSION "01.07.04.53") From 18a3b8b757823034feecc5483971195b0686216f Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Tue, 5 Sep 2023 12:00:03 +0800 Subject: [PATCH 050/240] FIX: slider show custom gcode issue Jira: STUDIO-4316 Change-Id: I576e35861cd6306b67a0b5bd098eb2a739faf75b (cherry picked from commit 59f80dad826ac81cf66a22a7e35fee87d94f0287) --- src/slic3r/GUI/IMSlider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/IMSlider.cpp b/src/slic3r/GUI/IMSlider.cpp index ccfa7a546..2cd0fe514 100644 --- a/src/slic3r/GUI/IMSlider.cpp +++ b/src/slic3r/GUI/IMSlider.cpp @@ -234,7 +234,7 @@ void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z) m_ticks.ticks.clear(); const std::vector &heights = custom_gcode_per_print_z.gcodes; for (auto h : heights) { - int tick = get_tick_from_value(h.print_z); + int tick = get_tick_from_value(h.print_z, true); if (tick >= 0) m_ticks.ticks.emplace(TickCode{tick, h.type, h.extruder, h.color, h.extra}); } From 4bb913bcc88336983679429defa83346d56844b9 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 6 Sep 2023 20:15:44 +0800 Subject: [PATCH 051/240] ENH: Support: set the float air warning also to non-critical JIRA: STUDIO-4217 Change-Id: Ic587acde0a566e4ea5217a5dc4f1ab8b6b155f5c --- src/libslic3r/PrintObject.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 9ae6843f6..d75fa7ec3 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -477,10 +477,7 @@ void PrintObject::generate_support_material() {LargeOverhang,L("large overhangs")} }; std::string warning_message = format(L("It seems object %s has %s. Please re-orient the object or enable support generation."), this->model_object()->name, reasons[sntype]); - if (SharpTail == sntype) - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); - else - this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); } #if 0 From 048ff596c98f01f473a829c3243353e23da522b8 Mon Sep 17 00:00:00 2001 From: gerrit Date: Thu, 7 Sep 2023 09:22:02 +0800 Subject: [PATCH 052/240] ci: update build version to 01.07.04.54 Change-Id: Ia78cc31809b92d0feaa9fee3d288a62c91ab00b4 --- version.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.inc b/version.inc index 159325ebc..fda23e790 100644 --- a/version.inc +++ b/version.inc @@ -12,4 +12,4 @@ set(BBL_INTERNAL_TESTING "1") endif() # The build_version should start from 50 in master branch -set(SLIC3R_VERSION "01.07.04.53") +set(SLIC3R_VERSION "01.07.04.54") From 607f4ca52681dbefb911ad2167c72f0477375ddb Mon Sep 17 00:00:00 2001 From: tao wang Date: Thu, 7 Sep 2023 11:39:32 +0800 Subject: [PATCH 053/240] ENH:update text that cannot connect to the printer Change-Id: Id408fc0b9dd2e71d8928f842e1c34caad9469a68 --- src/slic3r/GUI/SelectMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index d0031cbcd..76578e2f8 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -1205,7 +1205,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) m_sizer_prepare->Add(0, 0, 1, wxTOP, FromDIP(12)); auto hyperlink_sizer = new wxBoxSizer( wxHORIZONTAL ); - m_hyperlink = new wxHyperlinkCtrl(m_panel_prepare, wxID_ANY, _L("Can't connect to the printer"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE); + m_hyperlink = new wxHyperlinkCtrl(m_panel_prepare, wxID_ANY, _L("Click here if you can't connect to the printer"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE); hyperlink_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5); m_sizer_prepare->Add(hyperlink_sizer, 0, wxALIGN_CENTER | wxALL, 5); From 570a98fd4533d19fd123362cd7e8b25d3b3c460b Mon Sep 17 00:00:00 2001 From: Merikesh Dev Date: Fri, 1 Sep 2023 20:30:14 -0700 Subject: [PATCH 054/240] ENH: Format: Add ModelIO support on macOS Github pull request: #2439 Change-Id: I4464a735a0a20b3e8103a344a64500b3d14b70e6 --- src/libslic3r/CMakeLists.txt | 8 ++++++++ src/libslic3r/Format/ModelIO.hpp | 19 +++++++++++++++++++ src/libslic3r/Format/ModelIO.mm | 27 +++++++++++++++++++++++++++ src/libslic3r/Model.cpp | 17 +++++++++++++++++ src/slic3r/GUI/GUI_App.cpp | 10 +++++++++- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/libslic3r/Format/ModelIO.hpp create mode 100644 src/libslic3r/Format/ModelIO.mm diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index bdeae1897..f55363519 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -390,6 +390,8 @@ set(lisbslic3r_sources if (APPLE) list(APPEND lisbslic3r_sources MacUtils.mm + Format/ModelIO.hpp + Format/ModelIO.mm ) endif () @@ -505,6 +507,12 @@ if(NOT WIN32) endif() endif() +if (APPLE) + find_library(FOUNDATION Foundation REQUIRED) + find_library(MODELIO ModelIO REQUIRED) + target_link_libraries(libslic3r ${FOUNDATION} ${MODELIO}) +endif () + if (TARGET OpenVDB::openvdb) target_link_libraries(libslic3r OpenVDB::openvdb) endif() diff --git a/src/libslic3r/Format/ModelIO.hpp b/src/libslic3r/Format/ModelIO.hpp new file mode 100644 index 000000000..a0751f2d9 --- /dev/null +++ b/src/libslic3r/Format/ModelIO.hpp @@ -0,0 +1,19 @@ +#include + +namespace Slic3r { + /** + * Uses ModelIO to convert supported model types to a temporary STL + * that can then be consumed by the existing STL loader + * @param input_file The File to load + * @return Path to the temporary file, or an empty string if conversion failed + */ + std::string make_temp_stl_with_modelio(const std::string &input_file); + + /** + * Convenience function to delete the file. + * No return value since success isn't required + * @param temp_file File path to delete + */ + void delete_temp_file(const std::string &temp_file); +} + diff --git a/src/libslic3r/Format/ModelIO.mm b/src/libslic3r/Format/ModelIO.mm new file mode 100644 index 000000000..7d1d4e726 --- /dev/null +++ b/src/libslic3r/Format/ModelIO.mm @@ -0,0 +1,27 @@ +#include "ModelIO.hpp" +#import + +namespace Slic3r { + + std::string make_temp_stl_with_modelio(const std::string &input_file) + { + NSURL *input_url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:input_file.c_str()]]; + MDLAsset *asset = [[MDLAsset alloc] initWithURL:input_url]; + + NSString *tmp_file_name = [[[NSUUID UUID] UUIDString] stringByAppendingPathExtension:@"stl"]; + NSURL *tmp_file_url = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:tmp_file_name]]; + + if ([asset exportAssetToURL:tmp_file_url]) { + std::string output_file = std::string([[tmp_file_url path] UTF8String]); + return output_file; + } + + return std::string(); + } + void delete_temp_file(const std::string &temp_file) + { + NSString *file_path = [NSString stringWithUTF8String:temp_file.c_str()]; + [[NSFileManager defaultManager] removeItemAtPath:file_path error:NULL]; + } + +} // namespace Slic3r \ No newline at end of file diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index aa120dba1..9a0cc777a 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -40,6 +40,11 @@ // Transtltion #include "I18N.hpp" +// ModelIO support +#ifdef __APPLE__ +#include "Format/ModelIO.hpp" +#endif + #define _L(s) Slic3r::I18N::translate(s) namespace Slic3r { @@ -200,6 +205,18 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c //FIXME options & LoadStrategy::CheckVersion ? //BBS: is_xxx is used for is_bbs_3mf when load 3mf result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, is_xxx, file_version, proFn, options, project, plate_id); +#ifdef __APPLE__ + else if (boost::algorithm::iends_with(input_file, ".usd") || boost::algorithm::iends_with(input_file, ".usda") || + boost::algorithm::iends_with(input_file, ".usdc") || boost::algorithm::iends_with(input_file, ".usdz") || + boost::algorithm::iends_with(input_file, ".abc") || boost::algorithm::iends_with(input_file, ".ply")) { + std::string temp_stl = make_temp_stl_with_modelio(input_file); + if (temp_stl.empty()) { + throw Slic3r::RuntimeError("Failed to convert asset to STL via ModelIO."); + } + result = load_stl(temp_stl.c_str(), &model); + delete_temp_file(temp_stl); + } +#endif else throw Slic3r::RuntimeError(_L("Unknown file format. Input file must have .stl, .obj, .amf(.xml) extension.")); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e4a4df832..fa7272999 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -739,7 +739,11 @@ static const FileWildcards file_wildcards_by_type[FT_SIZE] = { /* FT_AMF */ { "AMF files"sv, { ".amf"sv, ".zip.amf"sv, ".xml"sv } }, /* FT_3MF */ { "3MF files"sv, { ".3mf"sv } }, /* FT_GCODE */ { "G-code files"sv, { ".gcode"sv } }, +#ifdef __APPLE__ + /* FT_MODEL */ { "Supported files"sv, { ".3mf"sv, ".stl"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv , ".usd"sv, ".usda"sv, ".usdc"sv, ".usdz"sv, ".abc"sv, ".ply"sv} }, +#else /* FT_MODEL */ {"Supported files"sv, {".3mf"sv, ".stl"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv }}, +#endif /* FT_PROJECT */ { "Project files"sv, { ".3mf"sv} }, /* FT_GALLERY */ { "Known files"sv, { ".stl"sv, ".obj"sv } }, @@ -3641,7 +3645,11 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const { input_files.Clear(); wxFileDialog dialog(parent ? parent : GetTopWindow(), - _L("Choose one or more files (3mf/step/stl/svg/obj/amf):"), +#ifdef __APPLE__ + _L("Choose one or more files (3mf/step/stl/svg/obj/amf/usd*/abc/ply):"), +#else + _L("Choose one or more files (3mf/step/stl/svg/obj/amf):"), +#endif from_u8(app_config->get_last_dir()), "", file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); From 1fe94590bd63b528de5fe902382553724534e6bd Mon Sep 17 00:00:00 2001 From: Merikesh Dev Date: Sun, 3 Sep 2023 12:57:37 -0700 Subject: [PATCH 055/240] =?UTF-8?q?Fix=EF=BC=9A=20fix=20the=20formatting?= =?UTF-8?q?=20on=20=5FL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Github pull request: #2439 --- src/slic3r/GUI/GUI_App.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index fa7272999..133ec8cbd 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3648,7 +3648,7 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const #ifdef __APPLE__ _L("Choose one or more files (3mf/step/stl/svg/obj/amf/usd*/abc/ply):"), #else - _L("Choose one or more files (3mf/step/stl/svg/obj/amf):"), + _L("Choose one or more files (3mf/step/stl/svg/obj/amf):"), #endif from_u8(app_config->get_last_dir()), "", file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); From d3166fda13e96cfe130c6d3b12390817ae154ee4 Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Wed, 23 Aug 2023 17:07:03 +0800 Subject: [PATCH 056/240] ENH: update slice status after insert all custom gcode Jira: STUDIO-4155 Change-Id: Ia088a471477895c92eaeac6f26052e7ec0f060a9 --- src/slic3r/GUI/MainFrame.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 9 +++++---- src/slic3r/GUI/Plater.hpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b83c4affa..980e50ad5 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1557,7 +1557,7 @@ wxBoxSizer* MainFrame::create_side_tools() m_slice_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { //this->m_plater->select_view_3D("Preview"); - m_plater->update(); + m_plater->update(false, true); if (m_slice_select == eSliceAll) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_ALL)); else diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f17de8a71..eabc620ad 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2569,7 +2569,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // update slice and print button wxGetApp().mainframe->update_slice_print_status(MainFrame::SlicePrintEventType::eEventSliceUpdate, true, false); - update(); + set_need_update(true); }); } if (wxGetApp().is_gcode_viewer()) @@ -9475,16 +9475,17 @@ void Plater::add_file() } } -void Plater::update(bool conside_update_flag) +void Plater::update(bool conside_update_flag, bool force_background_processing_update) { + unsigned int flag = force_background_processing_update ? (unsigned int)Plater::priv::UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE : 0; if (conside_update_flag) { if (need_update()) { - p->update(); + p->update(flag); p->set_need_update(false); } } else - p->update(); + p->update(flag); } void Plater::object_list_changed() { p->object_list_changed(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 97038a189..d3942ac50 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -268,7 +268,7 @@ public: const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; } - void update(bool conside_update_flag = false); + void update(bool conside_update_flag = false, bool force_background_processing_update = false); //BBS void object_list_changed(); void stop_jobs(); From db038d88fa142c47f93213e247209bdc080d91a8 Mon Sep 17 00:00:00 2001 From: "maosheng.wei" Date: Mon, 26 Jun 2023 09:57:39 +0800 Subject: [PATCH 057/240] ENH: [STUDIO-3151] Optimize scoring entry Jira: STUDIO-3151 Change-Id: I6ffd236faea7de9f1e35b77f818f926f2477939a (cherry picked from commit 5591f9d472bc7de45cc73acdd79e09bfc2549d89) --- resources/images/score_star_dark.svg | 3 + resources/images/score_star_light.svg | 3 + resources/images/single_little_photo.svg | 6 + src/slic3r/GUI/StatusPanel.cpp | 711 +++++++++++++++++++++-- src/slic3r/GUI/StatusPanel.hpp | 88 ++- src/slic3r/Utils/NetworkAgent.cpp | 40 ++ src/slic3r/Utils/NetworkAgent.hpp | 11 + 7 files changed, 812 insertions(+), 50 deletions(-) create mode 100644 resources/images/score_star_dark.svg create mode 100644 resources/images/score_star_light.svg create mode 100644 resources/images/single_little_photo.svg diff --git a/resources/images/score_star_dark.svg b/resources/images/score_star_dark.svg new file mode 100644 index 000000000..d703eafb7 --- /dev/null +++ b/resources/images/score_star_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/score_star_light.svg b/resources/images/score_star_light.svg new file mode 100644 index 000000000..909390e07 --- /dev/null +++ b/resources/images/score_star_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/single_little_photo.svg b/resources/images/single_little_photo.svg new file mode 100644 index 000000000..91fe14664 --- /dev/null +++ b/resources/images/single_little_photo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index db7ae2d86..a4ca7e916 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -15,6 +15,7 @@ #include "RecenterDialog.hpp" #include "CalibUtils.hpp" +#include namespace Slic3r { namespace GUI { @@ -109,6 +110,28 @@ static std::vector message_containing_done{ #define AXIS_MIN_SIZE (wxSize(FromDIP(220), FromDIP(220))) #define EXTRUDER_IMAGE_SIZE (wxSize(FromDIP(48), FromDIP(76))) +static void market_model_scoring_page(int design_id) +{ + std::string url; + std::string country_code = GUI::wxGetApp().app_config->get_country_code(); + std::string model_http_url = GUI::wxGetApp().get_model_http_url(country_code); + if (GUI::wxGetApp().getAgent()->get_model_mall_detail_url(&url, std::to_string(design_id)) == 0) { + std::string user_id = GUI::wxGetApp().getAgent()->get_user_id(); + boost::algorithm::replace_first(url, "models", "u/" + user_id + "/rating"); + // Prevent user_id from containing design_id + size_t sign_in = url.find("/rating"); + std::string sub_url = url.substr(0, sign_in + 7); + url.erase(0, sign_in + 7); + boost::algorithm::replace_first(url, std::to_string(design_id), ""); + url = sub_url + url; + try { + if (!url.empty()) { wxLaunchDefaultBrowser(url); } + } catch (...) { + return; + } + } +} + PrintingTaskPanel::PrintingTaskPanel(wxWindow* parent, PrintingTaskType type) : wxPanel(parent, wxID_ANY,wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL) { @@ -347,28 +370,10 @@ void PrintingTaskPanel::create_panel(wxWindow* parent) penel_bottons->SetSizer(bSizer_buttons); penel_bottons->Layout(); - StateColor btn_bg_green(std::pair(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled), std::pair(wxColour(27, 136, 68), StateColor::Pressed), - std::pair(wxColour(61, 203, 115), StateColor::Hovered), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); - StateColor btn_bd_green(std::pair(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled)); - - m_button_market_scoring = new Button(parent, _L("Immediately score")); - m_button_market_scoring->SetBackgroundColor(btn_bg_green); - m_button_market_scoring->SetBorderColor(btn_bd_green); - m_button_market_scoring->SetTextColor(wxColour("#FFFFFE")); - m_button_market_scoring->SetSize(wxSize(FromDIP(128), FromDIP(26))); - m_button_market_scoring->SetMinSize(wxSize(-1, FromDIP(26))); - m_button_market_scoring->SetCornerRadius(FromDIP(13)); - - wxBoxSizer *bSizer_market_scoring = new wxBoxSizer(wxHORIZONTAL); - bSizer_market_scoring->Add(m_button_market_scoring); - bSizer_market_scoring->Add(0, 0, 1, wxEXPAND, 0); - m_button_market_scoring->Hide(); - bSizer_subtask_info->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(14)); bSizer_subtask_info->Add(bSizer_task_name, 0, wxEXPAND|wxRIGHT, FromDIP(18)); bSizer_subtask_info->Add(m_staticText_profile_value, 0, wxEXPAND | wxTOP, FromDIP(5)); bSizer_subtask_info->Add(m_printing_stage_value, 0, wxEXPAND | wxTOP, FromDIP(5)); - bSizer_subtask_info->Add(bSizer_market_scoring, 0, wxEXPAND | wxTOP, FromDIP(5)); bSizer_subtask_info->Add(penel_bottons, 0, wxEXPAND | wxTOP, FromDIP(10)); bSizer_subtask_info->Add(m_panel_progress, 0, wxEXPAND|wxRIGHT, FromDIP(25)); @@ -422,6 +427,67 @@ void PrintingTaskPanel::create_panel(wxWindow* parent) sizer->Add(m_panel_error_txt, 0, wxEXPAND | wxALL, 0); sizer->Add(0, FromDIP(12), 0); + m_score_staticline = new wxPanel(parent, wxID_ANY); + m_score_staticline->SetBackgroundColour(wxColour(238, 238, 238)); + m_score_staticline->Layout(); + m_score_staticline->Hide(); + sizer->Add(0, 0, 0, wxTOP, FromDIP(15)); + sizer->Add(m_score_staticline, 0, wxEXPAND | wxALL, FromDIP(10)); + + m_score_subtask_info = new wxPanel(parent, wxID_ANY); + m_score_subtask_info->SetBackgroundColour(*wxWHITE); + + wxBoxSizer * static_score_sizer = new wxBoxSizer(wxVERTICAL); + wxStaticText *static_score_text = new wxStaticText(m_score_subtask_info, wxID_ANY, "How do you like this printing file?", wxDefaultPosition, wxDefaultSize, 0); + static_score_text->Wrap(-1); + static_score_sizer->Add(static_score_text, 1, wxEXPAND | wxALL, FromDIP(10)); + + m_star_count = 0; + wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL); + m_score_star.resize(5); + for (int i = 0; i < m_score_star.size(); ++i) { + m_score_star[i] = new ScalableButton(m_score_subtask_info, wxID_ANY, "score_star_dark", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition, + wxBU_EXACTFIT | wxNO_BORDER, true, 26); + m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) { + for (int j = 0; j < m_score_star.size(); ++j) { + ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26); + m_score_star[j]->SetBitmap(light_star.bmp()); + if (m_score_star[j] == m_score_star[i]) { + m_star_count = j + 1; + break; + } + } + for (int k = m_star_count; k < m_score_star.size(); ++k) { + ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26); + m_score_star[k]->SetBitmap(dark_star.bmp()); + } + }); + static_score_star_sizer->Add(m_score_star[i], 0, wxEXPAND | wxLEFT, FromDIP(10)); + } + + StateColor btn_bg_green(std::pair(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled), std::pair(wxColour(27, 136, 68), StateColor::Pressed), + std::pair(wxColour(61, 203, 115), StateColor::Hovered), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); + StateColor btn_bd_green(std::pair(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled)); + + m_button_market_scoring = new Button(m_score_subtask_info, _L("Immediately score")); + m_button_market_scoring->SetBackgroundColor(btn_bg_green); + m_button_market_scoring->SetBorderColor(btn_bd_green); + m_button_market_scoring->SetTextColor(wxColour("#FFFFFE")); + m_button_market_scoring->SetSize(wxSize(FromDIP(128), FromDIP(26))); + m_button_market_scoring->SetMinSize(wxSize(-1, FromDIP(26))); + m_button_market_scoring->SetCornerRadius(FromDIP(13)); + + static_score_star_sizer->Add(0, 0, 1, wxEXPAND, 0); + static_score_star_sizer->Add(m_button_market_scoring, 0, wxEXPAND | wxRIGHT, FromDIP(10)); + static_score_sizer->Add(static_score_star_sizer, 0, wxEXPAND, FromDIP(10)); + + m_score_subtask_info->SetSizer(static_score_sizer); + m_score_subtask_info->Layout(); + m_score_subtask_info->Hide(); + + sizer->Add(m_score_subtask_info, 0, wxEXPAND | wxALL, 0); + sizer->Add(0, FromDIP(12), 0); + if (m_type == CALIBRATION) { m_panel_printing_title->Hide(); m_bitmap_thumbnail->Hide(); @@ -611,6 +677,16 @@ void PrintingTaskPanel::show_profile_info(bool show, wxString profile /*= wxEmpt } } +void PrintingTaskPanel::market_scoring_show() { + m_score_staticline->Show(); + m_score_subtask_info->Show(); +} + +void PrintingTaskPanel::market_scoring_hide() { + m_score_staticline->Hide(); + m_score_subtask_info->Hide(); +} + StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) : wxScrolledWindow(parent, id, pos, size, wxHSCROLL | wxVSCROLL) { @@ -1433,6 +1509,8 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_buttons.push_back(m_bpButton_e_down_10); obj = nullptr; + m_score_data = new ScoreData; + m_score_data->job_id = -1; /* set default values */ m_switch_lamp->SetValue(false); m_switch_printing_fan->SetValue(false); @@ -1543,6 +1621,10 @@ StatusPanel::~StatusPanel() if (sdcard_hint_dlg != nullptr) delete sdcard_hint_dlg; + + if (m_score_data != nullptr) { + delete m_score_data; + } } void StatusPanel::init_scaled_buttons() @@ -1566,7 +1648,29 @@ void StatusPanel::init_scaled_buttons() void StatusPanel::on_market_scoring(wxCommandEvent &event) { if (obj && obj->get_modeltask() && obj->get_modeltask()->design_id > 0) { - market_model_scoring_page(obj->get_modeltask()->design_id); + if (m_score_data && m_score_data->job_id == obj->get_modeltask()->job_id) { + ScoreDialog m_score_dlg(this, m_score_data); + int ret = m_score_dlg.ShowModal(); + + if (ret == wxID_OK) { + m_score_data->job_id = -1; + return; + } + if (m_score_data != nullptr) { delete m_score_data; } + m_score_data = new ScoreData(m_score_dlg.get_score_data()); + } else { + ScoreDialog m_score_dlg(this, obj->get_modeltask()->design_id, obj->get_modeltask()->job_id, obj->get_modeltask()->model_id, obj->get_modeltask()->profile_id, + m_project_task_panel->get_star_count()); + int ret = m_score_dlg.ShowModal(); + if (ret == wxID_OK) { + m_score_data->job_id = -1; + return; + } + if (m_score_data != nullptr) { delete m_score_data; } + m_score_data = new ScoreData(m_score_dlg.get_score_data()); + } + + } } @@ -1793,28 +1897,6 @@ void StatusPanel::show_recenter_dialog() { obj->command_go_home(); } -void StatusPanel::market_model_scoring_page(int design_id) -{ - std::string url; - std::string country_code = GUI::wxGetApp().app_config->get_country_code(); - std::string model_http_url = GUI::wxGetApp().get_model_http_url(country_code); - if (GUI::wxGetApp().getAgent()->get_model_mall_detail_url(&url, std::to_string(design_id)) == 0) { - std::string user_id = GUI::wxGetApp().getAgent()->get_user_id(); - boost::algorithm::replace_first(url, "models", "u/" + user_id + "/rating"); - // Prevent user_id from containing design_id - size_t sign_in = url.find("/rating"); - std::string sub_url = url.substr(0, sign_in + 7); - url.erase(0, sign_in + 7); - boost::algorithm::replace_first(url, std::to_string(design_id), ""); - url = sub_url + url; - try { - if (!url.empty()) { wxLaunchDefaultBrowser(url); } - } catch (...) { - return; - } - } -} - void StatusPanel::show_error_message(MachineObject* obj, wxString msg, std::string print_error_str) { if (msg.IsEmpty()) { @@ -2502,7 +2584,7 @@ void StatusPanel::update_subtask(MachineObject *obj) reset_printing_values(); } else if (obj->is_in_printing() || obj->print_status == "FINISH") { if (obj->is_in_prepare() || obj->print_status == "SLICING") { - m_project_task_panel->get_market_scoring_button()->Hide(); + m_project_task_panel->market_scoring_hide(); m_project_task_panel->enable_abort_button(false); m_project_task_panel->enable_pause_resume_button(false, "pause_disable"); wxString prepare_text; @@ -2553,11 +2635,11 @@ void StatusPanel::update_subtask(MachineObject *obj) if (wxGetApp().has_model_mall()) { bool is_market_task = obj->get_modeltask() && obj->get_modeltask()->design_id > 0; if (is_market_task) { - m_project_task_panel->get_market_scoring_button()->Show(); + m_project_task_panel->market_scoring_show(); BOOST_LOG_TRIVIAL(info) << "SHOW_SCORE_BTU: design_id [" << obj->get_modeltask()->design_id << "] print_finish [" << m_print_finish << "]"; if (!m_print_finish && IsShownOnScreen()) { m_print_finish = true; - int job_id = obj->get_modeltask()->job_id; + /*int job_id = obj->get_modeltask()->job_id; if (wxGetApp().app_config->get("not_show_score_dialog") != "1" && rated_model_id.find(job_id) == rated_model_id.end()) { MessageDialog dlg(this, _L("Please give a score for your favorite Bambu Market model."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Score"), wxYES_NO | wxYES_DEFAULT | wxCENTRE); @@ -2569,15 +2651,15 @@ void StatusPanel::update_subtask(MachineObject *obj) rated_model_id.insert(job_id); BOOST_LOG_TRIVIAL(info) << "SHOW_SCORE_DLG: design_id [" << old_design_id << "] print_finish [" << m_print_finish << "] not_show [" << wxGetApp().app_config->get("not_show_score_dialog") << "] job_id [" << job_id << "]"; - } + }*/ } } else { - m_project_task_panel->get_market_scoring_button()->Hide(); + m_project_task_panel->market_scoring_hide(); } } } else { m_project_task_panel->enable_abort_button(true); - m_project_task_panel->get_market_scoring_button()->Hide(); + m_project_task_panel->market_scoring_hide(); if (m_print_finish) { m_print_finish = false; } @@ -2682,7 +2764,7 @@ void StatusPanel::reset_printing_values() m_project_task_panel->update_progress_percent(NA_STR, wxEmptyString); - m_project_task_panel->get_market_scoring_button()->Hide(); + m_project_task_panel->market_scoring_hide(); update_basic_print_data(false); m_project_task_panel->update_left_time(NA_STR); m_project_task_panel->update_layers_num(true, wxString::Format(_L("Layer: %s"), NA_STR)); @@ -3732,5 +3814,536 @@ void StatusPanel::msw_rescale() Layout(); Refresh(); } +static char *bbl_calc_md5_char(std::string &filename) +{ + unsigned char digest[16]; + MD5_CTX ctx; + MD5_Init(&ctx); + boost::filesystem::ifstream ifs(filename, std::ios::binary); + std::string buf(64 * 1024, 0); + const std::size_t & size = boost::filesystem::file_size(filename); + std::size_t left_size = size; + while (ifs) { + ifs.read(buf.data(), buf.size()); + int read_bytes = ifs.gcount(); + MD5_Update(&ctx, (unsigned char *) buf.data(), read_bytes); + } + MD5_Final(digest, &ctx); + char *md5_str = new char[33]; + for (int j = 0; j < 16; j++) { sprintf(&md5_str[j * 2], "%02X", (unsigned int) digest[j]); } + md5_str[32] = '\0'; + return md5_str; +} -}} // namespace Slic3r::GUI +ScoreDialog::ScoreDialog(wxWindow *parent,int design_id, int job_id, std::string model_id, int profile_id, int star_count) + : DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Scoring"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) + , m_design_id(design_id) + , m_job_id(job_id) + , m_model_id(model_id) + , m_profile_id(profile_id) + , m_star_count(star_count) + , m_upload_status_code(StatusCode::CODE_NUMBER) +{ + wxBoxSizer *m_main_sizer = get_main_sizer(); + + this->SetSizer(m_main_sizer); + Fit(); + Layout(); + wxGetApp().UpdateDlgDarkUI(this); +} + +ScoreDialog::ScoreDialog(wxWindow *parent, ScoreData *score_data) + : DPIDialog(parent, wxID_ANY, wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Scoring"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) + , m_design_id(score_data->design_id) + , m_job_id(score_data->job_id) + , m_model_id(score_data->model_id) + , m_profile_id(score_data->profile_id) + , m_star_count(score_data->star_count) + , m_upload_status_code(StatusCode::CODE_NUMBER) +{ + wxBoxSizer *m_main_sizer = get_main_sizer(score_data->image,score_data->comment_text); + m_need_upload_images = score_data->need_upload_images; + m_image_url_paths = score_data->image_url_paths; + m_local_to_url_image = score_data->local_to_url_image; + + for (auto image : m_image) { + wxString local_image_path = image.second.local_image_url; + if (m_need_upload_images.find(local_image_path) == m_need_upload_images.end()) { + image.second.is_uploaded = true; + } + } + + this->SetSizer(m_main_sizer); + Fit(); + Layout(); + wxGetApp().UpdateDlgDarkUI(this); + +} + +ScoreDialog::~ScoreDialog() {} + +void ScoreDialog::on_dpi_changed(const wxRect &suggested_rect) {} + +void ScoreDialog::OnBitmapClicked(wxMouseEvent &event) +{ + wxStaticBitmap *clickedBitmap = dynamic_cast(event.GetEventObject()); + if (m_image.find(clickedBitmap) != m_image.end()) { + if (!m_image[clickedBitmap].is_selected) { + for (auto panel : m_image[clickedBitmap].image_broad) { + panel->Show(); + } + m_image[clickedBitmap].is_selected = true; + m_selected_image_list.insert(clickedBitmap); + } else { + for (auto panel : m_image[clickedBitmap].image_broad) { + panel->Hide(); + } + m_image[clickedBitmap].is_selected = false; + m_selected_image_list.erase(clickedBitmap); + m_selected_image_list.erase(clickedBitmap); + } + } + if (m_selected_image_list.empty()) + m_delete_photo->Hide(); + else + m_delete_photo->Show(); + Fit(); + Layout(); + +} + +void ScoreDialog::add_need_upload_imgs() { + for (auto bitmap : m_image) { + wxString local_image_path = bitmap.second.local_image_url; + if (!bitmap.second.is_uploaded) { + m_need_upload_images.insert(local_image_path); + } else { + if (m_need_upload_images.find(local_image_path) != m_need_upload_images.end()) { + m_need_upload_images.erase(local_image_path); + } + } + } +} + +void ScoreDialog::init() { + SetBackgroundColour(*wxWHITE); + SetMinSize(wxSize(FromDIP(540), FromDIP(380))); + + // icon + std::string icon_path = (boost::format("%1%/images/BambuStudio.ico") % resources_dir()).str(); + SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); +} + +wxBoxSizer *ScoreDialog::get_score_sizer() { + wxBoxSizer *score_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText *static_score_text = new wxStaticText(this, wxID_ANY, _L("Scoring"), wxDefaultPosition, wxDefaultSize, 0); + static_score_text->Wrap(-1); + score_sizer->Add(static_score_text, 1, wxEXPAND | wxLEFT, FromDIP(24)); + score_sizer->Add(0, 0, 1, wxEXPAND, 0); + return score_sizer; +} + +wxBoxSizer *ScoreDialog::get_star_sizer() +{ + wxBoxSizer *static_score_star_sizer = new wxBoxSizer(wxHORIZONTAL); + m_score_star.resize(5); + for (int i = 0; i < m_score_star.size(); ++i) { + if (i < m_star_count) { + m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_light", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition, + wxBU_EXACTFIT | wxNO_BORDER, true, 26); + } else + m_score_star[i] = new ScalableButton(this, wxID_ANY, "score_star_dark", wxEmptyString, wxSize(FromDIP(26), FromDIP(26)), wxDefaultPosition, + wxBU_EXACTFIT | wxNO_BORDER, true, 26); + + m_score_star[i]->Bind(wxEVT_LEFT_DOWN, [this, i](auto &e) { + for (int j = 0; j < m_score_star.size(); ++j) { + ScalableBitmap light_star = ScalableBitmap(nullptr, "score_star_light", 26); + m_score_star[j]->SetBitmap(light_star.bmp()); + if (m_score_star[j] == m_score_star[i]) { + m_star_count = j + 1; + break; + } + } + for (int k = m_star_count; k < m_score_star.size(); ++k) { + ScalableBitmap dark_star = ScalableBitmap(nullptr, "score_star_dark", 26); + m_score_star[k]->SetBitmap(dark_star.bmp()); + } + }); + static_score_star_sizer->Add(m_score_star[i], 0, wxEXPAND | wxLEFT, FromDIP(20)); + } + + return static_score_star_sizer; +} + +wxBoxSizer* ScoreDialog::get_comment_text_sizer() { + wxBoxSizer* m_comment_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText *static_comment_text = new wxStaticText(this, wxID_ANY, _L("Comment"), wxDefaultPosition, wxDefaultSize, 0); + static_comment_text->Wrap(-1); + m_comment_sizer->Add(static_comment_text, 1, wxEXPAND | wxLEFT, FromDIP(24)); + m_comment_sizer->Add(0, 0, 1, wxEXPAND, 0); + return m_comment_sizer; +} + +void ScoreDialog::create_comment_text(const wxString& comment) { + m_comment_text = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(492), FromDIP(104)), wxTE_MULTILINE); + m_comment_text->SetLabelText(comment); + m_comment_text->SetHint(_L("Rate this print")); + m_comment_text->SetBackgroundColour(*wxWHITE); + m_comment_text->SetForegroundColour(wxColor("#BBBBBB")); + m_comment_text->SetMinSize(wxSize(FromDIP(492), FromDIP(104))); + + m_comment_text->Bind(wxEVT_SET_FOCUS, [this](auto &event) { + if (wxGetApp().dark_mode()) { + m_comment_text->SetForegroundColour(wxColor(*wxWHITE)); + } else + m_comment_text->SetForegroundColour(wxColor(*wxBLACK)); + m_comment_text->Refresh(); + event.Skip(); + }); +} + +wxBoxSizer *ScoreDialog::get_photo_btn_sizer() { + wxBoxSizer * m_photo_sizer = new wxBoxSizer(wxHORIZONTAL); + ScalableBitmap little_photo = ScalableBitmap(this, "single_little_photo", 20); + wxStaticBitmap *little_photo_img = new wxStaticBitmap(this, wxID_ANY, little_photo.bmp(), wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), 0); + m_photo_sizer->Add(little_photo_img, 0, wxEXPAND | wxLEFT, FromDIP(24)); + m_add_photo = new Label(this, _L("Add Photo")); + m_add_photo->SetBackgroundColour(*wxWHITE); + m_add_photo->SetForegroundColour(wxColor("#898989")); + m_add_photo->SetSize(wxSize(-1, FromDIP(20))); + m_photo_sizer->Add(m_add_photo, 0, wxEXPAND | wxLEFT, FromDIP(12)); + + m_delete_photo = new Label(this, _L("Delete Photo")); + m_delete_photo->SetBackgroundColour(*wxWHITE); + m_delete_photo->SetForegroundColour(wxColor("#898989")); + m_delete_photo->SetSize(wxSize(-1, FromDIP(20))); + m_photo_sizer->Add(m_delete_photo, 0, wxEXPAND | wxLEFT, FromDIP(12)); + m_delete_photo->Hide(); + m_photo_sizer->Add(0, 0, 1, wxEXPAND, 0); + + m_add_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { + // add photo logic + wxFileDialog openFileDialog(this, "Select Images", "", "", "Image files (*.bmp;*.png;*.jpg)|*.bmp;*.png;*.jpg", wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE); + + if (openFileDialog.ShowModal() == wxID_CANCEL) return; + + wxArrayString filePaths; + openFileDialog.GetPaths(filePaths); + wxArrayString filePaths_reduction; + for (int i = 0; i < filePaths.GetCount(); i++) { //It's ugly, but useful + bool is_repeat = false; + for (auto image : m_image) { + if (filePaths[i] == image.second.local_image_url) { + is_repeat = true; + continue; + } + } + if (!is_repeat) { + filePaths_reduction.push_back(filePaths[i]); + if (filePaths_reduction.size() + m_image.size() > m_photo_nums) { + break; + } + } + + } + + load_photo(filePaths_reduction); + + m_image_sizer->Layout(); + this->Fit(); + this->Layout(); + }); + + m_delete_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { + for (auto it = m_selected_image_list.begin(); it != m_selected_image_list.end();) { + auto bitmap = *it; + m_image_sizer->Detach(m_image[bitmap].image_tb_broad); + m_image[bitmap].image_tb_broad->DeleteWindows(); + wxString local_image_path = m_image[bitmap].local_image_url; + if (m_need_upload_images.find(local_image_path) != m_need_upload_images.end()) { m_need_upload_images.erase(local_image_path); } + if (m_local_to_url_image.find(local_image_path) != m_local_to_url_image.end()) { m_local_to_url_image.erase(local_image_path); } + + m_image.erase(bitmap); + it = m_selected_image_list.erase(it); + } + m_image_url_paths.clear(); + for (auto local_to_url_image : m_local_to_url_image) { m_image_url_paths.push_back(local_to_url_image.second); } + m_delete_photo->Hide(); + m_image_sizer->Layout(); + Layout(); + }); + + return m_photo_sizer; +} + +wxBoxSizer *ScoreDialog::get_button_sizer() +{ + wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL); + bSizer_button->Add(0, 0, 1, wxEXPAND, 0); + + StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered), + std::pair(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); + + m_button_ok = new Button(this, _L("OK")); + m_button_ok->SetBackgroundColor(btn_bg_green); + m_button_ok->SetBorderColor(*wxWHITE); + m_button_ok->SetTextColor(wxColour(0xFFFFFE)); + m_button_ok->SetFont(Label::Body_12); + m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24))); + m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24))); + m_button_ok->SetCornerRadius(FromDIP(12)); + bSizer_button->Add(m_button_ok, 0, wxRIGHT, FromDIP(24)); + + m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { + m_upload_status_code = StatusCode::UPLOAD_PROGRESS; + + if (m_star_count == 0) { + MessageDialog dlg(this, _L("Please click on the star first."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("InFo"), wxOK); + dlg.ShowModal(); + return; + } + + add_need_upload_imgs(); + + std::string comment = into_u8(m_comment_text->GetValue()); + unsigned int http_code; + std::string http_error; + wxString error_info; + + if (!m_need_upload_images.empty()) { + std::string config; + int ret = wxGetApp().getAgent()->get_oss_config(config, wxGetApp().app_config->get_country_code(), http_code, http_error); + if (ret == -1) { + error_info += into_u8(_L("Get oss config failed.")) + "\n\thttp code: " + std::to_string(http_code) + "\n\thttp error: " + http_error; + m_upload_status_code = StatusCode::UPLOAD_EXIST_ISSUE; + } + if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) { + int need_upload_nums = m_need_upload_images.size(); + int upload_nums = 0; + int upload_failed_nums = 0; + ProgressDialog *progress_dialog = new ProgressDialog(_L("Upload Pictrues"), wxString("..."), need_upload_nums, this); + for (std::set::iterator it = m_need_upload_images.begin(); it != m_need_upload_images.end();) { + wxString need_upload = *it; + std::string need_upload_uf8 = into_u8(need_upload); + ret = wxGetApp().getAgent()->put_rating_picture_oss(config, need_upload_uf8, m_model_id, m_profile_id, http_code, http_error); + switch (ret) { + case 0: + upload_nums++; + m_image_url_paths.push_back(need_upload_uf8); + m_local_to_url_image[*it] = need_upload_uf8; + it = m_need_upload_images.erase(it); + progress_dialog->Update(upload_nums, _L("Number of images successfully uploaded") + ": " + std::to_string(upload_nums) + "/" + std::to_string(need_upload_nums)); + progress_dialog->Fit(); + BOOST_LOG_TRIVIAL(info) << "put_rating_picture_oss: model_id [" << m_model_id << "] profile_id [" << m_profile_id << "] http_code [" << http_code + << "] http_error [" << http_error << "] config [" << config << "] image_path [" << need_upload << "]"; + break; + case -1: + error_info += need_upload + _L(" upload failed").ToUTF8().data() + "\n\thttp code:" + std::to_string(http_code) + "\n\thttp_error:" + http_error + "\n"; + m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; + ++it; + break; + case BAMBU_NETWORK_ERR_PARSE_CONFIG_FAILED: + error_info += need_upload + _L("upload config prase failed\n").ToUTF8().data() + "\n"; + m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; + ++it; + break; + case BAMBU_NETWORK_ERR_NO_CORRESPONDING_BUCKET: + error_info += need_upload + _L("No corresponding storage bucket\n").ToUTF8().data() + "\n"; + m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; + ++it; + break; + case BAMBU_NETWORK_ERR_OPEN_FILE_FAILED: + error_info += need_upload + _L("can not be opened\n").ToUTF8().data() + "\n"; + m_upload_status_code = StatusCode::UPLOAD_IMG_FAILED; + ++it; + break; + } + } + progress_dialog->Hide(); + if (progress_dialog) { + delete progress_dialog; + } + for (auto bitmap : m_image) { + wxString local_image_path = bitmap.second.local_image_url; + if (m_local_to_url_image.find(local_image_path) != m_local_to_url_image.end()) { + m_image[bitmap.first].is_uploaded = true; + } + } + + if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) { + std::string upload_failed_images = into_u8(_L("The following issues occurred during the process of uploading images. Do you want to ignore them?\n\n")); + MessageDialog dlg_info(this, upload_failed_images + error_info, wxString(_L("info")), wxOK | wxNO | wxCENTER); + if (dlg_info.ShowModal() == wxID_OK) { m_upload_status_code == StatusCode::UPLOAD_PROGRESS; } + } + } + } + + if (m_upload_status_code == StatusCode::UPLOAD_PROGRESS) { + int ret = wxGetApp().getAgent()->put_model_mall_rating(m_job_id, m_star_count, comment, m_image_url_paths, http_code, http_error); + MessageDialog *dlg_info; + switch (ret) { + case 0: EndModal(wxID_OK); break; + case BAMBU_NETWORK_ERR_GET_RATING_ID_FAILED: + dlg_info = new MessageDialog(this, _L("Synchronizing the printing results. Please retry a few seconds later."), wxString(_L("info")), wxOK | wxCENTER); + dlg_info->ShowModal(); + delete dlg_info; + break; + default: // Upload failed and obtaining instance_id failed + if (ret == -1) + error_info += _L("Upload failed\n").ToUTF8().data(); + else + error_info += _L("obtaining instance_id failed\n").ToUTF8().data(); + if (!error_info.empty()) { BOOST_LOG_TRIVIAL(info) << error_info; } + + dlg_info = new MessageDialog(this, _L("Your comment result cannot be uploaded due to some reasons. Would you like to redirect to the webpage for storing?"), + wxString(_L("info")), wxOK | wxNO | wxCENTER); + if (dlg_info->ShowModal() == wxID_OK) { + market_model_scoring_page(m_design_id); + EndModal(wxID_OK); + } + delete dlg_info; + break; + } + } else if (m_upload_status_code == StatusCode::UPLOAD_IMG_FAILED) { + MessageDialog *dlg_info = new MessageDialog(this, _L("Some of your images failed to upload. Would you like to redirect to the webpage for storing?"), + wxString(_L("info")), wxOK | wxNO | wxCENTER); + if (dlg_info->ShowModal() == wxID_OK) { + market_model_scoring_page(m_design_id); + EndModal(wxID_OK); + } + delete dlg_info; + if (!error_info.empty()) { BOOST_LOG_TRIVIAL(info) << error_info; } + } + }); + + StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered), + std::pair(*wxWHITE, StateColor::Normal)); + + m_button_cancel = new Button(this, _L("Cancel")); + m_button_cancel->SetBackgroundColor(btn_bg_white); + m_button_cancel->SetBorderColor(wxColour(38, 46, 48)); + m_button_cancel->SetFont(Label::Body_12); + m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24))); + m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24))); + m_button_cancel->SetCornerRadius(FromDIP(12)); + bSizer_button->Add(m_button_cancel, 0, wxRIGHT, FromDIP(24)); + + m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { EndModal(wxID_CANCEL); }); + + return bSizer_button; +} + +void ScoreDialog::load_photo(const wxArrayString &filePaths) +{ + for (size_t i = 0; i < filePaths.GetCount(); ++i) { + if (m_image.size() < m_photo_nums) { + wxString filePath = filePaths[i]; + + ImageMsg cur_image_msg; + wxStaticBitmap *imageCtrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxImage(filePath, wxBITMAP_TYPE_ANY).Rescale(FromDIP(80), FromDIP(60))), wxDefaultPosition, + wxDefaultSize, 0); + imageCtrl->Bind(wxEVT_LEFT_DOWN, &ScoreDialog::OnBitmapClicked, this); + cur_image_msg.local_image_url = filePath; + cur_image_msg.is_uploaded = false; + + // tb: top and bottom lr: left and right + auto m_image_tb_broad = new wxBoxSizer(wxVERTICAL); + auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); + line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); + m_image_tb_broad->Add(line_top, 0, wxEXPAND, 0); + cur_image_msg.image_broad.push_back(line_top); + line_top->Hide(); + + auto m_image_lr_broad = new wxBoxSizer(wxHORIZONTAL); + auto line_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL); + line_left->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); + m_image_lr_broad->Add(line_left, 0, wxEXPAND, 0); + cur_image_msg.image_broad.push_back(line_left); + line_left->Hide(); + + m_image_lr_broad->Add(imageCtrl, 0, wxALL, 5); + + auto line_right = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL); + line_right->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); + m_image_lr_broad->Add(line_right, 0, wxEXPAND, 0); + m_image_tb_broad->Add(m_image_lr_broad, 0, wxEXPAND, 0); + cur_image_msg.image_broad.push_back(line_right); + line_right->Hide(); + + auto line_bottom = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); + line_bottom->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); + m_image_tb_broad->Add(line_bottom, 0, wxEXPAND, 0); + cur_image_msg.image_broad.push_back(line_bottom); + line_bottom->Hide(); + + cur_image_msg.is_selected = false; + cur_image_msg.image_tb_broad = m_image_tb_broad; + m_image[imageCtrl] = cur_image_msg; + m_image_sizer->Add(m_image_tb_broad, 0, wxALL, 5); + + } else { + MessageDialog *dlg_info_up_to_8 = new MessageDialog(this, _L("You can select up to 5 images."), wxString(_L("info")), wxOK | wxCENTER); + dlg_info_up_to_8->ShowModal(); + break; + } + + } +} + +wxBoxSizer *ScoreDialog::get_main_sizer(const wxArrayString &images, const wxString &comment) { + init(); + wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL); + // top line + auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL); + m_line_top->SetBackgroundColour(wxColour(0xA6, 0xa9, 0xAA)); + m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0); + m_main_sizer->Add(0, 0, 0, wxTOP, FromDIP(32)); + + wxBoxSizer *score_sizer = get_score_sizer(); + m_main_sizer->Add(score_sizer, 0, wxEXPAND, FromDIP(20)); + m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8)); + + wxBoxSizer *static_score_star_sizer = get_star_sizer(); + m_main_sizer->Add(static_score_star_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(20)); + + wxBoxSizer *m_comment_sizer = get_comment_text_sizer(); + m_main_sizer->Add(m_comment_sizer, 0, wxEXPAND, FromDIP(20)); + m_main_sizer->Add(0, 0, 0, wxBOTTOM, FromDIP(8)); + + create_comment_text(comment); + m_main_sizer->Add(m_comment_text, 0, wxLEFT, FromDIP(24)); + + wxBoxSizer *m_photo_sizer = get_photo_btn_sizer(); + m_main_sizer->Add(m_photo_sizer, 0, wxEXPAND | wxTOP, FromDIP(8)); + + m_image_sizer = new wxBoxSizer(wxHORIZONTAL); + if (!images.empty()) { + load_photo(images); + } + m_main_sizer->Add(m_image_sizer, 0, wxEXPAND | wxLEFT, FromDIP(24)); + m_main_sizer->Add(0, 0, 1, wxEXPAND, 0); + + wxBoxSizer *bSizer_button = get_button_sizer(); + m_main_sizer->Add(bSizer_button, 0, wxEXPAND | wxBOTTOM, FromDIP(24)); + + return m_main_sizer; +} + +ScoreData ScoreDialog::get_score_data() { + ScoreData score_data; + score_data.design_id = m_design_id; + score_data.job_id = m_job_id; + score_data.model_id = m_model_id; + score_data.profile_id = m_profile_id; + score_data.star_count = m_star_count; + score_data.comment_text = m_comment_text->GetValue(); + score_data.image_url_paths = m_image_url_paths; + score_data.need_upload_images = m_need_upload_images; + for (auto img : m_image) { score_data.image.push_back(img.second.local_image_url); } + score_data.local_to_url_image = m_local_to_url_image; + + return score_data; +} + +} // namespace GUI +} // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index 0b61cf3b9..e0dcd3982 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -61,6 +61,84 @@ enum PrintingTaskType { CALIBRATION, }; +struct ScoreData +{ + int design_id; + int job_id; + std::string model_id; + int profile_id; + int star_count; + wxString comment_text; + std::vector image_url_paths; + std::set need_upload_images; + wxArrayString image; + std::unordered_map local_to_url_image; +}; + +class ScoreDialog : public GUI::DPIDialog +{ +public: + ScoreDialog(wxWindow *parent, int design_id, int job_id, std::string model_id, int profile_id, int star_count = 0); + ScoreDialog(wxWindow *parent, ScoreData *score_data); + ~ScoreDialog(); + + int get_job_id() { return m_job_id;} + ScoreData get_score_data(); + +protected: + enum StatusCode { + UPLOAD_PROGRESS = 0, + UPLOAD_EXIST_ISSUE, + UPLOAD_IMG_FAILED, + CODE_NUMBER + }; + + const int m_photo_nums = 5; + int m_design_id; + int m_job_id; + std::string m_model_id; + int m_profile_id; + int m_star_count; + std::vector m_image_url_paths; + std::set m_need_upload_images; + std::string m_upload_error_info; + StatusCode m_upload_status_code; + + struct ImageMsg + { + wxString local_image_url; + vector image_broad; + bool is_selected; + bool is_uploaded; + wxBoxSizer * image_tb_broad = nullptr; + }; + + std::vector m_score_star; + wxTextCtrl * m_comment_text = nullptr; + Button * m_button_ok = nullptr; + Button * m_button_cancel = nullptr; + Label * m_add_photo = nullptr; + Label * m_delete_photo = nullptr; + wxBoxSizer * m_image_sizer = nullptr; + std::unordered_map m_image; + std::unordered_set m_selected_image_list; + std::unordered_map m_local_to_url_image; + + void on_dpi_changed(const wxRect &suggested_rect) override; + void OnBitmapClicked(wxMouseEvent &event); + void add_need_upload_imgs(); + + void init(); + wxBoxSizer *get_score_sizer(); + wxBoxSizer *get_star_sizer(); + wxBoxSizer *get_comment_text_sizer(); + void create_comment_text(const wxString& comment = ""); + wxBoxSizer *get_photo_btn_sizer(); + wxBoxSizer *get_button_sizer(); + void load_photo(const wxArrayString &filePaths); + wxBoxSizer *get_main_sizer(const wxArrayString &images = wxArrayString(), const wxString &comment = ""); +}; + class PrintingTaskPanel : public wxPanel { public: @@ -96,6 +174,10 @@ private: ScalableButton* m_button_abort; Button* m_button_market_scoring; Button* m_button_clean; + wxPanel * m_score_subtask_info; + wxPanel * m_score_staticline; + int m_star_count; + std::vector m_score_star; ProgressBar* m_gauge_progress; Label* m_error_text; @@ -120,6 +202,8 @@ public: void update_layers_num(bool show, wxString num = wxEmptyString); void show_priting_use_info(bool show, wxString time = wxEmptyString, wxString weight = wxEmptyString); void show_profile_info(bool show, wxString profile = wxEmptyString); + void market_scoring_show(); + void market_scoring_hide(); public: ScalableButton* get_abort_button() {return m_button_abort;}; @@ -127,6 +211,7 @@ public: Button* get_market_scoring_button() {return m_button_market_scoring;}; Button* get_clean_button() {return m_button_clean;}; wxStaticBitmap* get_bitmap_thumbnail() {return m_bitmap_thumbnail;}; + int get_star_count() { return m_star_count; } }; class StatusBasePanel : public wxScrolledWindow @@ -370,6 +455,8 @@ protected: std::map m_print_connect_types; std::vector