From 8f1103f064d4b37f4dd657ca25ccfc6c87fbb403 Mon Sep 17 00:00:00 2001 From: summerkiller <643866083@qq.com> Date: Wed, 14 Oct 2026 15:44:58 +0800 Subject: [PATCH 1/3] Re-pull request regarding the printers of goofoo company (#16283) * add new repositories and new push * fix bug about setting_id * fix bug and complete the test * Fix Goofoo profiles so the bundle loads and passes profile checks Repair the OrcaFilamentLibrary index entry that broke JSON parsing, regenerate the hand-written filament ids as Orca ids, and bump the library version. Point each printer's default filament and print profiles at presets that exist, normalize the two presets that needed it, rebuild both indexes, correct the ABS-GF/PA-GF/PA6-CF filament types, align the GP1/Velo+ preset names with the library's @ spacing, and fix the casing and resolution of the model cover images. * Drop the copied Custom Klipper printer from the Goofoo bundle Goofoo shipped Custom's MyKlipper machine model verbatim, so the Add Printer list offered "Generic Klipper Printer" twice and the printer type resolved its model_id by vendor order. The Goofoo machines now inherit the shared fdm_klipper_common directly, carrying over the per-variant layer heights the removed base supplied, matching how the other Klipper vendors wire theirs. Each machine's resolved settings are unchanged. * Align the Goofoo preset names with the profile conventions The machine models and variants already followed the / nozzle shape, but the processes put the model in the quality slot and used the bare vendor as the @ target (0.20mm GP1 @Goofoo). They are now named like every other vendor's: mm @ (0.20mm Standard @Goofoo GP1), with the machines' default_print_profile and the index updated to match. The four leaves also inherit the shared fdm_process_klipper_common directly instead of the copied Custom "0.20mm Standard @MyKlipper" base, which is removed; GP1 and TurboM gained the layer_height 0.2 that base supplied, so every preset's resolved settings are unchanged. Removed the orphaned Generic Klipper Printer cover and the unused Turbo-M texture, and renamed TurboM's bed texture to the -texture.svg form the other two models use. * new Goofoo machine and clean profile * Restore library filaments dropped by merges from main * Give the Goofoo Velo+ Tool and 0.2 nozzle fitting processes --------- Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com> Co-authored-by: SoftFever --- resources/profiles/Goofoo.json | 89 ++++++++++ .../profiles/Goofoo/Goofoo GP1_cover.png | Bin 0 -> 25534 bytes .../profiles/Goofoo/Goofoo TurboM_cover.png | Bin 0 -> 11297 bytes .../profiles/Goofoo/Goofoo Velo+_cover.png | Bin 0 -> 18636 bytes .../profiles/Goofoo/Goofoo-GP1-texture.svg | 7 + resources/profiles/Goofoo/Goofoo-GP1.stl | Bin 0 -> 42284 bytes .../profiles/Goofoo/Goofoo-TurboM-texture.svg | 7 + resources/profiles/Goofoo/Goofoo-TurboM.stl | Bin 0 -> 11084 bytes .../profiles/Goofoo/Goofoo-Velo+-texture.svg | 6 + resources/profiles/Goofoo/Goofoo-Velo+.stl | Bin 0 -> 12084 bytes .../Goofoo/machine/Goofoo GP1 0.4 nozzle.json | 98 +++++++++++ .../profiles/Goofoo/machine/Goofoo GP1.json | 11 ++ .../machine/Goofoo TurboM 0.4 nozzle.json | 54 ++++++ .../Goofoo/machine/Goofoo TurboM.json | 11 ++ .../machine/Goofoo Velo+ 0.2 nozzle.json | 106 ++++++++++++ .../machine/Goofoo Velo+ 0.4 nozzle.json | 100 +++++++++++ .../machine/Goofoo Velo+ 0.6 nozzle.json | 106 ++++++++++++ .../Goofoo/machine/Goofoo Velo+ Tool 0.4.json | 152 ++++++++++++++++ .../Goofoo/machine/Goofoo Velo+ Tool.json | 11 ++ .../profiles/Goofoo/machine/Goofoo Velo+.json | 11 ++ .../Goofoo/machine/fdm_klipper_common.json | 13 ++ .../Goofoo/machine/fdm_machine_common.json | 118 +++++++++++++ .../0.10mm Standard @Goofoo Velo+.json | 26 +++ .../process/0.20mm Standard @Goofoo GP1.json | 35 ++++ .../0.20mm Standard @Goofoo TurboM.json | 67 ++++++++ .../0.20mm Standard @Goofoo Velo+.json | 70 ++++++++ .../0.30mm Standard @Goofoo Velo+.json | 13 ++ .../Goofoo/process/fdm_process_common.json | 91 ++++++++++ .../process/fdm_process_klipper_common.json | 23 +++ resources/profiles/OrcaFilamentLibrary.json | 162 +++++++++++++++++- .../Goofoo/Goofoo 90A TPU @System.json | 9 + .../filament/Goofoo/Goofoo 90A TPU @base.json | 41 +++++ .../Goofoo/Goofoo 95A TPU @System.json | 9 + .../filament/Goofoo/Goofoo 95A TPU @base.json | 38 ++++ .../filament/Goofoo/Goofoo ABS @System.json | 9 + .../filament/Goofoo/Goofoo ABS @base.json | 23 +++ .../filament/Goofoo/Goofoo ASA @System.json | 9 + .../filament/Goofoo/Goofoo ASA @base.json | 20 +++ .../filament/Goofoo/Goofoo PA @System.json | 9 + .../filament/Goofoo/Goofoo PA @base.json | 20 +++ .../filament/Goofoo/Goofoo PA-CF @System.json | 9 + .../filament/Goofoo/Goofoo PA-CF @base.json | 17 ++ .../Goofoo/Goofoo PA-GF10 @System.json | 9 + .../filament/Goofoo/Goofoo PA-GF10 @base.json | 23 +++ .../filament/Goofoo/Goofoo PE @System.json | 9 + .../filament/Goofoo/Goofoo PE @base.json | 14 ++ .../filament/Goofoo/Goofoo PE-CF @System.json | 9 + .../filament/Goofoo/Goofoo PE-CF @base.json | 14 ++ .../filament/Goofoo/Goofoo PETG @System.json | 9 + .../filament/Goofoo/Goofoo PETG @base.json | 26 +++ .../Goofoo/Goofoo PETG HF @System.json | 9 + .../filament/Goofoo/Goofoo PETG HF @base.json | 14 ++ .../Goofoo/Goofoo PETG-CF @System.json | 9 + .../filament/Goofoo/Goofoo PETG-CF @base.json | 14 ++ .../filament/Goofoo/Goofoo PHA @System.json | 9 + .../filament/Goofoo/Goofoo PHA @base.json | 14 ++ .../filament/Goofoo/Goofoo PLA @System.json | 9 + .../filament/Goofoo/Goofoo PLA @base.json | 26 +++ .../Goofoo/Goofoo PLA Silk @System.json | 9 + .../Goofoo/Goofoo PLA Silk @base.json | 14 ++ .../Goofoo/Goofoo PLA-CF @System.json | 9 + .../filament/Goofoo/Goofoo PLA-CF @base.json | 29 ++++ .../filament/Goofoo/Goofoo PP @System.json | 9 + .../filament/Goofoo/Goofoo PP @base.json | 14 ++ .../filament/Goofoo/Goofoo PP-CF @System.json | 9 + .../filament/Goofoo/Goofoo PP-CF @base.json | 14 ++ .../filament/Goofoo/Goofoo PP-GF @System.json | 9 + .../filament/Goofoo/Goofoo PP-GF @base.json | 14 ++ .../filament/Goofoo/Goofoo PVA @System.json | 9 + .../filament/Goofoo/Goofoo PVA @base.json | 14 ++ 70 files changed, 1969 insertions(+), 1 deletion(-) create mode 100644 resources/profiles/Goofoo.json create mode 100644 resources/profiles/Goofoo/Goofoo GP1_cover.png create mode 100644 resources/profiles/Goofoo/Goofoo TurboM_cover.png create mode 100644 resources/profiles/Goofoo/Goofoo Velo+_cover.png create mode 100644 resources/profiles/Goofoo/Goofoo-GP1-texture.svg create mode 100644 resources/profiles/Goofoo/Goofoo-GP1.stl create mode 100644 resources/profiles/Goofoo/Goofoo-TurboM-texture.svg create mode 100644 resources/profiles/Goofoo/Goofoo-TurboM.stl create mode 100644 resources/profiles/Goofoo/Goofoo-Velo+-texture.svg create mode 100644 resources/profiles/Goofoo/Goofoo-Velo+.stl create mode 100644 resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo GP1.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo TurboM.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json create mode 100644 resources/profiles/Goofoo/machine/Goofoo Velo+.json create mode 100644 resources/profiles/Goofoo/machine/fdm_klipper_common.json create mode 100644 resources/profiles/Goofoo/machine/fdm_machine_common.json create mode 100644 resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json create mode 100644 resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json create mode 100644 resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json create mode 100644 resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json create mode 100644 resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json create mode 100644 resources/profiles/Goofoo/process/fdm_process_common.json create mode 100644 resources/profiles/Goofoo/process/fdm_process_klipper_common.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json create mode 100644 resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json diff --git a/resources/profiles/Goofoo.json b/resources/profiles/Goofoo.json new file mode 100644 index 0000000000..441e3919ab --- /dev/null +++ b/resources/profiles/Goofoo.json @@ -0,0 +1,89 @@ +{ + "name": "Goofoo", + "version": "02.04.00.01", + "force_update": "0", + "description": "Goofoo configurations", + "machine_model_list": [ + { + "name": "Goofoo GP1", + "sub_path": "machine/Goofoo GP1.json" + }, + { + "name": "Goofoo TurboM", + "sub_path": "machine/Goofoo TurboM.json" + }, + { + "name": "Goofoo Velo+", + "sub_path": "machine/Goofoo Velo+.json" + }, + { + "name": "Goofoo Velo+ Tool", + "sub_path": "machine/Goofoo Velo+ Tool.json" + } + ], + "process_list": [ + { + "name": "fdm_process_common", + "sub_path": "process/fdm_process_common.json" + }, + { + "name": "fdm_process_klipper_common", + "sub_path": "process/fdm_process_klipper_common.json" + }, + { + "name": "0.20mm Standard @Goofoo GP1", + "sub_path": "process/0.20mm Standard @Goofoo GP1.json" + }, + { + "name": "0.20mm Standard @Goofoo TurboM", + "sub_path": "process/0.20mm Standard @Goofoo TurboM.json" + }, + { + "name": "0.20mm Standard @Goofoo Velo+", + "sub_path": "process/0.20mm Standard @Goofoo Velo+.json" + }, + { + "name": "0.30mm Standard @Goofoo Velo+", + "sub_path": "process/0.30mm Standard @Goofoo Velo+.json" + }, + { + "name": "0.10mm Standard @Goofoo Velo+", + "sub_path": "process/0.10mm Standard @Goofoo Velo+.json" + } + ], + "filament_list": [], + "machine_list": [ + { + "name": "fdm_machine_common", + "sub_path": "machine/fdm_machine_common.json" + }, + { + "name": "fdm_klipper_common", + "sub_path": "machine/fdm_klipper_common.json" + }, + { + "name": "Goofoo GP1 0.4 nozzle", + "sub_path": "machine/Goofoo GP1 0.4 nozzle.json" + }, + { + "name": "Goofoo TurboM 0.4 nozzle", + "sub_path": "machine/Goofoo TurboM 0.4 nozzle.json" + }, + { + "name": "Goofoo Velo+ 0.2 nozzle", + "sub_path": "machine/Goofoo Velo+ 0.2 nozzle.json" + }, + { + "name": "Goofoo Velo+ 0.4 nozzle", + "sub_path": "machine/Goofoo Velo+ 0.4 nozzle.json" + }, + { + "name": "Goofoo Velo+ 0.6 nozzle", + "sub_path": "machine/Goofoo Velo+ 0.6 nozzle.json" + }, + { + "name": "Goofoo Velo+ Tool 0.4", + "sub_path": "machine/Goofoo Velo+ Tool 0.4.json" + } + ] +} diff --git a/resources/profiles/Goofoo/Goofoo GP1_cover.png b/resources/profiles/Goofoo/Goofoo GP1_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..1a56866dc011bb1b322eea288f093290593889a8 GIT binary patch literal 25534 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 RGZ_E?002ovPDHLkV1gHp&xrs4 literal 0 HcmV?d00001 diff --git a/resources/profiles/Goofoo/Goofoo TurboM_cover.png b/resources/profiles/Goofoo/Goofoo TurboM_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..1064bb3b3c48dba6f43cb84f29506675390ac2e2 GIT binary patch literal 11297 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

O_5xv3{ggCXxHPCF(J)#hutA1r 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 literal 0 HcmV?d00001 diff --git a/resources/profiles/Goofoo/Goofoo Velo+_cover.png b/resources/profiles/Goofoo/Goofoo Velo+_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..d1e80038c5064cdeeab470c19f1e935cda01ff67 GIT binary patch literal 18636 zcmV)OK(@b$P)QohBWoTSoVG4{{H_K7aj`}6&4^IYjJ7|7Z(*8AtEU&ZFp|d)!$@lV^UUF zA|@+qZgFLBW)&SF8XY9X%+*#_T5Ni6Z+UPB6Bhyn2nZAy6C4|Je|2bXZT$WFX>Vs^ zZe$r6A9Q+hZFFn{3J@P6DQBf_QRucMB01vc9e{ zH#uKqV7j}x!N<^AWm@+3^uNNsc8Y#JLPVOSm$bIEZ+~)id3$$#b;8HM$I8WlihYcg ziFti|hLD4Jj)4&r8?U;mzQfF=ub~SR8-j&`dXR+V<>LUL=-}et$gT$^w}*>~ zm!FeOSWb|dj{fihjgXJ6w5ROu>{wq}%+1O~PDhlMmQr0&dVhcj3>AQsh*x7(6BZWE z&(Ex|vY4EpgNKL^5*nVOqob#&xxL1!tEW0bJ8pSuX>nnAd2kOC4K*|@@y`Vh4-;>7 zW!KHYkB))c)yDc;7W3d9`|VzY7!~M71@GL(pF1P|{RXV1A?wm&m5>?4y(9s!`b`7~ zRZ$Rrc@ge=PxtHJ^{I>1aICIg)IRmSq{q6NVUB1P>T&JfsYsa17YQ#sgr3nSxCW0o%-Tj6+NT z4pRtYAf%`Ol}ZAEgpd$2kfJg%q(YK+>vr8+_ulUJx^Ayt>vjM3F?sLyAN@~v-6dFy zPx8^xkud(9J@4=P_Kt~pJRXn7{*lXWYaMJrl=mnD~6{{^!@MNqPRsturb+ zYuAihQ&zidec9Yc5AT`Yt=k8BdV0#njl;8`tRNpxJPO7XG&FRN=^ir%FWuYMcXxL$ z>&EGJyl&sV^T?5XyLW8gJLk~@Tvo7a`V@?L^Zxk5l(T22oSkk7h2T!{jH;hE zWmI8c-jwQUz@0Kvy;@yZ=qxNG$Y(vyNMZH(o#WO#dVm|ccZ0Zq^G6l*S&($*lu^}F zs_P@wfLTZvri>azr=!lE1>nL_ptW;UfVWQv4iI+UyqN@e)TnCEdtP;Q zYoHbM9yMiNAxMnRM~!k8g07=zM9xM6k;wR61N$F6z}-7{4~-%~Gl{g|VNkMqR0QmM zHWI0>uAVuwz8d^JZ%QH9yAVR$8Uc|3yzp%Oks#w1t*yA$itnF23&8nn9!0>@M+s2Qe;hUC()B<5;j2H;xQ^Ga zzWT%Uuhn;d_~82W>mPh|{W^Vuu^TKf3O8xtcaI|AWk;r;Erf(tpRNA#n>P<0Jox6p zUyg68&x7i#`aMeLeMf~Nw!n00T zCTQu}N0OxrVRc8rae8x@!egI!W~>T$?AZT+`4{NVJoDx^a8atAo>AkEj{-}dt)9BGV8$aV!>SD~Jvegg*pWBKZUH{}898#~6Sy+=MfDym zeL!lE_#3z$5s$Na{E^KY9!V`dg$O)zX6eBvMiS(aTj=ogNP6=$y^I_?a_kc$m#UZn z{+Vy;t0TnHQ;$4~(NZ@67gi%6A_@~tF}Bb_h5XQGZ!kG)7*#fMS zCK0-gg!t)6biiX09={qn2_&8b$j{uYuCIr4**bM+e&wSFxBzx|-prYZ1E)U&w8MBO z4byexFlhDSBwPV-2=Ox`>+8W0p8DM%_hdd~>^iWl8;Q5|l!oi??x*bJn9ccPHusDv zYiMZb-=%8lojVrJtDadubLPT>MBb;LUJ7U`Cy#u3>By%i5nBT(FoV>So(ABtr9|Pv z`W@SQ=08+;pPDviGm?&D@~4fVmxlcO{4oUuJ!6oRq+Db}KYeN7$c}lXFiHzcrym@< z^jAxP3?huzrAvSHG%2s8Dp)$;8m^9fVkz(<)+pWaanId{3h;9c)A9!ZYz!f#QIMbC zP|(v;P|$$)`S~i~{++uQ&Rj^(g{M?i3@)DZG{Ia7h9-dtE?A1c7dkW21Xks{|@Hm+dIxQR%hj~kay$O-?4!+=5Hh0_7};1gisr%7HPj9<|W z7=BNJ4DvqxG?doig&;5zKRb@(_dZ-1*aiqNes)}9;><_6gZ3=`75%)Bgyah0|BldRl0lUwbKt*AVlN^DYu`goHJ+6^K(kJ&X`j& zXU^7fm>9x*%9!rMMB!aKAi?9OFC0JphMLehh3v+gYF_6crF>2epFeZ+K?3BXgWpUk zEgjavFmJ7#Q#t3v^#{{PJqPfm{YR#g#v&OWKXu2B9n;n4 z_=VG_j-NVyJRKHJr}L>(r_*6P#>~>vnaEy)!u<~y;Ew?q99^()2GBkatT+O8<2MAj ztYCBhFyI{vXHExG*DstpoyHD206Kx2K7Kj@ru%^hSb+>!ed+pv{d@7U`^dD14Df(z zkP3Fscv2-WxSGg(Sh{Wu2s{xiy?z^chDUbo zn7VFQJx$%AVp4J8ZRyluAzlX!K8zUZxdOaRkNW9TcYpWF!vuII0Fzf)RxpmH^UFX~ z9LA07Ar(#MfzB3K9a3LS!N{kKU@QG%0Sw3=zVym-|9v@#y!>AtBEVn#aB$p>84WvTjyn6t5f4W5r_Db! zt7AlS^AGRN1xwGJJQpOMyZouSfKA8&md0~)ea~0J>{**T`}pj&$8&Q>H;z6&`^uHKDmT8Pju%gz`t`U*CM@qmNE~gg5WJ_T!I# z`O}a8^iO~I+dur}=WQ!DZh7&eXlt+Kr+#exes^1DX6~8!Y4hi2CMM3R$y|hEdPjQJ z*7U7gXLOaUwJ+ZL_KOe3JF8Z1+_-V&N<3GtT!rJ}6)RWJz+3wHpJUs~pHKbx^I!h- z{y+ZHKmPg8+qSJ-jDN6l<(8MC3i#BIH_La8SigV&{>}|O`!^(Pz(TVg9QN;@ctIV-$(}%Bh=MHkHmhc5M4HtROqG^Shl#zWeUTcl&mIw`-sJ z{O-Gb`*w`D^wzhpy!9>(96u!4d_`5hP)blsba?4q{CxP~uvY%?rFUQY@ZAsbWx(I_ zFaP$}zy9^#{(b-J7xtd%{p!O_i#Kk0Dr)@vFyrr?w&S=9`H4> z?vB>p^-S#9KXHH0M2rp3Z-BQw?)eQfp5HKM!;=_u5IWD8@#K?mzY#;v+4|%fTznpf zHBZjiFk|AxC)Z3YgR*~;!Vp-v{`I>yt-Kj6z;9jp>UusF3NBkeZJ>K#Oat-&V+O`d zn>LU?fRRstG4f%a)UjdW26}FIaswTP$BZXu3=f?lmf0H4MR{Vc_{& zZ%2)(Z(jQP>l0&;pzS8|Qr2TyLxXxcZS&?aJ^2H}h{sLr!NSoE6A3Ji&*Qj;umKs6 zZdC_fXFRFWdd`gD8$oDiJh?`-<*Gd=A7)@#!-Wqnt^6@cfWN)<_17OvB#;DiK;>#R z*E21DGcoi78jl-hW)<%SqTn0?HAlrZkp8sR4QOUdpzXC)aXn692>%A*q zj1u7WH~#SDSC@8wx?n-xsPW_XVeH(w^TN}u5K6F2s%pPc~dPwd^g_r%t{d({v3KDj=BMt)E42S1&8WmUA| zq#4)0{lRUsS=?^D%N5e;bvC_jiC%Bfm0K)=4wo%%xm+jddA(qD>-8GRVqxM~m)^yd z`z$=qy4?yVu&joaSw@!h0Y>B$jxoBevLIO%C18~p4aXZ94bK=^&LfD<$c5K?_dfeh zv?yHg!4E%t8nP|X$qV$lP)M)SS<3Y`w`|e5hb*!nhX}L97~va~3Ue@VDZnspfx45m0Vkrl!GD8eub8C!@%yH*g0RTkCI>dp}QcRvxkcM!Lbu#oJ zCkPD7UJlXHsB^I{>szy;5w-i?;hD%iXPfNgq<-l+c+)D1Cuy)5Wu z4e)aCsavR~8_*f|H2HS#gb}Z!q)_1d-=B zQIp5wpE>cQ>#T?K+&Xh1S`_Xt1KuUz_g?k*SH<)I-##-Gk; zm=MnmF~X-4CJb@nP>dQY3h>mV7;$op$2objlM|hS!1+YRNq56Xly>4@3ZiIjVnso4 zimdZIMr@Pw)|s!O1-N@nu|;RIVCW#O8dfq|WV~7|c`^^K7RouWBO`=lhG%3!U?-R- zOc44uiOq2@IbF@mJeQm=EkEy!SuRL(MW>GuoC2V!=$y`gAUK@(*EkimTuT#lG&GlZ zo^xL4{qj__0GAa5uRhN0mh~DvXK~8%klvp+Bnxg9+8K<^3w+2bGwvZbX!U#c{r4xF z_kgs{nCj=w$9Q7IcVm2!n7LfbT#pk>jt2-ViV=bHIOzgp*96pk95-YTJqlFWd5`!( z?>iqwi>3EB+sO2~ZLq;IYw^2hXJ-{)- zCdM>#3+Bdo4m)FFBI4Z1qDV&87hwTdsCF`-wWm<@h_Ozog@cs$F|3E-9fElNyl|;^ zMf7C2*rtQ^(OICk+?sN?QzIMozzT}y33+ZNB=C&Fh(nB(hvpG}|NGxNonYK2A)7v5 zAV8YS=@FeA?5`jQk_Z9^a7S?61EY&eo`}=rf$B1`j0D34@pdwo&b%Epz-yXyHdRZz z%iVeU5MK1~vt&zoxghZZQ_gA_PT)mRVJ#N;RK9y2$fvlg8EgwDf_HKOkEajlJWx|k zj%*L-q&wjBcv?ggcvvfXoSatVTDU&8iDS&1hY^12eK%S%yr#bxR>>U#NTUohTy7}` z!OLYCzLwst*C|6GR+eR})u)sz7O=IbNP@(wR>%{OM57b-*Xc3AF8MsX=n3FW#7WFe zR30)xlyNUSxFE6)+&ae0a(VKt-VdV%crTO|xsy7*5jfpA56L!Lar21cVqJ4_vEE{_ z+AMIu^f>DE?j<@~9Js-v1muVusItgaisG{d1BykF^s+AyX$?r0NUP5sX!Qi@TU+ZD zUxwFi7h!x`z~3x)o`)=y-#YW|!6*UlEsFzQ_>eY42Jo|R(5GEGee2Z=r!QQ%^ueV| zy?gGSK6&!wmAiLOzJBuV-JkAe?m2npZrX*+%F0D)C$HV@T;ElBH|1_x+Sba-wzkTY zTFQ-e)>hsjonLRsqcFx+~%C@dI>Qd_7NNH=kl#-Hi0k3IEZ7CfcSsf{9sktZjWG?DD zRM}BknNwMr(pHH_TS{$8TiT+ut~45zZSyNh+&%EQJdEmJGyH|<0siXRk{=Kf>L9qX zMRr@@PFJ1Gopt>9$=Nj4?n!7*`At$=(iDZoPFrRna!yu zPiAJOchz*X<#YhBI=VU%J37)9-KPul&p^u0i!CzGi3~*%EPvt5+tC92ZP}-KJwiYL zc0qzIbl=ndGfAkhK=UVThEL95DVAZc%gSw zw3ODDWk2X_szO4DA1ddep4Y8yynTFj?&#yG?XySEF3Qe6y+6D2H$|P;)z+TuOz5mj$nH$q)0=g=t|(#tthC(3T+Cdg&Ci{mnbX<1p|icM zt*y4Q4YHh4d3$ffqc}OZ&_fJT0c_ro<3jJGC^;Ud`unHo$t)p2vcT&=YR1}nIyV<{ zO1ZhW8*@jewkKq-K6I#Pby87w@8>vA%C4K;{&{w8LUzK*J=uq9YfC!1(z-G;=clG( znr8m|`GeWD7*Jhp31IuQl(x*SfZ}nQ*$4v4CZ1)_v&px5S49c%;{64?^)?+68xq`% z5YM|ArS`bYxO`&65TS{j~Wk7JA=ip<@ViOB3%{p%NZhSFnfOo>DKwP8=*^szl zcz2%lRcNf^qjQhn2H4}HQ-|T^rj7=n+*yr@=_*$IUE zo|4km4g&_vZCz=ZAo7!}$5|*e!Rru_DS@iiUAV9%N?FUd`Wu!pdL6^MB}Q-|iQ{uy zbgv#CJsQ)bYi|>MbB`D09*0c^;#q*0o0^?FD|Z-gT0(nzc5Qo7PEt-CWH+fjC8;Zk zkP>CvvOxDmHEETVnKQVED6ppUCOdK^tVa~A7kZyv8XdrY+g>nWH0Dv(iFXS!@>iT- zIX!w0nP4a)B5Q7HBM~+=w{ccuW9lq$bSh1#CYIDD0AfOWQbJC8O+sQq9V~MK@p4j8 zLPA?+T3T0EWlkDoIPF@budk^^XhLS_{P{l7+2rr--54bbzw}*x4@4IcuZCrjs^cVM zD6Y4puB51BFdKl61845&*{P{Gs&uVMOrHhRc+Li{_8ibRr#&&TeO69edu_XV1Bz^xO_``Jt`9_O|XL${4VT>a3I79B$ z?Sn-{b%P1BMg!&O(Www)paqkIp=aR+%%V5Bv$K=36WUU8+Usg+W|hoOuLJm`oOH-? zS|$L`2aVG@7Imex)qd=ZfR9-i;wH|)u>vQ-4lj<PqTr(sN2mYSQbnvQpC%6H98cpsdrA>gwupaDZjkmY=*>|G^cw@o95W{IGNaZmtMDt=Fnt6m&^eVtP*cqRI}H;yLL^2XrAq zgdigWkliOls%fd)hzQqbUf^oV=)JJ&!zckh+~2R^jUX_mQ5ejEVFI+gZV(hMNj&}P zl`B`y9X)sMx946s`oeF|ojdmB)vLe#?QgIC_JynGu3mi|A6$J8dMhabzE)8Z-K3&J z*|jO{hl(HvC5gF>9XY_AQhCi3Tga(^>m@I`vOHpFUV0&ZTCzmgOJUqVpjt(DxH~jAM$HQ+g)60K5TKV~*tgNi>KHje|5GNjOcah51z# zR!S{iDtFnn^}`hAte8gTn<{!wL``Xd!Zscv%xkz1W_RI%@YcaQb&ZW=mSC3#p`Vfl z69$u@sp}9ez*kOcze6`7iQr||CZs@mDU84u+Y_Lr+jDRyl4?_OQXY()FJfao9#utgWm?chOBp$Q){-WQ!+L+WnI9QaF4fTUDNaW2{{i=jIc+g2n zcj^W~f70Ceq@Bo)PZH|t=#Hec0XE?$laz#9&$?Kxr%(kPV3F})_}1P%tKN+sU>yTZ zg~bb$GG_a*7Uy?s2a5*Vi-^R7gP>$W08HU?+VKqmI6uguHHTZNfd1x$uFfC74-B5T^E? ziJDpZa(%xJ-Uer6jKtPhTjjA{9=wy1bSL}vojZ53Rp3Rq0iS;kucLFYQ>A+`WIlExWVWlwr~aTSNoHHkmNh z!tCok6FnJT*6+fffK@lN(u!>n1SN9r%4eTlc>xZ_%NX=RC%>hEGxajg?!5f+IrZYp zFJFB5!8h=7jILaL`RYZS;{58luRpj{9BVT78MF?@AUYVc1AuSrc{Ykl%VlJE7h{Ga z%{q98!iGEU-@kpo?f(5cx9{Jny-(xL9USi7xeapOzkNsj1lRE9j{2c`ynjE1K3R0X z7B6@2-mkoSw{lU*$@{k}n=`Z~gTZdsa@r<=Y0I3<_!93Dr{;nLUY=U>s|y{}&Q3jgB0_uhN` z_0xOyj4+u@2Cb>dptZA24vn8#c56=*S^BcgC5Pa0!2f80zV5&t5)*T?(ra=OZzm?! z+)vL+#|K%7HH#9FEub^x=#k!<-8>Q!bS=uRL=rC%!EolH%$m$%!P#drw+Iexyn#2zJ1n;VI9e=ybyxoa4Hm+}mu7j< z!8%#Sdg;m=K#Vzu)yLOjP_j0)u?CYYjWsn{>FHo@WU+21sv}F~>MWvh4nX5Rq^2cy z+^I>+93GUgE%rF=T9ek`fCOuhowi=TkvTGI6b4`;h5s71rHQv<=7DvuzVa$|r!@kr z3K-K%m>q9SO}tI>4e2F`Iax?*&`%CR;jEIn^ep6Q)A0^0pOuKTU1iRpj>--!0q96f z>zI`pCwQQz&1QqW$>DeKM*sER%vDhY+^mr)NP-#Wcz+YZnOpDu?l-T#x_0$i+MNgJ z#|bnN)QzAhR8@L<4xy~eq7w|HIMYi28gJ6EvSU$4PFKyL%C4F;VEaT&wle8F!gF2UVU}73LBV@r`FI+ zOHCGGE>T4m{0t5!C62sqNmfUCrMi%%D=TRc<>E7ErFEpG&A(^TirQGM!EA!kipRq1 z4|<=E9^hpSajtlZmGX=l7^OUisLVe4+3$$PfQ=)K)x)d}wVViL3@Rtq;E)BKMe3Pe z!PK|`m~FrkkHoaJl9V)p47SEZYQP?AcbK$hvzF+~`2DwfudRrh9p2yH?03KdI~5z%4r=K)2xTW zl6i*@84m+zW{2*bdzG;M?l%Y`R9X{91GGxxMshJ48%xOFB1NSdx#LG7FPS*ZeTTO^m_7A~cNWY5Qem>q71USsUNacNbwD17X-{y4-9yaX?Z z9da17qQQ|YS>;wq@dcEs)?nD`^#y%ZUaMsF%SvliFzlrD=OlLI!Lx5}Cfd+YZ*BuOH;WQP@pnKAnvMvec*jW1U{7cIaa^<&YY#)T<| zcr8miPt01aEF@dC=Hz5;JSiHd!4O*?^vMBVvZ*Rk70j^5Vmm{1lg|@0nKH2MU8{|a z&9EbnW6H>gwZo~>YE7~BSR4$o27|$zK_IqgB=8z()=BG$AfJ z@&rdyOG|Q#St?zJQL(P|-nxp4iqd`7brr#2MbLY1Do)mApoPIYDlWBd$M^eof46UH z(4G++n`{Tr*hq%m+o#QNWMr6e&8wvl2`32t&G50z@n+WG*Sne^!z-f4(pwsK!@=Si ztHLQxgy|9s+FYA_MmV8w)?~n7oXa(Ru|7*p(?bA2!+ZDHOYNV=l-8|r2x98`d-)%np z=7`daSU}FOXJi;m_Sj%-&}2sr3&ReMCVONDR~uBOrgVot&KQ5=L^J_6>^8c1qXQF5 zc8AuZZ4un-{^j42*IlcYmJNt zG=gi2&CuGt!C2sjm=lNFwV<*A`7AS~w6u1I*_`Z%*YS=Ujqh%Y7T{BF_3y+US(a&X z2&~v=iZ%DKt?&Q&&k*8y-;JNtT3@lwQM&FPB)WCot*<{IPOe{9{QmpNt!Ec}QNL@_ z&iYb=R>`mjBdtMihRIgE2O zdVh<|NbVK~XV!*IS^*OJ#kyU)ckkMIJ>~W5txCmT->+DA@XFz1rSnK?t1ABbuYdh( z#lZCy*C$OHQBeVs+JP?C6zc(V#|9z0^aRO4dmIdA=q-Z@`5gte-mh_ir9WI6t-2P+ zK56K7F-DCf&|XjmJC0031u5yN#rJH*G{;#QO#X*|y}PcsXWi6$Ureniu84rQ*R`&z z$RK5oI{+;Opmrztn4SbQ!%z=?Hj&OU!8{o;}8TPWlTeTF}=Jk6_8+;;}*e!==%3JWdVvPjfji$AYcD3dftcfLF9TeHp=s zQWX?4f>K769sZ;j((TEJ4V%HS+6-*LGLXYnW$=2*2$O13k1$2{*azocyDG}D!)Oux zgTQ`3=HoRdV3wi=_`UuCBRosiYE?{vdS-yu zk#Gh$)&#dIn4t{@W6j#wh$%yB@Mwb&;RxJJqPl@B5mdF7Qqp!fmnus;%&427JF)lO zXQL&<8!z_vSb53Vhhhej!HGSlA_+zJMnX(N=lDqo8U)3kOQ;#WXK@jscU&8}y0>Br?2O zZ51+fc4BAPU)&JrDS(I10Y6I{YsOc##L;HhB}z*hb-Zr&iA^s?3-HDF3I^hkzQg<> zCWuX1(6q`KfCNK?tAd`OM=Q3*3if~()Yb-JYP^P^*B*{|@YVpJUNt&W6;r(#o+Wu# zTGb2#BVsKR-3l{JqnRneqjhMEHrT--iTDW`M1x%few;x`ss6^WH;pKmPT*sy z(+%bjIPWDy-F93nS zkYy+==wU64EScPlFk)d4H?)YmK=_F5E-$9-*RH_sx8r?@Uc_fWk$#_uQ5xK zRZs#|Qot0c@_B`TVp4=ivKRVE_QLI|^7@d$al{70rZA`V8nj-7_puOVZKMw>*`Q4} za3Cu*nHI!0la{9G6-oj))RdMz9y5mymoCnD;>3!mDXjws%Eq`XjK7I*@nB1lPx5(u zO3*8?gCQI?^qEXfco;-+%#1>BlPGJ+K5664 zL|O+!Kk@Mdcxw~^e^W3q4wZ$PG^}XA9&WGV2}Y_EhoW@`!afe(hp#H=^LYUlSv;aG zybS}~DJ>aTbFw)cM#jo+hB`Kf4antSxlRVKnvmB4SO?;N;4~9)HHej11WcN^6I(Y$ zk)`{~bS@VXwOG+2p@M<0O0iq9WnUEfv{rAh#nY-tBC@iIlHm-PMQ<`pt-}mL2a^#p zApCQ99m$-Q94UJrZh)2+u9$ec48a<_T?7-$STf86nVwu(Zf?9=0$vG9P z)~9#_CQ0;YO<}1j?6XP))EiDlR0uitB8_84e3CW*BLiw|R~oIa;w@6)yz`kWD%BPGM9 zNP#}5F9@=lgG64%kPPp_t98U8v=2g;J4}wS!Nh7whlTBZ1`gg92yGx{;07t8?<(6an%i=WgE+A$F!Riwf#;UaDc60hlgBcF9-=QS{v5F>jI&P$gwn~6i+F5vx8?;=+Mzdmw)S==&|(8 zWBp||hs&rzH7U#kIZaj{in{d~z^$S|i`}4hMN~Muw@OwNr)c(t!(qi7n`{V%LE#`0 zyYM}dP01#5EldPlg3z%`Lbom}0?t8Qx(uLNWS{E=}Clt*dU%jT(jf%i_#_ z7gm`19bunj7KbFSc1V;JF_3Js!}mZPB?0)Lw!&e1xGHSc!r==03}FydFd$rl+?o(J zBxfX3AgHB~L5=y%VM@=^azm|IX0dz++l5d{!fheIFGdgW=6stQ$zr3-3R<6+vm*ZY z`NW7raYh6aDoUB)Mh$te*4AgK3VS7QRj?`SGtm^Nw#wju`wUAPB;7P*N`_hX#*!mR z>+XgRU}$02 zHV1z7hDC#?#i>Qq6z&TMPhOj^l8(U_iV(-`RpE)h!Z8T1?o(IY0XI1wnW0__*jXJ z^$Ljo`;d$^BL!eKF{oY|<_tXOic~EYIhb20STd;-hrCQH!FZUZC{p<5vGomcdYd0i z9q*QWtkoH@vglFqoanRLfB*Z~*t765oovA1u?q;M3{Jr-XyJh>6jNzMAq))_fo4(^ zBy_CyJcAPz|4jBU1MZF|PNrEyGff-9`OvuH;#@{u^PD*wUyNFPX)KtILup+Xw$oy| z6k$@JN{A`Wn=C31SXwCeC>}+TeSPpgu>DktXeCzbbw;RiWm8y;H8{yIn_!4QY%6bo z>DID-gV6fZNf%$NgA zOmR#M^NZ4|^7|wqECqZ5FZo)$+7^dBz>%fR5S>WQH?^2r?5tf9eO9vq4)!RVXz;dp zT0n6}vX!W7GO+PxTG<#6yJWTL#OF5!3!7H|8lRyV4TG76FbE$om- z=|g-hg_S-@02bC9z&uM;a#b=a9~!)2Ap?GMEa&h6f1gR~2@AZ}>9M0ut=XWi*)bS+ zhZ-Hi$ASc-tOAmj8s+(q9f}VTJJ3E78}@a& zT!H5&Mo~*2JW`-X+65x4!E_6jhs)Tl#Y!>k1Hh9N2i7n7F!us4M35v!bQ-+AfH~|D zd{|n?Ih=h|sZ=nd#-qv6;(*Gga-{)AA~(yywGe>~YKGP?W6Q3~<%(>GCg4*$H^;fK z!IVlop!hfHPN2+eOw5yGa)wRts;jCz0YUOQI8O2c zDm)jKlTa9qm8~W%hu;Ndg=o0Np(e9(`&{)-{pdKsdGx=n-)GGW>36-Rsis)n6DiKA8MR?*!8;E8_Xo58J5)&^W z%Hrk%v02N-C!0x#A;3s^X!cF)iCzNW=FKAwI+ulaOB$+tfby}Zc;yZV@m${f4j<=M z-eXPX28v7RQ^RIO(J1CHiyeG!UKAKdvKVL*JtjDyoEI}U%#kC@j~riY+* z0hAV&Py(No1+L1p`!OU2-Qeg}Kr;Nut%6J`;7P-g_54K-=i?2hcPYTP_J zL~vuqO^Y7jn_Dh)7sJ6tsbx;)Mbu66aqO+hlXu8cDCERCK^@Blu&Z0KS}}!+q_vil zB?hYkkk`XI=s2^0FF?aPnWh#LVAg6{Pyj_nLE_2ke=ryRMiV`G1}0dY#u}KoK6)~I zbL6+nnss{Yo{~}a0GpPqObgH2;!s!X!8ZaN8({;2A}Nxr(i7)S37PAFsK_ih8X_ym zD247pk-ub|vqqHB=6Lh)Kc9>3P_!?KacM&Mak>4vo}Q1RsHL|Y=pNyQGNDEl=-VJ+ zuQ*Q$4>0yHiJYR9MY($go8>v527JtDS|k~Y48A1F#v_zs*$8cX@`-Sw6_hYCqj!nf zS{(D%+i$k4LH%11ldhKg03Vu;jmG{1NLSG4Gg%*skMbUH_Wr#JeS&*u+PWS zu75Yy!K=|fTA%pGWLOEDurVd?q@sK$K#YfcvN znGC&!xL>kXVac9^@`y+PD6Ey2C8SBHNRwm+dy9Tr#VBF9h=wm-u8tUmfj22A8mrn0 z#I18_dh(B~SQWKI{I?gnN02+}{iEe_CFhG(3tmE|7<4{)&=G(!+1zhVubkiS!H z!ov6jq^Z!r#HWDdj0KEtu_Atut(+a*SOgzqc$%0Tg-7IiZ!xz!th`{ ztdAG`a=>cE)*i_T#}Z4)*?^US`3Xo)R_W^_Wd+|uc2l1oA95S$aw0l4C=9~KxHNiA zs70@l{Vr@uLu%SGam@bcWi2=T;iqNA`Vg&CcZK*o5r)!925BwY8R;4vbi)Swg!Wj8q;@69SF-7{3_9x&inv|2|=YkysREr<+)-sAmI1 zLt4KRDJ{N*MKtNgx2>>L7HBY-EzSwG4O0gEtWo{_p%|nGv55pq4Q?i)2T*$Az_IAr z;Z0XZEc+o&2XC6Uh0ryN0U?GalSe2|nDD<(_+QX_N7Di|rO4zsJ9*5h8c@DQ!D@1p zT(wG^6%L1021UWpXgwsr7YFf?(|14kAN(?+U=;ifA#(=gm{IE)cxJ`6s8RS>^Y(zv z7U%MXpl^8Ig842#+LjnY%7nRdmxIEJ$V&8pf;NX0XC9=t%Bk=kpGJi5Wfd7Sl9ULU zgceqT4JNz{tGX>5T8>$Vd_1ow>2rS zY8a91FJ$>jx=rDyuJhDIVED#bRpBGVp3`xo`G#Dl;Shs>^9SXjNBs@Iw;qFY6 z8Q}*;j-k?Im{!tj7Fbx!4qG&u&6ih1&(qp;s$%<08(N0x+%QP)Je1Yq{4veVlba#K zF)>hD%8*785%dSp(@&AOCacfv3m~l*2%ycM6>b0A61+?_pOJCFtWDNJQDe^tABthP z7)gjRss-qf`gSocw1u%Tnx6IVMiKDg@4I&+ZE1syQSUH|D=&l`59;!g48H`xf-Jx@ zl+cm}GY<&%@k1^qnhjw#ktG)91dZUw3=3B;2Vm3CTZwlLX@nRJ6EozCk$63HAs;gG zm?*Uw^&#WH`j?^yc;$ijwjZ&5in{oE>I4vCIrot2RPq+E^uL3pVSIhGF_BbM0K82z zZZwd`WvFwb08iWM6Dcv<($t4Ko#>AS&m3BMg!(_A_>R$!a{ERW7RhGQg>3ojU)mNm zrM2?Ff$c|JAp)#-Lak`5A;z*Cf1d>ueq}NM`;pC&BpG=Dk4G-|`6Ri?%JCx79d7LW z!CPL99*hW)ET}+^5P~WjGP+;lX;gthM%2e^z|JmRNEfFYxEw{m8xI`r-f3Kb{z7PK z$zy#!yrew!?*xU(DnV%>b;nWOQc@t`1P-}7K*cmUixq8Tpqz-NkQ75go2s99;CToF z^dMSBQXC9F4ogVNHE~9l4aJA!z|t#LMk|T8apkd{+lyTmS6rS>a)lTsl*gj{G858+ z!jp-m1)5(`z`d|HK8=7m6iROTk)W1*P6{^!L`Z@}Sy*zZ;iYiYKYygYJ|e% z#2NVzdRSo@p363^`@<-*^u}Y$ra_m4+(sRm!yymgwy?PVcF0DqB>*Fl!wCwSaKM3v zW8r0uk{Tb9W`@>A8y18SqO5VklWOwGTqqBL5t{!Q0fPv9_kUq&KMD-y*^DxSxWTW{ z57`FRzq@!_)F=$V`9`!^vV~j{I1numG-x2^jPd^xJWxuSd}*r>={$)Rf>1|LK%a)<5dei_T#nYg- zLAcx@i%k!^WN~9J0HbpQ@MQ9(1)l}JGFJFtas?4#03HWoeg?@aG@DV%87lu#j+hrc zKZnXCUiR~%1*=G{dOkE%4n@u8k$0tsZ-e=N3m&#*11nZ8j+)Ziau`M8^m-#2EP>kh= z2^0SIx4%u8Aj4%uwNbc^Sa#`=hG2>G5-M*Y6(BK4N4iCL%6teD=}3fVBrE(2Fg(ZT zhW~@@s+K0|+Khe}KbYcy?rkfhCc|5{+}wT*D{FL1+~^}#{wZ1!xot7cF)?}W2QrM- zvPeNYWrjfnfsB{TA}bAL44X~8mJuUT!(Ie|I!b*qZq((rQ8#IK%nc+5jTWOW?`#!Mu#pPNiOtjlv7DLz^fGEx^hFtd)#y{&uN;*C+0;kP!uwZ3~vNT)+9Ks`0Lq*k?PFpaLu zXrQLo`GMc4xb>XX?WQKZ`nq89dqK4E%tkE*WpgjgpOBxVb`vrK-AtSme z!Vvl4Yq+SLBE16}p-4#2nGis|^y3@WZKEfb-)-~TELb~hq*##A+rZX1iKDpC zX2eCyf@SMZ+`SO33gRDb+SHA@hu~#uy9^=I6D*tBo>f;)t>e&byIcuTD|t8CjKew^ zWjPP-C+7;GMN^*J52mKZ>O|B~2rKOv&@zNR-68!F$Osf4UUbGdV5P>tah3(!2exdC zTGkR%n*H4ibSeo*Qv)?9p>xaVvkm-kL@Y8m-VG@Xp?N&M!a|4TmHW|^$~EMsq=6vh z!52ry#0Xi%1zu+%>!U-G!w<~rjfB>MDJE+Gwbi|Bt87Y3-a)18;8|(Xqd{t18lTe5^l09 z&Jw2*T_5L0?14VpaK~VzL*%J^>I&r<;j`K38+y8fFjC+SaC@B2zwOlD-j0dt*s|rL z10!_SVlZnnM6B5crY#0IAc|W8U{EwmEYwb1axcLEp>#&4JhVh_S)z{v*VBU})?KWZ zpvU}}n1e$q+lV=q#6evAZnutFI$Qj47X8nsPDL3n*``ffPMtdS+G`i_IQ-gS9B@2# z;PAzZFJGi_`0()Sfr~F6ptF}R9yoCI@L?P;9y|8sF??{~HGKHmJ1;)_BA)n72fn>f z`Q46t#UuXXXdW@*=Bany`8np{7(bo7hd-)#L~(Pm?OyV||DV5&);vwV7YxpuH}BpT zQ%YwptY0|&tzSNPD8^)TD7b&_+oL0X`n&(?^&fwJr}MR|S7RQkv2EvTub+GQAOG=x z+xd6@)fZ0Rt-bT}|MjEh2ny|C?J0(^JQh-0tS9{A7r)gx-Z81duV+g^LP zbXLs%5hK1m{Garzw~yF!;H{X4Zv5v(FuU#*$2=a7$K&yMJRXn7 + + Layer 1 + GP1 + + + \ No newline at end of file diff --git a/resources/profiles/Goofoo/Goofoo-GP1.stl b/resources/profiles/Goofoo/Goofoo-GP1.stl new file mode 100644 index 0000000000000000000000000000000000000000..09ba1bc44a17e0e7b7527ffd900ba2a86e910e21 GIT binary patch literal 42284 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 + + + Layer 1 + TurboM + + \ No newline at end of file diff --git a/resources/profiles/Goofoo/Goofoo-TurboM.stl b/resources/profiles/Goofoo/Goofoo-TurboM.stl new file mode 100644 index 0000000000000000000000000000000000000000..79fa370b240d51ee68d54d10a06f2e910f3d548a GIT binary patch literal 11084 zcmb`NdvMg%6~_;dY9bw^L8*?fDldl_9oy{kD%p)YIO6!kiIn046@&ytjnVkVpGs?p zk|^~7MFFF>JY;0pT@%pkFRoK76-EWDAOx|BgNg!Ss62GibMF0}UVT}pZ&38bE2$gEB}6f z;*i)s`aaPsnX%EC!|pf4j=`1ewJ~eGx@ed9ct?H7JL@JyB}Prjv~2xJn+)O77~{0r zvB;RWPrS7ViiMpk0E_8JK>zZKa8E!;=?gcb~n>v>a)d z=qTJ1`OkR;hIp=jS@zxcEP=F3T>X3|vgp2(4N+ec%TBrcD-#20m#ALS5IN(LA%>W` zVsy6sbxR=a66NDZMt0PVvN6_=%1-~*5=gs5^Ncwqk3MphA zNdqRE-W|GibV7*M4&O)GCI0!-`N_xMv3)gfeJmlh5&~(L*txcMYFy(lgO-;iq~$^& z?GkSu|46Fg;{JxHt4SoJcZHa`qKkHkf!}|S+EzTk5cB$vNyrEafwW7Ey62p9!GEKM znE2#H37I9PRzSPNiML*n-g4>~Lu9I_Bno6Eatx$h;;~V;j+lOXtyv#+U*D2AmuGt! z6G*$n?v`|F?&Ez-jQTm#5_PsGnLcY$&z(|f`l^b* ztZLh2`U>N@#OS97M;C?==ry;!JyBb&F)r9OIDJaJjnTkg=2zPo7|$hEeR(80D1<<- z9&~_L!G}RR>h3z4UfO56X$QtYuUey)7NAxMr^lhv5l*(*J0=@M2_RLWCa#j59 ze#>Ir3G~u7SzwIGB*FC9%wv^O_LnqR9hF?7@< zI>vK}50+P?c$VZ4=%usL#^^V(B64ZDC3N;l42klgk~R!f$?18k-}xMyI-v`IZ?eNf2b`q zmP9n6_p;azuT=T`|1iu^ST5F(D9F1${~y)tEV&N}EQx4WYES9=V`uSvAwoiJX)V%3 z4{rXG*#m{pJ%fJg$RMG%&AZK+vFQ~LUXzkct>^q%E<2{bgz1qYQ!h9BDU3 zZEc~9h3VZeqKwb&NSnTD(LD;ks4c|8>b==o+3ncQPoS6D9=DHZ1n->J2kp>uj@J#Q3w`Ea^S}qg(>K^qydeaZ|?*EBM}%+33^?z4V@7 z+o3(xoj@dQY&#Es+VSqf;)=A<#?j36{99=le}(-uPdWJv&xwIvdQY&#pi7EV_fA@#L!g)56D%?Pp-i%G*3Ti(OYaGm zn7gqiwzm3SUcW?PUS)8zu*AWm>td~=XBZ-^CPH9IM9UW!#m8*_gCW9ND+HFrdH12A z@kKwx3=!6&rdGin&erPb1ta61kGsGSVWZZ{F|Z_}UwcF2$%8gV*vt?DOCnmcs3^We z+Y#J^Wi}`+gxYqN96h`)c3!FNtFRd^1kPiknOkaN*9PMewu*$nl8C+>w6wJ4oQM6o zlb1$urQ(eqOVW(!nZ63k1`-2HA{sShY0DapA#7O2DdXJ|OET@qXgk8Pnh;nL(Zh$< zWo89^6_z=Lz>>^(_&Oe8+1bPh^dOJ-U^C{vj(OM)AOw~~^z4F>ep@iF!gd)Uuq2|s zvxfSQ1#=hoJEcXFQ`_!p3zro6E4JD75w=?jfh7^~8qDY#4BL?n5vX`J2G6U`@d(@X zr5#uj(cFPcTUvuL4?9^1fh7_BoplBxJFmh{FG65RL{}aDWc5kG{Txq7i}@5*&nIs= zAz?|KCo(e=!@NYf%}aPlsEvf!M0`)n@O{n1XlmP=y@S;OsRnAyPB3IUy#rqk?|*5b$w%! zTP}N4XLKRZOXq?mhK^}0Dek;^*_qM3CN9x7&h(XufiAqfwhJfX-Alsv^Fonn^sr3Y9nF$s(sgy=%Kk*Bh#|v3liERb|y~ZzWP;tE`eS; z7cBAH+QHFB1657?y?aeuVm|AM=|0oVs>PaUze%|m&*+K1>WTVAMo?`bknWr%Mo-k} z-3g`T_c98e|8~*oTr1+kY1cTbEitgR`3dw=+s-T2MMK+xG1RuTg4yor2ufLMOHX63 z^I4R~qakF~Vr!MKwF+Y7^p*CTv|MSi`Rv2W_LCuFj)Z0 zjV`rPTL`30-i@y>dLb#6ei1@#A+Uz-dz5~W@lac8i0?-EV<4fnlw|hv&~{+0)Rx*3 z<$LqOS)#U$k#7XCuhh0N_+%M66LI#bZDYv#3!8~JOVqY8IPZq8C|tE_+Zg#)6wY?F zZH#=G0pE($wlVT$23)mj+Ze%n6lY)}d=tW4qP8Vgd~5y=ASF4GcY5Dt zDPBk$O(s+qRb^8Mr1R^ds*wtTbbeh_mCaVE75r@rQ9fN%l}#a#&aaEAvMB`8`E^lM zHibZ%D4#B>%BE=t{H+nu4WHJ;N?8}>|A(QPi7F@3?(U3grrM@f@HbPkD&)sA>jTwH zwdI_Ew4;l9sAj4y1k#Q!>YZ6S~*0$tQ|bW!;GM5G;E)I&8>ZK;WtB=OwwKs8fs zA&@rnN_9~W)l9Wb4EP(*{JN;>lyWXbnke7fw&q~j&)w5&@a}A~D3*(7UzhkF@GC-C literal 0 HcmV?d00001 diff --git a/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg b/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg new file mode 100644 index 0000000000..a1fc804f20 --- /dev/null +++ b/resources/profiles/Goofoo/Goofoo-Velo+-texture.svg @@ -0,0 +1,6 @@ + + + Layer 1 + VELO+ + + \ No newline at end of file diff --git a/resources/profiles/Goofoo/Goofoo-Velo+.stl b/resources/profiles/Goofoo/Goofoo-Velo+.stl new file mode 100644 index 0000000000000000000000000000000000000000..db004034e6971a44c38884303789b0b31e517113 GIT binary patch literal 12084 zcmb`N3v^Y*6^1t?q!tzw1yssZVO^musZs72iwn`DwRz>hpQMwF18x_*ov(JC;J~>Bi*Xmse)0;&zw1j=>Pj`w%s|YOt0(Qmh!po^Tc)Q+>_pB$XRGl;(_8OO3|pVW@xni8VJZLU{x3w39=5t5(vWOdV@!&nUu}t$^{D^)i-E~0 z?gvRG5E(?<(pCkD2Y=&4yBzzb)q&V$LerQ*iG^!hZm3%SR;$&42q$M-ou>T+kI+lU zLI{7vsP*{yHRmQ@-f*e4YH|N5@#wV+O)R-}K7GCw-1uB|Wb%;x)~cnCm&99I4ME%M zG;OR>Iyzrdo4EO|v#gH%F(vW5y^9R7qfXO)BKt`1Xx~LoS{?JdmBec|EH+l{sMEBc zxS%P!%0!}!uF;NY*R-GLc+se;zYUc+Z*46z#C)S;Yh7CcJ@MGupViS?zBWy0nssD| zQ$MQ7+x+ZD){lOlRk{;9%rl;+>NM>qZa0zM@?fIgXmT{6rBGjQb7i}ci&DdvS2VC~ zhu*1lH?ExLatowbAId^ZUsbYYL+Pw)qap>{IVXnELX<{-k=N(^h52m>f4@5CpLWrx z+@_)JEP)Xtb51wJO4+vf#nm|4GM6|HOjM&hkCOaRH;`O1eLcI`A zk609&w?bwRQoKI2=cwlqF}uxk4_9AOIy1q3XsPG=l)2ci^vn`{yfjh&2QQ0iDU><# zzn;)ix@>n;VjqkzcC0QNHPz+4mNT5zf%2CV+!96$akR9l;il{vR!3`jsmmt-)}aZM zg*ak}X>Eu`qa%zK;zV=v;K93}3dXLdk7>V-pRO;f{>zWo+ZCnfW9XhKE>1Pj$28F# z6H{xFEGBHP2jaJ^$%}qImt&OWj@8+f2mxd)icE zcFqHmOF)pbrw(PN{luTL3SvETB*Q_9iS3sa#g|XG+sxozA5EkQErs%KqXRvOwZ@{D zvCL*sNO8a9OpY%(V06$6X?;u+G4ZHJXepFg3OxzY{^-W&fOn7E(bZCVbp6EKs-20* zkq7MPUj5pn_=;Jw1~uXD>CW9nHJ@F2T>;PFzSe}f|g>ST%of8Cm zi!!fyzmC_IRTTcxWI4_$kYWNl$Z12lvp(S)*tM0$iz5dGJUPAQ6-v`u;Xx}x$-fO9Iu9@sE z_~>qzWq_Exwb)(JNp=HG6LtI7;?%ocX4_|jFe%=n z{6zL;<*AO3ueZ;GXkjT>!aE%5Wxra}`<3L+#|)@3qZ>mD6Yz;>ua7o6&Lj2J+c%xE zPpMi8>m%y-*#5|`#vZkVmcrcd+V&Ge8#|<0M;6)jp{2rT$ydkY7pGP{dX*)# zRG5WAv`};OoN*=ADvU1goSM)hLNw~Zxiy=9xXO;z()q=1j~%kVYC`u!G;;Z@)bjUT zoF)ni)+o3B=NDt0H$k)0D#yq}{iME6@7lhJ9}fw&5zg(%#7RjQjA zFJl$Kb{-QDyo;hN`{1w);eg=CfD{v`m(hJC#;Tf!EiC)P*QJ+q=5^u=?o=Na{)-en-g1nMQX zf08>WI_ls-JGx;~OyfCpZ*RVl#{EIi%QLO`|M+D8d23{X$CX6QZiLf8x;Dr&+5sfgLVr6f1Po?!6&k#-ib_~ac~yl8AQEA$=oMyio8Fd zyY<7TBjogIPqnnDxh%TlljQ*d=TDZx37Jn837%MZ{S)Tk;-`r(b?5 z#x0J$>!(eNqXS#p$<4NI(FAUa_$G|#*U#@yteMoy&IfFlQOwK-tdi$;j&}321ma3o zPUg&r{agrjE+OPveL`ZN{KV~Nbxb}p?@a4CT3AZw65LG4-9W>M8}qmKeUNWCW4c8X zIxC42vpbz_{lNI}eFA7MgOEEJz9~A|=B7yB4sjkthLfA3hu-X8aMfEb>xiL6vSsF^ z?_cM`>-$!Bn>@~X?r+J=zn)p5_OIj&&i~%HfFGdQ5)h519Dbju?+`gM5G6v~yKDL2 zZ;kDo$9|xNr7&(h2e{>wxcYoWL-m9W4_QBSizaZt%eTWs1L}WS-Pc*Y#pv+eA%W)m zRuFRcT3I_~%eI|=4!oOqU|*%Vt&=w!`aK2F?O8KYC#K1LNtl#TQRgRS8{z{Y91ui} zX(=X9FYiBQ)Q(T>|Et_(eCLr$_m8*TVUB=K3Q|m?EW|At!T~`}Mv4j4b5BGavkFqL zdbb}37FN2W_lXWjF^#eiKWjK#J=#4S7^^T^h=CPn=AG(z$i|iLwtsk~+oPwv;ng(J zpr$iY#R<7Dp%5vet#w~YI3TnXmr*Zso>kV=aGrNVKQXJ)-8|lV*X-#F60*|yZzol? zZLK?Iz7S!w=+Fe-zHy7D{Z@^CAW^@-yJrX^IKq82ePdZgLyg>*IA~!hSQRAt{boV( zn#gp!qQaz@!06ghpjo{xO}y8$+3spu2P_N{hwdJlEc&$A>d<{@0&&GLMx;DOJU*xwVqe$2`TrQvmG8)6VN$`d z@37ehn9j4whFm~vjoxWA8y&QcY}O6 zpj$M73}=ir#2dpe$?H6RU0|I^VVwmqj#p zMMWXr3F|LwG>x*%AkVe=W9J-S2+2%kzWqVH5avD6FpfqZE3{ZbeP3j9OdPuektWch z2`-~vbey-eqVQAiE*vdwrEbWojHmZ5(ga#G!DZBYu{*7)kWVx023i7A!z<(1sfo?P6KLVR2n5rp7ait&6~l=PEli-yQmgk>niVByMj~^Di@oHX;n2eQ z6$I0$mpo=hHs+lZ2`x;Z%u-G7RL1eejXjITa27?25lRzGqh55Fn2MQ5u{XkKVFG2A zGC48MUk(Kcv~acr!8GcHFl!_IE)^}_S3#;@^}QdRzWEPT&BZ6ZXXnhi3)3N)Ix^?_ zr*fYBI6!E9=F1v$n}BZ>>4C%1r&qmizhObY)?T%0L5m+V$DA?fWUp`7ol}1ai22Z? z%cDTldCB2H-D~lDp7A4W&Y3n(#n1n~;JnYe^Np7;en4-i%uoXA$CbiW`t z8~FX`w7ezR;;yh(X({BAATfLNW%*st?`LlZbxs7qxeGmsRm(mdmmHHFw>luj{elka z7`Ap}NpFX*5SPM+0Q^cEfJ3sVq59gkAGnhB0$ zb@*ab#V(>WKpex8{ts te(3Xu|GcA5mSzGS^T(_W{^@T|_4r7A`s--fH9aDemwdE&V~VfX{{!B~tVRF; literal 0 HcmV?d00001 diff --git a/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json new file mode 100644 index 0000000000..d3713b2255 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo GP1 0.4 nozzle.json @@ -0,0 +1,98 @@ +{ + "type": "machine", + "name": "Goofoo GP1 0.4 nozzle", + "inherits": "fdm_klipper_common", + "from": "system", + "setting_id": "x4GJ08PooNDQ8WJj", + "instantiation": "true", + "nozzle_diameter": [ + "0.4" + ], + "default_filament_profile": [ + "Goofoo ABS @System" + ], + "printer_model": "Goofoo GP1", + "default_print_profile": "0.20mm Standard @Goofoo GP1", + "printer_variant": "0.4", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\n;G92 E0", + "change_filament_gcode": "G5", + "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\n;layer\n;{if layer_num == 2}\n;M106 P1 S255\n;{endif}\nSET_PRINT_STATS_INFO CURRENT_LAYER=[layer_num]\n", + "machine_end_gcode": "; End G-code\nEND_PRINT", + "machine_pause_gcode": "G5", + "machine_start_gcode": "M117 Printing...\nM107 ; Turn off the fan\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nM104 S140\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n;G32 ;Load bed mesh\nG28 ;home\nG29 bed leveling\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG0 Z2.0 F600;\nG0 X50 Y10 F8000;\nG92 E0.0 ; reset extruder distance position\nG0 Z0.4 F600;\nG1 X100.0 E10 F3000.0 ; intro line\nG92 E0.0 ; reset extruder distance position\nG1 X200.0 E15 F3000.0 ; intro line\nG92 E0.0 ; reset extruder distance position\nG0 Z0.8 F600;\nG1 X100.0 E15 F3000.0 ; intro line\nG1 Z0.4 F600 ;Wipe\nG0 Y12 F6000 ;Wipe\nG1 X100 F6000 ;Wipe\nG0 Y8 F12000 ;Wipe\nG1 X200 F6000 ;Wipe\nG1 X190 Y12 F6000 ;Wipe\nG1 X180 Y8 F6000 ;Wipe\nG1 X170 Y12 F6000 ;Wipe\nG1 X160 Y8 F6000 ;Wipe\nG1 X150 Y12 F6000 ;Wipe\n;G0 Z2.0 F600;\nG92 E0.0 ; reset extruder distance position\n;START_PRINT", + "purge_in_prime_tower": "0", + "time_lapse_gcode": ";TIMELAPSE_TAKE_FRAME", + "printable_height": "250", + "printable_area": [ + "0x0", + "250x0", + "250x250", + "0x250" + ], + "deretraction_speed": [ + "0" + ], + "extruder_clearance_height_to_lid": "140", + "extruder_clearance_height_to_rod": "36", + "extruder_clearance_radius": "65", + "machine_max_acceleration_e": [ + "20000", + "5000" + ], + "machine_max_acceleration_retracting": [ + "15000", + "5000" + ], + "machine_max_acceleration_z": [ + "100", + "200" + ], + "machine_max_jerk_e": [ + "1", + "2.5" + ], + "machine_max_jerk_x": [ + "5", + "9" + ], + "machine_max_jerk_y": [ + "5", + "9" + ], + "machine_max_speed_e": [ + "25", + "25" + ], + "machine_max_speed_x": [ + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200" + ], + "machine_max_speed_z": [ + "12", + "12" + ], + "retract_before_wipe": [ + "100%" + ], + "retract_length_toolchange": [ + "10" + ], + "retraction_length": [ + "0.5" + ], + "retraction_minimum_travel": [ + "2" + ], + "retraction_speed": [ + "50" + ], + "thumbnails": "300x300/PNG", + "z_hop": [ + "0" + ], + "upward_compatible_machine": [] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo GP1.json b/resources/profiles/Goofoo/machine/Goofoo GP1.json new file mode 100644 index 0000000000..53f55c7c84 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo GP1.json @@ -0,0 +1,11 @@ +{ + "type": "machine_model", + "name": "Goofoo GP1", + "nozzle_diameter": "0.4", + "bed_model": "Goofoo-GP1.stl", + "bed_texture": "Goofoo-GP1-texture.svg", + "family": "Goofoo", + "machine_tech": "FFF", + "model_id": "V003", + "default_materials": "Goofoo ABS @System" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json new file mode 100644 index 0000000000..183d049d39 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo TurboM 0.4 nozzle.json @@ -0,0 +1,54 @@ +{ + "type": "machine", + "name": "Goofoo TurboM 0.4 nozzle", + "inherits": "fdm_klipper_common", + "from": "system", + "setting_id": "Wmdn5zTy1HH93Q5d", + "instantiation": "true", + "nozzle_diameter": [ + "0.4" + ], + "nozzle_type": "brass", + "printer_model": "Goofoo TurboM", + "printer_variant": "0.4", + "default_filament_profile": [ + "Goofoo ABS @System" + ], + "default_print_profile": "0.20mm Standard @Goofoo TurboM", + "printable_area": [ + "0x0", + "230x0", + "230x200", + "0x200" + ], + "extruder_clearance_height_to_lid": "350", + "extruder_clearance_height_to_rod": "60", + "extruder_clearance_radius": "50", + "machine_end_gcode": "M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG92 E0.0 ; reset extruder distance position;\nG1 E-1 F2100 ; retract\nG28 X Y; home X Y axis\n;M84 ; disable motors\nM107 ; turn off fan\n;SET_VELOCITY_LIMIT ACCEL_TO_DECEL=4000", + "machine_max_jerk_z": [ + "3", + "0.4" + ], + "machine_start_gcode": "M107 ; Turn off the fan\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\n\n\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nG28 ;home\n\nG1 X2 Y10 F3000;\n\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nG1 Z0.28 F240\n\nG92 E0\n\nG1 Y140 E10 F1500 ; prime the nozzle\n\nG1 X2.3 F5000\nG92 E0\n\nG1 Y10 E10 F1200 ; prime the nozzle\n;G0 Z2.0 F600;\nG92 E0.0 ; reset extruder distance position;\nM82\n;SET_PRESSURE_ADVANCE ADVANCE=0.05\n;SET_VELOCITY_LIMIT ACCEL_TO_DECEL=10000\n", + "printable_height": "200", + "z_hop": [ + "0" + ], + "machine_max_speed_e": [ + "25", + "25" + ], + "machine_max_speed_x": [ + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200" + ], + "machine_max_speed_z": [ + "12", + "12" + ], + "upward_compatible_machine": [] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo TurboM.json b/resources/profiles/Goofoo/machine/Goofoo TurboM.json new file mode 100644 index 0000000000..1be44f99d9 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo TurboM.json @@ -0,0 +1,11 @@ +{ + "type": "machine_model", + "name": "Goofoo TurboM", + "nozzle_diameter": "0.4", + "bed_model": "Goofoo-TurboM.stl", + "bed_texture": "Goofoo-TurboM-texture.svg", + "family": "Goofoo", + "machine_tech": "FFF", + "model_id": "V002", + "default_materials": "Goofoo ABS @System" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json new file mode 100644 index 0000000000..43d8afdc46 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.2 nozzle.json @@ -0,0 +1,106 @@ +{ + "type": "machine", + "name": "Goofoo Velo+ 0.2 nozzle", + "inherits": "fdm_klipper_common", + "from": "system", + "setting_id": "wSr6VNECZHekeNRi", + "instantiation": "true", + "nozzle_diameter": [ + "0.2" + ], + "nozzle_type": "hardened_steel", + "printer_model": "Goofoo Velo+", + "printer_variant": "0.2", + "default_filament_profile": [ + "Goofoo ABS @System" + ], + "default_print_profile": "0.10mm Standard @Goofoo Velo+", + "printable_area": [ + "0x0", + "600x0", + "600x500", + "0x500" + ], + "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", + "printable_height": "600", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0", + "change_filament_gcode": "PAUSE", + "deretraction_speed": [ + "0" + ], + "extruder_clearance_height_to_lid": "350", + "extruder_clearance_height_to_rod": "60", + "extruder_clearance_radius": "50", + "machine_max_acceleration_e": [ + "20000", + "5000" + ], + "machine_max_acceleration_retracting": [ + "15000", + "5000" + ], + "machine_max_acceleration_z": [ + "100", + "200" + ], + "machine_max_jerk_e": [ + "1", + "2.5" + ], + "machine_max_jerk_x": [ + "5", + "9" + ], + "machine_max_jerk_y": [ + "5", + "9" + ], + "machine_max_speed_e": [ + "50", + "25" + ], + "machine_max_speed_x": [ + "730", + "200" + ], + "machine_max_speed_y": [ + "730", + "200" + ], + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零", + + "retract_before_wipe": [ + "100%" + ], + "retract_length_toolchange": [ + "10" + ], + "retraction_length": [ + "0.5" + ], + "retraction_minimum_travel": [ + "2" + ], + "retraction_speed": [ + "50" + ], + "thumbnails": "300x300/PNG", + "z_hop": [ + "0" + ], + "machine_max_acceleration_travel": [ + "10000", + "10000" + ], + "max_layer_height": [ + "0.16" + ], + "min_layer_height": [ + "0.04" + ], + "upward_compatible_machine": [] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json new file mode 100644 index 0000000000..b334146d6a --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.4 nozzle.json @@ -0,0 +1,100 @@ +{ + "type": "machine", + "name": "Goofoo Velo+ 0.4 nozzle", + "inherits": "fdm_klipper_common", + "from": "system", + "setting_id": "XzHz1vNOYg3Ofe8X", + "instantiation": "true", + "nozzle_diameter": [ + "0.4" + ], + "nozzle_type": "hardened_steel", + "printer_model": "Goofoo Velo+", + "printer_variant": "0.4", + "default_filament_profile": [ + "Goofoo ABS @System" + ], + "default_print_profile": "0.20mm Standard @Goofoo Velo+", + "printable_area": [ + "0x0", + "600x0", + "600x500", + "0x500" + ], + "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", + "printable_height": "600", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0", + "change_filament_gcode": "PAUSE", + "deretraction_speed": [ + "0" + ], + "extruder_clearance_height_to_lid": "350", + "extruder_clearance_height_to_rod": "60", + "extruder_clearance_radius": "50", + "machine_max_acceleration_e": [ + "20000", + "5000" + ], + "machine_max_acceleration_retracting": [ + "15000", + "5000" + ], + "machine_max_acceleration_z": [ + "100", + "200" + ], + "machine_max_jerk_e": [ + "1", + "2.5" + ], + "machine_max_jerk_x": [ + "5", + "9" + ], + "machine_max_jerk_y": [ + "5", + "9" + ], + "machine_max_speed_e": [ + "50", + "25" + ], + "machine_max_speed_x": [ + "730", + "200" + ], + "machine_max_speed_y": [ + "730", + "200" + ], + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零", + + "retract_before_wipe": [ + "100%" + ], + "retract_length_toolchange": [ + "10" + ], + "retraction_length": [ + "0.5" + ], + "retraction_minimum_travel": [ + "2" + ], + "retraction_speed": [ + "50" + ], + "thumbnails": "300x300/PNG", + "z_hop": [ + "0" + ], + "machine_max_acceleration_travel": [ + "10000", + "10000" + ], + "upward_compatible_machine": [] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json new file mode 100644 index 0000000000..56a0824da8 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ 0.6 nozzle.json @@ -0,0 +1,106 @@ +{ + "type": "machine", + "name": "Goofoo Velo+ 0.6 nozzle", + "inherits": "fdm_klipper_common", + "from": "system", + "setting_id": "Pauu7JRq7u2OD6kv", + "instantiation": "true", + "nozzle_diameter": [ + "0.6" + ], + "nozzle_type": "hardened_steel", + "printer_model": "Goofoo Velo+", + "printer_variant": "0.6", + "default_filament_profile": [ + "Goofoo ABS @System" + ], + "default_print_profile": "0.30mm Standard @Goofoo Velo+", + "printable_area": [ + "0x0", + "600x0", + "600x500", + "0x500" + ], + "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", + "printable_height": "600", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0", + "change_filament_gcode": "PAUSE", + "deretraction_speed": [ + "0" + ], + "extruder_clearance_height_to_lid": "350", + "extruder_clearance_height_to_rod": "60", + "extruder_clearance_radius": "50", + "machine_max_acceleration_e": [ + "20000", + "5000" + ], + "machine_max_acceleration_retracting": [ + "15000", + "5000" + ], + "machine_max_acceleration_z": [ + "100", + "200" + ], + "machine_max_jerk_e": [ + "1", + "2.5" + ], + "machine_max_jerk_x": [ + "5", + "9" + ], + "machine_max_jerk_y": [ + "5", + "9" + ], + "machine_max_speed_e": [ + "50", + "25" + ], + "machine_max_speed_x": [ + "730", + "200" + ], + "machine_max_speed_y": [ + "730", + "200" + ], + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] ; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零", + + "retract_before_wipe": [ + "100%" + ], + "retract_length_toolchange": [ + "10" + ], + "retraction_length": [ + "0.5" + ], + "retraction_minimum_travel": [ + "2" + ], + "retraction_speed": [ + "50" + ], + "thumbnails": "300x300/PNG", + "z_hop": [ + "0" + ], + "machine_max_acceleration_travel": [ + "10000", + "10000" + ], + "max_layer_height": [ + "0.4" + ], + "min_layer_height": [ + "0.12" + ], + "upward_compatible_machine": [] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json new file mode 100644 index 0000000000..37872c1e11 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool 0.4.json @@ -0,0 +1,152 @@ +{ + "type": "machine", + "name": "Goofoo Velo+ Tool 0.4", + "inherits": "Goofoo Velo+ 0.4 nozzle", + "from": "system", + "setting_id": "ww39WeaF5nYks1em", + "instantiation": "true", + "nozzle_diameter": [ + "0.4", + "0.4" + ], + "printer_model": "Goofoo Velo+ Tool", + "change_filament_gcode": "T[next_extruder]\n;M104 S[nozzle_temperature_initial_layer] T[next_extruder]; 正式设置喷嘴温度(与切片设置一致)\n;M109 S[nozzle_temperature_initial_layer] T[next_extruder] ; 等待喷嘴温度稳定\n", + "default_nozzle_volume_type": [ + "Standard", + "Standard" + ], + "deretraction_speed": [ + "0", + "0" + ], + "extruder_colour": [ + "#FCE94F", + "#FCE94F" + ], + "extruder_offset": [ + "0x0", + "0x0" + ], + "extruder_printable_height": [ + "0", + "0" + ], + "extruder_type": [ + "Direct Drive", + "Direct Drive" + ], + "extruder_variant_list": [ + "Direct Drive Standard", + "Direct Drive Standard" + ], + "long_retractions_when_cut": [ + "0", + "0" + ], + "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nT0\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", + "machine_start_gcode": "G90 ; 绝对坐标模式\nM83 ; 挤出机相对模式\nM140 S[first_layer_bed_temperature] ; 设置热床温度\nM104 S140 T0 ; 临时喷嘴温度=切片首层设定(防止归零渗料)\nM104 S140 T1\nG4 S10 ; 预热等待10秒\nG28 ; 归零所有轴\nG1 Z50 F240 ; Z轴抬升\nG1 X2 Y10 F3000 ; 移动至起始位置\nM104 S[nozzle_temperature_initial_layer] T0 ; 正式设置喷嘴温度(与切片设置一致)\nM104 S[nozzle_temperature_initial_layer] T1 ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] T0; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] T0 ; 等待喷嘴温度稳定\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X2.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零\nG1 Z20 F240 ; Z轴抬升\nG1 X280 Y10 F3000 ; 移动至起始位置\nT1\nM104 S[nozzle_temperature_initial_layer] T1 ; 正式设置喷嘴温度(与切片设置一致)\nM190 S[bed_temperature_initial_layer_single] T1; 等待热床温度稳定\nM109 S[nozzle_temperature_initial_layer] T1; 等待喷嘴温度稳定\nG4 S10 ; 预热等待10秒\nG1 Z0.28 F240 ; 喷嘴下降至打印高度\nG92 E0 ; 挤出机归零\nG1 Y140 E10 F1500 ; 画第一条 priming 线\nG1 X282.3 F5000 ; X轴微调\nG92 E0 ; 挤出机归零\nG1 Y10 E10 F1200 ; 画第二条 priming 线\nG92 E0 ; 最终挤出机归零", + "max_layer_height": [ + "0.32", + "0.32" + ], + "min_layer_height": [ + "0.08", + "0.08" + ], + "nozzle_flush_dataset": [ + "nil", + "0" + ], + "nozzle_type": [ + "nil", + "hardened_steel" + ], + "nozzle_volume": [ + "nil", + "0" + ], + "printable_area": [ + "0x0", + "300x0", + "300x300", + "0x300" + ], + "printer_extruder_id": [ + "1", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive Standard" + ], + "purge_in_prime_tower": "0", + "retract_before_wipe": [ + "100%", + "100%" + ], + "retract_length_toolchange": [ + "10", + "10" + ], + "retract_lift_above": [ + "0", + "0" + ], + "retract_lift_below": [ + "0", + "0" + ], + "retract_lift_enforce": [ + "All Surfaces", + "All Surfaces" + ], + "retract_restart_extra": [ + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1" + ], + "retraction_distances_when_cut": [ + "18", + "18" + ], + "retraction_length": [ + "0.5", + "0.5" + ], + "retraction_minimum_travel": [ + "2", + "2" + ], + "retraction_speed": [ + "50", + "50" + ], + "single_extruder_multi_material": "0", + "travel_slope": [ + "3", + "3" + ], + "wipe": [ + "1", + "1" + ], + "wipe_distance": [ + "1", + "1" + ], + "z_hop": [ + "0", + "0" + ], + "z_hop_types": [ + "Slope Lift", + "Slope Lift" + ] +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json new file mode 100644 index 0000000000..004352b3b3 --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+ Tool.json @@ -0,0 +1,11 @@ +{ + "type": "machine_model", + "name": "Goofoo Velo+ Tool", + "nozzle_diameter": "0.4", + "bed_model": "Goofoo-Velo+.stl", + "bed_texture": "Goofoo-Velo+-texture.svg", + "family": "Goofoo", + "machine_tech": "FFF", + "model_id": "V006", + "default_materials": "Goofoo ABS @System" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/Goofoo Velo+.json b/resources/profiles/Goofoo/machine/Goofoo Velo+.json new file mode 100644 index 0000000000..3f60e1738f --- /dev/null +++ b/resources/profiles/Goofoo/machine/Goofoo Velo+.json @@ -0,0 +1,11 @@ +{ + "type": "machine_model", + "name": "Goofoo Velo+", + "nozzle_diameter": "0.2;0.4;0.6", + "bed_model": "Goofoo-Velo+.stl", + "bed_texture": "Goofoo-Velo+-texture.svg", + "family": "Goofoo", + "machine_tech": "FFF", + "model_id": "V001", + "default_materials": "Goofoo ABS @System" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/fdm_klipper_common.json b/resources/profiles/Goofoo/machine/fdm_klipper_common.json new file mode 100644 index 0000000000..ece1ca5052 --- /dev/null +++ b/resources/profiles/Goofoo/machine/fdm_klipper_common.json @@ -0,0 +1,13 @@ +{ + "type": "machine", + "name": "fdm_klipper_common", + "inherits": "fdm_machine_common", + "from": "system", + "instantiation": "false", + "gcode_flavor": "klipper", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n", + "machine_start_gcode": "G90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nM140 S{first_layer_bed_temperature[0]} ; set bed temp\nM104 S140 ; set temporary nozzle temp to prevent oozing\nG4 S10 ; wait 10s for preheating\nG28 ; home all axes\nG1 Z50 F240 ; raise Z axis\nG1 X2 Y10 F3000 ; move to start position\nM104 S{first_layer_temperature[0]} ; set final nozzle temp\nM190 S{first_layer_bed_temperature[0]} ; wait for bed temp\nM109 S{first_layer_temperature[0]} ; wait for nozzle temp\nG1 Z0.28 F240 ; lower nozzle to print height\nG92 E0 ; reset extrusion distance\nG1 Y140 E10 F1500 ; prime the nozzle\nG1 X2.3 F5000 ; slight X adjustment\nG92 E0 ; reset extrusion distance\nG1 Y10 E10 F1200 ; prime again\nG92 E0 ; final extrusion reset", + "machine_end_gcode": "{if max_layer_z < printable_height}G1 Z{z_offset+min(max_layer_z+2, printable_height)} F600 ; Move print head up{endif}\nG1 X5 Y{print_bed_max[1]*0.8} F{travel_speed*60} ; present print\n{if max_layer_z < printable_height-10}G1 Z{z_offset+min(max_layer_z+70, printable_height-10)} F600 ; Move print head further up{endif}\n{if max_layer_z < max_print_height*0.6}G1 Z{printable_height*0.6} F600 ; Move print head further up{endif}\nM140 S0 ; turn off heatbed\nM104 S0 ; turn off temperature\nM107 ; turn off fan\nM84 X Y E ; disable motors", + "change_filament_gcode": "PAUSE", + "machine_pause_gcode": "PAUSE" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/machine/fdm_machine_common.json b/resources/profiles/Goofoo/machine/fdm_machine_common.json new file mode 100644 index 0000000000..bf8f2249cf --- /dev/null +++ b/resources/profiles/Goofoo/machine/fdm_machine_common.json @@ -0,0 +1,118 @@ +{ + "type": "machine", + "name": "fdm_machine_common", + "from": "system", + "instantiation": "false", + "printer_technology": "FFF", + "deretraction_speed": [ + "40" + ], + "extruder_colour": [ + "#FCE94F" + ], + "extruder_offset": [ + "0x0" + ], + "gcode_flavor": "marlin", + "machine_max_acceleration_e": [ + "5000" + ], + "machine_max_acceleration_extruding": [ + "10000" + ], + "machine_max_acceleration_retracting": [ + "1000" + ], + "machine_max_acceleration_x": [ + "10000" + ], + "machine_max_acceleration_y": [ + "10000" + ], + "machine_max_acceleration_z": [ + "500" + ], + "machine_max_speed_e": [ + "60" + ], + "machine_max_speed_x": [ + "500" + ], + "machine_max_speed_y": [ + "500" + ], + "machine_max_speed_z": [ + "10" + ], + "machine_max_jerk_e": [ + "5" + ], + "machine_max_jerk_x": [ + "8" + ], + "machine_max_jerk_y": [ + "8" + ], + "machine_max_jerk_z": [ + "0.4" + ], + "machine_min_extruding_rate": [ + "0" + ], + "machine_min_travel_rate": [ + "0" + ], + "max_layer_height": [ + "0.32" + ], + "min_layer_height": [ + "0.08" + ], + "printable_height": "250", + "extruder_clearance_radius": "65", + "extruder_clearance_height_to_rod": "36", + "extruder_clearance_height_to_lid": "140", + "nozzle_diameter": [ + "0.4" + ], + "printer_settings_id": "", + "printer_variant": "0.4", + "retraction_minimum_travel": [ + "2" + ], + "retract_before_wipe": [ + "70%" + ], + "retract_when_changing_layer": [ + "1" + ], + "retraction_length": [ + "1" + ], + "retract_length_toolchange": [ + "1" + ], + "z_hop": [ + "0" + ], + "retract_restart_extra": [ + "0" + ], + "retract_restart_extra_toolchange": [ + "0" + ], + "retraction_speed": [ + "60" + ], + "single_extruder_multi_material": "1", + "change_filament_gcode": "", + "wipe": [ + "1" + ], + "default_print_profile": "", + "machine_start_gcode": "G0 Z20 F9000\nG92 E0; G1 E-10 F1200\nG28\nM970 Q1 A10 B10 C130 K0\nM970 Q1 A10 B131 C250 K1\nM974 Q1 S1 P0\nM970 Q0 A10 B10 C130 H20 K0\nM970 Q0 A10 B131 C250 K1\nM974 Q0 S1 P0\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nG29 ;Home\nG90;\nG92 E0 ;Reset Extruder \nG1 Z2.0 F3000 ;Move Z Axis up \nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S205;\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder \nG1 X110 Y110 Z2.0 F3000 ;Move Z Axis up", + "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-4.0 F3600; retract \nG91\nG1 Z3;\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nG90 \nG0 X110 Y200 F3600 \nprint_end", + "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", + "machine_pause_gcode": "M601" +} diff --git a/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json new file mode 100644 index 0000000000..edd118bd26 --- /dev/null +++ b/resources/profiles/Goofoo/process/0.10mm Standard @Goofoo Velo+.json @@ -0,0 +1,26 @@ +{ + "type": "process", + "name": "0.10mm Standard @Goofoo Velo+", + "inherits": "0.20mm Standard @Goofoo Velo+", + "from": "system", + "setting_id": "dJV4bTrLbOPzW2YB", + "instantiation": "true", + "compatible_printers": [ + "Goofoo Velo+ 0.2 nozzle" + ], + "layer_height": "0.1", + "initial_layer_print_height": "0.1", + "bottom_shell_layers": "6", + "top_shell_layers": "12", + "wall_loops": "4", + "line_width": "0.22", + "initial_layer_line_width": "0.25", + "inner_wall_line_width": "0.22", + "outer_wall_line_width": "0.22", + "sparse_infill_line_width": "0.22", + "internal_solid_infill_line_width": "0.22", + "top_surface_line_width": "0.22", + "support_line_width": "0.22", + "support_top_z_distance": "0.1", + "support_bottom_z_distance": "0.1" +} diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json new file mode 100644 index 0000000000..5ee5aae3c6 --- /dev/null +++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo GP1.json @@ -0,0 +1,35 @@ +{ + "type": "process", + "name": "0.20mm Standard @Goofoo GP1", + "inherits": "fdm_process_klipper_common", + "from": "system", + "setting_id": "zrscQBUxp6L7BlQ9", + "instantiation": "true", + "compatible_printers": [ + "Goofoo GP1 0.4 nozzle" + ], + "layer_height": "0.2", + "accel_to_decel_enable": "0", + "bridge_acceleration": "100%", + "bridge_speed": "100", + "brim_type": "no_brim", + "gap_infill_speed": "250", + "initial_layer_acceleration": "1000", + "initial_layer_infill_speed": "100", + "initial_layer_speed": "70", + "inner_wall_speed": "250", + "internal_bridge_speed": "200%", + "internal_solid_infill_speed": "250", + "outer_wall_acceleration": "5000", + "outer_wall_speed": "100", + "overhang_4_4_speed": "0", + "reduce_crossing_wall": "1", + "skirt_distance": "6", + "skirt_height": "1", + "skirt_loops": "1", + "sparse_infill_pattern": "grid", + "sparse_infill_speed": "250", + "top_surface_acceleration": "5000", + "top_surface_speed": "200", + "travel_acceleration": "5000" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json new file mode 100644 index 0000000000..74812f5de4 --- /dev/null +++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo TurboM.json @@ -0,0 +1,67 @@ +{ + "type": "process", + "name": "0.20mm Standard @Goofoo TurboM", + "inherits": "fdm_process_klipper_common", + "from": "system", + "setting_id": "LVXxUtAcYGCY6irA", + "instantiation": "true", + "compatible_printers": [ + "Goofoo TurboM 0.4 nozzle" + ], + "layer_height": "0.2", + "bridge_acceleration": "2000", + "bridge_speed": "60", + "brim_type": "no_brim", + "default_acceleration": "10000", + "enable_support": "1", + "exclude_object": "0", + "gap_infill_speed": "200", + "infill_anchor": "600%", + "infill_combination": "1", + "infill_wall_overlap": "15%", + "initial_layer_acceleration": "1000", + "initial_layer_line_width": "0.45", + "initial_layer_speed": "60", + "inner_wall_acceleration": "3000", + "inner_wall_line_width": "0.42", + "inner_wall_speed": "150", + "internal_solid_infill_acceleration": "3000", + "internal_solid_infill_line_width": "0.42", + "internal_solid_infill_speed": "150", + "line_width": "0.42", + "min_skirt_length": "0", + "minimum_sparse_infill_area": "70", + "only_one_wall_top": "1", + "outer_wall_acceleration": "2500", + "outer_wall_line_width": "0.42", + "outer_wall_speed": "100", + "reduce_crossing_wall": "1", + "skirt_distance": "6", + "skirt_height": "1", + "skirt_loops": "4", + "small_perimeter_speed": "200", + "sparse_infill_acceleration": "3000", + "sparse_infill_line_width": "0.42", + "sparse_infill_pattern": "grid", + "sparse_infill_speed": "150", + "support_base_pattern": "rectilinear", + "support_interface_bottom_layers": "-1", + "support_interface_pattern": "rectilinear", + "support_interface_spacing": "0", + "support_interface_speed": "100", + "support_interface_top_layers": "3", + "support_line_width": "0.35", + "support_object_xy_distance": "0.21", + "support_speed": "100", + "thick_bridges": "1", + "top_shell_layers": "6", + "top_shell_thickness": "0", + "top_surface_acceleration": "2500", + "top_surface_line_width": "0.42", + "top_surface_speed": "150", + "travel_acceleration": "10000", + "travel_speed": "200", + "wall_generator": "classic", + "wall_loops": "2", + "wall_sequence": "outer wall/inner wall" +} \ No newline at end of file diff --git a/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json new file mode 100644 index 0000000000..68bb4470c6 --- /dev/null +++ b/resources/profiles/Goofoo/process/0.20mm Standard @Goofoo Velo+.json @@ -0,0 +1,70 @@ +{ + "type": "process", + "name": "0.20mm Standard @Goofoo Velo+", + "inherits": "fdm_process_klipper_common", + "from": "system", + "setting_id": "iWjynhCcvbF8MWev", + "instantiation": "true", + "compatible_printers": [ + "Goofoo Velo+ 0.4 nozzle", + "Goofoo Velo+ Tool 0.4" + ], + "layer_height": "0.2", + "initial_layer_print_height": "0.2", + "bottom_shell_layers": "3", + "top_shell_layers": "6", + "bridge_acceleration": "2000", + "bridge_speed": "60", + "brim_type": "no_brim", + "default_acceleration": "10000", + "enable_support": "1", + "exclude_object": "0", + "gap_infill_speed": "200", + "infill_anchor": "600%", + "infill_combination": "1", + "infill_wall_overlap": "15%", + "initial_layer_acceleration": "1000", + "initial_layer_line_width": "0.45", + "initial_layer_speed": "60", + "inner_wall_acceleration": "3000", + "inner_wall_line_width": "0.42", + "inner_wall_speed": "150", + "internal_solid_infill_acceleration": "3000", + "internal_solid_infill_line_width": "0.42", + "internal_solid_infill_speed": "150", + "line_width": "0.42", + "min_skirt_length": "0", + "minimum_sparse_infill_area": "70", + "only_one_wall_top": "1", + "outer_wall_acceleration": "2500", + "outer_wall_line_width": "0.42", + "outer_wall_speed": "100", + "reduce_crossing_wall": "1", + "skirt_distance": "6", + "skirt_height": "1", + "skirt_loops": "4", + "small_perimeter_speed": "200", + "sparse_infill_acceleration": "3000", + "sparse_infill_line_width": "0.42", + "sparse_infill_pattern": "grid", + "sparse_infill_speed": "150", + "support_base_pattern": "rectilinear", + "support_interface_bottom_layers": "-1", + "support_interface_pattern": "rectilinear", + "support_interface_spacing": "0", + "support_interface_speed": "100", + "support_interface_top_layers": "3", + "support_line_width": "0.35", + "support_object_xy_distance": "0.21", + "support_speed": "100", + "thick_bridges": "1", + "top_shell_thickness": "0", + "top_surface_acceleration": "2500", + "top_surface_line_width": "0.42", + "top_surface_speed": "150", + "travel_acceleration": "10000", + "travel_speed": "300", + "wall_generator": "classic", + "wall_loops": "2", + "wall_sequence": "outer wall/inner wall" +} diff --git a/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json b/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json new file mode 100644 index 0000000000..d25f90484b --- /dev/null +++ b/resources/profiles/Goofoo/process/0.30mm Standard @Goofoo Velo+.json @@ -0,0 +1,13 @@ +{ + "type": "process", + "name": "0.30mm Standard @Goofoo Velo+", + "inherits": "fdm_process_klipper_common", + "from": "system", + "setting_id": "mi8ogYOYpqb2x60z", + "instantiation": "true", + "compatible_printers": [ + "Goofoo Velo+ 0.6 nozzle" + ], + "initial_layer_print_height": "0.3", + "layer_height": "0.3" +} diff --git a/resources/profiles/Goofoo/process/fdm_process_common.json b/resources/profiles/Goofoo/process/fdm_process_common.json new file mode 100644 index 0000000000..b95f1c3487 --- /dev/null +++ b/resources/profiles/Goofoo/process/fdm_process_common.json @@ -0,0 +1,91 @@ +{ + "type": "process", + "name": "fdm_process_common", + "from": "system", + "instantiation": "false", + "seam_position": "aligned", + "resolution": "0.012", + "elefant_foot_compensation": "0.2", + "precise_outer_wall": "1", + "ironing_type": "no ironing", + "ironing_speed": "30", + "ironing_flow": "10%", + "ironing_spacing": "0.15", + "reduce_crossing_wall": "1", + "max_travel_detour_distance": "0", + "detect_overhang_wall": "1", + "wall_loops": "3", + "top_surface_pattern": "monotonicline", + "top_shell_layers": "5", + "top_shell_thickness": "0.7", + "bottom_surface_pattern": "monotonic", + "bottom_shell_layers": "4", + "bottom_shell_thickness": "0.5", + "sparse_infill_density": "15%", + "sparse_infill_pattern": "crosshatch", + "infill_wall_overlap": "23%", + "infill_direction": "45", + "minimum_sparse_infill_area": "15", + "infill_combination": "0", + "ensure_vertical_shell_thickness": "1", + "initial_layer_speed": "50", + "initial_layer_infill_speed": "50", + "initial_layer_travel_speed": "100%", + "outer_wall_speed": "125", + "inner_wall_speed": "250", + "sparse_infill_speed": "250", + "internal_solid_infill_speed": "200", + "top_surface_speed": "150", + "gap_infill_speed": "150", + "support_speed": "125", + "support_interface_speed": "80", + "enable_overhang_speed": "1", + "overhang_1_4_speed": "0", + "overhang_2_4_speed": "50", + "overhang_3_4_speed": "25", + "overhang_4_4_speed": "15", + "bridge_speed": "50", + "travel_speed": "300", + "default_acceleration": "2500", + "outer_wall_acceleration": "500", + "inner_wall_acceleration": "500", + "bridge_acceleration": "500", + "travel_acceleration": "2500", + "default_jerk": "15", + "outer_wall_jerk": "10", + "inner_wall_jerk": "15", + "infill_jerk": "15", + "top_surface_jerk": "12", + "initial_layer_jerk": "12", + "travel_jerk": "20", + "enable_support": "0", + "support_type": "normal(auto)", + "support_threshold_angle": "30", + "support_on_build_plate_only": "0", + "raft_layers": "0", + "support_filament": "0", + "support_interface_filament": "0", + "support_top_z_distance": "0.2", + "support_base_pattern": "default", + "support_base_pattern_spacing": "2.5", + "support_interface_top_layers": "2", + "support_interface_bottom_layers": "2", + "support_interface_spacing": "0.5", + "support_object_xy_distance": "0.5", + "bridge_no_support": "0", + "independent_support_layer_height": "1", + "tree_support_branch_angle": "30", + "tree_support_wall_count": "0", + "skirt_loops": "2", + "skirt_distance": "3", + "skirt_height": "1", + "brim_width": "5", + "brim_object_gap": "0.1", + "enable_prime_tower": "0", + "prime_tower_width": "60", + "wipe_tower_no_sparse_layers": "0", + "print_sequence": "by layer", + "spiral_mode": "0", + "reduce_infill_retraction": "1", + "filename_format": "{input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}.gcode" +} diff --git a/resources/profiles/Goofoo/process/fdm_process_klipper_common.json b/resources/profiles/Goofoo/process/fdm_process_klipper_common.json new file mode 100644 index 0000000000..2977d9392a --- /dev/null +++ b/resources/profiles/Goofoo/process/fdm_process_klipper_common.json @@ -0,0 +1,23 @@ +{ + "type": "process", + "name": "fdm_process_klipper_common", + "inherits": "fdm_process_common", + "from": "system", + "instantiation": "false", + "default_acceleration": "5000", + "top_surface_acceleration": "3000", + "travel_acceleration": "7000", + "inner_wall_acceleration": "5000", + "outer_wall_acceleration": "3000", + "initial_layer_acceleration": "500", + "initial_layer_speed": "50", + "initial_layer_infill_speed": "105", + "outer_wall_speed": "120", + "inner_wall_speed": "200", + "internal_solid_infill_speed": "200", + "top_surface_speed": "100", + "gap_infill_speed": "100", + "sparse_infill_speed": "200", + "travel_speed": "350", + "exclude_object": "1" +} diff --git a/resources/profiles/OrcaFilamentLibrary.json b/resources/profiles/OrcaFilamentLibrary.json index 084a12993f..93694b0824 100644 --- a/resources/profiles/OrcaFilamentLibrary.json +++ b/resources/profiles/OrcaFilamentLibrary.json @@ -1,6 +1,6 @@ { "name": "OrcaFilamentLibrary", - "version": "02.04.00.15", + "version": "02.04.00.16", "force_update": "0", "description": "Orca Filament Library", "filament_list": [ @@ -1396,6 +1396,10 @@ "name": "addnorth ABS rABS", "sub_path": "filament/addnorth/BBL/addnorth ABS rABS.json" }, + { + "name": "Goofoo ABS @base", + "sub_path": "filament/Goofoo/Goofoo ABS @base.json" + }, { "name": "NIT ABS @System", "sub_path": "filament/NIT/NIT ABS @System.json" @@ -1480,6 +1484,10 @@ "name": "Elegoo ASA-CF @base", "sub_path": "filament/Elegoo/Elegoo ASA-CF @base.json" }, + { + "name": "Goofoo ASA @base", + "sub_path": "filament/Goofoo/Goofoo ASA @base.json" + }, { "name": "Overture ASA @BBL X1", "sub_path": "filament/Overture/BBL/Overture ASA @BBL X1.json" @@ -1636,10 +1644,22 @@ "name": "addnorth PVDF Adamant S1", "sub_path": "filament/addnorth/BBL/addnorth PVDF Adamant S1.json" }, + { + "name": "Goofoo PA @base", + "sub_path": "filament/Goofoo/Goofoo PA @base.json" + }, { "name": "addnorth PA-CF Adura X", "sub_path": "filament/addnorth/BBL/addnorth PA-CF Adura X.json" }, + { + "name": "Goofoo PA-CF @base", + "sub_path": "filament/Goofoo/Goofoo PA-CF @base.json" + }, + { + "name": "Goofoo PA-GF10 @base", + "sub_path": "filament/Goofoo/Goofoo PA-GF10 @base.json" + }, { "name": "INSLOGIC PA6-66 @BBL P2S", "sub_path": "filament/INSLOGIC/BBL/INSLOGIC PA6-66 @BBL P2S.json" @@ -1712,6 +1732,10 @@ "name": "COEX PCTG PRIME @System", "sub_path": "filament/COEX/COEX PCTG PRIME @System.json" }, + { + "name": "Goofoo PE @base", + "sub_path": "filament/Goofoo/Goofoo PE @base.json" + }, { "name": "Generic PE-CF @System", "sub_path": "filament/Generic PE-CF @System.json" @@ -2176,6 +2200,10 @@ "name": "addnorth PETG rPETG Matte", "sub_path": "filament/addnorth/BBL/addnorth PETG rPETG Matte.json" }, + { + "name": "Goofoo PETG @base", + "sub_path": "filament/Goofoo/Goofoo PETG @base.json" + }, { "name": "Generic PETG HF @System", "sub_path": "filament/Generic PETG HF @System.json" @@ -2236,6 +2264,10 @@ "name": "eSUN PETG @System", "sub_path": "filament/eSUN/eSUN PETG @System.json" }, + { + "name": "Goofoo PHA @base", + "sub_path": "filament/Goofoo/Goofoo PHA @base.json" + }, { "name": "AliZ PLA @P1-X1", "sub_path": "filament/AliZ/BBL/AliZ PLA @P1-X1.json" @@ -3120,6 +3152,10 @@ "name": "addnorth PLA rPLA RE-ADD", "sub_path": "filament/addnorth/BBL/addnorth PLA rPLA RE-ADD.json" }, + { + "name": "Goofoo PLA @base", + "sub_path": "filament/Goofoo/Goofoo PLA @base.json" + }, { "name": "addnorth PLA X-PLA High Speed", "sub_path": "filament/addnorth/BBL/addnorth PLA X-PLA High Speed.json" @@ -3136,6 +3172,10 @@ "name": "addnorth PLA-CF Carbon Fiber", "sub_path": "filament/addnorth/BBL/addnorth PLA-CF Carbon Fiber.json" }, + { + "name": "Goofoo PLA-CF @base", + "sub_path": "filament/Goofoo/Goofoo PLA-CF @base.json" + }, { "name": "INSLOGIC PLA Pro @BBL P2S", "sub_path": "filament/INSLOGIC/BBL/INSLOGIC PLA Pro @BBL P2S.json" @@ -3820,6 +3860,10 @@ "name": "FILL3D PPCF @System", "sub_path": "filament/FILL3D/FILL3D PPCF @System.json" }, + { + "name": "Goofoo PP @base", + "sub_path": "filament/Goofoo/Goofoo PP @base.json" + }, { "name": "Generic PP-CF @System", "sub_path": "filament/Generic PP-CF @System.json" @@ -3840,6 +3884,10 @@ "name": "Bambu PVA @System", "sub_path": "filament/Bambu/Bambu PVA @System.json" }, + { + "name": "Goofoo PVA @base", + "sub_path": "filament/Goofoo/Goofoo PVA @base.json" + }, { "name": "FDplast SBS @System", "sub_path": "filament/FDplast/FDplast SBS @System.json" @@ -4112,6 +4160,14 @@ "name": "addnorth TPU Pro Matte 95A", "sub_path": "filament/addnorth/BBL/addnorth TPU Pro Matte 95A.json" }, + { + "name": "Goofoo 90A TPU @base", + "sub_path": "filament/Goofoo/Goofoo 90A TPU @base.json" + }, + { + "name": "Goofoo 95A TPU @base", + "sub_path": "filament/Goofoo/Goofoo 95A TPU @base.json" + }, { "name": "Overture TPU @BBL A1", "sub_path": "filament/Overture/BBL/Overture TPU @BBL A1.json" @@ -4156,10 +4212,30 @@ "name": "Overture TPU @System", "sub_path": "filament/Overture/Overture TPU @System.json" }, + { + "name": "Goofoo ABS @System", + "sub_path": "filament/Goofoo/Goofoo ABS @System.json" + }, { "name": "Elegoo ASA-CF @System", "sub_path": "filament/Elegoo/Elegoo ASA-CF @System.json" }, + { + "name": "Goofoo ASA @System", + "sub_path": "filament/Goofoo/Goofoo ASA @System.json" + }, + { + "name": "Goofoo PA @System", + "sub_path": "filament/Goofoo/Goofoo PA @System.json" + }, + { + "name": "Goofoo PA-CF @System", + "sub_path": "filament/Goofoo/Goofoo PA-CF @System.json" + }, + { + "name": "Goofoo PA-GF10 @System", + "sub_path": "filament/Goofoo/Goofoo PA-GF10 @System.json" + }, { "name": "Elegoo PC-FR @System", "sub_path": "filament/Elegoo/Elegoo PC-FR @System.json" @@ -4176,6 +4252,14 @@ "name": "COEX PCTG PRIME @BBL A1M 0.8 nozzle", "sub_path": "filament/COEX/BBL/COEX PCTG PRIME @BBL A1M 0.8 nozzle.json" }, + { + "name": "Goofoo PE @System", + "sub_path": "filament/Goofoo/Goofoo PE @System.json" + }, + { + "name": "Goofoo PE-CF @base", + "sub_path": "filament/Goofoo/Goofoo PE-CF @base.json" + }, { "name": "AliZ PETG-CF @P1-X1", "sub_path": "filament/AliZ/BBL/AliZ PETG-CF @P1-X1.json" @@ -4236,10 +4320,26 @@ "name": "Fiberon PETG-ESD @BBL X1", "sub_path": "filament/Polymaker/BBL/Fiberon PETG-ESD @BBL X1.json" }, + { + "name": "Goofoo PETG @System", + "sub_path": "filament/Goofoo/Goofoo PETG @System.json" + }, + { + "name": "Goofoo PETG HF @base", + "sub_path": "filament/Goofoo/Goofoo PETG HF @base.json" + }, { "name": "addnorth PETG-CF Rigid X", "sub_path": "filament/addnorth/BBL/addnorth PETG-CF Rigid X.json" }, + { + "name": "Goofoo PETG-CF @base", + "sub_path": "filament/Goofoo/Goofoo PETG-CF @base.json" + }, + { + "name": "Goofoo PHA @System", + "sub_path": "filament/Goofoo/Goofoo PHA @System.json" + }, { "name": "COEX PLA @BBL A1M 0.2 nozzle", "sub_path": "filament/COEX/BBL/COEX PLA @BBL A1M 0.2 nozzle.json" @@ -4304,6 +4404,14 @@ "name": "Elegoo Rapid PLA+ @System", "sub_path": "filament/Elegoo/Elegoo Rapid PLA+ @System.json" }, + { + "name": "Goofoo PLA @System", + "sub_path": "filament/Goofoo/Goofoo PLA @System.json" + }, + { + "name": "Goofoo PLA-CF @System", + "sub_path": "filament/Goofoo/Goofoo PLA-CF @System.json" + }, { "name": "Numakers PLA+ @BBL A1", "sub_path": "filament/Numakers/BBL/Numakers PLA+ @BBL A1.json" @@ -5188,9 +5296,61 @@ "name": "COEX PLA+Silk @System", "sub_path": "filament/COEX/COEX PLA+Silk @System.json" }, + { + "name": "Goofoo PLA Silk @base", + "sub_path": "filament/Goofoo/Goofoo PLA Silk @base.json" + }, + { + "name": "Goofoo PP @System", + "sub_path": "filament/Goofoo/Goofoo PP @System.json" + }, + { + "name": "Goofoo PP-CF @base", + "sub_path": "filament/Goofoo/Goofoo PP-CF @base.json" + }, + { + "name": "Goofoo PP-GF @base", + "sub_path": "filament/Goofoo/Goofoo PP-GF @base.json" + }, + { + "name": "Goofoo PVA @System", + "sub_path": "filament/Goofoo/Goofoo PVA @System.json" + }, { "name": "Elegoo Rapid TPU 95A @System", "sub_path": "filament/Elegoo/Elegoo Rapid TPU 95A @System.json" + }, + { + "name": "Goofoo 90A TPU @System", + "sub_path": "filament/Goofoo/Goofoo 90A TPU @System.json" + }, + { + "name": "Goofoo 95A TPU @System", + "sub_path": "filament/Goofoo/Goofoo 95A TPU @System.json" + }, + { + "name": "Goofoo PE-CF @System", + "sub_path": "filament/Goofoo/Goofoo PE-CF @System.json" + }, + { + "name": "Goofoo PETG HF @System", + "sub_path": "filament/Goofoo/Goofoo PETG HF @System.json" + }, + { + "name": "Goofoo PETG-CF @System", + "sub_path": "filament/Goofoo/Goofoo PETG-CF @System.json" + }, + { + "name": "Goofoo PLA Silk @System", + "sub_path": "filament/Goofoo/Goofoo PLA Silk @System.json" + }, + { + "name": "Goofoo PP-CF @System", + "sub_path": "filament/Goofoo/Goofoo PP-CF @System.json" + }, + { + "name": "Goofoo PP-GF @System", + "sub_path": "filament/Goofoo/Goofoo PP-GF @System.json" } ], "process_list": [], diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json new file mode 100644 index 0000000000..9c4d016d49 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo 90A TPU @System", + "inherits": "Goofoo 90A TPU @base", + "from": "system", + "setting_id": "tjq76AQe9SCzZVo6", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json new file mode 100644 index 0000000000..d54531f8c7 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 90A TPU @base.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Goofoo 90A TPU @base", + "inherits": "Generic TPU @System", + "from": "system", + "filament_id": "OFlVOXX3", + "instantiation": "false", + "fan_cooling_layer_time": [ + "60" + ], + "fan_min_speed": [ + "35" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "hot_plate_temp": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "40" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "slow_down_layer_time": [ + "5" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "TPU" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json new file mode 100644 index 0000000000..034e46e5dc --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo 95A TPU @System", + "inherits": "Goofoo 95A TPU @base", + "from": "system", + "setting_id": "2YTvrE1gu1yHHTNM", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json new file mode 100644 index 0000000000..2847a0d028 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo 95A TPU @base.json @@ -0,0 +1,38 @@ +{ + "type": "filament", + "name": "Goofoo 95A TPU @base", + "inherits": "Generic TPU @System", + "from": "system", + "filament_id": "OFk50t30", + "instantiation": "false", + "fan_cooling_layer_time": [ + "60" + ], + "fan_min_speed": [ + "35" + ], + "hot_plate_temp": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "40" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "slow_down_layer_time": [ + "5" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "TPU" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json new file mode 100644 index 0000000000..628ca6e5bd --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo ABS @System", + "inherits": "Goofoo ABS @base", + "from": "system", + "setting_id": "UeINgPGH4eaSJinC", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json new file mode 100644 index 0000000000..be841b5806 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ABS @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "name": "Goofoo ABS @base", + "inherits": "Generic ABS @System", + "from": "system", + "filament_id": "OFd3PmW4", + "instantiation": "false", + "close_fan_the_first_x_layers": [ + "1" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "ABS" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json new file mode 100644 index 0000000000..5b5c7355de --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo ASA @System", + "inherits": "Goofoo ASA @base", + "from": "system", + "setting_id": "9ohqNl44uygTPfS9", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json new file mode 100644 index 0000000000..3faf0926e2 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo ASA @base.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Goofoo ASA @base", + "inherits": "Generic ASA @System", + "from": "system", + "filament_id": "OFyncHIG", + "instantiation": "false", + "filament_flow_ratio": [ + "0.93" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "ASA" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json new file mode 100644 index 0000000000..1229eb0e3b --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PA @System", + "inherits": "Goofoo PA @base", + "from": "system", + "setting_id": "1ximJVgZZfGmGyzD", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json new file mode 100644 index 0000000000..2a490fa4e0 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA @base.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Goofoo PA @base", + "inherits": "Generic PA @System", + "from": "system", + "filament_id": "OFc2x7Ly", + "instantiation": "false", + "filament_max_volumetric_speed": [ + "12" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PA" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json new file mode 100644 index 0000000000..61f3d494b2 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PA-CF @System", + "inherits": "Goofoo PA-CF @base", + "from": "system", + "setting_id": "US4zznMNti8tLUHG", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json new file mode 100644 index 0000000000..ad309aa6bf --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-CF @base.json @@ -0,0 +1,17 @@ +{ + "type": "filament", + "name": "Goofoo PA-CF @base", + "inherits": "Generic PA-CF @System", + "from": "system", + "filament_id": "OF7skcRj", + "instantiation": "false", + "filament_max_volumetric_speed": [ + "12" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PA-CF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json new file mode 100644 index 0000000000..34235b2c92 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PA-GF10 @System", + "inherits": "Goofoo PA-GF10 @base", + "from": "system", + "setting_id": "Lea3hf2lQG0M9eTC", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json new file mode 100644 index 0000000000..c0233b81e4 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PA-GF10 @base.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "name": "Goofoo PA-GF10 @base", + "inherits": "Generic PA-CF @System", + "from": "system", + "filament_id": "OFtjqw2h", + "instantiation": "false", + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PA-GF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json new file mode 100644 index 0000000000..9ba71b4874 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PE @System", + "inherits": "Goofoo PE @base", + "from": "system", + "setting_id": "muNxvgr0vdavMaOJ", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json new file mode 100644 index 0000000000..a6ad2ee8a1 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PE @base", + "inherits": "Generic PE @System", + "from": "system", + "filament_id": "OFAln723", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PE" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json new file mode 100644 index 0000000000..fe4f954ade --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PE-CF @System", + "inherits": "Goofoo PE-CF @base", + "from": "system", + "setting_id": "58fMbg6AClvalw5o", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json new file mode 100644 index 0000000000..5f5719676b --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PE-CF @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PE-CF @base", + "inherits": "Generic PE-CF @System", + "from": "system", + "filament_id": "OF4Ll1Sk", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PE-CF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json new file mode 100644 index 0000000000..96a96f60f1 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PETG @System", + "inherits": "Goofoo PETG @base", + "from": "system", + "setting_id": "a9OKgJeoJgzfZiAB", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json new file mode 100644 index 0000000000..5d380c9207 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG @base.json @@ -0,0 +1,26 @@ +{ + "type": "filament", + "name": "Goofoo PETG @base", + "inherits": "Generic PETG @System", + "from": "system", + "filament_id": "OFHdIbiu", + "instantiation": "false", + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PETG" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json new file mode 100644 index 0000000000..9e7bef8497 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PETG HF @System", + "inherits": "Goofoo PETG HF @base", + "from": "system", + "setting_id": "eMjhTRf5qPeeqSgk", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json new file mode 100644 index 0000000000..dd5ec7628c --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG HF @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PETG HF @base", + "inherits": "Generic PETG HF @System", + "from": "system", + "filament_id": "OF5bjxyx", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PETG HF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json new file mode 100644 index 0000000000..6a2a6713f5 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PETG-CF @System", + "inherits": "Goofoo PETG-CF @base", + "from": "system", + "setting_id": "ULNFo6zjgjc5MEIa", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json new file mode 100644 index 0000000000..2c937a5b7e --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PETG-CF @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PETG-CF @base", + "inherits": "Generic PETG-CF @System", + "from": "system", + "filament_id": "OFo6Ff38", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PETG-CF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json new file mode 100644 index 0000000000..dee540cbca --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PHA @System", + "inherits": "Goofoo PHA @base", + "from": "system", + "setting_id": "cfdeMyqld72Lqh38", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json new file mode 100644 index 0000000000..bf93e717ee --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PHA @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PHA @base", + "inherits": "Generic PHA @System", + "from": "system", + "filament_id": "OFicmNhN", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PHA" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json new file mode 100644 index 0000000000..bb5cec6fb5 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PLA @System", + "inherits": "Goofoo PLA @base", + "from": "system", + "setting_id": "UFWRE1b3706Cu1Iq", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json new file mode 100644 index 0000000000..953226b7bb --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA @base.json @@ -0,0 +1,26 @@ +{ + "type": "filament", + "name": "Goofoo PLA @base", + "inherits": "Generic PLA @System", + "from": "system", + "filament_id": "OFoq0Cmt", + "instantiation": "false", + "hot_plate_temp": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "40" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PLA" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json new file mode 100644 index 0000000000..faff94a9dc --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PLA Silk @System", + "inherits": "Goofoo PLA Silk @base", + "from": "system", + "setting_id": "2pW2NEoY4hFCkNun", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json new file mode 100644 index 0000000000..0142549b3c --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA Silk @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PLA Silk @base", + "inherits": "Generic PLA Silk @System", + "from": "system", + "filament_id": "OFpta2gc", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PLA Silk" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json new file mode 100644 index 0000000000..b5dd4d30b2 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PLA-CF @System", + "inherits": "Goofoo PLA-CF @base", + "from": "system", + "setting_id": "R0UMDUPY9ryat8gQ", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json new file mode 100644 index 0000000000..e7c18576db --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PLA-CF @base.json @@ -0,0 +1,29 @@ +{ + "type": "filament", + "name": "Goofoo PLA-CF @base", + "inherits": "Generic PLA-CF @System", + "from": "system", + "filament_id": "OFMNABGJ", + "instantiation": "false", + "filament_flow_ratio": [ + "0.98" + ], + "hot_plate_temp": [ + "40" + ], + "hot_plate_temp_initial_layer": [ + "40" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PLA-CF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json new file mode 100644 index 0000000000..239d479185 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PP @System", + "inherits": "Goofoo PP @base", + "from": "system", + "setting_id": "TaB8JUtjJWgRcNrv", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json new file mode 100644 index 0000000000..e664d23e6c --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PP @base", + "inherits": "Generic PP @System", + "from": "system", + "filament_id": "OFlqlUSx", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PP" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json new file mode 100644 index 0000000000..ee7d75d9dc --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PP-CF @System", + "inherits": "Goofoo PP-CF @base", + "from": "system", + "setting_id": "uHocbocT6flJhlBz", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json new file mode 100644 index 0000000000..2a5650d6eb --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-CF @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PP-CF @base", + "inherits": "Generic PP-CF @System", + "from": "system", + "filament_id": "OFUUiuIV", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PP-CF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json new file mode 100644 index 0000000000..a532c66dd9 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PP-GF @System", + "inherits": "Goofoo PP-GF @base", + "from": "system", + "setting_id": "mns8gICV0aNwJ02L", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json new file mode 100644 index 0000000000..c6e692c13f --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PP-GF @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PP-GF @base", + "inherits": "Generic PP-GF @System", + "from": "system", + "filament_id": "OFaOhzl8", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PP-GF" + ] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json new file mode 100644 index 0000000000..a81dba232c --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @System.json @@ -0,0 +1,9 @@ +{ + "type": "filament", + "name": "Goofoo PVA @System", + "inherits": "Goofoo PVA @base", + "from": "system", + "setting_id": "tUXbv31nYkXJ87OT", + "instantiation": "true", + "compatible_printers": [] +} diff --git a/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json new file mode 100644 index 0000000000..a83b99e0d3 --- /dev/null +++ b/resources/profiles/OrcaFilamentLibrary/filament/Goofoo/Goofoo PVA @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "name": "Goofoo PVA @base", + "inherits": "Generic PVA @System", + "from": "system", + "filament_id": "OF86rkt6", + "instantiation": "false", + "filament_vendor": [ + "Goofoo" + ], + "filament_type": [ + "PVA" + ] +} From c7b4e8ef84916f88682c9610df1a6c7fc133b511 Mon Sep 17 00:00:00 2001 From: HanifKoh <76276251+HanifKoh@users.noreply.github.com> Date: Wed, 14 Oct 2026 15:59:41 +0800 Subject: [PATCH 2/3] build_linux.sh: Forward Arguments After -- to the CMake Configure Step (#16465) Everything after `--` is appended, unchanged and last, to the cmake configure line of the deps and OrcaSlicer builds, so a custom compiler, compile flags or linker can be passed without adding an option to the script for each one. The arguments are kept as an array, so a value with spaces such as -DCMAKE_CXX_FLAGS="-O2 -march=native" survives, and they are forwarded into the -g container. A stray argument without `--` aborts with a message instead of reaching cmake as a path. The existing DEPS_EXTRA_BUILD_ARGS and ORCA_EXTRA_BUILD_ARGS hooks are unchanged and now mentioned in the usage text. --- build_linux.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/build_linux.sh b/build_linux.sh index 59a0f824b8..816f1809fe 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -8,7 +8,7 @@ SCRIPT_PATH=$(dirname "$(readlink -f "${0}")") pushd "${SCRIPT_PATH}" > /dev/null function usage() { - echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-D][-e][-F][-g][-h][-i][-j N][-J N][-p][-r][-s][-t][-u][-l][-L]" + echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-D][-e][-F][-g][-h][-i][-j N][-J N][-p][-r][-s][-t][-u][-l][-L] [-- CMAKE_ARGS...]" echo " -1: limit builds to one core (where possible)" echo " -j N: limit builds to N cores (where possible)" echo " -J N: build up to N dependencies at a time, each still using -j jobs (default: 1)" @@ -29,11 +29,15 @@ function usage() { echo " -u: install system dependencies (asks for sudo password; build prerequisite)" echo " -l: use Clang instead of GCC (default: GCC)" echo " -L: use ld.lld as linker (if available)" + echo " -- CMAKE_ARGS...: pass everything after '--' to the cmake configure step of the deps (-d) and OrcaSlicer (-s/-t) builds," + echo " e.g. -DCMAKE_CXX_FLAGS=\"-O2 -march=native\", -DCMAKE_CXX_COMPILER=g++-14, -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=mold." + echo " They come last on the cmake command line, so they override what -l and -L set." echo "For a first use, you want to './${SCRIPT_NAME} -u'" echo " and then './${SCRIPT_NAME} -dsi'" echo "For a GitHub Actions-like Linux build locally, use './${SCRIPT_NAME} -g -istrlL'" echo "Use './${SCRIPT_NAME} -gF -istrlL' to rebuild the cached runner image first." echo "Set ORCA_CONTAINER_CLI, ORCA_DOCKER_IMAGE, ORCA_DOCKER_BASE_IMAGE, or ORCA_DOCKER_CMAKE_VERSION to override the container runtime, cached image tag, base image, or CMake version." + echo "DEPS_EXTRA_BUILD_ARGS and ORCA_EXTRA_BUILD_ARGS add whitespace-separated cmake configure arguments to the deps and OrcaSlicer builds; prefer '--' for arguments that contain spaces." } SLIC3R_PRECOMPILED_HEADERS="ON" @@ -131,6 +135,20 @@ while getopts ":1j:J:bcCdDeFghiprstulL" opt ; do esac done +# getopts stops at '--'; whatever follows is handed to cmake unchanged. +if [[ ${OPTIND} -le $# ]] ; then + separator_index=$((OPTIND-1)) + if [[ "${!separator_index}" != "--" ]] ; then + echo "Unexpected argument '${!OPTIND}': cmake arguments must follow '--', aborting." + exit 1 + fi +fi +shift $((OPTIND-1)) +EXTRA_CMAKE_ARGS=("$@") +if [[ ${#EXTRA_CMAKE_ARGS[@]} -gt 0 ]] ; then + FORWARDED_ARGS+=("--" "${EXTRA_CMAKE_ARGS[@]}") +fi + if [ ${OPTIND} -eq 1 ] ; then usage exit 1 @@ -547,7 +565,7 @@ if [[ -n "${BUILD_DEPS}" ]] ; then BUILD_ARGS+=(-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}") fi - print_and_run cmake -S deps -B deps/$BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" "${CMAKE_CCACHE_ARGS[@]}" -G Ninja "${COLORED_OUTPUT}" "${BUILD_ARGS[@]}" + print_and_run cmake -S deps -B deps/$BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" "${CMAKE_CCACHE_ARGS[@]}" -G Ninja "${COLORED_OUTPUT}" "${BUILD_ARGS[@]}" "${EXTRA_CMAKE_ARGS[@]}" # The top-level build runs one dependency at a time by default, which keeps the console # output readable and lets that dependency's own build use all of CMAKE_BUILD_PARALLEL_LEVEL. # -J raises the top level instead, and -j still applies in full to every dependency, so the @@ -593,7 +611,8 @@ if [[ -n "${BUILD_ORCA}" ]] || [[ -n "${BUILD_TESTS}" ]] ; then -DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} \ -DORCA_TOOLS=ON \ "${COLORED_OUTPUT}" \ -"${BUILD_ARGS[@]}" +"${BUILD_ARGS[@]}" \ +"${EXTRA_CMAKE_ARGS[@]}" echo "done" if [[ -n "${BUILD_ORCA}" ]]; then echo "Building OrcaSlicer ..." From ea90f451271128c56f13c7f1435e2c0cd1208cdc Mon Sep 17 00:00:00 2001 From: Swoy Derossi Date: Wed, 14 Oct 2026 11:06:56 +0200 Subject: [PATCH 3/3] Add Align/Distribute objects on the print plate (#13373) * Add Align/Distribute objects on the print plate Ports the Align/Distribute feature from BambuStudio 2.5 (AGPLv3, same license as OrcaSlicer). Adds a new GLGizmoAlignment helper that operates on the GLCanvas3D selection, twelve thin Plater wrappers, and an Align/Distribute submenu attached to the same five context menus BambuStudio attaches it to: object menu, text part, BBL part, and the single/multi-volume context menus. GLCanvas3D::do_move gains a defaulted force_volume_move parameter so the helper can move multiple selected volumes within a single object even when selection mode is Instance. GLGizmosManager gains check_object_located_outside_plate, which switches the active plate to the one containing the selection before align/distribute runs. Co-Authored-By: Claude Opus 4.7 (1M context) * fix build errors --------- Co-authored-by: yw4z Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com> --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GLCanvas3D.cpp | 22 +- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GUI_Factories.cpp | 254 +++++++- src/slic3r/GUI/GUI_Factories.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp | 694 +++++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp | 95 +++ src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 31 + src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + src/slic3r/GUI/Plater.cpp | 97 +++ src/slic3r/GUI/Plater.hpp | 12 + 11 files changed, 1196 insertions(+), 15 deletions(-) create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp create mode 100644 src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index dd13fd5353..0af1f2f2e1 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -174,6 +174,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoAssembly.hpp GUI/Gizmos/GLGizmoBase.cpp GUI/Gizmos/GLGizmoBase.hpp + GUI/Gizmos/GLGizmoAlignment.cpp + GUI/Gizmos/GLGizmoAlignment.hpp GUI/Gizmos/GLGizmoBrimEars.cpp GUI/Gizmos/GLGizmoBrimEars.hpp GUI/Gizmos/GLGizmoCut.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index de838f5a2b..3ac4fc2f78 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5520,7 +5520,7 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) m_tooltip.set_text(tooltip); } -void GLCanvas3D::do_move(const std::string& snapshot_type) +void GLCanvas3D::do_move(const std::string& snapshot_type, bool force_volume_move) { if (m_model == nullptr) return; @@ -5552,10 +5552,18 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) // Move instances/volumes ModelObject* model_object = m_model->objects[object_idx]; - if (model_object == nullptr) + if (model_object == nullptr) continue; - if (selection_mode == Selection::Instance) { + if (force_volume_move || selection_mode == Selection::Volume) { + auto cur_mv = model_object->volumes[volume_idx]; + if (cur_mv->get_transformation() != v->get_volume_transformation()) { + cur_mv->set_transformation(v->get_volume_transformation()); + // BBS: backup + Slic3r::save_object_mesh(*model_object); + } + } + else if (selection_mode == Selection::Instance) { if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) { if ((model_object->instances[instance_idx]->get_assemble_offset() - v->get_instance_offset()).norm() > 1e-2) { model_object->instances[instance_idx]->set_assemble_transformation(v->get_instance_transformation()); @@ -5564,14 +5572,6 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); } } - else if (selection_mode == Selection::Volume) { - auto cur_mv = model_object->volumes[volume_idx]; - if (cur_mv->get_transformation() != v->get_volume_transformation()) { - cur_mv->set_transformation(v->get_volume_transformation()); - // BBS: backup - Slic3r::save_object_mesh(*model_object); - } - } object_moved = true; model_object->invalidate_bounding_box(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2cb6bcea4f..df265bb080 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1305,7 +1305,7 @@ public: void set_tooltip(const std::string& tooltip); // the following methods add a snapshot to the undo/redo stack, unless the given string is empty - void do_move(const std::string& snapshot_type); + void do_move(const std::string& snapshot_type, bool force_volume_move = false); void do_rotate(const std::string& snapshot_type); void do_scale(const std::string& snapshot_type); void do_center(); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index f4508f47ac..ca487ec3a5 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -16,6 +16,7 @@ #include "Selection.hpp" //BBS: add partplate related logic #include "PartPlate.hpp" +#include "Gizmos/GLGizmoAlignment.hpp" #include "Gizmos/GLGizmoEmboss.hpp" #include "Gizmos/GLGizmoSVG.hpp" @@ -1672,6 +1673,8 @@ void MenuFactory::create_extra_object_menu() append_menu_item_merge_parts_to_single_part(&m_object_menu); // Object Center append_menu_item_center(&m_object_menu); + // Object Align/Distribute + append_menu_item_align_distribute(&m_object_menu); // Object Drop append_menu_item_drop(&m_object_menu); // Object Split @@ -1779,6 +1782,7 @@ void MenuFactory::create_text_part_menu() append_menu_item_fix_through_cgal(menu); append_menu_item_simplify(menu); append_menu_item_center(menu); + append_menu_item_align_distribute(menu); append_menu_items_mirror(menu); menu->AppendSeparator(); append_menu_item_per_object_process(menu); @@ -1811,6 +1815,7 @@ void MenuFactory::create_bbl_part_menu() append_menu_item_simplify(menu); append_menu_item_smooth_mesh(menu); append_menu_item_center(menu); + append_menu_item_align_distribute(menu); append_menu_item_drop(menu); append_menu_items_mirror(menu); wxMenu* split_menu = new wxMenu(); @@ -2136,6 +2141,7 @@ wxMenu* MenuFactory::multi_selection_menu() index++; } append_menu_item_center(menu); + append_menu_item_align_distribute(menu); append_menu_item_drop(menu); append_menu_item_fix_through_cgal(menu); //append_menu_item_simplify(menu); @@ -2144,13 +2150,13 @@ wxMenu* MenuFactory::multi_selection_menu() append_menu_item_set_printable(menu); menu->AppendSeparator(); - + append_menu_item_set_auto_drop(menu); menu->AppendSeparator(); - + append_menu_item_per_object_process(menu); menu->AppendSeparator(); - + append_menu_items_convert_unit(menu); append_menu_item_replace_all_with_stl(menu); //BBS @@ -2161,6 +2167,7 @@ wxMenu* MenuFactory::multi_selection_menu() } else { append_menu_item_center(menu); + append_menu_item_align_distribute(menu); append_menu_item_drop(menu); append_menu_item_fix_through_cgal(menu); //append_menu_item_simplify(menu); @@ -2325,6 +2332,247 @@ void MenuFactory::append_menu_item_center(wxMenu* menu) }, m_parent); } +void MenuFactory::append_menu_item_align_distribute(wxMenu *menu) +{ + wxMenu* align_distribute_menu = new wxMenu(); + if (!align_distribute_menu) + return; + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Distribute left-right") + " (X)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->distribute_selection_x(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_X); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Distribute front-back") + " (Y)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->distribute_selection_y(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Y); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Distribute top-bottom") + " (Z)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->distribute_selection_z(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Z); + }, + m_parent); + + align_distribute_menu->AppendSeparator(); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align left") + " (-X)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_x_min(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MIN); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align left-right center") + " (X)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_x_center(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_X); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align right") + " (+X)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_x_max(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MAX); + }, + m_parent); + + align_distribute_menu->AppendSeparator(); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align front") + " (-Y)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_y_min(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MIN); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align front-back center") + " (Y)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_y_center(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Y); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align back") + " (+Y)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_y_max(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MAX); + }, + m_parent); + + align_distribute_menu->AppendSeparator(); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align bottom") + " (-Z)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_z_min(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MIN); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align top-bottom center") + " (Z)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_z_center(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Z); + }, + m_parent); + + append_menu_item( + align_distribute_menu, wxID_ANY, _L("Align top") + " (+Z)", "", + [](wxCommandEvent &) { + auto canvas3d = plater()->get_view3D_canvas3D(); + canvas3d->get_gizmos_manager().check_object_located_outside_plate(true); + plater()->align_selection_z_max(); + }, + "", nullptr, + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + return alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MAX); + }, + m_parent); + + append_submenu(menu, align_distribute_menu, wxID_ANY, _L("Align/Distribute"), _L("Align and distribute objects"), "", + []() { + if (plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasView3D) + return false; + auto canvas3d = plater()->get_view3D_canvas3D(); + GLGizmoAlignment alignment_helper(*canvas3d); + + bool has_any_align = alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_X) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Y) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::CENTER_Z) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MAX) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::X_MIN) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MAX) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::Y_MIN) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MAX) || + alignment_helper.can_align(GLGizmoAlignment::AlignType::Z_MIN); + + bool has_any_distribute = alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_X) || + alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Y) || + alignment_helper.can_distribute(GLGizmoAlignment::AlignType::DISTRIBUTE_Z); + + return has_any_align || has_any_distribute; + }, m_parent); +} + void MenuFactory::append_menu_item_drop(wxMenu* menu) { append_menu_item(menu, wxID_ANY, _L("Drop") , "", diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index 4202cce5bc..65526c5c04 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -175,6 +175,7 @@ private: void append_menu_item_merge_to_single_object(wxMenu* menu); void append_menu_item_merge_parts_to_single_part(wxMenu *menu); void append_menu_items_mirror(wxMenu *menu); + void append_menu_item_align_distribute(wxMenu *menu); void append_menu_item_precise_seam_submenu(wxMenu* menu); void append_menu_item_invalidate_cut_info(wxMenu *menu); void append_menu_item_edit_text(wxMenu *menu); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp new file mode 100644 index 0000000000..7e97d64940 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.cpp @@ -0,0 +1,694 @@ +#include "GLGizmoAlignment.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "libslic3r/Model.hpp" + +namespace Slic3r { +namespace GUI { + +GLGizmoAlignment::GLGizmoAlignment(GLCanvas3D& canvas) : m_canvas(canvas) +{ +} + +bool GLGizmoAlignment::align_objects(AlignType type, bool align_parent) +{ + if (!validate_selection_for_align()) { + return false; + } + + switch (type) { + case AlignType::CENTER_X: return align_to_center(type, align_parent); + case AlignType::CENTER_Y: return align_to_center(type, align_parent); + case AlignType::CENTER_Z: return align_to_center(type, align_parent); + case AlignType::Y_MAX: return align_to_y_max(align_parent); + case AlignType::Y_MIN: return align_to_y_min(align_parent); + case AlignType::X_MAX: return align_to_x_max(align_parent); + case AlignType::X_MIN: return align_to_x_min(align_parent); + case AlignType::Z_MAX: return align_to_z_max(align_parent); + case AlignType::Z_MIN: return align_to_z_min(align_parent); + default: + return false; + } +} + +bool GLGizmoAlignment::distribute_objects(AlignType type) +{ + if (!can_distribute(type)) { + return false; + } + + switch (type) { + case AlignType::DISTRIBUTE_X: + return distribute_x(); + case AlignType::DISTRIBUTE_Y: + return distribute_y(); + case AlignType::DISTRIBUTE_Z: + return distribute_z(); + default: + return false; + } +} + +bool GLGizmoAlignment::align_to_y_max(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.max.y(); }, + [](Vec3d& displacement, double target, double current_max) { + displacement.y() = target - current_max; + }, "Align Y Max", align_parent + ); +} + +bool GLGizmoAlignment::align_to_y_min(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.min.y(); }, + [](Vec3d& displacement, double target, double current_min) { + displacement.y() = target - current_min; + }, "Align Y Min", align_parent + ); +} + +bool GLGizmoAlignment::align_to_x_max(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.max.x(); }, + [](Vec3d& displacement, double target, double current_max) { + displacement.x() = target - current_max; + }, "Align X Max", align_parent + ); +} + +bool GLGizmoAlignment::align_to_x_min(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.min.x(); }, + [](Vec3d& displacement, double target, double current_min) { + displacement.x() = target - current_min; + }, "Align X Min", align_parent + ); +} + +bool GLGizmoAlignment::align_to_center(AlignType type,bool align_parent) +{ + const Selection& selection = get_selection(); + std::string type_str = type == AlignType::CENTER_X ? "X" : (type == AlignType::CENTER_Y ? "Y" : "Z"); + std::string operation_name = type == AlignType::CENTER_X ? "X Center" : (type == AlignType::CENTER_Y ? "Y Center" : "Z Center"); + double selection_center = 0.f; + if (align_parent) { + selection_center = get_current_coord(operation_name, m_parent_box); + + // Handle multiple volume selection + if (is_part_align_parent()) { + if (!take_snapshot("Align to parent center " + type_str)) { + return false; + } + + get_selection().setup_cache(); + + auto selection_bbox = selection.get_bounding_box(); + double current_coord = get_current_coord(operation_name, selection_bbox); + Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord); + // Move each selected volume to align to the center of their collective bounding box + for (unsigned int idx : selection.get_volume_idxs()) { + const GLVolume *volume = selection.get_volume(idx); + if (volume) { + get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement); + } + } + finish_operation("Align to parent center " + type_str); + return true; + } + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.empty()) return false; + // Handle multiple objects or parts selection + + BoundingBoxf3 selection_bbox = selection.get_bounding_box(); + if (!take_snapshot("Align to parent center " + type_str)) { + return false; + } + + get_selection().setup_cache(); + double current_coord = get_current_coord(operation_name, big_bb); + Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord); + // Multiple objects: use selection bounding box for alignment + for (const auto &obj : objects) { + apply_transformation(obj.object_idx, obj.instance_idx, displacement); + } + + finish_operation("Align to parent center " + type_str); + return true; + } + // Handle single object selection// Handle multiple volume selection + if (selection.is_single_full_object() || + selection.is_multiple_volume() || selection.is_multiple_modifier() || selection.is_single_volume() || selection.is_single_modifier()) { + if (!take_snapshot("Align Parts Center " + type_str)){ + return false; + } + + get_selection().setup_cache(); + + BoundingBoxf3 selection_bbox = selection.get_bounding_box(); + selection_center = get_current_coord(operation_name, selection_bbox); + + // Move each selected volume to align to the center of their collective bounding box + for (unsigned int idx : selection.get_volume_idxs()) { + const GLVolume* volume = selection.get_volume(idx); + if (volume) { + auto temp_box = volume->transformed_convex_hull_bounding_box(); + double current = get_current_coord(operation_name, temp_box); + double offset = selection_center - current; + Vec3d displacement = generate_displacement(operation_name, offset); + get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement); + } + } + + finish_operation("Align Parts Center" + type_str, true); + return true; + } + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.empty()) return false; + // Handle multiple objects or parts selection + if (selection.is_multiple_full_object()) { + BoundingBoxf3 selection_bbox = selection.get_bounding_box(); + double selection_center = get_current_coord(operation_name, selection_bbox); + + if (!take_snapshot("Align Objects Center" + type_str)) { + return false; + } + + get_selection().setup_cache(); + // Multiple objects: use selection bounding box for alignment + for (const auto& obj : objects) { + BoundingBoxf3 temp_bbox = obj.bbox; + double current_coord = get_current_coord(operation_name, temp_bbox); + Vec3d displacement = generate_displacement(operation_name, selection_center - current_coord); + apply_transformation(obj.object_idx, obj.instance_idx, displacement); + } + finish_operation("Align Objects Center" + type_str); + return true; + } + return false; +} + +bool GLGizmoAlignment::align_to_z_max(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.max.z(); }, + [](Vec3d& displacement, double target, double current_max) { + displacement.z() = target - current_max; + }, "Align Z Max", align_parent + ); +} + +bool GLGizmoAlignment::align_to_z_min(bool align_parent) +{ + return align_objects_generic( + [](const ObjectInfo& obj) { return obj.bbox.min.z(); }, + [](Vec3d& displacement, double target, double current_min) { + displacement.z() = target - current_min; + }, "Align Z Min", align_parent + ); +} + +bool GLGizmoAlignment::distribute_y() +{ + return distribute_objects_generic( + [](const ObjectInfo& obj) { return obj.center.y(); }, + 1, + "Distribute Y" + ); +} + +bool GLGizmoAlignment::distribute_x() +{ + return distribute_objects_generic( + [](const ObjectInfo& obj) { return obj.center.x(); }, + 0, + "Distribute X" + ); +} + +bool GLGizmoAlignment::distribute_z() +{ + return distribute_objects_generic( + [](const ObjectInfo& obj) { return obj.center.z(); }, + 2, + "Distribute Z" + ); +} + +template +bool GLGizmoAlignment::align_objects_generic(GetCoordFunc get_coord, SetCoordFunc set_coord, const std::string &operation_name ,bool align_parent) +{ + const Selection& selection = get_selection(); + if (align_parent) { + // Find reference coordinate + double reference_coord = get_current_coord(operation_name, m_parent_box); + // Handle parts selection differently + if (is_part_align_parent()) { + if (!take_snapshot("align to parent node " + operation_name)) { + return false; + } + + get_selection().setup_cache(); + + // Get all selected volumes + std::vector volumes; + for (unsigned int idx : selection.get_volume_idxs()) { + const GLVolume *volume = selection.get_volume(idx); + if (volume) { volumes.push_back(volume); } + } + + if (volumes.empty()) + return false; + BoundingBoxf3 selection_bbox = selection.get_bounding_box(); + double current_coord = get_current_coord(operation_name, selection_bbox); + Vec3d displacement = generate_displacement(operation_name, reference_coord - current_coord); + for (const GLVolume *volume : volumes) { + if (displacement.norm() > 1e-6) { + get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement); + } + } + + finish_operation("align to parent node " + operation_name); + return true; + } + + // Handle objects selection (original logic) + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.empty()) return false; + + if (!take_snapshot("align to parent node " + operation_name)) { return false; } + + get_selection().setup_cache(); + + double current_coord = get_current_coord(operation_name, big_bb); + Vec3d displacement = generate_displacement(operation_name, reference_coord - current_coord); + + for (const auto &obj : objects) { + if (displacement.norm() > 1e-6) { + apply_transformation(obj.object_idx, obj.instance_idx, displacement); + } + } + + finish_operation("align to parent node " + operation_name); + return true; + } + // Handle parts selection differently + if (selection.is_single_full_object() || selection.is_multiple_volume() || selection.is_multiple_modifier()) { + if (!take_snapshot(operation_name)) { + return false; + } + + get_selection().setup_cache(); + + // Get all selected volumes + std::vector volumes; + for (unsigned int idx : selection.get_volume_idxs()) { + const GLVolume* volume = selection.get_volume(idx); + if (volume) { + volumes.push_back(volume); + } + } + + if (volumes.empty()) return false; + + // Find reference coordinate + double reference_coord = 0.0; + bool first = true; + + for (const GLVolume* volume : volumes) { + BoundingBoxf3 bbox = volume->transformed_convex_hull_bounding_box(); + double coord = 0.0; + + if (operation_name.find("X Max") != std::string::npos) { + coord = bbox.max.x(); + } else if (operation_name.find("X Min") != std::string::npos) { + coord = bbox.min.x(); + } else if (operation_name.find("Y Max") != std::string::npos) { + coord = bbox.max.y(); + } else if (operation_name.find("Y Min") != std::string::npos) { + coord = bbox.min.y(); + } else if (operation_name.find("Z Max") != std::string::npos) { + coord = bbox.max.z(); + } else if (operation_name.find("Z Min") != std::string::npos) { + coord = bbox.min.z(); + } + + if (first) { + reference_coord = coord; + first = false; + } else { + if (operation_name.find("Max") != std::string::npos) { + reference_coord = std::max(reference_coord, coord); + } else if (operation_name.find("Min") != std::string::npos) { + reference_coord = std::min(reference_coord, coord); + } + } + } + + for (const GLVolume* volume : volumes) { + BoundingBoxf3 bbox = volume->transformed_convex_hull_bounding_box(); + double current_coord = 0.0; + + if (operation_name.find("X Max") != std::string::npos) { + current_coord = bbox.max.x(); + } else if (operation_name.find("X Min") != std::string::npos) { + current_coord = bbox.min.x(); + } else if (operation_name.find("Y Max") != std::string::npos) { + current_coord = bbox.max.y(); + } else if (operation_name.find("Y Min") != std::string::npos) { + current_coord = bbox.min.y(); + } else if (operation_name.find("Z Max") != std::string::npos) { + current_coord = bbox.max.z(); + } else if (operation_name.find("Z Min") != std::string::npos) { + current_coord = bbox.min.z(); + } + + Vec3d displacement = Vec3d::Zero(); + + if (operation_name.find("X") != std::string::npos) { + displacement.x() = reference_coord - current_coord; + } else if (operation_name.find("Y") != std::string::npos) { + displacement.y() = reference_coord - current_coord; + } else if (operation_name.find("Z") != std::string::npos) { + displacement.z() = reference_coord - current_coord; + } + + if (displacement.norm() > 1e-6) { + get_selection().translate(volume->object_idx(), volume->instance_idx(), volume->volume_idx(), displacement); + } + } + + finish_operation(operation_name,true); + return true; + } + + // Handle objects selection (original logic) + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.empty()) return false; + + if (!take_snapshot(operation_name)) { + return false; + } + + get_selection().setup_cache(); + + double reference_coord = get_coord(objects[0]); + for (const auto& obj : objects) { + double coord = get_coord(obj); + if (operation_name.find("Max") != std::string::npos) { + reference_coord = std::max(reference_coord, coord); + } else if (operation_name.find("Min") != std::string::npos) { + reference_coord = std::min(reference_coord, coord); + } + } + + for (const auto& obj : objects) { + double current_coord = get_coord(obj); + Vec3d displacement = Vec3d::Zero(); + set_coord(displacement, reference_coord, current_coord); + + if (displacement.norm() > 1e-6) { + apply_transformation(obj.object_idx, obj.instance_idx, displacement); + } + } + + finish_operation(operation_name); + return true; +} + +template +bool GLGizmoAlignment::distribute_objects_generic(GetCoordFunc get_coord, int axis, const std::string& operation_name) +{ + const Selection& selection = get_selection(); + + if (selection.is_single_full_object() || selection.is_multiple_volume() || selection.is_multiple_modifier()) { + std::vector volumes; + for (unsigned int idx : selection.get_volume_idxs()) { + const GLVolume* v = selection.get_volume(idx); + if (v) volumes.push_back(v); + } + + if (volumes.size() < 3) return false; + if (!take_snapshot(operation_name)) { + return false; + } + get_selection().setup_cache(); + + struct VolEntry { const GLVolume* v; double coord; }; + std::vector entries; + entries.reserve(volumes.size()); + for (const GLVolume* v : volumes) { + BoundingBoxf3 bbox = v->transformed_convex_hull_bounding_box(); + Vec3d c = bbox.center(); + double coord = (axis == 0 ? c.x() : axis == 1 ? c.y() : c.z()); + entries.push_back({v, coord}); + } + + std::sort(entries.begin(), entries.end(), [](const VolEntry& a, const VolEntry& b){ return a.coord < b.coord; }); + + BoundingBoxf3 selection_bbox = selection.get_bounding_box(); + BoundingBoxf3 left_bbox = entries.front().v->transformed_convex_hull_bounding_box(); + BoundingBoxf3 right_bbox = entries.back().v->transformed_convex_hull_bounding_box(); + auto axis_extent = [&](const BoundingBoxf3 &bb) { return (axis == 0 ? (bb.max.x() - bb.min.x()) : axis == 1 ? (bb.max.y() - bb.min.y()) : (bb.max.z() - bb.min.z())); }; + double left_width = axis_extent(left_bbox); + double right_width = axis_extent(right_bbox); + double bbox_min = (axis == 0 ? selection_bbox.min.x() : axis == 1 ? selection_bbox.min.y() : selection_bbox.min.z()); + double bbox_max = (axis == 0 ? selection_bbox.max.x() : axis == 1 ? selection_bbox.max.y() : selection_bbox.max.z()); + double min_center = bbox_min + left_width * 0.5; + double max_center = bbox_max - right_width * 0.5; + double total_distance = max_center - min_center; + double interval = (entries.size() > 1) ? total_distance / (entries.size() - 1) : 0; + for (size_t i = 1; i < entries.size() - 1; ++i) { + double target_coord = min_center + i * interval; + double current_coord = entries[i].coord; + double offset = target_coord - current_coord; + + if (std::abs(offset) > 1e-6) { + Vec3d displacement = Vec3d::Zero(); + displacement[axis] = offset; + const GLVolume *v = entries[i].v; + get_selection().translate(v->object_idx(), v->instance_idx(), v->volume_idx(), displacement); + } + } + + finish_operation(operation_name,true); + return true; + } + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.size() < 3) return false; + + if (!take_snapshot(operation_name)) { + return false; + } + + get_selection().setup_cache(); + + std::sort(objects.begin(), objects.end(), + [&get_coord](const ObjectInfo& a, const ObjectInfo& b) { + return get_coord(a) < get_coord(b); + }); + + double min_coord = get_coord(objects.front()); + double max_coord = get_coord(objects.back()); + double total_distance = max_coord - min_coord; + double interval = (objects.size() > 1) ? total_distance / (objects.size() - 1) : 0; + for (size_t i = 1; i < objects.size() - 1; ++i) { + double target_coord = min_coord + i * interval; + double current_coord = get_coord(objects[i]); + double offset = target_coord - current_coord; + + if (std::abs(offset) > 1e-6) { + Vec3d displacement = Vec3d::Zero(); + displacement[axis] = offset; + apply_transformation(objects[i].object_idx, objects[i].instance_idx, displacement); + } + } + + finish_operation(operation_name); + return true; +} + +bool GLGizmoAlignment::can_align(AlignType type) const +{ + const Selection& selection = get_selection(); + + bool is_single_object = selection.is_single_full_object(); + bool is_multiple_objects = selection.is_multiple_full_object(); + bool is_single_part = selection.is_single_volume() || selection.is_single_modifier(); + bool is_multiple_parts = selection.is_multiple_volume() || selection.is_multiple_modifier(); + + + return validate_selection_for_align(); +} + +bool GLGizmoAlignment::can_distribute(AlignType type) const +{ + const Selection& selection = get_selection(); + if (selection.is_single_full_object()) { + size_t count = selection.get_volume_idxs().size(); + if (count >= 3) + return true; + } + if (selection.is_single_volume() || + selection.is_single_modifier()) { + return false; + } + + if (selection.is_multiple_volume() || selection.is_multiple_modifier()) { + size_t count = selection.get_volume_idxs().size(); + if (count < 3) return false; + return (type == AlignType::DISTRIBUTE_X || + type == AlignType::DISTRIBUTE_Y || + type == AlignType::DISTRIBUTE_Z); + } + + if (selection.is_multiple_full_object()) { + BoundingBoxf3 big_bb; + auto objects = get_selected_objects_info(big_bb); + if (objects.size() < 3) return false; + return (type == AlignType::DISTRIBUTE_X || type == AlignType::DISTRIBUTE_Y || type == AlignType::DISTRIBUTE_Z); + } + + return validate_selection_for_distribute(); +} + +double GLGizmoAlignment::get_current_coord(std::string operation_name, BoundingBoxf3 &bbox) +{ + double current_coord = 0.0; + if (operation_name.find("X Max") != std::string::npos) { + current_coord = bbox.max.x(); + } else if (operation_name.find("X Min") != std::string::npos) { + current_coord = bbox.min.x(); + } else if (operation_name.find("Y Max") != std::string::npos) { + current_coord = bbox.max.y(); + } else if (operation_name.find("Y Min") != std::string::npos) { + current_coord = bbox.min.y(); + } else if (operation_name.find("Z Max") != std::string::npos) { + current_coord = bbox.max.z(); + } else if (operation_name.find("Z Min") != std::string::npos) { + current_coord = bbox.min.z(); + } else if (operation_name.find("X Center") != std::string::npos) { + current_coord = bbox.center().x(); + } else if (operation_name.find("Y Center") != std::string::npos) { + current_coord = bbox.center().y(); + } else if (operation_name.find("Z Center") != std::string::npos) { + current_coord = bbox.center().z(); + } + return current_coord; +} + +Vec3d GLGizmoAlignment::generate_displacement(std::string operation_name, double offset) { + Vec3d displacement = Vec3d::Zero(); + if (operation_name.find("X") != std::string::npos) { + displacement.x() = offset; + } else if (operation_name.find("Y") != std::string::npos) { + displacement.y() = offset; + } else if (operation_name.find("Z") != std::string::npos) { + displacement.z() = offset; + } + return displacement; +} + +bool GLGizmoAlignment::is_part_align_parent() +{ + Selection &selection = get_selection(); + if (selection.is_multiple_volume() || selection.is_multiple_modifier() || selection.is_single_volume() || selection.is_single_modifier()) { + return true; + } + return false; +} + +std::vector GLGizmoAlignment::get_selected_objects_info(BoundingBoxf3 &big_bb) const +{ + std::vector objects; + Selection& selection = get_selection(); + + if (selection.is_empty()) return objects; + + const auto& content = selection.get_content(); + for (const auto& obj_it : content) { + for (const auto& inst_idx : obj_it.second) { + int obj_idx = obj_it.first; + + if (obj_idx >= 0 && obj_idx < selection.get_model()->objects.size()) { + ModelObject* object = selection.get_model()->objects[obj_idx]; + if (inst_idx >= 0 && inst_idx < object->instances.size()) { + BoundingBoxf3 bbox = object->instance_bounding_box(inst_idx); + big_bb.merge(bbox); + objects.emplace_back(obj_idx, inst_idx, bbox); + } + } + } + } + + return objects; +} + +void GLGizmoAlignment::set_parent_box(const BoundingBoxf3 &bb) { + m_parent_box = bb; +} + +Selection& GLGizmoAlignment::get_selection() const +{ + return m_canvas.get_selection(); +} + +bool GLGizmoAlignment::take_snapshot(const std::string& name) +{ + wxGetApp().plater()->take_snapshot(name); + return true; +} + +void GLGizmoAlignment::apply_transformation(int obj_idx, int inst_idx, const Vec3d& displacement) +{ + get_selection().translate(obj_idx, inst_idx, displacement); +} + +void GLGizmoAlignment::finish_operation(const std::string &operation_name, bool force_volume_move) +{ + get_selection().notify_instance_update(-1, -1); + m_canvas.do_move(operation_name, force_volume_move); +} + +bool GLGizmoAlignment::validate_selection_for_align() const +{ + const Selection& selection = get_selection(); + + if (selection.is_single_full_object() || + selection.is_single_volume() || + selection.is_single_modifier()) { + return true; + } + + return selection.get_volume_idxs().size() >= 2; +} + +bool GLGizmoAlignment::validate_selection_for_distribute() const +{ + const Selection& selection = get_selection(); + + if (selection.is_single_full_object() || selection.is_multiple_full_object()) { + std::set object_indices; + for (int volume_idx : selection.get_volume_idxs()) { + const GLVolume* volume = selection.get_volume(volume_idx); + if (volume) { + object_indices.insert(volume->object_idx()); + } + } + return object_indices.size() >= 3; + } + + return selection.get_volume_idxs().size() >= 3; +} + +} // namespace GUI +} // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp new file mode 100644 index 0000000000..5bbeceb7a6 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoAlignment.hpp @@ -0,0 +1,95 @@ +#ifndef slic3r_GLGizmoAlignment_hpp_ +#define slic3r_GLGizmoAlignment_hpp_ + +#include "libslic3r/Point.hpp" +#include "libslic3r/BoundingBox.hpp" +#include "slic3r/GUI/Selection.hpp" +#include +#include + +namespace Slic3r { +namespace GUI { + +class GLCanvas3D; + +class GLGizmoAlignment +{ +public: + enum class AlignType { + NONE = -1, + CENTER_X, + CENTER_Y, + CENTER_Z, + Y_MAX, + Y_MIN, + X_MAX, + X_MIN, + Z_MAX, + Z_MIN, + DISTRIBUTE_X, + DISTRIBUTE_Y, + DISTRIBUTE_Z + }; + struct ObjectInfo { + int object_idx; + int instance_idx; + BoundingBoxf3 bbox; + Vec3d center; + + ObjectInfo(int obj_idx, int inst_idx, const BoundingBoxf3& bb) + : object_idx(obj_idx), instance_idx(inst_idx), bbox(bb), center(bb.center()) {} + }; + + explicit GLGizmoAlignment(GLCanvas3D& canvas); + ~GLGizmoAlignment() = default; + + bool align_objects(AlignType type,bool align_parent = false); + bool distribute_objects(AlignType type); + + bool align_to_center(AlignType type,bool align_parent = false); + bool align_to_y_max(bool align_parent = false); + bool align_to_y_min(bool align_parent = false); + bool align_to_x_max(bool align_parent = false); + bool align_to_x_min(bool align_parent = false); + bool align_to_z_max(bool align_parent = false); + bool align_to_z_min(bool align_parent = false); + + bool distribute_x(); + bool distribute_y(); + bool distribute_z(); + + bool can_align(AlignType type) const; + bool can_distribute(AlignType type) const; + + std::vector get_selected_objects_info(BoundingBoxf3 &big_bb) const; + double get_current_coord(std::string operation_name, BoundingBoxf3 &bbox); + Vec3d generate_displacement(std::string operation_name, double offset); + bool is_part_align_parent(); + void set_parent_box(const BoundingBoxf3 &bb); + +private: + GLCanvas3D& m_canvas; + + template + bool align_objects_generic(GetCoordFunc get_coord, SetCoordFunc set_coord, const std::string &operation_name, bool align_parent = false); + + template + bool distribute_objects_generic(GetCoordFunc get_coord, int axis, + const std::string& operation_name); + + Selection& get_selection() const; + bool take_snapshot(const std::string& name); + void apply_transformation(int obj_idx, int inst_idx, const Vec3d& displacement); + void finish_operation(const std::string &operation_name, bool force_volume_move = false); + + bool validate_selection_for_align() const; + bool validate_selection_for_distribute() const; + +private: + BoundingBoxf3 m_parent_box; +}; + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLGizmoAlignment_hpp_ \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 41d4811664..a5a3122b85 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -470,6 +470,37 @@ bool GLGizmosManager::check_gizmos_closed_except(EType type) const return true; } +// Switches the active plate to the one containing the first selected object, +// so that subsequent operations (align/distribute) act on a plate the user +// can actually see. +void GLGizmosManager::check_object_located_outside_plate(bool change_plate) +{ + PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); + auto curr_plate_index = plate_list.get_curr_plate_index(); + Selection& selection = m_parent.get_selection(); + auto idxs = selection.get_volume_idxs(); + if (idxs.empty()) + return; + + const GLVolume* v = selection.get_volume(*idxs.begin()); + int object_idx = v->object_idx(); + const Model* model = m_parent.get_model(); + if (object_idx < 0 || object_idx >= (int) model->objects.size()) + return; + + ModelObject* model_object = model->objects[object_idx]; + for (size_t i = 0; i < plate_list.get_plate_count(); ++i) { + auto plate = plate_list.get_plate(i); + for (auto object : plate->get_objects_on_this_plate()) { + if (model_object == object) { + if (change_plate && curr_plate_index != (int) i) + plate_list.select_plate(i); + return; + } + } + } +} + void GLGizmosManager::set_hover_id(int id) { // Measure and assembly handles hover by itself diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 0914f8d958..cba59de9f1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -261,6 +261,7 @@ public: void reset_all_states(); bool open_gizmo(EType type); bool check_gizmos_closed_except(EType) const; + void check_object_located_outside_plate(bool change_plate = true); void set_hover_id(int id); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cf9dddeee7..da828527f2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -245,6 +245,7 @@ #include "Widgets/MultiNozzleSync.hpp" // NozzleOption, tryPopUpMultiNozzleDialog, setExtruderNozzleCount #include "DeviceCore/DevNozzleSystem.h" // DevNozzle, GetExtNozzles / GetRackNozzles #include "ProjectDirtyStateManager.hpp" +#include "Gizmos/GLGizmoAlignment.hpp" #include "Gizmos/GLGizmoSimplify.hpp" // create suggestion notification #include "Gizmos/GLGizmoSVG.hpp" // Drop SVG file #include "Gizmos/GizmoObjectManipulation.hpp" @@ -7484,6 +7485,18 @@ struct Plater::priv void delete_all_objects_from_model(); void reset(bool apply_presets_change = false, bool reload_presets = true); void center_selection(); + void distribute_selection_x(); + void distribute_selection_y(); + void distribute_selection_z(); + void align_selection_x_min(); + void align_selection_x_center(); + void align_selection_x_max(); + void align_selection_y_min(); + void align_selection_y_center(); + void align_selection_y_max(); + void align_selection_z_min(); + void align_selection_z_center(); + void align_selection_z_max(); void drop_selection(); void mirror(Axis axis); void split_object(bool auto_drop = true); @@ -10913,6 +10926,78 @@ void Plater::priv::center_selection() view3D->center_selected(); } +void Plater::priv::distribute_selection_x() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_X); +} + +void Plater::priv::distribute_selection_y() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_Y); +} + +void Plater::priv::distribute_selection_z() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.distribute_objects(GLGizmoAlignment::AlignType::DISTRIBUTE_Z); +} + +void Plater::priv::align_selection_x_min() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::X_MIN); +} + +void Plater::priv::align_selection_x_center() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_X); +} + +void Plater::priv::align_selection_x_max() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::X_MAX); +} + +void Plater::priv::align_selection_y_min() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::Y_MIN); +} + +void Plater::priv::align_selection_y_center() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_Y); +} + +void Plater::priv::align_selection_y_max() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::Y_MAX); +} + +void Plater::priv::align_selection_z_min() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::Z_MIN); +} + +void Plater::priv::align_selection_z_center() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::CENTER_Z); +} + +void Plater::priv::align_selection_z_max() +{ + GLGizmoAlignment alignment_helper(*view3D->get_canvas3d()); + alignment_helper.align_objects(GLGizmoAlignment::AlignType::Z_MAX); +} + void Plater::priv::drop_selection() { view3D->drop_selected(); @@ -22226,6 +22311,18 @@ void Plater::suppress_background_process(const bool stop_background_process) BackgroundSlicingProcess& Plater::background_process() { return p->background_process; } void Plater::center_selection() { p->center_selection(); } +void Plater::distribute_selection_x() { p->distribute_selection_x(); } +void Plater::distribute_selection_y() { p->distribute_selection_y(); } +void Plater::distribute_selection_z() { p->distribute_selection_z(); } +void Plater::align_selection_x_min() { p->align_selection_x_min(); } +void Plater::align_selection_x_center() { p->align_selection_x_center(); } +void Plater::align_selection_x_max() { p->align_selection_x_max(); } +void Plater::align_selection_y_min() { p->align_selection_y_min(); } +void Plater::align_selection_y_center() { p->align_selection_y_center(); } +void Plater::align_selection_y_max() { p->align_selection_y_max(); } +void Plater::align_selection_z_min() { p->align_selection_z_min(); } +void Plater::align_selection_z_center() { p->align_selection_z_center(); } +void Plater::align_selection_z_max() { p->align_selection_z_max(); } void Plater::drop_selection() { p->drop_selection(); } void Plater::mirror(Axis axis) { p->mirror(axis); } void Plater::split_object(bool auto_drop) { p->split_object(auto_drop); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 0bb2d65add..a270eea1c3 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -762,6 +762,18 @@ public: //BBS: add clone logic void clone_selection(); void center_selection(); + void distribute_selection_x(); + void distribute_selection_y(); + void distribute_selection_z(); + void align_selection_x_min(); + void align_selection_x_center(); + void align_selection_x_max(); + void align_selection_y_min(); + void align_selection_y_center(); + void align_selection_y_max(); + void align_selection_z_min(); + void align_selection_z_center(); + void align_selection_z_max(); void drop_selection(); void search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag); void mirror(Axis axis);