From b3d0438daa109490ebbdb8fed0b09a3a0280693a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Feb 2018 16:13:09 +0100 Subject: [PATCH 001/266] WIP: Update variant files - Remove "author" from "metadata" section - Add "hardware_type" for variants that don't have it - Reformat "metadata" section to have the following order: - setting_version - type - hardware_type --- resources/variants/cartesio_0.25.inst.cfg | 3 +-- resources/variants/cartesio_0.4.inst.cfg | 3 +-- resources/variants/cartesio_0.8.inst.cfg | 3 +-- resources/variants/fabtotum_hyb35.inst.cfg | 3 +-- resources/variants/fabtotum_lite04.inst.cfg | 3 +-- resources/variants/fabtotum_lite06.inst.cfg | 3 +-- resources/variants/fabtotum_pro02.inst.cfg | 3 +-- resources/variants/fabtotum_pro04.inst.cfg | 3 +-- resources/variants/fabtotum_pro06.inst.cfg | 3 +-- resources/variants/fabtotum_pro08.inst.cfg | 3 +-- resources/variants/gmax15plus_025_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_04_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_05_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_05_jhead.inst.cfg | 4 ++-- resources/variants/gmax15plus_06_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_08_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_10_jhead.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_025_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_04_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_05_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_05_jhead.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_06_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_08_e3d.inst.cfg | 4 ++-- resources/variants/gmax15plus_dual_10_jhead.inst.cfg | 4 ++-- resources/variants/imade3d_jellybox_0.4.inst.cfg | 3 +-- resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg | 3 +-- resources/variants/ultimaker2_0.25.inst.cfg | 5 ++--- resources/variants/ultimaker2_0.4.inst.cfg | 3 +-- resources/variants/ultimaker2_0.6.inst.cfg | 3 +-- resources/variants/ultimaker2_0.8.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_0.25.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_0.4.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_0.6.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_0.8.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_plus_0.25.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_plus_0.4.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_plus_0.6.inst.cfg | 3 +-- resources/variants/ultimaker2_extended_plus_0.8.inst.cfg | 3 +-- resources/variants/ultimaker2_plus_0.25.inst.cfg | 3 +-- resources/variants/ultimaker2_plus_0.4.inst.cfg | 3 +-- resources/variants/ultimaker2_plus_0.6.inst.cfg | 3 +-- resources/variants/ultimaker2_plus_0.8.inst.cfg | 3 +-- resources/variants/ultimaker3_aa0.25.inst.cfg | 3 +-- resources/variants/ultimaker3_aa0.8.inst.cfg | 3 +-- resources/variants/ultimaker3_aa04.inst.cfg | 4 +--- resources/variants/ultimaker3_bb0.8.inst.cfg | 3 +-- resources/variants/ultimaker3_bb04.inst.cfg | 5 ++--- resources/variants/ultimaker3_extended_aa0.25.inst.cfg | 4 +--- resources/variants/ultimaker3_extended_aa0.8.inst.cfg | 3 +-- resources/variants/ultimaker3_extended_aa04.inst.cfg | 3 +-- resources/variants/ultimaker3_extended_bb0.8.inst.cfg | 3 +-- resources/variants/ultimaker3_extended_bb04.inst.cfg | 5 ++--- 52 files changed, 69 insertions(+), 109 deletions(-) diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index 0cc01093f2..2272aebde5 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = cartesio [metadata] -author = Cartesio -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index 9920e699f5..bd3302da03 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = cartesio [metadata] -author = Cartesio -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index 8031a9fa31..eda8248584 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = cartesio [metadata] -author = Cartesio -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index e8fa13cc0d..6d699f6df8 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 7264abbdda..5d376de4a1 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index 0ad33ca332..0181461613 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index d83618b712..c63ed6d982 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index 4f2a622887..6fc2d7c4f7 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index aa44e762ba..bf48b91965 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index 597d23275e..83f13ef8fc 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = fabtotum [metadata] -author = FABtotum -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index 0500a63638..88730e6722 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.25 diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index 514893a8a5..f107d2ab16 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.4 diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 2579409d5a..72081a4b3d 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index ca107c9559..ca086fca96 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index eb709f1487..bbb5d18df1 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.6 diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index 093bce99c0..944420e064 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.8 diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 977469e304..832861a98a 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index b083174beb..b80074479e 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.25 diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index f1a95f4f2a..3f25835e3a 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.4 diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index dd148f8082..c7dccfd7c7 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index 7e038a3980..0cffafee3b 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index 93cf21780f..a0dc450ec0 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.6 diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index 3088113f27..547cee823d 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.8 diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index a526cc676e..a565c073af 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -4,9 +4,9 @@ version = 2 definition = gmax15plus_dual [metadata] -author = gcreate -type = variant setting_version = 4 +type = variant +hardware_type = nozzle [values] machine_nozzle_size = 0.5 diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index c37a2ecabf..cb20dadbf7 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = imade3d_jellybox [metadata] -author = IMADE3D -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index c3e63aab34..95b696f432 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = imade3d_jellybox [metadata] -author = IMADE3D -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg index aee83e2483..2b1b04f123 100644 --- a/resources/variants/ultimaker2_0.25.inst.cfg +++ b/resources/variants/ultimaker2_0.25.inst.cfg @@ -4,12 +4,11 @@ version = 2 definition = ultimaker2 [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] machine_nozzle_size = 0.25 machine_nozzle_tip_outer_diameter = 0.8 -raft_airgap = 0.25 \ No newline at end of file +raft_airgap = 0.25 diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg index fe128137d9..8886992f6f 100644 --- a/resources/variants/ultimaker2_0.4.inst.cfg +++ b/resources/variants/ultimaker2_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2 [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg index 7fea2fbb22..42de9d3ee8 100644 --- a/resources/variants/ultimaker2_0.6.inst.cfg +++ b/resources/variants/ultimaker2_0.6.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2 [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg index 5f1176b7ec..df2ca88ba2 100644 --- a/resources/variants/ultimaker2_0.8.inst.cfg +++ b/resources/variants/ultimaker2_0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2 [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg index e705327cf8..f04a28e5ba 100644 --- a/resources/variants/ultimaker2_extended_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg index d486ed4f4e..c54202750a 100644 --- a/resources/variants/ultimaker2_extended_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg index f9dd4d4e69..67176632aa 100644 --- a/resources/variants/ultimaker2_extended_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg index ee56b6d194..61917309ef 100644 --- a/resources/variants/ultimaker2_extended_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index f23406fec3..6386d71f50 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index c0b1c6ab79..1426f733cc 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index 6ef64bed5f..5ea4072022 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index 2f890d0827..69b2b9b0d0 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_extended_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index 1c4688568d..2b40656cf4 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index 00a4ef47dd..0aaf4f4e5a 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index 4dceab70d0..7988a949bc 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index e1bbddb823..1a7824b0b1 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker2_plus [metadata] -author = Ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg index 2d2d893202..8f06e73f91 100644 --- a/resources/variants/ultimaker3_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_aa0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3 [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg index 402190c357..218c1ea3bf 100644 --- a/resources/variants/ultimaker3_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_aa0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3 [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg index 0163024fa4..2964ab74a0 100644 --- a/resources/variants/ultimaker3_aa04.inst.cfg +++ b/resources/variants/ultimaker3_aa04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3 [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] @@ -40,4 +39,3 @@ switch_extruder_prime_speed = =switch_extruder_retraction_speeds switch_extruder_retraction_amount = =machine_heat_zone_length top_bottom_thickness = 1.2 wall_thickness = 1.3 - diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index 017da649a0..03b38f225c 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3 [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index 93b2025031..78d201318d 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3 [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] @@ -47,4 +46,4 @@ support_line_width = =round(line_width * 0.4 / 0.35, 2) support_offset = 3 support_xy_distance = =round(wall_line_width_0 * 0.75, 2) support_xy_distance_overhang = =wall_line_width_0 / 2 -switch_extruder_retraction_amount = 12 \ No newline at end of file +switch_extruder_retraction_amount = 12 diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg index 04d7a7990a..f45d90b762 100644 --- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3_extended [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] @@ -38,4 +37,3 @@ support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_line_width_x = 0.23 wall_thickness = 1.3 - diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg index 3e1b3ed3de..1f5709e504 100644 --- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3_extended [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg index 94bee65b5d..4d9d2b4646 100644 --- a/resources/variants/ultimaker3_extended_aa04.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3_extended [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index e1086535ec..752083f42a 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3_extended [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index a995acf77c..1ceaf58c5b 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -4,9 +4,8 @@ version = 2 definition = ultimaker3_extended [metadata] -author = ultimaker -type = variant setting_version = 4 +type = variant hardware_type = nozzle [values] @@ -47,4 +46,4 @@ support_line_width = =round(line_width * 0.4 / 0.35, 2) support_offset = 3 support_xy_distance = =round(wall_line_width_0 * 0.75, 2) support_xy_distance_overhang = =wall_line_width_0 / 2 -switch_extruder_retraction_amount = 12 \ No newline at end of file +switch_extruder_retraction_amount = 12 From 86eb9b925f3bc8e63e51b820e193c789e2feba2e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 7 Feb 2018 14:15:51 +0100 Subject: [PATCH 002/266] WIP: Use variant_name in metadata for XMLMaterialProfile --- .../XmlMaterialProfile/XmlMaterialProfile.py | 64 +++++-------------- 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index f0d016025e..a7d9a7be26 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -618,16 +618,9 @@ class XmlMaterialProfile(InstanceContainer): hotends = machine.iterfind("./um:hotend", self.__namespaces) for hotend in hotends: - hotend_id = hotend.get("id") - if hotend_id is None: - continue - - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) - if not variant_containers: - # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id) - - if not variant_containers: + # The "id" field for hotends in material profiles are actually + hotend_name = hotend.get("id") + if hotend_name is None: continue hotend_compatibility = machine_compatibility @@ -643,20 +636,20 @@ class XmlMaterialProfile(InstanceContainer): else: Logger.log("d", "Unsupported material setting %s", key) - new_hotend_id = self.getId() + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + new_hotend_specific_material_id = self.getId() + "_" + machine_id + "_" + hotend_name.replace(" ", "_") # Same as machine compatibility, keep the derived material containers consistent with the parent material - if ContainerRegistry.getInstance().isLoaded(new_hotend_id): - new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_id)[0] + if ContainerRegistry.getInstance().isLoaded(new_hotend_specific_material_id): + new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_specific_material_id)[0] is_new_material = False else: - new_hotend_material = XmlMaterialProfile(new_hotend_id) + new_hotend_material = XmlMaterialProfile(new_hotend_specific_material_id) is_new_material = True new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) - new_hotend_material.getMetaData()["id"] = new_hotend_id + new_hotend_material.getMetaData()["id"] = new_hotend_specific_material_id new_hotend_material.getMetaData()["name"] = self.getName() - new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"] + new_hotend_material.getMetaData()["variant_name"] = hotend_name new_hotend_material.setDefinition(machine_id) # Don't use setMetadata, as that overrides it for all materials with same base file new_hotend_material.getMetaData()["compatible"] = hotend_compatibility @@ -833,39 +826,30 @@ class XmlMaterialProfile(InstanceContainer): buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_map["buildplate_recommended"] for hotend in machine.iterfind("./um:hotend", cls.__namespaces): - hotend_id = hotend.get("id") - if hotend_id is None: + hotend_name = hotend.get("id") + if hotend_name is None: continue - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) - if not variant_containers: - # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id) - hotend_compatibility = machine_compatibility for entry in hotend.iterfind("./um:setting", cls.__namespaces): key = entry.get("key") if key == "hardware compatible": hotend_compatibility = cls._parseCompatibleValue(entry.text) - new_hotend_id = container_id + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + new_hotend_specific_material_id = container_id + "_" + machine_id + "_" + hotend_name.replace(" ", "_") # Same as machine compatibility, keep the derived material containers consistent with the parent material - found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_id) + found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_specific_material_id) if found_materials: new_hotend_material_metadata = found_materials[0] else: new_hotend_material_metadata = {} new_hotend_material_metadata.update(base_metadata) - if variant_containers: - new_hotend_material_metadata["variant"] = variant_containers[0]["id"] - else: - new_hotend_material_metadata["variant"] = hotend_id - _with_missing_variants.append(new_hotend_material_metadata) + new_hotend_material_metadata["variant_name"] = hotend_name new_hotend_material_metadata["compatible"] = hotend_compatibility new_hotend_material_metadata["machine_manufacturer"] = machine_manufacturer - new_hotend_material_metadata["id"] = new_hotend_id + new_hotend_material_metadata["id"] = new_hotend_specific_material_id new_hotend_material_metadata["definition"] = machine_id if buildplate_map["buildplate_compatible"]: new_hotend_material_metadata["buildplate_compatible"] = buildplate_map["buildplate_compatible"] @@ -992,21 +976,3 @@ def _indent(elem, level = 0): # before the last } def _tag_without_namespace(element): return element.tag[element.tag.rfind("}") + 1:] - -#While loading XML profiles, some of these profiles don't know what variant -#they belong to. We'd like to search by the machine ID and the variant's -#name, but we don't know the variant's ID. Not all variants have been loaded -#yet so we can't run a filter on the name and machine. The ID is unknown -#so we can't lazily load the variant either. So we have to wait until all -#the rest is loaded properly and then assign the correct variant to the -#material files that were missing it. -_with_missing_variants = [] -def _fillMissingVariants(): - registry = ContainerRegistry.getInstance() - for variant_metadata in _with_missing_variants: - variants = registry.findContainersMetadata(definition = variant_metadata["definition"], name = variant_metadata["variant"]) - if not variants: - Logger.log("w", "Could not find variant for variant-specific material {material_id}.".format(material_id = variant_metadata["id"])) - continue - variant_metadata["variant"] = variants[0]["id"] -ContainerRegistry.allMetadataLoaded.connect(_fillMissingVariants) From 55bdc0c85340478547273d35a02fe0964f45b70e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 6 Feb 2018 16:27:01 +0100 Subject: [PATCH 003/266] WIP: Create VariantManager --- cura/CuraApplication.py | 11 +++ cura/Machines/ContainerNode.py | 34 ++++++++ cura/Machines/VariantManager.py | 81 +++++++++++++++++++ cura/Machines/__init__.py | 0 cura/Settings/MachineManager.py | 20 +++++ cura/Settings/NozzleModel.py | 47 +++++++++++ .../XmlMaterialProfile/XmlMaterialProfile.py | 20 +++-- resources/qml/Menus/NozzleMenu.qml | 51 ++++++------ 8 files changed, 228 insertions(+), 36 deletions(-) create mode 100644 cura/Machines/ContainerNode.py create mode 100644 cura/Machines/VariantManager.py create mode 100644 cura/Machines/__init__.py create mode 100644 cura/Settings/NozzleModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 07b3aab60c..d209b90909 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -59,6 +59,8 @@ from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.UserProfilesModel import UserProfilesModel from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager +from cura.Machines.VariantManager import VariantManager + from . import PlatformPhysics from . import BuildVolume @@ -233,6 +235,9 @@ class CuraApplication(QtApplication): if kwargs["parsed_command_line"].get("trigger_early_crash", False): assert not "This crash is triggered by the trigger_early_crash command line argument." + # new stuff + self._variant_manager = VariantManager(ContainerRegistry.getInstance()) + self.default_theme = "cura-light" self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) @@ -707,6 +712,9 @@ class CuraApplication(QtApplication): return False return True + def getVariantManager(self): + return self._variant_manager + def preRun(self): # Last check for unknown commandline arguments parser = self.getCommandlineParser() @@ -723,6 +731,9 @@ class CuraApplication(QtApplication): def run(self): self.preRun() + container_registry = ContainerRegistry.getInstance() + self._variant_manager.initialize() + # Check if we should run as single instance or not self._setUpSingleInstanceServer() diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py new file mode 100644 index 0000000000..b9ebaa698a --- /dev/null +++ b/cura/Machines/ContainerNode.py @@ -0,0 +1,34 @@ +from typing import Optional + +from collections import OrderedDict + +from UM.Logger import Logger + + +## A metadata / container combination. Use getContainer to get the container corresponding to the metadata +class ContainerNode: + def __init__(self, metadata = None): + self.metadata = metadata + self.container = None + self.children_map = OrderedDict() + + def getChildNode(self, child_key: str) -> Optional["QualityNode"]: + return self.children_map.get(child_key) + + def getContainer(self) -> "InstanceContainer": + if self.metadata is None: + raise RuntimeError("Cannot get container for a QualityNode without metadata") + + if self.container is None: + container_id = self.metadata["id"] + Logger.log("d", "Lazy-loading container [%s]", container_id) + from UM.Settings.ContainerRegistry import ContainerRegistry + container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id) + if not container_list: + raise RuntimeError("Failed to lazy-load container [%s], cannot find it" % container_id) + self.container = container_list[0] + + return self.container + + def __str__(self): + return "ContainerNode[%s]" % self.metadata.get("id") diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py new file mode 100644 index 0000000000..1f9f0288ac --- /dev/null +++ b/cura/Machines/VariantManager.py @@ -0,0 +1,81 @@ +from typing import Optional + +from UM.Logger import Logger +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.InstanceContainer import InstanceContainer + +from cura.Machines.ContainerNode import ContainerNode +from cura.Settings.GlobalStack import GlobalStack + + +class VariantType: + BUILD_PLATE = "buildplate" + NOZZLE = "nozzle" + + +ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE) + + +# +# VariantManager is THE place to look for a specific variant. It maintains a variant lookup table with the following +# structure: +# +# [machine_definition_id] -> [variant_type] -> [variant_name] -> ContainerNode(metadata / container) +# Example: "ultimaker3" -> "buildplate" -> "Glass" (if present) -> ContainerNode +# -> ... +# -> "nozzle" -> "AA 0.4" +# -> "BB 0.8" +# -> ... +# +# Note that the "container" field is not loaded in the beginning because it would defeat the purpose of lazy-loading. +# A container is loaded when getVariant() is called to load a variant InstanceContainer. +# +class VariantManager: + + def __init__(self, container_registry): + self._container_registry = container_registry # type: ContainerRegistry + + self._machine_to_variant_dict_map = {} # -> + + self._exclude_variant_id_list = ["empty_variant"] + + # + # Initializes the VariantManager including: + # - initializing the variant lookup table based on the metadata in ContainerRegistry. + # + def initialize(self): + # Cache all variants from the container registry to a variant map for better searching and organization. + variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant") + for variant_metadata in variant_metadata_list: + if variant_metadata["id"] in self._exclude_variant_id_list: + Logger.log("d", "Exclude variant [%s]", variant_metadata["id"]) + continue + + variant_name = variant_metadata["name"] + variant_definition = variant_metadata["definition"] + if variant_definition not in self._machine_to_variant_dict_map: + self._machine_to_variant_dict_map[variant_definition] = {} + #for variant_type in ALL_VARIANT_TYPES: + # self._machine_to_variant_dict_map[variant_definition][variant_type] = {} + + variant_type = variant_metadata["hardware_type"] + #variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type] + variant_dict = self._machine_to_variant_dict_map[variant_definition] + if variant_name in variant_dict: + # ERROR: duplicated variant name. + raise RuntimeError("Found duplicated variant name [%s], type [%s] for machine [%s]" % + (variant_name, variant_type, variant_definition)) + + variant_dict[variant_name] = ContainerNode(metadata = variant_metadata) + + # + # Gets the variant InstanceContainer with the given information. + # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. + # + def getVariant(self, machine_type_name: str, variant_name: str, + variant_type: Optional[str] = None) -> Optional["InstanceContainer"]: + return self._machine_to_variant_dict_map[machine_type_name].get(variant_name) + + def getVariantNodes(self, machine: "GlobalStack"): + machine_type_name = machine.definition.getId() + return self._machine_to_variant_dict_map.get(machine_type_name) diff --git a/cura/Machines/__init__.py b/cura/Machines/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index cc5c4aa539..719f90bdd1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1490,3 +1490,23 @@ class MachineManager(QObject): stacks = ExtruderManager.getInstance().getActiveExtruderStacks() stacks.append(self._global_container_stack) return [ s.containersChanged for s in stacks ] + + # New + @pyqtSlot(str, "QVariant") + def setVariantGroup(self, position, container_node): + Logger.log("d", "---------------- container = [%s]", container_node) + position = str(position) + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._global_container_stack.extruders[position].variant = container_node.getContainer() + + @pyqtSlot("QVariant") + def handleQualityGroup(self, quality_group): + Logger.log("d", "---------------- qg = [%s]", quality_group.name) + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._global_container_stack.quality = quality_group.node_for_global.getContainer() + self._global_container_stack.qualityChanges = self._empty_quality_changes_container + for position, node in quality_group.nodes_for_extruders.items(): + self._global_container_stack.extruders[position].quality = node.getContainer() + self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container diff --git a/cura/Settings/NozzleModel.py b/cura/Settings/NozzleModel.py new file mode 100644 index 0000000000..3ad28f3287 --- /dev/null +++ b/cura/Settings/NozzleModel.py @@ -0,0 +1,47 @@ +from PyQt5.QtCore import Qt + +from UM.Application import Application +from UM.Qt.ListModel import ListModel + + +class NozzleModel(ListModel): + IdRole = Qt.UserRole + 1 + HotendNameRole = Qt.UserRole + 2 + ContainerNodeRole = Qt.UserRole + 3 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.HotendNameRole, "hotend_name") + self.addRoleName(self.ContainerNodeRole, "container_node") + + Application.getInstance().globalContainerStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) + Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) + + def _update(self): + self.items.clear() + + variant_manager = Application.getInstance()._variant_manager + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + return + + variant_group_dict = variant_manager.getVariantNodes(active_global_stack) + if not variant_group_dict: + self.setItems([]) + return + + item_list = [] + for hotend_name, container_node in sorted(variant_group_dict.items(), key = lambda i: i[0]): + item = {"id": hotend_name, + "hotend_name": hotend_name, + "container_node": container_node + } + + item_list.append(item) + + self.setItems(item_list) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index a7d9a7be26..54aaedb8f9 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -590,15 +590,14 @@ class XmlMaterialProfile(InstanceContainer): if buildplate_id is None: continue - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata( - id = buildplate_id) - if not variant_containers: - # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata( - definition = machine_id, name = buildplate_id) - - if not variant_containers: + from cura.Machines.VariantManager import VariantType + variant_manager = CuraApplication.getInstance().getVariantManager() + variant_node = variant_manager.getVariant(machine_id, VariantType.BUILD_PLATE, buildplate_id) + if not variant_node: continue + variant_metadata = variant_node.metadata + + # TODO: check if build plate variant exists buildplate_compatibility = machine_compatibility buildplate_recommended = machine_compatibility @@ -623,6 +622,11 @@ class XmlMaterialProfile(InstanceContainer): if hotend_name is None: continue + variant_manager = CuraApplication.getInstance().getVariantManager() + variant_node = variant_manager.getVariant(machine_id, hotend_name) + if not variant_node: + continue + hotend_compatibility = machine_compatibility hotend_setting_values = {} settings = hotend.iterfind("./um:setting", self.__namespaces) diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 81db20a79d..6d554218a1 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -29,38 +29,33 @@ Menu return true; } - MenuItem + // TODO: single instance?? + Cura.NozzleModel { - id: automaticNozzle - text: - { - if(visible) - { - var nozzleName = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex]; - return catalog.i18nc("@title:menuitem %1 is the nozzle currently loaded in the printer", "Automatic: %1").arg(nozzleName); - } - return ""; - } - visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds != undefined && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex && !isClusterPrinter - onTriggered: - { - var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - var hotendId = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex]; - var itemIndex = nozzleInstantiator.model.find("name", hotendId); - if(itemIndex > -1) - { - Cura.MachineManager.setActiveVariant(nozzleInstantiator.model.getItem(itemIndex).id); - } - Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); - } + id: nozzleModel } - MenuSeparator + Instantiator { - visible: automaticNozzle.visible - } + model: nozzleModel + MenuItem + { + text: model.hotend_name + checkable: true + checked: Cura.MachineManager.activeVariantId == model.hotend_name + exclusiveGroup: group + onTriggered: { + var position = Cura.ExtruderManager.activeExtruderIndex; + Cura.MachineManager.setVariantGroup(position, model.container_node); + } + visible: true + } + + onObjectAdded: menu.insertItem(index, object); + onObjectRemoved: menu.removeItem(object); + } + /* Instantiator { id: nozzleInstantiator @@ -96,7 +91,7 @@ Menu } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) - } + } */ ExclusiveGroup { id: group } } From f0d9fba2f5fdde7a3ad03657f8ce83d49502a489 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 7 Feb 2018 14:49:46 +0100 Subject: [PATCH 004/266] WIP: Create MaterialManager --- cura/CuraApplication.py | 10 +- cura/Machines/MaterialManager.py | 277 ++++++++++++++++++++ cura/Settings/ContainerManager.py | 38 ++- cura/Settings/MachineManager.py | 8 + cura/Settings/MaterialsModel.py | 181 ++++++++++++- resources/qml/Menus/MaterialMenu.qml | 118 +-------- resources/qml/Preferences/MaterialsPage.qml | 2 +- 7 files changed, 504 insertions(+), 130 deletions(-) create mode 100644 cura/Machines/MaterialManager.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index d209b90909..7812024422 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -53,7 +53,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Settings.ProfilesModel import ProfilesModel -from cura.Settings.MaterialsModel import MaterialsModel +from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.UserProfilesModel import UserProfilesModel @@ -734,6 +734,10 @@ class CuraApplication(QtApplication): container_registry = ContainerRegistry.getInstance() self._variant_manager.initialize() + from cura.Machines.MaterialManager import MaterialManager + self._material_manager = MaterialManager(container_registry) + self._material_manager.initialize() + # Check if we should run as single instance or not self._setUpSingleInstanceServer() @@ -914,6 +918,10 @@ class CuraApplication(QtApplication): qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel) + + qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") + qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") + qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel") diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py new file mode 100644 index 0000000000..596da50fb2 --- /dev/null +++ b/cura/Machines/MaterialManager.py @@ -0,0 +1,277 @@ +from typing import Optional + +from PyQt5.Qt import QTimer, QObject, pyqtSignal + +from UM.Logger import Logger +from UM.Settings import ContainerRegistry +from UM.Settings import InstanceContainer + +from cura.Machines.ContainerNode import ContainerNode + + +class MaterialGroup: + __slots__ = ("name", "root_material_node", "derived_material_node_list") + + def __init__(self, name: str): + self.name = name + self.root_material_node = None + self.derived_material_node_list = [] + + +class MaterialNode(ContainerNode): + __slots__ = ("material_map", "children_map") + + def __init__(self, metadata: Optional[dict] = None): + super().__init__(metadata = metadata) + self.material_map = {} + self.children_map = {} + + +class MaterialManager(QObject): + + materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. + + def __init__(self, container_registry, parent = None): + super().__init__(parent) + self._container_registry = container_registry # type: ContainerRegistry + + self._fallback_materials_map = dict() # material_type -> generic material metadata + self._material_group_map = dict() # root_material_id -> MaterialGroup + self._diameter_machine_variant_material_map = dict() # diameter -> dict(machine_definition_id -> MaterialNode) + + # The machine definition ID for the non-machine-specific materials. + # This is used as the last fallback option if the given machine-specific material(s) cannot be found. + self._default_machine_definition_id = "fdmprinter" + + self._update_timer = QTimer(self) + self._update_timer.setInterval(300) + self._update_timer.setSingleShot(True) + self._update_timer.timeout.connect(self._updateTables) + + self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) + self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) + self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged) + + def initialize(self): + # Find all materials and put them in a matrix for quick search. + material_metadata_list = self._container_registry.findContainersMetadata(type = "material") + + self._material_group_map = {} + self._diameter_machine_variant_material_map = {} + + # Table #1 + # root_material_id -> MaterialGroup + for material_metadata in material_metadata_list: + material_id = material_metadata["id"] + # We don't store empty material in the lookup tables + if material_id == "empty_material": + continue + + root_material_id = material_metadata.get("base_file") + if root_material_id not in self._material_group_map: + self._material_group_map[root_material_id] = MaterialGroup(root_material_id) + group = self._material_group_map[root_material_id] + + # We only add root materials here + if material_id == root_material_id: + group.root_material_node = MaterialNode(material_metadata) + else: + new_node = MaterialNode(material_metadata) + group.derived_material_node_list.append(new_node) + + # Table #2 + # Lookup table for material type -> fallback material metadata + grouped_by_type_dict = dict() + for root_material_id, material_node in self._material_group_map.items(): + material_type = material_node.root_material_node.metadata["material"] + if material_type not in grouped_by_type_dict: + grouped_by_type_dict[material_type] = {"generic": None, + "others": []} + brand = material_node.root_material_node.metadata["brand"] + if brand.lower() == "generic": + grouped_by_type_dict[material_type] = material_node.root_material_node.metadata + self._fallback_materials_map = grouped_by_type_dict + + # Table #3 + # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer + # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer + for material_metadata in material_metadata_list: + # We don't store empty material in the lookup tables + if material_metadata["id"] == "empty_material": + continue + + root_material_id = material_metadata["base_file"] + definition = material_metadata["definition"] + approximate_diameter = material_metadata["approximate_diameter"] + + if approximate_diameter not in self._diameter_machine_variant_material_map: + self._diameter_machine_variant_material_map[approximate_diameter] = {} + + machine_variant_material_map = self._diameter_machine_variant_material_map[approximate_diameter] + if definition not in machine_variant_material_map: + machine_variant_material_map[definition] = MaterialNode() + + machine_node = machine_variant_material_map[definition] + variant_name = material_metadata.get("variant_name") + if not variant_name: + # if there is no variant, this material is for the machine, so put its metadata in the machine node. + machine_node.material_map[root_material_id] = MaterialNode(material_metadata) + else: + # this material is variant-specific, so we save it in a variant-specific node under the + # machine-specific node + if variant_name not in machine_node.children_map: + machine_node.children_map[variant_name] = MaterialNode() + + variant_node = machine_node.children_map[variant_name] + if root_material_id not in variant_node.material_map: + variant_node.material_map[root_material_id] = MaterialNode(material_metadata) + else: + # Sanity check: make sure we don't have duplicated variant-specific materials for the same machine + raise RuntimeError("Found duplicate variant name [%s] for machine [%s] in material [%s]" % + (variant_name, definition, material_metadata["id"])) + + self.materialsUpdated.emit() + + def _updateTables(self): + self.initialize() + + def _onContainerMetadataChanged(self, container): + self._onContainerChanged(container) + + def _onContainerChanged(self, container): + container_type = container.getMetaDataEntry("type") + if container_type != "material": + return + + # TODO: update the cache table + self._update_timer.start() + + def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: + return self._material_group_map.get(root_material_id) + + def _test_metadata(self): + # print all metadata + import os + with open("c:/workspace/guid_map.txt", "w", encoding = "utf-8") as f: + for machine_id, node in self._guid_to_root_materials_map.items(): + f.write((" - %s -> %s" % (machine_id, node.metadata["id"])) + os.linesep) + + if False: + with open("c:/workspace/material_map.txt", "w", encoding = "utf-8") as f: + for machine_id in self._machine_variant_material_map: + f.write((" -> %s" % machine_id) + os.linesep) + + test_cases = [{"machine": "ultimaker3", "variant": "AA 0.4", "material": "generic_pla", "diameter": 2.85}, + {"machine": "ultimaker2_plus", "variant": None, "material": "generic_abs", "diameter": 2.85}, + {"machine": "fdmprinter", "variant": None, "material": "generic_cpe", "diameter": 2.85}, + {"machine": "fdmprinter", "variant": None, "material": "generic_abs_175", "diameter": 2.85}, + {"machine": "fdmprinter", "variant": None, "material": "generic_nylon", "diameter": 1.75}, + {"machine": "fdmprinter", "variant": None, "material": "generic_nylon_175", "diameter": 1.75}, + ] + for tc in test_cases: + result = self.getMaterialNode( + tc['machine'], + tc['variant'], + tc['diameter'], + tc['material']) + tc['result_id'] = result.getContainer().getId() if result else "None" + Logger.log("d", "!!!!!!!! MaterialManager test: %s", tc) + + # test available materials + with open("c:/workspace/test.txt", "w", encoding="utf-8") as f: + for tc in test_cases: + result = self.getAvailableMaterials(tc['machine'], + tc['variant'], + tc['diameter']) + f.write("--- [%s] [%s] [%s]:" % (tc['machine'], tc['variant'], tc['diameter']) + "\n") + for r, md in result.items(): + f.write(" - %s -> %s" % (r, md["id"]) + "\n") + + # + # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. + # + def getAvailableMaterials(self, machine_definition_id: str, variant_name: Optional[str], diameter: float) -> dict: + # round the diameter to get the approximate diameter + rounded_diameter = str(round(diameter)) + if rounded_diameter not in self._diameter_machine_variant_material_map: + Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter) + return {} + + # If there are variant materials, get the variant material + machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter] + machine_node = machine_variant_material_map.get(machine_definition_id) + variant_node = None + if machine_node is None: + machine_node = machine_variant_material_map.get(self._default_machine_definition_id) + if variant_name is not None and machine_node is not None: + variant_node = machine_node.getChildNode(variant_name) + + # Fallback mechanism of finding materials: + # 1. variant-specific material + # 2. machine-specific material + # 3. generic material (for fdmprinter) + material_id_metadata_dict = {} + if variant_node is not None: + material_id_metadata_dict = {mid: node for mid, node in variant_node.material_map.items()} + + # Fallback: machine-specific materials, including "fdmprinter" + if not material_id_metadata_dict: + if machine_node is not None: + material_id_metadata_dict = {mid: node for mid, node in machine_node.material_map.items()} + + return material_id_metadata_dict + + # + # Gets MaterialNode for the given extruder and machine with the given material name. + # Returns None if: + # 1. the given machine doesn't have materials; + # 2. cannot find any material InstanceContainers with the given settings. + # + def getMaterial(self, machine_definition_id: str, variant_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]: + # round the diameter to get the approximate diameter + rounded_diameter = str(round(diameter)) + if rounded_diameter not in self._diameter_machine_variant_material_map: + Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]", + diameter, rounded_diameter, root_material_id) + return None + + # If there are variant materials, get the variant material + machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter] + machine_node = machine_variant_material_map.get(machine_definition_id) + variant_node = None + + # Fallback for "fdmprinter" if the machine-specific materials cannot be found + if machine_node is None: + machine_node = machine_variant_material_map.get(self._default_machine_definition_id) + if machine_node is not None and variant_name is not None: + variant_node = machine_node.getChildNode(variant_name) + + # Fallback mechanism of finding materials: + # 1. variant-specific material + # 2. machine-specific material + # 3. generic material (for fdmprinter) + material_node = None + if variant_node is not None: + if root_material_id in variant_node.material_map: + material_node = variant_node.material_map.get(root_material_id) + + # Fallback: machine-specific materials, including "fdmprinter" + if material_node is None: + if machine_node is not None: + material_node = machine_node.material_map.get(root_material_id) + + return material_node + + # + # Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla". + # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use + # the generic material IDs to search for qualities. + # + # This function returns the generic root material ID for the given material type, where material types are "PLA", + # "ABS", etc. + # + def getFallbackMaterialForType(self, material_type: str) -> dict: + # For safety + if material_type not in self._fallback_materials_map: + raise RuntimeError("Material type [%s] is not in the fallback materials table." % material_type) + return self._fallback_materials_map[material_type] diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d2e8410dde..4c92eed845 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -766,22 +766,20 @@ class ContainerManager(QObject): # \return \type{str} the id of the newly created container. @pyqtSlot(str, result = str) def duplicateMaterial(self, material_id: str) -> str: - original = self._container_registry.findContainersMetadata(id = material_id) - if not original: + assert material_id + + from cura.CuraApplication import CuraApplication + material_manager = CuraApplication.getInstance()._material_manager + + material_group = material_manager.getMaterialGroup(material_id) + if not material_group: Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id) return "" - original = original[0] - base_container_id = original.get("base_file") - base_container = self._container_registry.findContainers(id = base_container_id) - if not base_container: - Logger.log("d", "Unable to duplicate the material with id {material_id}, because base_file {base_container_id} doesn't exist.".format(material_id = material_id, base_container_id = base_container_id)) - return "" - base_container = base_container[0] - - #We'll copy all containers with the same base. - #This way the correct variant and machine still gets assigned when loading the copy of the material. - containers_to_copy = self._container_registry.findInstanceContainers(base_file = base_container_id) + base_container = material_group.root_material_node.getContainer() + containers_to_copy = [] + for node in material_group.derived_material_node_list: + containers_to_copy.append(node.getContainer()) # Ensure all settings are saved. Application.getInstance().saveSettings() @@ -802,9 +800,9 @@ class ContainerManager(QObject): new_id = new_base_id if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": new_id += "_" + container_to_copy.getMetaDataEntry("definition") - if container_to_copy.getMetaDataEntry("variant"): - variant = self._container_registry.findContainers(id = container_to_copy.getMetaDataEntry("variant"))[0] - new_id += "_" + variant.getName().replace(" ", "_") + if container_to_copy.getMetaDataEntry("variant_name"): + variant_name = container_to_copy.getMetaDataEntry("variant_name") + new_id += "_" + variant_name.replace(" ", "_") if current_id == material_id: clone_of_original = new_id @@ -826,13 +824,7 @@ class ContainerManager(QObject): # check if the given material has a base file (i.e. was shipped by default) base_file = self.getContainerMetaDataEntry(material_id, "base_file") - - if base_file == "": - # there is no base file, so duplicate by ID - return self.duplicateMaterial(material_id) - else: - # there is a base file, so duplicate the original material - return self.duplicateMaterial(base_file) + return self.duplicateMaterial(base_file) ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 719f90bdd1..1fa4a602bc 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1237,6 +1237,14 @@ class MachineManager(QObject): return self.getQualityVariantId(self._global_container_stack.definition, variant) return "" + @pyqtProperty(str, notify = activeVariantChanged) + def activeQualityVariantName(self) -> str: + if self._active_container_stack: + variant = self._active_container_stack.variant + if variant.getId() != "empty_variant": + return variant.getName() + return "" + ## Get the Variant ID to use to select quality profiles for variants of the specified definitions # This is normally the id of the variant itself, but machines can specify a different definition # to inherit qualities from, which has consequences for the variant to use as well diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py index c4b0329336..ad3256ba32 100644 --- a/cura/Settings/MaterialsModel.py +++ b/cura/Settings/MaterialsModel.py @@ -2,10 +2,189 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Any, List +from PyQt5.QtCore import Qt + + +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry #To listen for changes to the materials. from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel #We're extending this class. -## A model that shows a list of currently valid materials. + +def getAvailableMaterials(): + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + + material_manager = CuraApplication.getInstance()._material_manager + + active_global_stack = machine_manager._global_container_stack + active_extruder_stack = extruder_manager.getActiveExtruderStack() + + if active_global_stack is None or active_extruder_stack is None: + Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", + active_global_stack, active_extruder_stack) + return + + machine_definition_id = active_global_stack.definition.getId() + variant_name = None + if active_extruder_stack.variant.getId() != "empty_variant": + variant_name = active_extruder_stack.variant.getName() + diameter = active_extruder_stack.getProperty("material_diameter", "value") + + # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. + result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) + return result_dict + + +class BaseMaterialsModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + IdRole = Qt.UserRole + 2 + NameRole = Qt.UserRole + 3 + BrandRole = Qt.UserRole + 4 + MaterialRole = Qt.UserRole + 5 + ColorRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 6 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialRole, "material") + self.addRoleName(self.ColorRole, "color_name") + self.addRoleName(self.ContainerNodeRole, "container_node") + + +class GenericMaterialsModel(BaseMaterialsModel): + + def __init__(self, parent = None): + super().__init__(parent) + + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + def _update(self): + item_list = [] + result_dict = getAvailableMaterials() + if result_dict is None: + self.setItems([]) + return + + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + # Only add results for generic materials + if metadata["brand"].lower() != "generic": + continue + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + item_list.append(item) + + # Sort the item list by material name alphabetically + item_list = sorted(item_list, key = lambda d: d["name"]) + + self.setItems(item_list) + + +class MaterialsModelGroupedByType(ListModel): + NameRole = Qt.UserRole + 1 + ColorsRole = Qt.UserRole + 2 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.ColorsRole, "colors") + + +## Brand --> Material Type -> list of materials +class BrandMaterialsModel(ListModel): + NameRole = Qt.UserRole + 1 + MaterialsRole = Qt.UserRole + 2 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.MaterialsRole, "materials") + + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + def _update(self): + brand_item_list = [] + result_dict = getAvailableMaterials() + if result_dict is None: + self.setItems([]) + return + + brand_group_dict = {} + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + brand = metadata["brand"] + # Only add results for generic materials + if brand.lower() == "generic": + continue + + if brand not in brand_group_dict: + brand_group_dict[brand] = {} + + material_type = metadata["material"] + if material_type not in brand_group_dict[brand]: + brand_group_dict[brand][material_type] = [] + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + brand_group_dict[brand][material_type].append(item) + + for brand, material_dict in brand_group_dict.items(): + brand_item = {"name": brand, + "materials": MaterialsModelGroupedByType(self)} # TODO + + material_type_item_list = [] + for material_type, material_list in material_dict.items(): + material_type_item = {"name": material_type, + "colors": BaseMaterialsModel(self)} + material_type_item["colors"].clear() + material_type_item["colors"].setItems(material_list) + + material_type_item_list.append(material_type_item) + + brand_item["materials"].setItems(material_type_item_list) + + brand_item_list.append(brand_item) + + self.setItems(brand_item_list) + + +## A model that shows a list of currently valid materials. Used by management page. class MaterialsModel(InstanceContainersModel): def __init__(self, parent = None): super().__init__(parent) diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index 3d04649f11..111e5ab6af 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -29,16 +29,6 @@ Menu return true; } - UM.SettingPropertyProvider - { - id: materialDiameterProvider - - containerStackId: Cura.ExtruderManager.activeExtruderStackId - key: "material_diameter" - watchedProperties: [ "value" ] - storeIndex: 5 - } - MenuItem { id: automaticMaterial @@ -83,12 +73,16 @@ Menu exclusiveGroup: group onTriggered: { + + const container_id = model.id; // This workaround is done because of the application menus for materials and variants for multiextrusion printers. // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. + var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveMaterial(model.id); - Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); + //Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); + //Cura.MachineManager.setActiveMaterial(container_id); + //Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); + Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node); } } onObjectAdded: menu.insertItem(index, object) @@ -126,11 +120,12 @@ Menu exclusiveGroup: group onTriggered: { + const container_id = model.id; // This workaround is done because of the application menus for materials and variants for multiextrusion printers. // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveMaterial(model.id); + Cura.MachineManager.setActiveMaterial(container_id); Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); } } @@ -146,105 +141,20 @@ Menu onObjectRemoved: menu.removeItem(object) } - ListModel + Cura.GenericMaterialsModel { id: genericMaterialsModel - Component.onCompleted: populateMenuModels() + //Component.onCompleted: populateMenuModels() } - ListModel + Cura.BrandMaterialsModel { id: brandModel } - //: Model used to populate the brandModel - Cura.MaterialsModel - { - id: materialsModel - filter: materialFilter() - onModelReset: populateMenuModels() - onDataChanged: populateMenuModels() - } - ExclusiveGroup { id: group } MenuSeparator { } MenuItem { action: Cura.Actions.manageMaterials } - - function materialFilter() - { - var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() }; - if(Cura.MachineManager.filterMaterialsByMachine) - { - result.definition = Cura.MachineManager.activeQualityDefinitionId; - if(Cura.MachineManager.hasVariants) - { - result.variant = Cura.MachineManager.activeQualityVariantId; - } - } - else - { - result.definition = "fdmprinter"; - result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway. - } - return result; - } - - function populateMenuModels() - { - // Create a structure of unique brands and their material-types - genericMaterialsModel.clear() - brandModel.clear(); - - var items = materialsModel.items; - var materialsByBrand = {}; - for (var i in items) { - var brandName = items[i]["metadata"]["brand"]; - var materialName = items[i]["metadata"]["material"]; - - if (brandName == "Generic") - { - // Add to top section - var materialId = items[i].id; - genericMaterialsModel.append({ - id: materialId, - name: items[i].name - }); - } - else - { - // Add to per-brand, per-material menu - if (!materialsByBrand.hasOwnProperty(brandName)) - { - materialsByBrand[brandName] = {}; - } - if (!materialsByBrand[brandName].hasOwnProperty(materialName)) - { - materialsByBrand[brandName][materialName] = []; - } - materialsByBrand[brandName][materialName].push({ - id: items[i].id, - name: items[i].name - }); - } - } - - for (var brand in materialsByBrand) - { - var materialsByBrandModel = []; - var materials = materialsByBrand[brand]; - for (var material in materials) - { - materialsByBrandModel.push({ - name: material, - colors: materials[material] - }) - } - brandModel.append({ - name: brand, - materials: materialsByBrandModel - }); - } - } } diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 22814683ad..3a72f66cfc 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -30,7 +30,7 @@ UM.ManagementPage result.definition = Cura.MachineManager.activeQualityDefinitionId; if(Cura.MachineManager.hasVariants) { - result.variant = Cura.MachineManager.activeQualityVariantId; + result.variant_name = Cura.MachineManager.activeQualityVariantName; } } else From 0505b16ffb55c243fa3641ab8296b7e0f45b78e0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Feb 2018 13:54:16 +0100 Subject: [PATCH 005/266] WIP: Update quality profiles - Add a new field "variant" in "metadata" section for quality profiles. "material" will only contain values such as "generic_abs", and "variant" will contain values such as "0.25 mm", "AA 0.4", etc. - Reformat "metadata" section to have the following order: - setting_version - type - quality_type - weight - global_quality - material - variant --- resources/quality/abax_pri3/apri3_pla_fast.inst.cfg | 10 +++++----- resources/quality/abax_pri3/apri3_pla_high.inst.cfg | 10 +++++----- resources/quality/abax_pri3/apri3_pla_normal.inst.cfg | 10 +++++----- resources/quality/abax_pri5/apri5_pla_fast.inst.cfg | 10 +++++----- resources/quality/abax_pri5/apri5_pla_high.inst.cfg | 10 +++++----- resources/quality/abax_pri5/apri5_pla_normal.inst.cfg | 10 +++++----- resources/quality/abax_titan/atitan_pla_fast.inst.cfg | 10 +++++----- resources/quality/abax_titan/atitan_pla_high.inst.cfg | 11 ++++++----- .../quality/abax_titan/atitan_pla_normal.inst.cfg | 10 +++++----- .../anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg | 4 ++-- .../anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg | 4 ++-- .../anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg | 4 ++-- .../builder_premium/bp_BVOH_Coarse_Quality.inst.cfg | 5 ++--- .../builder_premium/bp_BVOH_High_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_BVOH_Normal_Quality.inst.cfg | 6 +++--- .../bp_Innoflex60_Coarse_Quality.inst.cfg | 5 ++--- .../bp_Innoflex60_High_Quality.inst.cfg | 6 +++--- .../bp_Innoflex60_Normal_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PET_Coarse_Quality.inst.cfg | 5 ++--- .../builder_premium/bp_PET_High_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PET_Normal_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PLA_Coarse_Quality.inst.cfg | 5 ++--- .../builder_premium/bp_PLA_High_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PLA_Normal_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PVA_Coarse_Quality.inst.cfg | 5 ++--- .../builder_premium/bp_PVA_High_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_PVA_Normal_Quality.inst.cfg | 6 +++--- .../builder_premium/bp_global_Coarse_Quality.inst.cfg | 4 ++-- .../builder_premium/bp_global_High_Quality.inst.cfg | 4 ++-- .../builder_premium/bp_global_Normal_Quality.inst.cfg | 4 ++-- .../cartesio/abs/cartesio_0.25_abs_high.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.25_abs_normal.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.4_abs_high.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.4_abs_normal.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg | 5 +++-- .../abs/cartesio_0.8_abs_extra_coarse.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.8_abs_high.inst.cfg | 5 +++-- .../cartesio/abs/cartesio_0.8_abs_normal.inst.cfg | 5 +++-- .../arnitel/cartesio_0.4_arnitel2045_high.inst.cfg | 5 +++-- .../arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg | 5 +++-- .../cartesio/cartesio_global_Coarse_Quality.inst.cfg | 4 ++-- .../cartesio_global_Extra_Coarse_Quality.inst.cfg | 4 ++-- .../cartesio/cartesio_global_High_Quality.inst.cfg | 4 ++-- .../cartesio/cartesio_global_Normal_Quality.inst.cfg | 4 ++-- .../cartesio/hips/cartesio_0.25_hips_high.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.25_hips_normal.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.4_hips_high.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.4_hips_normal.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg | 5 +++-- .../hips/cartesio_0.8_hips_extra_coarse.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.8_hips_high.inst.cfg | 5 +++-- .../cartesio/hips/cartesio_0.8_hips_normal.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg | 5 +++-- .../nylon/cartesio_0.25_nylon_normal.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg | 5 +++-- .../nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg | 5 +++-- .../cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.25_pc_high.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.25_pc_normal.inst.cfg | 5 +++-- .../quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.4_pc_normal.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 5 +++-- .../quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 5 +++-- .../cartesio/pc/cartesio_0.8_pc_normal.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.25_petg_high.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.25_petg_normal.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.4_petg_high.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.4_petg_normal.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg | 5 +++-- .../petg/cartesio_0.8_petg_extra_coarse.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.8_petg_high.inst.cfg | 5 +++-- .../cartesio/petg/cartesio_0.8_petg_normal.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.25_pla_high.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.25_pla_normal.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.4_pla_high.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.4_pla_normal.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg | 5 +++-- .../pla/cartesio_0.8_pla_extra_coarse.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.8_pla_high.inst.cfg | 5 +++-- .../cartesio/pla/cartesio_0.8_pla_normal.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.25_pva_high.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.25_pva_normal.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.4_pva_high.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.4_pva_normal.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg | 5 +++-- .../pva/cartesio_0.8_pva_extra_coarse.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.8_pva_high.inst.cfg | 5 +++-- .../cartesio/pva/cartesio_0.8_pva_normal.inst.cfg | 5 +++-- resources/quality/coarse.inst.cfg | 4 ++-- .../quality/deltacomb/deltacomb_abs_fast.inst.cfg | 5 ++--- .../quality/deltacomb/deltacomb_abs_high.inst.cfg | 5 ++--- .../quality/deltacomb/deltacomb_abs_normal.inst.cfg | 4 ++-- .../quality/deltacomb/deltacomb_nylon_fast.inst.cfg | 4 ++-- .../quality/deltacomb/deltacomb_nylon_high.inst.cfg | 4 ++-- .../quality/deltacomb/deltacomb_nylon_normal.inst.cfg | 5 ++--- .../quality/deltacomb/deltacomb_pla_fast.inst.cfg | 5 ++--- .../quality/deltacomb/deltacomb_pla_high.inst.cfg | 5 ++--- .../quality/deltacomb/deltacomb_pla_normal.inst.cfg | 4 ++-- resources/quality/draft.inst.cfg | 5 ++--- resources/quality/extra_coarse.inst.cfg | 4 ++-- resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg | 5 ++--- resources/quality/fabtotum/fabtotum_abs_high.inst.cfg | 5 ++--- .../quality/fabtotum/fabtotum_abs_normal.inst.cfg | 5 ++--- .../quality/fabtotum/fabtotum_nylon_fast.inst.cfg | 6 +++--- .../quality/fabtotum/fabtotum_nylon_high.inst.cfg | 6 +++--- .../quality/fabtotum/fabtotum_nylon_normal.inst.cfg | 5 ++--- resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg | 5 ++--- resources/quality/fabtotum/fabtotum_pla_high.inst.cfg | 5 ++--- .../quality/fabtotum/fabtotum_pla_normal.inst.cfg | 5 ++--- .../gmax15plus/gmax15plus_pla_dual_normal.inst.cfg | 2 +- .../gmax15plus/gmax15plus_pla_dual_thick.inst.cfg | 2 +- .../gmax15plus/gmax15plus_pla_dual_thin.inst.cfg | 2 +- .../gmax15plus_pla_dual_very_thick.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_pla_normal.inst.cfg | 4 +--- .../quality/gmax15plus/gmax15plus_pla_thick.inst.cfg | 4 ++-- .../quality/gmax15plus/gmax15plus_pla_thin.inst.cfg | 4 ++-- .../gmax15plus/gmax15plus_pla_very_thick.inst.cfg | 4 ++-- resources/quality/high.inst.cfg | 4 ++-- .../imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg | 9 +++++---- .../generic_petg_0.4_coarse_2-fans.inst.cfg | 9 +++++---- .../imade3d_jellybox/generic_petg_0.4_medium.inst.cfg | 9 +++++---- .../generic_petg_0.4_medium_2-fans.inst.cfg | 9 +++++---- .../imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg | 9 +++++---- .../generic_pla_0.4_coarse_2-fans.inst.cfg | 9 +++++---- .../imade3d_jellybox/generic_pla_0.4_fine.inst.cfg | 9 +++++---- .../generic_pla_0.4_fine_2-fans.inst.cfg | 9 +++++---- .../imade3d_jellybox/generic_pla_0.4_medium.inst.cfg | 9 +++++---- .../generic_pla_0.4_medium_2-fans.inst.cfg | 9 +++++---- .../generic_pla_0.4_ultrafine.inst.cfg | 9 +++++---- .../generic_pla_0.4_ultrafine_2-fans.inst.cfg | 9 +++++---- .../quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg | 8 ++++---- .../quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg | 8 ++++---- .../quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg | 4 ++-- .../quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg | 4 ++-- .../kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg | 4 ++-- resources/quality/low.inst.cfg | 4 ++-- .../malyan_m200/abs/malyan_m200_abs_draft.inst.cfg | 6 +++--- .../malyan_m200/abs/malyan_m200_abs_fast.inst.cfg | 6 +++--- .../malyan_m200/abs/malyan_m200_abs_high.inst.cfg | 6 +++--- .../malyan_m200/abs/malyan_m200_abs_normal.inst.cfg | 6 +++--- .../abs/malyan_m200_abs_superdraft.inst.cfg | 6 +++--- .../abs/malyan_m200_abs_thickerdraft.inst.cfg | 6 +++--- .../malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg | 6 +++--- .../abs/malyan_m200_abs_verydraft.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.04375.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.0875.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.13125.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.175.inst.cfg | 8 ++++---- .../quality/malyan_m200/malyan_m200_0.21875.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.2625.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.30625.inst.cfg | 6 +++--- .../quality/malyan_m200/malyan_m200_0.35.inst.cfg | 8 ++++---- .../malyan_m200_global_Draft_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_Fast_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_High_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_Normal_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_SuperDraft_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_ThickerDraft_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_Ultra_Quality.inst.cfg | 8 ++++---- .../malyan_m200_global_VeryDraft_Quality.inst.cfg | 8 ++++---- .../malyan_m200/petg/malyan_m200_petg_draft.inst.cfg | 4 ++-- .../malyan_m200/petg/malyan_m200_petg_fast.inst.cfg | 4 ++-- .../malyan_m200/petg/malyan_m200_petg_high.inst.cfg | 4 ++-- .../malyan_m200/petg/malyan_m200_petg_normal.inst.cfg | 4 ++-- .../petg/malyan_m200_petg_superdraft.inst.cfg | 4 ++-- .../petg/malyan_m200_petg_thickerdraft.inst.cfg | 4 ++-- .../malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg | 4 ++-- .../petg/malyan_m200_petg_verydraft.inst.cfg | 4 ++-- .../malyan_m200/pla/malyan_m200_pla_draft.inst.cfg | 6 +++--- .../malyan_m200/pla/malyan_m200_pla_fast.inst.cfg | 6 +++--- .../malyan_m200/pla/malyan_m200_pla_high.inst.cfg | 6 +++--- .../malyan_m200/pla/malyan_m200_pla_normal.inst.cfg | 6 +++--- .../pla/malyan_m200_pla_superdraft.inst.cfg | 6 +++--- .../pla/malyan_m200_pla_thickerdraft.inst.cfg | 6 +++--- .../malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg | 6 +++--- .../pla/malyan_m200_pla_verydraft.inst.cfg | 6 +++--- .../abs/monoprice_select_mini_v2_abs_draft.inst.cfg | 6 +++--- .../abs/monoprice_select_mini_v2_abs_fast.inst.cfg | 6 +++--- .../abs/monoprice_select_mini_v2_abs_high.inst.cfg | 6 +++--- .../abs/monoprice_select_mini_v2_abs_normal.inst.cfg | 6 +++--- .../monoprice_select_mini_v2_abs_superdraft.inst.cfg | 6 +++--- ...monoprice_select_mini_v2_abs_thickerdraft.inst.cfg | 6 +++--- .../abs/monoprice_select_mini_v2_abs_ultra.inst.cfg | 6 +++--- .../monoprice_select_mini_v2_abs_verydraft.inst.cfg | 6 +++--- ...price_select_mini_v2_global_Draft_Quality.inst.cfg | 8 ++++---- ...oprice_select_mini_v2_global_Fast_Quality.inst.cfg | 8 ++++---- ...oprice_select_mini_v2_global_High_Quality.inst.cfg | 8 ++++---- ...rice_select_mini_v2_global_Normal_Quality.inst.cfg | 8 ++++---- ..._select_mini_v2_global_SuperDraft_Quality.inst.cfg | 8 ++++---- ...elect_mini_v2_global_ThickerDraft_Quality.inst.cfg | 8 ++++---- ...price_select_mini_v2_global_Ultra_Quality.inst.cfg | 8 ++++---- ...e_select_mini_v2_global_VeryDraft_Quality.inst.cfg | 8 ++++---- .../monoprice_select_mini_v2_nylon_draft.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_nylon_fast.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_nylon_high.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_nylon_normal.inst.cfg | 4 ++-- ...monoprice_select_mini_v2_nylon_superdraft.inst.cfg | 4 ++-- ...noprice_select_mini_v2_nylon_thickerdraft.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_nylon_ultra.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_nylon_verydraft.inst.cfg | 4 ++-- .../pc/monoprice_select_mini_v2_pc_draft.inst.cfg | 6 +++--- .../pc/monoprice_select_mini_v2_pc_fast.inst.cfg | 6 +++--- .../pc/monoprice_select_mini_v2_pc_high.inst.cfg | 6 +++--- .../pc/monoprice_select_mini_v2_pc_normal.inst.cfg | 6 +++--- .../monoprice_select_mini_v2_pc_superdraft.inst.cfg | 6 +++--- .../monoprice_select_mini_v2_pc_thickerdraft.inst.cfg | 6 +++--- .../pc/monoprice_select_mini_v2_pc_ultra.inst.cfg | 6 +++--- .../pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg | 6 +++--- .../petg/monoprice_select_mini_v2_petg_draft.inst.cfg | 4 ++-- .../petg/monoprice_select_mini_v2_petg_fast.inst.cfg | 4 ++-- .../petg/monoprice_select_mini_v2_petg_high.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_petg_normal.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_petg_superdraft.inst.cfg | 4 ++-- ...onoprice_select_mini_v2_petg_thickerdraft.inst.cfg | 4 ++-- .../petg/monoprice_select_mini_v2_petg_ultra.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_petg_verydraft.inst.cfg | 4 ++-- .../pla/monoprice_select_mini_v2_pla_draft.inst.cfg | 4 ++-- .../pla/monoprice_select_mini_v2_pla_fast.inst.cfg | 4 ++-- .../pla/monoprice_select_mini_v2_pla_high.inst.cfg | 4 ++-- .../pla/monoprice_select_mini_v2_pla_normal.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_pla_superdraft.inst.cfg | 4 ++-- ...monoprice_select_mini_v2_pla_thickerdraft.inst.cfg | 4 ++-- .../pla/monoprice_select_mini_v2_pla_ultra.inst.cfg | 4 ++-- .../monoprice_select_mini_v2_pla_verydraft.inst.cfg | 4 ++-- resources/quality/normal.inst.cfg | 4 ++-- .../quality/peopoly_moai/peopoly_moai_high.inst.cfg | 6 +++--- .../quality/peopoly_moai/peopoly_moai_max.inst.cfg | 6 +++--- .../quality/peopoly_moai/peopoly_moai_normal.inst.cfg | 6 +++--- .../tevo_blackwidow/tevo_blackwidow_draft.inst.cfg | 4 ++-- .../tevo_blackwidow/tevo_blackwidow_high.inst.cfg | 4 ++-- .../tevo_blackwidow/tevo_blackwidow_normal.inst.cfg | 4 ++-- resources/quality/ultimaker2/um2_draft.inst.cfg | 2 +- resources/quality/ultimaker2/um2_high.inst.cfg | 2 +- resources/quality/ultimaker2/um2_low.inst.cfg | 2 +- resources/quality/ultimaker2/um2_normal.inst.cfg | 2 +- .../quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.4_high.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.25_high.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg | 10 +++++----- .../quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg | 10 +++++----- .../ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg | 10 +++++----- .../ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg | 6 +++--- .../um3_aa0.25_Nylon_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg | 6 +++--- .../um3_aa0.4_Nylon_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg | 6 +++--- .../ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg | 5 +++-- .../um3_aa0.8_ABS_Superdraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg | 7 ++++--- .../um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 7 ++++--- .../um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg | 5 +++-- .../um3_aa0.8_CPE_Superdraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg | 5 +++-- .../um3_aa0.8_Nylon_Superdraft_Print.inst.cfg | 5 +++-- .../um3_aa0.8_Nylon_Verydraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg | 5 +++-- .../um3_aa0.8_PLA_Superdraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg | 5 +++-- .../ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg | 7 ++++--- .../um3_aa0.8_TPU_Superdraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg | 9 +++++---- .../ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg | 9 +++++---- .../ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg | 9 +++++---- .../ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg | 7 ++++--- .../um3_bb0.8_PVA_Superdraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg | 7 ++++--- .../ultimaker3/um3_global_Draft_Quality.inst.cfg | 4 ++-- .../ultimaker3/um3_global_Fast_Quality.inst.cfg | 4 ++-- .../ultimaker3/um3_global_High_Quality.inst.cfg | 4 ++-- .../ultimaker3/um3_global_Normal_Quality.inst.cfg | 4 ++-- .../ultimaker3/um3_global_Superdraft_Quality.inst.cfg | 4 ++-- .../ultimaker3/um3_global_Verydraft_Quality.inst.cfg | 4 ++-- .../k8800_ABS_Extreme_Quality.inst.cfg | 6 +++--- .../k8800_ABS_High_Quality.inst.cfg | 6 +++--- .../k8800_ABS_Normal_Quality.inst.cfg | 6 +++--- .../k8800_PET_Extreme_Quality.inst.cfg | 6 +++--- .../k8800_PET_High_Quality.inst.cfg | 6 +++--- .../k8800_PET_Normal_Quality.inst.cfg | 6 +++--- .../k8800_PLA_Extreme_Quality.inst.cfg | 6 +++--- .../k8800_PLA_High_Quality.inst.cfg | 6 +++--- .../k8800_PLA_Normal_Quality.inst.cfg | 6 +++--- .../k8800_TPU_Extreme_Quality.inst.cfg | 6 +++--- .../k8800_TPU_High_Quality.inst.cfg | 6 +++--- .../k8800_TPU_Normal_Quality.inst.cfg | 4 ++-- 386 files changed, 1234 insertions(+), 1134 deletions(-) diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 32550d86a5..7d1c1bf588 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_pri3 [metadata] -type = quality -material = generic_pla -weight = -1 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = -1 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 80 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 2007785719..46a4178dd9 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = abax_pri3 [metadata] -type = quality -material = generic_pla -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla [values] layer_height = 0.1 @@ -19,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index dba0a0460f..3f6f36cfe6 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_pri3 [metadata] -type = quality -material = generic_pla -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index 11892a6223..517c767ac5 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_pri5 [metadata] -type = quality -material = generic_pla -weight = -1 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = -1 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 80 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg index 852efe699e..01699e39f6 100644 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = abax_pri5 [metadata] -type = quality -material = generic_pla -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla [values] layer_height = 0.1 @@ -19,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg index 244d544c80..ea1023dc43 100644 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_pri5 [metadata] -type = quality -material = generic_pla -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index a2d802a3ba..ae489c3792 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_titan [metadata] -type = quality -material = generic_pla -weight = -1 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = -1 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 80 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg index 7ee8c35133..f9bf350814 100644 --- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg @@ -2,12 +2,13 @@ version = 2 name = Extra Fine definition = abax_titan + [metadata] -type = quality -material = generic_pla -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla [values] layer_height = 0.1 @@ -18,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg index 6c40914566..c73d6901fb 100644 --- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = abax_titan [metadata] -type = quality -material = generic_pla -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla [values] layer_height = 0.2 @@ -19,4 +19,4 @@ speed_print = 50 speed_layer_0 = =round(speed_print * 30 / 50) speed_topbottom = 20 cool_min_layer_time = 5 -cool_min_speed = 10 \ No newline at end of file +cool_min_speed = 10 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index c6281767f9..caa6d8edb6 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -4,10 +4,10 @@ name = Draft definition = anycubic_i3_mega [metadata] +setting_version = 4 type = quality quality_type = draft weight = 0 -setting_version = 4 [values] acceleration_enabled = True @@ -57,4 +57,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index 839054a4df..5d6f8d9013 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -4,10 +4,10 @@ name = High definition = anycubic_i3_mega [metadata] +setting_version = 4 type = quality quality_type = high weight = 2 -setting_version = 4 [values] acceleration_enabled = True @@ -57,4 +57,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index 241a8b2e2c..ca25afa424 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -4,10 +4,10 @@ name = Normal definition = anycubic_i3_mega [metadata] +setting_version = 4 type = quality quality_type = normal weight = 1 -setting_version = 4 [values] acceleration_enabled = True @@ -57,4 +57,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg index 92f899bdeb..d83f2a1ccd 100644 --- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -material = verbatim_bvoh_175 -setting_version = 4 weight = -1 +material = verbatim_bvoh_175 [values] material_print_temperature = =default_material_print_temperature + 5 @@ -21,4 +21,3 @@ layer_height = 0.3 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 speed_print = 40 - diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg index cd8947aa80..f029a0206f 100644 --- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -material = verbatim_bvoh_175 -setting_version = 4 weight = 1 +material = verbatim_bvoh_175 [values] acceleration_print = 2000 @@ -22,4 +22,4 @@ layer_height = 0.1 top_thickness = =layer_height * 7 bottom_thickness = =layer_height * 5 speed_print = 40 -layer_height_0 = 0.2 \ No newline at end of file +layer_height_0 = 0.2 diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg index d59f768470..640812b37d 100644 --- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -material = verbatim_bvoh_175 -setting_version = 4 weight = 0 +material = verbatim_bvoh_175 [values] material_print_temperature = =default_material_print_temperature + 5 @@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature layer_height = 0.2 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 -speed_print = 40 \ No newline at end of file +speed_print = 40 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg index 41d882ee1d..905cf50518 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -material = innofill_innoflex60_175 -setting_version = 4 weight = -1 +material = innofill_innoflex60_175 [values] material_print_temperature = =default_material_print_temperature @@ -21,4 +21,3 @@ layer_height = 0.3 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 speed_print = 30 - diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg index 147e1f4db8..835ce04d61 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -material = innofill_innoflex60_175 -setting_version = 4 weight = 1 +material = innofill_innoflex60_175 [values] acceleration_print = 2000 @@ -22,4 +22,4 @@ layer_height = 0.1 top_thickness = =layer_height * 7 bottom_thickness = =layer_height * 5 speed_print = 30 -layer_height_0 = 0.2 \ No newline at end of file +layer_height_0 = 0.2 diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg index fb43c8de19..ba176dbc5c 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -material = innofill_innoflex60_175 -setting_version = 4 weight = 0 +material = innofill_innoflex60_175 [values] material_print_temperature = =default_material_print_temperature @@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature layer_height = 0.2 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 -speed_print = 30 \ No newline at end of file +speed_print = 30 diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index f887600585..ce9e58ea04 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_petg_175 -setting_version = 4 weight = -1 +material = generic_petg_175 [values] material_print_temperature = =default_material_print_temperature - 5 @@ -21,4 +21,3 @@ layer_height = 0.3 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 speed_print = 60 - diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index 4258f2f708..cbde2790df 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175 -setting_version = 4 weight = 1 +material = generic_petg_175 [values] acceleration_print = 2000 @@ -22,4 +22,4 @@ layer_height = 0.1 top_thickness = =layer_height * 7 bottom_thickness = =layer_height * 5 speed_print = 40 -layer_height_0 = 0.2 \ No newline at end of file +layer_height_0 = 0.2 diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index b732073795..af122db9cc 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175 -setting_version = 4 weight = 0 +material = generic_petg_175 [values] material_print_temperature = =default_material_print_temperature - 5 @@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature layer_height = 0.2 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 -speed_print = 50 \ No newline at end of file +speed_print = 50 diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index 4f0c26dd7d..d8baf277a9 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_pla_175 -setting_version = 4 weight = -1 +material = generic_pla_175 [values] material_print_temperature = =default_material_print_temperature + 15 @@ -21,4 +21,3 @@ layer_height = 0.3 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 speed_print = 60 - diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 4a9bcb90bf..49675e25d9 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175 -setting_version = 4 weight = 1 +material = generic_pla_175 [values] acceleration_print = 2000 @@ -22,4 +22,4 @@ layer_height = 0.1 top_thickness = =layer_height * 7 bottom_thickness = =layer_height * 5 speed_print = 40 -layer_height_0 = 0.2 \ No newline at end of file +layer_height_0 = 0.2 diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index 6af5601fd6..113bdba605 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175 -setting_version = 4 weight = 0 +material = generic_pla_175 [values] material_print_temperature = =default_material_print_temperature + 15 @@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature layer_height = 0.2 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 -speed_print = 50 \ No newline at end of file +speed_print = 50 diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index 12a4c9d883..059f25a70f 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_pva_175 -setting_version = 4 weight = -1 +material = generic_pva_175 [values] material_print_temperature = =default_material_print_temperature + 10 @@ -21,4 +21,3 @@ layer_height = 0.3 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 speed_print = 40 - diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index d32017c5f2..5da254aa9b 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pva_175 -setting_version = 4 weight = 1 +material = generic_pva_175 [values] acceleration_print = 2000 @@ -22,4 +22,4 @@ layer_height = 0.1 top_thickness = =layer_height * 7 bottom_thickness = =layer_height * 5 speed_print = 40 -layer_height_0 = 0.2 \ No newline at end of file +layer_height_0 = 0.2 diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index 2acc354822..562b2257f5 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pva_175 -setting_version = 4 weight = 0 +material = generic_pva_175 [values] material_print_temperature = =default_material_print_temperature + 10 @@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature layer_height = 0.2 top_thickness = =layer_height * 5 bottom_thickness = =layer_height * 3 -speed_print = 40 \ No newline at end of file +speed_print = 40 diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg index 4b66293d04..c9b2b3a654 100644 --- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = coarse -setting_version = 4 weight = -1 global_quality = True [values] -layer_height = 0.3 \ No newline at end of file +layer_height = 0.3 diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg index 4a97dda084..efad0f96e5 100644 --- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = high -setting_version = 4 weight = 1 global_quality = True [values] -layer_height = 0.1 \ No newline at end of file +layer_height = 0.1 diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg index 15ea66879f..69c6214aa8 100644 --- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = builder_premium_small [metadata] +setting_version = 4 type = quality quality_type = normal -setting_version = 4 weight = 0 global_quality = True [values] -layer_height = 0.2 \ No newline at end of file +layer_height = 0.2 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index 418855a9ba..89ab9a09d4 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_abs_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index e95ef08e22..a83a6d1e31 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_abs_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index 524f5ba12a..b5281407dd 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_abs_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index 24ffb19d6f..b366026793 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_abs_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index 1281a3afdd..0f4896ea74 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_abs_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_abs_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index a8d19deef7..5f3f20c9ee 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_abs_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_abs_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index 87cc855f44..2a5b873dd4 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_abs_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 4ca2598051..887a252e06 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_abs_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg index 42eb705f11..6b186f427c 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = dsm_arnitel2045_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = dsm_arnitel2045_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 538fe91b76..11bf7cf2e6 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = dsm_arnitel2045_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = dsm_arnitel2045_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg index 11760b139f..53cbb6bf06 100644 --- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -global_quality = True weight = -3 -setting_version = 4 +global_quality = True [values] layer_height = 0.4 diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg index c654dba598..4d612db89f 100644 --- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -global_quality = True weight = -4 -setting_version = 4 +global_quality = True [values] layer_height = 0.6 diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg index 393a5f3b39..b9e4f287a1 100644 --- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -global_quality = True weight = 1 -setting_version = 4 +global_quality = True [values] layer_height = 0.1 diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg index c09493ba10..1b3af7c9ce 100644 --- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -global_quality = True weight = 0 -setting_version = 4 +global_quality = True [values] layer_height = 0.2 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index eae4e82cd3..b4417d4bcf 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_hips_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_hips_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index 0c47b18196..b669f21a2b 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_hips_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_hips_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index 14f1ea4662..c88f8be029 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_hips_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_hips_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index bd13b358ff..4790926e3b 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_hips_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_hips_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index ca864692c3..e096fbb3a4 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_hips_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_hips_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index 3cadef4fdd..80a44678ca 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_hips_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_hips_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index 07839c8a9a..e1754d5ba0 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_hips_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_hips_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index acc9db0891..b728e01c99 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_hips_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_hips_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index b1f2f17d41..b81a053cd3 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_nylon_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_nylon_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index bcfa1c2e30..b09e2ac794 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_nylon_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index 2cd50efeb2..b43839439f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_nylon_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_nylon_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index 7a7d767ea3..36cfe49afb 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_nylon_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index 5684c89e23..ef3185814b 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_nylon_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_nylon_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index 8d97e9ac5f..af57d6f3ab 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_nylon_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_nylon_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index 946f8de34d..99e932c954 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_nylon_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_nylon_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index 80f390c254..a0fef367a6 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_nylon_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index ff6547dd91..ac0f7a35fa 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pc_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_pc_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index f3faa9c129..5f77a2a91e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_pc_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 3aa808fab5..835c94e5fd 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pc_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_pc_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index f9be12da3a..7e48b4a94c 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_pc_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index 597187437b..e857476b8b 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_pc_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_pc_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 6d1fa196ec..0fc24de569 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_pc_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_pc_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index c570b65350..3c58129546 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pc_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_pc_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 0d73b24197..3b8765b21a 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_pc_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index c5c4be6f4a..94bf52b2a4 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_petg_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index 6d12bdc402..d5517b57b5 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_petg_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 43dda5007c..33b3bfa99d 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_petg_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index 094dc33263..1bdbe32229 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_petg_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index da9e4ad3dd..20b2d38856 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_petg_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_petg_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index 607ba778a1..cdb4d08dd0 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_petg_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_petg_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index 3010d95dab..e125e9dd63 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_petg_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index fbf8fac67f..91a513d171 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_petg_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index 9d8130602e..cbd40f3f8f 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_pla_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index 98401dbf42..3eed8df302 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175_cartesio_0.25_mm weight = 0 -setting_version = 4 +material = generic_pla_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index 2eda5103d7..0822ab8c07 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_pla_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index f3d3820ff7..80fb24553f 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175_cartesio_0.4_mm weight = 0 -setting_version = 4 +material = generic_pla_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index d2cf708336..c6b92d50a7 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_pla_175_cartesio_0.8_mm weight = -3 -setting_version = 4 +material = generic_pla_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index 888d8f91a7..cb2633313a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_pla_175_cartesio_0.8_mm weight = -4 -setting_version = 4 +material = generic_pla_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index 558514db98..de0298f57e 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_pla_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index 9c508e4a1f..c6f4e012b6 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175_cartesio_0.8_mm weight = 0 -setting_version = 4 +material = generic_pla_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index fcbf4913de..22fdd98317 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pva_175_cartesio_0.25_mm weight = 1 -setting_version = 4 +material = generic_pva_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 3893421df0..8288294d0c 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pva_175_cartesio_0.25_mm weight = 2 -setting_version = 4 +material = generic_pva_175 +variant = 0.25 mm [values] infill_line_width = 0.3 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index 5876db1e2e..2719eb458e 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pva_175_cartesio_0.4_mm weight = 1 -setting_version = 4 +material = generic_pva_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index c977e79a5c..6a97ec860f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pva_175_cartesio_0.4_mm weight = 2 -setting_version = 4 +material = generic_pva_175 +variant = 0.4 mm [values] infill_line_width = 0.5 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index 8c36d8e7ed..12ca609a7b 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = coarse -material = generic_pva_175_cartesio_0.8_mm weight = 3 -setting_version = 4 +material = generic_pva_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index c2b19868f6..d793282c41 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Extra Coarse definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = extra coarse -material = generic_pva_175_cartesio_0.8_mm weight = 4 -setting_version = 4 +material = generic_pva_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index 5bd285285a..a43689e7c9 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -4,11 +4,12 @@ name = High definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pva_175_cartesio_0.8_mm weight = 1 -setting_version = 4 +material = generic_pva_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index a11bff95e1..f9ead11d79 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = cartesio [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pva_175_cartesio_0.8_mm weight = 2 -setting_version = 4 +material = generic_pva_175 +variant = 0.8 mm [values] infill_line_width = 0.9 diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg index 133ffc8951..1accd77807 100644 --- a/resources/quality/coarse.inst.cfg +++ b/resources/quality/coarse.inst.cfg @@ -4,11 +4,11 @@ name = Coarse Quality definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = coarse -global_quality = True weight = -3 -setting_version = 4 +global_quality = True [values] layer_height = 0.4 diff --git a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg index 43643b6b92..aebb72d610 100644 --- a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = Fast Quality (beta) [metadata] -type = quality setting_version = 4 -material = generic_abs_175 +type = quality quality_type = fast weight = -1 +material = generic_abs_175 [values] adhesion_type = raft @@ -22,4 +22,3 @@ cool_fan_speed_min = 50 cool_min_layer_time = 3 cool_min_speed = 20 material_bed_temperature = 80 - diff --git a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg index 99e47bc9cb..05b54eb81e 100644 --- a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = High Quality (beta) [metadata] -type = quality setting_version = 4 -material = generic_abs_175 +type = quality quality_type = high weight = 1 +material = generic_abs_175 [values] adhesion_type = raft @@ -22,4 +22,3 @@ cool_fan_speed_min = 50 cool_min_layer_time = 3 cool_min_speed = 20 material_bed_temperature = 80 - diff --git a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg index a2aa2be769..67c8525b4f 100644 --- a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = Normal Quality (beta) [metadata] -type = quality setting_version = 4 -material = generic_abs_175 +type = quality quality_type = normal weight = 0 +material = generic_abs_175 [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg index fac23939cf..511ee2712f 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg @@ -4,11 +4,11 @@ name = Fast Quality (beta) definition = deltacomb [metadata] +setting_version = 4 type = quality -material = generic_nylon_175 quality_type = fast weight = -1 -setting_version = 4 +material = generic_nylon_175 [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg index d594126474..47c3e26782 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg @@ -4,11 +4,11 @@ name = High Quality (beta) definition = deltacomb [metadata] +setting_version = 4 type = quality -material = generic_nylon_175 quality_type = high weight = 1 -setting_version = 4 +material = generic_nylon_175 [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg index 76716fc16d..49ffada336 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg @@ -4,11 +4,11 @@ name = Normal Quality (beta) definition = deltacomb [metadata] +setting_version = 4 type = quality -material = generic_nylon_175 quality_type = normal weight = 0 -setting_version = 4 +material = generic_nylon_175 [values] adhesion_type = raft @@ -55,4 +55,3 @@ support_z_distance = 0.15 top_bottom_thickness = 0.8 wall_thickness = 0.8 z_seam_type = random - diff --git a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg index 9783cb11cc..684b72587c 100644 --- a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = Fast Quality [metadata] -type = quality setting_version = 4 -material = generic_pla_175 +type = quality quality_type = fast weight = -1 +material = generic_pla_175 [values] adhesion_type = skirt @@ -21,4 +21,3 @@ cool_fan_speed_max = 100 cool_fan_speed_min = 100 cool_min_layer_time = 5 cool_min_speed = 20 - diff --git a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg index 9513e98b6a..a80f23fa9b 100644 --- a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = High Quality [metadata] -type = quality setting_version = 4 -material = generic_pla_175 +type = quality quality_type = high weight = 1 +material = generic_pla_175 [values] adhesion_type = skirt @@ -22,4 +22,3 @@ cool_fan_speed_min = 100 cool_min_layer_time = 5 cool_min_speed = 20 material_print_temperature_layer_0 = =default_material_print_temperature + 5 - diff --git a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg index d88f5909f0..8a02873fa2 100644 --- a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg @@ -4,11 +4,11 @@ definition = deltacomb name = Normal Quality [metadata] -type = quality setting_version = 4 -material = generic_pla_175 +type = quality quality_type = normal weight = 0 +material = generic_pla_175 [values] adhesion_type = skirt diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg index a155c8f2e1..2b375878b6 100644 --- a/resources/quality/draft.inst.cfg +++ b/resources/quality/draft.inst.cfg @@ -1,15 +1,14 @@ - [general] version = 2 name = Draft Quality definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = draft -global_quality = True weight = -2 -setting_version = 4 +global_quality = True [values] layer_height = 0.2 diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index ce28e54721..6c11c9e61b 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -4,11 +4,11 @@ name = Extra Coarse Quality definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = Extra coarse -global_quality = True weight = -4 -setting_version = 4 +global_quality = True [values] layer_height = 0.6 diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg index 245997a27e..8a48962553 100644 --- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = Fast Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_abs +type = quality quality_type = fast weight = -1 +material = fabtotum_abs [values] adhesion_type = raft @@ -21,4 +21,3 @@ cool_fan_speed_max = 50 cool_fan_speed_min = 50 cool_min_layer_time = 3 cool_min_speed = 20 - diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg index 26300eec7d..c8a970e180 100644 --- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = High Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_abs +type = quality quality_type = high weight = 1 +material = fabtotum_abs [values] adhesion_type = raft @@ -21,4 +21,3 @@ cool_fan_speed_max = 50 cool_fan_speed_min = 50 cool_min_layer_time = 3 cool_min_speed = 20 - diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg index 53d20c8cbc..03b580a9c3 100644 --- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = Normal Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_abs +type = quality quality_type = normal weight = 0 +material = fabtotum_abs [values] adhesion_type = raft @@ -21,4 +21,3 @@ cool_fan_speed_max = 50 cool_fan_speed_min = 50 cool_min_layer_time = 3 cool_min_speed = 20 - diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg index 22bbcbeaeb..7c5769c489 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg @@ -4,11 +4,11 @@ name = Fast Quality definition = fabtotum [metadata] +setting_version = 4 type = quality -material = fabtotum_nylon quality_type = fast weight = -1 -setting_version = 4 +material = fabtotum_nylon [values] adhesion_type = raft @@ -54,4 +54,4 @@ support_type = buildplate support_z_distance = 0.15 top_bottom_thickness = 0.8 wall_thickness = 0.8 -z_seam_type = random \ No newline at end of file +z_seam_type = random diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg index a625bd715f..a74a6d5138 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg @@ -4,11 +4,11 @@ name = High Quality definition = fabtotum [metadata] +setting_version = 4 type = quality -material = fabtotum_nylon quality_type = high weight = 1 -setting_version = 4 +material = fabtotum_nylon [values] adhesion_type = raft @@ -54,4 +54,4 @@ support_type = buildplate support_z_distance = 0.15 top_bottom_thickness = 0.8 wall_thickness = 0.8 -z_seam_type = random \ No newline at end of file +z_seam_type = random diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg index b05d30c5c6..c3de34beb3 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg @@ -4,11 +4,11 @@ name = Normal Quality definition = fabtotum [metadata] +setting_version = 4 type = quality -material = fabtotum_nylon quality_type = normal weight = 0 -setting_version = 4 +material = fabtotum_nylon [values] adhesion_type = raft @@ -55,4 +55,3 @@ support_z_distance = 0.15 top_bottom_thickness = 0.8 wall_thickness = 0.8 z_seam_type = random - diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg index 1f1c93961b..3c71af3727 100644 --- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = Fast Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_pla +type = quality quality_type = fast weight = -1 +material = fabtotum_pla [values] adhesion_type = skirt @@ -21,4 +21,3 @@ cool_fan_speed_max = 100 cool_fan_speed_min = 100 cool_min_layer_time = 5 cool_min_speed = 20 - diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg index 9cd067703c..0832f84d0c 100644 --- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = High Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_pla +type = quality quality_type = high weight = 1 +material = fabtotum_pla [values] adhesion_type = skirt @@ -21,4 +21,3 @@ cool_fan_speed_max = 100 cool_fan_speed_min = 100 cool_min_layer_time = 5 cool_min_speed = 20 - diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg index 5b5125c4e5..16afc56cf1 100644 --- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg @@ -4,11 +4,11 @@ definition = fabtotum name = Normal Quality [metadata] -type = quality setting_version = 4 -material = fabtotum_pla +type = quality quality_type = normal weight = 0 +material = fabtotum_pla [values] adhesion_type = skirt @@ -21,4 +21,3 @@ cool_fan_speed_max = 100 cool_fan_speed_min = 100 cool_min_layer_time = 5 cool_min_speed = 20 - diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg index 74d3d1c134..67b5cb49b8 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Dual Normal Layers definition = gmax15plus_dual [metadata] +setting_version = 4 type = quality quality_type = normal weight = -1 -setting_version = 4 global_quality = True [values] diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg index 32191f36d8..376e3241ff 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Dual Thick Layers definition = gmax15plus_dual [metadata] +setting_version = 4 type = quality quality_type = course weight = -2 -setting_version = 4 global_quality = True [values] diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg index 5906875a3a..1c0cabd84f 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Dual Thin Layers definition = gmax15plus_dual [metadata] +setting_version = 4 type = quality quality_type = high weight = 0 -setting_version = 4 global_quality = True [values] diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg index a94a621a88..d292284531 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Dual Very Thick Layers definition = gmax15plus_dual [metadata] +setting_version = 4 type = quality quality_type = extra_course weight = -3 -setting_version = 4 global_quality = True [values] diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg index a6513cba80..3baad3a928 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Normal Layers definition = gmax15plus [metadata] +setting_version = 4 type = quality quality_type = normal weight = -1 -setting_version = 4 global_quality = True [values] @@ -58,5 +58,3 @@ top_thickness = 1 bottom_layers = 2 wall_line_count = 2 z_seam_corner = z_seam_corner_none - - diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg index be0d99a413..856ab7d3db 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Thick Layers definition = gmax15plus [metadata] +setting_version = 4 type = quality quality_type = course weight = -2 -setting_version = 4 global_quality = True [values] @@ -57,4 +57,4 @@ top_layers = 3 top_thickness = 1 bottom_layers = 2 wall_line_count = 2 -z_seam_corner = z_seam_corner_none \ No newline at end of file +z_seam_corner = z_seam_corner_none diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg index 7069db6dd6..46f41e195f 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Thin Layers definition = gmax15plus [metadata] +setting_version = 4 type = quality quality_type = high weight = 0 -setting_version = 4 global_quality = True [values] @@ -57,4 +57,4 @@ top_layers = 5 top_thickness = 1 bottom_layers = 3 wall_line_count = 2 -z_seam_corner = z_seam_corner_none \ No newline at end of file +z_seam_corner = z_seam_corner_none diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg index 88d03ee77f..938f21a13d 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg @@ -4,10 +4,10 @@ name = gMax 1.5+ Very Thick Layers definition = gmax15plus [metadata] +setting_version = 4 type = quality quality_type = extra_course weight = -3 -setting_version = 4 global_quality = True [values] @@ -56,4 +56,4 @@ top_layers = 3 top_thickness = 1 bottom_layers = 2 wall_line_count = 2 -z_seam_corner = z_seam_corner_none \ No newline at end of file +z_seam_corner = z_seam_corner_none diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index d4333c90da..9ef90181a3 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = high -global_quality = True weight = 1 -setting_version = 4 +global_quality = True [values] layer_height = 0.06 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index e36286c6ae..e5b3aed52b 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = imade3d_jellybox [metadata] -type = quality -material = generic_petg_imade3d_jellybox_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_petg +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 3240bad98b..e7f2d5d60a 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = imade3d_jellybox [metadata] -type = quality -material = generic_petg_imade3d_jellybox_0.4_mm_2-fans -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_petg +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index 2790a5a742..4d122f1ac2 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -4,11 +4,12 @@ name = Medium definition = imade3d_jellybox [metadata] -type = quality -material = generic_petg_imade3d_jellybox_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_petg +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index 14f141f0bf..9646b0bb5f 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = Medium definition = imade3d_jellybox [metadata] -type = quality -material = generic_petg_imade3d_jellybox_0.4_mm_2-fans -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_petg +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 842ec618e0..8ecfa927a7 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pla +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 17e085d84d..52c7df70f3 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = Coarse definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm_2-fans -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pla +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index a4b44f47f6..a48dbe2f81 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index 962b3c9ad4..4707337611 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm_2-fans -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 952b16ecf8..2f5a0f33a8 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -4,11 +4,12 @@ name = Medium definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index bd70d105a4..f0451fc9be 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = Medium definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm_2-fans -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index a9d0679612..179623153a 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -4,11 +4,12 @@ name = UltraFine definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm -weight = 2 -quality_type = ultrahigh setting_version = 4 +type = quality +quality_type = ultrahigh +weight = 2 +material = generic_pla +variant = 0.4 mm [values] adhesion_type = skirt diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index 097e1fc76a..b35db0fde6 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -4,11 +4,12 @@ name = UltraFine definition = imade3d_jellybox [metadata] -type = quality -material = generic_pla_imade3d_jellybox_0.4_mm_2-fans -weight = 2 -quality_type = ultrahigh setting_version = 4 +type = quality +quality_type = ultrahigh +weight = 2 +material = generic_pla +variant = 0.4 mm 2-fans [values] adhesion_type = skirt diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg index 5401ec7bd6..add07c797a 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg @@ -4,11 +4,11 @@ name = Draft definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = coarse weight = -3 material = generic_abs -quality_type = coarse -setting_version = 4 [values] layer_height = 0.35 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg index aea8fc9535..8d31e439e1 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = high weight = 1 material = generic_abs -quality_type = high -setting_version = 4 [values] layer_height = 0.06 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg index 24adbd9f6c..936e9f8cd8 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = normal weight = 0 material = generic_abs -quality_type = normal -setting_version = 4 [values] layer_height = 0.1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg index 98d2475633..8f48616dbf 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg @@ -4,11 +4,11 @@ name = Low definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = draft weight = -2 material = generic_abs -quality_type = draft -setting_version = 4 [values] layer_height = 0.2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index ab2e9dabbc..440575a066 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = low weight = -1 material = generic_abs -quality_type = low -setting_version = 4 [values] layer_height = 0.15 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg index f868ab40fc..d9ea0e6850 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg @@ -4,11 +4,11 @@ name = Draft definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = coarse weight = -3 material = generic_pla -quality_type = coarse -setting_version = 4 [values] layer_height = 0.35 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg index e907f7ccaf..b1775b994f 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = kemiq_q2_beta [metadata] -type = quality -material = generic_pla -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla [values] layer_height = 0.06 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg index 841023d532..cf7e070cb8 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = normal weight = 0 material = generic_pla -quality_type = normal -setting_version = 4 [values] layer_height = 0.1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg index ca874c6bce..8b40fabb7b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg @@ -4,11 +4,11 @@ name = Low definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = draft weight = -2 material = generic_pla -quality_type = draft -setting_version = 4 [values] layer_height = 0.2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index fcfbe72b24..12ca8ed571 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = kemiq_q2_beta [metadata] +setting_version = 4 type = quality +quality_type = low weight = -1 material = generic_pla -quality_type = low -setting_version = 4 [values] layer_height = 0.15 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg index 009af9b87b..fcda1b081e 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg @@ -4,11 +4,11 @@ name = Draft definition = kemiq_q2_gama [metadata] +setting_version = 4 type = quality +quality_type = coarse weight = -3 material = generic_pla -quality_type = coarse -setting_version = 4 [values] layer_height = 0.35 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg index 447e3b012d..52e5e8df98 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = kemiq_q2_gama [metadata] -type = quality -material = generic_pla -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla [values] layer_height = 0.06 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg index 80b2375108..b3ea5b8967 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = kemiq_q2_gama [metadata] +setting_version = 4 type = quality +quality_type = normal weight = 0 material = generic_pla -quality_type = normal -setting_version = 4 [values] layer_height = 0.1 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg index e30c52f4e6..08a3db0b1f 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg @@ -4,11 +4,11 @@ name = Low definition = kemiq_q2_gama [metadata] +setting_version = 4 type = quality +quality_type = draft weight = -2 material = generic_pla -quality_type = draft -setting_version = 4 [values] layer_height = 0.2 diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index 31bdaa51bc..51368f1b1b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = kemiq_q2_gama [metadata] +setting_version = 4 type = quality +quality_type = low weight = -1 material = generic_pla -quality_type = low -setting_version = 4 [values] layer_height = 0.15 diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index e92490722d..25cb71e2bc 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -4,11 +4,11 @@ name = Low Quality definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = low -global_quality = True weight = -1 -setting_version = 4 +global_quality = True [values] infill_sparse_density = 10 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index 19cc9fd00d..084094f5e7 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -4,12 +4,12 @@ name = Fast definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_abs_175 weight = -2 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index 5677a0d58d..1e3419dc7e 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -4,12 +4,12 @@ name = Normal definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_abs_175 weight = -1 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 7798b3f545..0758cd6630 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -4,12 +4,12 @@ name = Finer definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_175 weight = 1 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index c87c66c813..da347ac13c 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -4,12 +4,12 @@ name = Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_175 weight = 0 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index e6e3cfcd6c..cc25431062 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -4,12 +4,12 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_abs_175 weight = -5 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index fb08013809..2b7f830b3f 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -4,12 +4,12 @@ name = Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_abs_175 weight = -3 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index 385d852688..73abddc696 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -4,12 +4,12 @@ name = Ultra Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_abs_175 weight = 2 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 7026391fb6..22adb14e71 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -4,12 +4,12 @@ name = Low Detail Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_abs_175 weight = -4 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg index 54be6ecbcc..89d7f2f2ec 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg @@ -4,10 +4,10 @@ name = M1 Quality definition = malyan_m200 [metadata] -type = quality -weight = 2 -quality_type = fine setting_version = 4 +type = quality +quality_type = fine +weight = 2 [values] layer_height = 0.04375 diff --git a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg index 568dd796f3..555b280c1c 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg @@ -4,10 +4,10 @@ name = M2 Quality definition = malyan_m200 [metadata] -type = quality -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 [values] layer_height = 0.0875 diff --git a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg index 1dc436502b..7829f33086 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg @@ -4,10 +4,10 @@ name = M3 Quality definition = malyan_m200 [metadata] -type = quality -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 [values] layer_height = 0.13125 diff --git a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg index 314a8acd83..e6fd4c9368 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg @@ -4,11 +4,11 @@ name = M4 Quality definition = malyan_m200 [metadata] -type = quality -weight = -1 -quality_type = fast -global_quality = true setting_version = 4 +type = quality +quality_type = fast +weight = -1 +global_quality = true [values] layer_height = 0.175 diff --git a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg index a7fedb7e04..143693dbc4 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg @@ -4,10 +4,10 @@ name = M5 Quality definition = malyan_m200 [metadata] -type = quality -weight = -2 -quality_type = faster setting_version = 4 +type = quality +quality_type = faster +weight = -2 [values] layer_height = 0.21875 diff --git a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg index 441abc3070..3dc33a81a0 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg @@ -4,10 +4,10 @@ name = M6 Quality definition = malyan_m200 [metadata] -type = quality -weight = -3 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -3 [values] layer_height = 0.2625 diff --git a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg index 2588838174..c7d6911a67 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg @@ -4,10 +4,10 @@ name = M7 Quality definition = malyan_m200 [metadata] -type = quality -weight = -4 -quality_type = turbo setting_version = 4 +type = quality +quality_type = turbo +weight = -4 [values] layer_height = 0.30625 diff --git a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg index 800b6104d9..5d14204a1e 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg @@ -4,11 +4,11 @@ name = M8 Quality definition = malyan_m200 [metadata] -type = quality -weight = -5 -quality_type = hyper -global_quality = true setting_version = 4 +type = quality +quality_type = hyper +weight = -5 +global_quality = true [values] layer_height = 0.35 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg index d3104caa87..fd999cc6c7 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fast definition = malyan_m200 [metadata] -type = quality -weight = -2 -quality_type = draft -global_quality = True setting_version = 4 +type = quality +quality_type = draft +weight = -2 +global_quality = True [values] layer_height = 0.21875 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg index aec535bd71..8027a7b01a 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = malyan_m200 [metadata] -type = quality -weight = -1 -quality_type = fast -global_quality = True setting_version = 4 +type = quality +quality_type = fast +weight = -1 +global_quality = True [values] layer_height = 0.175 diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg index ca202862a2..01fea67382 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Finer definition = malyan_m200 [metadata] -type = quality -weight = 1 -quality_type = high -global_quality = True setting_version = 4 +type = quality +quality_type = high +weight = 1 +global_quality = True [values] layer_height = 0.0875 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg index 7076718903..a705d187f1 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = malyan_m200 [metadata] -type = quality -weight = 0 -quality_type = normal -global_quality = True setting_version = 4 +type = quality +quality_type = normal +weight = 0 +global_quality = True [values] layer_height = 0.13125 diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg index 7dfbdb5886..92f1eb2286 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] -type = quality -weight = -5 -quality_type = superdraft -global_quality = True setting_version = 4 +type = quality +quality_type = superdraft +weight = -5 +global_quality = True [values] layer_height = 0.35 diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg index 2fbf82b128..246443503e 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Draft definition = malyan_m200 [metadata] -type = quality -weight = -3 -quality_type = thickerdraft -global_quality = True setting_version = 4 +type = quality +quality_type = thickerdraft +weight = -3 +global_quality = True [values] layer_height = 0.2625 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg index 90e589cca5..0bbe46be4e 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Ultra Fine definition = malyan_m200 [metadata] -type = quality -weight = 2 -quality_type = ultra -global_quality = True setting_version = 4 +type = quality +quality_type = ultra +weight = 2 +global_quality = True [values] layer_height = 0.04375 diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index 1210ee214b..5cc85b9bc8 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Low Detail Draft definition = malyan_m200 [metadata] -type = quality -weight = -4 -quality_type = verydraft -global_quality = True setting_version = 4 +type = quality +quality_type = verydraft +weight = -4 +global_quality = True [values] layer_height = 0.30625 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index aef83471ba..9d3e31cb16 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -4,8 +4,8 @@ name = Fast definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_petg_175 weight = -2 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index 3c7fc2c239..9d68dee0bf 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -4,8 +4,8 @@ name = Normal definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_petg_175 weight = -1 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index eb1654eae3..63aefb027b 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -4,8 +4,8 @@ name = Finer definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175 weight = 1 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 53e60d2d62..402c87886c 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -4,8 +4,8 @@ name = Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index d2a96386ae..9029b4508a 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -4,8 +4,8 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_petg_175 weight = -5 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index e2f37ae43b..e9b440e1f6 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -4,8 +4,8 @@ name = Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_petg_175 weight = -3 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index 0fa89f2569..1517f7d340 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -4,8 +4,8 @@ name = Ultra Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_petg_175 weight = 2 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index 84bedf5c14..3d3346eac5 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -4,8 +4,8 @@ name = Low Detail Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_petg_175 weight = -4 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index 4f221eceb7..b05a336aee 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -4,12 +4,12 @@ name = Fast definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pla_175 weight = -2 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index 3097fe055a..e45fe903e2 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -4,12 +4,12 @@ name = Normal definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pla_175 weight = -1 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index 062c120ad0..adeae8ae33 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -4,12 +4,12 @@ name = Finer definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175 weight = 1 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index e01141ed9e..0c0f9fcb5a 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -4,12 +4,12 @@ name = Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175 weight = 0 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index 53eb4380eb..e5e5d6d40d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -4,12 +4,12 @@ name = Lowest Quality Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pla_175 weight = -5 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index 32d2b419bc..95323181d7 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -4,12 +4,12 @@ name = Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_pla_175 weight = -3 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 3865059254..8b0005e60d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -4,12 +4,12 @@ name = Ultra Fine definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_pla_175 weight = 2 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index a624c056be..cc8ef3c9cd 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -4,12 +4,12 @@ name = Low Detail Draft definition = malyan_m200 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_pla_175 weight = -4 -setting_version = 4 +material = generic_pla_175 [values] material_bed_temperature = 60 -material_bed_temperature_layer_0 = 60 \ No newline at end of file +material_bed_temperature_layer_0 = 60 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index a63256573a..b75f20a1a6 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -4,12 +4,12 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_abs_175 weight = -2 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index 49f4486596..e06394dea5 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -4,12 +4,12 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_abs_175 weight = -1 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index eab16a8e2b..7249fb039c 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -4,12 +4,12 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_175 weight = 1 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index 03aeb4067b..a0237b3af2 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -4,12 +4,12 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_175 weight = 0 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index 148f53ba73..c858d341d2 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -4,12 +4,12 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_abs_175 weight = -5 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index e2ad71a360..9996338c79 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -4,12 +4,12 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_abs_175 weight = -3 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index 7ebdf80baf..5d94f941c8 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -4,12 +4,12 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_abs_175 weight = 2 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 9965ae8bcf..0635565027 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -4,12 +4,12 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_abs_175 weight = -4 -setting_version = 4 +material = generic_abs_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg index b7d0faa2c7..d8aa07b779 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = -2 -quality_type = draft -global_quality = True setting_version = 4 +type = quality +quality_type = draft +weight = -2 +global_quality = True [values] layer_height = 0.21875 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg index f7f338e4c9..a0620d532a 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = -1 -quality_type = fast -global_quality = True setting_version = 4 +type = quality +quality_type = fast +weight = -1 +global_quality = True [values] layer_height = 0.175 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg index 4a37a1afd8..7237dbc42a 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = 1 -quality_type = high -global_quality = True setting_version = 4 +type = quality +quality_type = high +weight = 1 +global_quality = True [values] layer_height = 0.0875 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg index b8e545adcf..bcb360d310 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = 0 -quality_type = normal -global_quality = True setting_version = 4 +type = quality +quality_type = normal +weight = 0 +global_quality = True [values] layer_height = 0.13125 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg index 0ef9db5875..81954f86e7 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = -5 -quality_type = superdraft -global_quality = True setting_version = 4 +type = quality +quality_type = superdraft +weight = -5 +global_quality = True [values] layer_height = 0.35 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg index 4dd3a7aafe..1fe7ee22ab 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = -3 -quality_type = thickerdraft -global_quality = True setting_version = 4 +type = quality +quality_type = thickerdraft +weight = -3 +global_quality = True [values] layer_height = 0.2625 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg index 337f0d06bc..89e2f43dad 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = 2 -quality_type = ultra -global_quality = True setting_version = 4 +type = quality +quality_type = ultra +weight = 2 +global_quality = True [values] layer_height = 0.04375 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index e884077069..c7fc09d9e8 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] -type = quality -weight = -4 -quality_type = verydraft -global_quality = True setting_version = 4 +type = quality +quality_type = verydraft +weight = -4 +global_quality = True [values] layer_height = 0.30625 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index 4a03c17a63..42e0d69476 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -4,8 +4,8 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_nylon_175 weight = -2 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index 1c04f77b8b..e62e654fc3 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -4,8 +4,8 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_nylon_175 weight = -1 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index d57516598a..cca4b98678 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -4,8 +4,8 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_nylon_175 weight = 1 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 308ea86311..56c28e372f 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -4,8 +4,8 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index db4f3ca907..14375b3c41 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -4,8 +4,8 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_nylon_175 weight = -5 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index 9a1afc0e48..01c45f2401 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -4,8 +4,8 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_nylon_175 weight = -3 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index 3453671a72..205915cd7c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -4,8 +4,8 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_nylon_175 weight = 2 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index ee2531fc4e..124121c35c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -4,8 +4,8 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_nylon_175 weight = -4 -setting_version = 4 \ No newline at end of file +material = generic_nylon_175 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index aa5fc7844d..ae69e5fe46 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -4,12 +4,12 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pc_175 weight = -2 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index 232c4ab6f3..8e78ee7827 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -4,12 +4,12 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pc_175 weight = -1 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index aa9da322fb..761859e1a5 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -4,12 +4,12 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pc_175 weight = 1 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index 145b21221b..91575da188 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -4,12 +4,12 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_175 weight = 0 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index b6e53bda62..9295b6b6d1 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -4,12 +4,12 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pc_175 weight = -5 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index 055228ab13..02ba4841e8 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -4,12 +4,12 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_pc_175 weight = -3 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index a3e99b998e..8b3833371b 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -4,12 +4,12 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_pc_175 weight = 2 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 73f5a2f2c9..f0ada1c6a8 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -4,12 +4,12 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_pc_175 weight = -4 -setting_version = 4 +material = generic_pc_175 [values] material_bed_temperature = 70 -material_bed_temperature_layer_0 = 70 \ No newline at end of file +material_bed_temperature_layer_0 = 70 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index 8a33e03310..9278a6920a 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -4,8 +4,8 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_petg_175 weight = -2 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index fb084fa08e..503362f755 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -4,8 +4,8 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_petg_175 weight = -1 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index 16891f6f43..3d8ae1d5d0 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -4,8 +4,8 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_petg_175 weight = 1 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index bb2f0b47a8..66c69b237e 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -4,8 +4,8 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_petg_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 78ca1b6b7a..2b517e1521 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -4,8 +4,8 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_petg_175 weight = -5 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index 69606ff913..969bd71f1a 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -4,8 +4,8 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_petg_175 weight = -3 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index 7c5ac599c8..ef97518e2a 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -4,8 +4,8 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_petg_175 weight = 2 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index ed0c2510f5..7d338616dd 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -4,8 +4,8 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_petg_175 weight = -4 -setting_version = 4 \ No newline at end of file +material = generic_petg_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index 04a955cf6c..b3ccc9f82b 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -4,8 +4,8 @@ name = Fast definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pla_175 weight = -2 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index 6efc0935e2..67ed46db58 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -4,8 +4,8 @@ name = Normal definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pla_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index 8fe2371e5d..17b8f7a8b7 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -4,8 +4,8 @@ name = Finer definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index 01351154c4..7852138707 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -4,8 +4,8 @@ name = Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_175 weight = 0 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index adfced9787..aa46df06b6 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -4,8 +4,8 @@ name = Lowest Quality Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pla_175 weight = -5 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index f4522c9778..39cf607b25 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -4,8 +4,8 @@ name = Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = thickerdraft -material = generic_pla_175 weight = -3 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index 2fa8eb7f81..18d93dac2d 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -4,8 +4,8 @@ name = Ultra Fine definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality quality_type = ultra -material = generic_pla_175 weight = 2 -setting_version = 4 \ No newline at end of file +material = generic_pla_175 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index e59cf4a490..e8fff16371 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -4,8 +4,8 @@ name = Low Detail Draft definition = monoprice_select_mini_v2 [metadata] +setting_version = 4 type = quality -quality_type = verydraft material = generic_pla_175 weight = 0 -setting_version = 4 \ No newline at end of file +quality_type = verydraft diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 9fb7b238cd..2eeb91324f 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -4,10 +4,10 @@ name = Fine definition = fdmprinter [metadata] +setting_version = 4 type = quality quality_type = normal -global_quality = True weight = 0 -setting_version = 4 +global_quality = True [values] diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg index ae8a377116..208fa453fe 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg @@ -4,10 +4,10 @@ name = Extra Fine definition = peopoly_moai [metadata] -type = quality -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 [values] infill_sparse_density = 70 diff --git a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg index 07ab7e364b..cc764009a9 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg @@ -4,10 +4,10 @@ name = Maximum Quality definition = peopoly_moai [metadata] -type = quality -weight = 2 -quality_type = extra_high setting_version = 4 +type = quality +quality_type = extra_high +weight = 2 [values] infill_sparse_density = 70 diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index e0d2f7d818..2baa70be1e 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -4,10 +4,10 @@ name = Fine definition = peopoly_moai [metadata] -type = quality -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 [values] infill_sparse_density = 70 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg index 082b7dded7..2536cbba12 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg @@ -4,10 +4,10 @@ name = Draft definition = tevo_blackwidow [metadata] +setting_version = 4 type = quality quality_type = draft weight = -2 -setting_version = 4 [values] brim_width = 4.0 @@ -30,4 +30,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg index 79d020463f..29599eaebc 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg @@ -4,10 +4,10 @@ name = High definition = tevo_blackwidow [metadata] +setting_version = 4 type = quality quality_type = high weight = 1 -setting_version = 4 [values] brim_width = 4.0 @@ -30,4 +30,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg index 2982c44d3d..98dbf5a79a 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg @@ -4,10 +4,10 @@ name = Normal definition = tevo_blackwidow [metadata] +setting_version = 4 type = quality quality_type = normal weight = 0 -setting_version = 4 [values] brim_width = 4.0 @@ -30,4 +30,4 @@ support_type = everywhere support_use_towers = False support_xy_distance = 0.7 top_bottom_thickness = 1.2 -wall_thickness = 1.2 \ No newline at end of file +wall_thickness = 1.2 diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 4fe3f51e20..821c864bb8 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -4,10 +4,10 @@ name = Draft Quality definition = ultimaker2 [metadata] +setting_version = 4 type = quality quality_type = draft weight = -2 -setting_version = 4 [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 96941beed2..54119933b5 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -4,10 +4,10 @@ name = Extra Fine definition = ultimaker2 [metadata] +setting_version = 4 type = quality quality_type = high weight = 1 -setting_version = 4 [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2/um2_low.inst.cfg b/resources/quality/ultimaker2/um2_low.inst.cfg index 832962984c..acd6c849d1 100644 --- a/resources/quality/ultimaker2/um2_low.inst.cfg +++ b/resources/quality/ultimaker2/um2_low.inst.cfg @@ -4,10 +4,10 @@ name = Low Quality definition = ultimaker2 [metadata] +setting_version = 4 type = quality quality_type = low weight = -1 -setting_version = 4 [values] infill_sparse_density = 10 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index ea804feb80..ea7efc64ac 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -4,9 +4,9 @@ name = Fine definition = ultimaker2 [metadata] +setting_version = 4 type = quality quality_type = normal weight = 0 -setting_version = 4 [values] diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index 638a1a9384..07e3dcd7db 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pla_ultimaker2_plus_0.25_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla +variant = 0.25 mm [values] cool_min_layer_time = 5 @@ -19,4 +20,3 @@ speed_layer_0 = =round(speed_print * 30 / 30) speed_print = 30 top_bottom_thickness = 0.72 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 9f4dfc0b5d..2a72e40d80 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_pla_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pla +variant = 0.4 mm [values] cool_min_layer_time = 5 @@ -22,4 +23,3 @@ speed_travel = 150 speed_wall = 50 top_bottom_thickness = 0.75 wall_thickness = 0.7 - diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 7bf51b0211..ce41158378 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pla_ultimaker2_plus_0.4_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla +variant = 0.4 mm [values] cool_min_layer_time = 5 @@ -20,4 +21,3 @@ speed_print = 50 speed_topbottom = 20 top_bottom_thickness = 0.72 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 3c6f40e0bc..edfe131ddf 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pla_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla +variant = 0.4 mm [values] cool_min_layer_time = 5 @@ -20,4 +21,3 @@ speed_print = 50 speed_topbottom = 20 top_bottom_thickness = 0.8 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index ef79e30b74..548c7478ba 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -material = generic_pla_ultimaker2_plus_0.6_mm -type = quality -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla +variant = 0.6 mm [values] cool_min_layer_time = 5 @@ -22,4 +23,3 @@ speed_wall = 40 speed_wall_0 = 25 top_bottom_thickness = 1.2 wall_thickness = 1.59 - diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index 42418ea392..a257d3d6f8 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -material = generic_pla_ultimaker2_plus_0.8_mm -type = quality -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pla +variant = 0.8 mm [values] cool_min_layer_time = 5 @@ -20,4 +21,3 @@ speed_print = 40 speed_wall_0 = 25 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 50a4076de2..e448b9d180 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.25_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_abs +variant = 0.25 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.2 @@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 30) speed_print = 30 top_bottom_thickness = 0.72 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index 9d1bcf6ff5..3fd2de3a36 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_abs +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.2 @@ -24,4 +25,3 @@ speed_travel = 150 speed_wall = 40 top_bottom_thickness = 0.75 wall_thickness = 0.7 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 84a5557434..2f119ae86b 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.4_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_abs +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.2 @@ -22,4 +23,3 @@ speed_print = 45 speed_wall = 30 top_bottom_thickness = 0.72 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index efc749ad8c..8416e69dba 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_abs +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.2 @@ -22,4 +23,3 @@ speed_print = 45 speed_wall = 30 top_bottom_thickness = 0.8 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index eb706c5762..393e630299 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.6_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_abs +variant = 0.6 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.5 @@ -22,4 +23,3 @@ speed_layer_0 = =round(speed_print * 30 / 40) speed_print = 40 top_bottom_thickness = 1.2 wall_thickness = 1.59 - diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 2dba5a9304..d0dcbb0908 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_abs_ultimaker2_plus_0.8_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_abs +variant = 0.8 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.5 @@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40) speed_print = 40 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index 8e87e0e7b6..1047b0ca39 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.25_mm -weight = -1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = -1 +material = generic_cpe +variant = 0.25 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.2 @@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 30) speed_print = 30 top_bottom_thickness = 0.72 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index e311df00a8..7beaf2f229 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_cpe +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.8 @@ -23,4 +24,3 @@ speed_travel = 150 speed_wall = 40 top_bottom_thickness = 0.75 wall_thickness = 0.7 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 685b7798fc..efd73655b1 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.4_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_cpe +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.8 @@ -22,4 +23,3 @@ speed_print = 45 speed_wall = 30 top_bottom_thickness = 0.72 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index aadb4195f3..3badb3f191 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_cpe +variant = 0.4 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.8 @@ -22,4 +23,3 @@ speed_print = 45 speed_wall = 30 top_bottom_thickness = 0.8 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index 332033368f..727d68eede 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.6_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_cpe +variant = 0.6 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.8 @@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40) speed_print = 40 top_bottom_thickness = 1.2 wall_thickness = 1.59 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index e4fcae8aa1..1460d69b7a 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_ultimaker2_plus_0.8_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_cpe +variant = 0.8 mm [values] cool_fan_speed_min = =cool_fan_speed * 0.8 @@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40) speed_print = 40 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg index 55af936a89..be33739e72 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.4_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_cpe_plus +variant = 0.4 mm [values] adhesion_type = raft @@ -40,4 +41,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 1.5 wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg index eb0ca5e81f..58cf4bd0e3 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_cpe_plus +variant = 0.4 mm [values] adhesion_type = raft @@ -40,4 +41,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 1.5 wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg index b324d867bc..fe4f895611 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.6_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_cpe_plus +variant = 0.6 mm [values] adhesion_type = raft @@ -44,4 +45,3 @@ support_xy_distance = 0.6 support_z_distance = 0.22 top_bottom_thickness = 0.75 wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg index c8c7576d30..bcc507a3d9 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.6_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_cpe_plus +variant = 0.6 mm [values] adhesion_type = raft @@ -44,4 +45,3 @@ support_xy_distance = 0.6 support_z_distance = 0.22 top_bottom_thickness = 0.75 wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg index 28353f729d..c27d90ead8 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.8_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_cpe_plus +variant = 0.8 mm [values] adhesion_type = raft @@ -39,4 +40,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg index f74db21b91..7eb8b1fd72 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_cpe_plus_ultimaker2_plus_0.8_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_cpe_plus +variant = 0.8 mm [values] adhesion_type = raft @@ -39,4 +40,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg index b8924423e2..33041f89ae 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.25_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_nylon +variant = 0.25 mm [values] adhesion_type = raft @@ -41,4 +42,3 @@ support_xy_distance = 0.6 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg index 323fa51a8d..88974491cb 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.25_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_nylon +variant = 0.25 mm [values] adhesion_type = raft @@ -41,4 +42,3 @@ support_xy_distance = 0.6 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg index 7628cd0be1..832fa12bc9 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_nylon +variant = 0.4 mm [values] adhesion_type = raft @@ -40,4 +41,3 @@ support_xy_distance = 0.6 support_z_distance = =layer_height * 2 top_bottom_thickness = 0.75 wall_thickness = 1.06 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg index a97a4c4e8f..c12573691e 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_nylon +variant = 0.4 mm [values] adhesion_type = raft @@ -39,4 +40,3 @@ support_xy_distance = 0.6 support_z_distance = =layer_height * 2 top_bottom_thickness = 0.75 wall_thickness = 1.06 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg index 0cd7bbdbfd..eaa4f86e23 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.6_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_nylon +variant = 0.6 mm [values] adhesion_type = raft @@ -45,4 +46,3 @@ support_xy_distance = 0.7 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1.2 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg index d5e0025913..5e3db4db22 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.6_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_nylon +variant = 0.6 mm [values] adhesion_type = raft @@ -43,4 +44,3 @@ support_xy_distance = 0.7 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1.2 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg index f653a90f95..38a71c9109 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.8_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_nylon +variant = 0.8 mm [values] adhesion_type = raft @@ -44,4 +45,3 @@ support_xy_distance = 0.75 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 2.4 - diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg index 144c8e74ac..9d20a6d91f 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_nylon_ultimaker2_plus_0.8_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_nylon +variant = 0.8 mm [values] adhesion_type = raft @@ -44,4 +45,3 @@ support_xy_distance = 0.75 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 2.4 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg index d38f2af4d3..7829d7b7b9 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.25_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pc +variant = 0.25 mm [values] adhesion_type = raft @@ -35,4 +36,3 @@ support_infill_rate = 20 support_pattern = lines support_z_distance = 0.19 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg index aa176f67a2..168a308916 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.25_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pc +variant = 0.25 mm [values] adhesion_type = raft @@ -35,4 +36,3 @@ support_infill_rate = 20 support_pattern = lines support_z_distance = 0.19 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg index 0408ead05e..46a349d81f 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pc +variant = 0.4 mm [values] adhesion_type = raft @@ -36,4 +37,3 @@ support_infill_rate = 20 support_pattern = lines support_z_distance = 0.19 wall_thickness = 1.2 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg index ed430f10c0..0c2450f512 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pc +variant = 0.4 mm [values] adhesion_type = raft @@ -36,4 +37,3 @@ support_infill_rate = 20 support_pattern = lines support_z_distance = 0.19 wall_thickness = 1.2 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg index b6c3a66c0b..68528a0209 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.6_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pc +variant = 0.6 mm [values] adhesion_type = raft @@ -42,4 +43,3 @@ support_pattern = lines support_z_distance = 0.21 top_bottom_thickness = 0.75 wall_thickness = 1.06 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg index 0dfb533f56..a92110a149 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.6_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pc +variant = 0.6 mm [values] adhesion_type = raft @@ -42,4 +43,3 @@ support_pattern = lines support_z_distance = 0.21 top_bottom_thickness = 0.75 wall_thickness = 1.06 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg index 3eee23006f..8c8bff3846 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.8_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_pc +variant = 0.8 mm [values] adhesion_type = raft @@ -36,4 +37,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 2.0 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg index 40da82e6bf..db83d5181f 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pc_ultimaker2_plus_0.8_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pc +variant = 0.8 mm [values] adhesion_type = raft @@ -36,4 +37,3 @@ support_pattern = lines support_z_distance = 0.26 top_bottom_thickness = 1.2 wall_thickness = 2.1 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg index 6f4e366209..b7474044f3 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.4_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pp +variant = 0.4 mm [values] acceleration_enabled = True @@ -68,4 +69,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.38 / 0.38, 2) wall_thickness = 0.76 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg index c7224f475f..f6d2c38161 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pp +variant = 0.4 mm [values] acceleration_enabled = True @@ -67,4 +68,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.38 / 0.38, 2) wall_thickness = 0.76 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg index 203db9883e..e2fa538445 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.6_mm -weight = -2 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -2 +material = generic_pp +variant = 0.6 mm [values] acceleration_enabled = True @@ -70,4 +71,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.57 / 0.57, 2) wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg index 64dfbc9281..3cda5e7e63 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.6_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_pp +variant = 0.6 mm [values] acceleration_enabled = True @@ -70,4 +71,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.57 / 0.57, 2) wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index f6d56242dd..402d63f027 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.8_mm -weight = -2 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -2 +material = generic_pp +variant = 0.8 mm [values] acceleration_enabled = True @@ -70,4 +71,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.76 / 0.76, 2) wall_thickness = 1.52 - diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index ecb3e3da4a..2275bd49a7 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker2_plus [metadata] -type = quality -material = generic_pp_ultimaker2_plus_0.8_mm -weight = -3 -quality_type = draft setting_version = 4 +type = quality +quality_type = draft +weight = -3 +material = generic_pp +variant = 0.8 mm [values] acceleration_enabled = True @@ -70,4 +71,3 @@ travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =round(line_width * 0.76 / 0.76, 2) wall_thickness = 1.52 - diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg index b1cb56a543..2ad062bd31 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_tpu_ultimaker2_plus_0.25_mm -weight = 1 -quality_type = high setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_tpu +variant = 0.25 mm [values] adhesion_type = brim @@ -40,4 +41,3 @@ support_xy_distance = 0.6 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 0.88 - diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg index 80cc92fe64..56ce55ee96 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker2_plus [metadata] -type = quality -material = generic_tpu_ultimaker2_plus_0.4_mm -weight = 0 -quality_type = normal setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_tpu +variant = 0.4 mm [values] adhesion_type = brim @@ -37,4 +38,3 @@ support_xy_distance = 0.65 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1.05 - diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg index 9796adada9..6bcc5fa31f 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker2_plus [metadata] -type = quality -material = generic_tpu_ultimaker2_plus_0.6_mm -weight = -1 -quality_type = fast setting_version = 4 +type = quality +quality_type = fast +weight = -1 +material = generic_tpu +variant = 0.6 mm [values] adhesion_type = brim @@ -42,4 +43,3 @@ support_xy_distance = 0.7 support_z_distance = =layer_height * 2 top_bottom_thickness = 1.2 wall_thickness = 1.14 - diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg index fc7d4d12d2..0b100d8717 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_abs +variant = AA 0.25 [values] cool_fan_speed = 40 @@ -20,4 +21,3 @@ prime_tower_wall_thickness = 0.9 retraction_prime_speed = 25 speed_topbottom = =math.ceil(speed_print * 30 / 55) wall_thickness = 0.92 - diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg index 83e0c549c4..77494d6339 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_cpe_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_cpe +variant = AA 0.25 [values] prime_tower_size = 12 @@ -18,4 +19,3 @@ speed_infill = 40 speed_topbottom = =math.ceil(speed_print * 30 / 55) top_bottom_thickness = 0.8 wall_thickness = 0.92 - diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg index 58ddc32101..0187084ff8 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_nylon +variant = AA 0.25 [values] cool_min_layer_time_fan_speed_max = 20 @@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30 switch_extruder_retraction_amount = 30 switch_extruder_retraction_speeds = 40 wall_line_width_x = =wall_line_width - diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index 7c9fa32949..0070419a4e 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_pc +variant = AA 0.25 [values] acceleration_enabled = True @@ -53,4 +54,3 @@ switch_extruder_retraction_speeds = 35 wall_0_inset = 0 wall_line_width_x = =line_width wall_thickness = 1.2 - diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg index 1bee4b8f18..b2347f1902 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_pla +variant = AA 0.25 [values] brim_width = 8 @@ -33,4 +34,3 @@ travel_avoid_distance = 0.4 wall_0_inset = 0.015 wall_0_wipe_dist = 0.25 wall_thickness = 0.7 - diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index ccc558530e..732289dedf 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pp_ultimaker3_AA_0.25 weight = 0 -setting_version = 4 +material = generic_pp +variant = AA 0.25 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg index 13dca72c27..a5cc4aaa0c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_abs_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_abs +variant = AA 0.4 [values] machine_nozzle_cool_down_speed = 0.85 @@ -24,4 +25,3 @@ speed_topbottom = =math.ceil(speed_print * 35 / 60) speed_wall = =math.ceil(speed_print * 45 / 60) speed_wall_0 = =math.ceil(speed_wall * 35 / 45) wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg index 10fa10c726..ba80ad588e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_abs_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_abs +variant = AA 0.4 [values] cool_min_speed = 7 @@ -24,4 +25,3 @@ speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 60) speed_wall = =math.ceil(speed_print * 40 / 60) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 02f2327468..c84ef6dabe 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_abs_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_abs +variant = AA 0.4 [values] cool_min_speed = 12 @@ -23,4 +24,3 @@ speed_print = 50 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 50) speed_wall = =math.ceil(speed_print * 30 / 50) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index fccb6a35f5..f3c9f6a892 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_abs_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_abs +variant = AA 0.4 [values] machine_nozzle_cool_down_speed = 0.85 @@ -21,4 +22,3 @@ speed_print = 55 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 55) speed_wall = =math.ceil(speed_print * 30 / 55) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg index f3c6ae8387..fbc0c599ef 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_bam_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_bam +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg index e027477595..d6f64cb056 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_bam_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_bam +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg index 3ced3a0417..53fb52bff6 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_bam_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_bam +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg index dfdb1ca8a7..dd089294de 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_cpe_plus_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg index 93b371a627..373107d767 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_cpe_plus_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg index 93647f9f44..67544db97b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_cpe_plus_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg index 2886ef2229..183d05ce60 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_cpe_plus_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg index 5e3daf5a9e..74395628af 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_cpe_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_cpe +variant = AA 0.4 [values] material_print_temperature = =default_material_print_temperature + 10 @@ -22,4 +23,3 @@ speed_topbottom = =math.ceil(speed_print * 35 / 60) speed_wall = =math.ceil(speed_print * 45 / 60) speed_wall_0 = =math.ceil(speed_wall * 35 / 45) wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg index e48f83994d..dbcf7f3e42 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_cpe_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_cpe +variant = AA 0.4 [values] cool_min_speed = 7 @@ -21,4 +22,3 @@ speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 60) speed_wall = =math.ceil(speed_print * 40 / 60) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg index fd0a8cd18d..89b5210631 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_cpe_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_cpe +variant = AA 0.4 [values] cool_min_speed = 12 @@ -22,4 +23,3 @@ speed_print = 50 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 50) speed_wall = =math.ceil(speed_print * 30 / 50) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg index 56c997eb15..12927714ec 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_cpe_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_cpe +variant = AA 0.4 [values] machine_nozzle_cool_down_speed = 0.85 @@ -20,4 +21,3 @@ speed_print = 55 speed_layer_0 = 20 speed_topbottom = =math.ceil(speed_print * 30 / 55) speed_wall = =math.ceil(speed_print * 30 / 55) - diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg index 15283a3242..ff938df8f8 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_nylon_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_nylon +variant = AA 0.4 [values] adhesion_type = brim @@ -33,4 +34,3 @@ switch_extruder_prime_speed = 30 switch_extruder_retraction_amount = 30 switch_extruder_retraction_speeds = 40 wall_line_width_x = =wall_line_width - diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg index c063725e82..e9fd6df1e2 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_nylon_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_nylon +variant = AA 0.4 [values] adhesion_type = brim @@ -33,4 +34,3 @@ switch_extruder_prime_speed = 30 switch_extruder_retraction_amount = 30 switch_extruder_retraction_speeds = 40 wall_line_width_x = =wall_line_width - diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg index 218e1e50e1..635cc573ea 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_nylon_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_nylon +variant = AA 0.4 [values] adhesion_type = brim @@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30 switch_extruder_retraction_amount = 30 switch_extruder_retraction_speeds = 40 wall_line_width_x = =wall_line_width - diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg index 3b96939ac9..778ace19e4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_nylon_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_nylon +variant = AA 0.4 [values] adhesion_type = brim @@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30 switch_extruder_retraction_amount = 30 switch_extruder_retraction_speeds = 40 wall_line_width_x = =wall_line_width - diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg index f8b4dd067c..437e4676b3 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pc_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_pc +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg index 1db3935180..320cf0a96f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pc_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_pc +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg index 0f9e9b15b0..6d7e8f7976 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pc_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_pc +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg index 26a3136069..c18e9dbbd5 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pc_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_pc +variant = AA 0.4 [values] acceleration_enabled = True diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg index a32d9268d3..24b7c51fbc 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pla_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_pla +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height @@ -26,4 +27,3 @@ speed_wall = =math.ceil(speed_print * 55 / 70) speed_wall_0 = =math.ceil(speed_wall * 45 / 50) top_bottom_thickness = 1 wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg index 30b7d44d4e..6b3d8642e0 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pla_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_pla +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height @@ -25,4 +26,3 @@ speed_wall = =math.ceil(speed_print * 40 / 80) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) top_bottom_thickness = 1 wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg index da62ce2e3f..6009031e0c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -material = generic_pla_ultimaker3_AA_0.4 weight = 1 -setting_version = 4 +material = generic_pla +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height @@ -27,4 +28,3 @@ speed_topbottom = =math.ceil(speed_print * 30 / 60) speed_wall = =math.ceil(speed_print * 30 / 60) top_bottom_thickness = 1 wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg index 04707735f5..3722134df6 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pla_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_pla +variant = AA 0.4 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height @@ -23,4 +24,3 @@ skin_overlap = 10 speed_layer_0 = 20 top_bottom_thickness = 1 wall_thickness = 1 - diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg index 3fe25e563a..265e068598 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pp_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_pp +variant = AA 0.4 [values] acceleration_enabled = True @@ -63,4 +64,4 @@ switch_extruder_retraction_speeds = 35 travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = =line_width * 3 \ No newline at end of file +wall_thickness = =line_width * 3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg index 4c92c7a14b..7698c0a273 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_pp_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_pp +variant = AA 0.4 [values] acceleration_enabled = True @@ -63,4 +64,4 @@ top_bottom_thickness = 1.1 travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = =line_width * 3 \ No newline at end of file +wall_thickness = =line_width * 3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg index db55956497..897ec993e7 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_pp_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_pp +variant = AA 0.4 [values] acceleration_enabled = True @@ -62,4 +63,4 @@ top_bottom_thickness = 1 travel_avoid_distance = 3 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = =line_width * 3 \ No newline at end of file +wall_thickness = =line_width * 3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg index f6828f88fb..c34415462c 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_tpu_ultimaker3_AA_0.4 weight = -2 -setting_version = 4 +material = generic_tpu +variant = AA 0.4 [values] acceleration_enabled = True @@ -62,4 +63,4 @@ top_bottom_thickness = 0.7 travel_avoid_distance = 1.5 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = 0.76 \ No newline at end of file +wall_thickness = 0.76 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg index 80be26d24c..70a638ee17 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -material = generic_tpu_ultimaker3_AA_0.4 weight = -1 -setting_version = 4 +material = generic_tpu +variant = AA 0.4 [values] acceleration_enabled = True @@ -63,4 +64,4 @@ top_bottom_thickness = 0.7 travel_avoid_distance = 1.5 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = 0.76 \ No newline at end of file +wall_thickness = 0.76 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg index 53044e1805..a92c9c7391 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg @@ -4,11 +4,12 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -material = generic_tpu_ultimaker3_AA_0.4 weight = 0 -setting_version = 4 +material = generic_tpu +variant = AA 0.4 [values] acceleration_enabled = True @@ -60,4 +61,4 @@ top_bottom_thickness = 0.7 travel_avoid_distance = 1.5 wall_0_inset = 0 wall_line_width_x = =line_width -wall_thickness = 0.76 \ No newline at end of file +wall_thickness = 0.76 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg index 7c16e6e8ee..78930b84e2 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_abs_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_abs +variant = AA 0.8 [values] line_width = =machine_nozzle_size * 0.875 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg index 728b4c868f..9470779bd4 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_abs_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_abs +variant = AA 0.8 [values] layer_height = 0.4 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg index 98ae70c568..d28e9b75b6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_abs_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_abs +variant = AA 0.8 [values] layer_height = 0.3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index 0a05e9aafd..6f84174c5a 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_cpe_plus_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.8 [values] brim_width = 14 @@ -35,4 +36,4 @@ support_bottom_distance = =support_z_distance support_line_width = =round(line_width * 0.6 / 0.7, 2) support_z_distance = =layer_height top_bottom_thickness = 1.2 -travel_avoid_distance = 1.5 \ No newline at end of file +travel_avoid_distance = 1.5 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index 82efb6a57b..09e59ee8ca 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_cpe_plus_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.8 [values] brim_width = 14 @@ -36,4 +37,4 @@ support_bottom_distance = =support_z_distance support_line_width = =round(line_width * 0.6 / 0.7, 2) support_z_distance = =layer_height top_bottom_thickness = 1.2 -travel_avoid_distance = 1.5 \ No newline at end of file +travel_avoid_distance = 1.5 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index ff375b6e49..7b7d211c21 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_cpe_plus_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_cpe_plus +variant = AA 0.8 [values] brim_width = 14 @@ -36,4 +37,4 @@ support_bottom_distance = =support_z_distance support_line_width = =round(line_width * 0.6 / 0.7, 2) support_z_distance = =layer_height top_bottom_thickness = 1.2 -travel_avoid_distance = 1.5 \ No newline at end of file +travel_avoid_distance = 1.5 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg index b4d7035b8d..ecce20d9a2 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_cpe_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_cpe +variant = AA 0.8 [values] brim_width = 15 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg index b5ccc38534..a14d4601ee 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_cpe_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_cpe +variant = AA 0.8 [values] brim_width = 15 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg index 33ae223526..7a6cbc7251 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_cpe_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_cpe +variant = AA 0.8 [values] brim_width = 15 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg index 43ec77453c..9254894df3 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_nylon_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_nylon +variant = AA 0.8 [values] brim_width = 5.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg index 5b8626e8c2..f6e2787e65 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_nylon_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_nylon +variant = AA 0.8 [values] brim_width = 5.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg index 0b115ada4b..794ccd006d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_nylon_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_nylon +variant = AA 0.8 [values] brim_width = 5.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index 0b666d2e0b..c0ae3852dc 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pc_ultimaker3_AA_0.8 weight = 0 -setting_version = 4 +material = generic_pc +variant = AA 0.8 [values] brim_width = 14 @@ -28,4 +29,4 @@ speed_topbottom = =math.ceil(speed_print * 25 / 50) speed_wall = =math.ceil(speed_print * 40 / 50) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) support_line_width = =round(line_width * 0.6 / 0.7, 2) -travel_avoid_distance = 3 \ No newline at end of file +travel_avoid_distance = 3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index de212df4af..ca58342847 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pc_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_pc +variant = AA 0.8 [values] brim_width = 14 @@ -28,4 +29,4 @@ speed_topbottom = =math.ceil(speed_print * 25 / 50) speed_wall = =math.ceil(speed_print * 40 / 50) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) support_line_width = =round(line_width * 0.6 / 0.7, 2) -travel_avoid_distance = 3 \ No newline at end of file +travel_avoid_distance = 3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index 3e0c669eeb..6c69aa8ff5 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast - Experimental definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_pc_ultimaker3_AA_0.8 weight = -1 -setting_version = 4 +material = generic_pc +variant = AA 0.8 [values] brim_width = 14 @@ -29,4 +30,4 @@ speed_topbottom = =math.ceil(speed_print * 25 / 50) speed_wall = =math.ceil(speed_print * 40 / 50) speed_wall_0 = =math.ceil(speed_wall * 30 / 40) support_line_width = =round(line_width * 0.6 / 0.7, 2) -travel_avoid_distance = 3 \ No newline at end of file +travel_avoid_distance = 3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg index 8b3c3e56c6..c03cc1ad5f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pla_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_pla +variant = AA 0.8 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg index 2fe8f7c6f9..b1252a3662 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pla_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_pla +variant = AA 0.8 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg index 9072e0c60f..191a7a4b1d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_pla_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_pla +variant = AA 0.8 [values] cool_fan_full_at_height = =layer_height_0 + 2 * layer_height diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg index f46c3cfb8f..fb67666dc7 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_pp_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_pp +variant = AA 0.8 [values] brim_width = 25 @@ -48,4 +49,4 @@ top_bottom_thickness = 1.6 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.8 / 0.8, 2) -wall_thickness = 1.6 \ No newline at end of file +wall_thickness = 1.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg index ac8087d0c4..0fe9eb2bf9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_pp_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_pp +variant = AA 0.8 [values] brim_width = 25 @@ -48,4 +49,4 @@ top_bottom_thickness = 1.6 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.8 / 0.8, 2) -wall_thickness = 1.6 \ No newline at end of file +wall_thickness = 1.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg index daf60f24e6..5ec1311987 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_pp_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_pp +variant = AA 0.8 [values] brim_width = 25 @@ -48,4 +49,4 @@ top_bottom_thickness = 1.6 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.8 / 0.8, 2) -wall_thickness = 1.6 \ No newline at end of file +wall_thickness = 1.6 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg index d5d7479a0e..c2dd5f696d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -material = generic_tpu_ultimaker3_AA_0.8 weight = -2 -setting_version = 4 +material = generic_tpu +variant = AA 0.8 [values] brim_width = 8.75 @@ -60,4 +61,4 @@ travel_avoid_distance = 1.5 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.6 / 0.8, 2) -wall_thickness = 1.3 \ No newline at end of file +wall_thickness = 1.3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg index 86c6a3df77..b4efb6158d 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -material = generic_tpu_ultimaker3_AA_0.8 weight = -4 -setting_version = 4 +material = generic_tpu +variant = AA 0.8 [values] brim_width = 8.75 @@ -61,4 +62,4 @@ travel_avoid_distance = 1.5 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.6 / 0.8, 2) -wall_thickness = 1.3 \ No newline at end of file +wall_thickness = 1.3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg index 8af3edcddd..4d2a18cd71 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -4,11 +4,12 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -material = generic_tpu_ultimaker3_AA_0.8 weight = -3 -setting_version = 4 +material = generic_tpu +variant = AA 0.8 [values] brim_width = 8.75 @@ -60,4 +61,4 @@ travel_avoid_distance = 1.5 travel_compensate_overlapping_walls_0_enabled = False wall_0_wipe_dist = =line_width * 2 wall_line_width_x = =round(line_width * 0.6 / 0.8, 2) -wall_thickness = 1.3 \ No newline at end of file +wall_thickness = 1.3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg index c87f744932..eacdaccffe 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg @@ -4,14 +4,15 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_pva_ultimaker3_BB_0.4 -setting_version = 4 +material = generic_pva +variant = BB 0.4 [values] material_print_temperature = =default_material_print_temperature + 10 material_standby_temperature = 100 prime_tower_enable = False -skin_overlap = 20 \ No newline at end of file +skin_overlap = 20 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg index 23fa6d61d8..c6ddd85181 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg @@ -4,15 +4,16 @@ name = Normal definition = ultimaker3 [metadata] -weight = -1 +setting_version = 4 type = quality quality_type = fast -material = generic_pva_ultimaker3_BB_0.4 -setting_version = 4 +weight = -1 +material = generic_pva +variant = BB 0.4 [values] material_print_temperature = =default_material_print_temperature + 5 material_standby_temperature = 100 prime_tower_enable = False skin_overlap = 15 -support_infill_sparse_thickness = 0.3 \ No newline at end of file +support_infill_sparse_thickness = 0.3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg index 3ba82d65c6..0b1d0f9f8d 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg @@ -4,13 +4,14 @@ name = Extra Fine definition = ultimaker3 [metadata] -weight = 1 +setting_version = 4 type = quality quality_type = high -material = generic_pva_ultimaker3_BB_0.4 -setting_version = 4 +weight = 1 +material = generic_pva +variant = BB 0.4 [values] material_standby_temperature = 100 prime_tower_enable = False -support_infill_sparse_thickness = 0.18 \ No newline at end of file +support_infill_sparse_thickness = 0.18 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg index a709d5613b..9980e2b31c 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg @@ -4,12 +4,13 @@ name = Fine definition = ultimaker3 [metadata] -weight = 0 +setting_version = 4 type = quality quality_type = normal -material = generic_pva_ultimaker3_BB_0.4 -setting_version = 4 +weight = 0 +material = generic_pva +variant = BB 0.4 [values] material_standby_temperature = 100 -prime_tower_enable = False \ No newline at end of file +prime_tower_enable = False diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg index 4cb296b4c7..edc960cc8c 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg @@ -4,12 +4,13 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_pva_ultimaker3_BB_0.8 -setting_version = 4 +material = generic_pva +variant = BB 0.8 [values] material_print_temperature = =default_material_print_temperature + 5 -material_standby_temperature = 100 \ No newline at end of file +material_standby_temperature = 100 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg index 5249517844..6fb66dab14 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -4,13 +4,14 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft weight = -4 -material = generic_pva_ultimaker3_BB_0.8 -setting_version = 4 +material = generic_pva +variant = BB 0.8 [values] layer_height = 0.4 material_standby_temperature = 100 -support_interface_height = 0.9 \ No newline at end of file +support_interface_height = 0.9 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg index c34e19b134..12288919fe 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -4,14 +4,15 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft weight = -3 -material = generic_pva_ultimaker3_BB_0.8 -setting_version = 4 +material = generic_pva +variant = BB 0.8 [values] layer_height = 0.3 material_standby_temperature = 100 support_infill_sparse_thickness = 0.3 -support_interface_height = 1.2 \ No newline at end of file +support_interface_height = 1.2 diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg index b56775a987..9f13bbd3c2 100644 --- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = draft -global_quality = True weight = -2 -setting_version = 4 +global_quality = True [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg index 12f1183364..073ae82a07 100644 --- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = fast -global_quality = True weight = -1 -setting_version = 4 +global_quality = True [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index cf6e6c45e0..1daff86c49 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = high -global_quality = True weight = 0 -setting_version = 4 +global_quality = True [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg index fef2328923..91c5bab8b7 100644 --- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Fine definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = normal -global_quality = True weight = 0 -setting_version = 4 +global_quality = True [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg index be9acd4394..da39b065d5 100644 --- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Sprint definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = superdraft -global_quality = True weight = -4 -setting_version = 4 +global_quality = True [values] layer_height = 0.4 diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg index e2c828fc2d..11e8315a7b 100644 --- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extra Fast definition = ultimaker3 [metadata] +setting_version = 4 type = quality quality_type = verydraft -global_quality = True weight = -3 -setting_version = 4 +global_quality = True [values] layer_height = 0.3 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg index 2c42bd82b6..50a1ef3415 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extreme definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = extreme -material = Vertex_Delta_ABS weight = 2 -setting_version = 4 +material = Vertex_Delta_ABS [values] layer_height = 0.05 @@ -19,4 +19,4 @@ material_initial_print_temperature = 250 material_print_temperature = 250 retraction_amount = 3 material_standby_temperature = 225 -cool_fan_speed = 0 \ No newline at end of file +cool_fan_speed = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg index a770131adb..e650f11afd 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = high -material = Vertex_Delta_ABS weight = 1 -setting_version = 4 +material = Vertex_Delta_ABS [values] layer_height = 0.1 @@ -19,4 +19,4 @@ material_initial_print_temperature = 250 material_print_temperature = 250 retraction_amount = 3 material_standby_temperature = 225 -cool_fan_speed = 0 \ No newline at end of file +cool_fan_speed = 0 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg index 7c7e635149..aa962190ce 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = normal -material = Vertex_Delta_ABS weight = 0 -setting_version = 4 +material = Vertex_Delta_ABS [values] layer_height = 0.2 @@ -19,4 +19,4 @@ material_initial_print_temperature = 250 material_print_temperature = 250 retraction_amount = 3 material_standby_temperature = 225 -cool_fan_speed = 00 \ No newline at end of file +cool_fan_speed = 00 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg index 836d900247..29a4170adf 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extreme definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = extreme -material = Vertex_Delta_PET weight = 2 -setting_version = 4 +material = Vertex_Delta_PET [values] layer_height = 0.05 @@ -19,4 +19,4 @@ material_initial_print_temperature = 240 material_print_temperature = 240 retraction_amount = 3 material_standby_temperature = 215 -cool_fan_speed = 10 \ No newline at end of file +cool_fan_speed = 10 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg index b0cae312b2..fc92590da1 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = high -material = Vertex_Delta_PET weight = 1 -setting_version = 4 +material = Vertex_Delta_PET [values] layer_height = 0.1 @@ -19,4 +19,4 @@ material_initial_print_temperature = 240 material_print_temperature = 240 retraction_amount = 3 material_standby_temperature = 215 -cool_fan_speed = 10 \ No newline at end of file +cool_fan_speed = 10 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg index ebec26d04a..b02bfa5178 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = normal -material = Vertex_Delta_PET weight = 0 -setting_version = 4 +material = Vertex_Delta_PET [values] layer_height = 0.2 @@ -19,4 +19,4 @@ material_initial_print_temperature = 240 material_print_temperature = 240 retraction_amount = 3 material_standby_temperature = 215 -cool_fan_speed = 10 \ No newline at end of file +cool_fan_speed = 10 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg index 13ad6455c9..3cdad7a06f 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extreme definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = extreme -material = Vertex_Delta_PLA weight = 2 -setting_version = 4 +material = Vertex_Delta_PLA [values] layer_height = 0.05 @@ -19,4 +19,4 @@ material_initial_print_temperature = 200 material_print_temperature = 200 retraction_amount = 3 material_standby_temperature = 175 -cool_fan_speed = 40 \ No newline at end of file +cool_fan_speed = 40 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg index e8c7e893cb..192750ef71 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = high -material = Vertex_Delta_PLA weight = 1 -setting_version = 4 +material = Vertex_Delta_PLA [values] layer_height = 0.1 @@ -19,4 +19,4 @@ material_initial_print_temperature = 200 material_print_temperature = 200 retraction_amount = 3 material_standby_temperature = 175 -cool_fan_speed = 40 \ No newline at end of file +cool_fan_speed = 40 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg index 27002caea2..1e519734bb 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = normal -material = Vertex_Delta_PLA weight = 0 -setting_version = 4 +material = Vertex_Delta_PLA [values] layer_height = 0.2 @@ -19,4 +19,4 @@ material_initial_print_temperature = 200 material_print_temperature = 200 retraction_amount = 3 material_standby_temperature = 175 -cool_fan_speed = 40 \ No newline at end of file +cool_fan_speed = 40 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg index 8a0a01fb0b..9da37f2148 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Extreme definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = extreme -material = Vertex_Delta_TPU weight = 2 -setting_version = 4 +material = Vertex_Delta_TPU [values] layer_height = 0.05 @@ -19,4 +19,4 @@ material_initial_print_temperature = 220 material_print_temperature = 220 retraction_amount = 3 material_standby_temperature = 195 -cool_fan_speed = 20 \ No newline at end of file +cool_fan_speed = 20 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg index 7e23947f39..f5583d32b9 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg @@ -4,11 +4,11 @@ name = High definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = high -material = Vertex_Delta_TPU weight = 1 -setting_version = 4 +material = Vertex_Delta_TPU [values] layer_height = 0.1 @@ -19,4 +19,4 @@ material_initial_print_temperature = 220 material_print_temperature = 220 retraction_amount = 3 material_standby_temperature = 195 -cool_fan_speed = 20 \ No newline at end of file +cool_fan_speed = 20 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg index 5fb46e1ea6..a520eb2473 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg @@ -4,11 +4,11 @@ name = Normal definition = vertex_delta_k8800 [metadata] +setting_version = 4 type = quality quality_type = normal -material = Vertex_Delta_TPU weight = 0 -setting_version = 4 +material = Vertex_Delta_TPU [values] layer_height = 0.2 From 8ac9811b41301ccec1eb0678e6530439a027bd6a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Feb 2018 09:29:30 +0100 Subject: [PATCH 006/266] WIP: Create QualityManager --- cura/CuraApplication.py | 11 +- cura/Machines/ContainerGroup.py | 10 + cura/Machines/QualityManager.py | 358 ++++++++++++++++++++++ cura/Settings/MachineManager.py | 8 +- cura/Settings/ProfilesModel.py | 56 ++++ resources/definitions/ultimaker3.def.json | 1 + resources/qml/Menus/ProfileMenu.qml | 13 +- 7 files changed, 450 insertions(+), 7 deletions(-) create mode 100644 cura/Machines/ContainerGroup.py create mode 100644 cura/Machines/QualityManager.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7812024422..82a112f56f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -52,7 +52,8 @@ from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyT from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator -from cura.Settings.ProfilesModel import ProfilesModel +from cura.Settings.NozzleModel import NozzleModel +from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager @@ -60,6 +61,7 @@ from cura.Settings.UserProfilesModel import UserProfilesModel from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Machines.VariantManager import VariantManager +from cura.Machines.QualityManager import QualityGroup from . import PlatformPhysics @@ -738,6 +740,10 @@ class CuraApplication(QtApplication): self._material_manager = MaterialManager(container_registry) self._material_manager.initialize() + from cura.Machines.QualityManager import QualityManager + self._quality_manager = QualityManager(container_registry) + self._quality_manager.initialize() + # Check if we should run as single instance or not self._setUpSingleInstanceServer() @@ -922,6 +928,9 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") + qmlRegisterType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel") + qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") + qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel") diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py new file mode 100644 index 0000000000..5c34f0f123 --- /dev/null +++ b/cura/Machines/ContainerGroup.py @@ -0,0 +1,10 @@ +from PyQt5.Qt import QObject + +from cura.Machines.ContainerNode import ContainerNode + + +class ContainerGroup(QObject): + def __init__(self, parent = None): + super().__init__(parent) + self.node_for_global = None # type: ContainerNode + self.nodes_for_extruders = dict() diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py new file mode 100644 index 0000000000..43556dbb4a --- /dev/null +++ b/cura/Machines/QualityManager.py @@ -0,0 +1,358 @@ +from typing import Optional + +from PyQt5.Qt import pyqtSignal, QObject + +from UM.Application import Application +from UM.Logger import Logger +from UM.Settings.InstanceContainer import InstanceContainer +from UM.Util import parseBool + +from cura.Machines.ContainerGroup import ContainerGroup +from cura.Machines.ContainerNode import ContainerNode + + +# +# Quality lookup tree structure: +# +# ------| +# | | +# +# | +# +# | +# +# | +# +# + +# + + +class QualityChangesGroup: + __slots__ = ("name", "qc_for_global", "qc_for_extruders_dict") + + def __init__(self, name: str): + self.name = name # type: str + self.qc_for_global = None # type: Optional["QualityNode"] + self.qc_for_extruders_dict = dict() # -> QualityNode + + def addMetadata(self, metadata: dict): + extruder_id = metadata.get("extruder") + if extruder_id is not None: + self.qc_for_extruders_dict[extruder_id] = QualityNode(metadata) + else: + self.qc_for_global = QualityNode(metadata) + + def getContainerForGlobalStack(self) -> "InstanceContainer": + return self.qc_for_global.getContainer() + + def getContainerForExtruderStack(self, extruder_definition_id: str) -> Optional["InstanceContainer"]: + qc_node = self.qc_for_extruders_dict.get(extruder_definition_id) + container = None + if qc_node is not None: + container = qc_node.getContainer() + return container + + +class QualityGroup(ContainerGroup): + + def __init__(self, name, quality_type, parent = None): + super().__init__(parent) + self.name = name + self.quality_type = quality_type + self.is_available = False + + +class QualityNode(ContainerNode): + __slots__ = ("metadata", "container", "quality_type_map", "children_map") + + def __init__(self, metadata = None): + super().__init__(metadata = metadata) + self.quality_type_map = {} + + + def addQualityMetadata(self, quality_type: str, metadata: dict): + if quality_type not in self.quality_type_map: + self.quality_type_map[quality_type] = QualityNode(metadata) + + def getQualityNode(self, quality_type: str): + return self.quality_type_map.get(quality_type) + + def addQualityChangesMetadata(self, quality_type: str, metadata: dict): + if quality_type not in self.quality_type_map: + self.quality_type_map[quality_type] = QualityNode() + quality_type_node = self.quality_type_map[quality_type] + + name = metadata["name"] + if name not in quality_type_node.children_map: + quality_type_node.children_map[name] = QualityChangesGroup(name) + qc_group = quality_type_node.children_map[name] + qc_group.addMetadata(metadata) + + +class QualityManager(QObject): + + def __init__(self, container_registry, parent = None): + super().__init__(parent) + + self._material_manager = Application.getInstance()._material_manager + + self._container_registry = container_registry + self._empty_quality_container = self._container_registry.findInstanceContainers(id = "empty_quality")[0] + #self._empty_quality_changes_container = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] + + self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup + self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup + + self._default_machine_definition_id = "fdmprinter" + + def initialize(self): + # Initialize the lookup tree for quality profiles with following structure: + # -> -> + # -> + quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality") + for metadata in quality_metadata_list: + if metadata["id"] == "empty_quality": + continue + + definition_id = metadata["definition"] + quality_type = metadata["quality_type"] + + root_material_id = metadata.get("material") + variant_name = metadata.get("variant") + is_global_quality = metadata.get("global_quality", False) + is_global_quality = is_global_quality or (root_material_id is None and variant_name is None) + + # Sanity check: material+variant and is_global_quality cannot be present at the same time + if is_global_quality and (root_material_id or variant_name): + raise RuntimeError("Quality profile [%s] contains invalid data: it is a global quality but contains 'material' and 'nozzle' info." % metadata["id"]) + + if definition_id not in self._machine_variant_material_quality_type_to_quality_dict: + self._machine_variant_material_quality_type_to_quality_dict[definition_id] = QualityNode() + machine_node = self._machine_variant_material_quality_type_to_quality_dict[definition_id] + + if is_global_quality: + # For global qualities, save data in the machine node + machine_node.addQualityMetadata(quality_type, metadata) + continue + + if variant_name is not None: + # If variant_name is specified in the quality/quality_changes profile, check if material is specified, + # too. + if variant_name not in machine_node.children_map: + machine_node.children_map[variant_name] = QualityNode() + variant_node = machine_node.children_map[variant_name] + + if root_material_id is None: + # If only variant_name is specified but material is not, add the quality/quality_changes metadata + # into the current variant node. + variant_node.addQualityMetadata(quality_type, metadata) + else: + # If only variant_name and material are both specified, go one level deeper: create a material node + # under the current variant node, and then add the quality/quality_changes metadata into the + # material node. + if root_material_id not in variant_node.children_map: + variant_node.children_map[root_material_id] = QualityNode() + material_node = variant_node.children_map[root_material_id] + + material_node.addQualityMetadata(quality_type, metadata) + + else: + # If variant_name is not specified, check if material is specified. + if root_material_id is not None: + if root_material_id not in machine_node.children_map: + machine_node.children_map[root_material_id] = QualityNode() + material_node = machine_node.children_map[root_material_id] + + material_node.addQualityMetadata(quality_type, metadata) + + # Initialize the lookup tree for quality_changes profiles with following structure: + # -> -> + quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes") + for metadata in quality_changes_metadata_list: + if metadata["id"] == "empty_quality_changes": + continue + + machine_definition_id = metadata["definition"] + quality_type = metadata["quality_type"] + + if machine_definition_id not in self._machine_quality_type_to_quality_changes_dict: + self._machine_quality_type_to_quality_changes_dict[machine_definition_id] = QualityNode() + machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id] + + machine_node.addQualityChangesMetadata(quality_type, metadata) + + def getQualityGroups(self, machine: "GlobalStack") -> dict: + # TODO: How to make this simpler, including the fallbacks. + # Get machine definition ID + machine_definition_id = self._default_machine_definition_id + if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): + machine_definition_id = machine.getMetaDataEntry("quality_definition") + if machine_definition_id is None: + machine_definition_id = machine.definition.getId() + + machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) + if not machine_node: + Logger.log("e", "Cannot find node for machine def [%s] in quality lookup table", machine_definition_id) + + # iterate over all quality_types in the machine node + quality_group_dict = {} + for quality_type, quality_node in machine_node.quality_type_map.items(): + quality_group = QualityGroup(quality_node.metadata["name"], quality_type) + quality_group.node_for_global = quality_node + + quality_group_dict[quality_type] = quality_group + + # Iterate over all extruders + for position, extruder in machine.extruders.items(): + variant_name = None + if extruder.variant.getId() != "empty_variant": + variant_name = extruder.variant.getName() + + # This is a list of root material IDs to use for searching for suitable quality profiles. + # The root material IDs in this list are in prioritized order. + root_material_id_list = [] + has_material = False # flag indicating whether this extruder has a material assigned + if extruder.material.getId() != "empty_material": + has_material = True + root_material_id = extruder.material.getMetaDataEntry("base_file") + root_material_id_list.append(root_material_id) + + # Also try to get the fallback material + material_type = extruder.material.getMetaDataEntry("material") + fallback_root_material_metadata = self._material_manager.getFallbackMaterialForType(material_type) + if fallback_root_material_metadata: + root_material_id_list.append(fallback_root_material_metadata["id"]) + + variant_node = None + material_node = None + + if variant_name: + # In this case, we have both a specific variant and a specific material + variant_node = machine_node.getChildNode(variant_name) + if not variant_node: + continue + if has_material: + for root_material_id in root_material_id_list: + material_node = variant_node.getChildNode(root_material_id) + if material_node: + break + if not material_node: + # No suitable quality found: not supported + Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", + machine_definition_id, variant_name, ", ".join(root_material_id_list)) + continue + else: + # In this case, we only have a specific material but NOT a variant + if has_material: + for root_material_id in root_material_id_list: + material_node = machine_node.getChildNode(root_material_id) + if material_node: + break + if not material_node: + # No suitable quality found: not supported + Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", + machine_definition_id, variant_name, ", ".join(root_material_id_list)) + continue + + node_to_check = material_node + if not node_to_check: + node_to_check = variant_node + if not node_to_check: + node_to_check = machine_node + + for quality_type, quality_node in node_to_check.quality_type_map.items(): + if quality_type not in quality_group_dict: + quality_group = QualityGroup(quality_node.metadata["name"], quality_type) + quality_group_dict[quality_type] = quality_group + + quality_group = quality_group_dict[quality_type] + + quality_group.nodes_for_extruders[position] = quality_node + + used_extruders = set() + # TODO: This will change after the Machine refactoring + for i in range(machine.getProperty("machine_extruder_count", "value")): + used_extruders.add(str(i)) + + # Update the "is_available" flag for each quality group. + for quality_group in quality_group_dict.values(): + is_available = True + if quality_group.node_for_global is None: + is_available = False + if is_available: + for position in used_extruders: + if position not in quality_group.nodes_for_extruders: + is_available = False + break + + quality_group.is_available = is_available + + return quality_group_dict + + + def getQuality(self, quality_type: str, machine: "GlobalStack"): + # Get machine definition ID + machine_definition_id = self._default_machine_definition_id + if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): + machine_definition_id = machine.getMetaDataEntry("quality_definition") + if machine_definition_id is None: + machine_definition_id = machine.definition.getId() + + machine_quality = self.getQualityContainer(quality_type, machine_definition_id) + extruder_quality_dict = {} + for position, extruder in machine.extruders.items(): + variant = extruder.variant + material = extruder.material + + variant_name = variant.getName() + if variant.getId() == "empty_variant": + variant_name = None + root_material_id = material.getMetaDataEntry("base_file") + if material.getId() == "empty_material": + root_material_id = None + + extruder_quality = self.getQualityContainer(quality_type, machine_definition_id, + variant_name, root_material_id) + extruder_quality_dict[position] = extruder_quality + + # TODO: return as a group + return machine_quality, extruder_quality_dict + + def getQualityContainer(self, quality_type: str, machine_definition_id: dict, + variant_name: Optional[str] = None, + root_material_id: Optional[str] = None) -> "InstanceContainer": + assert machine_definition_id is not None + assert quality_type is not None + + # If the specified quality cannot be found, empty_quality will be returned. + container = self._empty_quality_container + + machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) + variant_node = None + material_node = None + if machine_node is not None: + if variant_name is not None: + variant_node = machine_node.getChildNode(variant_name) + if variant_node is not None: + if root_material_id is not None: + material_node = variant_node.getChildNode(root_material_id) + elif root_material_id is not None: + material_node = machine_node.getChildNode(root_material_id) + + nodes_to_try = [material_node, variant_node, machine_node] + if machine_definition_id != self._default_machine_definition_id: + default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id) + nodes_to_try.append(default_machine_node) + + for node in nodes_to_try: + if node is None: + continue + quality_node = node.getQualityNode(quality_type) + if quality_node is None: + continue + + container = quality_node.getContainer() + break + + return container + diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1fa4a602bc..f0305751d4 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1509,12 +1509,12 @@ class MachineManager(QObject): self._global_container_stack.extruders[position].variant = container_node.getContainer() @pyqtSlot("QVariant") - def handleQualityGroup(self, quality_group): - Logger.log("d", "---------------- qg = [%s]", quality_group.name) + def handleQualityGroup(self, qg): + Logger.log("d", "---------------- qg = [%s]", qg.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self._global_container_stack.quality = quality_group.node_for_global.getContainer() + self._global_container_stack.quality = qg.node_for_global.getContainer() self._global_container_stack.qualityChanges = self._empty_quality_changes_container - for position, node in quality_group.nodes_for_extruders.items(): + for position, node in qg.nodes_for_extruders.items(): self._global_container_stack.extruders[position].quality = node.getContainer() self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 77cd407457..719a406406 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -18,6 +18,62 @@ if TYPE_CHECKING: from cura.Settings.ExtruderStack import ExtruderStack +from UM.Qt.ListModel import ListModel + + +class NewQualityProfilesModel(ListModel): + IdRole = Qt.UserRole + 1 + NameRole = Qt.UserRole + 2 + QualityTypeRole = Qt.UserRole + 3 + LayerHeightRole = Qt.UserRole + 4 + AvailableRole = Qt.UserRole + 5 + QualityGroupRole = Qt.UserRole + 6 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.QualityTypeRole, "quality_type") + self.addRoleName(self.LayerHeightRole, "layer_height") + self.addRoleName(self.AvailableRole, "available") + self.addRoleName(self.QualityGroupRole, "quality_group") + + # TODO: connect signals + Application.getInstance().globalContainerStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) + Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) + + def _update(self): + # TODO: get all available qualities + self.items.clear() + + quality_manager = Application.getInstance()._quality_manager + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + return + + quality_group_dict = quality_manager.getQualityGroups(active_global_stack) + + item_list = [] + + for key in sorted(quality_group_dict): + quality_group = quality_group_dict[key] + + item = {"id": "TODO", + "name": quality_group.name, + "layer_height": "TODO", + "available": quality_group.is_available, + "quality_group": quality_group} + + item_list.append(item) + + self.setItems(item_list) + + + ## QML Model for listing the current list of valid quality profiles. # class ProfilesModel(InstanceContainersModel): diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 826960a621..74e4a9551e 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -17,6 +17,7 @@ "has_variants": true, "preferred_variant": "*aa04*", "preferred_quality": "*Normal*", + "preferred_quality_type": "fine", "variants_name": "Print core", "machine_extruder_trains": { diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index f543bb36eb..bde60a3dde 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -11,9 +11,15 @@ Menu { id: menu + // TODO: single instance + Cura.NewQualityProfilesModel + { + id: qualityProfilesModel + } + Instantiator { - model: Cura.ProfilesModel + model: qualityProfilesModel MenuItem { @@ -21,7 +27,10 @@ Menu checkable: true checked: Cura.MachineManager.activeQualityId == model.id exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveQuality(model.id) + onTriggered: { + Cura.MachineManager.handleQualityGroup(model.quality_group) + //Cura.MachineManager.setActiveQuality(model.id) + } visible: model.available } From 0f045ce1213859bd50861aed6cfd733c614f68dd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 8 Feb 2018 16:28:26 +0100 Subject: [PATCH 007/266] WIP: TO BE REMOVED: TestTools plugin --- plugins/TestTools/TestTool.py | 27 +++++++++++++++++++++++++++ plugins/TestTools/__init__.py | 13 +++++++++++++ plugins/TestTools/plugin.json | 7 +++++++ 3 files changed, 47 insertions(+) create mode 100644 plugins/TestTools/TestTool.py create mode 100644 plugins/TestTools/__init__.py create mode 100644 plugins/TestTools/plugin.json diff --git a/plugins/TestTools/TestTool.py b/plugins/TestTools/TestTool.py new file mode 100644 index 0000000000..3c852e5997 --- /dev/null +++ b/plugins/TestTools/TestTool.py @@ -0,0 +1,27 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. +from UM.Extension import Extension + +from PyQt5.QtCore import QObject + + +class TestTool(Extension, QObject): + def __init__(self, parent = None): + QObject.__init__(self, parent) + Extension.__init__(self) + + self.addMenuItem("Test material manager", self._testMaterialManager) + self.addMenuItem("Test get quality", self._testGetQuality) + + def _testMaterialManager(self): + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + from cura.CuraApplication import CuraApplication + CuraApplication.getInstance()._material_manager._test_metadata() + + def _testGetQuality(self): + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + from cura.CuraApplication import CuraApplication + result_dict = {} + global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack + result = CuraApplication.getInstance()._quality_manager.getQualityGroups(global_stack) + diff --git a/plugins/TestTools/__init__.py b/plugins/TestTools/__init__.py new file mode 100644 index 0000000000..7d41651404 --- /dev/null +++ b/plugins/TestTools/__init__.py @@ -0,0 +1,13 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from . import TestTool + +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + +def getMetaData(): + return {} + +def register(app): + return {"extension": TestTool.TestTool()} diff --git a/plugins/TestTools/plugin.json b/plugins/TestTools/plugin.json new file mode 100644 index 0000000000..846e39bf09 --- /dev/null +++ b/plugins/TestTools/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "Test Tools", + "author": "Ultimaker", + "version": "1.0", + "description": "Dump the contents of all settings to a HTML file.", + "api": 4 +} \ No newline at end of file From e65adc72580472ad3b8ec18403654ca7934e4bc2 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 13 Feb 2018 16:46:47 +0100 Subject: [PATCH 008/266] WIP: New setMaterial/Variant/Quality in MachineManager --- cura/Settings/MachineManager.py | 103 +++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 8 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f0305751d4..000fb93e0e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -132,6 +132,9 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) + ### new + self._current_quality_group = None + globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() @@ -1500,21 +1503,105 @@ class MachineManager(QObject): return [ s.containersChanged for s in stacks ] # New + def _setEmptyQuality(self): + self._current_quality_group = None + self._global_container_stack.quality = self._empty_quality_container + self._global_container_stack.qualityChanges = self._empty_quality_changes_container + for extruder in self._global_container_stack.extruders.values(): + extruder.quality = self._empty_quality_container + extruder.qualityChanges = self._empty_quality_changes_container + + def _setQualityGroup(self, quality_group, empty_quality_changes = True): + self._current_quality_group = quality_group + self._global_container_stack.quality = quality_group.node_for_global.getContainer() + if empty_quality_changes: + self._global_container_stack.qualityChanges = self._empty_quality_changes_container + for position, node in quality_group.nodes_for_extruders.items(): + self._global_container_stack.extruders[position].quality = node.getContainer() + if empty_quality_changes: + self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container + + def _setVariantGroup(self, position, container_node): + self._global_container_stack.extruders[position].variant = container_node.getContainer() + + def _setMaterial(self, position, container_node = None): + if container_node: + self._global_container_stack.extruders[position].material = container_node.getContainer() + else: + self._global_container_stack.extruders[position].material = self._empty_material_container + + ## Update current quality type and machine after setting material + def _updateQualityWithMaterial(self): + current_quality = None + if self._current_quality_group: + current_quality = self._current_quality_group.quality_type + quality_manager = Application.getInstance()._quality_manager + candidate_quality_groups = quality_manager.getQualityGroups(self._global_container_stack) + available_quality_types = {qt for qt, g in candidate_quality_groups.items() if g.is_available} + + if not available_quality_types: + self._setEmptyQuality() + return + + if current_quality in available_quality_types: + self._setQualityGroup(candidate_quality_groups[current_quality], empty_quality_changes = False) + return + + quality_type = sorted(list(available_quality_types))[0] + preferred_quality_type = self._global_container_stack.getMetaDataEntry("preferred_quality_type") + if preferred_quality_type in available_quality_types: + quality_type = preferred_quality_type + + self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = False) + + def _updateMaterialWithVariant(self, position, current_material_base_name, current_variant_name): + material_manager = Application.getInstance()._material_manager + material_diameter = self._global_container_stack.getProperty("material_diameter", "value") + candidate_materials = material_manager.getAvailableMaterials( + self._global_container_stack.getId(), + current_variant_name, + material_diameter) + + if not candidate_materials: + self._setMaterial(position, container_node = None) + return + + if current_material_base_name in candidate_materials: + new_material = candidate_materials[current_material_base_name] + self._setMaterial(position, new_material) + return + + # # Find a fallback material + # preferred_material_query = self._global_container_stack.getMetaDataEntry("preferred_material") + # preferred_material_key = preferred_material_query.replace("*", "") + # if preferred_material_key in candidate_materials: + # self._setMaterial(position, candidate_materials[preferred_material_key]) + # return + + @pyqtSlot(str, "QVariant") + def setMaterial(self, position, container_node): + Logger.log("d", "---------------- container = [%s]", container_node) + position = str(position) + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setMaterial(position, container_node) + self._updateQualityWithMaterial() + @pyqtSlot(str, "QVariant") def setVariantGroup(self, position, container_node): Logger.log("d", "---------------- container = [%s]", container_node) position = str(position) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self._global_container_stack.extruders[position].variant = container_node.getContainer() + self._setVariantGroup(position, container_node) + current_variant_name = container_node.metadata["name"] + current_material_base_name = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") + self._updateMaterialWithVariant(position, current_material_base_name, current_variant_name) + self._updateQualityWithMaterial() @pyqtSlot("QVariant") - def handleQualityGroup(self, qg): - Logger.log("d", "---------------- qg = [%s]", qg.name) + def handleQualityGroup(self, quality_group): + Logger.log("d", "---------------- qg = [%s]", quality_group.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self._global_container_stack.quality = qg.node_for_global.getContainer() - self._global_container_stack.qualityChanges = self._empty_quality_changes_container - for position, node in qg.nodes_for_extruders.items(): - self._global_container_stack.extruders[position].quality = node.getContainer() - self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container + self._setQualityGroup(quality_group) From d99bacb2d2ebe586ed1e7a2f6c68d22b4b5656cd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Feb 2018 21:13:44 +0100 Subject: [PATCH 009/266] WIP: Create ContainerNode and ContainerGroup --- cura/Machines/ContainerGroup.py | 5 ++++- cura/Machines/ContainerNode.py | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index 5c34f0f123..1061abadda 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -1,10 +1,13 @@ +from typing import Optional + from PyQt5.Qt import QObject from cura.Machines.ContainerNode import ContainerNode class ContainerGroup(QObject): + def __init__(self, parent = None): super().__init__(parent) - self.node_for_global = None # type: ContainerNode + self.node_for_global = None # type: Optional[ContainerNode] self.nodes_for_extruders = dict() diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py index b9ebaa698a..059bccba0d 100644 --- a/cura/Machines/ContainerNode.py +++ b/cura/Machines/ContainerNode.py @@ -3,25 +3,37 @@ from typing import Optional from collections import OrderedDict from UM.Logger import Logger +from UM.Settings.InstanceContainer import InstanceContainer -## A metadata / container combination. Use getContainer to get the container corresponding to the metadata +## +# A metadata / container combination. Use getContainer() to get the container corresponding to the metadata. +# +# ContainerNode is a multi-purpose class. It has two main purposes: +# 1. It encapsulates an InstanceContainer. It contains that InstanceContainer's +# - metadata (Always) +# - container (lazy-loaded when needed) +# 2. It also serves as a node in a hierarchical InstanceContainer lookup table/tree. +# This is used in Variant, Material, and Quality Managers. +# class ContainerNode: - def __init__(self, metadata = None): + __slots__ = ("metadata", "container", "children_map") + + def __init__(self, metadata: Optional[dict] = None): self.metadata = metadata self.container = None self.children_map = OrderedDict() - def getChildNode(self, child_key: str) -> Optional["QualityNode"]: + def getChildNode(self, child_key: str) -> Optional["ContainerNode"]: return self.children_map.get(child_key) def getContainer(self) -> "InstanceContainer": if self.metadata is None: - raise RuntimeError("Cannot get container for a QualityNode without metadata") + raise RuntimeError("Cannot get container for a ContainerNode without metadata") if self.container is None: container_id = self.metadata["id"] - Logger.log("d", "Lazy-loading container [%s]", container_id) + Logger.log("i", "Lazy-loading container [%s]", container_id) from UM.Settings.ContainerRegistry import ContainerRegistry container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id) if not container_list: @@ -30,5 +42,5 @@ class ContainerNode: return self.container - def __str__(self): + def __str__(self) -> str: return "ContainerNode[%s]" % self.metadata.get("id") From 8f8de0454f2e5cf6d6697e045f7d5ad5da8ceab9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Feb 2018 21:34:23 +0100 Subject: [PATCH 010/266] WIP: Cleanup the current MachineManager --- cura/Settings/MachineManager.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 000fb93e0e..a2be0e0e27 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -652,25 +652,6 @@ class MachineManager(QObject): return 0 # No quality profile. - ## Get the Material ID associated with the currently active material - # \returns MaterialID (string) if found, empty string otherwise - @pyqtProperty(str, notify=activeQualityChanged) - def activeQualityMaterialId(self) -> str: - if self._active_container_stack: - quality = self._active_container_stack.quality - if quality: - material_id = quality.getMetaDataEntry("material") - if material_id: - # if the currently active machine inherits its qualities from a different machine - # definition, make sure to return a material that is relevant to that machine definition - definition_id = self.activeDefinitionId - quality_definition_id = self.activeQualityDefinitionId - if definition_id != quality_definition_id: - material_id = material_id.replace(definition_id, quality_definition_id, 1) - - return material_id - return "" - @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self) -> str: if self._active_container_stack and self._global_container_stack: From cd53ae06390db7e7da853c77bcedecd0dbadb1cd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Feb 2018 21:33:43 +0100 Subject: [PATCH 011/266] WIP: Refactor ProfileMenu.qml --- cura/CuraApplication.py | 9 ++++- cura/Machines/ContainerGroup.py | 9 ++++- cura/Machines/QualityManager.py | 5 +-- cura/Settings/MachineManager.py | 20 +++++++++- cura/Settings/ProfilesModel.py | 59 +++++++++++++++++++++-------- resources/qml/Menus/ProfileMenu.qml | 36 +++--------------- 6 files changed, 83 insertions(+), 55 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 82a112f56f..9a74cde13f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -388,6 +388,8 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize + self._new_quality_profile_model = None + CuraApplication.Created = True @pyqtSlot(str, result = str) @@ -896,6 +898,11 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information + def getNewQualityProfileModel(self, *args, **kwargs): + if self._new_quality_profile_model is None: + self._new_quality_profile_model = NewQualityProfilesModel(self) + return self._new_quality_profile_model + ## Registers objects for the QML engine to use. # # \param engine The QML engine. @@ -928,7 +935,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") - qmlRegisterType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel") + qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index 1061abadda..3b17a0ae60 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -1,13 +1,18 @@ from typing import Optional -from PyQt5.Qt import QObject +from PyQt5.Qt import QObject, pyqtSlot from cura.Machines.ContainerNode import ContainerNode class ContainerGroup(QObject): - def __init__(self, parent = None): + def __init__(self, name: str, parent = None): super().__init__(parent) + self.name = name self.node_for_global = None # type: Optional[ContainerNode] self.nodes_for_extruders = dict() + + @pyqtSlot(result = str) + def getName(self) -> str: + return self.name diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 43556dbb4a..7d998361b1 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -55,9 +55,8 @@ class QualityChangesGroup: class QualityGroup(ContainerGroup): - def __init__(self, name, quality_type, parent = None): - super().__init__(parent) - self.name = name + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(name, parent) self.quality_type = quality_type self.is_available = False diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a2be0e0e27..aeec747fa5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -46,6 +46,7 @@ if TYPE_CHECKING: class MachineManager(QObject): + def __init__(self, parent = None): super().__init__(parent) @@ -132,9 +133,13 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - ### new + ### NEW self._current_quality_group = None + ### NEW + activeQualityGroupChanged = pyqtSignal() + + globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() @@ -1494,14 +1499,20 @@ class MachineManager(QObject): def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group + + # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: self._global_container_stack.qualityChanges = self._empty_quality_changes_container + + # Set quality and quality_changes for each ExtruderStack for position, node in quality_group.nodes_for_extruders.items(): self._global_container_stack.extruders[position].quality = node.getContainer() if empty_quality_changes: self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container + self.activeQualityGroupChanged.emit() + def _setVariantGroup(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() @@ -1581,8 +1592,13 @@ class MachineManager(QObject): self._updateQualityWithMaterial() @pyqtSlot("QVariant") - def handleQualityGroup(self, quality_group): + def setQualityGroup(self, quality_group): Logger.log("d", "---------------- qg = [%s]", quality_group.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) + + @pyqtProperty("QVariant", fset = setQualityGroup, notify = activeQualityGroupChanged) + def activeQualityGroup(self): + return self._current_quality_group + diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 719a406406..fd508f247a 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -2,25 +2,24 @@ # Cura is released under the terms of the LGPLv3 or higher. from collections import OrderedDict +from typing import List, TYPE_CHECKING from PyQt5.QtCore import Qt from UM.Application import Application +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel from cura.QualityManager import QualityManager from cura.Settings.ExtruderManager import ExtruderManager - -from typing import List, TYPE_CHECKING +from cura.Machines.QualityManager import QualityGroup if TYPE_CHECKING: from cura.Settings.ExtruderStack import ExtruderStack -from UM.Qt.ListModel import ListModel - - class NewQualityProfilesModel(ListModel): IdRole = Qt.UserRole + 1 NameRole = Qt.UserRole + 2 @@ -39,32 +38,35 @@ class NewQualityProfilesModel(ListModel): self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.QualityGroupRole, "quality_group") - # TODO: connect signals + # connect signals Application.getInstance().globalContainerStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) - Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) + Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) + + self._quality_manager = Application.getInstance()._quality_manager + + self._layer_height_unit = "" # This is cached def _update(self): - # TODO: get all available qualities - self.items.clear() + Logger.log("d", "Updating quality profile model ...") - quality_manager = Application.getInstance()._quality_manager active_global_stack = Application.getInstance().getMachineManager()._global_container_stack if active_global_stack is None: self.setItems([]) + Logger.log("d", "No active GlobalStack, set quality profile model as empty.") return - quality_group_dict = quality_manager.getQualityGroups(active_global_stack) + quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) item_list = [] - for key in sorted(quality_group_dict): quality_group = quality_group_dict[key] - item = {"id": "TODO", + layer_height = self._fetchLayerHeight(quality_group) + + item = {"id": "TODO", # TODO: probably will be removed "name": quality_group.name, - "layer_height": "TODO", + "layer_height": layer_height + self._layer_height_unit, + "layer_height_without_unit": layer_height, "available": quality_group.is_available, "quality_group": quality_group} @@ -72,6 +74,31 @@ class NewQualityProfilesModel(ListModel): self.setItems(item_list) + def _fetchLayerHeight(self, quality_group: "QualityGroup"): + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if not self._layer_height_unit: + unit = active_global_stack.definition.getProperty("layer_height", "unit") + if not unit: + unit = "" + self._layer_height_unit = unit + + if not quality_group.is_available: + return "" + + # Get layer_height from the quality profile for the GlobalStack + container = quality_group.node_for_global.getContainer() + + layer_height = "" + if container.hasProperty("layer_height", "value"): + layer_height = str(container.getProperty("layer_height", "value")) + else: + # Look for layer_height in the GlobalStack from material -> definition + for idx in range(4): + container = active_global_stack.getContainer(idx) + if container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") + break + return str(layer_height) ## QML Model for listing the current list of valid quality profiles. diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index bde60a3dde..9013216e32 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2016 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -11,25 +11,18 @@ Menu { id: menu - // TODO: single instance - Cura.NewQualityProfilesModel - { - id: qualityProfilesModel - } - Instantiator { - model: qualityProfilesModel + model: Cura.NewQualityProfilesModel MenuItem { text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.activeQualityGroup.getName() == model.name exclusiveGroup: group onTriggered: { - Cura.MachineManager.handleQualityGroup(model.quality_group) - //Cura.MachineManager.setActiveQuality(model.id) + Cura.MachineManager.setQualityGroup(model.quality_group) } visible: model.available } @@ -82,23 +75,4 @@ Menu MenuItem { action: Cura.Actions.resetProfile } MenuSeparator { } MenuItem { action: Cura.Actions.manageProfiles } - - function getFilter(initial_conditions) - { - var result = initial_conditions; - - if(Cura.MachineManager.filterQualityByMachine) - { - result.definition = Cura.MachineManager.activeQualityDefinitionId; - if(Cura.MachineManager.hasMaterials) - { - result.material = Cura.MachineManager.activeQualityMaterialId; - } - } - else - { - result.definition = "fdmprinter" - } - return result - } } From 54363bad025072822488ae6bfb708a8b91e8112e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 13 Feb 2018 22:37:43 +0100 Subject: [PATCH 012/266] WIP: Refactor NozzleMenu.qml --- cura/Settings/MachineManager.py | 6 ++-- resources/qml/Menus/NozzleMenu.qml | 45 ++---------------------------- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index aeec747fa5..d4ca2e7d47 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1168,11 +1168,11 @@ class MachineManager(QObject): return "" @pyqtProperty(str, notify = activeVariantChanged) - def activeVariantId(self) -> str: + def activeVariantName(self) -> str: if self._active_container_stack: variant = self._active_container_stack.variant if variant: - return variant.getId() + return variant.getName() return "" @@ -1488,7 +1488,9 @@ class MachineManager(QObject): stacks.append(self._global_container_stack) return [ s.containersChanged for s in stacks ] + # # New + # def _setEmptyQuality(self): self._current_quality_group = None self._global_container_stack.quality = self._empty_quality_container diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 6d554218a1..27082cfb4b 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -16,20 +16,19 @@ Menu property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 property bool isClusterPrinter: { - if(Cura.MachineManager.printerOutputDevices.length == 0) + if (Cura.MachineManager.printerOutputDevices.length == 0) { return false; } var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize; // This is not a cluster printer or the cluster it is just one printer - if(clusterSize == undefined || clusterSize == 1) + if (clusterSize == undefined || clusterSize == 1) { return false; } return true; } - // TODO: single instance?? Cura.NozzleModel { id: nozzleModel @@ -43,55 +42,17 @@ Menu { text: model.hotend_name checkable: true - checked: Cura.MachineManager.activeVariantId == model.hotend_name + checked: Cura.MachineManager.activeVariantName == model.hotend_name exclusiveGroup: group onTriggered: { var position = Cura.ExtruderManager.activeExtruderIndex; Cura.MachineManager.setVariantGroup(position, model.container_node); } - visible: true } onObjectAdded: menu.insertItem(index, object); onObjectRemoved: menu.removeItem(object); } - /* - Instantiator - { - id: nozzleInstantiator - model: UM.InstanceContainersModel - { - filter: - { - var filter_dict = - { - "type": "variant", - "definition": Cura.MachineManager.activeQualityDefinitionId //Only show variants of this machine - } - if (Cura.MachineManager.hasVariantBuildplates) - { - filter_dict["hardware_type"] = "nozzle" - } - - return filter_dict - } - } - MenuItem { - text: model.name - checkable: true - checked: model.id == Cura.MachineManager.allActiveVariantIds[Cura.ExtruderManager.extruderIds[extruderIndex]] - exclusiveGroup: group - onTriggered: - { - var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveVariant(model.id); - Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); - } - } - onObjectAdded: menu.insertItem(index, object) - onObjectRemoved: menu.removeItem(object) - } */ ExclusiveGroup { id: group } } From 27169e883cdc557f3c6ca1876fd546af4144db66 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 14 Feb 2018 10:34:56 +0100 Subject: [PATCH 013/266] CURA-4606 Ensure the correct material is highlighted in the material menu --- cura/Machines/MaterialManager.py | 3 +- cura/Settings/MachineManager.py | 18 ++++++++- resources/qml/Menus/MaterialMenu.qml | 59 +--------------------------- 3 files changed, 20 insertions(+), 60 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 596da50fb2..b65e01487c 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -4,7 +4,6 @@ from PyQt5.Qt import QTimer, QObject, pyqtSignal from UM.Logger import Logger from UM.Settings import ContainerRegistry -from UM.Settings import InstanceContainer from cura.Machines.ContainerNode import ContainerNode @@ -227,7 +226,7 @@ class MaterialManager(QObject): # 1. the given machine doesn't have materials; # 2. cannot find any material InstanceContainers with the given settings. # - def getMaterial(self, machine_definition_id: str, variant_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]: + def getMaterialNode(self, machine_definition_id: str, variant_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]: # round the diameter to get the approximate diameter rounded_diameter = str(round(diameter)) if rounded_diameter not in self._diameter_machine_variant_material_map: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index d4ca2e7d47..bb2f8cbd79 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -135,11 +135,11 @@ class MachineManager(QObject): ### NEW self._current_quality_group = None + self._current_root_material_id = {} ### NEW activeQualityGroupChanged = pyqtSignal() - globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() activeVariantChanged = pyqtSignal() @@ -155,6 +155,8 @@ class MachineManager(QObject): outputDevicesChanged = pyqtSignal() + rootMaterialChanged = pyqtSignal() + def _onOutputDevicesChanged(self) -> None: for printer_output_device in self._printer_output_devices: printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged) @@ -1491,6 +1493,15 @@ class MachineManager(QObject): # # New # + + @pyqtProperty("QVariant", notify = rootMaterialChanged) + def currentRootMaterialId(self): + # initial filling the current_root_material_id + for position in self._global_container_stack.extruders: + if position not in self._current_root_material_id: + self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") + return self._current_root_material_id + def _setEmptyQuality(self): self._current_quality_group = None self._global_container_stack.quality = self._empty_quality_container @@ -1523,6 +1534,11 @@ class MachineManager(QObject): self._global_container_stack.extruders[position].material = container_node.getContainer() else: self._global_container_stack.extruders[position].material = self._empty_material_container + # The _current_root_material_id is used in the MaterialMenu to see which material is selected + root_material_id = container_node.metadata["base_file"] + if root_material_id != self._current_root_material_id[position]: + self._current_root_material_id[position] = root_material_id + self.rootMaterialChanged.emit() ## Update current quality type and machine after setting material def _updateQualityWithMaterial(self): diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index 111e5ab6af..cb4ee5eefb 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -14,48 +14,6 @@ Menu property int extruderIndex: 0 property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 - property bool isClusterPrinter: - { - if(Cura.MachineManager.printerOutputDevices.length == 0) - { - return false; - } - var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize; - // This is not a cluster printer or the cluster it is just one printer - if(clusterSize == undefined || clusterSize == 1) - { - return false; - } - return true; - } - - MenuItem - { - id: automaticMaterial - text: - { - if(visible) - { - var materialName = Cura.MachineManager.printerOutputDevices[0].materialNames[extruderIndex]; - return catalog.i18nc("@title:menuitem %1 is the automatically selected material", "Automatic: %1").arg(materialName); - } - return ""; - } - visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames != undefined && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex && !isClusterPrinter - onTriggered: - { - var materialId = Cura.MachineManager.printerOutputDevices[0].materialIds[extruderIndex]; - var items = materialsModel.items; - for(var i in items) - { - if (items[i]["metadata"]["GUID"] == materialId) - { - Cura.MachineManager.setActiveMaterial(items[i].id); - break; - } - } - } - } MenuSeparator { @@ -69,19 +27,11 @@ Menu { text: model.name checkable: true - checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]] + checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[Cura.ExtruderManager.activeExtruderIndex] exclusiveGroup: group onTriggered: { - - const container_id = model.id; - // This workaround is done because of the application menus for materials and variants for multiextrusion printers. - // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. - var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - //Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - //Cura.MachineManager.setActiveMaterial(container_id); - //Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node); } } @@ -120,13 +70,8 @@ Menu exclusiveGroup: group onTriggered: { - const container_id = model.id; - // This workaround is done because of the application menus for materials and variants for multiextrusion printers. - // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); - Cura.MachineManager.setActiveMaterial(container_id); - Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); + Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node); } } onObjectAdded: brandMaterialsMenu.insertItem(index, object) From d84ea07e9efe54ce90be2524803fa5a2d753f81d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 09:31:42 +0100 Subject: [PATCH 014/266] WIP: add getQaulityChangesGroup() --- cura/Machines/ContainerNode.py | 2 +- cura/Machines/QualityManager.py | 147 ++++++++++++++++++++++---------- plugins/TestTools/TestTool.py | 14 ++- 3 files changed, 113 insertions(+), 50 deletions(-) diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py index 059bccba0d..4d8d663284 100644 --- a/cura/Machines/ContainerNode.py +++ b/cura/Machines/ContainerNode.py @@ -43,4 +43,4 @@ class ContainerNode: return self.container def __str__(self) -> str: - return "ContainerNode[%s]" % self.metadata.get("id") + return "%s[%s]" % (self.__class__.__name__, self.metadata.get("id")) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 7d998361b1..0e9bf99bd4 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -27,30 +27,48 @@ from cura.Machines.ContainerNode import ContainerNode # -class QualityChangesGroup: - __slots__ = ("name", "qc_for_global", "qc_for_extruders_dict") +class QualityChangesGroup(ContainerGroup): - def __init__(self, name: str): - self.name = name # type: str - self.qc_for_global = None # type: Optional["QualityNode"] - self.qc_for_extruders_dict = dict() # -> QualityNode + def __init__(self, name: str, parent = None): + super().__init__(name, parent) + + def addNode(self, node: "QualityNode"): + # TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the + # extruder definition ID it belongs to. But, in fact, we only need to know the following things: + # 1. which machine a custom profile is suitable for, + # 2. if this profile is for the GlobalStack, + # 3. if this profile is for an ExtruderStack and which one (the position). + # + # So, it is preferred to have a field like this: + # extruder_position = 1 + # instead of this: + # extruder = custom_extruder_1 + # + # An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition + # to figure out its position. + # + extruder_definition_id = node.metadata.get("extruder") + if extruder_definition_id: + container_registry = Application.getInstance().getContainerRegistry() + metadata_list = container_registry.findDefinitionContainersMetadata(id = extruder_definition_id) + if not metadata_list: + raise RuntimeError("%s cannot get metadata for extruder definition [%s]" % + (self, extruder_definition_id)) + extruder_definition_metadata = metadata_list[0] + extruder_position = str(extruder_definition_metadata["position"]) + + if extruder_position in self.nodes_for_extruders: + raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" % + (self, extruder_position, self.node_for_global, node)) + + self.nodes_for_extruders[extruder_position] = node - def addMetadata(self, metadata: dict): - extruder_id = metadata.get("extruder") - if extruder_id is not None: - self.qc_for_extruders_dict[extruder_id] = QualityNode(metadata) else: - self.qc_for_global = QualityNode(metadata) - - def getContainerForGlobalStack(self) -> "InstanceContainer": - return self.qc_for_global.getContainer() - - def getContainerForExtruderStack(self, extruder_definition_id: str) -> Optional["InstanceContainer"]: - qc_node = self.qc_for_extruders_dict.get(extruder_definition_id) - container = None - if qc_node is not None: - container = qc_node.getContainer() - return container + # This is a quality_changes for the GlobalStack + if self.node_for_global is not None: + raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" % + (self, self.node_for_global, node)) + self.node_for_global = node class QualityGroup(ContainerGroup): @@ -60,20 +78,20 @@ class QualityGroup(ContainerGroup): self.quality_type = quality_type self.is_available = False - +# +# QualityNode is used for BOTH quality and quality_changes containers. +# class QualityNode(ContainerNode): - __slots__ = ("metadata", "container", "quality_type_map", "children_map") - def __init__(self, metadata = None): + def __init__(self, metadata: Optional[dict] = None): super().__init__(metadata = metadata) - self.quality_type_map = {} - + self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer def addQualityMetadata(self, quality_type: str, metadata: dict): if quality_type not in self.quality_type_map: self.quality_type_map[quality_type] = QualityNode(metadata) - def getQualityNode(self, quality_type: str): + def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]: return self.quality_type_map.get(quality_type) def addQualityChangesMetadata(self, quality_type: str, metadata: dict): @@ -84,8 +102,8 @@ class QualityNode(ContainerNode): name = metadata["name"] if name not in quality_type_node.children_map: quality_type_node.children_map[name] = QualityChangesGroup(name) - qc_group = quality_type_node.children_map[name] - qc_group.addMetadata(metadata) + quality_changes_group = quality_type_node.children_map[name] + quality_changes_group.addNode(QualityNode(metadata)) class QualityManager(QObject): @@ -164,6 +182,11 @@ class QualityManager(QObject): material_node.addQualityMetadata(quality_type, metadata) + # Initialize quality + self._initializeQualityChangesTables() + + + def _initializeQualityChangesTables(self): # Initialize the lookup tree for quality_changes profiles with following structure: # -> -> quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes") @@ -180,6 +203,51 @@ class QualityManager(QObject): machine_node.addQualityChangesMetadata(quality_type, metadata) + # Updates the given quality groups' availabilities according to which extruders are being used/ enabled. + def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list): + used_extruders = set() + # TODO: This will change after the Machine refactoring + for i in range(machine.getProperty("machine_extruder_count", "value")): + used_extruders.add(str(i)) + + # Update the "is_available" flag for each quality group. + for quality_group in quality_group_list: + is_available = True + if quality_group.node_for_global is None: + is_available = False + if is_available: + for position in used_extruders: + if position not in quality_group.nodes_for_extruders: + is_available = False + break + + quality_group.is_available = is_available + + # Returns a dict of "custom profile name" -> QualityChangesGroup + def getQualityChangesGroup(self, machine: "GlobalStack") -> dict: + # TODO: How to make this simpler? + # Get machine definition ID + machine_definition_id = self._default_machine_definition_id + if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): + machine_definition_id = machine.getMetaDataEntry("quality_definition") + if machine_definition_id is None: + machine_definition_id = machine.definition.getId() + + machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) + if not machine_node: + raise RuntimeError("Cannot find node for machine def [%s] in QualityChanges lookup table" % machine_definition_id) + + # iterate over all quality_types in the machine node + quality_changes_group_dict = dict() + for quality_type, quality_changes_node in machine_node.quality_type_map.items(): + for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items(): + quality_changes_group_dict[quality_changes_name] = quality_changes_group + + # Update availabilities for each quality group + self._updateQualityGroupsAvailability(machine, quality_changes_group_dict.values()) + + return quality_changes_group_dict + def getQualityGroups(self, machine: "GlobalStack") -> dict: # TODO: How to make this simpler, including the fallbacks. # Get machine definition ID @@ -191,7 +259,7 @@ class QualityManager(QObject): machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) if not machine_node: - Logger.log("e", "Cannot find node for machine def [%s] in quality lookup table", machine_definition_id) + raise RuntimeError("Cannot find node for machine def [%s] in Quality lookup table" % machine_definition_id) # iterate over all quality_types in the machine node quality_group_dict = {} @@ -268,23 +336,8 @@ class QualityManager(QObject): quality_group.nodes_for_extruders[position] = quality_node - used_extruders = set() - # TODO: This will change after the Machine refactoring - for i in range(machine.getProperty("machine_extruder_count", "value")): - used_extruders.add(str(i)) - - # Update the "is_available" flag for each quality group. - for quality_group in quality_group_dict.values(): - is_available = True - if quality_group.node_for_global is None: - is_available = False - if is_available: - for position in used_extruders: - if position not in quality_group.nodes_for_extruders: - is_available = False - break - - quality_group.is_available = is_available + # Update availabilities for each quality group + self._updateQualityGroupsAvailability(machine, quality_group_dict.values()) return quality_group_dict diff --git a/plugins/TestTools/TestTool.py b/plugins/TestTools/TestTool.py index 3c852e5997..e2312e578f 100644 --- a/plugins/TestTools/TestTool.py +++ b/plugins/TestTools/TestTool.py @@ -1,5 +1,5 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the AGPLv3 or higher. +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv2 or higher. from UM.Extension import Extension from PyQt5.QtCore import QObject @@ -12,6 +12,7 @@ class TestTool(Extension, QObject): self.addMenuItem("Test material manager", self._testMaterialManager) self.addMenuItem("Test get quality", self._testGetQuality) + self.addMenuItem("Test get quality changes", self.testGetQualityChanges) def _testMaterialManager(self): print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") @@ -24,4 +25,13 @@ class TestTool(Extension, QObject): result_dict = {} global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack result = CuraApplication.getInstance()._quality_manager.getQualityGroups(global_stack) + print("!!!!!!!!!!!!!!!!!!!") + def testGetQualityChanges(self): + print("!!!!!!!!!!!!!!!!!!!") + + from cura.CuraApplication import CuraApplication + result_dict = {} + global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack + result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroup(global_stack) + print("!!!!!!!!!!!!!!!!!!!") From bf2317a74d09707e24f88d74864ecdde9dfb96c8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 10:47:30 +0100 Subject: [PATCH 015/266] WIP: use new QualityChangesGroups --- cura/CuraApplication.py | 9 +++++++- cura/Machines/QualityManager.py | 35 +++++++++++++++++------------ cura/Settings/MachineManager.py | 29 +++++++++++++++++++++++- cura/Settings/ProfilesModel.py | 29 ++++++++++++++++++++++++ plugins/TestTools/TestTool.py | 5 +++-- resources/qml/Menus/ProfileMenu.qml | 13 ++++++----- 6 files changed, 97 insertions(+), 23 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9a74cde13f..44d4761321 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -53,7 +53,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Settings.NozzleModel import NozzleModel -from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel +from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager @@ -389,6 +389,7 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize self._new_quality_profile_model = None + self._new_custom_quality_profile_model = None CuraApplication.Created = True @@ -903,6 +904,11 @@ class CuraApplication(QtApplication): self._new_quality_profile_model = NewQualityProfilesModel(self) return self._new_quality_profile_model + def getNewCustomQualityProfilesModel(self, *args, **kwargs): + if self._new_custom_quality_profile_model is None: + self._new_custom_quality_profile_model = NewCustomQualityProfilesModel(self) + return self._new_custom_quality_profile_model + ## Registers objects for the QML engine to use. # # \param engine The QML engine. @@ -936,6 +942,7 @@ class CuraApplication(QtApplication): qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) + qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 0e9bf99bd4..1c7f82550a 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -27,10 +27,18 @@ from cura.Machines.ContainerNode import ContainerNode # -class QualityChangesGroup(ContainerGroup): +class QualityGroup(ContainerGroup): - def __init__(self, name: str, parent = None): + def __init__(self, name: str, quality_type: str, parent = None): super().__init__(name, parent) + self.quality_type = quality_type + self.is_available = False + + +class QualityChangesGroup(QualityGroup): + + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(name, quality_type, parent) def addNode(self, node: "QualityNode"): # TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the @@ -70,13 +78,9 @@ class QualityChangesGroup(ContainerGroup): (self, self.node_for_global, node)) self.node_for_global = node + def __str__(self) -> str: + return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available) -class QualityGroup(ContainerGroup): - - def __init__(self, name: str, quality_type: str, parent = None): - super().__init__(name, parent) - self.quality_type = quality_type - self.is_available = False # # QualityNode is used for BOTH quality and quality_changes containers. @@ -101,7 +105,7 @@ class QualityNode(ContainerNode): name = metadata["name"] if name not in quality_type_node.children_map: - quality_type_node.children_map[name] = QualityChangesGroup(name) + quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type) quality_changes_group = quality_type_node.children_map[name] quality_changes_group.addNode(QualityNode(metadata)) @@ -224,7 +228,7 @@ class QualityManager(QObject): quality_group.is_available = is_available # Returns a dict of "custom profile name" -> QualityChangesGroup - def getQualityChangesGroup(self, machine: "GlobalStack") -> dict: + def getQualityChangesGroups(self, machine: "GlobalStack") -> dict: # TODO: How to make this simpler? # Get machine definition ID machine_definition_id = self._default_machine_definition_id @@ -237,14 +241,17 @@ class QualityManager(QObject): if not machine_node: raise RuntimeError("Cannot find node for machine def [%s] in QualityChanges lookup table" % machine_definition_id) - # iterate over all quality_types in the machine node + # Update availability for each QualityChangesGroup: + # A custom profile is always available as long as the quality_type it's based on is available + quality_group_dict = self.getQualityGroups(machine) + available_quality_type_list = [qt for qt, qg in quality_group_dict.items() if qg.is_available] + + # Iterate over all quality_types in the machine node quality_changes_group_dict = dict() for quality_type, quality_changes_node in machine_node.quality_type_map.items(): for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items(): quality_changes_group_dict[quality_changes_name] = quality_changes_group - - # Update availabilities for each quality group - self._updateQualityGroupsAvailability(machine, quality_changes_group_dict.values()) + quality_changes_group.is_available = quality_type in available_quality_type_list return quality_changes_group_dict diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index bb2f8cbd79..3b37afd328 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -134,11 +134,13 @@ class MachineManager(QObject): containers[0].nameChanged.connect(self._onMaterialNameChanged) ### NEW - self._current_quality_group = None self._current_root_material_id = {} + self._current_quality_group = None + self._current_quality_changes_group = None ### NEW activeQualityGroupChanged = pyqtSignal() + activeQualityChangesGroupChanged = pyqtSignal() globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() @@ -1502,6 +1504,27 @@ class MachineManager(QObject): self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") return self._current_root_material_id + def _setQualityChangesGroup(self, quality_changes_group): + self._current_quality_changes_group = quality_changes_group + + # TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time. + # Can we do this better, like caching the quality group a quality_changes group depends on? + quality_manager = Application.getInstance()._quality_manager + quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack) + + quality_type = quality_changes_group.quality_type + + container = self._empty_quality_changes_container + if quality_changes_group.node_for_global is not None: + container = quality_changes_group.node_for_global.getContainer() + self._global_container_stack.qualityChanges = container + self._global_container_stack.quality = quality_group_dict[quality_type] + + for position, extruder in self._global_container_stack.extruders.items(): + container = quality_changes_group.nodes_for_extruders.get(position, + self._empty_quality_changes_container) + extruder.qualityChanges = container + def _setEmptyQuality(self): self._current_quality_group = None self._global_container_stack.quality = self._empty_quality_container @@ -1510,9 +1533,13 @@ class MachineManager(QObject): extruder.quality = self._empty_quality_container extruder.qualityChanges = self._empty_quality_changes_container + self.activeQualityGroupChanged.emit() + def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group + #TODO: check quality_changes + # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index fd508f247a..b05bc46dd5 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -101,6 +101,35 @@ class NewQualityProfilesModel(ListModel): return str(layer_height) +class NewCustomQualityProfilesModel(NewQualityProfilesModel): + + def _update(self): + Logger.log("d", "Updating %s ...", self.__class__.__name__) + + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) + return + + quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack) + + item_list = [] + for key in sorted(quality_changes_group_dict): + quality_changes_group = quality_changes_group_dict[key] + + item = {"id": "TODO", # TODO: probably will be removed + "name": quality_changes_group.name, + "layer_height": "", + "layer_height_without_unit": "", + "available": quality_changes_group.is_available, + "quality_changes_group": quality_changes_group} + + item_list.append(item) + + self.setItems(item_list) + + ## QML Model for listing the current list of valid quality profiles. # class ProfilesModel(InstanceContainersModel): diff --git a/plugins/TestTools/TestTool.py b/plugins/TestTools/TestTool.py index e2312e578f..a8812c21ba 100644 --- a/plugins/TestTools/TestTool.py +++ b/plugins/TestTools/TestTool.py @@ -33,5 +33,6 @@ class TestTool(Extension, QObject): from cura.CuraApplication import CuraApplication result_dict = {} global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack - result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroup(global_stack) - print("!!!!!!!!!!!!!!!!!!!") + result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroups(global_stack) + for name, r in result.items(): + print("!!!!!!!!!! [%s] - %s" % (name, r)) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 9013216e32..f212d82b6e 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -40,18 +40,21 @@ Menu Instantiator { id: customProfileInstantiator - model: Cura.UserProfilesModel + model: Cura.NewCustomQualityProfilesModel + + Connections { - onModelReset: customSeparator.visible = rowCount() > 0 + target: Cura.NewCustomQualityProfilesModel + onModelReset: customSeparator.visible = Cura.NewCustomQualityProfilesModel.rowCount() > 0 } MenuItem { text: model.name - checkable: true - checked: Cura.MachineManager.activeQualityChangesId == model.id + checkable: model.available + checked: Cura.MachineManager.activeQualityChangesId == model.id // TODO: fix for new exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveQuality(model.id) + onTriggered: Cura.MachineManager.setActiveQuality(model.id) // TODO: fix for new } onObjectAdded: From 8aab8f4394368d851fb1f6412a51666dd2f4cf9a Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 14 Feb 2018 11:12:21 +0100 Subject: [PATCH 016/266] CURA-4606 cleanup and optimization for replaceContainer --- cura/Machines/QualityManager.py | 3 ++- cura/Settings/CuraContainerStack.py | 4 ++++ cura/Settings/MachineManager.py | 1 + resources/qml/Menus/MaterialMenu.qml | 6 ------ resources/qml/Menus/NozzleMenu.qml | 15 --------------- resources/qml/Menus/ProfileMenu.qml | 2 +- 6 files changed, 8 insertions(+), 23 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 1c7f82550a..a719a7df8c 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -239,7 +239,8 @@ class QualityManager(QObject): machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) if not machine_node: - raise RuntimeError("Cannot find node for machine def [%s] in QualityChanges lookup table" % machine_definition_id) + Logger.log("e", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id) + return {} # Update availability for each QualityChangesGroup: # A custom profile is always available as long as the quality_type it's based on is available diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index b97bb3314e..93e4b55bba 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -348,6 +348,10 @@ class CuraContainerStack(ContainerStack): elif container != self._empty_instance_container and container.getMetaDataEntry("type") != expected_type: raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type.".format(index = index, type = expected_type, actual_type = container.getMetaDataEntry("type"))) + current_container = self._containers[index] + if current_container.getId() == container.getId(): + return + super().replaceContainer(index, container, postpone_emit) ## Overridden from ContainerStack diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3b37afd328..15bb388f26 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1642,6 +1642,7 @@ class MachineManager(QObject): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) + Logger.log("d", "Quality set!") @pyqtProperty("QVariant", fset = setQualityGroup, notify = activeQualityGroupChanged) def activeQualityGroup(self): diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index cb4ee5eefb..e77ab2861a 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -13,12 +13,6 @@ Menu title: "Material" property int extruderIndex: 0 - property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 - - MenuSeparator - { - visible: automaticMaterial.visible - } Instantiator { diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 27082cfb4b..8cb01fcde6 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -13,21 +13,6 @@ Menu title: "Nozzle" property int extruderIndex: 0 - property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 - property bool isClusterPrinter: - { - if (Cura.MachineManager.printerOutputDevices.length == 0) - { - return false; - } - var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize; - // This is not a cluster printer or the cluster it is just one printer - if (clusterSize == undefined || clusterSize == 1) - { - return false; - } - return true; - } Cura.NozzleModel { diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index f212d82b6e..6005ce9805 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -19,7 +19,7 @@ Menu { text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name checkable: true - checked: Cura.MachineManager.activeQualityGroup.getName() == model.name + checked: Cura.MachineManager.activeQualityGroup && (Cura.MachineManager.activeQualityGroup.getName() == model.name) exclusiveGroup: group onTriggered: { Cura.MachineManager.setQualityGroup(model.quality_group) From b1e4cb91de02ade0bd567389419f7c73c8082b9b Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 14 Feb 2018 11:19:33 +0100 Subject: [PATCH 017/266] CURA-4606 cleanup auto sync in machinemanager --- cura/Settings/MachineManager.py | 114 -------------------------------- 1 file changed, 114 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 15bb388f26..752353fe79 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -160,16 +160,10 @@ class MachineManager(QObject): rootMaterialChanged = pyqtSignal() def _onOutputDevicesChanged(self) -> None: - for printer_output_device in self._printer_output_devices: - printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged) - printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged) - self._printer_output_devices = [] for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices(): if isinstance(printer_output_device, PrinterOutputDevice): self._printer_output_devices.append(printer_output_device) - printer_output_device.hotendIdChanged.connect(self._onHotendIdChanged) - printer_output_device.materialIdChanged.connect(self._onMaterialIdChanged) self.outputDevicesChanged.emit() @@ -193,114 +187,6 @@ class MachineManager(QObject): def totalNumberOfSettings(self) -> int: return len(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0].getAllKeys()) - def _onHotendIdChanged(self) -> None: - if not self._global_container_stack or not self._printer_output_devices: - return - - active_printer_model = self._printer_output_devices[0].activePrinter - if not active_printer_model: - return - - change_found = False - machine_id = self.activeMachineId - extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id), - key=lambda k: k.getMetaDataEntry("position")) - - for extruder_model, extruder in zip(active_printer_model.extruders, extruders): - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="variant", - definition=self._global_container_stack.definition.getId(), - name=extruder_model.hotendID) - if containers: - # The hotend ID is known. - machine_id = self.activeMachineId - if extruder.variant.getName() != extruder_model.hotendID: - change_found = True - self._auto_hotends_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"] - - if change_found: - # A change was found, let the output device handle this. - self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) - - def _onMaterialIdChanged(self) -> None: - if not self._global_container_stack or not self._printer_output_devices: - return - - active_printer_model = self._printer_output_devices[0].activePrinter - if not active_printer_model: - return - - change_found = False - machine_id = self.activeMachineId - extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id), - key=lambda k: k.getMetaDataEntry("position")) - - for extruder_model, extruder in zip(active_printer_model.extruders, extruders): - if extruder_model.activeMaterial is None: - continue - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="material", - definition=self._global_container_stack.definition.getId(), - GUID=extruder_model.activeMaterial.guid) - if containers: - # The material is known. - if extruder.material.getMetaDataEntry("GUID") != extruder_model.activeMaterial.guid: - change_found = True - if self._global_container_stack.definition.getMetaDataEntry("has_variants") and extruder.variant: - variant_id = self.getQualityVariantId(self._global_container_stack.definition, - extruder.variant) - for container in containers: - if container.get("variant") == variant_id: - self._auto_materials_changed[extruder.getMetaDataEntry("position")] = container["id"] - break - else: - # Just use the first result we found. - self._auto_materials_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"] - if change_found: - # A change was found, let the output device handle this. - self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) - - def _materialHotendChangedCallback(self, button) -> None: - if button == QMessageBox.No: - self._auto_materials_changed = {} - self._auto_hotends_changed = {} - return - self._autoUpdateMaterials() - self._autoUpdateHotends() - - def _autoUpdateMaterials(self) -> None: - extruder_manager = ExtruderManager.getInstance() - for position in self._auto_materials_changed: - material_id = self._auto_materials_changed[position] - old_index = extruder_manager.activeExtruderIndex - - if old_index != int(position): - extruder_manager.setActiveExtruderIndex(int(position)) - else: - old_index = None - - Logger.log("d", "Setting material of hotend %s to %s" % (position, material_id)) - self.setActiveMaterial(material_id) - - if old_index is not None: - extruder_manager.setActiveExtruderIndex(old_index) - self._auto_materials_changed = {} # Processed all of them now. - - def _autoUpdateHotends(self) -> None: - extruder_manager = ExtruderManager.getInstance() - for position in self._auto_hotends_changed: - hotend_id = self._auto_hotends_changed[position] - old_index = extruder_manager.activeExtruderIndex - - if old_index != int(position): - extruder_manager.setActiveExtruderIndex(int(position)) - else: - old_index = None - Logger.log("d", "Setting hotend variant of hotend %s to %s" % (position, hotend_id)) - self.setActiveVariant(hotend_id) - - if old_index is not None: - extruder_manager.setActiveExtruderIndex(old_index) - self._auto_hotends_changed = {} # Processed all of them now. - def _onGlobalContainerChanged(self) -> None: if self._global_container_stack: try: From 730cbb25bf317802bebb2eadf0153ac20c0a90bf Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 14:13:21 +0100 Subject: [PATCH 018/266] WIP: Simplify machine creation --- cura/CuraApplication.py | 6 + cura/Machines/QualityManager.py | 9 +- cura/Settings/CuraStackBuilder.py | 204 ++++++++++-------- resources/definitions/fdmprinter.def.json | 3 +- .../definitions/ultimaker2_plus.def.json | 1 + resources/definitions/ultimaker3.def.json | 3 +- 6 files changed, 129 insertions(+), 97 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 44d4761321..dc0a65be1d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -294,21 +294,25 @@ class CuraApplication(QtApplication): # Since they are empty, they should never be serialized and instead just programmatically created. # We need them to simplify the switching between materials. empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + self.empty_container = empty_container empty_definition_changes_container = copy.deepcopy(empty_container) empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") empty_definition_changes_container.addMetaDataEntry("type", "definition_changes") ContainerRegistry.getInstance().addContainer(empty_definition_changes_container) + self.empty_definition_changes_container = empty_definition_changes_container empty_variant_container = copy.deepcopy(empty_container) empty_variant_container.setMetaDataEntry("id", "empty_variant") empty_variant_container.addMetaDataEntry("type", "variant") ContainerRegistry.getInstance().addContainer(empty_variant_container) + self.empty_variant_container = empty_variant_container empty_material_container = copy.deepcopy(empty_container) empty_material_container.setMetaDataEntry("id", "empty_material") empty_material_container.addMetaDataEntry("type", "material") ContainerRegistry.getInstance().addContainer(empty_material_container) + self.empty_material_container = empty_material_container empty_quality_container = copy.deepcopy(empty_container) empty_quality_container.setMetaDataEntry("id", "empty_quality") @@ -317,12 +321,14 @@ class CuraApplication(QtApplication): empty_quality_container.addMetaDataEntry("type", "quality") empty_quality_container.addMetaDataEntry("supported", False) ContainerRegistry.getInstance().addContainer(empty_quality_container) + self.empty_quality_container = empty_quality_container empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") empty_quality_changes_container.addMetaDataEntry("quality_type", "not_supported") ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) + self.empty_quality_changes_container = empty_quality_changes_container with ContainerRegistry.getInstance().lockFile(): ContainerRegistry.getInstance().loadAllMetadata() diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index a719a7df8c..ee8b9c8922 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -257,7 +257,7 @@ class QualityManager(QObject): return quality_changes_group_dict def getQualityGroups(self, machine: "GlobalStack") -> dict: - # TODO: How to make this simpler, including the fallbacks. + # TODO: How to make this simpler, including the fall backs. # Get machine definition ID machine_definition_id = self._default_machine_definition_id if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): @@ -270,8 +270,13 @@ class QualityManager(QObject): raise RuntimeError("Cannot find node for machine def [%s] in Quality lookup table" % machine_definition_id) # iterate over all quality_types in the machine node + node_to_fetch_global = machine_node quality_group_dict = {} - for quality_type, quality_node in machine_node.quality_type_map.items(): + if not node_to_fetch_global.quality_type_map: + # Fallback mechanism: + # If there is no machine-specific quality, fallback to use the default fdmprinter's. + node_to_fetch_global = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id) + for quality_type, quality_node in node_to_fetch_global.quality_type_map.items(): quality_group = QualityGroup(quality_node.metadata["name"], quality_type) quality_group.node_for_global = quality_node diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 608a13c600..365658ee48 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -6,6 +6,7 @@ from UM.Logger import Logger from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Util import parseBool from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack @@ -22,7 +23,13 @@ class CuraStackBuilder: # \return The new global stack or None if an error occurred. @classmethod def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]: + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() + variant_manager = CuraApplication.getInstance()._variant_manager + material_manager = CuraApplication.getInstance()._material_manager + quality_manager = CuraApplication.getInstance()._quality_manager registry = ContainerRegistry.getInstance() + definitions = registry.findDefinitionContainers(id = definition_id) if not definitions: Logger.log("w", "Definition {definition} was not found!", definition = definition_id) @@ -30,7 +37,33 @@ class CuraStackBuilder: machine_definition = definitions[0] - generated_name = registry.createUniqueName("machine", "", name, machine_definition.name) + # get variant container for extruders + variant_container = application.empty_variant_container + # Only look for the preferred variant if this machine has variants + variant_name = None + if parseBool(machine_definition.getMetaDataEntry("has_variants", False)): + variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") + if variant_name: + variant_node = variant_manager.getVariant(definition_id, variant_name) + # Sanity check. If you see this error, the related definition files should be fixed. + if variant_node is None: + raise RuntimeError("Cannot find variant with definition [%s] and variant name [%s]" % (definition_id, variant_name)) + variant_container = variant_node.getContainer() + + # get material container for extruders + material_container = application.empty_material_container + # Only look for the preferred material if this machine has materials + if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): + material_diameter = machine_definition.getProperty("material_diameter", "value") + root_material_id = machine_definition.getMetaDataEntry("preferred_material") + material_node = material_manager.getMaterialNode(definition_id, variant_name, material_diameter, root_material_id) + # Sanity check. If you see this error, the related definition files should be fixed. + if not material_node: + raise RuntimeError("Cannot find material with definition [%s], variant_name [%s], and root_material_id [%s]" % + (definition_id, variant_name, root_material_id)) + material_container = material_node.getContainer() + + generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) # Make sure the new name does not collide with any definition or (quality) profile # createUniqueName() only looks at other stacks, but not at definitions or quality profiles # Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true @@ -40,49 +73,45 @@ class CuraStackBuilder: new_global_stack = cls.createGlobalStack( new_stack_id = generated_name, definition = machine_definition, - quality = "default", - material = "default", - variant = "default", + variant_container = application.empty_variant_container, # TODO: fix for build plate + material_container = application.empty_material_container, + quality_container = application.empty_quality_container, ) - new_global_stack.setName(generated_name) - extruder_definition = registry.findDefinitionContainers(machine = machine_definition.getId()) + # Create ExtruderStacks + extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains") - if not extruder_definition: - # create extruder stack for single extrusion machines that have no separate extruder definition files - extruder_definition = registry.findDefinitionContainers(id = "fdmextruder")[0] - new_extruder_id = registry.uniqueName(machine_definition.getName() + " " + extruder_definition.id) + for position, extruder_definition_id in extruder_dict.items(): + # Sanity check: make sure that the positions in the extruder definitions are same as in the machine + # definition + extruder_definition = registry.findDefinitionContainers(id = extruder_definition_id)[0] + position_in_extruder_def = extruder_definition.getMetaDataEntry("position") + if position_in_extruder_def != position: + raise RuntimeError("Extruder position [%s] defined in extruder definition [%s] is not the same as in machine definition [%s] position [%s]" % + (position_in_extruder_def, extruder_definition_id, definition_id, position)) + + new_extruder_id = registry.uniqueName(extruder_definition_id) new_extruder = cls.createExtruderStack( new_extruder_id, - definition = extruder_definition, - machine_definition_id = machine_definition.getId(), - quality = "default", - material = "default", - variant = "default", - next_stack = new_global_stack + extruder_definition = extruder_definition, + machine_definition_id = definition_id, + position = position, + variant_container = variant_container, + material_container = material_container, + quality_container = application.empty_quality_container, ) + new_extruder.setNextStack(new_global_stack) new_global_stack.addExtruder(new_extruder) registry.addContainer(new_extruder) - else: - # create extruder stack for each found extruder definition - for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id): - position = extruder_definition.getMetaDataEntry("position", None) - if not position: - Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.id) - new_extruder_id = registry.uniqueName(extruder_definition.id) - new_extruder = cls.createExtruderStack( - new_extruder_id, - definition = extruder_definition, - machine_definition_id = machine_definition.getId(), - quality = "default", - material = "default", - variant = "default", - next_stack = new_global_stack - ) - new_global_stack.addExtruder(new_extruder) - registry.addContainer(new_extruder) + preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type") + quality_group_dict = quality_manager.getQualityGroups(new_global_stack) + quality_group = quality_group_dict.get(preferred_quality_type) + + new_global_stack.quality = quality_group.node_for_global.getContainer() + for position, extruder_stack in new_global_stack.extruders.items(): + extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() # Register the global stack after the extruder stacks are created. This prevents the registry from adding another # extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1). @@ -100,43 +129,27 @@ class CuraStackBuilder: # # \return A new Global stack instance with the specified parameters. @classmethod - def createExtruderStack(cls, new_stack_id: str, definition: DefinitionContainerInterface, machine_definition_id: str, **kwargs) -> ExtruderStack: - stack = ExtruderStack(new_stack_id) - stack.setName(definition.getName()) - stack.setDefinition(definition) - stack.addMetaDataEntry("position", definition.getMetaDataEntry("position")) - - if "next_stack" in kwargs: - # Add stacks before containers are added, since they may trigger a setting update. - stack.setNextStack(kwargs["next_stack"]) - - user_container = InstanceContainer(new_stack_id + "_user") - user_container.addMetaDataEntry("type", "user") - user_container.addMetaDataEntry("extruder", new_stack_id) + def createExtruderStack(cls, new_stack_id: str, extruder_definition: DefinitionContainerInterface, machine_definition_id: str, + position: int, + variant_container, material_container, quality_container) -> ExtruderStack: from cura.CuraApplication import CuraApplication - user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) - user_container.setDefinition(machine_definition_id) + application = CuraApplication.getInstance() - stack.setUserChanges(user_container) + stack = ExtruderStack(new_stack_id) + stack.setName(extruder_definition.getName()) + stack.setDefinition(extruder_definition) - # Important! The order here matters, because that allows the stack to - # assume the material and variant have already been set. - if "definition_changes" in kwargs: - stack.setDefinitionChangesById(kwargs["definition_changes"]) - else: - stack.setDefinitionChanges(cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings")) + stack.addMetaDataEntry("position", position) - if "variant" in kwargs: - stack.setVariantById(kwargs["variant"]) + user_container = cls.createUserChangesContainer(new_stack_id + "_user", machine_definition_id, new_stack_id, + is_global_stack = False) - if "material" in kwargs: - stack.setMaterialById(kwargs["material"]) - - if "quality" in kwargs: - stack.setQualityById(kwargs["quality"]) - - if "quality_changes" in kwargs: - stack.setQualityChangesById(kwargs["quality_changes"]) + stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings") + stack.variant = variant_container + stack.material = material_container + stack.quality = quality_container + stack.qualityChanges = application.empty_quality_changes_container + stack.userChanges = user_container # Only add the created containers to the registry after we have set all the other # properties. This makes the create operation more transactional, since any problems @@ -153,42 +166,47 @@ class CuraStackBuilder: # # \return A new Global stack instance with the specified parameters. @classmethod - def createGlobalStack(cls, new_stack_id: str, definition: DefinitionContainerInterface, **kwargs) -> GlobalStack: + def createGlobalStack(cls, new_stack_id: str, definition: DefinitionContainerInterface, + variant_container, material_container, quality_container) -> GlobalStack: + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() + stack = GlobalStack(new_stack_id) stack.setDefinition(definition) - user_container = InstanceContainer(new_stack_id + "_user") - user_container.addMetaDataEntry("type", "user") - user_container.addMetaDataEntry("machine", new_stack_id) - from cura.CuraApplication import CuraApplication - user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) - user_container.setDefinition(definition.getId()) + # Create user container + user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id, + is_global_stack = True) - stack.setUserChanges(user_container) - - # Important! The order here matters, because that allows the stack to - # assume the material and variant have already been set. - if "definition_changes" in kwargs: - stack.setDefinitionChangesById(kwargs["definition_changes"]) - else: - stack.setDefinitionChanges(cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings")) - - if "variant" in kwargs: - stack.setVariantById(kwargs["variant"]) - - if "material" in kwargs: - stack.setMaterialById(kwargs["material"]) - - if "quality" in kwargs: - stack.setQualityById(kwargs["quality"]) - - if "quality_changes" in kwargs: - stack.setQualityChangesById(kwargs["quality_changes"]) + stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings") + stack.variant = variant_container + stack.material = material_container + stack.quality = quality_container + stack.qualityChanges = application.empty_quality_changes_container + stack.userChanges = user_container ContainerRegistry.getInstance().addContainer(user_container) return stack + @classmethod + def createUserChangesContainer(cls, container_name: str, definition_id: str, stack_id: str, + is_global_stack: bool) -> "InstanceContainer": + from cura.CuraApplication import CuraApplication + + unique_container_name = ContainerRegistry.getInstance().uniqueName(container_name) + + container = InstanceContainer(unique_container_name) + container.setDefinition(definition_id) + container.addMetaDataEntry("type", "user") + container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) + + metadata_key_to_add = "machine" if is_global_stack else "extruder" + container.addMetaDataEntry(metadata_key_to_add, stack_id) + + return container + + @classmethod def createDefinitionChangesContainer(cls, container_stack, container_name, container_index = None): from cura.CuraApplication import CuraApplication diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 80bb9b19b9..366158d042 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -11,8 +11,9 @@ "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "visible": false, "has_materials": true, - "preferred_material": "*generic_pla*", + "preferred_material": "generic_pla", "preferred_quality": "*normal*", + "preferred_quality_type": "normal", "machine_extruder_trains": { "0": "fdmextruder" diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 58833904d2..bc90776289 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -10,6 +10,7 @@ "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2Plusbackplate.png", "preferred_variant": "*0.4*", + "preferred_variant_name": "0.4 mm", "has_variants": true, "has_materials": true, "has_machine_materials": true, diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 74e4a9551e..9a98b83efb 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -16,8 +16,9 @@ "has_variant_materials": true, "has_variants": true, "preferred_variant": "*aa04*", + "preferred_variant_name": "AA 0.4", "preferred_quality": "*Normal*", - "preferred_quality_type": "fine", + "preferred_quality_type": "normal", "variants_name": "Print core", "machine_extruder_trains": { From c469ebbf9fac22448828945f69e361bfd6834e2e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 16:08:21 +0100 Subject: [PATCH 019/266] WIP: Fix material lookup problems and update definition files --- cura/Machines/MaterialManager.py | 16 +++++++-------- cura/Machines/QualityManager.py | 3 +-- .../definitions/anycubic_i3_mega.def.json | 2 +- .../builder_premium_large.def.json | 20 +++++++++---------- .../builder_premium_medium.def.json | 20 +++++++++---------- .../builder_premium_small.def.json | 20 +++++++++---------- resources/definitions/cartesio.def.json | 5 ++--- resources/definitions/creality_cr10.def.json | 2 +- resources/definitions/fabtotum.def.json | 4 ++-- resources/definitions/fdmprinter.def.json | 1 - resources/definitions/gmax15plus.def.json | 4 +--- .../definitions/gmax15plus_dual.def.json | 4 ++-- .../definitions/imade3d_jellybox.def.json | 5 ++--- resources/definitions/malyan_m200.def.json | 2 +- .../monoprice_select_mini_v2.def.json | 2 +- .../definitions/tevo_blackwidow.def.json | 2 +- .../definitions/ultimaker2_plus.def.json | 1 - resources/definitions/ultimaker3.def.json | 2 -- .../definitions/ultimaker3_extended.def.json | 2 +- 19 files changed, 51 insertions(+), 66 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index b65e01487c..880ef399bf 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -249,15 +249,15 @@ class MaterialManager(QObject): # 1. variant-specific material # 2. machine-specific material # 3. generic material (for fdmprinter) - material_node = None - if variant_node is not None: - if root_material_id in variant_node.material_map: - material_node = variant_node.material_map.get(root_material_id) + nodes_to_check = [variant_node, machine_node, + machine_variant_material_map.get(self._default_machine_definition_id)] - # Fallback: machine-specific materials, including "fdmprinter" - if material_node is None: - if machine_node is not None: - material_node = machine_node.material_map.get(root_material_id) + material_node = None + for node in nodes_to_check: + if node is not None: + material_node = node.material_map.get(root_material_id) + if material_node: + break return material_node diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index ee8b9c8922..132c2e3dfa 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -320,7 +320,7 @@ class QualityManager(QObject): # No suitable quality found: not supported Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", machine_definition_id, variant_name, ", ".join(root_material_id_list)) - continue + else: # In this case, we only have a specific material but NOT a variant if has_material: @@ -332,7 +332,6 @@ class QualityManager(QObject): # No suitable quality found: not supported Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", machine_definition_id, variant_name, ", ".join(root_material_id_list)) - continue node_to_check = material_node if not node_to_check: diff --git a/resources/definitions/anycubic_i3_mega.def.json b/resources/definitions/anycubic_i3_mega.def.json index cba868900c..7106038193 100644 --- a/resources/definitions/anycubic_i3_mega.def.json +++ b/resources/definitions/anycubic_i3_mega.def.json @@ -12,7 +12,7 @@ "platform": "anycubic_i3_mega_platform.stl", "has_materials": false, "has_machine_quality": true, - "preferred_quality": "*normal*" + "preferred_quality_type": "normal" }, "overrides": diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json index b496dc524e..deb1539a9a 100644 --- a/resources/definitions/builder_premium_large.def.json +++ b/resources/definitions/builder_premium_large.def.json @@ -12,16 +12,14 @@ "platform": "builder_premium_platform.stl", "platform_offset": [-126, -36, 117], "has_machine_quality": true, - "preferred_quality": "*Normal*", + "preferred_quality_type": "normal", "machine_extruder_trains": { "0": "builder_premium_large_rear", "1": "builder_premium_large_front" } }, - - - + "overrides": { "machine_name": { "default_value": "Builder Premium Large" }, "machine_heated_bed": { "default_value": true }, @@ -36,7 +34,7 @@ "default_material_print_temperature": { "value": "215" }, "material_print_temperature_layer_0": { "value": "material_print_temperature + 5" }, "material_standby_temperature": { "value": "material_print_temperature" }, - + "switch_extruder_retraction_speeds": {"default_value": 15 }, "switch_extruder_retraction_speed": {"default_value": 15 }, "switch_extruder_prime_speed": {"default_value": 15 }, @@ -58,9 +56,9 @@ "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, "dual_pre_wipe": { "default_value": false }, - + "prime_blob_enable": { "enabled": true }, - + "acceleration_enabled": { "value": "True" }, "acceleration_layer_0": { "value": "acceleration_topbottom" }, "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, @@ -71,7 +69,7 @@ "acceleration_travel": { "value": "acceleration_print" }, "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" }, "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" }, - + "cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" }, "cool_min_layer_time": { "default_value": 10 }, @@ -84,9 +82,9 @@ "jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" }, "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" }, "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" }, - + "wall_thickness": { "value": "1.2" }, - + "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, "retraction_retract_speed": { "default_value": 15 }, @@ -113,4 +111,4 @@ }, "machine_extruder_count": { "default_value": 2 } } -} \ No newline at end of file +} diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json index fe8a039fc4..c28c7c5de6 100644 --- a/resources/definitions/builder_premium_medium.def.json +++ b/resources/definitions/builder_premium_medium.def.json @@ -12,16 +12,14 @@ "platform": "builder_premium_platform.stl", "platform_offset": [-126, -36, 117], "has_machine_quality": true, - "preferred_quality": "*Normal*", + "preferred_quality_type": "normal", "machine_extruder_trains": { "0": "builder_premium_medium_rear", "1": "builder_premium_medium_front" } }, - - - + "overrides": { "machine_name": { "default_value": "Builder Premium Medium" }, "machine_heated_bed": { "default_value": true }, @@ -36,7 +34,7 @@ "default_material_print_temperature": { "value": "215" }, "material_print_temperature_layer_0": { "value": "material_print_temperature + 5" }, "material_standby_temperature": { "value": "material_print_temperature" }, - + "switch_extruder_retraction_speeds": {"default_value": 15 }, "switch_extruder_retraction_speed": {"default_value": 15 }, "switch_extruder_prime_speed": {"default_value": 15 }, @@ -58,9 +56,9 @@ "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, "dual_pre_wipe": { "default_value": false }, - + "prime_blob_enable": { "enabled": true }, - + "acceleration_enabled": { "value": "True" }, "acceleration_layer_0": { "value": "acceleration_topbottom" }, "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, @@ -71,7 +69,7 @@ "acceleration_travel": { "value": "acceleration_print" }, "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" }, "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" }, - + "cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" }, "cool_min_layer_time": { "default_value": 10 }, @@ -84,9 +82,9 @@ "jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" }, "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" }, "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" }, - + "wall_thickness": { "value": "1.2" }, - + "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, "retraction_retract_speed": { "default_value": 15 }, @@ -113,4 +111,4 @@ }, "machine_extruder_count": { "default_value": 2 } } -} \ No newline at end of file +} diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json index a1660b63cf..8e2fe44631 100644 --- a/resources/definitions/builder_premium_small.def.json +++ b/resources/definitions/builder_premium_small.def.json @@ -11,16 +11,14 @@ "platform": "builder_premium_platform.stl", "platform_offset": [-126, -36, 117], "has_machine_quality": true, - "preferred_quality": "*Normal*", + "preferred_quality_type": "normal", "machine_extruder_trains": { "0": "builder_premium_small_rear", "1": "builder_premium_small_front" } }, - - - + "overrides": { "machine_name": { "default_value": "Builder Premium Small" }, "machine_heated_bed": { "default_value": true }, @@ -35,7 +33,7 @@ "default_material_print_temperature": { "value": "215" }, "material_print_temperature_layer_0": { "value": "material_print_temperature + 5" }, "material_standby_temperature": { "value": "material_print_temperature" }, - + "switch_extruder_retraction_speeds": {"default_value": 15 }, "switch_extruder_retraction_speed": {"default_value": 15 }, "switch_extruder_prime_speed": {"default_value": 15 }, @@ -57,9 +55,9 @@ "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, "dual_pre_wipe": { "default_value": false }, - + "prime_blob_enable": { "enabled": true }, - + "acceleration_enabled": { "value": "True" }, "acceleration_layer_0": { "value": "acceleration_topbottom" }, "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, @@ -70,7 +68,7 @@ "acceleration_travel": { "value": "acceleration_print" }, "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" }, "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" }, - + "cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" }, "cool_min_layer_time": { "default_value": 10 }, @@ -83,9 +81,9 @@ "jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" }, "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" }, "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" }, - + "wall_thickness": { "value": "1.2" }, - + "retraction_amount": { "default_value": 3 }, "retraction_speed": { "default_value": 15 }, "retraction_retract_speed": { "default_value": 15 }, @@ -112,4 +110,4 @@ }, "machine_extruder_count": { "default_value": 2 } } -} \ No newline at end of file +} diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json index 44f3153015..9deb257ac3 100644 --- a/resources/definitions/cartesio.def.json +++ b/resources/definitions/cartesio.def.json @@ -15,9 +15,8 @@ "has_variants": true, "variants_name": "Nozzle size", - "preferred_variant": "*0.8*", - "preferred_material": "*pla*", - "preferred_quality": "*normal*", + "preferred_variant_name": "0.8 mm", + "preferred_quality_type": "normal", "machine_extruder_trains": { diff --git a/resources/definitions/creality_cr10.def.json b/resources/definitions/creality_cr10.def.json index 7a58adcd4d..eb0b8c7306 100644 --- a/resources/definitions/creality_cr10.def.json +++ b/resources/definitions/creality_cr10.def.json @@ -7,7 +7,7 @@ "author": "Michael Wildermuth", "manufacturer": "Creality3D", "file_formats": "text/x-gcode", - "preferred_quality": "*Draft*" + "preferred_quality_type": "draft" }, "overrides": { "machine_width": { diff --git a/resources/definitions/fabtotum.def.json b/resources/definitions/fabtotum.def.json index 87ce11a35c..a53e9d9efb 100644 --- a/resources/definitions/fabtotum.def.json +++ b/resources/definitions/fabtotum.def.json @@ -13,8 +13,8 @@ "has_machine_quality": true, "has_variants": true, "variants_name": "Head", - "preferred_variant": "*lite04*", - "preferred_material": "*fabtotum_pla*", + "preferred_variant_name": "Lite 0.4 mm", + "preferred_material": "fabtotum_pla", "supports_usb_connection": false }, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 366158d042..274c13d0f3 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -12,7 +12,6 @@ "visible": false, "has_materials": true, "preferred_material": "generic_pla", - "preferred_quality": "*normal*", "preferred_quality_type": "normal", "machine_extruder_trains": { diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index d651a86bb3..3a207cd054 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -12,9 +12,7 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", - "preferred_variant": "*0.5mm E3D (Default)*" - - + "preferred_variant_name": "0.5mm E3D (Default)" }, "overrides": { diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index 4e9a91e88d..af26a2e30a 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -12,11 +12,11 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", - "preferred_variant": "*0.5mm E3D (Default)*", + "preferred_variant_name": "0.5mm E3D (Default)", "machine_extruder_trains": { "0": "gmax15plus_dual_extruder_0", "1": "gmax15plus_dual_extruder_1" - } + } }, "overrides": { diff --git a/resources/definitions/imade3d_jellybox.def.json b/resources/definitions/imade3d_jellybox.def.json index 11df730408..b234e4b2cd 100644 --- a/resources/definitions/imade3d_jellybox.def.json +++ b/resources/definitions/imade3d_jellybox.def.json @@ -9,9 +9,8 @@ "platform": "imade3d_jellybox_platform.stl", "platform_offset": [ 0, -0.3, 0], "file_formats": "text/x-gcode", - "preferred_variant": "*0.4*", - "preferred_material": "*generic_pla*", - "preferred_quality": "*fast*", + "preferred_variant_name": "0.4 mm", + "preferred_quality_type": "fast", "has_materials": true, "has_variants": true, "has_machine_materials": true, diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json index 365b031c43..a3f4f81ecf 100644 --- a/resources/definitions/malyan_m200.def.json +++ b/resources/definitions/malyan_m200.def.json @@ -11,7 +11,7 @@ "platform": "malyan_m200_platform.stl", "has_machine_quality": true, "has_materials": true, - "preferred_quality": "*normal*", + "preferred_quality_type": "normal", "supports_usb_connection": true, "visible": true, "first_start_actions": ["MachineSettingsAction"], diff --git a/resources/definitions/monoprice_select_mini_v2.def.json b/resources/definitions/monoprice_select_mini_v2.def.json index 87014c136b..99bb7ef50a 100644 --- a/resources/definitions/monoprice_select_mini_v2.def.json +++ b/resources/definitions/monoprice_select_mini_v2.def.json @@ -10,7 +10,7 @@ "file_formats": "text/x-gcode", "has_machine_quality": true, "has_materials": true, - "preferred_quality": "*normal*", + "preferred_quality_type": "normal", "visible": true }, diff --git a/resources/definitions/tevo_blackwidow.def.json b/resources/definitions/tevo_blackwidow.def.json index 04cadfb160..22f7095e17 100644 --- a/resources/definitions/tevo_blackwidow.def.json +++ b/resources/definitions/tevo_blackwidow.def.json @@ -11,7 +11,7 @@ "has_materials": false, "has_machine_quality": true, "platform": "tevo_blackwidow.stl", - "preferred_quality": "*normal*" + "preferred_quality_type": "normal" }, "overrides": { diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index bc90776289..935bf5b6c0 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -9,7 +9,6 @@ "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2Plusbackplate.png", - "preferred_variant": "*0.4*", "preferred_variant_name": "0.4 mm", "has_variants": true, "has_materials": true, diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 9a98b83efb..8fda63f970 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -15,9 +15,7 @@ "has_machine_materials": true, "has_variant_materials": true, "has_variants": true, - "preferred_variant": "*aa04*", "preferred_variant_name": "AA 0.4", - "preferred_quality": "*Normal*", "preferred_quality_type": "normal", "variants_name": "Print core", "machine_extruder_trains": diff --git a/resources/definitions/ultimaker3_extended.def.json b/resources/definitions/ultimaker3_extended.def.json index 385199f4f1..3a1be3a303 100644 --- a/resources/definitions/ultimaker3_extended.def.json +++ b/resources/definitions/ultimaker3_extended.def.json @@ -16,7 +16,7 @@ "has_variant_materials": true, "has_materials": true, "has_variants": true, - "preferred_variant": "*aa04*", + "preferred_variant_name": "AA 0.4", "variants_name": "Print core", "machine_extruder_trains": { From 5ad4447e379cc4b40b2aade200a57d92d719c64d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 17:02:04 +0100 Subject: [PATCH 020/266] WIP: Update and fix definition files --- resources/definitions/101Hero.def.json | 1 + resources/definitions/3dator.def.json | 1 + resources/definitions/bq_hephestos_2.def.json | 1 + resources/definitions/builder_premium_large.def.json | 1 + resources/definitions/builder_premium_medium.def.json | 1 + resources/definitions/builder_premium_small.def.json | 1 + resources/definitions/cartesio.def.json | 1 + resources/definitions/delta_go.def.json | 3 ++- resources/definitions/deltacomb.def.json | 3 ++- resources/definitions/folgertech_FT-5.def.json | 3 ++- resources/definitions/gmax15plus.def.json | 1 + resources/definitions/gmax15plus_dual.def.json | 1 + resources/definitions/helloBEEprusa.def.json | 3 ++- resources/definitions/imade3d_jellybox.def.json | 1 + resources/definitions/julia.def.json | 3 ++- resources/definitions/makerbotreplicator.def.json | 3 ++- resources/definitions/malyan_m200.def.json | 1 + resources/definitions/mankati_fullscale_xt_plus.def.json | 3 ++- resources/definitions/ord.def.json | 1 + resources/definitions/printrbot_play.def.json | 3 ++- resources/definitions/printrbot_simple.def.json | 3 ++- resources/definitions/printrbot_simple_extended.def.json | 3 ++- resources/definitions/prusa_i3_mk2.def.json | 3 ++- resources/definitions/punchtec_connect_xl.def.json | 3 ++- resources/definitions/rigid3d.def.json | 3 ++- resources/definitions/rigid3d_3rdgen.def.json | 3 ++- resources/definitions/rigid3d_hobby.def.json | 3 ++- resources/definitions/rigid3d_zero.def.json | 3 ++- resources/definitions/robo_3d_r1.def.json | 3 ++- resources/definitions/tam.def.json | 1 + resources/definitions/zone3d_printer.def.json | 3 ++- 31 files changed, 49 insertions(+), 18 deletions(-) diff --git a/resources/definitions/101Hero.def.json b/resources/definitions/101Hero.def.json index 620fcfb519..ead1bd4cd2 100644 --- a/resources/definitions/101Hero.def.json +++ b/resources/definitions/101Hero.def.json @@ -8,6 +8,7 @@ "manufacturer": "101Hero", "file_formats": "text/x-gcode", "platform": "101hero-platform.stl", + "preferred_material": "generic_pla_175", "supports_usb_connection": true }, diff --git a/resources/definitions/3dator.def.json b/resources/definitions/3dator.def.json index 19307bfddd..3d9b2bd7e5 100644 --- a/resources/definitions/3dator.def.json +++ b/resources/definitions/3dator.def.json @@ -9,6 +9,7 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "supports_usb_connection": true, + "preferred_material": "generic_pla_175", "platform": "3dator_platform.stl" }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index a3493334b6..4c36384d63 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -8,6 +8,7 @@ "manufacturer": "BQ", "platform": "bq_hephestos_2_platform.stl", "platform_offset": [6, 1320, 0 ], + "preferred_material": "generic_pla_175", "file_formats": "text/x-gcode" }, diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json index deb1539a9a..15e85d7910 100644 --- a/resources/definitions/builder_premium_large.def.json +++ b/resources/definitions/builder_premium_large.def.json @@ -13,6 +13,7 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_large_rear", diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json index c28c7c5de6..500bfca75f 100644 --- a/resources/definitions/builder_premium_medium.def.json +++ b/resources/definitions/builder_premium_medium.def.json @@ -13,6 +13,7 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_medium_rear", diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json index 8e2fe44631..1d6451430c 100644 --- a/resources/definitions/builder_premium_small.def.json +++ b/resources/definitions/builder_premium_small.def.json @@ -12,6 +12,7 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_small_rear", diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json index 9deb257ac3..49eecd2c24 100644 --- a/resources/definitions/cartesio.def.json +++ b/resources/definitions/cartesio.def.json @@ -17,6 +17,7 @@ "variants_name": "Nozzle size", "preferred_variant_name": "0.8 mm", "preferred_quality_type": "normal", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { diff --git a/resources/definitions/delta_go.def.json b/resources/definitions/delta_go.def.json index a6d75b2983..6e9fa4aa09 100644 --- a/resources/definitions/delta_go.def.json +++ b/resources/definitions/delta_go.def.json @@ -8,7 +8,8 @@ "manufacturer": "Deltaprintr", "file_formats": "text/x-gcode", "platform_offset": [0, 0, 0], - "platform": "" + "platform": "", + "preferred_material": "generic_pla_175" }, "overrides": { "machine_name": { "default_value": "Delta Go" }, diff --git a/resources/definitions/deltacomb.def.json b/resources/definitions/deltacomb.def.json index 7e6e956dbc..26004e835e 100644 --- a/resources/definitions/deltacomb.def.json +++ b/resources/definitions/deltacomb.def.json @@ -10,7 +10,8 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "platform": "deltacomb.stl", - "has_machine_quality": true + "has_machine_quality": true, + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/folgertech_FT-5.def.json b/resources/definitions/folgertech_FT-5.def.json index 71c6987a1a..7c3489951f 100644 --- a/resources/definitions/folgertech_FT-5.def.json +++ b/resources/definitions/folgertech_FT-5.def.json @@ -7,7 +7,8 @@ "author": "Jaime van Kessel & Paul Bussiere", "manufacturer": "Folger Tech", "file_formats": "text/x-gcode", - "platform": "FT-5_build_plate.stl" + "platform": "FT-5_build_plate.stl", + "preferred_material": "generic_pla_175" }, "overrides": { "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index 3a207cd054..8bd765d156 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -12,6 +12,7 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", + "preferred_material": "generic_pla_175", "preferred_variant_name": "0.5mm E3D (Default)" }, diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index af26a2e30a..e93fc7c6a0 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -12,6 +12,7 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", + "preferred_material": "generic_pla_175", "preferred_variant_name": "0.5mm E3D (Default)", "machine_extruder_trains": { "0": "gmax15plus_dual_extruder_0", diff --git a/resources/definitions/helloBEEprusa.def.json b/resources/definitions/helloBEEprusa.def.json index 2699a6c7d7..26692f8486 100644 --- a/resources/definitions/helloBEEprusa.def.json +++ b/resources/definitions/helloBEEprusa.def.json @@ -9,6 +9,7 @@ "platform": "BEEVERYCREATIVE-helloBEEprusa.stl", "platform_offset": [-226, -75, -196], "file_formats": "text/x-gcode", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "hBp_extruder_left", @@ -52,4 +53,4 @@ "retraction_speed": { "default_value": 15.0}, "retraction_amount": { "default_value": 1.5} } -} \ No newline at end of file +} diff --git a/resources/definitions/imade3d_jellybox.def.json b/resources/definitions/imade3d_jellybox.def.json index b234e4b2cd..42bf61f388 100644 --- a/resources/definitions/imade3d_jellybox.def.json +++ b/resources/definitions/imade3d_jellybox.def.json @@ -9,6 +9,7 @@ "platform": "imade3d_jellybox_platform.stl", "platform_offset": [ 0, -0.3, 0], "file_formats": "text/x-gcode", + "preferred_material": "generic_pla_175", "preferred_variant_name": "0.4 mm", "preferred_quality_type": "fast", "has_materials": true, diff --git a/resources/definitions/julia.def.json b/resources/definitions/julia.def.json index 7fdee30272..8a9402b332 100644 --- a/resources/definitions/julia.def.json +++ b/resources/definitions/julia.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Fracktal", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/makerbotreplicator.def.json b/resources/definitions/makerbotreplicator.def.json index 3d690990ce..77aa5ab667 100644 --- a/resources/definitions/makerbotreplicator.def.json +++ b/resources/definitions/makerbotreplicator.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "MakerBot", "file_formats": "application/x3g", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json index a3f4f81ecf..855fe58cd2 100644 --- a/resources/definitions/malyan_m200.def.json +++ b/resources/definitions/malyan_m200.def.json @@ -11,6 +11,7 @@ "platform": "malyan_m200_platform.stl", "has_machine_quality": true, "has_materials": true, + "preferred_material": "generic_pla_175", "preferred_quality_type": "normal", "supports_usb_connection": true, "visible": true, diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json index 15ba889efc..39b3d018bf 100644 --- a/resources/definitions/mankati_fullscale_xt_plus.def.json +++ b/resources/definitions/mankati_fullscale_xt_plus.def.json @@ -7,7 +7,8 @@ "author": "RBC", "manufacturer": "Mankati", "file_formats": "text/x-gcode", - "platform": "mankati_fullscale_xt_plus_platform.stl" + "platform": "mankati_fullscale_xt_plus_platform.stl", + "preferred_material": "generic_pla_175" }, "overrides": { "machine_name": { "default_value": "Mankati Fullscale XT Plus" }, diff --git a/resources/definitions/ord.def.json b/resources/definitions/ord.def.json index 3238583ceb..471385cc7c 100644 --- a/resources/definitions/ord.def.json +++ b/resources/definitions/ord.def.json @@ -7,6 +7,7 @@ "author": "Ultimaker", "manufacturer": "ORD Solutions", "file_formats": "text/x-gcode", + "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "ord_extruder_0", diff --git a/resources/definitions/printrbot_play.def.json b/resources/definitions/printrbot_play.def.json index 36ef93e60c..3f98aff798 100644 --- a/resources/definitions/printrbot_play.def.json +++ b/resources/definitions/printrbot_play.def.json @@ -7,7 +7,8 @@ "author": "Chris Pearson", "manufacturer": "Printrbot", "file_formats": "text/x-gcode", - "platform": "printrbot_play.stl" + "platform": "printrbot_play.stl", + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index 7c86617ce5..52472fd743 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -8,7 +8,8 @@ "manufacturer": "PrintrBot", "platform": "printrbot_simple_metal_platform.stl", "platform_offset": [0, -3.45, 0], - "file_formats": "text/x-gcode" + "file_formats": "text/x-gcode", + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/printrbot_simple_extended.def.json b/resources/definitions/printrbot_simple_extended.def.json index 95395efb23..9463af5554 100644 --- a/resources/definitions/printrbot_simple_extended.def.json +++ b/resources/definitions/printrbot_simple_extended.def.json @@ -8,7 +8,8 @@ "manufacturer": "PrintrBot", "platform": "printrbot_simple_metal_upgrade.stl", "platform_offset": [0, -0.3, 0], - "file_formats": "text/x-gcode" + "file_formats": "text/x-gcode", + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json index e58eb4d903..b70e2ab1dc 100644 --- a/resources/definitions/prusa_i3_mk2.def.json +++ b/resources/definitions/prusa_i3_mk2.def.json @@ -9,7 +9,8 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "platform": "prusai3_platform.stl", - "has_materials": true + "has_materials": true, + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/punchtec_connect_xl.def.json b/resources/definitions/punchtec_connect_xl.def.json index 02d3562b41..c1f5780270 100644 --- a/resources/definitions/punchtec_connect_xl.def.json +++ b/resources/definitions/punchtec_connect_xl.def.json @@ -12,7 +12,8 @@ "0": "punchtec_connect_xl_extruder_0", "1": "punchtec_connect_xl_extruder_1" }, - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/rigid3d.def.json b/resources/definitions/rigid3d.def.json index 97b0ebd276..21673e0010 100644 --- a/resources/definitions/rigid3d.def.json +++ b/resources/definitions/rigid3d.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/rigid3d_3rdgen.def.json b/resources/definitions/rigid3d_3rdgen.def.json index 46c22bfa57..b5c2ae87ce 100644 --- a/resources/definitions/rigid3d_3rdgen.def.json +++ b/resources/definitions/rigid3d_3rdgen.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/rigid3d_hobby.def.json b/resources/definitions/rigid3d_hobby.def.json index 872cc3e6f4..4b18521319 100644 --- a/resources/definitions/rigid3d_hobby.def.json +++ b/resources/definitions/rigid3d_hobby.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/rigid3d_zero.def.json b/resources/definitions/rigid3d_zero.def.json index 56fb8284c0..44e5e7e96a 100644 --- a/resources/definitions/rigid3d_zero.def.json +++ b/resources/definitions/rigid3d_zero.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/robo_3d_r1.def.json b/resources/definitions/robo_3d_r1.def.json index b179779c59..1c87e4575f 100644 --- a/resources/definitions/robo_3d_r1.def.json +++ b/resources/definitions/robo_3d_r1.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Robo 3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { diff --git a/resources/definitions/tam.def.json b/resources/definitions/tam.def.json index 20bc96358d..11833b7841 100644 --- a/resources/definitions/tam.def.json +++ b/resources/definitions/tam.def.json @@ -10,6 +10,7 @@ "platform": "tam_series1.stl", "platform_offset": [-580.0, -6.23, 253.5], "has_materials": false, + "preferred_material": "generic_pla_175", "supported_actions":["UpgradeFirmware"] }, "overrides": { diff --git a/resources/definitions/zone3d_printer.def.json b/resources/definitions/zone3d_printer.def.json index bac8968951..b7f852054a 100644 --- a/resources/definitions/zone3d_printer.def.json +++ b/resources/definitions/zone3d_printer.def.json @@ -7,7 +7,8 @@ "author": "Ultimaker", "manufacturer": "Unknown", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0] + "platform_offset": [ 0, 0, 0], + "preferred_material": "generic_pla_175" }, "overrides": { From 194988dc9a0c0235e2f0ad2eefc6d182db6dcb1b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 20:44:44 +0100 Subject: [PATCH 021/266] WIP: Improve quality search fall back --- cura/Machines/QualityManager.py | 151 ++++++++------------------------ 1 file changed, 35 insertions(+), 116 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 132c2e3dfa..ad4fa6fc8f 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -189,7 +189,6 @@ class QualityManager(QObject): # Initialize quality self._initializeQualityChangesTables() - def _initializeQualityChangesTables(self): # Initialize the lookup tree for quality_changes profiles with following structure: # -> -> @@ -265,24 +264,24 @@ class QualityManager(QObject): if machine_definition_id is None: machine_definition_id = machine.definition.getId() + # To find the quality container for the GlobalStack, check in the following fall-back manner: + # (1) the machine-specific node + # (2) the generic node machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) - if not machine_node: - raise RuntimeError("Cannot find node for machine def [%s] in Quality lookup table" % machine_definition_id) + default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id) + nodes_to_check = [machine_node, default_machine_node] - # iterate over all quality_types in the machine node - node_to_fetch_global = machine_node + # Iterate over all quality_types in the machine node quality_group_dict = {} - if not node_to_fetch_global.quality_type_map: - # Fallback mechanism: - # If there is no machine-specific quality, fallback to use the default fdmprinter's. - node_to_fetch_global = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id) - for quality_type, quality_node in node_to_fetch_global.quality_type_map.items(): - quality_group = QualityGroup(quality_node.metadata["name"], quality_type) - quality_group.node_for_global = quality_node + for node in nodes_to_check: + if node and node.quality_type_map: + for quality_type, quality_node in node.quality_type_map.items(): + quality_group = QualityGroup(quality_node.metadata["name"], quality_type) + quality_group.node_for_global = quality_node + quality_group_dict[quality_type] = quality_group + break - quality_group_dict[quality_type] = quality_group - - # Iterate over all extruders + # Iterate over all extruders to find quality containers for each extruder for position, extruder in machine.extruders.items(): variant_name = None if extruder.variant.getId() != "empty_variant": @@ -303,120 +302,40 @@ class QualityManager(QObject): if fallback_root_material_metadata: root_material_id_list.append(fallback_root_material_metadata["id"]) - variant_node = None - material_node = None + nodes_to_check = [] if variant_name: # In this case, we have both a specific variant and a specific material variant_node = machine_node.getChildNode(variant_name) - if not variant_node: - continue - if has_material: + if variant_node and has_material: for root_material_id in root_material_id_list: material_node = variant_node.getChildNode(root_material_id) if material_node: + nodes_to_check.append(material_node) break - if not material_node: - # No suitable quality found: not supported - Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", - machine_definition_id, variant_name, ", ".join(root_material_id_list)) + nodes_to_check.append(variant_node) - else: - # In this case, we only have a specific material but NOT a variant - if has_material: - for root_material_id in root_material_id_list: - material_node = machine_node.getChildNode(root_material_id) - if material_node: - break - if not material_node: - # No suitable quality found: not supported - Logger.log("d", "Cannot find quality with machine [%s], variant name [%s], and materials [%s].", - machine_definition_id, variant_name, ", ".join(root_material_id_list)) + # In this case, we only have a specific material but NOT a variant + if has_material: + for root_material_id in root_material_id_list: + material_node = machine_node.getChildNode(root_material_id) + if material_node: + nodes_to_check.append(material_node) + break - node_to_check = material_node - if not node_to_check: - node_to_check = variant_node - if not node_to_check: - node_to_check = machine_node + nodes_to_check += [machine_node, default_machine_node] + for node in nodes_to_check: + if node and node.quality_type_map: + for quality_type, quality_node in node.quality_type_map.items(): + if quality_type not in quality_group_dict: + quality_group = QualityGroup(quality_node.metadata["name"], quality_type) + quality_group_dict[quality_type] = quality_group - for quality_type, quality_node in node_to_check.quality_type_map.items(): - if quality_type not in quality_group_dict: - quality_group = QualityGroup(quality_node.metadata["name"], quality_type) - quality_group_dict[quality_type] = quality_group - - quality_group = quality_group_dict[quality_type] - - quality_group.nodes_for_extruders[position] = quality_node + quality_group = quality_group_dict[quality_type] + quality_group.nodes_for_extruders[position] = quality_node + break # Update availabilities for each quality group self._updateQualityGroupsAvailability(machine, quality_group_dict.values()) return quality_group_dict - - - def getQuality(self, quality_type: str, machine: "GlobalStack"): - # Get machine definition ID - machine_definition_id = self._default_machine_definition_id - if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): - machine_definition_id = machine.getMetaDataEntry("quality_definition") - if machine_definition_id is None: - machine_definition_id = machine.definition.getId() - - machine_quality = self.getQualityContainer(quality_type, machine_definition_id) - extruder_quality_dict = {} - for position, extruder in machine.extruders.items(): - variant = extruder.variant - material = extruder.material - - variant_name = variant.getName() - if variant.getId() == "empty_variant": - variant_name = None - root_material_id = material.getMetaDataEntry("base_file") - if material.getId() == "empty_material": - root_material_id = None - - extruder_quality = self.getQualityContainer(quality_type, machine_definition_id, - variant_name, root_material_id) - extruder_quality_dict[position] = extruder_quality - - # TODO: return as a group - return machine_quality, extruder_quality_dict - - def getQualityContainer(self, quality_type: str, machine_definition_id: dict, - variant_name: Optional[str] = None, - root_material_id: Optional[str] = None) -> "InstanceContainer": - assert machine_definition_id is not None - assert quality_type is not None - - # If the specified quality cannot be found, empty_quality will be returned. - container = self._empty_quality_container - - machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) - variant_node = None - material_node = None - if machine_node is not None: - if variant_name is not None: - variant_node = machine_node.getChildNode(variant_name) - if variant_node is not None: - if root_material_id is not None: - material_node = variant_node.getChildNode(root_material_id) - elif root_material_id is not None: - material_node = machine_node.getChildNode(root_material_id) - - nodes_to_try = [material_node, variant_node, machine_node] - if machine_definition_id != self._default_machine_definition_id: - default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id) - nodes_to_try.append(default_machine_node) - - for node in nodes_to_try: - if node is None: - continue - quality_node = node.getQualityNode(quality_type) - if quality_node is None: - continue - - container = quality_node.getContainer() - break - - return container - From c79dd313ac9942b72a6ea5a7f51dae50b6ae1139 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 20:45:34 +0100 Subject: [PATCH 022/266] WIP: Refactor duplicated code and clean up --- cura/Machines/MachineTools.py | 25 +++++++++++++++++++++++++ cura/Machines/QualityManager.py | 30 +++++++++++------------------- cura/Settings/CuraStackBuilder.py | 5 ++--- 3 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 cura/Machines/MachineTools.py diff --git a/cura/Machines/MachineTools.py b/cura/Machines/MachineTools.py new file mode 100644 index 0000000000..91daa2490b --- /dev/null +++ b/cura/Machines/MachineTools.py @@ -0,0 +1,25 @@ +from UM.Util import parseBool + + +# +# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given +# machine. The rule is as follows: +# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic +# machine. +# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's +# own machine definition ID for quality search. +# Example: for an Ultimaker 3, the definition ID should be "ultimaker3". +# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the +# definition ID specified in "quality_definition" should be used. +# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended +# shares the same set of qualities profiles as Ultimaker 3. +# +def getMachineDefinitionIDForQualitySearch(machine: "GlobalStack", default_definition_id: str = "fdmprinter") -> str: + machine_definition_id = default_definition_id + if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): + # Only use the machine's own quality definition ID if this machine has machine quality. + machine_definition_id = machine.getMetaDataEntry("quality_definition") + if machine_definition_id is None: + machine_definition_id = machine.definition.getId() + + return machine_definition_id diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index ad4fa6fc8f..cb723f41d0 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,14 +1,14 @@ from typing import Optional -from PyQt5.Qt import pyqtSignal, QObject +from PyQt5.Qt import QObject from UM.Application import Application from UM.Logger import Logger -from UM.Settings.InstanceContainer import InstanceContainer from UM.Util import parseBool from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerNode import ContainerNode +from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch # @@ -114,12 +114,12 @@ class QualityManager(QObject): def __init__(self, container_registry, parent = None): super().__init__(parent) - - self._material_manager = Application.getInstance()._material_manager - + self._application = Application.getInstance() + self._material_manager = self._application._material_manager self._container_registry = container_registry - self._empty_quality_container = self._container_registry.findInstanceContainers(id = "empty_quality")[0] - #self._empty_quality_changes_container = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] + + self._empty_quality_container = self._application.empty_quality_container + self._empty_quality_changes_container = self._application.empty_quality_changes_container self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup @@ -229,12 +229,8 @@ class QualityManager(QObject): # Returns a dict of "custom profile name" -> QualityChangesGroup def getQualityChangesGroups(self, machine: "GlobalStack") -> dict: # TODO: How to make this simpler? - # Get machine definition ID - machine_definition_id = self._default_machine_definition_id - if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): - machine_definition_id = machine.getMetaDataEntry("quality_definition") - if machine_definition_id is None: - machine_definition_id = machine.definition.getId() + # Get machine definition ID for quality search + machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) if not machine_node: @@ -257,12 +253,8 @@ class QualityManager(QObject): def getQualityGroups(self, machine: "GlobalStack") -> dict: # TODO: How to make this simpler, including the fall backs. - # Get machine definition ID - machine_definition_id = self._default_machine_definition_id - if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): - machine_definition_id = machine.getMetaDataEntry("quality_definition") - if machine_definition_id is None: - machine_definition_id = machine.definition.getId() + # Get machine definition ID for quality search + machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) # To find the quality container for the GlobalStack, check in the following fall-back manner: # (1) the machine-specific node diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 365658ee48..19a5caacb8 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from UM.Logger import Logger @@ -206,9 +206,8 @@ class CuraStackBuilder: return container - @classmethod - def createDefinitionChangesContainer(cls, container_stack, container_name, container_index = None): + def createDefinitionChangesContainer(cls, container_stack, container_name): from cura.CuraApplication import CuraApplication unique_container_name = ContainerRegistry.getInstance().uniqueName(container_name) From 73968e5c4894c2b196c3f1825cfc931cd4ce765a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 20:46:29 +0100 Subject: [PATCH 023/266] Revert "WIP: Update and fix definition files" This reverts commit 27a346a58beaea9de249ebf229f0979d51ad21ff. --- resources/definitions/101Hero.def.json | 1 - resources/definitions/3dator.def.json | 1 - resources/definitions/bq_hephestos_2.def.json | 1 - resources/definitions/builder_premium_large.def.json | 1 - resources/definitions/builder_premium_medium.def.json | 1 - resources/definitions/builder_premium_small.def.json | 1 - resources/definitions/cartesio.def.json | 1 - resources/definitions/delta_go.def.json | 3 +-- resources/definitions/deltacomb.def.json | 3 +-- resources/definitions/folgertech_FT-5.def.json | 3 +-- resources/definitions/gmax15plus.def.json | 1 - resources/definitions/gmax15plus_dual.def.json | 1 - resources/definitions/helloBEEprusa.def.json | 3 +-- resources/definitions/imade3d_jellybox.def.json | 1 - resources/definitions/julia.def.json | 3 +-- resources/definitions/makerbotreplicator.def.json | 3 +-- resources/definitions/malyan_m200.def.json | 1 - resources/definitions/mankati_fullscale_xt_plus.def.json | 3 +-- resources/definitions/ord.def.json | 1 - resources/definitions/printrbot_play.def.json | 3 +-- resources/definitions/printrbot_simple.def.json | 3 +-- resources/definitions/printrbot_simple_extended.def.json | 3 +-- resources/definitions/prusa_i3_mk2.def.json | 3 +-- resources/definitions/punchtec_connect_xl.def.json | 3 +-- resources/definitions/rigid3d.def.json | 3 +-- resources/definitions/rigid3d_3rdgen.def.json | 3 +-- resources/definitions/rigid3d_hobby.def.json | 3 +-- resources/definitions/rigid3d_zero.def.json | 3 +-- resources/definitions/robo_3d_r1.def.json | 3 +-- resources/definitions/tam.def.json | 1 - resources/definitions/zone3d_printer.def.json | 3 +-- ...r_0.def.json => punchtec_connect_xl_extruder_left.def.json} | 0 ..._1.def.json => punchtec_connect_xl_extruder_right.def.json} | 0 33 files changed, 18 insertions(+), 49 deletions(-) rename resources/extruders/{punchtec_connect_xl_extruder_0.def.json => punchtec_connect_xl_extruder_left.def.json} (100%) rename resources/extruders/{punchtec_connect_xl_extruder_1.def.json => punchtec_connect_xl_extruder_right.def.json} (100%) diff --git a/resources/definitions/101Hero.def.json b/resources/definitions/101Hero.def.json index ead1bd4cd2..620fcfb519 100644 --- a/resources/definitions/101Hero.def.json +++ b/resources/definitions/101Hero.def.json @@ -8,7 +8,6 @@ "manufacturer": "101Hero", "file_formats": "text/x-gcode", "platform": "101hero-platform.stl", - "preferred_material": "generic_pla_175", "supports_usb_connection": true }, diff --git a/resources/definitions/3dator.def.json b/resources/definitions/3dator.def.json index 3d9b2bd7e5..19307bfddd 100644 --- a/resources/definitions/3dator.def.json +++ b/resources/definitions/3dator.def.json @@ -9,7 +9,6 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "supports_usb_connection": true, - "preferred_material": "generic_pla_175", "platform": "3dator_platform.stl" }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index 4c36384d63..a3493334b6 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -8,7 +8,6 @@ "manufacturer": "BQ", "platform": "bq_hephestos_2_platform.stl", "platform_offset": [6, 1320, 0 ], - "preferred_material": "generic_pla_175", "file_formats": "text/x-gcode" }, diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json index 15e85d7910..deb1539a9a 100644 --- a/resources/definitions/builder_premium_large.def.json +++ b/resources/definitions/builder_premium_large.def.json @@ -13,7 +13,6 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_large_rear", diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json index 500bfca75f..c28c7c5de6 100644 --- a/resources/definitions/builder_premium_medium.def.json +++ b/resources/definitions/builder_premium_medium.def.json @@ -13,7 +13,6 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_medium_rear", diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json index 1d6451430c..8e2fe44631 100644 --- a/resources/definitions/builder_premium_small.def.json +++ b/resources/definitions/builder_premium_small.def.json @@ -12,7 +12,6 @@ "platform_offset": [-126, -36, 117], "has_machine_quality": true, "preferred_quality_type": "normal", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "builder_premium_small_rear", diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json index 49eecd2c24..9deb257ac3 100644 --- a/resources/definitions/cartesio.def.json +++ b/resources/definitions/cartesio.def.json @@ -17,7 +17,6 @@ "variants_name": "Nozzle size", "preferred_variant_name": "0.8 mm", "preferred_quality_type": "normal", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { diff --git a/resources/definitions/delta_go.def.json b/resources/definitions/delta_go.def.json index 6e9fa4aa09..a6d75b2983 100644 --- a/resources/definitions/delta_go.def.json +++ b/resources/definitions/delta_go.def.json @@ -8,8 +8,7 @@ "manufacturer": "Deltaprintr", "file_formats": "text/x-gcode", "platform_offset": [0, 0, 0], - "platform": "", - "preferred_material": "generic_pla_175" + "platform": "" }, "overrides": { "machine_name": { "default_value": "Delta Go" }, diff --git a/resources/definitions/deltacomb.def.json b/resources/definitions/deltacomb.def.json index 26004e835e..7e6e956dbc 100644 --- a/resources/definitions/deltacomb.def.json +++ b/resources/definitions/deltacomb.def.json @@ -10,8 +10,7 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "platform": "deltacomb.stl", - "has_machine_quality": true, - "preferred_material": "generic_pla_175" + "has_machine_quality": true }, "overrides": { diff --git a/resources/definitions/folgertech_FT-5.def.json b/resources/definitions/folgertech_FT-5.def.json index 7c3489951f..71c6987a1a 100644 --- a/resources/definitions/folgertech_FT-5.def.json +++ b/resources/definitions/folgertech_FT-5.def.json @@ -7,8 +7,7 @@ "author": "Jaime van Kessel & Paul Bussiere", "manufacturer": "Folger Tech", "file_formats": "text/x-gcode", - "platform": "FT-5_build_plate.stl", - "preferred_material": "generic_pla_175" + "platform": "FT-5_build_plate.stl" }, "overrides": { "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index 8bd765d156..3a207cd054 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -12,7 +12,6 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", - "preferred_material": "generic_pla_175", "preferred_variant_name": "0.5mm E3D (Default)" }, diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index e93fc7c6a0..af26a2e30a 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -12,7 +12,6 @@ "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, "variants_name": "Hotend", - "preferred_material": "generic_pla_175", "preferred_variant_name": "0.5mm E3D (Default)", "machine_extruder_trains": { "0": "gmax15plus_dual_extruder_0", diff --git a/resources/definitions/helloBEEprusa.def.json b/resources/definitions/helloBEEprusa.def.json index 26692f8486..2699a6c7d7 100644 --- a/resources/definitions/helloBEEprusa.def.json +++ b/resources/definitions/helloBEEprusa.def.json @@ -9,7 +9,6 @@ "platform": "BEEVERYCREATIVE-helloBEEprusa.stl", "platform_offset": [-226, -75, -196], "file_formats": "text/x-gcode", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "hBp_extruder_left", @@ -53,4 +52,4 @@ "retraction_speed": { "default_value": 15.0}, "retraction_amount": { "default_value": 1.5} } -} +} \ No newline at end of file diff --git a/resources/definitions/imade3d_jellybox.def.json b/resources/definitions/imade3d_jellybox.def.json index 42bf61f388..b234e4b2cd 100644 --- a/resources/definitions/imade3d_jellybox.def.json +++ b/resources/definitions/imade3d_jellybox.def.json @@ -9,7 +9,6 @@ "platform": "imade3d_jellybox_platform.stl", "platform_offset": [ 0, -0.3, 0], "file_formats": "text/x-gcode", - "preferred_material": "generic_pla_175", "preferred_variant_name": "0.4 mm", "preferred_quality_type": "fast", "has_materials": true, diff --git a/resources/definitions/julia.def.json b/resources/definitions/julia.def.json index 8a9402b332..7fdee30272 100644 --- a/resources/definitions/julia.def.json +++ b/resources/definitions/julia.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Fracktal", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/makerbotreplicator.def.json b/resources/definitions/makerbotreplicator.def.json index 77aa5ab667..3d690990ce 100644 --- a/resources/definitions/makerbotreplicator.def.json +++ b/resources/definitions/makerbotreplicator.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "MakerBot", "file_formats": "application/x3g", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json index 855fe58cd2..a3f4f81ecf 100644 --- a/resources/definitions/malyan_m200.def.json +++ b/resources/definitions/malyan_m200.def.json @@ -11,7 +11,6 @@ "platform": "malyan_m200_platform.stl", "has_machine_quality": true, "has_materials": true, - "preferred_material": "generic_pla_175", "preferred_quality_type": "normal", "supports_usb_connection": true, "visible": true, diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json index 39b3d018bf..15ba889efc 100644 --- a/resources/definitions/mankati_fullscale_xt_plus.def.json +++ b/resources/definitions/mankati_fullscale_xt_plus.def.json @@ -7,8 +7,7 @@ "author": "RBC", "manufacturer": "Mankati", "file_formats": "text/x-gcode", - "platform": "mankati_fullscale_xt_plus_platform.stl", - "preferred_material": "generic_pla_175" + "platform": "mankati_fullscale_xt_plus_platform.stl" }, "overrides": { "machine_name": { "default_value": "Mankati Fullscale XT Plus" }, diff --git a/resources/definitions/ord.def.json b/resources/definitions/ord.def.json index 471385cc7c..3238583ceb 100644 --- a/resources/definitions/ord.def.json +++ b/resources/definitions/ord.def.json @@ -7,7 +7,6 @@ "author": "Ultimaker", "manufacturer": "ORD Solutions", "file_formats": "text/x-gcode", - "preferred_material": "generic_pla_175", "machine_extruder_trains": { "0": "ord_extruder_0", diff --git a/resources/definitions/printrbot_play.def.json b/resources/definitions/printrbot_play.def.json index 3f98aff798..36ef93e60c 100644 --- a/resources/definitions/printrbot_play.def.json +++ b/resources/definitions/printrbot_play.def.json @@ -7,8 +7,7 @@ "author": "Chris Pearson", "manufacturer": "Printrbot", "file_formats": "text/x-gcode", - "platform": "printrbot_play.stl", - "preferred_material": "generic_pla_175" + "platform": "printrbot_play.stl" }, "overrides": { diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index 52472fd743..7c86617ce5 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -8,8 +8,7 @@ "manufacturer": "PrintrBot", "platform": "printrbot_simple_metal_platform.stl", "platform_offset": [0, -3.45, 0], - "file_formats": "text/x-gcode", - "preferred_material": "generic_pla_175" + "file_formats": "text/x-gcode" }, "overrides": { diff --git a/resources/definitions/printrbot_simple_extended.def.json b/resources/definitions/printrbot_simple_extended.def.json index 9463af5554..95395efb23 100644 --- a/resources/definitions/printrbot_simple_extended.def.json +++ b/resources/definitions/printrbot_simple_extended.def.json @@ -8,8 +8,7 @@ "manufacturer": "PrintrBot", "platform": "printrbot_simple_metal_upgrade.stl", "platform_offset": [0, -0.3, 0], - "file_formats": "text/x-gcode", - "preferred_material": "generic_pla_175" + "file_formats": "text/x-gcode" }, "overrides": { diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json index b70e2ab1dc..e58eb4d903 100644 --- a/resources/definitions/prusa_i3_mk2.def.json +++ b/resources/definitions/prusa_i3_mk2.def.json @@ -9,8 +9,7 @@ "file_formats": "text/x-gcode", "icon": "icon_ultimaker2", "platform": "prusai3_platform.stl", - "has_materials": true, - "preferred_material": "generic_pla_175" + "has_materials": true }, "overrides": { diff --git a/resources/definitions/punchtec_connect_xl.def.json b/resources/definitions/punchtec_connect_xl.def.json index c1f5780270..02d3562b41 100644 --- a/resources/definitions/punchtec_connect_xl.def.json +++ b/resources/definitions/punchtec_connect_xl.def.json @@ -12,8 +12,7 @@ "0": "punchtec_connect_xl_extruder_0", "1": "punchtec_connect_xl_extruder_1" }, - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/rigid3d.def.json b/resources/definitions/rigid3d.def.json index 21673e0010..97b0ebd276 100644 --- a/resources/definitions/rigid3d.def.json +++ b/resources/definitions/rigid3d.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/rigid3d_3rdgen.def.json b/resources/definitions/rigid3d_3rdgen.def.json index b5c2ae87ce..46c22bfa57 100644 --- a/resources/definitions/rigid3d_3rdgen.def.json +++ b/resources/definitions/rigid3d_3rdgen.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/rigid3d_hobby.def.json b/resources/definitions/rigid3d_hobby.def.json index 4b18521319..872cc3e6f4 100644 --- a/resources/definitions/rigid3d_hobby.def.json +++ b/resources/definitions/rigid3d_hobby.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/rigid3d_zero.def.json b/resources/definitions/rigid3d_zero.def.json index 44e5e7e96a..56fb8284c0 100644 --- a/resources/definitions/rigid3d_zero.def.json +++ b/resources/definitions/rigid3d_zero.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Rigid3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/robo_3d_r1.def.json b/resources/definitions/robo_3d_r1.def.json index 1c87e4575f..b179779c59 100644 --- a/resources/definitions/robo_3d_r1.def.json +++ b/resources/definitions/robo_3d_r1.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Robo 3D", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/definitions/tam.def.json b/resources/definitions/tam.def.json index 11833b7841..20bc96358d 100644 --- a/resources/definitions/tam.def.json +++ b/resources/definitions/tam.def.json @@ -10,7 +10,6 @@ "platform": "tam_series1.stl", "platform_offset": [-580.0, -6.23, 253.5], "has_materials": false, - "preferred_material": "generic_pla_175", "supported_actions":["UpgradeFirmware"] }, "overrides": { diff --git a/resources/definitions/zone3d_printer.def.json b/resources/definitions/zone3d_printer.def.json index b7f852054a..bac8968951 100644 --- a/resources/definitions/zone3d_printer.def.json +++ b/resources/definitions/zone3d_printer.def.json @@ -7,8 +7,7 @@ "author": "Ultimaker", "manufacturer": "Unknown", "file_formats": "text/x-gcode", - "platform_offset": [ 0, 0, 0], - "preferred_material": "generic_pla_175" + "platform_offset": [ 0, 0, 0] }, "overrides": { diff --git a/resources/extruders/punchtec_connect_xl_extruder_0.def.json b/resources/extruders/punchtec_connect_xl_extruder_left.def.json similarity index 100% rename from resources/extruders/punchtec_connect_xl_extruder_0.def.json rename to resources/extruders/punchtec_connect_xl_extruder_left.def.json diff --git a/resources/extruders/punchtec_connect_xl_extruder_1.def.json b/resources/extruders/punchtec_connect_xl_extruder_right.def.json similarity index 100% rename from resources/extruders/punchtec_connect_xl_extruder_1.def.json rename to resources/extruders/punchtec_connect_xl_extruder_right.def.json From 1538486e852e9208a1a447c87a23f9a88e33ff52 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 21:35:50 +0100 Subject: [PATCH 024/266] WIP: Change low quality_type to fast "low" is "fast", and the majority is using "fast". --- resources/quality/{low.inst.cfg => fast.inst.cfg} | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg | 2 +- .../quality/ultimaker2/{um2_low.inst.cfg => um2_fast.inst.cfg} | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename resources/quality/{low.inst.cfg => fast.inst.cfg} (94%) rename resources/quality/ultimaker2/{um2_low.inst.cfg => um2_fast.inst.cfg} (93%) diff --git a/resources/quality/low.inst.cfg b/resources/quality/fast.inst.cfg similarity index 94% rename from resources/quality/low.inst.cfg rename to resources/quality/fast.inst.cfg index 25cb71e2bc..4b78cfcd75 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/fast.inst.cfg @@ -6,7 +6,7 @@ definition = fdmprinter [metadata] setting_version = 4 type = quality -quality_type = low +quality_type = fast weight = -1 global_quality = True diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index 440575a066..947fd0774d 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -6,7 +6,7 @@ definition = kemiq_q2_beta [metadata] setting_version = 4 type = quality -quality_type = low +quality_type = fast weight = -1 material = generic_abs diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index 12ca8ed571..cc7d877c70 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -6,7 +6,7 @@ definition = kemiq_q2_beta [metadata] setting_version = 4 type = quality -quality_type = low +quality_type = fast weight = -1 material = generic_pla diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index 51368f1b1b..a71c3c731b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -6,7 +6,7 @@ definition = kemiq_q2_gama [metadata] setting_version = 4 type = quality -quality_type = low +quality_type = fast weight = -1 material = generic_pla diff --git a/resources/quality/ultimaker2/um2_low.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg similarity index 93% rename from resources/quality/ultimaker2/um2_low.inst.cfg rename to resources/quality/ultimaker2/um2_fast.inst.cfg index acd6c849d1..1292613642 100644 --- a/resources/quality/ultimaker2/um2_low.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -6,7 +6,7 @@ definition = ultimaker2 [metadata] setting_version = 4 type = quality -quality_type = low +quality_type = fast weight = -1 [values] From 0349c1c5d73d03accbcfe6033879c287d3d7d444 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 21:38:17 +0100 Subject: [PATCH 025/266] WIP: Fix Cartesio quality_type "Extra coarse" -> "extra coarse" --- resources/quality/extra_coarse.inst.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index 6c11c9e61b..bc8257a97f 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -6,7 +6,7 @@ definition = fdmprinter [metadata] setting_version = 4 type = quality -quality_type = Extra coarse +quality_type = extra coarse weight = -4 global_quality = True From df1d2f137b5a2772a30587ee1e9b5ab621213b6a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 21:40:40 +0100 Subject: [PATCH 026/266] WIP: Add material-diameter mapping to fix preferred material lookup --- cura/Machines/MaterialManager.py | 75 +++++++++++++++---------------- cura/Settings/CuraStackBuilder.py | 2 + 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 880ef399bf..bd827fe5ba 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -1,3 +1,4 @@ +from collections import defaultdict from typing import Optional from PyQt5.Qt import QTimer, QObject, pyqtSignal @@ -37,6 +38,7 @@ class MaterialManager(QObject): self._fallback_materials_map = dict() # material_type -> generic material metadata self._material_group_map = dict() # root_material_id -> MaterialGroup self._diameter_machine_variant_material_map = dict() # diameter -> dict(machine_definition_id -> MaterialNode) + self._material_diameter_map = defaultdict() # root_material_id -> diameter -> root_material_id for that diameter # The machine definition ID for the non-machine-specific materials. # This is used as the last fallback option if the given machine-specific material(s) cannot be found. @@ -58,7 +60,7 @@ class MaterialManager(QObject): self._material_group_map = {} self._diameter_machine_variant_material_map = {} - # Table #1 + # Map #1 # root_material_id -> MaterialGroup for material_metadata in material_metadata_list: material_id = material_metadata["id"] @@ -78,7 +80,7 @@ class MaterialManager(QObject): new_node = MaterialNode(material_metadata) group.derived_material_node_list.append(new_node) - # Table #2 + # Map #2 # Lookup table for material type -> fallback material metadata grouped_by_type_dict = dict() for root_material_id, material_node in self._material_group_map.items(): @@ -91,7 +93,35 @@ class MaterialManager(QObject): grouped_by_type_dict[material_type] = material_node.root_material_node.metadata self._fallback_materials_map = grouped_by_type_dict - # Table #3 + # Map #3 + # There can be multiple material profiles for the same material with different diameters, such as "generic_pla" + # and "generic_pla_175". This is inconvenient when we do material-specific quality lookup because a quality can + # be for either "generic_pla" or "generic_pla_175", but not both. This map helps to get the correct material ID + # for quality search. + self._material_diameter_map = defaultdict(defaultdict) + + # Group the material IDs by the same name, material, brand, and color but with different diameters. + material_group_dict = dict() + keys_to_fetch = ("name", "material", "brand", "color") + for root_material_id, machine_node in self._material_group_map.items(): + root_material_metadata = machine_node.root_material_node.metadata + + key_data = [] + for key in keys_to_fetch: + key_data.append(root_material_metadata.get(key)) + key_data = tuple(key_data) + + if key_data not in material_group_dict: + material_group_dict[key_data] = dict() + approximate_diameter = root_material_metadata.get("approximate_diameter") + material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"] + + for data_dict in material_group_dict.values(): + for rmid1 in data_dict.values(): + for ad2, rmid2 in data_dict.items(): + self._material_diameter_map[rmid1][ad2] = rmid2 + + # Map #4 # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer for material_metadata in material_metadata_list: @@ -148,43 +178,8 @@ class MaterialManager(QObject): def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: return self._material_group_map.get(root_material_id) - def _test_metadata(self): - # print all metadata - import os - with open("c:/workspace/guid_map.txt", "w", encoding = "utf-8") as f: - for machine_id, node in self._guid_to_root_materials_map.items(): - f.write((" - %s -> %s" % (machine_id, node.metadata["id"])) + os.linesep) - - if False: - with open("c:/workspace/material_map.txt", "w", encoding = "utf-8") as f: - for machine_id in self._machine_variant_material_map: - f.write((" -> %s" % machine_id) + os.linesep) - - test_cases = [{"machine": "ultimaker3", "variant": "AA 0.4", "material": "generic_pla", "diameter": 2.85}, - {"machine": "ultimaker2_plus", "variant": None, "material": "generic_abs", "diameter": 2.85}, - {"machine": "fdmprinter", "variant": None, "material": "generic_cpe", "diameter": 2.85}, - {"machine": "fdmprinter", "variant": None, "material": "generic_abs_175", "diameter": 2.85}, - {"machine": "fdmprinter", "variant": None, "material": "generic_nylon", "diameter": 1.75}, - {"machine": "fdmprinter", "variant": None, "material": "generic_nylon_175", "diameter": 1.75}, - ] - for tc in test_cases: - result = self.getMaterialNode( - tc['machine'], - tc['variant'], - tc['diameter'], - tc['material']) - tc['result_id'] = result.getContainer().getId() if result else "None" - Logger.log("d", "!!!!!!!! MaterialManager test: %s", tc) - - # test available materials - with open("c:/workspace/test.txt", "w", encoding="utf-8") as f: - for tc in test_cases: - result = self.getAvailableMaterials(tc['machine'], - tc['variant'], - tc['diameter']) - f.write("--- [%s] [%s] [%s]:" % (tc['machine'], tc['variant'], tc['diameter']) + "\n") - for r, md in result.items(): - f.write(" - %s -> %s" % (r, md["id"]) + "\n") + def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str: + return self._material_diameter_map.get(root_material_id).get(approximate_diameter, root_material_id) # # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 19a5caacb8..c50b034471 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -55,7 +55,9 @@ class CuraStackBuilder: # Only look for the preferred material if this machine has materials if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): material_diameter = machine_definition.getProperty("material_diameter", "value") + approximate_material_diameter = str(round(material_diameter)) root_material_id = machine_definition.getMetaDataEntry("preferred_material") + root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) material_node = material_manager.getMaterialNode(definition_id, variant_name, material_diameter, root_material_id) # Sanity check. If you see this error, the related definition files should be fixed. if not material_node: From 4af176dbf39a58fd59b8a613ba64407df3313204 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 21:48:04 +0100 Subject: [PATCH 027/266] WIP: Rename function to getVariantNode() --- cura/Machines/VariantManager.py | 4 ++-- cura/Settings/CuraStackBuilder.py | 2 +- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 1f9f0288ac..555dfec4a3 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -72,8 +72,8 @@ class VariantManager: # Gets the variant InstanceContainer with the given information. # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. # - def getVariant(self, machine_type_name: str, variant_name: str, - variant_type: Optional[str] = None) -> Optional["InstanceContainer"]: + def getVariantNode(self, machine_type_name: str, variant_name: str, + variant_type: Optional[str] = None) -> Optional["InstanceContainer"]: return self._machine_to_variant_dict_map[machine_type_name].get(variant_name) def getVariantNodes(self, machine: "GlobalStack"): diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index c50b034471..c396a4a2be 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -44,7 +44,7 @@ class CuraStackBuilder: if parseBool(machine_definition.getMetaDataEntry("has_variants", False)): variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") if variant_name: - variant_node = variant_manager.getVariant(definition_id, variant_name) + variant_node = variant_manager.getVariantNode(definition_id, variant_name) # Sanity check. If you see this error, the related definition files should be fixed. if variant_node is None: raise RuntimeError("Cannot find variant with definition [%s] and variant name [%s]" % (definition_id, variant_name)) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 54aaedb8f9..36a7733568 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -592,10 +592,9 @@ class XmlMaterialProfile(InstanceContainer): from cura.Machines.VariantManager import VariantType variant_manager = CuraApplication.getInstance().getVariantManager() - variant_node = variant_manager.getVariant(machine_id, VariantType.BUILD_PLATE, buildplate_id) + variant_node = variant_manager.getVariantNode(machine_id, buildplate_id) if not variant_node: continue - variant_metadata = variant_node.metadata # TODO: check if build plate variant exists @@ -623,7 +622,7 @@ class XmlMaterialProfile(InstanceContainer): continue variant_manager = CuraApplication.getInstance().getVariantManager() - variant_node = variant_manager.getVariant(machine_id, hotend_name) + variant_node = variant_manager.getVariantNode(machine_id, hotend_name) if not variant_node: continue From 12164a0c888e251911ed81e9595d56215dd09d80 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 22:00:00 +0100 Subject: [PATCH 028/266] WIP: Remove set..ById()s in CuraContainerStack --- cura/Settings/CuraContainerRegistry.py | 12 +-- cura/Settings/CuraContainerStack.py | 113 ------------------------- tests/Settings/TestExtruderStack.py | 59 ------------- tests/Settings/TestGlobalStack.py | 72 ---------------- 4 files changed, 6 insertions(+), 250 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index be5a10e293..e18710e46d 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -579,21 +579,21 @@ class CuraContainerRegistry(ContainerRegistry): variant_id = machine.variant.getId() else: variant_id = "empty_variant" - extruder_stack.setVariantById(variant_id) + extruder_stack.variant = self.findInstanceContainers(id = variant_id)[0] material_id = "default" if machine.material.getId() not in ("empty", "empty_material"): material_id = machine.material.getId() else: material_id = "empty_material" - extruder_stack.setMaterialById(material_id) + extruder_stack.material = self.findInstanceContainers(id = material_id)[0] quality_id = "default" if machine.quality.getId() not in ("empty", "empty_quality"): quality_id = machine.quality.getId() else: quality_id = "empty_quality" - extruder_stack.setQualityById(quality_id) + extruder_stack.quality = self.findInstanceContainers(id = quality_id)[0] machine_quality_changes = machine.qualityChanges if new_global_quality_changes is not None: @@ -605,7 +605,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_quality_changes_container = extruder_quality_changes_container[0] quality_changes_id = extruder_quality_changes_container.getId() - extruder_stack.setQualityChangesById(quality_changes_id) + extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0] else: # Some extruder quality_changes containers can be created at runtime as files in the qualities # folder. Those files won't be loaded in the registry immediately. So we also need to search @@ -614,7 +614,7 @@ class CuraContainerRegistry(ContainerRegistry): if extruder_quality_changes_container: quality_changes_id = extruder_quality_changes_container.getId() extruder_quality_changes_container.addMetaDataEntry("extruder", extruder_stack.definition.getId()) - extruder_stack.setQualityChangesById(quality_changes_id) + extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0] else: # if we still cannot find a quality changes container for the extruder, create a new one container_name = machine_quality_changes.getName() @@ -649,7 +649,7 @@ class CuraContainerRegistry(ContainerRegistry): machine_quality_changes.removeInstance(qc_setting_key, postpone_emit=True) else: - extruder_stack.setQualityChangesById("empty_quality_changes") + extruder_stack.qualityChanges = self.findInstanceContainers(id = "empty_quality_changes")[0] self.addContainer(extruder_stack) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 93e4b55bba..c2fd4ba2f4 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -83,20 +83,6 @@ class CuraContainerStack(ContainerStack): def setQualityChanges(self, new_quality_changes: InstanceContainer, postpone_emit = False) -> None: self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes, postpone_emit = postpone_emit) - ## Set the quality changes container by an ID. - # - # This will search for the specified container and set it. If no container was found, an error will be raised. - # - # \param new_quality_changes_id The ID of the new quality changes container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setQualityChangesById(self, new_quality_changes_id: str) -> None: - quality_changes = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_changes_id) - if quality_changes: - self.setQualityChanges(quality_changes[0]) - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_changes_id)) - ## Get the quality changes container. # # \return The quality changes container. Should always be a valid container, but can be equal to the empty InstanceContainer. @@ -110,31 +96,6 @@ class CuraContainerStack(ContainerStack): def setQuality(self, new_quality: InstanceContainer, postpone_emit = False) -> None: self.replaceContainer(_ContainerIndexes.Quality, new_quality, postpone_emit = postpone_emit) - ## Set the quality container by an ID. - # - # This will search for the specified container and set it. If no container was found, an error will be raised. - # There is a special value for ID, which is "default". The "default" value indicates the quality should be set - # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultQuality - # for details. - # - # \param new_quality_id The ID of the new quality container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setQualityById(self, new_quality_id: str) -> None: - quality = self._empty_quality - if new_quality_id == "default": - new_quality = self.findDefaultQuality() - if new_quality: - quality = new_quality - else: - qualities = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_id) - if qualities: - quality = qualities[0] - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_id)) - - self.setQuality(quality) - ## Get the quality container. # # \return The quality container. Should always be a valid container, but can be equal to the empty InstanceContainer. @@ -148,31 +109,6 @@ class CuraContainerStack(ContainerStack): def setMaterial(self, new_material: InstanceContainer, postpone_emit = False) -> None: self.replaceContainer(_ContainerIndexes.Material, new_material, postpone_emit = postpone_emit) - ## Set the material container by an ID. - # - # This will search for the specified container and set it. If no container was found, an error will be raised. - # There is a special value for ID, which is "default". The "default" value indicates the quality should be set - # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultMaterial - # for details. - # - # \param new_material_id The ID of the new material container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setMaterialById(self, new_material_id: str) -> None: - material = self._empty_material - if new_material_id == "default": - new_material = self.findDefaultMaterial() - if new_material: - material = new_material - else: - materials = ContainerRegistry.getInstance().findInstanceContainers(id = new_material_id) - if materials: - material = materials[0] - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_material_id)) - - self.setMaterial(material) - ## Get the material container. # # \return The material container. Should always be a valid container, but can be equal to the empty InstanceContainer. @@ -186,31 +122,6 @@ class CuraContainerStack(ContainerStack): def setVariant(self, new_variant: InstanceContainer) -> None: self.replaceContainer(_ContainerIndexes.Variant, new_variant) - ## Set the variant container by an ID. - # - # This will search for the specified container and set it. If no container was found, an error will be raised. - # There is a special value for ID, which is "default". The "default" value indicates the quality should be set - # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultVariant - # for details. - # - # \param new_variant_id The ID of the new variant container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setVariantById(self, new_variant_id: str) -> None: - variant = self._empty_variant - if new_variant_id == "default": - new_variant = self.findDefaultVariantBuildplate() if self.getMetaDataEntry("type") == "machine" else self.findDefaultVariant() - if new_variant: - variant = new_variant - else: - variants = ContainerRegistry.getInstance().findInstanceContainers(id = new_variant_id) - if variants: - variant = variants[0] - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_variant_id)) - - self.setVariant(variant) - ## Get the variant container. # # \return The variant container. Should always be a valid container, but can be equal to the empty InstanceContainer. @@ -224,18 +135,6 @@ class CuraContainerStack(ContainerStack): def setDefinitionChanges(self, new_definition_changes: InstanceContainer) -> None: self.replaceContainer(_ContainerIndexes.DefinitionChanges, new_definition_changes) - ## Set the definition changes container by an ID. - # - # \param new_definition_changes_id The ID of the new definition changes container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setDefinitionChangesById(self, new_definition_changes_id: str) -> None: - new_definition_changes = ContainerRegistry.getInstance().findInstanceContainers(id = new_definition_changes_id) - if new_definition_changes: - self.setDefinitionChanges(new_definition_changes[0]) - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_definition_changes_id)) - ## Get the definition changes container. # # \return The definition changes container. Should always be a valid container, but can be equal to the empty InstanceContainer. @@ -249,18 +148,6 @@ class CuraContainerStack(ContainerStack): def setDefinition(self, new_definition: DefinitionContainerInterface) -> None: self.replaceContainer(_ContainerIndexes.Definition, new_definition) - ## Set the definition container by an ID. - # - # \param new_definition_id The ID of the new definition container. - # - # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID. - def setDefinitionById(self, new_definition_id: str) -> None: - new_definition = ContainerRegistry.getInstance().findDefinitionContainers(id = new_definition_id) - if new_definition: - self.setDefinition(new_definition[0]) - else: - raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_definition_id)) - ## Get the definition container. # # \return The definition container. Should always be a valid container, but can be equal to the empty InstanceContainer. diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index e1538cd3fc..ce829da4b3 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -325,30 +325,6 @@ def test_removeContainer(extruder_stack): with pytest.raises(InvalidOperationError): extruder_stack.removeContainer(unittest.mock.MagicMock()) -## Tests setting definitions by specifying an ID of a definition that exists. -def test_setDefinitionByIdExists(extruder_stack, container_registry): - container_registry.return_value = DefinitionContainer(container_id = "some_definition") - extruder_stack.setDefinitionById("some_definition") - assert extruder_stack.definition.getId() == "some_definition" - -## Tests setting definitions by specifying an ID of a definition that doesn't -# exist. -def test_setDefinitionByIdDoesntExist(extruder_stack): - with pytest.raises(InvalidContainerError): - extruder_stack.setDefinitionById("some_definition") #Container registry is empty now. - -## Tests setting materials by specifying an ID of a material that exists. -def test_setMaterialByIdExists(extruder_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "material") - extruder_stack.setMaterialById("InstanceContainer") - assert extruder_stack.material.getId() == "InstanceContainer" - -## Tests setting materials by specifying an ID of a material that doesn't -# exist. -def test_setMaterialByIdDoesntExist(extruder_stack): - with pytest.raises(InvalidContainerError): - extruder_stack.setMaterialById("some_material") #Container registry is empty now. - ## Tests setting properties directly on the extruder stack. @pytest.mark.parametrize("key, property, value", [ ("layer_height", "value", 0.1337), @@ -387,38 +363,3 @@ def test_setPropertyOtherContainers(target_container, stack_variable, extruder_s extruder_stack.setProperty(key, property, value, target_container = target_container) #The actual test. getattr(extruder_stack, stack_variable).setProperty.assert_called_once_with(key, property, value) #Make sure that the proper container gets a setProperty call. - -## Tests setting qualities by specifying an ID of a quality that exists. -def test_setQualityByIdExists(extruder_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "quality") - extruder_stack.setQualityById("InstanceContainer") - assert extruder_stack.quality.getId() == "InstanceContainer" - -## Tests setting qualities by specifying an ID of a quality that doesn't exist. -def test_setQualityByIdDoesntExist(extruder_stack): - with pytest.raises(InvalidContainerError): - extruder_stack.setQualityById("some_quality") #Container registry is empty now. - -## Tests setting quality changes by specifying an ID of a quality change that -# exists. -def test_setQualityChangesByIdExists(extruder_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "quality_changes") - extruder_stack.setQualityChangesById("InstanceContainer") - assert extruder_stack.qualityChanges.getId() == "InstanceContainer" - -## Tests setting quality changes by specifying an ID of a quality change that -# doesn't exist. -def test_setQualityChangesByIdDoesntExist(extruder_stack): - with pytest.raises(InvalidContainerError): - extruder_stack.setQualityChangesById("some_quality_changes") #Container registry is empty now. - -## Tests setting variants by specifying an ID of a variant that exists. -def test_setVariantByIdExists(extruder_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "variant") - extruder_stack.setVariantById("InstanceContainer") - assert extruder_stack.variant.getId() == "InstanceContainer" - -## Tests setting variants by specifying an ID of a variant that doesn't exist. -def test_setVariantByIdDoesntExist(extruder_stack): - with pytest.raises(InvalidContainerError): - extruder_stack.setVariantById("some_variant") #Container registry is empty now. diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 9b0735c8f2..dc786b2df4 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -486,43 +486,6 @@ def test_removeContainer(global_stack): with pytest.raises(InvalidOperationError): global_stack.removeContainer(unittest.mock.MagicMock()) -## Tests setting definitions by specifying an ID of a definition that exists. -def test_setDefinitionByIdExists(global_stack, container_registry): - container_registry.return_value = DefinitionContainer(container_id = "some_definition") - global_stack.setDefinitionById("some_definition") - assert global_stack.definition.getId() == "some_definition" - -## Tests setting definitions by specifying an ID of a definition that doesn't -# exist. -def test_setDefinitionByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setDefinitionById("some_definition") #Container registry is empty now. - -## Tests setting definition changes by specifying an ID of a container that -# exists. -def test_setDefinitionChangesByIdExists(global_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "definition_changes") - global_stack.setDefinitionChangesById("InstanceContainer") - assert global_stack.definitionChanges.getId() == "InstanceContainer" - -## Tests setting definition changes by specifying an ID of a container that -# doesn't exist. -def test_setDefinitionChangesByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setDefinitionChangesById("some_definition_changes") #Container registry is empty now. - -## Tests setting materials by specifying an ID of a material that exists. -def test_setMaterialByIdExists(global_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "material") - global_stack.setMaterialById("InstanceContainer") - assert global_stack.material.getId() == "InstanceContainer" - -## Tests setting materials by specifying an ID of a material that doesn't -# exist. -def test_setMaterialByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setMaterialById("some_material") #Container registry is empty now. - ## Tests whether changing the next stack is properly forbidden. def test_setNextStack(global_stack): with pytest.raises(InvalidOperationError): @@ -568,41 +531,6 @@ def test_setPropertyOtherContainers(target_container, stack_variable, global_sta getattr(global_stack, stack_variable).setProperty.assert_called_once_with(key, property, value) #Make sure that the proper container gets a setProperty call. -## Tests setting qualities by specifying an ID of a quality that exists. -def test_setQualityByIdExists(global_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "quality") - global_stack.setQualityById("InstanceContainer") - assert global_stack.quality.getId() == "InstanceContainer" - -## Tests setting qualities by specifying an ID of a quality that doesn't exist. -def test_setQualityByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setQualityById("some_quality") #Container registry is empty now. - -## Tests setting quality changes by specifying an ID of a quality change that -# exists. -def test_setQualityChangesByIdExists(global_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "quality_changes") - global_stack.setQualityChangesById("InstanceContainer") - assert global_stack.qualityChanges.getId() == "InstanceContainer" - -## Tests setting quality changes by specifying an ID of a quality change that -# doesn't exist. -def test_setQualityChangesByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setQualityChangesById("some_quality_changes") #Container registry is empty now. - -## Tests setting variants by specifying an ID of a variant that exists. -def test_setVariantByIdExists(global_stack, container_registry): - container_registry.return_value = getInstanceContainer(container_type = "variant") - global_stack.setVariantById("InstanceContainer") - assert global_stack.variant.getId() == "InstanceContainer" - -## Tests setting variants by specifying an ID of a variant that doesn't exist. -def test_setVariantByIdDoesntExist(global_stack): - with pytest.raises(InvalidContainerError): - global_stack.setVariantById("some_variant") #Container registry is empty now. - ## Smoke test for findDefaultVariant def test_smoke_findDefaultVariant(global_stack): global_stack.findDefaultVariant() From f4d69918fb8bb49ea03a9a0df84868cf4b4ca9e4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 22:05:11 +0100 Subject: [PATCH 029/266] WIP: Remove findDefault..()s --- cura/Settings/CuraContainerStack.py | 237 ---------------------------- cura/Settings/ExtruderStack.py | 5 - tests/Settings/TestGlobalStack.py | 12 -- 3 files changed, 254 deletions(-) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index c2fd4ba2f4..00db4f57c7 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -282,243 +282,6 @@ class CuraContainerStack(ContainerStack): self._containers = new_containers - ## Find the variant that should be used as "default" variant. - # - # This will search for variants that match the current definition and pick the preferred one, - # if specified by the machine definition. - # - # The following criteria are used to find the default variant: - # - If the machine definition does not have a metadata entry "has_variants" set to True, return None - # - The definition of the variant should be the same as the machine definition for this stack. - # - The container should have a metadata entry "type" with value "variant". - # - If the machine definition has a metadata entry "preferred_variant", filter the variant IDs based on that. - # - # \return The container that should be used as default, or None if nothing was found or the machine does not use variants. - # - # \note This method assumes the stack has a valid machine definition. - def findDefaultVariant(self) -> Optional[ContainerInterface]: - definition = self._getMachineDefinition() - # has_variants can be overridden in other containers and stacks. - # In the case of UM2, it is overridden in the GlobalStack - if not self.getMetaDataEntry("has_variants"): - # If the machine does not use variants, we should never set a variant. - return None - - # First add any variant. Later, overwrite with preference if the preference is valid. - variant = None - definition_id = self._findInstanceContainerDefinitionId(definition) - variants = ContainerRegistry.getInstance().findInstanceContainers(definition = definition_id, type = "variant") - if variants: - variant = variants[0] - - preferred_variant_id = definition.getMetaDataEntry("preferred_variant") - if preferred_variant_id: - preferred_variants = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id, definition = definition_id, type = "variant") - if preferred_variants: - variant = preferred_variants[0] - else: - Logger.log("w", "The preferred variant \"{variant}\" of stack {stack} does not exist or is not a variant.", variant = preferred_variant_id, stack = self.id) - # And leave it at the default variant. - - if variant: - return variant - - Logger.log("w", "Could not find a valid default variant for stack {stack}", stack = self.id) - return None - - ## Find the global variant that should be used as "default". This is used for the buildplates. - # - # This will search for variants that match the current definition and pick the preferred one, - # if specified by the machine definition. - # - # The following criteria are used to find the default global variant: - # - If the machine definition does not have a metadata entry "has_variant_buildplates" set to True, return None - # - The definition of the variant should be the same as the machine definition for this stack. - # - The container should have a metadata entry "type" with value "variant" and "hardware_type" with value "buildplate". - # - If the machine definition has a metadata entry "preferred_variant_buildplate", filter the variant IDs based on that. - # - # \return The container that should be used as default, or None if nothing was found or the machine does not use variants. - # - # \note This method assumes the stack has a valid machine definition. - def findDefaultVariantBuildplate(self) -> Optional[ContainerInterface]: - definition = self._getMachineDefinition() - # has_variant_buildplates can be overridden in other containers and stacks. - # In the case of UM2, it is overridden in the GlobalStack - if not self.getMetaDataEntry("has_variant_buildplates"): - # If the machine does not use variants, we should never set a variant. - return None - - # First add any variant. Later, overwrite with preference if the preference is valid. - variant = None - definition_id = self._findInstanceContainerDefinitionId(definition) - variants = ContainerRegistry.getInstance().findInstanceContainers(definition = definition_id, type = "variant", hardware_type = "buildplate") - if variants: - variant = variants[0] - - preferred_variant_buildplate_id = definition.getMetaDataEntry("preferred_variant_buildplate") - if preferred_variant_buildplate_id: - preferred_variant_buildplates = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_buildplate_id, definition = definition_id, type = "variant") - if preferred_variant_buildplates: - variant = preferred_variant_buildplates[0] - else: - Logger.log("w", "The preferred variant buildplate \"{variant}\" of stack {stack} does not exist or is not a variant.", - variant = preferred_variant_buildplate_id, stack = self.id) - # And leave it at the default variant. - - if variant: - return variant - - Logger.log("w", "Could not find a valid default buildplate variant for stack {stack}", stack = self.id) - return None - - ## Find the material that should be used as "default" material. - # - # This will search for materials that match the current definition and pick the preferred one, - # if specified by the machine definition. - # - # The following criteria are used to find the default material: - # - If the machine definition does not have a metadata entry "has_materials" set to True, return None - # - If the machine definition has a metadata entry "has_machine_materials", the definition of the material should - # be the same as the machine definition for this stack. Otherwise, the definition should be "fdmprinter". - # - The container should have a metadata entry "type" with value "material". - # - The material should have an approximate diameter that matches the machine - # - If the machine definition has a metadata entry "has_variants" and set to True, the "variant" metadata entry of - # the material should be the same as the ID of the variant in the stack. Only applies if "has_machine_materials" is also True. - # - If the stack currently has a material set, try to find a material that matches the current material by name. - # - Otherwise, if the machine definition has a metadata entry "preferred_material", try to find a material that matches the specified ID. - # - # \return The container that should be used as default, or None if nothing was found or the machine does not use materials. - def findDefaultMaterial(self) -> Optional[ContainerInterface]: - definition = self._getMachineDefinition() - if not definition.getMetaDataEntry("has_materials"): - # Machine does not use materials, never try to set it. - return None - - search_criteria = {"type": "material"} - if definition.getMetaDataEntry("has_machine_materials"): - search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition) - - if definition.getMetaDataEntry("has_variants"): - search_criteria["variant"] = self.variant.id - else: - search_criteria["definition"] = "fdmprinter" - - if self.material != self._empty_material: - search_criteria["name"] = self.material.name - else: - preferred_material = definition.getMetaDataEntry("preferred_material") - if preferred_material: - search_criteria["id"] = preferred_material - - approximate_material_diameter = str(round(self.getProperty("material_diameter", "value"))) - search_criteria["approximate_diameter"] = approximate_material_diameter - - materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) - if not materials: - Logger.log("w", "The preferred material \"{material}\" could not be found for stack {stack}", material = preferred_material, stack = self.id) - # We failed to find any materials matching the specified criteria, drop some specific criteria and try to find - # a material that sort-of matches what we want. - search_criteria.pop("variant", None) - search_criteria.pop("id", None) - search_criteria.pop("name", None) - materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) - - if not materials: - Logger.log("w", "Could not find a valid material for stack {stack}", stack = self.id) - return None - - for material in materials: - # Prefer a read-only material - if ContainerRegistry.getInstance().isReadOnly(material.getId()): - return material - - return materials[0] - - - ## Find the quality that should be used as "default" quality. - # - # This will search for qualities that match the current definition and pick the preferred one, - # if specified by the machine definition. - # - # \return The container that should be used as default, or None if nothing was found. - def findDefaultQuality(self) -> Optional[ContainerInterface]: - definition = self._getMachineDefinition() - registry = ContainerRegistry.getInstance() - material_container = self.material if self.material.getId() not in (self._empty_material.getId(), self._empty_instance_container.getId()) else None - - search_criteria = {"type": "quality"} - - if definition.getMetaDataEntry("has_machine_quality"): - search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition) - - if definition.getMetaDataEntry("has_materials") and material_container: - search_criteria["material"] = material_container.id - else: - search_criteria["definition"] = "fdmprinter" - - if self.quality != self._empty_quality: - search_criteria["name"] = self.quality.name - else: - preferred_quality = definition.getMetaDataEntry("preferred_quality") - if preferred_quality: - search_criteria["id"] = preferred_quality - - containers = registry.findInstanceContainers(**search_criteria) - if containers: - return containers[0] - - if "material" in search_criteria: - # First check if we can solve our material not found problem by checking if we can find quality containers - # that are assigned to the parents of this material profile. - try: - inherited_files = material_container.getInheritedFiles() - except AttributeError: # Material_container does not support inheritance. - inherited_files = [] - - if inherited_files: - for inherited_file in inherited_files: - # Extract the ID from the path we used to load the file. - search_criteria["material"] = os.path.basename(inherited_file).split(".")[0] - containers = registry.findInstanceContainers(**search_criteria) - if containers: - return containers[0] - - # We still weren't able to find a quality for this specific material. - # Try to find qualities for a generic version of the material. - material_search_criteria = {"type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"} - if definition.getMetaDataEntry("has_machine_quality"): - if self.material != self._empty_instance_container: - material_search_criteria["definition"] = material_container.getMetaDataEntry("definition") - - if definition.getMetaDataEntry("has_variants"): - material_search_criteria["variant"] = material_container.getMetaDataEntry("variant") - else: - material_search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition) - - if definition.getMetaDataEntry("has_variants") and self.variant != self._empty_instance_container: - material_search_criteria["variant"] = self.variant.id - else: - material_search_criteria["definition"] = "fdmprinter" - material_containers = registry.findInstanceContainersMetadata(**material_search_criteria) - # Try all materials to see if there is a quality profile available. - for material_container in material_containers: - search_criteria["material"] = material_container["id"] - - containers = registry.findInstanceContainers(**search_criteria) - if containers: - return containers[0] - - if "name" in search_criteria or "id" in search_criteria: - # If a quality by this name can not be found, try a wider set of search criteria - search_criteria.pop("name", None) - search_criteria.pop("id", None) - - containers = registry.findInstanceContainers(**search_criteria) - if containers: - return containers[0] - - return None - ## protected: # Helper to make sure we emit a PyQt signal on container changes. diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 6f89d33393..a2ff092143 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -187,11 +187,6 @@ class ExtruderStack(CuraContainerStack): if has_global_dependencies: self.getNextStack().propertiesChanged.emit(key, properties) - def findDefaultVariant(self): - # The default variant is defined in the machine stack and/or definition, so use the machine stack to find - # the default variant. - return self.getNextStack().findDefaultVariant() - extruder_stack_mime = MimeType( name = "application/x-cura-extruderstack", diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index dc786b2df4..45ff13aaf3 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -530,15 +530,3 @@ def test_setPropertyOtherContainers(target_container, stack_variable, global_sta global_stack.setProperty(key, property, value, target_container = target_container) #The actual test. getattr(global_stack, stack_variable).setProperty.assert_called_once_with(key, property, value) #Make sure that the proper container gets a setProperty call. - -## Smoke test for findDefaultVariant -def test_smoke_findDefaultVariant(global_stack): - global_stack.findDefaultVariant() - -## Smoke test for findDefaultMaterial -def test_smoke_findDefaultMaterial(global_stack): - global_stack.findDefaultMaterial() - -## Smoke test for findDefaultQuality -def test_smoke_findDefaultQuality(global_stack): - global_stack.findDefaultQuality() From 13d745f07d2abcae26028b65ce1e431abca9af80 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 22:27:07 +0100 Subject: [PATCH 030/266] WIP: Move NozzleModel.py --- cura/CuraApplication.py | 4 +--- cura/{Settings => Machines/Models}/NozzleModel.py | 0 cura/Machines/Models/__init__.py | 0 cura/Settings/MachineManager.py | 3 --- 4 files changed, 1 insertion(+), 6 deletions(-) rename cura/{Settings => Machines/Models}/NozzleModel.py (100%) create mode 100644 cura/Machines/Models/__init__.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index dc0a65be1d..b1ec388f48 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -52,7 +52,7 @@ from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyT from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator -from cura.Settings.NozzleModel import NozzleModel +from cura.Machines.Models.NozzleModel import NozzleModel from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel @@ -61,8 +61,6 @@ from cura.Settings.UserProfilesModel import UserProfilesModel from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Machines.VariantManager import VariantManager -from cura.Machines.QualityManager import QualityGroup - from . import PlatformPhysics from . import BuildVolume diff --git a/cura/Settings/NozzleModel.py b/cura/Machines/Models/NozzleModel.py similarity index 100% rename from cura/Settings/NozzleModel.py rename to cura/Machines/Models/NozzleModel.py diff --git a/cura/Machines/Models/__init__.py b/cura/Machines/Models/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 752353fe79..f5996bcf0f 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -122,9 +122,6 @@ class MachineManager(QObject): # Make sure _active_container_stack is properly initiated ExtruderManager.getInstance().setActiveExtruderIndex(0) - self._auto_materials_changed = {} - self._auto_hotends_changed = {} - self._material_incompatible_message = Message(catalog.i18nc("@info:status", "The selected material is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Incompatible Material")) From 9ffe89b49c351e65b8fee9313cfc40340882054b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 22:27:35 +0100 Subject: [PATCH 031/266] WIP: Remove setActiveVariant() --- cura/Settings/MachineManager.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f5996bcf0f..4871886542 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -749,27 +749,6 @@ class MachineManager(QObject): self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes) - @pyqtSlot(str) - def setActiveVariant(self, variant_id: str, always_discard_changes = False): - with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) - if not containers or not self._active_container_stack: - return - Logger.log("d", "Attempting to change the active variant to %s", variant_id) - old_variant = self._active_container_stack.variant - old_material = self._active_container_stack.material - if old_variant: - self.blurSettings.emit() - self._new_variant_container = containers[0] # self._active_container_stack will be updated with a delay - Logger.log("d", "Active variant changed to {active_variant_id}".format(active_variant_id = containers[0].getId())) - preferred_material_name = None - if old_material: - preferred_material_name = old_material.getName() - preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id - self.setActiveMaterial(preferred_material_id, always_discard_changes = always_discard_changes) - else: - Logger.log("w", "While trying to set the active variant, no variant was found to replace.") - @pyqtSlot(str) def setActiveVariantBuildplate(self, variant_buildplate_id: str): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): From 6dc53eb741d2c3aa97d1dd4a32d99b4a184b877b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 22:27:54 +0100 Subject: [PATCH 032/266] WIP: Fix NozzleMenu extruder binding --- resources/qml/Menus/BuildplateMenu.qml | 4 ++-- resources/qml/Menus/NozzleMenu.qml | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/qml/Menus/BuildplateMenu.qml b/resources/qml/Menus/BuildplateMenu.qml index 4b85aa9e93..2679eec1d1 100644 --- a/resources/qml/Menus/BuildplateMenu.qml +++ b/resources/qml/Menus/BuildplateMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 8cb01fcde6..d3ddbb8473 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -1,8 +1,8 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import UM 1.2 as UM import Cura 1.0 as Cura @@ -27,11 +27,10 @@ Menu { text: model.hotend_name checkable: true - checked: Cura.MachineManager.activeVariantName == model.hotend_name + checked: Cura.MachineManager.activeMachine.extruders[extruderIndex].variant.name == model.hotend_name exclusiveGroup: group onTriggered: { - var position = Cura.ExtruderManager.activeExtruderIndex; - Cura.MachineManager.setVariantGroup(position, model.container_node); + Cura.MachineManager.setVariantGroup(extruderIndex, model.container_node); } } From 8275e506ce6b3e995a2a03e485eb822f525119f8 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 15 Feb 2018 11:17:25 +0100 Subject: [PATCH 033/266] CURA-4606 fix material names for 1.75mm materials --- cura/Machines/MaterialManager.py | 31 ++++++++++++++++--- cura/Machines/QualityManager.py | 8 +++-- resources/definitions/gmax15plus.def.json | 1 + .../definitions/gmax15plus_dual.def.json | 1 + .../gmax15plus_pla_dual_normal.inst.cfg | 1 - .../gmax15plus_pla_dual_thick.inst.cfg | 1 - .../gmax15plus_pla_dual_thin.inst.cfg | 1 - .../gmax15plus_pla_dual_very_thick.inst.cfg | 1 - .../gmax15plus/gmax15plus_pla_normal.inst.cfg | 1 - .../gmax15plus/gmax15plus_pla_thick.inst.cfg | 1 - .../gmax15plus/gmax15plus_pla_thin.inst.cfg | 1 - .../gmax15plus_pla_very_thick.inst.cfg | 1 - 12 files changed, 33 insertions(+), 16 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index bd827fe5ba..f5a8995af1 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -38,11 +38,17 @@ class MaterialManager(QObject): self._fallback_materials_map = dict() # material_type -> generic material metadata self._material_group_map = dict() # root_material_id -> MaterialGroup self._diameter_machine_variant_material_map = dict() # diameter -> dict(machine_definition_id -> MaterialNode) + + # We're using these two maps to convert between the specific diameter material id and the generic material id + # because the generic material ids are used in qualities and definitions, while the specific diameter material is meant + # i.e. generic_pla -> generic_pla_175 self._material_diameter_map = defaultdict() # root_material_id -> diameter -> root_material_id for that diameter + self._diameter_material_map = dict() # material id including diameter (generic_pla_175) -> material root id (generic_pla) # The machine definition ID for the non-machine-specific materials. # This is used as the last fallback option if the given machine-specific material(s) cannot be found. self._default_machine_definition_id = "fdmprinter" + self._default_approximate_diameter_for_quality_search = "3" self._update_timer = QTimer(self) self._update_timer.setInterval(300) @@ -99,6 +105,7 @@ class MaterialManager(QObject): # be for either "generic_pla" or "generic_pla_175", but not both. This map helps to get the correct material ID # for quality search. self._material_diameter_map = defaultdict(defaultdict) + self._diameter_material_map = dict() # Group the material IDs by the same name, material, brand, and color but with different diameters. material_group_dict = dict() @@ -116,10 +123,17 @@ class MaterialManager(QObject): approximate_diameter = root_material_metadata.get("approximate_diameter") material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"] + # Map [root_material_id][diameter] -> root_material_id for this diameter for data_dict in material_group_dict.values(): - for rmid1 in data_dict.values(): - for ad2, rmid2 in data_dict.items(): - self._material_diameter_map[rmid1][ad2] = rmid2 + for root_material_id1 in data_dict.values(): + for approximate_diameter2, root_material_id2 in data_dict.items(): + self._material_diameter_map[root_material_id1][approximate_diameter2] = root_material_id2 + + default_root_material_id = data_dict.get(self._default_approximate_diameter_for_quality_search) + if default_root_material_id is None: + default_root_material_id = list(data_dict.values())[0] # no default diameter present, just take "the" only one + for root_material_id in data_dict.values(): + self._diameter_material_map[root_material_id] = default_root_material_id # Map #4 # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer @@ -181,6 +195,9 @@ class MaterialManager(QObject): def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str: return self._material_diameter_map.get(root_material_id).get(approximate_diameter, root_material_id) + def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str: + return self._diameter_material_map.get(root_material_id) + # # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. # @@ -264,8 +281,12 @@ class MaterialManager(QObject): # This function returns the generic root material ID for the given material type, where material types are "PLA", # "ABS", etc. # - def getFallbackMaterialForType(self, material_type: str) -> dict: + def getFallbackMaterialId(self, material_type: str) -> str: # For safety if material_type not in self._fallback_materials_map: raise RuntimeError("Material type [%s] is not in the fallback materials table." % material_type) - return self._fallback_materials_map[material_type] + fallback_material = self._fallback_materials_map[material_type] + if fallback_material: + return self.getRootMaterialIDWithoutDiameter(fallback_material["id"]) + else: + return None diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index cb723f41d0..f0fd0168a6 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -286,13 +286,15 @@ class QualityManager(QObject): if extruder.material.getId() != "empty_material": has_material = True root_material_id = extruder.material.getMetaDataEntry("base_file") + # Convert possible generic_pla_175 -> generic_pla + root_material_id = self._material_manager.getRootMaterialIDWithoutDiameter(root_material_id) root_material_id_list.append(root_material_id) # Also try to get the fallback material material_type = extruder.material.getMetaDataEntry("material") - fallback_root_material_metadata = self._material_manager.getFallbackMaterialForType(material_type) - if fallback_root_material_metadata: - root_material_id_list.append(fallback_root_material_metadata["id"]) + fallback_root_material_id = self._material_manager.getFallbackMaterialId(material_type) + if fallback_root_material_id: + root_material_id_list.append(fallback_root_material_id) nodes_to_check = [] diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json index 3a207cd054..897d492bb2 100644 --- a/resources/definitions/gmax15plus.def.json +++ b/resources/definitions/gmax15plus.def.json @@ -10,6 +10,7 @@ "category": "Other", "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", + "has_machine_quality": true, "has_variants": true, "variants_name": "Hotend", "preferred_variant_name": "0.5mm E3D (Default)" diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json index af26a2e30a..8c57c8af63 100644 --- a/resources/definitions/gmax15plus_dual.def.json +++ b/resources/definitions/gmax15plus_dual.def.json @@ -11,6 +11,7 @@ "file_formats": "text/x-gcode", "platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl", "has_variants": true, + "has_machine_quality": true, "variants_name": "Hotend", "preferred_variant_name": "0.5mm E3D (Default)", "machine_extruder_trains": { diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg index 67b5cb49b8..e08a6ff421 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = normal weight = -1 -global_quality = True [values] layer_height = 0.2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg index 376e3241ff..86bfe2af6c 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = course weight = -2 -global_quality = True [values] layer_height = 0.28 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg index 1c0cabd84f..0d19c6c9f0 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = high weight = 0 -global_quality = True [values] layer_height = 0.16 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg index d292284531..2b58120762 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = extra_course weight = -3 -global_quality = True [values] layer_height = 0.32 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg index 3baad3a928..70920b6f6a 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = normal weight = -1 -global_quality = True [values] layer_height = 0.2 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg index 856ab7d3db..0f1e8a3802 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = course weight = -2 -global_quality = True [values] layer_height = 0.28 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg index 46f41e195f..f548affc2c 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = high weight = 0 -global_quality = True [values] layer_height = 0.16 diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg index 938f21a13d..5db77a70ea 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg @@ -8,7 +8,6 @@ setting_version = 4 type = quality quality_type = extra_course weight = -3 -global_quality = True [values] layer_height = 0.32 From aed0c124e942c450e1d1795613aaff50b6fc29a5 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 15 Feb 2018 11:47:14 +0100 Subject: [PATCH 034/266] CURA-4606 improved addExtruderStackForSingleExtrusionMachine by using containers directly --- cura/Settings/CuraContainerRegistry.py | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index e18710e46d..393e36db30 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -25,7 +25,6 @@ from UM.Resources import Resources from . import ExtruderStack from . import GlobalStack -from .ContainerManager import ContainerManager from .ExtruderManager import ExtruderManager from cura.CuraApplication import CuraApplication @@ -33,6 +32,7 @@ from cura.CuraApplication import CuraApplication from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") + class CuraContainerRegistry(ContainerRegistry): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -514,8 +514,6 @@ class CuraContainerRegistry(ContainerRegistry): extruder_stack.setDefinition(extruder_definition) extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) - from cura.CuraApplication import CuraApplication - # create a new definition_changes container for the extruder stack definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings") if create_new_ids else extruder_stack.getId() + "_settings" definition_changes_name = definition_changes_id @@ -574,26 +572,28 @@ class CuraContainerRegistry(ContainerRegistry): self.addContainer(user_container) extruder_stack.setUserChanges(user_container) - variant_id = "default" + application = CuraApplication.getInstance() + empty_variant = application.empty_variant_container + empty_material = application.empty_material_container + empty_quality = application.empty_quality_container + if machine.variant.getId() not in ("empty", "empty_variant"): - variant_id = machine.variant.getId() + variant = machine.variant else: - variant_id = "empty_variant" - extruder_stack.variant = self.findInstanceContainers(id = variant_id)[0] + variant = empty_variant + extruder_stack.variant = variant - material_id = "default" if machine.material.getId() not in ("empty", "empty_material"): - material_id = machine.material.getId() + material = machine.material else: - material_id = "empty_material" - extruder_stack.material = self.findInstanceContainers(id = material_id)[0] + material = empty_material + extruder_stack.material = material - quality_id = "default" if machine.quality.getId() not in ("empty", "empty_quality"): - quality_id = machine.quality.getId() + quality = machine.quality else: - quality_id = "empty_quality" - extruder_stack.quality = self.findInstanceContainers(id = quality_id)[0] + quality = empty_quality + extruder_stack.quality = quality machine_quality_changes = machine.qualityChanges if new_global_quality_changes is not None: From 1e0a078af8b06611c2ff9f0dbe0fb76de742d303 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 15 Feb 2018 15:05:37 +0100 Subject: [PATCH 035/266] WIP: Refactor Materials management page to use new Managers --- cura/CuraApplication.py | 3 +- cura/Settings/MaterialsModel.py | 112 +++- resources/qml/Preferences/MaterialView.qml | 18 +- resources/qml/Preferences/MaterialsPage.qml | 584 ++++++++---------- resources/qml/Preferences/OldMaterialView.qml | 467 ++++++++++++++ .../qml/Preferences/OldMaterialsPage.qml | 412 ++++++++++++ 6 files changed, 1264 insertions(+), 332 deletions(-) create mode 100644 resources/qml/Preferences/OldMaterialView.qml create mode 100644 resources/qml/Preferences/OldMaterialsPage.qml diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b1ec388f48..eee0ecabe0 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -54,7 +54,7 @@ from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Machines.Models.NozzleModel import NozzleModel from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel -from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel +from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.UserProfilesModel import UserProfilesModel @@ -944,6 +944,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") + qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel") qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py index ad3256ba32..f133684032 100644 --- a/cura/Settings/MaterialsModel.py +++ b/cura/Settings/MaterialsModel.py @@ -1,17 +1,16 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, List -from PyQt5.QtCore import Qt - +from typing import Any, List, Optional +from PyQt5.QtCore import Qt, QObject from UM.Logger import Logger from UM.Qt.ListModel import ListModel -from UM.Settings.ContainerRegistry import ContainerRegistry #To listen for changes to the materials. -from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel #We're extending this class. +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel -def getAvailableMaterials(): +def getAvailableMaterials(extruder_position: Optional[int] = None): from cura.CuraApplication import CuraApplication machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() @@ -19,18 +18,21 @@ def getAvailableMaterials(): material_manager = CuraApplication.getInstance()._material_manager active_global_stack = machine_manager._global_container_stack - active_extruder_stack = extruder_manager.getActiveExtruderStack() + extruder_stack = extruder_manager.getActiveExtruderStack() + if extruder_position is not None: + if active_global_stack is not None: + extruder_stack = active_global_stack.extruders.get(str(extruder_position)) - if active_global_stack is None or active_extruder_stack is None: + if active_global_stack is None or extruder_stack is None: Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", - active_global_stack, active_extruder_stack) + active_global_stack, extruder_stack) return machine_definition_id = active_global_stack.definition.getId() variant_name = None - if active_extruder_stack.variant.getId() != "empty_variant": - variant_name = active_extruder_stack.variant.getName() - diameter = active_extruder_stack.getProperty("material_diameter", "value") + if extruder_stack.variant.getId() != "empty_variant": + variant_name = extruder_stack.variant.getName() + diameter = extruder_stack.getProperty("material_diameter", "value") # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) @@ -44,7 +46,7 @@ class BaseMaterialsModel(ListModel): BrandRole = Qt.UserRole + 4 MaterialRole = Qt.UserRole + 5 ColorRole = Qt.UserRole + 6 - ContainerNodeRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 def __init__(self, parent = None): super().__init__(parent) @@ -184,6 +186,90 @@ class BrandMaterialsModel(ListModel): self.setItems(brand_item_list) +# +# This model is for the Material management page. +# +class NewMaterialsModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + DisplayNameRole = Qt.UserRole + 2 + BrandRole = Qt.UserRole + 3 + MaterialTypeRole = Qt.UserRole + 4 + ColorNameRole = Qt.UserRole + 5 + ColorCodeRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 + ContainerIdRole = Qt.UserRole + 8 + + DescriptionRole = Qt.UserRole + 9 + AdhesionInfoRole = Qt.UserRole + 10 + ApproximateDiameterRole = Qt.UserRole + 11 + GuidRole = Qt.UserRole + 12 + DensityRole = Qt.UserRole + 13 + DiameterRole = Qt.UserRole + 14 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.DisplayNameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialTypeRole, "material") + self.addRoleName(self.ColorNameRole, "color_name") + self.addRoleName(self.ColorCodeRole, "color_code") + self.addRoleName(self.ContainerNodeRole, "container_node") + self.addRoleName(self.ContainerIdRole, "container_id") + + self.addRoleName(self.DescriptionRole, "description") + self.addRoleName(self.AdhesionInfoRole, "adhesion_info") + self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter") + self.addRoleName(self.GuidRole, "guid") + self.addRoleName(self.DensityRole, "density") + self.addRoleName(self.DiameterRole, "diameter") + + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + self._update() + + def _update(self): + result_dict = getAvailableMaterials() + if result_dict is None: + self.setItems([]) + return + + material_list = [] + for root_material_id, container_node in result_dict.items(): + keys_to_fetch = ("name", + "brand", + "material", + "color_name", + "color_code", + "description", + "adhesion_info", + "approximate_diameter",) + + item = {"root_material_id": container_node.metadata["base_file"], + "container_node": container_node, + "guid": container_node.metadata["GUID"], + "container_id": container_node.metadata["id"], + "density": container_node.metadata.get("properties", {}).get("density", ""), + "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), + } + + for key in keys_to_fetch: + item[key] = container_node.metadata.get(key, "") + + material_list.append(item) + + material_list = sorted(material_list, key = lambda k: (k["brand"], k["name"])) + self.setItems(material_list) + + ## A model that shows a list of currently valid materials. Used by management page. class MaterialsModel(InstanceContainersModel): def __init__(self, parent = None): diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 5fdc8a24eb..50eb3d3e99 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -1,8 +1,8 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.3 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 import UM 1.2 as UM @@ -357,8 +357,18 @@ TabView onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) } - UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key } - UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key } + UM.ContainerPropertyProvider { + id: materialPropertyProvider + containerId: base.containerId + watchedProperties: [ "value" ] + key: model.key + } + UM.ContainerPropertyProvider { + id: machinePropertyProvider + containerId: Cura.MachineManager.activeDefinitionId + watchedProperties: [ "value" ] + key: model.key + } } } } diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 3a72f66cfc..cf8cd959bf 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -1,147 +1,61 @@ -//Copyright (c) 2017 Ultimaker B.V. -//Cura is released under the terms of the LGPLv3 or higher. +// Copyright (c) 2018 Ultimaker B.V. +// Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Dialogs 1.2 +import QtQuick 2.8 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura -UM.ManagementPage + +Item { - id: base; + id: base + property var resetEnabled: false // Keep PreferencesDialog happy - title: catalog.i18nc("@title:tab", "Materials"); + UM.I18nCatalog { id: catalog; name: "cura"; } - Component.onCompleted: - { - // Workaround to make sure all of the items are visible - objectList.positionViewAtBeginning(); + Cura.NewMaterialsModel { + id: materialsModel } - model: Cura.MaterialsModel - { - filter: - { - var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() } - if(Cura.MachineManager.filterMaterialsByMachine) - { - result.definition = Cura.MachineManager.activeQualityDefinitionId; - if(Cura.MachineManager.hasVariants) - { - result.variant_name = Cura.MachineManager.activeQualityVariantName; - } - } - else - { - result.definition = "fdmprinter"; - result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway. - } - return result + Label { + id: titleLabel + + anchors { + top: parent.top + left: parent.left + right: parent.right + margins: 5 * screenScaleFactor } - sectionProperty: "brand" + font.pointSize: 18 + text: catalog.i18nc("@title:tab", "Materials") } - delegate: Rectangle + Row // Button Row { - width: objectList.width; - height: childrenRect.height; - color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase - property bool isCurrentItem: ListView.isCurrentItem - - Row - { - spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - Rectangle - { - width: Math.round(parent.height * 0.8) - height: Math.round(parent.height * 0.8) - color: model.metadata.color_code - border.color: isCurrentItem ? palette.highlightedText : palette.text; - anchors.verticalCenter: parent.verticalCenter - } - Label - { - width: Math.round((parent.width * 0.3)) - text: model.metadata.material - elide: Text.ElideRight - font.italic: model.id == activeId - color: isCurrentItem ? palette.highlightedText : palette.text; - } - Label - { - text: (model.name != model.metadata.material) ? model.name : "" - elide: Text.ElideRight - font.italic: model.id == activeId - color: isCurrentItem ? palette.highlightedText : palette.text; - } + id: buttonRow + anchors { + left: parent.left + right: parent.right + top: titleLabel.bottom } - - MouseArea - { - anchors.fill: parent; - onClicked: - { - forceActiveFocus(); - if(!parent.ListView.isCurrentItem) - { - parent.ListView.view.currentIndex = index; - base.itemActivated(); - } - } - } - } - - activeId: Cura.MachineManager.activeMaterialId - activeIndex: getIndexById(activeId) - function getIndexById(material_id) - { - for(var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).id == material_id) { - return i; - } - } - return -1; - } - - scrollviewCaption: - { - var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; - if (Cura.MachineManager.hasVariants) - { - caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName; - } - return caption; - } - detailsVisible: true - - section.property: "section" - section.delegate: Label - { - text: section - font.bold: true - anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("default_lining").width; - } - - buttons: [ + height: childrenRect.height // Activate button Button { text: catalog.i18nc("@action:button", "Activate") - iconName: "list-activate"; - enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials + iconName: "list-activate" + //enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials + enabled: true // TODO onClicked: { forceActiveFocus() Cura.MachineManager.setActiveMaterial(base.currentItem.id) currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. } - }, + } // Create button Button { @@ -149,31 +63,32 @@ UM.ManagementPage iconName: "list-add" onClicked: { forceActiveFocus() - Cura.ContainerManager.createMaterial() + // TODO } - }, + } // Duplicate button Button { text: catalog.i18nc("@action:button", "Duplicate"); - iconName: "list-add"; - enabled: base.currentItem != null + iconName: "list-add" + enabled: true //TODO onClicked: { forceActiveFocus() - Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id) + // TODO } - }, + } // Remove button Button { text: catalog.i18nc("@action:button", "Remove") iconName: "list-remove" - enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) + //enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) + enabled: true // TODO onClicked: { forceActiveFocus() - confirmDialog.open() + // TODO } - }, + } // Import button Button { @@ -181,10 +96,10 @@ UM.ManagementPage iconName: "document-import" onClicked: { forceActiveFocus() - importDialog.open() + // TODO } visible: true - }, + } // Export button Button { @@ -192,221 +107,262 @@ UM.ManagementPage iconName: "document-export" onClicked: { forceActiveFocus() - exportDialog.open() + // TODO } enabled: currentItem != null } - - ] + } Item { - visible: base.currentItem != null - anchors.fill: parent + id: contentsItem + + anchors { + top: titleLabel.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: 5 * screenScaleFactor + bottomMargin: 0 + } + + clip: true + } + + Item + { + anchors { + top: buttonRow.bottom + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left + right: parent.right + bottom: parent.bottom + } + + SystemPalette { id: palette } + + Label + { + id: captionLabel + anchors { + top: parent.top + left: parent.left + } + text: "TODO" + width: materialScrollView.width + elide: Text.ElideRight + } + + ScrollView + { + id: materialScrollView + anchors { + top: captionLabel.visible ? captionLabel.bottom : parent.top + topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0 + bottom: parent.bottom + left: parent.left + } + + Rectangle { + parent: viewport + anchors.fill: parent + color: palette.light + } + + width: true ? (parent.width * 0.4) | 0 : parent.width + + ListView + { + id: materialListView + + model: materialsModel + + section.property: "brand" + section.criteria: ViewSection.FullString + section.delegate: Rectangle + { + width: materialScrollView.width + height: childrenRect.height + color: palette.light + + Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + text: section + font.bold: true + color: palette.text + } + } + + delegate: Rectangle + { + width: materialScrollView.width + height: childrenRect.height + color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase + + Row + { + spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: parent.right + Rectangle + { + width: Math.floor(parent.height * 0.8) + height: Math.floor(parent.height * 0.8) + color: model.color_code + border.color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; + anchors.verticalCenter: parent.verticalCenter + } + Label + { + width: Math.floor((parent.width * 0.3)) + text: model.material + elide: Text.ElideRight + font.italic: { + const extruder_position = Cura.ExtruderManager.activeExtruderIndex; + const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; + return model.root_material_id == root_material_id; // TODO + } + color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; + } + Label + { + text: (model.name != model.material) ? model.name : "" + elide: Text.ElideRight + font.italic: { + const extruder_position = Cura.ExtruderManager.activeExtruderIndex; + const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; + return model.root_material_id == root_material_id; // TODO + } + color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; + } + } + + MouseArea + { + anchors.fill: parent + onClicked: { + parent.ListView.view.currentIndex = model.index; + } + } + } + + onCurrentIndexChanged: + { + var model = materialsModel.getItem(currentIndex); + materialDetailsView.containerId = model.container_id; + + detailsPanel.updateMaterialPropertiesObject(); + } + } + } + Item { - id: profileName + id: detailsPanel - width: parent.width; - height: childrenRect.height - - Label { text: materialProperties.name; font: UM.Theme.getFont("large"); } - } - - MaterialView - { - anchors - { - left: parent.left - right: parent.right - top: profileName.bottom - topMargin: UM.Theme.getSize("default_margin").height + anchors { + left: materialScrollView.right + leftMargin: UM.Theme.getSize("default_margin").width + top: parent.top bottom: parent.bottom + right: parent.right } - editingEnabled: base.currentItem != null && !base.currentItem.readOnly - - properties: materialProperties - containerId: base.currentItem != null ? base.currentItem.id : "" - - property alias pane: base - } - - QtObject - { - id: materialProperties - - property string guid: "00000000-0000-0000-0000-000000000000" - property string name: "Unknown"; - property string profile_type: "Unknown"; - property string supplier: "Unknown"; - property string material_type: "Unknown"; - - property string color_name: "Yellow"; - property color color_code: "yellow"; - - property real density: 0.0; - property real diameter: 0.0; - property string approximate_diameter: "0"; - - property real spool_cost: 0.0; - property real spool_weight: 0.0; - property real spool_length: 0.0; - property real cost_per_meter: 0.0; - - property string description: ""; - property string adhesion_info: ""; - } - - UM.ConfirmRemoveDialog - { - id: confirmDialog - object: base.currentItem != null ? base.currentItem.name : "" - onYes: + function updateMaterialPropertiesObject() { - // A material container can actually be multiple items, so we need to find (and remove) all of them. - var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") - if(base_file == "") - { - base_file = base.currentItem.id - } - var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID") - // remove base container first, it otherwise triggers loading the base file while removing other containers - var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"}) - for(var i in base_containers) - { - Cura.ContainerManager.removeContainer(base_containers[i]); - } - var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"}) - for(var i in containers) - { - Cura.ContainerManager.removeContainer(containers[i]); - } - if(base.objectList.currentIndex > 0) - { - base.objectList.currentIndex--; - } - currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. - } - } + var currentItem = materialsModel.getItem(materialListView.currentIndex); - FileDialog - { - id: importDialog; - title: catalog.i18nc("@title:window", "Import Material"); - selectExisting: true; - nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") - onAccepted: - { - var result = Cura.ContainerManager.importMaterialContainer(fileUrl) + materialProperties.name = currentItem.name; + materialProperties.guid = currentItem.guid; - messageDialog.title = catalog.i18nc("@title:window", "Import Material") - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message) - if(result.status == "success") + materialProperties.supplier = currentItem.brand ? currentItem.brand : "Unknown"; + materialProperties.material_type = currentItem.material ? currentItem.material : "Unknown"; + materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow"; + materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow"; + + materialProperties.description = currentItem.description ? currentItem.description : ""; + materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : ""; + + if(currentItem.properties != undefined && currentItem.properties != null) { - messageDialog.icon = StandardIcon.Information - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl) - } - else if(result.status == "duplicate") - { - messageDialog.icon = StandardIcon.Warning + materialProperties.density = currentItem.density ? currentItem.density : 0.0; + materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0; + materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0"; } else { - messageDialog.icon = StandardIcon.Critical + materialProperties.density = 0.0; + materialProperties.diameter = 0.0; + materialProperties.approximate_diameter = "0"; } - messageDialog.open() - CuraApplication.setDefaultPath("dialog_material_path", folder) } - } - FileDialog - { - id: exportDialog; - title: catalog.i18nc("@title:window", "Export Material"); - selectExisting: false; - nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") - onAccepted: + Item { - if(base.currentItem.metadata.base_file) + anchors.fill: parent + + Item // Material title Label { - var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl) - } - else - { - var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl) + id: profileName + + width: parent.width + height: childrenRect.height + + Label { + text: materialProperties.name + font: UM.Theme.getFont("large") + } } - messageDialog.title = catalog.i18nc("@title:window", "Export Material") - if(result.status == "error") + MaterialView // Material detailed information view below the title Label { - messageDialog.icon = StandardIcon.Critical - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message) - messageDialog.open() + id: materialDetailsView + anchors + { + left: parent.left + right: parent.right + top: profileName.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottom: parent.bottom + } + + editingEnabled: base.currentItem != null && !base.currentItem.readOnly + + properties: materialProperties + containerId: base.currentItem != null ? base.currentItem.id : "" + + property alias pane: base } - else if(result.status == "success") + + QtObject { - messageDialog.icon = StandardIcon.Information - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path) - messageDialog.open() + id: materialProperties + + property string guid: "00000000-0000-0000-0000-000000000000" + property string name: "Unknown"; + property string profile_type: "Unknown"; + property string supplier: "Unknown"; + property string material_type: "Unknown"; + + property string color_name: "Yellow"; + property color color_code: "yellow"; + + property real density: 0.0; + property real diameter: 0.0; + property string approximate_diameter: "0"; + + property real spool_cost: 0.0; + property real spool_weight: 0.0; + property real spool_length: 0.0; + property real cost_per_meter: 0.0; + + property string description: ""; + property string adhesion_info: ""; } - CuraApplication.setDefaultPath("dialog_material_path", folder) } } - - MessageDialog - { - id: messageDialog - } - - UM.SettingPropertyProvider - { - id: materialDiameterProvider - - containerStackId: Cura.ExtruderManager.activeExtruderStackId - key: "material_diameter" - watchedProperties: [ "value" ] - storeIndex: 5 - } - - UM.I18nCatalog { id: catalog; name: "cura"; } - SystemPalette { id: palette } - } - - onCurrentItemChanged: - { - if(currentItem == null) - { - return - } - materialProperties.name = currentItem.name; - materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID"); - - if(currentItem.metadata != undefined && currentItem.metadata != null) - { - materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown"; - materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown"; - materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow"; - materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow"; - - materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : ""; - materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : ""; - - if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null) - { - materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0; - materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0; - materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0"; - } - else - { - materialProperties.density = 0.0; - materialProperties.diameter = 0.0; - materialProperties.approximate_diameter = "0"; - } - - } } } diff --git a/resources/qml/Preferences/OldMaterialView.qml b/resources/qml/Preferences/OldMaterialView.qml new file mode 100644 index 0000000000..1b3a3b93a8 --- /dev/null +++ b/resources/qml/Preferences/OldMaterialView.qml @@ -0,0 +1,467 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.8 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +TabView +{ + id: base + + property QtObject properties; + + property bool editingEnabled: false; + property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€" + property real firstColumnWidth: (width * 0.50) | 0 + property real secondColumnWidth: (width * 0.40) | 0 + property string containerId: "" + property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {} + + property double spoolLength: calculateSpoolLength() + property real costPerMeter: calculateCostPerMeter() + + property bool reevaluateLinkedMaterials: false + property string linkedMaterialNames: + { + if (reevaluateLinkedMaterials) + { + reevaluateLinkedMaterials = false; + } + if(!base.containerId || !base.editingEnabled) + { + return "" + } + var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId); + return linkedMaterials.join(", "); + } + + Tab + { + title: catalog.i18nc("@title", "Information") + + anchors.margins: UM.Theme.getSize("default_margin").width + + ScrollView + { + id: scrollView + anchors.fill: parent + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + flickableItem.flickableDirection: Flickable.VerticalFlick + frameVisible: true + + property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 + + Flow + { + id: containerGrid + + x: UM.Theme.getSize("default_margin").width + y: UM.Theme.getSize("default_lining").height + + width: base.width + property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } + ReadOnlyTextField + { + id: displayNameTextField; + width: scrollView.columnWidth; + text: properties.name; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialDisplayName(properties.name, text) + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") } + ReadOnlyTextField + { + id: textField; + width: scrollView.columnWidth; + text: properties.supplier; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialSupplier(properties.supplier, text) + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") } + ReadOnlyTextField + { + width: scrollView.columnWidth; + text: properties.material_type; + readOnly: !base.editingEnabled; + onEditingFinished: base.updateMaterialType(properties.material_type, text) + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } + Row { + width: scrollView.columnWidth + height: parent.rowHeight + spacing: Math.floor(UM.Theme.getSize("default_margin").width / 2) + + // color indicator square + Rectangle { + id: colorSelector + color: properties.color_code + + width: Math.floor(colorLabel.height * 0.75) + height: Math.floor(colorLabel.height * 0.75) + border.width: UM.Theme.getSize("default_lining").height + + anchors.verticalCenter: parent.verticalCenter + + // open the color selection dialog on click + MouseArea { + anchors.fill: parent + onClicked: colorDialog.open() + enabled: base.editingEnabled + } + } + + // pretty color name text field + ReadOnlyTextField { + id: colorLabel; + text: properties.color_name; + readOnly: !base.editingEnabled + onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) + } + + // popup dialog to select a new color + // if successful it sets the properties.color_code value to the new color + ColorDialog { + id: colorDialog + color: properties.color_code + onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) + } + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") } + ReadOnlySpinBox + { + id: densitySpinBox + width: scrollView.columnWidth + value: properties.density + decimals: 2 + suffix: " g/cm³" + stepSize: 0.01 + readOnly: !base.editingEnabled + + onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value) + onValueChanged: updateCostPerMeter() + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") } + ReadOnlySpinBox + { + id: diameterSpinBox + width: scrollView.columnWidth + value: properties.diameter + decimals: 2 + suffix: " mm" + stepSize: 0.01 + readOnly: !base.editingEnabled + + onEditingFinished: + { + // This does not use a SettingPropertyProvider, because we need to make the change to all containers + // which derive from the same base_file + var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString(); + var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); + base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString()); + base.setMetaDataEntry("properties/diameter", properties.diameter, value); + var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); + if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter) + { + Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter); + } + Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value); + } + onValueChanged: updateCostPerMeter() + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } + SpinBox + { + id: spoolCostSpinBox + width: scrollView.columnWidth + value: base.getMaterialPreferenceValue(properties.guid, "spool_cost") + prefix: base.currency + " " + decimals: 2 + maximumValue: 100000000 + + onValueChanged: { + base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value)) + updateCostPerMeter() + } + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } + SpinBox + { + id: spoolWeightSpinBox + width: scrollView.columnWidth + value: base.getMaterialPreferenceValue(properties.guid, "spool_weight") + suffix: " g" + stepSize: 100 + decimals: 0 + maximumValue: 10000 + + onValueChanged: { + base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value)) + updateCostPerMeter() + } + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") } + Label + { + width: scrollView.columnWidth + text: "~ %1 m".arg(Math.round(base.spoolLength)) + verticalAlignment: Qt.AlignVCenter + height: parent.rowHeight + } + + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") } + Label + { + width: scrollView.columnWidth + text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency) + verticalAlignment: Qt.AlignVCenter + height: parent.rowHeight + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible } + Label + { + width: 2 * scrollView.columnWidth + verticalAlignment: Qt.AlignVCenter + text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames) + wrapMode: Text.WordWrap + visible: unlinkMaterialButton.visible + } + Button + { + id: unlinkMaterialButton + text: catalog.i18nc("@label", "Unlink Material") + visible: base.linkedMaterialNames != "" + onClicked: + { + Cura.ContainerManager.unlinkMaterial(base.containerId) + base.reevaluateLinkedMaterials = true + } + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") } + + ReadOnlyTextArea + { + text: properties.description; + width: 2 * scrollView.columnWidth + wrapMode: Text.WordWrap + + readOnly: !base.editingEnabled; + + onEditingFinished: base.setMetaDataEntry("description", properties.description, text) + } + + Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") } + + ReadOnlyTextArea + { + text: properties.adhesion_info; + width: 2 * scrollView.columnWidth + wrapMode: Text.WordWrap + + readOnly: !base.editingEnabled; + + onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text) + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + } + + function updateCostPerMeter() + { + base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value); + base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value); + } + } + } + + Tab + { + title: catalog.i18nc("@label", "Print settings") + anchors + { + leftMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_margin").height + bottomMargin: UM.Theme.getSize("default_margin").height + rightMargin: 0 + } + + ScrollView + { + anchors.fill: parent; + + ListView + { + model: UM.SettingDefinitionsModel + { + containerId: Cura.MachineManager.activeDefinitionId + visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } + expanded: ["*"] + } + + delegate: UM.TooltipArea + { + width: childrenRect.width + height: childrenRect.height + text: model.description + Label + { + id: label + width: base.firstColumnWidth; + height: spinBox.height + UM.Theme.getSize("default_lining").height + text: model.label + elide: Text.ElideRight + verticalAlignment: Qt.AlignVCenter + } + ReadOnlySpinBox + { + id: spinBox + anchors.left: label.right + value: { + if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) + { + return parseFloat(materialPropertyProvider.properties.value); + } + if (!isNaN(parseFloat(machinePropertyProvider.properties.value))) + { + return parseFloat(machinePropertyProvider.properties.value); + } + return 0; + } + width: base.secondColumnWidth + readOnly: !base.editingEnabled + suffix: " " + model.unit + maximumValue: 99999 + decimals: model.unit == "mm" ? 2 : 0 + + onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) + } + + UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key } + UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key } + } + } + } + } + + function calculateSpoolLength(diameter, density, spoolWeight) + { + if(!diameter) + { + diameter = properties.diameter; + } + if(!density) + { + density = properties.density; + } + if(!spoolWeight) + { + spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight"); + } + + if (diameter == 0 || density == 0 || spoolWeight == 0) + { + return 0; + } + var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2 + var volume = (spoolWeight / density); // in cm3 + return volume / area; // in m + } + + function calculateCostPerMeter(spoolCost) + { + if(!spoolCost) + { + spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost"); + } + + if (spoolLength == 0) + { + return 0; + } + return spoolCost / spoolLength; + } + + // Tiny convenience function to check if a value really changed before trying to set it. + function setMetaDataEntry(entry_name, old_value, new_value) { + if (old_value != new_value) { + Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) + // make sure the UI properties are updated as well since we don't re-fetch the entire model here + // When the entry_name is something like properties/diameter, we take the last part of the entry_name + var list = entry_name.split("/") + var key = list[list.length - 1] + properties[key] = new_value + } + } + + function setMaterialPreferenceValue(material_guid, entry_name, new_value) + { + if(!(material_guid in materialPreferenceValues)) + { + materialPreferenceValues[material_guid] = {}; + } + if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value) + { + // value has not changed + return + } + materialPreferenceValues[material_guid][entry_name] = new_value; + + // store preference + UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues)); + } + + function getMaterialPreferenceValue(material_guid, entry_name) + { + if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid]) + { + return materialPreferenceValues[material_guid][entry_name]; + } + return 0; + } + + // update the display name of the material + function updateMaterialDisplayName (old_name, new_name) { + + // don't change when new name is the same + if (old_name == new_name) { + return + } + + // update the values + Cura.ContainerManager.setContainerName(base.containerId, new_name) + materialProperties.name = new_name + } + + // update the type of the material + function updateMaterialType (old_type, new_type) { + base.setMetaDataEntry("material", old_type, new_type) + materialProperties.material_type = new_type + } + + // update the supplier of the material + function updateMaterialSupplier (old_supplier, new_supplier) { + base.setMetaDataEntry("brand", old_supplier, new_supplier) + materialProperties.supplier = new_supplier + } +} diff --git a/resources/qml/Preferences/OldMaterialsPage.qml b/resources/qml/Preferences/OldMaterialsPage.qml new file mode 100644 index 0000000000..0a24b9c663 --- /dev/null +++ b/resources/qml/Preferences/OldMaterialsPage.qml @@ -0,0 +1,412 @@ +//Copyright (c) 2017 Ultimaker B.V. +//Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.8 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +UM.ManagementPage +{ + id: base + title: catalog.i18nc("@title:tab", "Materials") + + Component.onCompleted: + { + // Workaround to make sure all of the items are visible + objectList.positionViewAtBeginning(); + } + + model: Cura.MaterialsModel + { + filter: + { + var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() } + if(Cura.MachineManager.filterMaterialsByMachine) + { + result.definition = Cura.MachineManager.activeQualityDefinitionId; + if(Cura.MachineManager.hasVariants) + { + result.variant_name = Cura.MachineManager.activeQualityVariantName; + } + } + else + { + result.definition = "fdmprinter"; + result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway. + } + return result + } + + sectionProperty: "brand" + } + + delegate: Rectangle + { + width: objectList.width; + height: childrenRect.height; + color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase + property bool isCurrentItem: ListView.isCurrentItem + + Row + { + spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: parent.right + Rectangle + { + width: Math.floor(parent.height * 0.8) + height: Math.floor(parent.height * 0.8) + color: model.metadata.color_code + border.color: isCurrentItem ? palette.highlightedText : palette.text; + anchors.verticalCenter: parent.verticalCenter + } + Label + { + width: Math.floor((parent.width * 0.3)) + text: model.metadata.material + elide: Text.ElideRight + font.italic: model.id == activeId + color: isCurrentItem ? palette.highlightedText : palette.text; + } + Label + { + text: (model.name != model.metadata.material) ? model.name : "" + elide: Text.ElideRight + font.italic: model.id == activeId + color: isCurrentItem ? palette.highlightedText : palette.text; + } + } + + MouseArea + { + anchors.fill: parent; + onClicked: + { + forceActiveFocus(); + if(!parent.ListView.isCurrentItem) + { + parent.ListView.view.currentIndex = index; + base.itemActivated(); + } + } + } + } + + activeId: Cura.MachineManager.activeMaterialId + activeIndex: getIndexById(activeId) + function getIndexById(material_id) + { + for(var i = 0; i < model.rowCount(); i++) { + if (model.getItem(i).id == material_id) { + return i; + } + } + return -1; + } + + scrollviewCaption: + { + var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; + if (Cura.MachineManager.hasVariants) + { + caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName; + } + return caption; + } + detailsVisible: true + + section.property: "section" + section.delegate: Label + { + text: section + font.bold: true + anchors.left: parent.left; + anchors.leftMargin: UM.Theme.getSize("default_lining").width; + } + + buttons: [ + + // Activate button + Button { + text: catalog.i18nc("@action:button", "Activate") + iconName: "list-activate"; + enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials + onClicked: { + forceActiveFocus() + Cura.MachineManager.setActiveMaterial(base.currentItem.id) + currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. + } + }, + + // Create button + Button { + text: catalog.i18nc("@action:button", "Create") + iconName: "list-add" + onClicked: { + forceActiveFocus() + Cura.ContainerManager.createMaterial() + } + }, + + // Duplicate button + Button { + text: catalog.i18nc("@action:button", "Duplicate"); + iconName: "list-add"; + enabled: base.currentItem != null + onClicked: { + forceActiveFocus() + Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id) + } + }, + + // Remove button + Button { + text: catalog.i18nc("@action:button", "Remove") + iconName: "list-remove" + enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) + onClicked: { + forceActiveFocus() + confirmDialog.open() + } + }, + + // Import button + Button { + text: catalog.i18nc("@action:button", "Import") + iconName: "document-import" + onClicked: { + forceActiveFocus() + importDialog.open() + } + visible: true + }, + + // Export button + Button { + text: catalog.i18nc("@action:button", "Export") + iconName: "document-export" + onClicked: { + forceActiveFocus() + exportDialog.open() + } + enabled: currentItem != null + } + + ] + + Item { + visible: base.currentItem != null + anchors.fill: parent + + Item // Material title Label + { + id: profileName + + width: parent.width; + height: childrenRect.height + + Label { text: materialProperties.name; font: UM.Theme.getFont("large"); } + } + + MaterialView // Material detailed information view below the title Label + { + anchors + { + left: parent.left + right: parent.right + top: profileName.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottom: parent.bottom + } + + editingEnabled: base.currentItem != null && !base.currentItem.readOnly + + properties: materialProperties + containerId: base.currentItem != null ? base.currentItem.id : "" + + property alias pane: base + } + + QtObject + { + id: materialProperties + + property string guid: "00000000-0000-0000-0000-000000000000" + property string name: "Unknown"; + property string profile_type: "Unknown"; + property string supplier: "Unknown"; + property string material_type: "Unknown"; + + property string color_name: "Yellow"; + property color color_code: "yellow"; + + property real density: 0.0; + property real diameter: 0.0; + property string approximate_diameter: "0"; + + property real spool_cost: 0.0; + property real spool_weight: 0.0; + property real spool_length: 0.0; + property real cost_per_meter: 0.0; + + property string description: ""; + property string adhesion_info: ""; + } + + UM.ConfirmRemoveDialog + { + id: confirmDialog + object: base.currentItem != null ? base.currentItem.name : "" + onYes: + { + // A material container can actually be multiple items, so we need to find (and remove) all of them. + var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") + if(base_file == "") + { + base_file = base.currentItem.id + } + var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID") + // remove base container first, it otherwise triggers loading the base file while removing other containers + var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"}) + for(var i in base_containers) + { + Cura.ContainerManager.removeContainer(base_containers[i]); + } + var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"}) + for(var i in containers) + { + Cura.ContainerManager.removeContainer(containers[i]); + } + if(base.objectList.currentIndex > 0) + { + base.objectList.currentIndex--; + } + currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. + } + } + + FileDialog + { + id: importDialog; + title: catalog.i18nc("@title:window", "Import Material"); + selectExisting: true; + nameFilters: Cura.ContainerManager.getContainerNameFilters("material") + folder: CuraApplication.getDefaultPath("dialog_material_path") + onAccepted: + { + var result = Cura.ContainerManager.importMaterialContainer(fileUrl) + + messageDialog.title = catalog.i18nc("@title:window", "Import Material") + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message) + if(result.status == "success") + { + messageDialog.icon = StandardIcon.Information + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl) + } + else if(result.status == "duplicate") + { + messageDialog.icon = StandardIcon.Warning + } + else + { + messageDialog.icon = StandardIcon.Critical + } + messageDialog.open() + CuraApplication.setDefaultPath("dialog_material_path", folder) + } + } + + FileDialog + { + id: exportDialog; + title: catalog.i18nc("@title:window", "Export Material"); + selectExisting: false; + nameFilters: Cura.ContainerManager.getContainerNameFilters("material") + folder: CuraApplication.getDefaultPath("dialog_material_path") + onAccepted: + { + if(base.currentItem.metadata.base_file) + { + var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl) + } + else + { + var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl) + } + + messageDialog.title = catalog.i18nc("@title:window", "Export Material") + if(result.status == "error") + { + messageDialog.icon = StandardIcon.Critical + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message) + messageDialog.open() + } + else if(result.status == "success") + { + messageDialog.icon = StandardIcon.Information + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path) + messageDialog.open() + } + CuraApplication.setDefaultPath("dialog_material_path", folder) + } + } + + MessageDialog + { + id: messageDialog + } + + UM.SettingPropertyProvider + { + id: materialDiameterProvider + + containerStackId: Cura.ExtruderManager.activeExtruderStackId + key: "material_diameter" + watchedProperties: [ "value" ] + storeIndex: 5 + } + + UM.I18nCatalog { id: catalog; name: "cura"; } + SystemPalette { id: palette } + } + + onCurrentItemChanged: + { + if(currentItem == null) + { + return + } + materialProperties.name = currentItem.name; + materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID"); + + if(currentItem.metadata != undefined && currentItem.metadata != null) + { + materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown"; + materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown"; + materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow"; + materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow"; + + materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : ""; + materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : ""; + + if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null) + { + materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0; + materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0; + materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0"; + } + else + { + materialProperties.density = 0.0; + materialProperties.diameter = 0.0; + materialProperties.approximate_diameter = "0"; + } + + } + } +} From 4468f4d620ad7babdb1c26f27fa00c8bed573bf6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 15 Feb 2018 15:06:15 +0100 Subject: [PATCH 036/266] WIP: Fix NozzleMenu warning on non-notifiable bindings --- cura/Settings/MachineManager.py | 7 ++++++- resources/qml/Menus/NozzleMenu.qml | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4871886542..89106f9bda 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1302,6 +1302,12 @@ class MachineManager(QObject): def createMachineManager(): return MachineManager() + @pyqtSlot(int, result = "QVariant") + def getExtruder(self, position: int): + if self._global_container_stack: + return self._global_container_stack.extruders.get(str(position)) + return None + @deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7") def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None) -> InstanceContainer: if not definition.getMetaDataEntry("has_materials"): @@ -1357,7 +1363,6 @@ class MachineManager(QObject): # # New # - @pyqtProperty("QVariant", notify = rootMaterialChanged) def currentRootMaterialId(self): # initial filling the current_root_material_id diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index d3ddbb8473..96b21f285c 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -19,6 +19,16 @@ Menu id: nozzleModel } + property var extruderStack: Cura.MachineManager.getExtruder(extruderIndex) + + Connections + { + target: Cura.MachineManager + onGlobalContainerChanged: { + menu.extruderStack = Cura.MachineManager.getExtruder(extruderIndex) + } + } + Instantiator { model: nozzleModel @@ -27,7 +37,7 @@ Menu { text: model.hotend_name checkable: true - checked: Cura.MachineManager.activeMachine.extruders[extruderIndex].variant.name == model.hotend_name + checked: extruderStack.variant.name == model.hotend_name exclusiveGroup: group onTriggered: { Cura.MachineManager.setVariantGroup(extruderIndex, model.container_node); From a0b53dc1c9befb7e36c9dfc264caa4fdaf50929a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 15 Feb 2018 15:47:00 +0100 Subject: [PATCH 037/266] WIP: Materials management page, make Activate work --- .../MaterialSettingsVisibilityHandler.py | 1 + cura/Settings/MaterialsModel.py | 4 ++ resources/qml/Preferences/MaterialsPage.qml | 45 ++++++++++++++----- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/cura/Settings/MaterialSettingsVisibilityHandler.py b/cura/Settings/MaterialSettingsVisibilityHandler.py index 5b6050d2c0..bafe566293 100644 --- a/cura/Settings/MaterialSettingsVisibilityHandler.py +++ b/cura/Settings/MaterialSettingsVisibilityHandler.py @@ -3,6 +3,7 @@ import UM.Settings.Models.SettingVisibilityHandler + class MaterialSettingsVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler.SettingVisibilityHandler): def __init__(self, parent = None, *args, **kwargs): super().__init__(parent = parent, *args, **kwargs) diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py index f133684032..51f9e09be6 100644 --- a/cura/Settings/MaterialsModel.py +++ b/cura/Settings/MaterialsModel.py @@ -205,6 +205,7 @@ class NewMaterialsModel(ListModel): GuidRole = Qt.UserRole + 12 DensityRole = Qt.UserRole + 13 DiameterRole = Qt.UserRole + 14 + IsReadOnlyRole = Qt.UserRole + 15 def __init__(self, parent = None): super().__init__(parent) @@ -224,8 +225,10 @@ class NewMaterialsModel(ListModel): self.addRoleName(self.GuidRole, "guid") self.addRoleName(self.DensityRole, "density") self.addRoleName(self.DiameterRole, "diameter") + self.addRoleName(self.IsReadOnlyRole, "is_read_only") from cura.CuraApplication import CuraApplication + self._container_registry = CuraApplication.getInstance().getContainerRegistry() machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() material_manager = CuraApplication.getInstance()._material_manager @@ -259,6 +262,7 @@ class NewMaterialsModel(ListModel): "container_id": container_node.metadata["id"], "density": container_node.metadata.get("properties", {}).get("density", ""), "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), + "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]), } for key in keys_to_fetch: diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index cf8cd959bf..ae90c13e8c 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -34,6 +34,19 @@ Item text: catalog.i18nc("@title:tab", "Materials") } + property var currentItem: + { + var current_index = materialListView.currentIndex; + return materialsModel.getItem(current_index); + } + + property var isCurrentItemActivated: + { + const extruder_position = Cura.ExtruderManager.activeExtruderIndex; + const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; + return base.currentItem.root_material_id == root_material_id; + } + Row // Button Row { id: buttonRow @@ -48,12 +61,15 @@ Item Button { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" - //enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials - enabled: true // TODO + enabled: !isCurrentItemActivated onClicked: { forceActiveFocus() - Cura.MachineManager.setActiveMaterial(base.currentItem.id) - currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. + + var current_index = materialListView.currentIndex; + var item = materialsModel.getItem(current_index); + + const extruder_position = Cura.ExtruderManager.activeExtruderIndex; + Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node); } } @@ -147,7 +163,16 @@ Item top: parent.top left: parent.left } - text: "TODO" + visible: text != "" + text: { + // OLD STUFF + var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; + if (Cura.MachineManager.hasVariants) + { + caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName; + } + return caption; + } width: materialScrollView.width elide: Text.ElideRight } @@ -219,10 +244,10 @@ Item width: Math.floor((parent.width * 0.3)) text: model.material elide: Text.ElideRight - font.italic: { + font.italic: { // TODO: make it easier const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; - return model.root_material_id == root_material_id; // TODO + return model.root_material_id == root_material_id } color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; } @@ -230,10 +255,10 @@ Item { text: (model.name != model.material) ? model.name : "" elide: Text.ElideRight - font.italic: { + font.italic: { // TODO: make it easier const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; - return model.root_material_id == root_material_id; // TODO + return model.root_material_id == root_material_id; } color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; } @@ -329,7 +354,7 @@ Item bottom: parent.bottom } - editingEnabled: base.currentItem != null && !base.currentItem.readOnly + editingEnabled: base.currentItem != null && !base.currentItem.is_read_only properties: materialProperties containerId: base.currentItem != null ? base.currentItem.id : "" From 20e0f8a82af24f32ba34888980f4178d0381bf5a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 11:00:48 +0100 Subject: [PATCH 038/266] WIP: Fix material serialization --- .../XmlMaterialProfile/XmlMaterialProfile.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 36a7733568..f35f15b737 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -190,6 +190,8 @@ class XmlMaterialProfile(InstanceContainer): machine_container_map = {} machine_nozzle_map = {} + variant_manager = CuraApplication.getInstance()._variant_manager + all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self.getId()) for container in all_containers: definition_id = container.getDefinition().getId() @@ -202,9 +204,10 @@ class XmlMaterialProfile(InstanceContainer): if definition_id not in machine_nozzle_map: machine_nozzle_map[definition_id] = {} - variant = container.getMetaDataEntry("variant") - if variant: - machine_nozzle_map[definition_id][variant] = container + variant_name = container.getMetaDataEntry("variant_name") + if variant_name: + machine_nozzle_map[definition_id][variant_name] = variant_manager.getVariantNode(definition_id, + variant_name) continue machine_container_map[definition_id] = container @@ -236,16 +239,12 @@ class XmlMaterialProfile(InstanceContainer): self._addSettingElement(builder, instance) # Find all hotend sub-profiles corresponding to this material and machine and add them to this profile. - for hotend_id, hotend in machine_nozzle_map[definition_id].items(): - variant_containers = registry.findInstanceContainersMetadata(id = hotend.getMetaDataEntry("variant")) - if not variant_containers: - continue - + for hotend_name, variant_node in machine_nozzle_map[definition_id].items(): # The hotend identifier is not the containers name, but its "name". - builder.start("hotend", {"id": variant_containers[0]["name"]}) + builder.start("hotend", {"id": hotend_name}) # Compatible is a special case, as it's added as a meta data entry (instead of an instance). - compatible = hotend.getMetaDataEntry("compatible") + compatible = variant_node.metadata.get("compatible") if compatible is not None: builder.start("setting", {"key": "hardware compatible"}) if compatible: @@ -254,7 +253,7 @@ class XmlMaterialProfile(InstanceContainer): builder.data("no") builder.end("setting") - for instance in hotend.findInstances(): + for instance in variant_node.getContainer().findInstances(): if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value: # If the settings match that of the machine profile, just skip since we inherit the machine profile. continue From 7fa218e9cdde2fd8ba0ad57e2e27a4fddbaa0715 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 11:16:49 +0100 Subject: [PATCH 039/266] WIP: Remove old Settings/MaterialManager --- cura/CuraApplication.py | 7 ---- cura/Settings/MaterialManager.py | 57 -------------------------------- 2 files changed, 64 deletions(-) delete mode 100644 cura/Settings/MaterialManager.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eee0ecabe0..e9be1f96c9 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -73,7 +73,6 @@ from . import CameraImageProvider from . import MachineActionManager from cura.Settings.MachineManager import MachineManager -from cura.Settings.MaterialManager import MaterialManager from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.UserChangesModel import UserChangesModel from cura.Settings.ExtrudersModel import ExtrudersModel @@ -852,11 +851,6 @@ class CuraApplication(QtApplication): self._extruder_manager = ExtruderManager.createExtruderManager() return self._extruder_manager - def getMaterialManager(self, *args): - if self._material_manager is None: - self._material_manager = MaterialManager.createMaterialManager() - return self._material_manager - def getObjectsModel(self, *args): if self._object_manager is None: self._object_manager = ObjectsModel.createObjectsModel() @@ -930,7 +924,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController) qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager) qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager) - qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager) qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager) qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) diff --git a/cura/Settings/MaterialManager.py b/cura/Settings/MaterialManager.py deleted file mode 100644 index 80d2723438..0000000000 --- a/cura/Settings/MaterialManager.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from PyQt5.QtCore import QObject, pyqtSlot #To expose data to QML. - -from cura.Settings.ContainerManager import ContainerManager -from UM.Logger import Logger -from UM.Message import Message #To create a warning message about material diameter. -from UM.i18n import i18nCatalog #Translated strings. - -catalog = i18nCatalog("cura") - -## Handles material-related data, processing requests to change them and -# providing data for the GUI. -# -# TODO: Move material-related managing over from the machine manager to here. -class MaterialManager(QObject): - ## Creates the global values for the material manager to use. - def __init__(self, parent = None): - super().__init__(parent) - - #Material diameter changed warning message. - self._material_diameter_warning_message = Message(catalog.i18nc("@info:status Has a cancel button next to it.", - "The selected material diameter causes the material to become incompatible with the current printer."), title = catalog.i18nc("@info:title", "Incompatible Material")) - self._material_diameter_warning_message.addAction("Undo", catalog.i18nc("@action:button", "Undo"), None, catalog.i18nc("@action", "Undo changing the material diameter.")) - self._material_diameter_warning_message.actionTriggered.connect(self._materialWarningMessageAction) - - ## Creates an instance of the MaterialManager. - # - # This should only be called by PyQt to create the singleton instance of - # this class. - @staticmethod - def createMaterialManager(engine = None, script_engine = None): - return MaterialManager() - - @pyqtSlot(str, str) - def showMaterialWarningMessage(self, material_id, previous_diameter): - self._material_diameter_warning_message.previous_diameter = previous_diameter #Make sure that the undo button can properly undo the action. - self._material_diameter_warning_message.material_id = material_id - self._material_diameter_warning_message.show() - - ## Called when clicking "undo" on the warning dialogue for disappeared - # materials. - # - # This executes the undo action, restoring the material diameter. - # - # \param button The identifier of the button that was pressed. - def _materialWarningMessageAction(self, message, button): - if button == "Undo": - container_manager = ContainerManager.getInstance() - container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter) - approximate_previous_diameter = str(round(float(self._material_diameter_warning_message.previous_diameter))) - container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "approximate_diameter", approximate_previous_diameter) - container_manager.setContainerProperty(self._material_diameter_warning_message.material_id, "material_diameter", "value", self._material_diameter_warning_message.previous_diameter); - message.hide() - else: - Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button)) \ No newline at end of file From f024f45cfe02da487ac41231692793fb65b5cf18 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 11:18:19 +0100 Subject: [PATCH 040/266] WIP: Rework Material management page --- cura/Machines/MaterialManager.py | 41 +++++--- cura/Settings/ContainerManager.py | 98 ++++++------------- .../XmlMaterialProfile/XmlMaterialProfile.py | 24 +++-- resources/qml/Preferences/MaterialView.qml | 34 ++++--- resources/qml/Preferences/MaterialsPage.qml | 21 ++-- 5 files changed, 104 insertions(+), 114 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index f5a8995af1..25130fe255 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -1,4 +1,4 @@ -from collections import defaultdict +from collections import defaultdict, OrderedDict from typing import Optional from PyQt5.Qt import QTimer, QObject, pyqtSignal @@ -17,6 +17,9 @@ class MaterialGroup: self.root_material_node = None self.derived_material_node_list = [] + def __str__(self) -> str: + return "%s[%s]" % (self.__class__.__name__, self.name) + class MaterialNode(ContainerNode): __slots__ = ("material_map", "children_map") @@ -45,6 +48,9 @@ class MaterialManager(QObject): self._material_diameter_map = defaultdict() # root_material_id -> diameter -> root_material_id for that diameter self._diameter_material_map = dict() # material id including diameter (generic_pla_175) -> material root id (generic_pla) + # This is used in Legacy UM3 send material function and the material management page. + self._guid_material_groups_map = defaultdict(list) # GUID -> a list of material_groups + # The machine definition ID for the non-machine-specific materials. # This is used as the last fallback option if the given machine-specific material(s) cannot be found. self._default_machine_definition_id = "fdmprinter" @@ -63,7 +69,7 @@ class MaterialManager(QObject): # Find all materials and put them in a matrix for quick search. material_metadata_list = self._container_registry.findContainersMetadata(type = "material") - self._material_group_map = {} + self._material_group_map = OrderedDict() self._diameter_machine_variant_material_map = {} # Map #1 @@ -85,6 +91,14 @@ class MaterialManager(QObject): else: new_node = MaterialNode(material_metadata) group.derived_material_node_list.append(new_node) + self._material_group_map = OrderedDict(sorted(self._material_group_map.items(), key = lambda x: x[0])) + + # Map #1.5 + # GUID -> material group list + self._guid_material_groups_map = defaultdict(list) + for root_material_id, material_group in self._material_group_map.items(): + guid = material_group.root_material_node.metadata["GUID"] + self._guid_material_groups_map[guid].append(material_group) # Map #2 # Lookup table for material type -> fallback material metadata @@ -198,6 +212,9 @@ class MaterialManager(QObject): def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str: return self._diameter_material_map.get(root_material_id) + def getMaterialGroupListByGUID(self, guid: str) -> Optional[list]: + return self._guid_material_groups_map.get(guid) + # # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. # @@ -206,29 +223,27 @@ class MaterialManager(QObject): rounded_diameter = str(round(diameter)) if rounded_diameter not in self._diameter_machine_variant_material_map: Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter) - return {} + return dict() # If there are variant materials, get the variant material machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter] machine_node = machine_variant_material_map.get(machine_definition_id) + default_machine_node = machine_variant_material_map.get(self._default_machine_definition_id) variant_node = None - if machine_node is None: - machine_node = machine_variant_material_map.get(self._default_machine_definition_id) if variant_name is not None and machine_node is not None: variant_node = machine_node.getChildNode(variant_name) + nodes_to_check = [variant_node, machine_node, default_machine_node] + # Fallback mechanism of finding materials: # 1. variant-specific material # 2. machine-specific material # 3. generic material (for fdmprinter) - material_id_metadata_dict = {} - if variant_node is not None: - material_id_metadata_dict = {mid: node for mid, node in variant_node.material_map.items()} - - # Fallback: machine-specific materials, including "fdmprinter" - if not material_id_metadata_dict: - if machine_node is not None: - material_id_metadata_dict = {mid: node for mid, node in machine_node.material_map.items()} + material_id_metadata_dict = dict() + for node in nodes_to_check: + if node is not None: + material_id_metadata_dict = {mid: node for mid, node in variant_node.material_map.items()} + break return material_id_metadata_dict diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 4c92eed845..7d4c702cf4 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -764,16 +764,16 @@ class ContainerManager(QObject): ## Create a duplicate of a material, which has the same GUID and base_file metadata # # \return \type{str} the id of the newly created container. - @pyqtSlot(str, result = str) - def duplicateMaterial(self, material_id: str) -> str: - assert material_id + @pyqtSlot("QVariant") + def duplicateMaterial(self, material_node): + root_material_id = material_node.metadata["base_file"] from cura.CuraApplication import CuraApplication material_manager = CuraApplication.getInstance()._material_manager - material_group = material_manager.getMaterialGroup(material_id) + material_group = material_manager.getMaterialGroup(root_material_id) if not material_group: - Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id) + Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) return "" base_container = material_group.root_material_node.getContainer() @@ -803,7 +803,7 @@ class ContainerManager(QObject): if container_to_copy.getMetaDataEntry("variant_name"): variant_name = container_to_copy.getMetaDataEntry("variant_name") new_id += "_" + variant_name.replace(" ", "_") - if current_id == material_id: + if current_id == root_material_id: clone_of_original = new_id new_container = copy.deepcopy(container_to_copy) @@ -814,17 +814,6 @@ class ContainerManager(QObject): for container_to_add in new_containers: container_to_add.setDirty(True) ContainerRegistry.getInstance().addContainer(container_to_add) - return self._getMaterialContainerIdForActiveMachine(clone_of_original) - - ## Create a duplicate of a material or it's original entry - # - # \return \type{str} the id of the newly created container. - @pyqtSlot(str, result = str) - def duplicateOriginalMaterial(self, material_id): - - # check if the given material has a base file (i.e. was shipped by default) - base_file = self.getContainerMetaDataEntry(material_id, "base_file") - return self.duplicateMaterial(base_file) ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # @@ -869,72 +858,43 @@ class ContainerManager(QObject): duplicated_container.setName(catalog.i18nc("@label", "Custom Material")) self._container_registry.addContainer(duplicated_container) - return self._getMaterialContainerIdForActiveMachine(new_id) - - ## Find the id of a material container based on the new material - # Utilty function that is shared between duplicateMaterial and createMaterial - # - # \param base_file \type{str} the id of the created container. - def _getMaterialContainerIdForActiveMachine(self, base_file): - global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack: - return base_file - - has_machine_materials = parseBool(global_stack.getMetaDataEntry("has_machine_materials", default = False)) - has_variant_materials = parseBool(global_stack.getMetaDataEntry("has_variant_materials", default = False)) - has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", default = False)) - if has_machine_materials or has_variant_materials: - if has_variants: - materials = self._container_registry.findInstanceContainersMetadata(type = "material", base_file = base_file, definition = global_stack.getBottom().getId(), variant = self._machine_manager.activeVariantId) - else: - materials = self._container_registry.findInstanceContainersMetadata(type = "material", base_file = base_file, definition = global_stack.getBottom().getId()) - - if materials: - return materials[0]["id"] - - Logger.log("w", "Unable to find a suitable container based on %s for the current machine.", base_file) - return "" # do not activate a new material if a container can not be found - - return base_file ## Get a list of materials that have the same GUID as the reference material # # \param material_id \type{str} the id of the material for which to get the linked materials. # \return \type{list} a list of names of materials with the same GUID - @pyqtSlot(str, result = "QStringList") - def getLinkedMaterials(self, material_id: str): - containers = self._container_registry.findInstanceContainersMetadata(id = material_id) - if not containers: - Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't exist.", material_id) - return [] + @pyqtSlot("QVariant", result = "QStringList") + def getLinkedMaterials(self, material_node): + guid = material_node.metadata["GUID"] - material_container = containers[0] - material_base_file = material_container.get("base_file", "") - material_guid = material_container.get("GUID", "") - if not material_guid: - Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't have a GUID.", material_id) - return [] + from cura.CuraApplication import CuraApplication + material_manager = CuraApplication.getInstance()._material_manager + + material_group_list = material_manager.getMaterialGroupListByGUID(guid) - containers = self._container_registry.findInstanceContainersMetadata(type = "material", GUID = material_guid) linked_material_names = [] - for container in containers: - if container["id"] in [material_id, material_base_file] or container.get("base_file") != container["id"]: - continue - - linked_material_names.append(container["name"]) + if material_group_list: + for material_group in material_group_list: + linked_material_names.append(material_group.root_material_node.metadata["name"]) return linked_material_names ## Unlink a material from all other materials by creating a new GUID # \param material_id \type{str} the id of the material to create a new GUID for. - @pyqtSlot(str) - def unlinkMaterial(self, material_id: str): - containers = self._container_registry.findInstanceContainers(id=material_id) - if not containers: - Logger.log("d", "Unable to make the material with id %s unique, because it doesn't exist.", material_id) - return "" + @pyqtSlot("QVariant") + def unlinkMaterial(self, material_node): + # Get the material group + from cura.CuraApplication import CuraApplication + material_manager = CuraApplication.getInstance()._material_manager + material_group = material_manager.getMaterialGroup(material_node.metadata["base_file"]) - containers[0].setMetaDataEntry("GUID", str(uuid.uuid4())) + # Generate a new GUID + new_guid = str(uuid.uuid4()) + # Update the GUID + # NOTE: We only need to set the root material container because XmlMaterialProfile.setMetaDataEntry() will + # take care of the derived containers too + container = material_group.root_material_node.getContainer() + container.setMetaDataEntry("GUID", new_guid) ## Get the singleton instance for this class. @classmethod diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index f35f15b737..338a72434f 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -48,18 +48,28 @@ class XmlMaterialProfile(InstanceContainer): ## Overridden from InstanceContainer # set the meta data for all machine / variant combinations - def setMetaDataEntry(self, key, value): + def setMetaDataEntry(self, key, value, is_first_call = True): registry = ContainerRegistry.getInstance() if registry.isReadOnly(self.getId()): return - super().setMetaDataEntry(key, value) + # Prevent recursion + if is_first_call: + super().setMetaDataEntry(key, value) - basefile = self.getMetaDataEntry("base_file", self.getId()) #if basefile is self.getId, this is a basefile. - # Update all containers that share basefile - for container in registry.findInstanceContainers(base_file = basefile): - if container.getMetaDataEntry(key, None) != value: # Prevent recursion - container.setMetaDataEntry(key, value) + # Get the MaterialGroup + material_manager = CuraApplication.getInstance()._material_manager + root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile. + material_group = material_manager.getMaterialGroup(root_material_id) + + # Update the root material container + root_material_container = material_group.root_material_node.getContainer() + root_material_container.setMetaDataEntry(key, value, is_first_call = False) + + # Update all containers derived from it + for node in material_group.derived_material_node_list: + container = node.getContainer() + container.setMetaDataEntry(key, value, is_first_call = False) ## Overridden from InstanceContainer, similar to setMetaDataEntry. # without this function the setName would only set the name of the specific nozzle / material / machine combination container diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 50eb3d3e99..f07564f7a5 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -12,7 +12,8 @@ TabView { id: base - property QtObject properties; + property QtObject properties + property var currentMaterialNode: null property bool editingEnabled: false; property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€" @@ -27,15 +28,16 @@ TabView property bool reevaluateLinkedMaterials: false property string linkedMaterialNames: { - if (reevaluateLinkedMaterials) - { + if (reevaluateLinkedMaterials) { reevaluateLinkedMaterials = false; } - if(!base.containerId || !base.editingEnabled) - { + if (!base.containerId || !base.editingEnabled) { + return "" + } + var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode); + if (linkedMaterials.length <= 1) { return "" } - var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId); return linkedMaterials.join(", "); } @@ -80,18 +82,18 @@ TabView { id: textField; width: scrollView.columnWidth; - text: properties.supplier; + text: properties.brand; readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialSupplier(properties.supplier, text) + onEditingFinished: base.updateMaterialBrand(properties.brand, text) } Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") } ReadOnlyTextField { width: scrollView.columnWidth; - text: properties.material_type; + text: properties.material; readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialType(properties.material_type, text) + onEditingFinished: base.updateMaterialType(properties.material, text) } Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } @@ -251,7 +253,7 @@ TabView visible: base.linkedMaterialNames != "" onClicked: { - Cura.ContainerManager.unlinkMaterial(base.containerId) + Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode) base.reevaluateLinkedMaterials = true } } @@ -466,12 +468,12 @@ TabView // update the type of the material function updateMaterialType (old_type, new_type) { base.setMetaDataEntry("material", old_type, new_type) - materialProperties.material_type = new_type + materialProperties.material= new_type } - // update the supplier of the material - function updateMaterialSupplier (old_supplier, new_supplier) { - base.setMetaDataEntry("brand", old_supplier, new_supplier) - materialProperties.supplier = new_supplier + // update the brand of the material + function updateMaterialBrand (old_brand, new_brand) { + base.setMetaDataEntry("brand", old_brand, new_brand) + materialProperties.brand = new_brand } } diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index ae90c13e8c..9fbd8a5042 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -34,6 +34,8 @@ Item text: catalog.i18nc("@title:tab", "Materials") } + property var hasCurrentItem: materialListView.currentItem != null; + property var currentItem: { var current_index = materialListView.currentIndex; @@ -65,9 +67,6 @@ Item onClicked: { forceActiveFocus() - var current_index = materialListView.currentIndex; - var item = materialsModel.getItem(current_index); - const extruder_position = Cura.ExtruderManager.activeExtruderIndex; Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node); } @@ -87,10 +86,11 @@ Item Button { text: catalog.i18nc("@action:button", "Duplicate"); iconName: "list-add" - enabled: true //TODO + enabled: base.hasCurrentItem onClicked: { forceActiveFocus() - // TODO + + Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); } } @@ -277,6 +277,7 @@ Item { var model = materialsModel.getItem(currentIndex); materialDetailsView.containerId = model.container_id; + materialDetailsView.currentMaterialNode = model.container_node; detailsPanel.updateMaterialPropertiesObject(); } @@ -303,8 +304,8 @@ Item materialProperties.name = currentItem.name; materialProperties.guid = currentItem.guid; - materialProperties.supplier = currentItem.brand ? currentItem.brand : "Unknown"; - materialProperties.material_type = currentItem.material ? currentItem.material : "Unknown"; + materialProperties.brand = currentItem.brand ? currentItem.brand : "Unknown"; + materialProperties.material = currentItem.material ? currentItem.material : "Unknown"; materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow"; materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow"; @@ -358,6 +359,7 @@ Item properties: materialProperties containerId: base.currentItem != null ? base.currentItem.id : "" + currentMaterialNode: base.currentItem property alias pane: base } @@ -369,8 +371,9 @@ Item property string guid: "00000000-0000-0000-0000-000000000000" property string name: "Unknown"; property string profile_type: "Unknown"; - property string supplier: "Unknown"; - property string material_type: "Unknown"; + property string brand: "Unknown"; + property string material: "Unknown"; // This needs to be named as "material" to be consistent with + // the material container's metadata entry property string color_name: "Yellow"; property color color_code: "yellow"; From 188c0343cff3feaa42552804396ab054daf233c4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 11:54:11 +0100 Subject: [PATCH 041/266] WIP: Improve map creation in MaterialManager --- cura/Machines/MaterialManager.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 25130fe255..a97b588e68 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -45,7 +45,7 @@ class MaterialManager(QObject): # We're using these two maps to convert between the specific diameter material id and the generic material id # because the generic material ids are used in qualities and definitions, while the specific diameter material is meant # i.e. generic_pla -> generic_pla_175 - self._material_diameter_map = defaultdict() # root_material_id -> diameter -> root_material_id for that diameter + self._material_diameter_map = defaultdict(dict) # root_material_id -> diameter -> root_material_id for that diameter self._diameter_material_map = dict() # material id including diameter (generic_pla_175) -> material root id (generic_pla) # This is used in Legacy UM3 send material function and the material management page. @@ -118,7 +118,7 @@ class MaterialManager(QObject): # and "generic_pla_175". This is inconvenient when we do material-specific quality lookup because a quality can # be for either "generic_pla" or "generic_pla_175", but not both. This map helps to get the correct material ID # for quality search. - self._material_diameter_map = defaultdict(defaultdict) + self._material_diameter_map = defaultdict(dict) self._diameter_material_map = dict() # Group the material IDs by the same name, material, brand, and color but with different diameters. @@ -140,8 +140,11 @@ class MaterialManager(QObject): # Map [root_material_id][diameter] -> root_material_id for this diameter for data_dict in material_group_dict.values(): for root_material_id1 in data_dict.values(): - for approximate_diameter2, root_material_id2 in data_dict.items(): - self._material_diameter_map[root_material_id1][approximate_diameter2] = root_material_id2 + if root_material_id1 in self._material_diameter_map: + continue + diameter_map = data_dict + for root_material_id2 in data_dict.values(): + self._material_diameter_map[root_material_id2] = diameter_map default_root_material_id = data_dict.get(self._default_approximate_diameter_for_quality_search) if default_root_material_id is None: From a5afaab467a52e19107ba8d25758010027729652 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 12:12:43 +0100 Subject: [PATCH 042/266] WIP: Fix material duplication and metadata update --- cura/Machines/MaterialManager.py | 4 +- cura/Settings/ContainerManager.py | 40 +++++++------------ .../XmlMaterialProfile/XmlMaterialProfile.py | 9 +++-- resources/qml/Preferences/MaterialView.qml | 2 +- 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index a97b588e68..550308f1dc 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -69,8 +69,7 @@ class MaterialManager(QObject): # Find all materials and put them in a matrix for quick search. material_metadata_list = self._container_registry.findContainersMetadata(type = "material") - self._material_group_map = OrderedDict() - self._diameter_machine_variant_material_map = {} + self._material_group_map = dict() # Map #1 # root_material_id -> MaterialGroup @@ -155,6 +154,7 @@ class MaterialManager(QObject): # Map #4 # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer + self._diameter_machine_variant_material_map = dict() for material_metadata in material_metadata_list: # We don't store empty material in the lookup tables if material_metadata["id"] == "empty_material": diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 7d4c702cf4..737810ee9d 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -42,8 +42,10 @@ class ContainerManager(QObject): def __init__(self, parent = None): super().__init__(parent) + self._application = Application.getInstance() self._container_registry = ContainerRegistry.getInstance() - self._machine_manager = Application.getInstance().getMachineManager() + self._machine_manager = self._application.getMachineManager() + self._material_manager = self._application._material_manager self._container_name_filters = {} ## Create a duplicate of the specified container @@ -211,18 +213,15 @@ class ContainerManager(QObject): # \param entry_value The new value of the entry. # # \return True if successful, False if not. - @pyqtSlot(str, str, str, result = bool) - def setContainerMetaDataEntry(self, container_id, entry_name, entry_value): - if self._container_registry.isReadOnly(container_id): - Logger.log("w", "Cannot set metadata of read-only container %s.", container_id) + # TODO: This is ONLY used by MaterialView for material containers. Maybe refactor this. + @pyqtSlot("QVariant", str, str) + def setContainerMetaDataEntry(self, container_node, entry_name, entry_value): + root_material_id = container_node.metadata["base_file"] + if self._container_registry.isReadOnly(root_material_id): + Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id) return False - containers = self._container_registry.findContainers(id = container_id) #We need the complete container, since we need to know whether the container is read-only or not. - if not containers: - Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id) - return False - - container = containers[0] + material_group = self._material_manager.getMaterialGroup(root_material_id) entries = entry_name.split("/") entry_name = entries.pop() @@ -230,7 +229,7 @@ class ContainerManager(QObject): sub_item_changed = False if entries: root_name = entries.pop(0) - root = container.getMetaDataEntry(root_name) + root = material_group.root_material_node.metadata.get(root_name) item = root for _ in range(len(entries)): @@ -243,12 +242,11 @@ class ContainerManager(QObject): entry_name = root_name entry_value = root + container = material_group.root_material_node.getContainer() container.setMetaDataEntry(entry_name, entry_value) if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed. container.metaDataChanged.emit(container) - return True - ## Set a setting property of the specified container. # # This will set the specified property of the specified setting of the container @@ -768,10 +766,7 @@ class ContainerManager(QObject): def duplicateMaterial(self, material_node): root_material_id = material_node.metadata["base_file"] - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - - material_group = material_manager.getMaterialGroup(root_material_id) + material_group = self._material_manager.getMaterialGroup(root_material_id) if not material_group: Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) return "" @@ -867,10 +862,7 @@ class ContainerManager(QObject): def getLinkedMaterials(self, material_node): guid = material_node.metadata["GUID"] - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - - material_group_list = material_manager.getMaterialGroupListByGUID(guid) + material_group_list = self._material_manager.getMaterialGroupListByGUID(guid) linked_material_names = [] if material_group_list: @@ -883,9 +875,7 @@ class ContainerManager(QObject): @pyqtSlot("QVariant") def unlinkMaterial(self, material_node): # Get the material group - from cura.CuraApplication import CuraApplication - material_manager = CuraApplication.getInstance()._material_manager - material_group = material_manager.getMaterialGroup(material_node.metadata["base_file"]) + material_group = self._material_manager.getMaterialGroup(material_node.metadata["base_file"]) # Generate a new GUID new_guid = str(uuid.uuid4()) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 338a72434f..80e3e3b721 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -48,14 +48,15 @@ class XmlMaterialProfile(InstanceContainer): ## Overridden from InstanceContainer # set the meta data for all machine / variant combinations - def setMetaDataEntry(self, key, value, is_first_call = True): + def setMetaDataEntry(self, key, value, apply_to_all = True): registry = ContainerRegistry.getInstance() if registry.isReadOnly(self.getId()): return # Prevent recursion - if is_first_call: + if not apply_to_all: super().setMetaDataEntry(key, value) + return # Get the MaterialGroup material_manager = CuraApplication.getInstance()._material_manager @@ -64,12 +65,12 @@ class XmlMaterialProfile(InstanceContainer): # Update the root material container root_material_container = material_group.root_material_node.getContainer() - root_material_container.setMetaDataEntry(key, value, is_first_call = False) + root_material_container.setMetaDataEntry(key, value, apply_to_all = False) # Update all containers derived from it for node in material_group.derived_material_node_list: container = node.getContainer() - container.setMetaDataEntry(key, value, is_first_call = False) + container.setMetaDataEntry(key, value, apply_to_all = False) ## Overridden from InstanceContainer, similar to setMetaDataEntry. # without this function the setName would only set the name of the specific nozzle / material / machine combination container diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index f07564f7a5..0c3063ff41 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -417,7 +417,7 @@ TabView // Tiny convenience function to check if a value really changed before trying to set it. function setMetaDataEntry(entry_name, old_value, new_value) { if (old_value != new_value) { - Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) + Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value) // make sure the UI properties are updated as well since we don't re-fetch the entire model here // When the entry_name is something like properties/diameter, we take the last part of the entry_name var list = entry_name.split("/") From 779f49f5454f163037cbda62b800c31179318a92 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 12:35:51 +0100 Subject: [PATCH 043/266] WIP: Make material removal work in material management dialog --- cura/Settings/ContainerManager.py | 22 ++++++++---- resources/qml/Preferences/MaterialsPage.qml | 38 +++++++++++++++------ 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 737810ee9d..3775655671 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -759,6 +759,19 @@ class ContainerManager(QObject): return new_change_instances + @pyqtSlot("QVariant") + def removeMaterial(self, material_node): + root_material_id = material_node.metadata["base_file"] + material_group = self._material_manager.getMaterialGroup(root_material_id) + if not material_group: + Logger.log("d", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id) + return + + nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list + for node in nodes_to_remove: + self._container_registry.removeContainer(node.metadata["id"]) + + ## Create a duplicate of a material, which has the same GUID and base_file metadata # # \return \type{str} the id of the newly created container. @@ -769,7 +782,7 @@ class ContainerManager(QObject): material_group = self._material_manager.getMaterialGroup(root_material_id) if not material_group: Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) - return "" + return base_container = material_group.root_material_node.getContainer() containers_to_copy = [] @@ -787,10 +800,9 @@ class ContainerManager(QObject): new_base_container.getMetaData()["base_file"] = new_base_id new_containers.append(new_base_container) - #Clone all of them. - clone_of_original = None #Keeping track of which one is the clone of the original material, since we need to return that. + # Clone all of them. for container_to_copy in containers_to_copy: - #Create unique IDs for every clone. + # Create unique IDs for every clone. current_id = container_to_copy.getId() new_id = new_base_id if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": @@ -798,8 +810,6 @@ class ContainerManager(QObject): if container_to_copy.getMetaDataEntry("variant_name"): variant_name = container_to_copy.getMetaDataEntry("variant_name") new_id += "_" + variant_name.replace(" ", "_") - if current_id == root_material_id: - clone_of_original = new_id new_container = copy.deepcopy(container_to_copy) new_container.getMetaData()["id"] = new_id diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 9fbd8a5042..782637a6be 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -4,6 +4,7 @@ import QtQuick 2.8 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -34,16 +35,14 @@ Item text: catalog.i18nc("@title:tab", "Materials") } - property var hasCurrentItem: materialListView.currentItem != null; + property var hasCurrentItem: materialListView.currentItem != null - property var currentItem: - { + property var currentItem: { var current_index = materialListView.currentIndex; return materialsModel.getItem(current_index); } - property var isCurrentItemActivated: - { + property var isCurrentItemActivated: { const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; return base.currentItem.root_material_id == root_material_id; @@ -88,8 +87,7 @@ Item iconName: "list-add" enabled: base.hasCurrentItem onClicked: { - forceActiveFocus() - + forceActiveFocus(); Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); } } @@ -98,11 +96,10 @@ Item Button { text: catalog.i18nc("@action:button", "Remove") iconName: "list-remove" - //enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) - enabled: true // TODO + enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated onClicked: { - forceActiveFocus() - // TODO + forceActiveFocus(); + confirmRemoveMaterialDialog.open(); } } @@ -129,6 +126,25 @@ Item } } + MessageDialog + { + id: confirmRemoveMaterialDialog + + icon: StandardIcon.Question; + title: catalog.i18nc("@title:window", "Confirm Remove") + text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name) + standardButtons: StandardButton.Yes | StandardButton.No + modality: Qt.ApplicationModal + + onYes: + { + Cura.ContainerManager.removeMaterial(base.currentItem.container_node); + // reset current item to the first if available + materialListView.currentIndex = 0; + } + } + + Item { id: contentsItem From 4f29fc9ab270fd99184a7714fe4987cef19291b5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 13:54:15 +0100 Subject: [PATCH 044/266] WIP: make material creation work --- cura/Settings/ContainerManager.py | 56 ++++++++------------- resources/qml/Preferences/MaterialsPage.qml | 4 +- 2 files changed, 24 insertions(+), 36 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 3775655671..f31c4fda04 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -776,7 +776,7 @@ class ContainerManager(QObject): # # \return \type{str} the id of the newly created container. @pyqtSlot("QVariant") - def duplicateMaterial(self, material_node): + def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None): root_material_id = material_node.metadata["base_file"] material_group = self._material_manager.getMaterialGroup(root_material_id) @@ -794,16 +794,19 @@ class ContainerManager(QObject): # Create a new ID & container to hold the data. new_containers = [] - new_base_id = self._container_registry.uniqueName(base_container.getId()) + if new_base_id is None: + new_base_id = self._container_registry.uniqueName(base_container.getId()) new_base_container = copy.deepcopy(base_container) new_base_container.getMetaData()["id"] = new_base_id new_base_container.getMetaData()["base_file"] = new_base_id + if new_metadata is not None: + for key, value in new_metadata.items(): + new_base_container.getMetaData()[key] = value new_containers.append(new_base_container) # Clone all of them. for container_to_copy in containers_to_copy: # Create unique IDs for every clone. - current_id = container_to_copy.getId() new_id = new_base_id if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": new_id += "_" + container_to_copy.getMetaDataEntry("definition") @@ -814,6 +817,10 @@ class ContainerManager(QObject): new_container = copy.deepcopy(container_to_copy) new_container.getMetaData()["id"] = new_id new_container.getMetaData()["base_file"] = new_base_id + if new_metadata is not None: + for key, value in new_metadata.items(): + new_container.getMetaData()[key] = value + new_containers.append(new_container) for container_to_add in new_containers: @@ -823,46 +830,27 @@ class ContainerManager(QObject): ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # # \return \type{str} the id of the newly created container. - @pyqtSlot(result = str) - def createMaterial(self) -> str: + @pyqtSlot() + def createMaterial(self): # Ensure all settings are saved. Application.getInstance().saveSettings() global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack: - return "" - approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value"))) - containers = self._container_registry.findInstanceContainersMetadata(id = "generic_pla*", approximate_diameter = approximate_diameter) - if not containers: - Logger.log("d", "Unable to create a new material by cloning Generic PLA, because it cannot be found for the material diameter for this machine.") - return "" - - base_file = containers[0].get("base_file") - containers = self._container_registry.findInstanceContainers(id = base_file) - if not containers: - Logger.log("d", "Unable to create a new material by cloning Generic PLA, because the base file for Generic PLA for this machine can not be found.") - return "" + root_material_id = "generic_pla" + root_material_id = self._material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_diameter) + material_group = self._material_manager.getMaterialGroup(root_material_id) # Create a new ID & container to hold the data. new_id = self._container_registry.uniqueName("custom_material") - container_type = type(containers[0]) # Always XMLMaterialProfile, since we specifically clone the base_file - duplicated_container = container_type(new_id) + new_metadata = {"name": catalog.i18nc("@label", "Custom Material"), + "brand": catalog.i18nc("@label", "Custom"), + "GUID": str(uuid.uuid4()), + } - # Instead of duplicating we load the data from the basefile again. - # This ensures that the inheritance goes well and all "cut up" subclasses of the xmlMaterial profile - # are also correctly created. - with open(containers[0].getPath(), encoding="utf-8") as f: - duplicated_container.deserialize(f.read()) - - duplicated_container.setMetaDataEntry("GUID", str(uuid.uuid4())) - duplicated_container.setMetaDataEntry("brand", catalog.i18nc("@label", "Custom")) - # We're defaulting to PLA, as machines with material profiles don't like material types they don't know. - # TODO: This is a hack, the only reason this is in now is to bandaid the problem as we're close to a release! - duplicated_container.setMetaDataEntry("material", "PLA") - duplicated_container.setName(catalog.i18nc("@label", "Custom Material")) - - self._container_registry.addContainer(duplicated_container) + self.duplicateMaterial(material_group.root_material_node, + new_base_id = new_id, + new_metadata = new_metadata) ## Get a list of materials that have the same GUID as the reference material # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 782637a6be..4a8bc9e3c9 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -76,8 +76,8 @@ Item text: catalog.i18nc("@action:button", "Create") iconName: "list-add" onClicked: { - forceActiveFocus() - // TODO + forceActiveFocus(); + Cura.ContainerManager.createMaterial(); } } From 0b859bb308e35093b32ad1111ffa8a1e6baabf74 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:04:49 +0100 Subject: [PATCH 045/266] WIP: Make material export work --- cura/Settings/ContainerManager.py | 16 +++++----- resources/qml/Preferences/MaterialsPage.qml | 35 +++++++++++++++++++-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index f31c4fda04..3738825d26 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -397,7 +397,7 @@ class ContainerManager(QObject): @pyqtSlot(str, str, QUrl, result = "QVariantMap") def exportContainer(self, container_id: str, file_type: str, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]: if not container_id or not file_type or not file_url_or_string: - return { "status": "error", "message": "Invalid arguments"} + return {"status": "error", "message": "Invalid arguments"} if isinstance(file_url_or_string, QUrl): file_url = file_url_or_string.toLocalFile() @@ -405,20 +405,20 @@ class ContainerManager(QObject): file_url = file_url_or_string if not file_url: - return { "status": "error", "message": "Invalid path"} + return {"status": "error", "message": "Invalid path"} mime_type = None - if not file_type in self._container_name_filters: + if file_type not in self._container_name_filters: try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_url) except MimeTypeNotFoundError: - return { "status": "error", "message": "Unknown File Type" } + return {"status": "error", "message": "Unknown File Type"} else: mime_type = self._container_name_filters[file_type]["mime"] containers = self._container_registry.findContainers(id = container_id) if not containers: - return { "status": "error", "message": "Container not found"} + return {"status": "error", "message": "Container not found"} container = containers[0] if Platform.isOSX() and "." in file_url: @@ -435,12 +435,12 @@ class ContainerManager(QObject): result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_url)) if result == QMessageBox.No: - return { "status": "cancelled", "message": "User cancelled"} + return {"status": "cancelled", "message": "User cancelled"} try: contents = container.serialize() except NotImplementedError: - return { "status": "error", "message": "Unable to serialize container"} + return {"status": "error", "message": "Unable to serialize container"} if contents is None: return {"status": "error", "message": "Serialization returned None. Unable to write to file"} @@ -448,7 +448,7 @@ class ContainerManager(QObject): with SaveFile(file_url, "w") as f: f.write(contents) - return { "status": "success", "message": "Succesfully exported container", "path": file_url} + return {"status": "success", "message": "Successfully exported container", "path": file_url} ## Imports a profile from a file # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 4a8bc9e3c9..5592e97150 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -119,8 +119,8 @@ Item text: catalog.i18nc("@action:button", "Export") iconName: "document-export" onClicked: { - forceActiveFocus() - // TODO + forceActiveFocus(); + exportMaterialDialog.open(); } enabled: currentItem != null } @@ -144,6 +144,37 @@ Item } } + FileDialog + { + id: exportMaterialDialog + title: catalog.i18nc("@title:window", "Export Material") + selectExisting: false + nameFilters: Cura.ContainerManager.getContainerNameFilters("material") + folder: CuraApplication.getDefaultPath("dialog_material_path") + onAccepted: + { + var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl); + + messageDialog.title = catalog.i18nc("@title:window", "Export Material"); + if (result.status == "error") { + messageDialog.icon = StandardIcon.Critical; + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message); + messageDialog.open(); + } + else if (result.status == "success") { + messageDialog.icon = StandardIcon.Information; + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path); + messageDialog.open(); + } + CuraApplication.setDefaultPath("dialog_material_path", folder); + } + } + + MessageDialog + { + id: messageDialog + } + Item { id: contentsItem From 581699cd8d1a5c0f993bfcce75413eae436097fb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:08:45 +0100 Subject: [PATCH 046/266] WIP: Make material import work --- cura/Settings/ContainerManager.py | 12 ++++---- resources/qml/Preferences/MaterialsPage.qml | 32 +++++++++++++++++++-- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 3738825d26..240b7dfa4d 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -459,7 +459,7 @@ class ContainerManager(QObject): @pyqtSlot(QUrl, result = "QVariantMap") def importMaterialContainer(self, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]: if not file_url_or_string: - return { "status": "error", "message": "Invalid path"} + return {"status": "error", "message": "Invalid path"} if isinstance(file_url_or_string, QUrl): file_url = file_url_or_string.toLocalFile() @@ -467,16 +467,16 @@ class ContainerManager(QObject): file_url = file_url_or_string if not file_url or not os.path.exists(file_url): - return { "status": "error", "message": "Invalid path" } + return {"status": "error", "message": "Invalid path"} try: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_url) except MimeTypeNotFoundError: - return { "status": "error", "message": "Could not determine mime type of file" } + return {"status": "error", "message": "Could not determine mime type of file"} container_type = self._container_registry.getContainerForMimeType(mime_type) if not container_type: - return { "status": "error", "message": "Could not find a container to handle the specified file."} + return {"status": "error", "message": "Could not find a container to handle the specified file."} container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url))) container_id = self._container_registry.uniqueName(container_id) @@ -487,7 +487,7 @@ class ContainerManager(QObject): with open(file_url, "rt", encoding = "utf-8") as f: container.deserialize(f.read()) except PermissionError: - return { "status": "error", "message": "Permission denied when trying to read the file"} + return {"status": "error", "message": "Permission denied when trying to read the file"} except Exception as ex: return {"status": "error", "message": str(ex)} @@ -495,7 +495,7 @@ class ContainerManager(QObject): self._container_registry.addContainer(container) - return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) } + return {"status": "success", "message": "Successfully imported container {0}".format(container.getName())} ## Update the current active quality changes container with the settings from the user container. # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 5592e97150..92d596485c 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -108,8 +108,8 @@ Item text: catalog.i18nc("@action:button", "Import") iconName: "document-import" onClicked: { - forceActiveFocus() - // TODO + forceActiveFocus(); + importMaterialDialog.open(); } visible: true } @@ -144,6 +144,34 @@ Item } } + FileDialog + { + id: importMaterialDialog + title: catalog.i18nc("@title:window", "Import Material") + selectExisting: true + nameFilters: Cura.ContainerManager.getContainerNameFilters("material") + folder: CuraApplication.getDefaultPath("dialog_material_path") + onAccepted: + { + var result = Cura.ContainerManager.importMaterialContainer(fileUrl); + + messageDialog.title = catalog.i18nc("@title:window", "Import Material"); + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message); + if (result.status == "success") { + messageDialog.icon = StandardIcon.Information; + messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl); + } + else if (result.status == "duplicate") { + messageDialog.icon = StandardIcon.Warning; + } + else { + messageDialog.icon = StandardIcon.Critical; + } + messageDialog.open(); + CuraApplication.setDefaultPath("dialog_material_path", folder); + } + } + FileDialog { id: exportMaterialDialog From 850661fbdc0bb6bb893bb2fef2050c903a2ae292 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:09:38 +0100 Subject: [PATCH 047/266] WIP: Remove old material management QMLs --- resources/qml/Preferences/OldMaterialView.qml | 467 ------------------ .../qml/Preferences/OldMaterialsPage.qml | 412 --------------- 2 files changed, 879 deletions(-) delete mode 100644 resources/qml/Preferences/OldMaterialView.qml delete mode 100644 resources/qml/Preferences/OldMaterialsPage.qml diff --git a/resources/qml/Preferences/OldMaterialView.qml b/resources/qml/Preferences/OldMaterialView.qml deleted file mode 100644 index 1b3a3b93a8..0000000000 --- a/resources/qml/Preferences/OldMaterialView.qml +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.8 -import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -TabView -{ - id: base - - property QtObject properties; - - property bool editingEnabled: false; - property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€" - property real firstColumnWidth: (width * 0.50) | 0 - property real secondColumnWidth: (width * 0.40) | 0 - property string containerId: "" - property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {} - - property double spoolLength: calculateSpoolLength() - property real costPerMeter: calculateCostPerMeter() - - property bool reevaluateLinkedMaterials: false - property string linkedMaterialNames: - { - if (reevaluateLinkedMaterials) - { - reevaluateLinkedMaterials = false; - } - if(!base.containerId || !base.editingEnabled) - { - return "" - } - var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId); - return linkedMaterials.join(", "); - } - - Tab - { - title: catalog.i18nc("@title", "Information") - - anchors.margins: UM.Theme.getSize("default_margin").width - - ScrollView - { - id: scrollView - anchors.fill: parent - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - flickableItem.flickableDirection: Flickable.VerticalFlick - frameVisible: true - - property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0 - - Flow - { - id: containerGrid - - x: UM.Theme.getSize("default_margin").width - y: UM.Theme.getSize("default_lining").height - - width: base.width - property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } - ReadOnlyTextField - { - id: displayNameTextField; - width: scrollView.columnWidth; - text: properties.name; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialDisplayName(properties.name, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") } - ReadOnlyTextField - { - id: textField; - width: scrollView.columnWidth; - text: properties.supplier; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialSupplier(properties.supplier, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") } - ReadOnlyTextField - { - width: scrollView.columnWidth; - text: properties.material_type; - readOnly: !base.editingEnabled; - onEditingFinished: base.updateMaterialType(properties.material_type, text) - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } - Row { - width: scrollView.columnWidth - height: parent.rowHeight - spacing: Math.floor(UM.Theme.getSize("default_margin").width / 2) - - // color indicator square - Rectangle { - id: colorSelector - color: properties.color_code - - width: Math.floor(colorLabel.height * 0.75) - height: Math.floor(colorLabel.height * 0.75) - border.width: UM.Theme.getSize("default_lining").height - - anchors.verticalCenter: parent.verticalCenter - - // open the color selection dialog on click - MouseArea { - anchors.fill: parent - onClicked: colorDialog.open() - enabled: base.editingEnabled - } - } - - // pretty color name text field - ReadOnlyTextField { - id: colorLabel; - text: properties.color_name; - readOnly: !base.editingEnabled - onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text) - } - - // popup dialog to select a new color - // if successful it sets the properties.color_code value to the new color - ColorDialog { - id: colorDialog - color: properties.color_code - onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) - } - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - - Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") } - ReadOnlySpinBox - { - id: densitySpinBox - width: scrollView.columnWidth - value: properties.density - decimals: 2 - suffix: " g/cm³" - stepSize: 0.01 - readOnly: !base.editingEnabled - - onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value) - onValueChanged: updateCostPerMeter() - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") } - ReadOnlySpinBox - { - id: diameterSpinBox - width: scrollView.columnWidth - value: properties.diameter - decimals: 2 - suffix: " mm" - stepSize: 0.01 - readOnly: !base.editingEnabled - - onEditingFinished: - { - // This does not use a SettingPropertyProvider, because we need to make the change to all containers - // which derive from the same base_file - var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString(); - var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); - base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString()); - base.setMetaDataEntry("properties/diameter", properties.diameter, value); - var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); - if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter) - { - Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter); - } - Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value); - } - onValueChanged: updateCostPerMeter() - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } - SpinBox - { - id: spoolCostSpinBox - width: scrollView.columnWidth - value: base.getMaterialPreferenceValue(properties.guid, "spool_cost") - prefix: base.currency + " " - decimals: 2 - maximumValue: 100000000 - - onValueChanged: { - base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value)) - updateCostPerMeter() - } - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } - SpinBox - { - id: spoolWeightSpinBox - width: scrollView.columnWidth - value: base.getMaterialPreferenceValue(properties.guid, "spool_weight") - suffix: " g" - stepSize: 100 - decimals: 0 - maximumValue: 10000 - - onValueChanged: { - base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value)) - updateCostPerMeter() - } - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") } - Label - { - width: scrollView.columnWidth - text: "~ %1 m".arg(Math.round(base.spoolLength)) - verticalAlignment: Qt.AlignVCenter - height: parent.rowHeight - } - - Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") } - Label - { - width: scrollView.columnWidth - text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency) - verticalAlignment: Qt.AlignVCenter - height: parent.rowHeight - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible } - Label - { - width: 2 * scrollView.columnWidth - verticalAlignment: Qt.AlignVCenter - text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames) - wrapMode: Text.WordWrap - visible: unlinkMaterialButton.visible - } - Button - { - id: unlinkMaterialButton - text: catalog.i18nc("@label", "Unlink Material") - visible: base.linkedMaterialNames != "" - onClicked: - { - Cura.ContainerManager.unlinkMaterial(base.containerId) - base.reevaluateLinkedMaterials = true - } - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - - Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") } - - ReadOnlyTextArea - { - text: properties.description; - width: 2 * scrollView.columnWidth - wrapMode: Text.WordWrap - - readOnly: !base.editingEnabled; - - onEditingFinished: base.setMetaDataEntry("description", properties.description, text) - } - - Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") } - - ReadOnlyTextArea - { - text: properties.adhesion_info; - width: 2 * scrollView.columnWidth - wrapMode: Text.WordWrap - - readOnly: !base.editingEnabled; - - onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text) - } - - Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } - } - - function updateCostPerMeter() - { - base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value); - base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value); - } - } - } - - Tab - { - title: catalog.i18nc("@label", "Print settings") - anchors - { - leftMargin: UM.Theme.getSize("default_margin").width - topMargin: UM.Theme.getSize("default_margin").height - bottomMargin: UM.Theme.getSize("default_margin").height - rightMargin: 0 - } - - ScrollView - { - anchors.fill: parent; - - ListView - { - model: UM.SettingDefinitionsModel - { - containerId: Cura.MachineManager.activeDefinitionId - visibilityHandler: Cura.MaterialSettingsVisibilityHandler { } - expanded: ["*"] - } - - delegate: UM.TooltipArea - { - width: childrenRect.width - height: childrenRect.height - text: model.description - Label - { - id: label - width: base.firstColumnWidth; - height: spinBox.height + UM.Theme.getSize("default_lining").height - text: model.label - elide: Text.ElideRight - verticalAlignment: Qt.AlignVCenter - } - ReadOnlySpinBox - { - id: spinBox - anchors.left: label.right - value: { - if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) - { - return parseFloat(materialPropertyProvider.properties.value); - } - if (!isNaN(parseFloat(machinePropertyProvider.properties.value))) - { - return parseFloat(machinePropertyProvider.properties.value); - } - return 0; - } - width: base.secondColumnWidth - readOnly: !base.editingEnabled - suffix: " " + model.unit - maximumValue: 99999 - decimals: model.unit == "mm" ? 2 : 0 - - onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) - } - - UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key } - UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key } - } - } - } - } - - function calculateSpoolLength(diameter, density, spoolWeight) - { - if(!diameter) - { - diameter = properties.diameter; - } - if(!density) - { - density = properties.density; - } - if(!spoolWeight) - { - spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight"); - } - - if (diameter == 0 || density == 0 || spoolWeight == 0) - { - return 0; - } - var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2 - var volume = (spoolWeight / density); // in cm3 - return volume / area; // in m - } - - function calculateCostPerMeter(spoolCost) - { - if(!spoolCost) - { - spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost"); - } - - if (spoolLength == 0) - { - return 0; - } - return spoolCost / spoolLength; - } - - // Tiny convenience function to check if a value really changed before trying to set it. - function setMetaDataEntry(entry_name, old_value, new_value) { - if (old_value != new_value) { - Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) - // make sure the UI properties are updated as well since we don't re-fetch the entire model here - // When the entry_name is something like properties/diameter, we take the last part of the entry_name - var list = entry_name.split("/") - var key = list[list.length - 1] - properties[key] = new_value - } - } - - function setMaterialPreferenceValue(material_guid, entry_name, new_value) - { - if(!(material_guid in materialPreferenceValues)) - { - materialPreferenceValues[material_guid] = {}; - } - if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value) - { - // value has not changed - return - } - materialPreferenceValues[material_guid][entry_name] = new_value; - - // store preference - UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues)); - } - - function getMaterialPreferenceValue(material_guid, entry_name) - { - if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid]) - { - return materialPreferenceValues[material_guid][entry_name]; - } - return 0; - } - - // update the display name of the material - function updateMaterialDisplayName (old_name, new_name) { - - // don't change when new name is the same - if (old_name == new_name) { - return - } - - // update the values - Cura.ContainerManager.setContainerName(base.containerId, new_name) - materialProperties.name = new_name - } - - // update the type of the material - function updateMaterialType (old_type, new_type) { - base.setMetaDataEntry("material", old_type, new_type) - materialProperties.material_type = new_type - } - - // update the supplier of the material - function updateMaterialSupplier (old_supplier, new_supplier) { - base.setMetaDataEntry("brand", old_supplier, new_supplier) - materialProperties.supplier = new_supplier - } -} diff --git a/resources/qml/Preferences/OldMaterialsPage.qml b/resources/qml/Preferences/OldMaterialsPage.qml deleted file mode 100644 index 0a24b9c663..0000000000 --- a/resources/qml/Preferences/OldMaterialsPage.qml +++ /dev/null @@ -1,412 +0,0 @@ -//Copyright (c) 2017 Ultimaker B.V. -//Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.8 -import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 - -import UM 1.2 as UM -import Cura 1.0 as Cura - - -UM.ManagementPage -{ - id: base - title: catalog.i18nc("@title:tab", "Materials") - - Component.onCompleted: - { - // Workaround to make sure all of the items are visible - objectList.positionViewAtBeginning(); - } - - model: Cura.MaterialsModel - { - filter: - { - var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() } - if(Cura.MachineManager.filterMaterialsByMachine) - { - result.definition = Cura.MachineManager.activeQualityDefinitionId; - if(Cura.MachineManager.hasVariants) - { - result.variant_name = Cura.MachineManager.activeQualityVariantName; - } - } - else - { - result.definition = "fdmprinter"; - result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway. - } - return result - } - - sectionProperty: "brand" - } - - delegate: Rectangle - { - width: objectList.width; - height: childrenRect.height; - color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase - property bool isCurrentItem: ListView.isCurrentItem - - Row - { - spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - Rectangle - { - width: Math.floor(parent.height * 0.8) - height: Math.floor(parent.height * 0.8) - color: model.metadata.color_code - border.color: isCurrentItem ? palette.highlightedText : palette.text; - anchors.verticalCenter: parent.verticalCenter - } - Label - { - width: Math.floor((parent.width * 0.3)) - text: model.metadata.material - elide: Text.ElideRight - font.italic: model.id == activeId - color: isCurrentItem ? palette.highlightedText : palette.text; - } - Label - { - text: (model.name != model.metadata.material) ? model.name : "" - elide: Text.ElideRight - font.italic: model.id == activeId - color: isCurrentItem ? palette.highlightedText : palette.text; - } - } - - MouseArea - { - anchors.fill: parent; - onClicked: - { - forceActiveFocus(); - if(!parent.ListView.isCurrentItem) - { - parent.ListView.view.currentIndex = index; - base.itemActivated(); - } - } - } - } - - activeId: Cura.MachineManager.activeMaterialId - activeIndex: getIndexById(activeId) - function getIndexById(material_id) - { - for(var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).id == material_id) { - return i; - } - } - return -1; - } - - scrollviewCaption: - { - var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; - if (Cura.MachineManager.hasVariants) - { - caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName; - } - return caption; - } - detailsVisible: true - - section.property: "section" - section.delegate: Label - { - text: section - font.bold: true - anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("default_lining").width; - } - - buttons: [ - - // Activate button - Button { - text: catalog.i18nc("@action:button", "Activate") - iconName: "list-activate"; - enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials - onClicked: { - forceActiveFocus() - Cura.MachineManager.setActiveMaterial(base.currentItem.id) - currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. - } - }, - - // Create button - Button { - text: catalog.i18nc("@action:button", "Create") - iconName: "list-add" - onClicked: { - forceActiveFocus() - Cura.ContainerManager.createMaterial() - } - }, - - // Duplicate button - Button { - text: catalog.i18nc("@action:button", "Duplicate"); - iconName: "list-add"; - enabled: base.currentItem != null - onClicked: { - forceActiveFocus() - Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id) - } - }, - - // Remove button - Button { - text: catalog.i18nc("@action:button", "Remove") - iconName: "list-remove" - enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) - onClicked: { - forceActiveFocus() - confirmDialog.open() - } - }, - - // Import button - Button { - text: catalog.i18nc("@action:button", "Import") - iconName: "document-import" - onClicked: { - forceActiveFocus() - importDialog.open() - } - visible: true - }, - - // Export button - Button { - text: catalog.i18nc("@action:button", "Export") - iconName: "document-export" - onClicked: { - forceActiveFocus() - exportDialog.open() - } - enabled: currentItem != null - } - - ] - - Item { - visible: base.currentItem != null - anchors.fill: parent - - Item // Material title Label - { - id: profileName - - width: parent.width; - height: childrenRect.height - - Label { text: materialProperties.name; font: UM.Theme.getFont("large"); } - } - - MaterialView // Material detailed information view below the title Label - { - anchors - { - left: parent.left - right: parent.right - top: profileName.bottom - topMargin: UM.Theme.getSize("default_margin").height - bottom: parent.bottom - } - - editingEnabled: base.currentItem != null && !base.currentItem.readOnly - - properties: materialProperties - containerId: base.currentItem != null ? base.currentItem.id : "" - - property alias pane: base - } - - QtObject - { - id: materialProperties - - property string guid: "00000000-0000-0000-0000-000000000000" - property string name: "Unknown"; - property string profile_type: "Unknown"; - property string supplier: "Unknown"; - property string material_type: "Unknown"; - - property string color_name: "Yellow"; - property color color_code: "yellow"; - - property real density: 0.0; - property real diameter: 0.0; - property string approximate_diameter: "0"; - - property real spool_cost: 0.0; - property real spool_weight: 0.0; - property real spool_length: 0.0; - property real cost_per_meter: 0.0; - - property string description: ""; - property string adhesion_info: ""; - } - - UM.ConfirmRemoveDialog - { - id: confirmDialog - object: base.currentItem != null ? base.currentItem.name : "" - onYes: - { - // A material container can actually be multiple items, so we need to find (and remove) all of them. - var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") - if(base_file == "") - { - base_file = base.currentItem.id - } - var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID") - // remove base container first, it otherwise triggers loading the base file while removing other containers - var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"}) - for(var i in base_containers) - { - Cura.ContainerManager.removeContainer(base_containers[i]); - } - var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"}) - for(var i in containers) - { - Cura.ContainerManager.removeContainer(containers[i]); - } - if(base.objectList.currentIndex > 0) - { - base.objectList.currentIndex--; - } - currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. - } - } - - FileDialog - { - id: importDialog; - title: catalog.i18nc("@title:window", "Import Material"); - selectExisting: true; - nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") - onAccepted: - { - var result = Cura.ContainerManager.importMaterialContainer(fileUrl) - - messageDialog.title = catalog.i18nc("@title:window", "Import Material") - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message) - if(result.status == "success") - { - messageDialog.icon = StandardIcon.Information - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl) - } - else if(result.status == "duplicate") - { - messageDialog.icon = StandardIcon.Warning - } - else - { - messageDialog.icon = StandardIcon.Critical - } - messageDialog.open() - CuraApplication.setDefaultPath("dialog_material_path", folder) - } - } - - FileDialog - { - id: exportDialog; - title: catalog.i18nc("@title:window", "Export Material"); - selectExisting: false; - nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") - onAccepted: - { - if(base.currentItem.metadata.base_file) - { - var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl) - } - else - { - var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl) - } - - messageDialog.title = catalog.i18nc("@title:window", "Export Material") - if(result.status == "error") - { - messageDialog.icon = StandardIcon.Critical - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message) - messageDialog.open() - } - else if(result.status == "success") - { - messageDialog.icon = StandardIcon.Information - messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path) - messageDialog.open() - } - CuraApplication.setDefaultPath("dialog_material_path", folder) - } - } - - MessageDialog - { - id: messageDialog - } - - UM.SettingPropertyProvider - { - id: materialDiameterProvider - - containerStackId: Cura.ExtruderManager.activeExtruderStackId - key: "material_diameter" - watchedProperties: [ "value" ] - storeIndex: 5 - } - - UM.I18nCatalog { id: catalog; name: "cura"; } - SystemPalette { id: palette } - } - - onCurrentItemChanged: - { - if(currentItem == null) - { - return - } - materialProperties.name = currentItem.name; - materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID"); - - if(currentItem.metadata != undefined && currentItem.metadata != null) - { - materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown"; - materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown"; - materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow"; - materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow"; - - materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : ""; - materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : ""; - - if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null) - { - materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0; - materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0; - materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0"; - } - else - { - materialProperties.density = 0.0; - materialProperties.diameter = 0.0; - materialProperties.approximate_diameter = "0"; - } - - } - } -} From e5cc7efdf2562e0bf9830e00d517694af237b213 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:17:10 +0100 Subject: [PATCH 048/266] WIP: Cleanup ContainerManager --- cura/Settings/ContainerManager.py | 144 ------------------------------ 1 file changed, 144 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 240b7dfa4d..0df7f4ba05 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -48,150 +48,6 @@ class ContainerManager(QObject): self._material_manager = self._application._material_manager self._container_name_filters = {} - ## Create a duplicate of the specified container - # - # This will create and add a duplicate of the container corresponding - # to the container ID. - # - # \param container_id \type{str} The ID of the container to duplicate. - # - # \return The ID of the new container, or an empty string if duplication failed. - @pyqtSlot(str, result = str) - def duplicateContainer(self, container_id): - #TODO: It should be able to duplicate a container of which only the metadata is known. - containers = self._container_registry.findContainers(id = container_id) - if not containers: - Logger.log("w", "Could duplicate container %s because it was not found.", container_id) - return "" - - container = containers[0] - new_container = self.duplicateContainerInstance(container) - return new_container.getId() - - ## Create a duplicate of the given container instance - # - # This will create and add a duplicate of the container that was passed. - # - # \param container \type{ContainerInterface} The container to duplicate. - # - # \return The duplicated container, or None if duplication failed. - def duplicateContainerInstance(self, container): - new_container = None - new_name = self._container_registry.uniqueName(container.getName()) - # Only InstanceContainer has a duplicate method at the moment. - # So fall back to serialize/deserialize when no duplicate method exists. - if hasattr(container, "duplicate"): - new_container = container.duplicate(new_name) - else: - new_container = container.__class__(new_name) - new_container.deserialize(container.serialize()) - new_container.setName(new_name) - - # TODO: we probably don't want to add it to the registry here! - if new_container: - self._container_registry.addContainer(new_container) - - return new_container - - ## Change the name of a specified container to a new name. - # - # \param container_id \type{str} The ID of the container to change the name of. - # \param new_id \type{str} The new ID of the container. - # \param new_name \type{str} The new name of the specified container. - # - # \return True if successful, False if not. - @pyqtSlot(str, str, str, result = bool) - def renameContainer(self, container_id, new_id, new_name): - containers = self._container_registry.findContainers(id = container_id) - if not containers: - Logger.log("w", "Could rename container %s because it was not found.", container_id) - return False - - container = containers[0] - # First, remove the container from the registry. This will clean up any files related to the container. - self._container_registry.removeContainer(container_id) - - # Ensure we have a unique name for the container - new_name = self._container_registry.uniqueName(new_name) - - # Then, update the name and ID of the container - container.setName(new_name) - container._id = new_id # TODO: Find a nicer way to set a new, unique ID - - # Finally, re-add the container so it will be properly serialized again. - self._container_registry.addContainer(container) - - return True - - ## Remove the specified container. - # - # \param container_id \type{str} The ID of the container to remove. - # - # \return True if the container was successfully removed, False if not. - @pyqtSlot(str, result = bool) - def removeContainer(self, container_id): - containers = self._container_registry.findContainers(id = container_id) - if not containers: - Logger.log("w", "Could not remove container %s because it was not found.", container_id) - return False - - self._container_registry.removeContainer(containers[0].getId()) - - return True - - ## Merge a container with another. - # - # This will try to merge one container into the other, by going through the container - # and setting the right properties on the other container. - # - # \param merge_into_id \type{str} The ID of the container to merge into. - # \param merge_id \type{str} The ID of the container to merge. - # - # \return True if successfully merged, False if not. - @pyqtSlot(str, result = bool) - def mergeContainers(self, merge_into_id, merge_id): - containers = self._container_registry.findContainers(id = merge_into_id) - if not containers: - Logger.log("w", "Could merge into container %s because it was not found.", merge_into_id) - return False - - merge_into = containers[0] - - containers = self._container_registry.findContainers(id = merge_id) - if not containers: - Logger.log("w", "Could not merge container %s because it was not found", merge_id) - return False - - merge = containers[0] - - if not isinstance(merge, type(merge_into)): - Logger.log("w", "Cannot merge two containers of different types") - return False - - self._performMerge(merge_into, merge) - - return True - - ## Clear the contents of a container. - # - # \param container_id \type{str} The ID of the container to clear. - # - # \return True if successful, False if not. - @pyqtSlot(str, result = bool) - def clearContainer(self, container_id): - if self._container_registry.isReadOnly(container_id): - Logger.log("w", "Cannot clear read-only container %s", container_id) - return False - - containers = self._container_registry.findContainers(id = container_id) - if not containers: - Logger.log("w", "Could clear container %s because it was not found.", container_id) - return False - - containers[0].clear() - - return True - @pyqtSlot(str, str, result=str) def getContainerMetaDataEntry(self, container_id, entry_name): metadatas = self._container_registry.findContainersMetadata(id = container_id) From f7f9c68fcc8ae8d14d4fb3e8c635bce6147eaf6b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:17:35 +0100 Subject: [PATCH 049/266] WIP: Refactor setMaterialName() --- cura/Settings/ContainerManager.py | 23 +++++++++------------- resources/qml/Preferences/MaterialView.qml | 3 +-- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 0df7f4ba05..c420f5b49e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -160,21 +160,16 @@ class ContainerManager(QObject): return container.getProperty(setting_key, property_name) - ## Set the name of the specified container. - @pyqtSlot(str, str, result = bool) - def setContainerName(self, container_id, new_name): - if self._container_registry.isReadOnly(container_id): - Logger.log("w", "Cannot set name of read-only container %s.", container_id) - return False + ## Set the name of the specified material. + @pyqtSlot("QVariant", str) + def setMaterialName(self, material_node, new_name): + root_material_id = material_node.metadata["base_file"] + if self._container_registry.isReadOnly(root_material_id): + Logger.log("w", "Cannot set name of read-only container %s.", root_material_id) + return - containers = self._container_registry.findContainers(id = container_id) #We need to get the full container, not just metadata, since we need to know whether it's read-only. - if not containers: - Logger.log("w", "Could not set name of container %s because it was not found.", container_id) - return False - - containers[0].setName(new_name) - - return True + material_group = self._material_manager.getMaterialGroup(root_material_id) + material_group.root_material_node.getContainer().setName(new_name) ## Find instance containers matching certain criteria. # diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 0c3063ff41..6e3d04fa2c 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -454,14 +454,13 @@ TabView // update the display name of the material function updateMaterialDisplayName (old_name, new_name) { - // don't change when new name is the same if (old_name == new_name) { return } // update the values - Cura.ContainerManager.setContainerName(base.containerId, new_name) + Cura.ContainerManager.setMaterialName(base.currentMaterialNode, new_name) materialProperties.name = new_name } From bed2106fc6b4d5bec2691cb8e8411b59c5a861ce Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 14:26:04 +0100 Subject: [PATCH 050/266] WIP: Backup old profile management QMLs --- resources/qml/Preferences/{ProfileTab.qml => OldProfileTab.qml} | 0 .../qml/Preferences/{ProfilesPage.qml => OldProfilesPage.qml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename resources/qml/Preferences/{ProfileTab.qml => OldProfileTab.qml} (100%) rename resources/qml/Preferences/{ProfilesPage.qml => OldProfilesPage.qml} (100%) diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/OldProfileTab.qml similarity index 100% rename from resources/qml/Preferences/ProfileTab.qml rename to resources/qml/Preferences/OldProfileTab.qml diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/OldProfilesPage.qml similarity index 100% rename from resources/qml/Preferences/ProfilesPage.qml rename to resources/qml/Preferences/OldProfilesPage.qml From 96f126436465c69368733914f58dddab5205f497 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 16:40:09 +0100 Subject: [PATCH 051/266] WIP: Rework profile management page --- cura/CuraApplication.py | 4 + cura/Machines/MaterialManager.py | 6 +- .../Machines/Models/QualityManagementModel.py | 75 +++++ cura/Machines/QualityManager.py | 34 +- cura/Settings/MachineManager.py | 82 +++-- cura/Settings/MaterialsModel.py | 2 +- cura/Settings/ProfilesModel.py | 2 + resources/qml/Preferences/ProfileTab.qml | 98 ++++++ resources/qml/Preferences/ProfilesPage.qml | 294 ++++++++++++++++++ 9 files changed, 561 insertions(+), 36 deletions(-) create mode 100644 cura/Machines/Models/QualityManagementModel.py create mode 100644 resources/qml/Preferences/ProfileTab.qml create mode 100644 resources/qml/Preferences/ProfilesPage.qml diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e9be1f96c9..3b15069598 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -61,6 +61,7 @@ from cura.Settings.UserProfilesModel import UserProfilesModel from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Machines.VariantManager import VariantManager +from cura.Machines.Models.QualityManagementModel import QualityManagementModel from . import PlatformPhysics from . import BuildVolume @@ -939,6 +940,9 @@ class CuraApplication(QtApplication): qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel") + # TODO: make this singleton? + qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") + qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 550308f1dc..84f08a3b27 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -59,7 +59,7 @@ class MaterialManager(QObject): self._update_timer = QTimer(self) self._update_timer.setInterval(300) self._update_timer.setSingleShot(True) - self._update_timer.timeout.connect(self._updateTables) + self._update_timer.timeout.connect(self._updateMaps) self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) @@ -192,7 +192,7 @@ class MaterialManager(QObject): self.materialsUpdated.emit() - def _updateTables(self): + def _updateMaps(self): self.initialize() def _onContainerMetadataChanged(self, container): @@ -203,7 +203,7 @@ class MaterialManager(QObject): if container_type != "material": return - # TODO: update the cache table + # update the maps self._update_timer.start() def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py new file mode 100644 index 0000000000..fab6a36410 --- /dev/null +++ b/cura/Machines/Models/QualityManagementModel.py @@ -0,0 +1,75 @@ + + +from PyQt5.QtCore import Qt + +from UM.Qt.ListModel import ListModel + + +class QualityManagementModel(ListModel): + NameRole = Qt.UserRole + 1 + IsReadOnlyRole = Qt.UserRole + 2 + QualityGroupRole = Qt.UserRole + 3 + QualityChangesGroupRole = Qt.UserRole + 4 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.IsReadOnlyRole, "is_read_only") + self.addRoleName(self.QualityGroupRole, "quality_group") + self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") + + from cura.CuraApplication import CuraApplication + self._container_registry = CuraApplication.getInstance().getContainerRegistry() + self._machine_manager = CuraApplication.getInstance().getMachineManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._quality_manager = CuraApplication.getInstance()._quality_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + #self._quality_manager.materialsUpdated.connect(self._update) # TODO + + self._update() + + def _update(self): + global_stack = self._machine_manager._global_container_stack + + quality_group_dict = self._quality_manager.getQualityGroups(global_stack) + quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack) + + available_quality_types = set(qt for qt, qg in quality_group_dict.items() if qg.is_available) + if not available_quality_types and not quality_changes_group_dict: + # Nothing to show + self.setItems([]) + return + + item_list = [] + # Create quality group items + for quality_group in quality_group_dict.values(): + if not quality_group.is_available: + continue + + item = {"name": quality_group.name, + "is_read_only": True, + "quality_group": quality_group, + "quality_changes_group": None} + item_list.append(item) + # Sort by quality names + item_list = sorted(item_list, key = lambda x: x["name"]) + + # Create quality_changes group items + quality_changes_item_list = [] + for quality_changes_group in quality_changes_group_dict.values(): + if quality_changes_group.quality_type not in available_quality_types: + continue + quality_group = quality_group_dict[quality_changes_group.quality_type] + item = {"name": quality_changes_group.name, + "is_read_only": False, + "quality_group": quality_group, + "quality_changes_group": quality_changes_group} + quality_changes_item_list.append(item) + + # Sort quality_changes items by names and append to the item list + quality_changes_item_list = sorted(quality_changes_item_list, key = lambda x: x["name"]) + item_list += quality_changes_item_list + + self.setItems(item_list) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index f0fd0168a6..53b85a1dca 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,10 +1,9 @@ from typing import Optional -from PyQt5.Qt import QObject +from PyQt5.QtCore import QObject, QTimer from UM.Application import Application from UM.Logger import Logger -from UM.Util import parseBool from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerNode import ContainerNode @@ -126,6 +125,15 @@ class QualityManager(QObject): self._default_machine_definition_id = "fdmprinter" + self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged) + self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) + self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged) + + self._update_timer = QTimer(self) + self._update_timer.setInterval(300) + self._update_timer.setSingleShot(True) + self._update_timer.timeout.connect(self._updateMaps) + def initialize(self): # Initialize the lookup tree for quality profiles with following structure: # -> -> @@ -186,10 +194,6 @@ class QualityManager(QObject): material_node.addQualityMetadata(quality_type, metadata) - # Initialize quality - self._initializeQualityChangesTables() - - def _initializeQualityChangesTables(self): # Initialize the lookup tree for quality_changes profiles with following structure: # -> -> quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes") @@ -206,6 +210,20 @@ class QualityManager(QObject): machine_node.addQualityChangesMetadata(quality_type, metadata) + def _updateMaps(self): + self.initialize() + + def _onContainerMetadataChanged(self, container): + self._onContainerChanged(container) + + def _onContainerChanged(self, container): + container_type = container.getMetaDataEntry("type") + if container_type not in ("quality", "quality_changes"): + return + + # update the cache table + self._update_timer.start() + # Updates the given quality groups' availabilities according to which extruders are being used/ enabled. def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list): used_extruders = set() @@ -234,8 +252,8 @@ class QualityManager(QObject): machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) if not machine_node: - Logger.log("e", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id) - return {} + Logger.log("i", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id) + return dict() # Update availability for each QualityChangesGroup: # A custom profile is always available as long as the quality_type it's based on is available diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 89106f9bda..8f66f92f1c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -12,7 +12,6 @@ from UM.Signal import Signal from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer import UM.FlameProfiler from UM.FlameProfiler import pyqtSlot -from PyQt5.QtWidgets import QMessageBox from UM import Util from UM.Application import Application @@ -1371,27 +1370,6 @@ class MachineManager(QObject): self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") return self._current_root_material_id - def _setQualityChangesGroup(self, quality_changes_group): - self._current_quality_changes_group = quality_changes_group - - # TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time. - # Can we do this better, like caching the quality group a quality_changes group depends on? - quality_manager = Application.getInstance()._quality_manager - quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack) - - quality_type = quality_changes_group.quality_type - - container = self._empty_quality_changes_container - if quality_changes_group.node_for_global is not None: - container = quality_changes_group.node_for_global.getContainer() - self._global_container_stack.qualityChanges = container - self._global_container_stack.quality = quality_group_dict[quality_type] - - for position, extruder in self._global_container_stack.extruders.items(): - container = quality_changes_group.nodes_for_extruders.get(position, - self._empty_quality_changes_container) - extruder.qualityChanges = container - def _setEmptyQuality(self): self._current_quality_group = None self._global_container_stack.quality = self._empty_quality_container @@ -1405,8 +1383,6 @@ class MachineManager(QObject): def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group - #TODO: check quality_changes - # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: @@ -1419,6 +1395,44 @@ class MachineManager(QObject): self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container self.activeQualityGroupChanged.emit() + self.activeQualityChangesGroupChanged.emit() + + def _setQualityChangesGroup(self, quality_changes_group): + # TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time. + # Can we do this better, like caching the quality group a quality_changes group depends on? + quality_type = quality_changes_group.quality_type + quality_manager = Application.getInstance()._quality_manager + quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack) + quality_group = quality_group_dict[quality_type] + + quality_changes_container = self._empty_quality_changes_container + quality_container = self._empty_quality_changes_container + if quality_changes_group.node_for_global: + quality_changes_container = quality_changes_group.node_for_global.getContainer() + if quality_group.node_for_global: + quality_container = quality_group.node_for_global.getContainer() + + self._global_container_stack.quality = quality_container + self._global_container_stack.qualityChanges = quality_changes_container + + for position, extruder in self._global_container_stack.extruders.items(): + quality_changes_node = quality_changes_group.nodes_for_extruders.get(position) + quality_node = quality_group.nodes_for_extruders.get(position) + + quality_changes_container = self._empty_quality_changes_container + quality_container = self._empty_quality_changes_container + if quality_changes_node: + quality_changes_container = quality_changes_node.getContainer() + if quality_node: + quality_container = quality_node.getContainer() + + extruder.quality = quality_container + extruder.qualityChanges = quality_changes_container + + self._current_quality_group = quality_group + self._current_quality_changes_group = quality_changes_group + self.activeQualityGroupChanged.emit() + self.activeQualityChangesGroupChanged.emit() def _setVariantGroup(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() @@ -1515,3 +1529,23 @@ class MachineManager(QObject): def activeQualityGroup(self): return self._current_quality_group + @pyqtSlot("QVariant") + def setQualityChangesGroup(self, quality_changes_group): + Logger.log("d", "---------------- qcg = [%s]", quality_changes_group.name) + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setQualityChangesGroup(quality_changes_group) + Logger.log("d", "Quality changes set!") + + @pyqtProperty("QVariant", fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) + def activeQualityChangesGroup(self): + return self._current_quality_changes_group + + @pyqtProperty(str, notify = activeQualityGroupChanged) + def activeQualityOrQualityChangesName(self): + name = "" + if self._current_quality_changes_group: + name = self._current_quality_changes_group.name + elif self._current_quality_group: + name = self._current_quality_group.name + return name diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py index 51f9e09be6..72b39a90aa 100644 --- a/cura/Settings/MaterialsModel.py +++ b/cura/Settings/MaterialsModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Any, List, Optional -from PyQt5.QtCore import Qt, QObject +from PyQt5.QtCore import Qt from UM.Logger import Logger from UM.Qt.ListModel import ListModel diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index b05bc46dd5..eaef48e168 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -27,6 +27,7 @@ class NewQualityProfilesModel(ListModel): LayerHeightRole = Qt.UserRole + 4 AvailableRole = Qt.UserRole + 5 QualityGroupRole = Qt.UserRole + 6 + QualityChangesGroupRole = Qt.UserRole + 7 def __init__(self, parent = None): super().__init__(parent) @@ -37,6 +38,7 @@ class NewQualityProfilesModel(ListModel): self.addRoleName(self.LayerHeightRole, "layer_height") self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.QualityGroupRole, "quality_group") + self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") # connect signals Application.getInstance().globalContainerStackChanged.connect(self._update) diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml new file mode 100644 index 0000000000..47446c82c2 --- /dev/null +++ b/resources/qml/Preferences/ProfileTab.qml @@ -0,0 +1,98 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.8 +import QtQuick.Controls 1.4 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Tab +{ + id: base + + property string extruderId: ""; + property string extruderDefinition: ""; + property string quality: ""; + property string material: ""; + + TableView + { + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_margin").width + + Component + { + id: itemDelegate + + UM.TooltipArea + { + property var setting: qualitySettings.getItem(styleData.row) + height: childrenRect.height + width: (parent != null) ? parent.width : 0 + text: (styleData.value.substr(0,1) == "=") ? styleData.value : "" + + Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: parent.right + text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value + font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != "" + font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "") + opacity: font.strikeout ? 0.5 : 1 + color: styleData.textColor + elide: Text.ElideRight + } + } + } + + TableViewColumn + { + role: "label" + title: catalog.i18nc("@title:column", "Setting") + width: (parent.width * 0.4) | 0 + delegate: itemDelegate + } + TableViewColumn + { + role: "profile_value" + title: catalog.i18nc("@title:column", "Profile") + width: (parent.width * 0.18) | 0 + delegate: itemDelegate + } + TableViewColumn + { + role: "user_value" + title: catalog.i18nc("@title:column", "Current"); + visible: quality == Cura.MachineManager.globalQualityId + width: (parent.width * 0.18) | 0 + delegate: itemDelegate + } + TableViewColumn + { + role: "unit" + title: catalog.i18nc("@title:column", "Unit") + width: (parent.width * 0.14) | 0 + delegate: itemDelegate + } + + section.property: "category" + section.delegate: Label + { + text: section + font.bold: true + } + + model: Cura.QualitySettingsModel + { + id: qualitySettings + extruderId: base.extruderId + extruderDefinition: base.extruderDefinition + quality: base.quality != null ? base.quality : "" + material: base.material != null ? base.material : "" + } + + SystemPalette { id: palette } + } +} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml new file mode 100644 index 0000000000..633e965bd9 --- /dev/null +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -0,0 +1,294 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Uranium is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.8 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +Item +{ + id: base + property var resetEnabled: false // Keep PreferencesDialog happy + + UM.I18nCatalog { id: catalog; name: "cura"; } + + Cura.QualityManagementModel { + id: qualitiesModel + } + + Label { + id: titleLabel + + anchors { + top: parent.top + left: parent.left + right: parent.right + margins: 5 * screenScaleFactor + } + + font.pointSize: 18 + text: catalog.i18nc("@title:tab", "Profiles") + } + + Row // Button Row + { + id: buttonRow + anchors { + left: parent.left + right: parent.right + top: titleLabel.bottom + } + height: childrenRect.height + + // Activate button + Button + { + text: catalog.i18nc("@action:button", "Activate") + iconName: "list-activate" + //enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false; + enabled: true // TODO + onClicked: { + // TODO + } + } + + // Create button + Button + { + text: catalog.i18nc("@label", "Create") + iconName: "list-add" + //enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors + enabled: true // TODO + //visible: base.canCreateProfile() + visible: true // TODO + + onClicked: { + // TODO + } + } + + // Duplicate button + Button + { + text: catalog.i18nc("@label", "Duplicate") + iconName: "list-add" + //enabled: ! base.canCreateProfile() + enabled: true // TODO + //visible: ! base.canCreateProfile() + visible: true // TODO + + onClicked: { + // TODO + } + } + + // Remove button + Button + { + text: catalog.i18nc("@action:button", "Remove") + iconName: "list-remove" + //enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false; + enabled: true // TODO + onClicked: { + // TODO + } + } + + // Rename button + Button + { + text: catalog.i18nc("@action:button", "Rename") + iconName: "edit-rename" + //enabled: base.currentItem != null ? !base.currentItem.readOnly : false; + enabled: true // TODO + onClicked: { + // TODO + } + } + + // Import button + Button + { + text: catalog.i18nc("@action:button", "Import") + iconName: "document-import" + onClicked: { + // TODO + } + } + + // Export button + Button + { + text: catalog.i18nc("@action:button", "Export") + iconName: "document-export" + //enabled: currentItem != null && !base.currentItem.readOnly + enabled: true // TODO + onClicked: { + // TODO + } + } + } + + + + Item { + id: contentsItem + + anchors { + top: titleLabel.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: 5 * screenScaleFactor + bottomMargin: 0 + } + + clip: true + } + + Item + { + anchors { + top: buttonRow.bottom + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left + right: parent.right + bottom: parent.bottom + } + + SystemPalette { id: palette } + + Label + { + id: captionLabel + anchors { + top: parent.top + left: parent.left + } + visible: text != "" + text: { + // OLD STUFF + return catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachineName); + } + width: profileScrollView.width + elide: Text.ElideRight + } + + ScrollView + { + id: profileScrollView + anchors { + top: captionLabel.visible ? captionLabel.bottom : parent.top + topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0 + bottom: parent.bottom + left: parent.left + } + + Rectangle { + parent: viewport + anchors.fill: parent + color: palette.light + } + + width: true ? (parent.width * 0.4) | 0 : parent.width + + ListView + { + id: qualityListView + + model: qualitiesModel + + section.property: "is_read_only" + section.delegate: Rectangle + { + height: childrenRect.height + + Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_lining").width + text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles") + font.bold: true + } + } + + delegate: Rectangle + { + width: profileScrollView.width + height: childrenRect.height + color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase + + Row + { + spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.right: parent.right + Label + { + width: Math.floor((parent.width * 0.3)) + text: model.name + elide: Text.ElideRight + font.italic: { // TODO: make it easier + return model.name == Cura.MachineManager.activeQualityOrQualityChangesName; + } + color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; + } + } + + MouseArea + { + anchors.fill: parent + onClicked: { + parent.ListView.view.currentIndex = model.index; + } + } + } + + onCurrentIndexChanged: + { + var model = qualitiesModel.getItem(currentIndex); + // TODO + } + } + } + + + Item + { + id: detailsPanel + + anchors { + left: profileScrollView.right + leftMargin: UM.Theme.getSize("default_margin").width + top: parent.top + bottom: parent.bottom + right: parent.right + } + + Item + { + anchors.fill: parent + + Item // Profile title Label + { + id: profileName + + width: parent.width + height: childrenRect.height + + Label { + text: "TODO" // TODO + font: UM.Theme.getFont("large") + } + } + + } + } + } +} From 720dd70935e7c1079566d3a386f04501e551d95a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 17:01:57 +0100 Subject: [PATCH 052/266] WIP: Cleanup MachineManager --- cura/Settings/MachineManager.py | 112 +------------------------------- 1 file changed, 3 insertions(+), 109 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 8f66f92f1c..d3480b503b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -333,16 +333,6 @@ class MachineManager(QObject): Logger.log("d", "Checking %s stacks for errors took %.2f s" % (count, time.time() - time_start)) return False - ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings) - @pyqtSlot() - def clearUserSettings(self) -> None: - if not self._active_container_stack: - return - - self.blurSettings.emit() - user_settings = self._active_container_stack.getTop() - user_settings.clear() - ## Check if the global_container has instances in the user container @pyqtProperty(bool, notify = activeStackValueChanged) def hasUserSettings(self) -> bool: @@ -484,21 +474,6 @@ class MachineManager(QObject): return "" - @pyqtProperty("QVariantMap", notify = activeVariantChanged) - def allActiveVariantIds(self) -> Dict[str, str]: - result = {} - - active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - if active_stacks is not None: #If we have a global stack. - for stack in active_stacks: - variant_container = stack.variant - if not variant_container: - continue - - result[stack.getId()] = variant_container.getId() - - return result - ## Gets a dict with the active materials ids set in all extruder stacks and the global stack # (when there is one extruder, the material is set in the global stack) # @@ -622,21 +597,6 @@ class MachineManager(QObject): return False return True - ## Get the Quality ID associated with the currently active extruder - # Note that this only returns the "quality", not the "quality_changes" - # \returns QualityID (string) if found, empty string otherwise - # \sa activeQualityId() - # \todo Ideally, this method would be named activeQualityId(), and the other one - # would be named something like activeQualityOrQualityChanges() for consistency - @pyqtProperty(str, notify = activeQualityChanged) - def activeQualityContainerId(self) -> str: - # We're using the active stack instead of the global stack in case the list of qualities differs per extruder - if self._global_container_stack: - quality = self._active_container_stack.quality - if quality: - return quality.getId() - return "" - @pyqtProperty(str, notify = activeQualityChanged) def activeQualityChangesId(self) -> str: if self._active_container_stack: @@ -748,6 +708,7 @@ class MachineManager(QObject): self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes) + # TODO: refactor this @pyqtSlot(str) def setActiveVariantBuildplate(self, variant_buildplate_id: str): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): @@ -843,7 +804,6 @@ class MachineManager(QObject): # before the user decided to keep or discard any of their changes using the dialog. # The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method. def _executeDelayedActiveContainerStackChanges(self): - Logger.log("d", "Applying configuration changes...") if self._new_variant_container is not None: @@ -1032,15 +992,6 @@ class MachineManager(QObject): return "" - @pyqtProperty(str, notify = activeVariantChanged) - def activeVariantName(self) -> str: - if self._active_container_stack: - variant = self._active_container_stack.variant - if variant: - return variant.getName() - - return "" - @pyqtProperty(str, notify = activeVariantChanged) def activeVariantBuildplateName(self) -> str: if self._global_container_stack: @@ -1080,25 +1031,6 @@ class MachineManager(QObject): def getQualityDefinitionId(self, definition: "DefinitionContainer") -> str: return QualityManager.getInstance().getParentMachineDefinition(definition).getId() - ## Get the Variant ID to use to select quality profiles for the currently active variant - # \returns VariantID (string) if found, empty string otherwise - # \sa getQualityVariantId - @pyqtProperty(str, notify = activeVariantChanged) - def activeQualityVariantId(self) -> str: - if self._active_container_stack: - variant = self._active_container_stack.variant - if variant: - return self.getQualityVariantId(self._global_container_stack.definition, variant) - return "" - - @pyqtProperty(str, notify = activeVariantChanged) - def activeQualityVariantName(self) -> str: - if self._active_container_stack: - variant = self._active_container_stack.variant - if variant.getId() != "empty_variant": - return variant.getName() - return "" - ## Get the Variant ID to use to select quality profiles for variants of the specified definitions # This is normally the id of the variant itself, but machines can specify a different definition # to inherit qualities from, which has consequences for the variant to use as well @@ -1307,44 +1239,6 @@ class MachineManager(QObject): return self._global_container_stack.extruders.get(str(position)) return None - @deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7") - def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None) -> InstanceContainer: - if not definition.getMetaDataEntry("has_materials"): - return self._empty_material_container - - approximate_material_diameter = str(round(stack.getProperty("material_diameter", "value"))) - search_criteria = { "type": "material", "approximate_diameter": approximate_material_diameter } - - if definition.getMetaDataEntry("has_machine_materials"): - search_criteria["definition"] = self.getQualityDefinitionId(definition) - - if definition.getMetaDataEntry("has_variants") and variant_container: - search_criteria["variant"] = self.getQualityVariantId(definition, variant_container) - else: - search_criteria["definition"] = "fdmprinter" - - if preferred_material_name: - search_criteria["name"] = preferred_material_name - else: - preferred_material = definition.getMetaDataEntry("preferred_material") - if preferred_material: - search_criteria["id"] = preferred_material - - containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) - if containers: - return containers[0] - - if "variant" in search_criteria or "id" in search_criteria: - # If a material by this name can not be found, try a wider set of search criteria - search_criteria.pop("variant", None) - search_criteria.pop("id", None) - - containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) - if containers: - return containers[0] - Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.") - return self._empty_material_container - def _onMachineNameChanged(self): self.globalContainerChanged.emit() @@ -1434,7 +1328,7 @@ class MachineManager(QObject): self.activeQualityGroupChanged.emit() self.activeQualityChangesGroupChanged.emit() - def _setVariantGroup(self, position, container_node): + def _setVariantNode(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() def _setMaterial(self, position, container_node = None): @@ -1511,7 +1405,7 @@ class MachineManager(QObject): position = str(position) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self._setVariantGroup(position, container_node) + self._setVariantNode(position, container_node) current_variant_name = container_node.metadata["name"] current_material_base_name = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") self._updateMaterialWithVariant(position, current_material_base_name, current_variant_name) From e0f82fb5c6ecea6f71cd2fad885292077d661fe5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 16 Feb 2018 17:02:24 +0100 Subject: [PATCH 053/266] WIP: Fix MaterialsManager getAvailableMaterials() --- cura/Machines/MaterialManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 84f08a3b27..b52bd7dca2 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -245,7 +245,7 @@ class MaterialManager(QObject): material_id_metadata_dict = dict() for node in nodes_to_check: if node is not None: - material_id_metadata_dict = {mid: node for mid, node in variant_node.material_map.items()} + material_id_metadata_dict = {mid: node for mid, node in node.material_map.items()} break return material_id_metadata_dict From 1a19175b35a59fbe86c9238bc06409700ebdd97d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 13:36:25 +0100 Subject: [PATCH 054/266] WIP: Fix quality sliderbar --- cura/Settings/ProfilesModel.py | 7 ++++--- resources/qml/Menus/ProfileMenu.qml | 2 +- resources/qml/SidebarSimple.qml | 24 ++++++++++++++---------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index eaef48e168..719eaf0869 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -67,6 +67,7 @@ class NewQualityProfilesModel(ListModel): item = {"id": "TODO", # TODO: probably will be removed "name": quality_group.name, + "quality_type": quality_group.quality_type, "layer_height": layer_height + self._layer_height_unit, "layer_height_without_unit": layer_height, "available": quality_group.is_available, @@ -74,6 +75,9 @@ class NewQualityProfilesModel(ListModel): item_list.append(item) + # Sort items based on layer_height + item_list = sorted(item_list, key = lambda x: float(x["layer_height_without_unit"])) + self.setItems(item_list) def _fetchLayerHeight(self, quality_group: "QualityGroup"): @@ -84,9 +88,6 @@ class NewQualityProfilesModel(ListModel): unit = "" self._layer_height_unit = unit - if not quality_group.is_available: - return "" - # Get layer_height from the quality profile for the GlobalStack container = quality_group.node_for_global.getContainer() diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 6005ce9805..713b4b856e 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -34,7 +34,7 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.UserProfilesModel.rowCount > 0 + visible: Cura.NewCustomQualityProfilesModel.rowCount > 0 } Instantiator diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index ae9fe57b64..33aa98ba9f 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -57,7 +57,10 @@ Item interval: 50 running: false repeat: false - onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualitySlider.value).id) + onTriggered: { + var item = Cura.NewQualityProfilesModel.getItem(qualitySlider.value); + Cura.MachineManager.activeQualityGroup = item.quality_group; + } } Component.onCompleted: qualityModel.update() @@ -102,14 +105,14 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.ProfilesModel.rowCount(); i++) { - var qualityItem = Cura.ProfilesModel.getItem(i) + for (var i = 0; i < Cura.NewQualityProfilesModel.rowCount(); i++) { + var qualityItem = Cura.NewQualityProfilesModel.getItem(i) // Add each quality item to the UI quality model qualityModel.append(qualityItem) // Set selected value - if (Cura.MachineManager.activeQualityType == qualityItem.metadata.quality_type) { + if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) { // set to -1 when switching to user created profile so all ticks are clickable if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { @@ -165,7 +168,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.ProfilesModel.rowCount() - 1) + qualityModel.totalTicks = Math.max(0, Cura.NewQualityProfilesModel.rowCount() - 1) } } @@ -191,13 +194,13 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) - color: (Cura.MachineManager.activeMachine != null && Cura.ProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: (Cura.MachineManager.activeMachine != null && Cura.NewQualityProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { var result = "" if(Cura.MachineManager.activeMachine != null) { - result = Cura.ProfilesModel.getItem(index).layer_height_without_unit + result = Cura.NewQualityProfilesModel.getItem(index).layer_height_without_unit if(result == undefined) { @@ -262,7 +265,7 @@ Item Rectangle { anchors.verticalCenter: parent.verticalCenter - color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: Cura.NewQualityProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 * screenScaleFactor height: 6 * screenScaleFactor y: 0 @@ -408,9 +411,10 @@ Item // if the current profile is user-created, switch to a built-in quality if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { - if (Cura.ProfilesModel.rowCount() > 0) + if (Cura.NewQualityProfilesModel.rowCount() > 0) { - Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(0).id) + var item = Cura.NewQualityProfilesModel.getItem(0); + Cura.MachineManager.activeQualityGroup = item.quality_group; } } if (Cura.SimpleModeSettingsManager.isProfileCustomized) From 2cfdbc1b164eafc410f260ca39b945dfe587c8a8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 14:10:01 +0100 Subject: [PATCH 055/266] WIP: Remove old quality models --- cura/CuraApplication.py | 7 +- cura/Settings/MachineManager.py | 12 -- cura/Settings/ProfilesModel.py | 204 ------------------- cura/Settings/QualityAndUserProfilesModel.py | 54 ----- cura/Settings/UserProfilesModel.py | 85 -------- 5 files changed, 1 insertion(+), 361 deletions(-) delete mode 100644 cura/Settings/QualityAndUserProfilesModel.py delete mode 100644 cura/Settings/UserProfilesModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3b15069598..ee94050515 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -53,11 +53,9 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Machines.Models.NozzleModel import NozzleModel -from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel +from cura.Settings.ProfilesModel import NewQualityProfilesModel, NewCustomQualityProfilesModel from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel -from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager -from cura.Settings.UserProfilesModel import UserProfilesModel from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Machines.VariantManager import VariantManager @@ -934,7 +932,6 @@ class CuraApplication(QtApplication): qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") - qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel) qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") @@ -948,8 +945,6 @@ class CuraApplication(QtApplication): qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") - qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") - qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel") qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index d3480b503b..e53145ee87 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -18,10 +18,8 @@ from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger from UM.Message import Message -from UM.Decorators import deprecated from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.ContainerStack import ContainerStack from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique @@ -36,8 +34,6 @@ from .CuraStackBuilder import CuraStackBuilder from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") -from cura.Settings.ProfilesModel import ProfilesModel - if TYPE_CHECKING: from UM.Settings.DefinitionContainer import DefinitionContainer from cura.Settings.CuraContainerStack import CuraContainerStack @@ -72,7 +68,6 @@ class MachineManager(QObject): Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) Application.getInstance().getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged) - self._connected_to_profiles_model = False ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) @@ -269,13 +264,6 @@ class MachineManager(QObject): self.__emitChangedSignals() def _onInstanceContainersChanged(self, container) -> None: - # This should not trigger the ProfilesModel to be created, or there will be an infinite recursion - if not self._connected_to_profiles_model and ProfilesModel.hasInstance(): - # This triggers updating the qualityModel in SidebarSimple whenever ProfilesModel is updated - Logger.log("d", "Connecting profiles model...") - ProfilesModel.getInstance().itemsChanged.connect(self._onProfilesModelChanged) - self._connected_to_profiles_model = True - self._instance_container_timer.start() def _onPropertyChanged(self, key: str, property_name: str) -> None: diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 719eaf0869..a6276cdbed 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -131,207 +131,3 @@ class NewCustomQualityProfilesModel(NewQualityProfilesModel): item_list.append(item) self.setItems(item_list) - - -## QML Model for listing the current list of valid quality profiles. -# -class ProfilesModel(InstanceContainersModel): - LayerHeightRole = Qt.UserRole + 1001 - LayerHeightWithoutUnitRole = Qt.UserRole + 1002 - AvailableRole = Qt.UserRole + 1003 - - def __init__(self, parent = None): - super().__init__(parent) - self.addRoleName(self.LayerHeightRole, "layer_height") - self.addRoleName(self.LayerHeightWithoutUnitRole, "layer_height_without_unit") - self.addRoleName(self.AvailableRole, "available") - - Application.getInstance().globalContainerStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update) - Application.getInstance().getMachineManager().activeStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update) - - self._empty_quality = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0] - - # Factory function, used by QML - @staticmethod - def createProfilesModel(engine, js_engine): - return ProfilesModel.getInstance() - - ## Get the singleton instance for this class. - @classmethod - def getInstance(cls) -> "ProfilesModel": - # Note: Explicit use of class name to prevent issues with inheritance. - if not ProfilesModel.__instance: - ProfilesModel.__instance = cls() - return ProfilesModel.__instance - - @classmethod - def hasInstance(cls) -> bool: - return ProfilesModel.__instance is not None - - __instance = None # type: "ProfilesModel" - - ## Fetch the list of containers to display. - # - # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers(). - def _fetchInstanceContainers(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack is None: - return {}, {} - global_stack_definition = global_container_stack.definition - - # Get the list of extruders and place the selected extruder at the front of the list. - extruder_stacks = self._getOrderedExtruderStacksList() - materials = [extruder.material for extruder in extruder_stacks] - - # Fetch the list of usable qualities across all extruders. - # The actual list of quality profiles come from the first extruder in the extruder list. - result = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks) - - # The usable quality types are set - quality_type_set = set([x.getMetaDataEntry("quality_type") for x in result]) - - # Fetch all qualities available for this machine and the materials selected in extruders - all_qualities = QualityManager.getInstance().findAllQualitiesForMachineAndMaterials(global_stack_definition, materials) - - # If in the all qualities there is some of them that are not available due to incompatibility with materials - # we also add it so that they will appear in the slide quality bar. However in recomputeItems will be marked as - # not available so they will be shown in gray - for quality in all_qualities: - if quality.getMetaDataEntry("quality_type") not in quality_type_set: - result.append(quality) - - if len(result) > 1 and self._empty_quality in result: - result.remove(self._empty_quality) - - return {item.getId(): item for item in result}, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet. - - ## Re-computes the items in this model, and adds the layer height role. - def _recomputeItems(self): - # Some globals that we can re-use. - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack is None: - return - - extruder_stacks = self._getOrderedExtruderStacksList() - container_registry = ContainerRegistry.getInstance() - - # Get a list of usable/available qualities for this machine and material - qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks) - - unit = global_container_stack.getBottom().getProperty("layer_height", "unit") - if not unit: - unit = "" - - # group all quality items according to quality_types, so we know which profile suits the currently - # active machine and material, and later yield the right ones. - tmp_all_quality_items = OrderedDict() - for item in super()._recomputeItems(): - profiles = container_registry.findContainersMetadata(id = item["id"]) - if not profiles or "quality_type" not in profiles[0]: - quality_type = "" - else: - quality_type = profiles[0]["quality_type"] - - if quality_type not in tmp_all_quality_items: - tmp_all_quality_items[quality_type] = {"suitable_container": None, "all_containers": []} - - tmp_all_quality_items[quality_type]["all_containers"].append(item) - if tmp_all_quality_items[quality_type]["suitable_container"] is None: - tmp_all_quality_items[quality_type]["suitable_container"] = item - - # reverse the ordering (finest first, coarsest last) - all_quality_items = OrderedDict() - for key in reversed(tmp_all_quality_items.keys()): - all_quality_items[key] = tmp_all_quality_items[key] - - # First the suitable containers are set in the model - containers = [] - for data_item in all_quality_items.values(): - suitable_item = data_item["suitable_container"] - if suitable_item is not None: - containers.append(suitable_item) - - # Once the suitable containers are collected, the rest of the containers are appended - for data_item in all_quality_items.values(): - for item in data_item["all_containers"]: - if item not in containers: - containers.append(item) - - # Now all the containers are set - for item in containers: - profile = container_registry.findContainers(id = item["id"]) - - # When for some reason there is no profile container in the registry - if not profile: - self._setItemLayerHeight(item, "", "") - item["available"] = False - yield item - continue - - profile = profile[0] - - # When there is a profile but it's an empty quality should. It's shown in the list (they are "Not Supported" profiles) - if profile.getId() == "empty_quality": - self._setItemLayerHeight(item, "", "") - item["available"] = True - yield item - continue - - item["available"] = profile in qualities - - # Easy case: This profile defines its own layer height. - if profile.hasProperty("layer_height", "value"): - self._setItemLayerHeight(item, profile.getProperty("layer_height", "value"), unit) - yield item - continue - - machine_manager = Application.getInstance().getMachineManager() - - # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile. - quality_type = profile.getMetaDataEntry("quality_type", None) - if quality_type: - quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(quality_type) - for quality_result in quality_results: - if quality_result["stack"] is global_container_stack: - quality = quality_result["quality"] - break - else: - # No global container stack in the results: - if quality_results: - # Take any of the extruders. - quality = quality_results[0]["quality"] - else: - quality = None - if quality and quality.hasProperty("layer_height", "value"): - self._setItemLayerHeight(item, quality.getProperty("layer_height", "value"), unit) - yield item - continue - - # Quality has no value for layer height either. Get the layer height from somewhere lower in the stack. - skip_until_container = global_container_stack.material - if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No material in stack. - skip_until_container = global_container_stack.variant - if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No variant in stack. - skip_until_container = global_container_stack.getBottom() - self._setItemLayerHeight(item, global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId()), unit) # Fall through to the currently loaded material. - yield item - - ## Get a list of extruder stacks with the active extruder at the front of the list. - @staticmethod - def _getOrderedExtruderStacksList() -> List["ExtruderStack"]: - extruder_manager = ExtruderManager.getInstance() - extruder_stacks = extruder_manager.getActiveExtruderStacks() - active_extruder = extruder_manager.getActiveExtruderStack() - - if active_extruder in extruder_stacks: - extruder_stacks.remove(active_extruder) - extruder_stacks = [active_extruder] + extruder_stacks - - return extruder_stacks - - @staticmethod - def _setItemLayerHeight(item, value, unit): - item["layer_height"] = str(value) + unit - item["layer_height_without_unit"] = str(value) diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py deleted file mode 100644 index 645e63acdb..0000000000 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. -from UM.Application import Application -from UM.Settings.ContainerRegistry import ContainerRegistry - -from cura.QualityManager import QualityManager -from cura.Settings.ProfilesModel import ProfilesModel -from cura.Settings.ExtruderManager import ExtruderManager - - -## QML Model for listing the current list of valid quality and quality changes profiles. -# -class QualityAndUserProfilesModel(ProfilesModel): - def __init__(self, parent = None): - super().__init__(parent) - - self._empty_quality = ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] - - ## Fetch the list of containers to display. - # - # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers(). - def _fetchInstanceContainers(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if not global_container_stack: - return {}, {} - - # Fetch the list of quality changes. - quality_manager = QualityManager.getInstance() - machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition) - quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) - - extruder_manager = ExtruderManager.getInstance() - active_extruder = extruder_manager.getActiveExtruderStack() - extruder_stacks = self._getOrderedExtruderStacksList() - - # Fetch the list of usable qualities across all extruders. - # The actual list of quality profiles come from the first extruder in the extruder list. - quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks) - - # Filter the quality_change by the list of available quality_types - quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list]) - # Also show custom profiles based on "Not Supported" quality profile - quality_type_set.add(self._empty_quality.getMetaDataEntry("quality_type")) - filtered_quality_changes = {qc.getId(): qc for qc in quality_changes_list if - qc.getMetaDataEntry("quality_type") in quality_type_set and - qc.getMetaDataEntry("extruder") is not None and - (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or - qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())} - - result = filtered_quality_changes - for q in quality_list: - if q.getId() != "empty_quality": - result[q.getId()] = q - return result, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet. diff --git a/cura/Settings/UserProfilesModel.py b/cura/Settings/UserProfilesModel.py deleted file mode 100644 index 6605f52f8a..0000000000 --- a/cura/Settings/UserProfilesModel.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from UM.Application import Application -from UM.Settings.ContainerRegistry import ContainerRegistry - -from cura.QualityManager import QualityManager -from cura.Settings.ProfilesModel import ProfilesModel -from cura.Settings.ExtruderManager import ExtruderManager - -## QML Model for listing the current list of valid quality changes profiles. -# -class UserProfilesModel(ProfilesModel): - def __init__(self, parent = None): - super().__init__(parent) - - #Need to connect to the metaDataChanged signal of the active materials. - self.__current_extruders = [] - self.__current_materials = [] - - Application.getInstance().getExtruderManager().extrudersChanged.connect(self.__onExtrudersChanged) - self.__onExtrudersChanged() - self.__current_materials = [extruder.material for extruder in self.__current_extruders] - for material in self.__current_materials: - material.metaDataChanged.connect(self._onContainerChanged) - - self._empty_quality = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0] - - ## Fetch the list of containers to display. - # - # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers(). - def _fetchInstanceContainers(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if not global_container_stack: - return {}, {} - - # Fetch the list of quality changes. - quality_manager = QualityManager.getInstance() - machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition) - quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) - - extruder_manager = ExtruderManager.getInstance() - active_extruder = extruder_manager.getActiveExtruderStack() - extruder_stacks = self._getOrderedExtruderStacksList() - - # Fetch the list of usable qualities across all extruders. - # The actual list of quality profiles come from the first extruder in the extruder list. - quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks) - - # Filter the quality_change by the list of available quality_types - quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list]) - quality_type_set.add(self._empty_quality.getMetaDataEntry("quality_type")) - - filtered_quality_changes = {qc.getId():qc for qc in quality_changes_list if - qc.getMetaDataEntry("quality_type") in quality_type_set and - qc.getMetaDataEntry("extruder") is not None and - (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or - qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())} - - return filtered_quality_changes, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet. - - ## Called when a container changed on an extruder stack. - # - # If it's the material we need to connect to the metaDataChanged signal of - # that. - def __onContainerChanged(self, new_container): - #Careful not to update when a quality or quality changes profile changed! - #If you then update you're going to have an infinite recursion because the update may change the container. - if new_container.getMetaDataEntry("type") == "material": - for material in self.__current_materials: - material.metaDataChanged.disconnect(self._onContainerChanged) - self.__current_materials = [extruder.material for extruder in self.__current_extruders] - for material in self.__current_materials: - material.metaDataChanged.connect(self._onContainerChanged) - - ## Called when the current set of extruders change. - # - # This makes sure that we are listening to the signal for when the - # materials change. - def __onExtrudersChanged(self): - for extruder in self.__current_extruders: - extruder.containersChanged.disconnect(self.__onContainerChanged) - self.__current_extruders = Application.getInstance().getExtruderManager().getExtruderStacks() - for extruder in self.__current_extruders: - extruder.containersChanged.connect(self.__onContainerChanged) \ No newline at end of file From b449f39cc74e722e1d6db17ebf3721cd8ce49c5a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 14:39:47 +0100 Subject: [PATCH 056/266] WIP: Do not profiles submenu for each Extruder You cannot change quality for an individual Extruder, so it doesn't make sense to show that for each Extruder. --- resources/qml/Cura.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index f474d93900..4a75f76e8b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -194,7 +194,6 @@ UM.MainWindow NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } - ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); } MenuSeparator { } @@ -207,7 +206,7 @@ UM.MainWindow BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: Cura.MachineManager.hasVariantBuildplates } NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants } MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials } - ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); visible: machineExtruderCount.properties.value <= 1 } + ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); } MenuSeparator { } From 9dce0afaea3b4a8b53b7657b3578890af2c604d4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 14:44:39 +0100 Subject: [PATCH 057/266] WIP: Fix extruder submenu --- resources/qml/Cura.qml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 4a75f76e8b..9dbbb80904 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -190,22 +190,24 @@ UM.MainWindow model: Cura.ExtrudersModel { simpleNames: true } Menu { title: model.name - visible: machineExtruderCount.properties.value > 1 NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } - MenuSeparator { } + MenuSeparator { + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials + } - MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) } + MenuItem { + text: catalog.i18nc("@action:inmenu", "Set as Active Extruder") + onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) + } } onObjectAdded: settingsMenu.insertItem(index, object) onObjectRemoved: settingsMenu.removeItem(object) } BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: Cura.MachineManager.hasVariantBuildplates } - NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants } - MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials } ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); } MenuSeparator { } From 171a05ae6add981719911f86b789e335c256f91b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 14:48:09 +0100 Subject: [PATCH 058/266] WIP: Fix layer_height fetching that inherits the default Fix layer height fetching for those quality profiles that inherits the layer height from the definition. --- cura/Settings/ProfilesModel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index a6276cdbed..06b5679d9e 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -88,10 +88,12 @@ class NewQualityProfilesModel(ListModel): unit = "" self._layer_height_unit = unit + default_layer_height = active_global_stack.definition.getProperty("layer_height", "value") + # Get layer_height from the quality profile for the GlobalStack container = quality_group.node_for_global.getContainer() - layer_height = "" + layer_height = default_layer_height if container.hasProperty("layer_height", "value"): layer_height = str(container.getProperty("layer_height", "value")) else: From 236bd09d083c7b0fa4400fb26905c9c802913cff Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 14:58:56 +0100 Subject: [PATCH 059/266] WIP: Refactor quality model files --- cura/CuraApplication.py | 29 ++- .../Models/CustomQualityProfilesModel.py | 36 +++ cura/Machines/Models/NozzleModel.py | 3 + .../Machines/Models/QualityManagementModel.py | 3 +- .../Models/QualityProfilesModel.py} | 233 ++++++++---------- resources/qml/Menus/ProfileMenu.qml | 12 +- resources/qml/SidebarSimple.qml | 22 +- 7 files changed, 172 insertions(+), 166 deletions(-) create mode 100644 cura/Machines/Models/CustomQualityProfilesModel.py rename cura/{Settings/ProfilesModel.py => Machines/Models/QualityProfilesModel.py} (68%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index ee94050515..395d6655cb 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -52,8 +52,11 @@ from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyT from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator + from cura.Machines.Models.NozzleModel import NozzleModel -from cura.Settings.ProfilesModel import NewQualityProfilesModel, NewCustomQualityProfilesModel +from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel +from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfilesModel + from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager @@ -390,8 +393,8 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize - self._new_quality_profile_model = None - self._new_custom_quality_profile_model = None + self._quality_profile_model = None + self._custom_quality_profile_model = None CuraApplication.Created = True @@ -896,15 +899,15 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information - def getNewQualityProfileModel(self, *args, **kwargs): - if self._new_quality_profile_model is None: - self._new_quality_profile_model = NewQualityProfilesModel(self) - return self._new_quality_profile_model + def getQualityProfileModel(self, *args, **kwargs): + if self._quality_profile_model is None: + self._quality_profile_model = QualityProfilesModel(self) + return self._quality_profile_model - def getNewCustomQualityProfilesModel(self, *args, **kwargs): - if self._new_custom_quality_profile_model is None: - self._new_custom_quality_profile_model = NewCustomQualityProfilesModel(self) - return self._new_custom_quality_profile_model + def getCustomQualityProfilesModel(self, *args, **kwargs): + if self._custom_quality_profile_model is None: + self._custom_quality_profile_model = CustomQualityProfilesModel(self) + return self._custom_quality_profile_model ## Registers objects for the QML engine to use. # @@ -940,8 +943,8 @@ class CuraApplication(QtApplication): # TODO: make this singleton? qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") - qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel) - qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel) + qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel) + qmlRegisterSingletonType(CustomQualityProfilesModel, "Cura", 1, 0, "CustomQualityProfilesModel", self.getCustomQualityProfilesModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") diff --git a/cura/Machines/Models/CustomQualityProfilesModel.py b/cura/Machines/Models/CustomQualityProfilesModel.py new file mode 100644 index 0000000000..8b6fc2deb6 --- /dev/null +++ b/cura/Machines/Models/CustomQualityProfilesModel.py @@ -0,0 +1,36 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Application import Application +from UM.Logger import Logger + +from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel + + +class CustomQualityProfilesModel(QualityProfilesModel): + + def _update(self): + Logger.log("d", "Updating %s ...", self.__class__.__name__) + + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) + return + + quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack) + + item_list = [] + for key in sorted(quality_changes_group_dict): + quality_changes_group = quality_changes_group_dict[key] + + item = {"id": "TODO", # TODO: probably will be removed + "name": quality_changes_group.name, + "layer_height": "", + "layer_height_without_unit": "", + "available": quality_changes_group.is_available, + "quality_changes_group": quality_changes_group} + + item_list.append(item) + + self.setItems(item_list) diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 3ad28f3287..271580962a 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from PyQt5.QtCore import Qt from UM.Application import Application diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index fab6a36410..589fec3440 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -1,4 +1,5 @@ - +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import Qt diff --git a/cura/Settings/ProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py similarity index 68% rename from cura/Settings/ProfilesModel.py rename to cura/Machines/Models/QualityProfilesModel.py index 06b5679d9e..19262bf75a 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -1,135 +1,98 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from collections import OrderedDict -from typing import List, TYPE_CHECKING - -from PyQt5.QtCore import Qt - -from UM.Application import Application -from UM.Logger import Logger -from UM.Qt.ListModel import ListModel -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel - -from cura.QualityManager import QualityManager -from cura.Settings.ExtruderManager import ExtruderManager -from cura.Machines.QualityManager import QualityGroup - -if TYPE_CHECKING: - from cura.Settings.ExtruderStack import ExtruderStack - - -class NewQualityProfilesModel(ListModel): - IdRole = Qt.UserRole + 1 - NameRole = Qt.UserRole + 2 - QualityTypeRole = Qt.UserRole + 3 - LayerHeightRole = Qt.UserRole + 4 - AvailableRole = Qt.UserRole + 5 - QualityGroupRole = Qt.UserRole + 6 - QualityChangesGroupRole = Qt.UserRole + 7 - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.IdRole, "id") - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.QualityTypeRole, "quality_type") - self.addRoleName(self.LayerHeightRole, "layer_height") - self.addRoleName(self.AvailableRole, "available") - self.addRoleName(self.QualityGroupRole, "quality_group") - self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") - - # connect signals - Application.getInstance().globalContainerStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) - - self._quality_manager = Application.getInstance()._quality_manager - - self._layer_height_unit = "" # This is cached - - def _update(self): - Logger.log("d", "Updating quality profile model ...") - - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack - if active_global_stack is None: - self.setItems([]) - Logger.log("d", "No active GlobalStack, set quality profile model as empty.") - return - - quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) - - item_list = [] - for key in sorted(quality_group_dict): - quality_group = quality_group_dict[key] - - layer_height = self._fetchLayerHeight(quality_group) - - item = {"id": "TODO", # TODO: probably will be removed - "name": quality_group.name, - "quality_type": quality_group.quality_type, - "layer_height": layer_height + self._layer_height_unit, - "layer_height_without_unit": layer_height, - "available": quality_group.is_available, - "quality_group": quality_group} - - item_list.append(item) - - # Sort items based on layer_height - item_list = sorted(item_list, key = lambda x: float(x["layer_height_without_unit"])) - - self.setItems(item_list) - - def _fetchLayerHeight(self, quality_group: "QualityGroup"): - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack - if not self._layer_height_unit: - unit = active_global_stack.definition.getProperty("layer_height", "unit") - if not unit: - unit = "" - self._layer_height_unit = unit - - default_layer_height = active_global_stack.definition.getProperty("layer_height", "value") - - # Get layer_height from the quality profile for the GlobalStack - container = quality_group.node_for_global.getContainer() - - layer_height = default_layer_height - if container.hasProperty("layer_height", "value"): - layer_height = str(container.getProperty("layer_height", "value")) - else: - # Look for layer_height in the GlobalStack from material -> definition - for idx in range(4): - container = active_global_stack.getContainer(idx) - if container.hasProperty("layer_height", "value"): - layer_height = container.getProperty("layer_height", "value") - break - return str(layer_height) - - -class NewCustomQualityProfilesModel(NewQualityProfilesModel): - - def _update(self): - Logger.log("d", "Updating %s ...", self.__class__.__name__) - - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack - if active_global_stack is None: - self.setItems([]) - Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) - return - - quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack) - - item_list = [] - for key in sorted(quality_changes_group_dict): - quality_changes_group = quality_changes_group_dict[key] - - item = {"id": "TODO", # TODO: probably will be removed - "name": quality_changes_group.name, - "layer_height": "", - "layer_height_without_unit": "", - "available": quality_changes_group.is_available, - "quality_changes_group": quality_changes_group} - - item_list.append(item) - - self.setItems(item_list) +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import Qt + +from UM.Application import Application +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel +from cura.Machines.QualityManager import QualityGroup + + +# +# QML Model for all built-in quality profiles. +# +class QualityProfilesModel(ListModel): + IdRole = Qt.UserRole + 1 + NameRole = Qt.UserRole + 2 + QualityTypeRole = Qt.UserRole + 3 + LayerHeightRole = Qt.UserRole + 4 + AvailableRole = Qt.UserRole + 5 + QualityGroupRole = Qt.UserRole + 6 + QualityChangesGroupRole = Qt.UserRole + 7 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.QualityTypeRole, "quality_type") + self.addRoleName(self.LayerHeightRole, "layer_height") + self.addRoleName(self.AvailableRole, "available") + self.addRoleName(self.QualityGroupRole, "quality_group") + self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") + + # connect signals + Application.getInstance().globalContainerStackChanged.connect(self._update) + Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) + + self._quality_manager = Application.getInstance()._quality_manager + + self._layer_height_unit = "" # This is cached + + def _update(self): + Logger.log("d", "Updating quality profile model ...") + + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if active_global_stack is None: + self.setItems([]) + Logger.log("d", "No active GlobalStack, set quality profile model as empty.") + return + + quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) + + item_list = [] + for key in sorted(quality_group_dict): + quality_group = quality_group_dict[key] + + layer_height = self._fetchLayerHeight(quality_group) + + item = {"id": "TODO", # TODO: probably will be removed + "name": quality_group.name, + "quality_type": quality_group.quality_type, + "layer_height": layer_height + self._layer_height_unit, + "layer_height_without_unit": layer_height, + "available": quality_group.is_available, + "quality_group": quality_group} + + item_list.append(item) + + # Sort items based on layer_height + item_list = sorted(item_list, key = lambda x: float(x["layer_height_without_unit"])) + + self.setItems(item_list) + + def _fetchLayerHeight(self, quality_group: "QualityGroup"): + active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + if not self._layer_height_unit: + unit = active_global_stack.definition.getProperty("layer_height", "unit") + if not unit: + unit = "" + self._layer_height_unit = unit + + default_layer_height = active_global_stack.definition.getProperty("layer_height", "value") + + # Get layer_height from the quality profile for the GlobalStack + container = quality_group.node_for_global.getContainer() + + layer_height = default_layer_height + if container.hasProperty("layer_height", "value"): + layer_height = str(container.getProperty("layer_height", "value")) + else: + # Look for layer_height in the GlobalStack from material -> definition + for idx in range(4): + container = active_global_stack.getContainer(idx) + if container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") + break + return str(layer_height) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 713b4b856e..8d26bfc982 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.8 @@ -13,7 +13,7 @@ Menu Instantiator { - model: Cura.NewQualityProfilesModel + model: Cura.QualityProfilesModel MenuItem { @@ -34,18 +34,18 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.NewCustomQualityProfilesModel.rowCount > 0 + visible: Cura.CustomQualityProfilesModel.rowCount > 0 } Instantiator { id: customProfileInstantiator - model: Cura.NewCustomQualityProfilesModel + model: Cura.CustomQualityProfilesModel Connections { - target: Cura.NewCustomQualityProfilesModel - onModelReset: customSeparator.visible = Cura.NewCustomQualityProfilesModel.rowCount() > 0 + target: Cura.CustomQualityProfilesModel + onModelReset: customSeparator.visible = Cura.CustomQualityProfilesModel.rowCount() > 0 } MenuItem diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 33aa98ba9f..c296a72281 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -1,7 +1,7 @@ -// Copyright (c) 2017 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.8 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 @@ -58,7 +58,7 @@ Item running: false repeat: false onTriggered: { - var item = Cura.NewQualityProfilesModel.getItem(qualitySlider.value); + var item = Cura.QualityProfilesModel.getItem(qualitySlider.value); Cura.MachineManager.activeQualityGroup = item.quality_group; } } @@ -105,8 +105,8 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.NewQualityProfilesModel.rowCount(); i++) { - var qualityItem = Cura.NewQualityProfilesModel.getItem(i) + for (var i = 0; i < Cura.QualityProfilesModel.rowCount(); i++) { + var qualityItem = Cura.QualityProfilesModel.getItem(i) // Add each quality item to the UI quality model qualityModel.append(qualityItem) @@ -168,7 +168,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.NewQualityProfilesModel.rowCount() - 1) + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesModel.rowCount() - 1) } } @@ -194,13 +194,13 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) - color: (Cura.MachineManager.activeMachine != null && Cura.NewQualityProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { var result = "" if(Cura.MachineManager.activeMachine != null) { - result = Cura.NewQualityProfilesModel.getItem(index).layer_height_without_unit + result = Cura.QualityProfilesModel.getItem(index).layer_height_without_unit if(result == undefined) { @@ -265,7 +265,7 @@ Item Rectangle { anchors.verticalCenter: parent.verticalCenter - color: Cura.NewQualityProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: Cura.QualityProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 * screenScaleFactor height: 6 * screenScaleFactor y: 0 @@ -411,9 +411,9 @@ Item // if the current profile is user-created, switch to a built-in quality if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { - if (Cura.NewQualityProfilesModel.rowCount() > 0) + if (Cura.QualityProfilesModel.rowCount() > 0) { - var item = Cura.NewQualityProfilesModel.getItem(0); + var item = Cura.QualityProfilesModel.getItem(0); Cura.MachineManager.activeQualityGroup = item.quality_group; } } From 1c8f63e47fe7840905d5c844aba0ce475b011e5d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 15:08:47 +0100 Subject: [PATCH 060/266] WIP: Fix for buildplate --- cura/Machines/Models/NozzleModel.py | 6 +++--- cura/Machines/VariantManager.py | 31 +++++++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 271580962a..9d1be393cf 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -33,13 +33,13 @@ class NozzleModel(ListModel): self.setItems([]) return - variant_group_dict = variant_manager.getVariantNodes(active_global_stack) - if not variant_group_dict: + variant_node_dict = variant_manager.getVariantNodes(active_global_stack) + if not variant_node_dict: self.setItems([]) return item_list = [] - for hotend_name, container_node in sorted(variant_group_dict.items(), key = lambda i: i[0]): + for hotend_name, container_node in sorted(variant_node_dict.items(), key = lambda i: i[0]): item = {"id": hotend_name, "hotend_name": hotend_name, "container_node": container_node diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 555dfec4a3..05ddfe869c 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -1,8 +1,11 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from collections import OrderedDict from typing import Optional from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer from cura.Machines.ContainerNode import ContainerNode from cura.Settings.GlobalStack import GlobalStack @@ -35,7 +38,7 @@ class VariantManager: def __init__(self, container_registry): self._container_registry = container_registry # type: ContainerRegistry - self._machine_to_variant_dict_map = {} # -> + self._machine_to_variant_dict_map = dict() # -> self._exclude_variant_id_list = ["empty_variant"] @@ -44,6 +47,8 @@ class VariantManager: # - initializing the variant lookup table based on the metadata in ContainerRegistry. # def initialize(self): + self._machine_to_variant_dict_map = OrderedDict() + # Cache all variants from the container registry to a variant map for better searching and organization. variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant") for variant_metadata in variant_metadata_list: @@ -54,13 +59,12 @@ class VariantManager: variant_name = variant_metadata["name"] variant_definition = variant_metadata["definition"] if variant_definition not in self._machine_to_variant_dict_map: - self._machine_to_variant_dict_map[variant_definition] = {} - #for variant_type in ALL_VARIANT_TYPES: - # self._machine_to_variant_dict_map[variant_definition][variant_type] = {} + self._machine_to_variant_dict_map[variant_definition] = OrderedDict() + for variant_type in ALL_VARIANT_TYPES: + self._machine_to_variant_dict_map[variant_definition][variant_type] = dict() variant_type = variant_metadata["hardware_type"] - #variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type] - variant_dict = self._machine_to_variant_dict_map[variant_definition] + variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type] if variant_name in variant_dict: # ERROR: duplicated variant name. raise RuntimeError("Found duplicated variant name [%s], type [%s] for machine [%s]" % @@ -72,10 +76,11 @@ class VariantManager: # Gets the variant InstanceContainer with the given information. # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. # - def getVariantNode(self, machine_type_name: str, variant_name: str, - variant_type: Optional[str] = None) -> Optional["InstanceContainer"]: - return self._machine_to_variant_dict_map[machine_type_name].get(variant_name) + def getVariantNode(self, machine_definition_id: str, variant_name: str, + variant_type: Optional[str] = VariantType.NOZZLE) -> Optional["ContainerNode"]: + return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name) - def getVariantNodes(self, machine: "GlobalStack"): - machine_type_name = machine.definition.getId() - return self._machine_to_variant_dict_map.get(machine_type_name) + def getVariantNodes(self, machine: "GlobalStack", + variant_type: Optional[str] = VariantType.NOZZLE) -> dict: + machine_definition_id = machine.definition.getId() + return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}) From 495fc8bbd705f5145fe8312207b3f048a7dcc106 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 22:23:49 +0100 Subject: [PATCH 061/266] WIP: Refactor BuildPlateModel and split MultiBuildPlateModel --- cura/CuraApplication.py | 32 ++++++---- cura/Machines/Models/BuildPlateModel.py | 40 +++++++++++++ .../Models/Other/MultiBuildPlateModel.py} | 23 ++++---- cura/Machines/Models/Other/__init__.py | 0 cura/PrintInformation.py | 19 +++--- cura/Scene/ConvexHullNode.py | 2 +- cura/Scene/CuraSceneController.py | 16 ++--- cura/Scene/CuraSceneNode.py | 4 +- cura/Settings/MachineManager.py | 59 +++++++++++++------ plugins/3MFReader/ThreeMFReader.py | 2 +- plugins/3MFWriter/ThreeMFWriter.py | 2 +- .../CuraEngineBackend/CuraEngineBackend.py | 10 ++-- plugins/CuraEngineBackend/ProcessGCodeJob.py | 2 +- plugins/GCodeReader/FlavorParser.py | 2 +- plugins/GCodeWriter/GCodeWriter.py | 2 +- .../PostProcessingPlugin.py | 2 +- plugins/SimulationView/SimulationPass.py | 2 +- plugins/SupportEraser/SupportEraser.py | 2 +- .../ClusterUM3OutputDevice.py | 2 +- .../LegacyUM3OutputDevice.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- .../qml/DiscardOrKeepProfileChangesDialog.qml | 2 +- resources/qml/Menus/BuildplateMenu.qml | 20 ++----- resources/qml/Menus/ContextMenu.qml | 12 ++-- resources/qml/Menus/ViewMenu.qml | 10 ++-- resources/qml/ObjectsList.qml | 10 ++-- resources/qml/SidebarSimple.qml | 2 +- 27 files changed, 172 insertions(+), 111 deletions(-) create mode 100644 cura/Machines/Models/BuildPlateModel.py rename cura/{BuildPlateModel.py => Machines/Models/Other/MultiBuildPlateModel.py} (76%) create mode 100644 cura/Machines/Models/Other/__init__.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 395d6655cb..b369ebcfed 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -53,10 +53,13 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.SettingFunction import SettingFunction from cura.Settings.MachineNameValidator import MachineNameValidator +from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.NozzleModel import NozzleModel from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfilesModel +from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel + from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager @@ -84,7 +87,6 @@ from cura.Settings.QualitySettingsModel import QualitySettingsModel from cura.Settings.ContainerManager import ContainerManager from cura.ObjectsModel import ObjectsModel -from cura.BuildPlateModel import BuildPlateModel from PyQt5.QtCore import QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from UM.FlameProfiler import pyqtSlot @@ -219,6 +221,7 @@ class CuraApplication(QtApplication): self._material_manager = None self._object_manager = None self._build_plate_model = None + self._multi_build_plate_model = None self._setting_inheritance_manager = None self._simple_mode_settings_manager = None self._cura_scene_controller = None @@ -858,10 +861,14 @@ class CuraApplication(QtApplication): self._object_manager = ObjectsModel.createObjectsModel() return self._object_manager + def getMultiBuildPlateModel(self, *args): + if self._multi_build_plate_model is None: + self._multi_build_plate_model = MultiBuildPlateModel(self) + return self._multi_build_plate_model + def getBuildPlateModel(self, *args): if self._build_plate_model is None: - self._build_plate_model = BuildPlateModel.createBuildPlateModel() - + self._build_plate_model = BuildPlateModel(self) return self._build_plate_model def getCuraSceneController(self, *args): @@ -923,15 +930,16 @@ class CuraApplication(QtApplication): qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") - qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController) + qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, "SceneController", self.getCuraSceneController) qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager) qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager) qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager) - qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) + qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) - qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 2, "ObjectsModel", self.getObjectsModel) - qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 2, "BuildPlateModel", self.getBuildPlateModel) + qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 0, "ObjectsModel", self.getObjectsModel) + qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel", self.getBuildPlateModel) + qmlRegisterSingletonType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel", self.getMultiBuildPlateModel) qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") @@ -951,7 +959,7 @@ class CuraApplication(QtApplication): qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") - qmlRegisterType(UserChangesModel, "Cura", 1, 1, "UserChangesModel") + qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel") qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager) # As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work. @@ -1033,7 +1041,7 @@ class CuraApplication(QtApplication): count = 0 scene_bounding_box = None is_block_slicing_node = False - active_build_plate = self.getBuildPlateModel().activeBuildPlate + active_build_plate = self._multi_build_plate_model.activeBuildPlate for node in DepthFirstIterator(self.getController().getScene().getRoot()): if ( not issubclass(type(node), CuraSceneNode) or @@ -1282,7 +1290,7 @@ class CuraApplication(QtApplication): @pyqtSlot() def arrangeAll(self): nodes = [] - active_build_plate = self.getBuildPlateModel().activeBuildPlate + active_build_plate = self._multi_build_plate_model.activeBuildPlate for node in DepthFirstIterator(self.getController().getScene().getRoot()): if not isinstance(node, SceneNode): continue @@ -1431,7 +1439,7 @@ class CuraApplication(QtApplication): group_decorator = GroupDecorator() group_node.addDecorator(group_decorator) group_node.addDecorator(ConvexHullDecorator()) - group_node.addDecorator(BuildPlateDecorator(self.getBuildPlateModel().activeBuildPlate)) + group_node.addDecorator(BuildPlateDecorator(self._multi_build_plate_model.activeBuildPlate)) group_node.setParent(self.getController().getScene().getRoot()) group_node.setSelectable(True) center = Selection.getSelectionCenter() @@ -1576,7 +1584,7 @@ class CuraApplication(QtApplication): arrange_objects_on_load = ( not Preferences.getInstance().getValue("cura/use_multi_build_plate") or not Preferences.getInstance().getValue("cura/not_arrange_objects_on_load")) - target_build_plate = self.getBuildPlateModel().activeBuildPlate if arrange_objects_on_load else -1 + target_build_plate = self._multi_build_plate_model.activeBuildPlate if arrange_objects_on_load else -1 root = self.getController().getScene().getRoot() fixed_nodes = [] diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py new file mode 100644 index 0000000000..ff623eeca7 --- /dev/null +++ b/cura/Machines/Models/BuildPlateModel.py @@ -0,0 +1,40 @@ +from PyQt5.QtCore import Qt + +from UM.Application import Application +from UM.Qt.ListModel import ListModel + +from cura.Machines.VariantManager import VariantType + + +class BuildPlateModel(ListModel): + NameRole = Qt.UserRole + 1 + ContainerNodeRole = Qt.UserRole + 2 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.ContainerNodeRole, "container_node") + + self._application = Application.getInstance() + self._variant_manager = self._application._variant_manager + self._machine_manager = self._application.getMachineManager() + + self._machine_manager.globalContainerChanged.connect(self._update) + + self._update() + + def _update(self): + global_stack = self._machine_manager._global_container_stack + if not global_stack: + self.setItems([]) + return + + variant_dict = self._variant_manager.getVariantNodes(global_stack, variant_type = VariantType.BUILD_PLATE) + + item_list = [] + for name, variant_node in variant_dict.items(): + item = {"name": name, + "container_node": variant_node} + item_list.append(item) + self.setItems(item_list) diff --git a/cura/BuildPlateModel.py b/cura/Machines/Models/Other/MultiBuildPlateModel.py similarity index 76% rename from cura/BuildPlateModel.py rename to cura/Machines/Models/Other/MultiBuildPlateModel.py index 73f61202c6..78ad458a99 100644 --- a/cura/BuildPlateModel.py +++ b/cura/Machines/Models/Other/MultiBuildPlateModel.py @@ -1,24 +1,25 @@ -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot +from PyQt5.QtCore import pyqtSignal, pyqtProperty -from UM.Qt.ListModel import ListModel -from UM.Scene.Selection import Selection -from UM.Logger import Logger from UM.Application import Application +from UM.Scene.Selection import Selection +from UM.Qt.ListModel import ListModel -class BuildPlateModel(ListModel): +class MultiBuildPlateModel(ListModel): + maxBuildPlateChanged = pyqtSignal() activeBuildPlateChanged = pyqtSignal() selectionChanged = pyqtSignal() - def __init__(self): - super().__init__() - Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSelectedObjectBuildPlateNumbers) + def __init__(self, parent = None): + super().__init__(parent) + + self._application = Application.getInstance() + self._application.getController().getScene().sceneChanged.connect(self._updateSelectedObjectBuildPlateNumbers) Selection.selectionChanged.connect(self._updateSelectedObjectBuildPlateNumbers) self._max_build_plate = 1 # default self._active_build_plate = -1 - self._selection_build_plates = [] def setMaxBuildPlate(self, max_build_plate): self._max_build_plate = max_build_plate @@ -37,10 +38,6 @@ class BuildPlateModel(ListModel): def activeBuildPlate(self): return self._active_build_plate - @staticmethod - def createBuildPlateModel(): - return BuildPlateModel() - def _updateSelectedObjectBuildPlateNumbers(self, *args): result = set() for node in Selection.getAllSelectedObjects(): diff --git a/cura/Machines/Models/Other/__init__.py b/cura/Machines/Models/Other/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 8b6fbb1f28..9cbd7aec7e 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -76,15 +76,18 @@ class PrintInformation(QObject): self._active_build_plate = 0 self._initVariablesWithBuildPlate(self._active_build_plate) - Application.getInstance().globalContainerStackChanged.connect(self._updateJobName) - Application.getInstance().fileLoaded.connect(self.setBaseName) - Application.getInstance().getBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged) - Application.getInstance().workspaceLoaded.connect(self.setProjectName) + self._application = Application.getInstance() + self._multi_build_plate_model = self._application.getMultiBuildPlateModel() + + self._application.globalContainerStackChanged.connect(self._updateJobName) + self._application.fileLoaded.connect(self.setBaseName) + self._application.workspaceLoaded.connect(self.setProjectName) + self._multi_build_plate_model.activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged) Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) self._active_material_container = None - Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged) + self._application.getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged) self._onActiveMaterialChanged() self._material_amounts = [] @@ -260,7 +263,7 @@ class PrintInformation(QObject): if preference != "cura/material_settings": return - for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1): + for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1): self._calculateInformation(build_plate_number) def _onActiveMaterialChanged(self): @@ -278,7 +281,7 @@ class PrintInformation(QObject): self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged) def _onActiveBuildPlateChanged(self): - new_active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + new_active_build_plate = self._multi_build_plate_model.activeBuildPlate if new_active_build_plate != self._active_build_plate: self._active_build_plate = new_active_build_plate @@ -291,7 +294,7 @@ class PrintInformation(QObject): self.currentPrintTimeChanged.emit() def _onMaterialMetaDataChanged(self, *args, **kwargs): - for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1): + for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1): self._calculateInformation(build_plate_number) @pyqtSlot(str) diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py index 6c8c201498..1131958627 100644 --- a/cura/Scene/ConvexHullNode.py +++ b/cura/Scene/ConvexHullNode.py @@ -68,7 +68,7 @@ class ConvexHullNode(SceneNode): ConvexHullNode.shader.setUniformValue("u_opacity", 0.6) if self.getParent(): - if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate: + if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate: renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8) if self._convex_hull_head_mesh: renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8) diff --git a/cura/Scene/CuraSceneController.py b/cura/Scene/CuraSceneController.py index 1c008d1893..d60179ae08 100644 --- a/cura/Scene/CuraSceneController.py +++ b/cura/Scene/CuraSceneController.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QObject from PyQt5.QtWidgets import QApplication from cura.ObjectsModel import ObjectsModel -from cura.BuildPlateModel import BuildPlateModel +from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel from UM.Application import Application from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -16,11 +16,11 @@ from UM.Signal import Signal class CuraSceneController(QObject): activeBuildPlateChanged = Signal() - def __init__(self, objects_model: ObjectsModel, build_plate_model: BuildPlateModel): + def __init__(self, objects_model: ObjectsModel, multi_build_plate_model: MultiBuildPlateModel): super().__init__() self._objects_model = objects_model - self._build_plate_model = build_plate_model + self._multi_build_plate_model = multi_build_plate_model self._active_build_plate = -1 self._last_selected_index = 0 @@ -41,9 +41,9 @@ class CuraSceneController(QObject): self._max_build_plate = max_build_plate changed = True if changed: - self._build_plate_model.setMaxBuildPlate(self._max_build_plate) + self._multi_build_plate_model.setMaxBuildPlate(self._max_build_plate) build_plates = [{"name": "Build Plate %d" % (i + 1), "buildPlateNumber": i} for i in range(self._max_build_plate + 1)] - self._build_plate_model.setItems(build_plates) + self._multi_build_plate_model.setItems(build_plates) if self._active_build_plate > self._max_build_plate: build_plate_number = 0 if self._last_selected_index >= 0: # go to the buildplate of the item you last selected @@ -104,12 +104,12 @@ class CuraSceneController(QObject): self._active_build_plate = nr Selection.clear() - self._build_plate_model.setActiveBuildPlate(nr) + self._multi_build_plate_model.setActiveBuildPlate(nr) self._objects_model.setActiveBuildPlate(nr) self.activeBuildPlateChanged.emit() @staticmethod def createCuraSceneController(): objects_model = Application.getInstance().getObjectsModel() - build_plate_model = Application.getInstance().getBuildPlateModel() - return CuraSceneController(objects_model = objects_model, build_plate_model = build_plate_model) + multi_build_plate_model = Application.getInstance().getMultiBuildPlateModel() + return CuraSceneController(objects_model = objects_model, multi_build_plate_model = multi_build_plate_model) diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py index 969d491f49..df346baaad 100644 --- a/cura/Scene/CuraSceneNode.py +++ b/cura/Scene/CuraSceneNode.py @@ -20,10 +20,10 @@ class CuraSceneNode(SceneNode): return self._outside_buildarea or self.callDecoration("getBuildPlateNumber") < 0 def isVisible(self): - return super().isVisible() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate + return super().isVisible() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate def isSelectable(self) -> bool: - return super().isSelectable() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate + return super().isSelectable() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate ## Get the extruder used to print this node. If there is no active node, then the extruder in position zero is returned # TODO The best way to do it is by adding the setActiveExtruder decorator to every node when is loaded diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e53145ee87..9f25e27a5c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -545,11 +545,11 @@ class MachineManager(QObject): return "" @pyqtProperty(str, notify=activeVariantChanged) - def globalVariantId(self) -> str: + def globalVariantName(self) -> str: if self._global_container_stack: variant = self._global_container_stack.variant if variant and not isinstance(variant, type(self._empty_variant_container)): - return variant.getId() + return variant.getName() return "" @pyqtProperty(str, notify = activeQualityChanged) @@ -1319,6 +1319,9 @@ class MachineManager(QObject): def _setVariantNode(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() + def _setGlobalVariant(self, container_node): + self._global_container_stack.variant = container_node.getContainer() + def _setMaterial(self, position, container_node = None): if container_node: self._global_container_stack.extruders[position].material = container_node.getContainer() @@ -1354,22 +1357,33 @@ class MachineManager(QObject): self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = False) - def _updateMaterialWithVariant(self, position, current_material_base_name, current_variant_name): - material_manager = Application.getInstance()._material_manager - material_diameter = self._global_container_stack.getProperty("material_diameter", "value") - candidate_materials = material_manager.getAvailableMaterials( - self._global_container_stack.getId(), - current_variant_name, - material_diameter) + def _updateMaterialWithVariant(self, position: Optional[str]): + if position is None: + position_list = list(self._global_container_stack.extruders.keys()) + else: + position_list = [position] - if not candidate_materials: - self._setMaterial(position, container_node = None) - return + for position in position_list: + extruder = self._global_container_stack.extruders[position] - if current_material_base_name in candidate_materials: - new_material = candidate_materials[current_material_base_name] - self._setMaterial(position, new_material) - return + current_material_base_name = extruder.material.getMetaDataEntry("base_file") + current_variant_name = extruder.variant.getMetaDataEntry("name") + + material_manager = Application.getInstance()._material_manager + material_diameter = self._global_container_stack.getProperty("material_diameter", "value") + candidate_materials = material_manager.getAvailableMaterials( + self._global_container_stack.getId(), + current_variant_name, + material_diameter) + + if not candidate_materials: + self._setMaterial(position, container_node = None) + continue + + if current_material_base_name in candidate_materials: + new_material = candidate_materials[current_material_base_name] + self._setMaterial(position, new_material) + continue # # Find a fallback material # preferred_material_query = self._global_container_stack.getMetaDataEntry("preferred_material") @@ -1378,6 +1392,15 @@ class MachineManager(QObject): # self._setMaterial(position, candidate_materials[preferred_material_key]) # return + @pyqtSlot("QVariant") + def setGlobalVariant(self, container_node): + Logger.log("d", "---------------- container = [%s]", container_node) + self.blurSettings.emit() + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setGlobalVariant(container_node) + self._updateMaterialWithVariant(None) # Update all materials + self._updateQualityWithMaterial() + @pyqtSlot(str, "QVariant") def setMaterial(self, position, container_node): Logger.log("d", "---------------- container = [%s]", container_node) @@ -1394,9 +1417,7 @@ class MachineManager(QObject): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setVariantNode(position, container_node) - current_variant_name = container_node.metadata["name"] - current_material_base_name = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") - self._updateMaterialWithVariant(position, current_material_base_name, current_variant_name) + self._updateMaterialWithVariant(position) self._updateQualityWithMaterial() @pyqtSlot("QVariant") diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 1726818100..907c1c44b7 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -77,7 +77,7 @@ class ThreeMFReader(MeshReader): self._object_count += 1 node_name = "Object %s" % self._object_count - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate um_node = CuraSceneNode() um_node.addDecorator(BuildPlateDecorator(active_build_plate)) diff --git a/plugins/3MFWriter/ThreeMFWriter.py b/plugins/3MFWriter/ThreeMFWriter.py index c4b7035cf1..ff6333763a 100644 --- a/plugins/3MFWriter/ThreeMFWriter.py +++ b/plugins/3MFWriter/ThreeMFWriter.py @@ -68,7 +68,7 @@ class ThreeMFWriter(MeshWriter): if not isinstance(um_node, SceneNode): return None - active_build_plate_nr = CuraApplication.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_nr = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate if um_node.callDecoration("getBuildPlateNumber") != active_build_plate_nr: return diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 1c275d6d5b..cd4f74141b 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -70,7 +70,7 @@ class CuraEngineBackend(QObject, Backend): # Workaround to disable layer view processing if layer view is not active. self._layer_view_active = False Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) - Application.getInstance().getBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveViewChanged) + Application.getInstance().getMultiBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveViewChanged) self._onActiveViewChanged() self._stored_layer_data = [] self._stored_optimized_layer_data = {} # key is build plate number, then arrays are stored until they go to the ProcessSlicesLayersJob @@ -207,7 +207,7 @@ class CuraEngineBackend(QObject, Backend): self._scene.gcode_dict = {} # see if we really have to slice - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate build_plate_to_be_sliced = self._build_plates_to_be_sliced.pop(0) Logger.log("d", "Going to slice build plate [%s]!" % build_plate_to_be_sliced) num_objects = self._numObjects() @@ -497,7 +497,7 @@ class CuraEngineBackend(QObject, Backend): node.getParent().removeChild(node) def markSliceAll(self): - for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1): + for build_plate_number in range(Application.getInstance().getMultiBuildPlateModel().maxBuildPlate + 1): if build_plate_number not in self._build_plates_to_be_sliced: self._build_plates_to_be_sliced.append(build_plate_number) @@ -582,7 +582,7 @@ class CuraEngineBackend(QObject, Backend): Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time ) # See if we need to process the sliced layers job. - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()) and active_build_plate == self._start_slice_job_build_plate: self._startProcessSlicedLayersJob(active_build_plate) # self._onActiveViewChanged() @@ -702,7 +702,7 @@ class CuraEngineBackend(QObject, Backend): application = Application.getInstance() view = application.getController().getActiveView() if view: - active_build_plate = application.getBuildPlateModel().activeBuildPlate + active_build_plate = application.getMultiBuildPlateModel().activeBuildPlate if view.getPluginId() == "SimulationView": # If switching to layer view, we should process the layers if that hasn't been done yet. self._layer_view_active = True # There is data and we're not slicing at the moment diff --git a/plugins/CuraEngineBackend/ProcessGCodeJob.py b/plugins/CuraEngineBackend/ProcessGCodeJob.py index ed430f8fa9..817daa9f85 100644 --- a/plugins/CuraEngineBackend/ProcessGCodeJob.py +++ b/plugins/CuraEngineBackend/ProcessGCodeJob.py @@ -12,6 +12,6 @@ class ProcessGCodeLayerJob(Job): self._message = message def run(self): - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_list = self._scene.gcode_dict[active_build_plate_id] gcode_list.append(self._message.data.decode("utf-8", "replace")) diff --git a/plugins/GCodeReader/FlavorParser.py b/plugins/GCodeReader/FlavorParser.py index f63ba3ca69..c064ffbf10 100644 --- a/plugins/GCodeReader/FlavorParser.py +++ b/plugins/GCodeReader/FlavorParser.py @@ -437,7 +437,7 @@ class FlavorParser: scene_node.addDecorator(gcode_list_decorator) # gcode_dict stores gcode_lists for a number of build plates. - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_dict = {active_build_plate_id: gcode_list} Application.getInstance().getController().getScene().gcode_dict = gcode_dict diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 368942fd08..ede0e2c251 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -60,7 +60,7 @@ class GCodeWriter(MeshWriter): Logger.log("e", "GCodeWriter does not support non-text mode.") return False - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate scene = Application.getInstance().getController().getScene() gcode_dict = getattr(scene, "gcode_dict") if not gcode_dict: diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index f491afbec0..566b05abf3 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -62,7 +62,7 @@ class PostProcessingPlugin(QObject, Extension): return # get gcode list for the active build plate - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_list = gcode_dict[active_build_plate_id] if not gcode_list: return diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py index 76d7127534..cd0eda2929 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -93,7 +93,7 @@ class SimulationPass(RenderPass): self.bind() tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay, backface_cull = True) - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate head_position = None # Indicates the current position of the print head nozzle_node = None diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index 9e2d41014d..ddc6b96c3a 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -42,7 +42,7 @@ class SupportEraser(Tool): mesh.addCube(10,10,10) node.setMeshData(mesh.build()) - active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate node.addDecorator(SettingOverrideDecorator()) node.addDecorator(BuildPlateDecorator(active_build_plate)) diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py index 26b445ef90..0b5a0696c6 100644 --- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py @@ -81,7 +81,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self.writeStarted.emit(self) gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", []) - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_list = gcode_dict[active_build_plate_id] if not gcode_list: diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 647a7f822c..512671b3b3 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -184,7 +184,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.writeStarted.emit(self) gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", []) - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_list = gcode_dict[active_build_plate_id] if not gcode_list: diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index b53f502d81..6e2b5153db 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -99,7 +99,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): Application.getInstance().getController().setActiveStage("MonitorStage") # find the G-code for the active build plate to print - active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate + active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict") gcode_list = gcode_dict[active_build_plate_id] diff --git a/resources/qml/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/DiscardOrKeepProfileChangesDialog.qml index 915a11fde2..afa9fda0bd 100644 --- a/resources/qml/DiscardOrKeepProfileChangesDialog.qml +++ b/resources/qml/DiscardOrKeepProfileChangesDialog.qml @@ -7,7 +7,7 @@ import QtQuick.Dialogs 1.2 import QtQuick.Window 2.1 import UM 1.2 as UM -import Cura 1.1 as Cura +import Cura 1.0 as Cura UM.Dialog { diff --git a/resources/qml/Menus/BuildplateMenu.qml b/resources/qml/Menus/BuildplateMenu.qml index 2679eec1d1..8dfc3ced6c 100644 --- a/resources/qml/Menus/BuildplateMenu.qml +++ b/resources/qml/Menus/BuildplateMenu.qml @@ -14,26 +14,18 @@ Menu Instantiator { - id: buildplateInstantiator - model: UM.InstanceContainersModel - { - filter: - { - "type": "variant", - "hardware_type": "buildplate", - "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine - } - } + model: Cura.BuildPlateModel + MenuItem { text: model.name checkable: true - checked: model.id == Cura.MachineManager.globalVariantId + checked: model.name == Cura.MachineManager.globalVariantName // TODO exclusiveGroup: group - onTriggered: - { - Cura.MachineManager.setActiveVariantBuildplate(model.id); + onTriggered: { + Cura.MachineManager.setGlobalVariant(model.container_node); // TODO } } + onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) } diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index b5f51f4d63..a37204d255 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -7,7 +7,7 @@ import QtQuick.Dialogs 1.2 import QtQuick.Window 2.1 import UM 1.2 as UM -import Cura 1.2 as Cura +import Cura 1.0 as Cura Menu { @@ -45,13 +45,13 @@ Menu Instantiator { - model: Cura.BuildPlateModel + model: Cura.MultiBuildPlateModel MenuItem { enabled: UM.Selection.hasSelection - text: Cura.BuildPlateModel.getItem(index).name; - onTriggered: CuraActions.setBuildPlateForSelection(Cura.BuildPlateModel.getItem(index).buildPlateNumber); + text: Cura.MultiBuildPlateModel.getItem(index).name; + onTriggered: CuraActions.setBuildPlateForSelection(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber); checkable: true - checked: Cura.BuildPlateModel.selectionBuildPlates.indexOf(Cura.BuildPlateModel.getItem(index).buildPlateNumber) != -1; + checked: Cura.MultiBuildPlateModel.selectionBuildPlates.indexOf(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber) != -1; visible: UM.Preferences.getValue("cura/use_multi_build_plate") } onObjectAdded: base.insertItem(index, object); @@ -62,7 +62,7 @@ Menu enabled: UM.Selection.hasSelection text: "New build plate"; onTriggered: { - CuraActions.setBuildPlateForSelection(Cura.BuildPlateModel.maxBuildPlate + 1); + CuraActions.setBuildPlateForSelection(Cura.MultiBuildPlateModel.maxBuildPlate + 1); checked = false; } checkable: true diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index afc80dd314..ff749bec90 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -5,7 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.2 as UM -import Cura 1.2 as Cura +import Cura 1.0 as Cura Menu { @@ -53,12 +53,12 @@ Menu visible: UM.Preferences.getValue("cura/use_multi_build_plate") Instantiator { - model: Cura.BuildPlateModel + model: Cura.MultiBuildPlateModel MenuItem { - text: Cura.BuildPlateModel.getItem(index).name; - onTriggered: Cura.SceneController.setActiveBuildPlate(Cura.BuildPlateModel.getItem(index).buildPlateNumber); + text: Cura.MultiBuildPlateModel.getItem(index).name; + onTriggered: Cura.SceneController.setActiveBuildPlate(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber); checkable: true; - checked: Cura.BuildPlateModel.getItem(index).buildPlateNumber == Cura.BuildPlateModel.activeBuildPlate; + checked: Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber == Cura.MultiBuildPlateModel.activeBuildPlate; exclusiveGroup: buildPlateGroup; visible: UM.Preferences.getValue("cura/use_multi_build_plate") } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index b64f08d003..f51e1081e6 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 import UM 1.3 as UM -import Cura 1.2 as Cura +import Cura 1.0 as Cura import "Menus" @@ -67,7 +67,7 @@ Rectangle Rectangle { height: childrenRect.height - color: Cura.BuildPlateModel.getItem(index).buildPlateNumber == Cura.BuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase + color: Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber == Cura.MultiBuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase width: parent.width Label { @@ -75,8 +75,8 @@ Rectangle anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30 - text: Cura.BuildPlateModel.getItem(index) ? Cura.BuildPlateModel.getItem(index).name : ""; - color: Cura.BuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text + text: Cura.MultiBuildPlateModel.getItem(index) ? Cura.MultiBuildPlateModel.getItem(index).name : ""; + color: Cura.MultiBuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text elide: Text.ElideRight } @@ -118,7 +118,7 @@ Rectangle ListView { id: buildPlateListView - model: Cura.BuildPlateModel + model: Cura.MultiBuildPlateModel width: parent.width delegate: buildPlateDelegate } diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index c296a72281..0f9c8b0e55 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 import UM 1.2 as UM -import Cura 1.2 as Cura +import Cura 1.0 as Cura Item { From 6124729f01001aa7f09118e8c29228e37446363e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 17 Feb 2018 22:27:56 +0100 Subject: [PATCH 062/266] WIP: Cleanup MachineManager --- cura/Settings/MachineManager.py | 106 -------------------------------- 1 file changed, 106 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9f25e27a5c..28a36b7e87 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -609,112 +609,6 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved - ## Set the active material by switching out a container - # Depending on from/to material+current variant, a quality profile is chosen and set. - @pyqtSlot(str) - def setActiveMaterial(self, material_id: str, always_discard_changes = False): - with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id) - if not containers or not self._active_container_stack: - return - material_container = containers[0] - - Logger.log("d", "Attempting to change the active material to %s", material_id) - - old_material = self._active_container_stack.material - old_quality = self._active_container_stack.quality - old_quality_type = None - if old_quality and old_quality.getId() != self._empty_quality_container.getId(): - old_quality_type = old_quality.getMetaDataEntry("quality_type") - old_quality_changes = self._active_container_stack.qualityChanges - if not old_material: - Logger.log("w", "While trying to set the active material, no material was found to replace it.") - return - - if old_quality_changes and isinstance(old_quality_changes, type(self._empty_quality_changes_container)): - old_quality_changes = None - - self.blurSettings.emit() - old_material.nameChanged.disconnect(self._onMaterialNameChanged) - - self._new_material_container = material_container # self._active_container_stack will be updated with a delay - Logger.log("d", "Active material changed") - - material_container.nameChanged.connect(self._onMaterialNameChanged) - - if material_container.getMetaDataEntry("compatible") == False: - self._material_incompatible_message.show() - else: - self._material_incompatible_message.hide() - - quality_type = None - new_quality_id = None - if old_quality: - new_quality_id = old_quality.getId() - quality_type = old_quality.getMetaDataEntry("quality_type") - if old_quality_changes: - quality_type = old_quality_changes.getMetaDataEntry("quality_type") - new_quality_id = old_quality_changes.getId() - - global_stack = Application.getInstance().getGlobalContainerStack() - if global_stack: - quality_manager = QualityManager.getInstance() - - candidate_quality = None - if quality_type: - candidate_quality = quality_manager.findQualityByQualityType(quality_type, - quality_manager.getWholeMachineDefinition(global_stack.definition), - [material_container.getMetaData()]) - - if not candidate_quality or candidate_quality.getId() == self._empty_quality_changes_container: - Logger.log("d", "Attempting to find fallback quality") - # Fall back to a quality (which must be compatible with all other extruders) - new_qualities = quality_manager.findAllUsableQualitiesForMachineAndExtruders( - self._global_container_stack, ExtruderManager.getInstance().getExtruderStacks()) - - quality_types = sorted([q.getMetaDataEntry("quality_type") for q in new_qualities], reverse = True) - quality_type_to_use = None - if quality_types: - # try to use the same quality as before, otherwise the first one in the quality_types - quality_type_to_use = quality_types[0] - if old_quality_type is not None and old_quality_type in quality_type_to_use: - quality_type_to_use = old_quality_type - - new_quality = None - for q in new_qualities: - if quality_type_to_use is not None and q.getMetaDataEntry("quality_type") == quality_type_to_use: - new_quality = q - break - - if new_quality is not None: - new_quality_id = new_quality.getId() # Just pick the first available one - else: - Logger.log("w", "No quality profile found that matches the current machine and extruders.") - else: - if not old_quality_changes: - new_quality_id = candidate_quality.getId() - - self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes) - - # TODO: refactor this - @pyqtSlot(str) - def setActiveVariantBuildplate(self, variant_buildplate_id: str): - with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_buildplate_id) - if not containers or not self._global_container_stack: - return - Logger.log("d", "Attempting to change the active buildplate to %s", variant_buildplate_id) - old_buildplate = self._global_container_stack.variant - if old_buildplate: - self.blurSettings.emit() - self._new_buildplate_container = containers[0] # self._active_container_stack will be updated with a delay - Logger.log("d", "Active buildplate changed to {active_variant_buildplate_id}".format(active_variant_buildplate_id = containers[0].getId())) - - # Force set the active quality as it is so the values are updated - self.setActiveMaterial(self._active_container_stack.material.getId()) - else: - Logger.log("w", "While trying to set the active buildplate, no buildplate was found to replace.") - ## set the active quality # \param quality_id The quality_id of either a quality or a quality_changes @pyqtSlot(str) From 1891294079320f8fee3e39c58a549ff25fd29cf3 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 11:02:08 +0100 Subject: [PATCH 063/266] CURA-4606 fix material manager to exclude custom materials from some lookup tables --- cura/Machines/MaterialManager.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index b52bd7dca2..664d55a4c1 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -100,16 +100,24 @@ class MaterialManager(QObject): self._guid_material_groups_map[guid].append(material_group) # Map #2 - # Lookup table for material type -> fallback material metadata + # Lookup table for material type -> fallback material metadata, only for read-only materials grouped_by_type_dict = dict() for root_material_id, material_node in self._material_group_map.items(): + if not self._container_registry.isReadOnly(root_material_id): + continue material_type = material_node.root_material_node.metadata["material"] if material_type not in grouped_by_type_dict: grouped_by_type_dict[material_type] = {"generic": None, "others": []} brand = material_node.root_material_node.metadata["brand"] if brand.lower() == "generic": - grouped_by_type_dict[material_type] = material_node.root_material_node.metadata + to_add = True + if material_type in grouped_by_type_dict: + diameter = material_node.root_material_node.metadata.get("approximate_diameter") + if diameter != self._default_approximate_diameter_for_quality_search: + to_add = False # don't add if it's not the default diameter + if to_add: + grouped_by_type_dict[material_type] = material_node.root_material_node.metadata self._fallback_materials_map = grouped_by_type_dict # Map #3 @@ -124,6 +132,9 @@ class MaterialManager(QObject): material_group_dict = dict() keys_to_fetch = ("name", "material", "brand", "color") for root_material_id, machine_node in self._material_group_map.items(): + if not self._container_registry.isReadOnly(root_material_id): + continue + root_material_metadata = machine_node.root_material_node.metadata key_data = [] From 5d4a2a7e4930431b5ad4a0a54983a9526c3c3afb Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 11:02:42 +0100 Subject: [PATCH 064/266] CURA-4606 qtquick dialogs 1.2 to be compatible with older pyqt --- resources/qml/Preferences/MaterialsPage.qml | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 92d596485c..4eddc45d76 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -4,7 +4,7 @@ import QtQuick 2.8 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import QtQuick.Dialogs 1.3 +import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 633e965bd9..df5f4faa33 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -4,7 +4,7 @@ import QtQuick 2.8 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import QtQuick.Dialogs 1.3 +import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura From 2d5f65a954fd44fc2d4e63e3ab114a20fa5d34b3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 14:23:05 +0100 Subject: [PATCH 065/266] WIP: Fix NozzleMenu QObject result type --- cura/Settings/MachineManager.py | 2 +- resources/qml/Menus/NozzleMenu.qml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 28a36b7e87..3c35aaad64 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1115,7 +1115,7 @@ class MachineManager(QObject): def createMachineManager(): return MachineManager() - @pyqtSlot(int, result = "QVariant") + @pyqtSlot(int, result = QObject) def getExtruder(self, position: int): if self._global_container_stack: return self._global_container_stack.extruders.get(str(position)) diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 96b21f285c..ea1c0000f4 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -13,19 +13,18 @@ Menu title: "Nozzle" property int extruderIndex: 0 + property var extruderStack: Cura.MachineManager.getExtruder(menu.extruderIndex) Cura.NozzleModel { id: nozzleModel } - property var extruderStack: Cura.MachineManager.getExtruder(extruderIndex) - Connections { target: Cura.MachineManager onGlobalContainerChanged: { - menu.extruderStack = Cura.MachineManager.getExtruder(extruderIndex) + menu.extruderStack = Cura.MachineManager.getExtruder(extruderIndex); } } From 3ff9cb6b1e3bb917cee1e5041eae03c2a9cab6d2 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 15:03:04 +0100 Subject: [PATCH 066/266] CURA-4606 added first Profile management page --- cura/CuraApplication.py | 2 +- cura/Machines/ContainerGroup.py | 9 + cura/Machines/Models/QualitySettingsModel.py | 147 ++++++++ cura/Machines/QualityManager.py | 5 +- cura/Settings/QualitySettingsModel.py | 249 ------------ resources/qml/Preferences/OldProfileTab.qml | 98 ----- resources/qml/Preferences/OldProfilesPage.qml | 356 ------------------ resources/qml/Preferences/ProfileTab.qml | 16 +- resources/qml/Preferences/ProfilesPage.qml | 96 ++++- 9 files changed, 260 insertions(+), 718 deletions(-) create mode 100644 cura/Machines/Models/QualitySettingsModel.py delete mode 100644 cura/Settings/QualitySettingsModel.py delete mode 100644 resources/qml/Preferences/OldProfileTab.qml delete mode 100644 resources/qml/Preferences/OldProfilesPage.qml diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b369ebcfed..57054c5d3b 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -83,7 +83,7 @@ from cura.Settings.UserChangesModel import UserChangesModel from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.ContainerSettingsModel import ContainerSettingsModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler -from cura.Settings.QualitySettingsModel import QualitySettingsModel +from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel from cura.Settings.ContainerManager import ContainerManager from cura.ObjectsModel import ObjectsModel diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index 3b17a0ae60..d1ceb81dec 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -16,3 +16,12 @@ class ContainerGroup(QObject): @pyqtSlot(result = str) def getName(self) -> str: return self.name + + def getAllKeys(self) -> set: + result = set() + for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): + if node is None: + continue + for key in node.getContainer().getAllKeys(): + result.add(key) + return result diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py new file mode 100644 index 0000000000..d3a177c3eb --- /dev/null +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -0,0 +1,147 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt + +from UM.Logger import Logger +import UM.Qt +from UM.Application import Application +from UM.Settings.ContainerRegistry import ContainerRegistry +import os + +from UM.i18n import i18nCatalog + + +class QualitySettingsModel(UM.Qt.ListModel.ListModel): + KeyRole = Qt.UserRole + 1 + LabelRole = Qt.UserRole + 2 + UnitRole = Qt.UserRole + 3 + ProfileValueRole = Qt.UserRole + 4 + ProfileValueSourceRole = Qt.UserRole + 5 + UserValueRole = Qt.UserRole + 6 + CategoryRole = Qt.UserRole + 7 + + def __init__(self, parent = None): + super().__init__(parent = parent) + + self._container_registry = ContainerRegistry.getInstance() + self._application = Application.getInstance() + + self._extruder_position = "" + self._quality = None + self._i18n_catalog = None + + self.addRoleName(self.KeyRole, "key") + self.addRoleName(self.LabelRole, "label") + self.addRoleName(self.UnitRole, "unit") + self.addRoleName(self.ProfileValueRole, "profile_value") + self.addRoleName(self.ProfileValueSourceRole, "profile_value_source") + self.addRoleName(self.UserValueRole, "user_value") + self.addRoleName(self.CategoryRole, "category") + + self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] + + self._update() + + def setExtruderPosition(self, extruder_position): + if extruder_position != self._extruder_position: + self._extruder_position = extruder_position + self._update() + self.extruderPositionChanged.emit() + + extruderPositionChanged = pyqtSignal() + @pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self): + return self._extruder_position + + def setQuality(self, quality): + if quality != self._quality: + self._quality = quality + self._update() + self.qualityChanged.emit() + + qualityChanged = pyqtSignal() + @pyqtProperty(dict, fset = setQuality, notify = qualityChanged) + def quality(self): + return self._quality + + def _update(self): + if self._quality is None: + self.setItems([]) + return + + items = [] + + global_container_stack = Application.getInstance().getGlobalContainerStack() + definition_container = global_container_stack.definition + + quality_group = self._quality["quality_group"] + quality_changes_group = self._quality["quality_changes_group"] + + if self._extruder_position == "": + quality_node = quality_group.node_for_global + else: + quality_node = quality_group.nodes_for_extruders.get(self._extruder_position) + settings_keys = quality_group.getAllKeys() + quality_containers = [quality_node.getContainer()] + + if quality_changes_group is not None: + if self._extruder_position == "": + quality_changes_node = quality_changes_group.node_for_global + else: + quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._extruder_position) + if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime + quality_containers.insert(0, quality_changes_node.getContainer()) + settings_keys.update(quality_changes_group.getAllKeys()) + + current_category = "" + for definition in definition_container.findDefinitions(): + if definition.type == "category": + current_category = definition.label + if self._i18n_catalog: + current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label) + continue + + profile_value = None + profile_value_source = "" + for quality_container in quality_containers: + new_value = quality_container.getProperty(definition.key, "value") + + if new_value is not None: + profile_value_source = quality_container.getMetaDataEntry("type") + profile_value = new_value + + # Global tab should use resolve (if there is one) + if self._extruder_position == "": + resolve_value = global_container_stack.getProperty(definition.key, "resolve") + if resolve_value is not None and definition.key in settings_keys: + profile_value = resolve_value + + if profile_value is not None: + break + + user_value = None + if not self._extruder_position: + user_value = global_container_stack.userChanges.getProperty(definition.key, "value") + else: + extruder_stack = global_container_stack.extruders[self._extruder_position] + user_value = extruder_stack.userChanges.getProperty(definition.key, "value") + + if profile_value is None and user_value is None: + continue + + label = definition.label + if self._i18n_catalog: + label = self._i18n_catalog.i18nc(definition.key + " label", label) + + items.append({ + "key": definition.key, + "label": label, + "unit": definition.unit, + "profile_value": "" if profile_value is None else str(profile_value), # it is for display only + "profile_value_source": profile_value_source, + "user_value": "" if user_value is None else str(user_value), + "category": current_category + }) + + self.setItems(items) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 53b85a1dca..c2481af85e 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -138,6 +138,10 @@ class QualityManager(QObject): # Initialize the lookup tree for quality profiles with following structure: # -> -> # -> + + self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup + self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup + quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality") for metadata in quality_metadata_list: if metadata["id"] == "empty_quality": @@ -207,7 +211,6 @@ class QualityManager(QObject): if machine_definition_id not in self._machine_quality_type_to_quality_changes_dict: self._machine_quality_type_to_quality_changes_dict[machine_definition_id] = QualityNode() machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id] - machine_node.addQualityChangesMetadata(quality_type, metadata) def _updateMaps(self): diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py deleted file mode 100644 index fb1aa9a6b2..0000000000 --- a/cura/Settings/QualitySettingsModel.py +++ /dev/null @@ -1,249 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt - -from UM.Logger import Logger -import UM.Qt -from UM.Application import Application -from UM.Settings.ContainerRegistry import ContainerRegistry -import os - -from UM.i18n import i18nCatalog - - -class QualitySettingsModel(UM.Qt.ListModel.ListModel): - KeyRole = Qt.UserRole + 1 - LabelRole = Qt.UserRole + 2 - UnitRole = Qt.UserRole + 3 - ProfileValueRole = Qt.UserRole + 4 - ProfileValueSourceRole = Qt.UserRole + 5 - UserValueRole = Qt.UserRole + 6 - CategoryRole = Qt.UserRole + 7 - - def __init__(self, parent = None): - super().__init__(parent = parent) - - self._container_registry = ContainerRegistry.getInstance() - - self._extruder_id = None - self._extruder_definition_id = None - self._quality_id = None - self._material_id = None - self._i18n_catalog = None - - self.addRoleName(self.KeyRole, "key") - self.addRoleName(self.LabelRole, "label") - self.addRoleName(self.UnitRole, "unit") - self.addRoleName(self.ProfileValueRole, "profile_value") - self.addRoleName(self.ProfileValueSourceRole, "profile_value_source") - self.addRoleName(self.UserValueRole, "user_value") - self.addRoleName(self.CategoryRole, "category") - - self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] - - def setExtruderId(self, extruder_id): - if extruder_id != self._extruder_id: - self._extruder_id = extruder_id - self._update() - self.extruderIdChanged.emit() - - extruderIdChanged = pyqtSignal() - @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged) - def extruderId(self): - return self._extruder_id - - def setExtruderDefinition(self, extruder_definition): - if extruder_definition != self._extruder_definition_id: - self._extruder_definition_id = extruder_definition - self._update() - self.extruderDefinitionChanged.emit() - - extruderDefinitionChanged = pyqtSignal() - @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged) - def extruderDefinition(self): - return self._extruder_definition_id - - def setQuality(self, quality): - if quality != self._quality_id: - self._quality_id = quality - self._update() - self.qualityChanged.emit() - - qualityChanged = pyqtSignal() - @pyqtProperty(str, fset = setQuality, notify = qualityChanged) - def quality(self): - return self._quality_id - - def setMaterial(self, material): - if material != self._material_id: - self._material_id = material - self._update() - self.materialChanged.emit() - - materialChanged = pyqtSignal() - @pyqtProperty(str, fset = setMaterial, notify = materialChanged) - def material(self): - return self._material_id - - def _update(self): - if not self._quality_id: - return - - items = [] - - definition_container = Application.getInstance().getGlobalContainerStack().getBottom() - - containers = self._container_registry.findInstanceContainers(id = self._quality_id) - if not containers: - Logger.log("w", "Could not find a quality container with id %s", self._quality_id) - return - - quality_container = None - quality_changes_container = None - - if containers[0].getMetaDataEntry("type") == "quality": - quality_container = containers[0] - else: - quality_changes_container = containers[0] - - if quality_changes_container.getMetaDataEntry("quality_type") == self._empty_quality.getMetaDataEntry("quality_type"): - quality_container = self._empty_quality - else: - criteria = { - "type": "quality", - "quality_type": quality_changes_container.getMetaDataEntry("quality_type"), - "definition": quality_changes_container.getDefinition().getId() - } - - quality_container = self._container_registry.findInstanceContainers(**criteria) - if not quality_container: - Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId()) - return - - quality_container = quality_container[0] - - quality_type = quality_container.getMetaDataEntry("quality_type") - - if quality_type == "not_supported": - containers = [] - else: - definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition()) - definition = quality_container.getDefinition() - - # Check if the definition container has a translation file. - definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix - catalog = i18nCatalog(os.path.basename(definition_id + "." + definition_suffix)) - if catalog.hasTranslationLoaded(): - self._i18n_catalog = catalog - - for file_name in quality_container.getDefinition().getInheritedFiles(): - catalog = i18nCatalog(os.path.basename(file_name)) - if catalog.hasTranslationLoaded(): - self._i18n_catalog = catalog - - criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} - - if self._material_id and self._material_id != "empty_material": - criteria["material"] = self._material_id - - criteria["extruder"] = self._extruder_id - - containers = self._container_registry.findInstanceContainers(**criteria) - if not containers: - # Try again, this time without extruder - new_criteria = criteria.copy() - new_criteria.pop("extruder") - containers = self._container_registry.findInstanceContainers(**new_criteria) - - if not containers and "material" in criteria: - # Try again, this time without material - criteria.pop("material", None) - containers = self._container_registry.findInstanceContainers(**criteria) - - if not containers: - # Try again, this time without material or extruder - criteria.pop("extruder") # "material" has already been popped - containers = self._container_registry.findInstanceContainers(**criteria) - - if not containers: - Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria)) - return - - if quality_changes_container: - if quality_type == "not_supported": - criteria = {"type": "quality_changes", "quality_type": quality_type, "name": quality_changes_container.getName()} - else: - criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()} - if self._extruder_definition_id != "": - extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id) - if extruder_definitions: - criteria["extruder"] = Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0]) - criteria["name"] = quality_changes_container.getName() - else: - criteria["extruder"] = None - - changes = self._container_registry.findInstanceContainers(**criteria) - if changes: - containers.extend(changes) - - global_container_stack = Application.getInstance().getGlobalContainerStack() - - current_category = "" - for definition in definition_container.findDefinitions(): - if definition.type == "category": - current_category = definition.label - if self._i18n_catalog: - current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label) - continue - - profile_value = None - profile_value_source = "" - for container in containers: - new_value = container.getProperty(definition.key, "value") - - if new_value is not None: - profile_value_source = container.getMetaDataEntry("type") - profile_value = new_value - - # Global tab should use resolve (if there is one) - if not self._extruder_id: - resolve_value = global_container_stack.getProperty(definition.key, "resolve") - if resolve_value is not None and profile_value is not None and profile_value_source != "quality_changes": - profile_value = resolve_value - - user_value = None - if not self._extruder_id: - user_value = global_container_stack.getTop().getProperty(definition.key, "value") - else: - extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id) - if extruder_stack: - user_value = extruder_stack[0].getTop().getProperty(definition.key, "value") - - if profile_value is None and user_value is None: - continue - - settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder") - # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value. - if self._extruder_id != "" and not settable_per_extruder: - continue - - # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value. - if self._extruder_id == "" and settable_per_extruder: - continue - - label = definition.label - if self._i18n_catalog: - label = self._i18n_catalog.i18nc(definition.key + " label", label) - - items.append({ - "key": definition.key, - "label": label, - "unit": definition.unit, - "profile_value": "" if profile_value is None else str(profile_value), # it is for display only - "profile_value_source": profile_value_source, - "user_value": "" if user_value is None else str(user_value), - "category": current_category - }) - - self.setItems(items) diff --git a/resources/qml/Preferences/OldProfileTab.qml b/resources/qml/Preferences/OldProfileTab.qml deleted file mode 100644 index acebea3500..0000000000 --- a/resources/qml/Preferences/OldProfileTab.qml +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2016 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.1 -import QtQuick.Controls 1.1 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -Tab -{ - id: base - - property string extruderId: ""; - property string extruderDefinition: ""; - property string quality: ""; - property string material: ""; - - TableView - { - anchors.fill: parent - anchors.margins: UM.Theme.getSize("default_margin").width - - Component - { - id: itemDelegate - - UM.TooltipArea - { - property var setting: qualitySettings.getItem(styleData.row) - height: childrenRect.height - width: (parent != null) ? parent.width : 0 - text: (styleData.value.substr(0,1) == "=") ? styleData.value : "" - - Label - { - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.right: parent.right - text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value - font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != "" - font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "") - opacity: font.strikeout ? 0.5 : 1 - color: styleData.textColor - elide: Text.ElideRight - } - } - } - - TableViewColumn - { - role: "label" - title: catalog.i18nc("@title:column", "Setting") - width: (parent.width * 0.4) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "profile_value" - title: catalog.i18nc("@title:column", "Profile") - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "user_value" - title: catalog.i18nc("@title:column", "Current"); - visible: quality == Cura.MachineManager.globalQualityId - width: (parent.width * 0.18) | 0 - delegate: itemDelegate - } - TableViewColumn - { - role: "unit" - title: catalog.i18nc("@title:column", "Unit") - width: (parent.width * 0.14) | 0 - delegate: itemDelegate - } - - section.property: "category" - section.delegate: Label - { - text: section - font.bold: true - } - - model: Cura.QualitySettingsModel - { - id: qualitySettings - extruderId: base.extruderId - extruderDefinition: base.extruderDefinition - quality: base.quality != null ? base.quality : "" - material: base.material != null ? base.material : "" - } - - SystemPalette { id: palette } - } -} diff --git a/resources/qml/Preferences/OldProfilesPage.qml b/resources/qml/Preferences/OldProfilesPage.qml deleted file mode 100644 index e3ba9b23a4..0000000000 --- a/resources/qml/Preferences/OldProfilesPage.qml +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (c) 2016 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Dialogs 1.2 - -import UM 1.2 as UM -import Cura 1.0 as Cura - -UM.ManagementPage -{ - id: base; - - title: catalog.i18nc("@title:tab", "Profiles"); - property var extrudersModel: Cura.ExtrudersModel{} - - model: Cura.QualityAndUserProfilesModel { } - - section.property: "readOnly" - section.delegate: Rectangle - { - height: childrenRect.height; - - Label - { - anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("default_lining").width; - text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles") - font.bold: true - } - } - - activeId: Cura.MachineManager.activeQualityId - activeIndex: { - for(var i = 0; i < model.rowCount(); i++) { - if (model.getItem(i).id == Cura.MachineManager.activeQualityId) { - return i; - } - } - return -1; - } - - function canCreateProfile() { - return base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings; - } - - buttons: [ - Button - { - text: catalog.i18nc("@action:button", "Activate"); - iconName: "list-activate"; - enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false; - onClicked: - { - Cura.MachineManager.setActiveQuality(base.currentItem.id) - currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item. - } - }, - - // Create button - Button - { - text: catalog.i18nc("@label", "Create") - enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors - visible: base.canCreateProfile() - iconName: "list-add"; - - onClicked: - { - newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : ""; - newNameDialog.open(); - newNameDialog.selectText(); - } - }, - - // Duplicate button - Button - { - text: catalog.i18nc("@label", "Duplicate") - enabled: ! base.canCreateProfile() - visible: ! base.canCreateProfile() - iconName: "list-add"; - - onClicked: - { - newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); - newDuplicateNameDialog.open(); - newDuplicateNameDialog.selectText(); - } - }, - - Button - { - text: catalog.i18nc("@action:button", "Remove"); - iconName: "list-remove"; - enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false; - onClicked: confirmDialog.open(); - }, - Button - { - text: catalog.i18nc("@action:button", "Rename"); - iconName: "edit-rename"; - enabled: base.currentItem != null ? !base.currentItem.readOnly : false; - onClicked: - { - renameDialog.open(); - renameDialog.selectText(); - } - }, - Button - { - text: catalog.i18nc("@action:button", "Import"); - iconName: "document-import"; - onClicked: importDialog.open(); - }, - Button - { - text: catalog.i18nc("@action:button", "Export") - iconName: "document-export" - onClicked: exportDialog.open() - enabled: currentItem != null && !base.currentItem.readOnly - } - ] - - scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) - - signal createProfile() - onCreateProfile: - { - newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : ""; - newNameDialog.open(); - newNameDialog.selectText(); - } - - signal selectContainer(string name) - onSelectContainer: - { - objectList.currentIndex = objectList.model.find("name", name); - } - - Item { - visible: base.currentItem != null - anchors.fill: parent - - Label { - id: profileName - text: base.currentItem ? base.currentItem.name: "" - font: UM.Theme.getFont("large") - width: parent.width - elide: Text.ElideRight - } - - Flow { - id: currentSettingsActions - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - anchors.left: parent.left - anchors.right: parent.right - anchors.top: profileName.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - - Button - { - text: { - return catalog.i18nc("@action:button", "Update profile with current settings/overrides"); - } - enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.ContainerManager.updateQualityChanges() - } - - Button - { - text: catalog.i18nc("@action:button", "Discard current changes"); - enabled: Cura.MachineManager.hasUserSettings - onClicked: Cura.ContainerManager.clearUserContainers(); - } - } - - Column { - id: profileNotices - anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - anchors.right: parent.right - spacing: UM.Theme.getSize("default_margin").height - - Label { - id: defaultsMessage - visible: false - text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.") - wrapMode: Text.WordWrap - width: parent.width - } - Label { - id: noCurrentSettingsMessage - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings - text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") - wrapMode: Text.WordWrap - width: parent.width - } - } - - TabView - { - anchors.left: parent.left - anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: parent.right - anchors.bottom: parent.bottom - - currentIndex: Cura.ExtruderManager.extruderCount > 0 ? Cura.ExtruderManager.activeExtruderIndex + 1 : 0 - - ProfileTab - { - title: catalog.i18nc("@title:tab", "Global Settings"); - quality: base.currentItem != null ? base.currentItem.id : ""; - material: Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId] - } - - Repeater - { - model: base.extrudersModel - - ProfileTab - { - title: model.name; - extruderId: model.id; - extruderDefinition: model.definition; - quality: base.currentItem != null ? base.currentItem.id : ""; - material: Cura.MachineManager.allActiveMaterialIds[model.id] - } - } - } - } - - Item - { - UM.I18nCatalog { id: catalog; name: "cura"; } - - UM.ConfirmRemoveDialog - { - id: confirmDialog - object: base.currentItem != null ? base.currentItem.name : "" - onYes: - { - var name = base.currentItem.name; - Cura.ContainerManager.removeQualityChanges(name) - if(Cura.MachineManager.activeQualityName == name) - { - Cura.MachineManager.setActiveQuality(base.model.getItem(0).name) - } - objectList.currentIndex = -1 //Reset selection. - } - } - - UM.RenameDialog - { - title: catalog.i18nc("@title:window", "Rename Profile") - id: renameDialog; - object: base.currentItem != null ? base.currentItem.name : "" - onAccepted: - { - Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName) - objectList.currentIndex = -1 //Reset selection. - } - } - - // Dialog to request a name when creating a new profile - UM.RenameDialog - { - title: catalog.i18nc("@title:window", "Create Profile") - id: newNameDialog; - object: ""; - onAccepted: - { - var selectedContainer = Cura.ContainerManager.createQualityChanges(newName); - base.selectContainer(selectedContainer); - objectList.currentIndex = -1 //Reset selection. - } - } - - // Dialog to request a name when duplicating a new profile - UM.RenameDialog - { - title: catalog.i18nc("@title:window", "Duplicate Profile") - id: newDuplicateNameDialog; - object: ""; - onAccepted: - { - var selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name, newName); - base.selectContainer(selectedContainer); - objectList.currentIndex = -1 //Reset selection. - } - } - - MessageDialog - { - id: messageDialog - title: catalog.i18nc("@window:title", "Import Profile"); - standardButtons: StandardButton.Ok - modality: Qt.ApplicationModal - } - - FileDialog - { - id: importDialog; - title: catalog.i18nc("@title:window", "Import Profile"); - selectExisting: true; - nameFilters: base.model.getFileNameFilters("profile_reader") - folder: CuraApplication.getDefaultPath("dialog_profile_path") - onAccepted: - { - var result = Cura.ContainerManager.importProfile(fileUrl); - messageDialog.text = result.message - if(result.status == "ok") - { - messageDialog.icon = StandardIcon.Information - } - else if(result.status == "duplicate") - { - messageDialog.icon = StandardIcon.Warning - } - else - { - messageDialog.icon = StandardIcon.Critical - } - messageDialog.open() - CuraApplication.setDefaultPath("dialog_profile_path", folder) - } - } - - FileDialog - { - id: exportDialog; - title: catalog.i18nc("@title:window", "Export Profile"); - selectExisting: false; - nameFilters: base.model.getFileNameFilters("profile_writer") - folder: CuraApplication.getDefaultPath("dialog_profile_path") - onAccepted: - { - var containers = Cura.ContainerManager.findInstanceContainers({"type": "quality_changes", "name": base.currentItem.name}) - var result = Cura.ContainerManager.exportProfile(containers, fileUrl, selectedNameFilter) - - if(result && result.status == "error") - { - messageDialog.icon = StandardIcon.Critical - messageDialog.text = result.message - messageDialog.open() - } - - // else pop-up Message thing from python code - CuraApplication.setDefaultPath("dialog_profile_path", folder) - } - } - } -} diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 47446c82c2..0ea84dbc83 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -11,10 +11,8 @@ Tab { id: base - property string extruderId: ""; - property string extruderDefinition: ""; - property string quality: ""; - property string material: ""; + property string extruderPosition: ""; + property var quality: null; TableView { @@ -38,8 +36,8 @@ Tab anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value - font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != "" - font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "") + font.strikeout: styleData.column == 1 && setting.user_value != "" // TODO && quality == Cura.MachineManager.globalQualityId + font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "") // TODO: (setting.user_value != "" && quality == Cura.MachineManager.globalQualityId) opacity: font.strikeout ? 0.5 : 1 color: styleData.textColor elide: Text.ElideRight @@ -65,7 +63,7 @@ Tab { role: "user_value" title: catalog.i18nc("@title:column", "Current"); - visible: quality == Cura.MachineManager.globalQualityId + visible: true // TODO quality == Cura.MachineManager.globalQualityId width: (parent.width * 0.18) | 0 delegate: itemDelegate } @@ -87,10 +85,8 @@ Tab model: Cura.QualitySettingsModel { id: qualitySettings - extruderId: base.extruderId - extruderDefinition: base.extruderDefinition + extruderPosition: base.extruderPosition quality: base.quality != null ? base.quality : "" - material: base.material != null ? base.material : "" } SystemPalette { id: palette } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index df5f4faa33..f2a442debe 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -14,6 +14,7 @@ Item { id: base property var resetEnabled: false // Keep PreferencesDialog happy + property var extrudersModel: Cura.ExtrudersModel{} UM.I18nCatalog { id: catalog; name: "cura"; } @@ -35,6 +36,17 @@ Item text: catalog.i18nc("@title:tab", "Profiles") } + property var hasCurrentItem: qualityListView.currentItem != null + + property var currentItem: { + var current_index = qualityListView.currentIndex; + return qualitiesModel.getItem(current_index); + } + + property var isCurrentItemActivated: { + // TODO + } + Row // Button Row { id: buttonRow @@ -50,8 +62,7 @@ Item { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" - //enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false; - enabled: true // TODO + enabled: base.currentItem != null ? base.currentItem.name != Cura.MachineManager.activeQualityOrQualityChangesName : false; onClicked: { // TODO } @@ -259,6 +270,7 @@ Item } + // details panel on the right Item { id: detailsPanel @@ -283,11 +295,89 @@ Item height: childrenRect.height Label { - text: "TODO" // TODO + text: base.currentItem.name // TODO font: UM.Theme.getFont("large") } } + Flow { + id: currentSettingsActions + visible: true // TODO //currentItem && currentItem.id == Cura.MachineManager.activeQualityId + anchors.left: parent.left + anchors.right: parent.right + anchors.top: profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + + Button + { + text: { + return catalog.i18nc("@action:button", "Update profile with current settings/overrides"); + } + enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + onClicked: Cura.ContainerManager.updateQualityChanges() + } + + Button + { + text: catalog.i18nc("@action:button", "Discard current changes"); + enabled: Cura.MachineManager.hasUserSettings + onClicked: Cura.ContainerManager.clearUserContainers(); + } + } + + Column { + id: profileNotices + anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.left: parent.left + anchors.right: parent.right + spacing: UM.Theme.getSize("default_margin").height + + Label { + id: defaultsMessage + visible: false + text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.") + wrapMode: Text.WordWrap + width: parent.width + } + Label { + id: noCurrentSettingsMessage + visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings + text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") + wrapMode: Text.WordWrap + width: parent.width + } + } + + + TabView + { + anchors.left: parent.left + anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: parent.right + anchors.bottom: parent.bottom + + currentIndex: 0 + + ProfileTab + { + title: catalog.i18nc("@title:tab", "Global Settings"); + quality: base.currentItem; + } + + Repeater + { + model: base.extrudersModel + + ProfileTab + { + title: model.name; + extruderPosition: model.index; + quality: base.currentItem; + } + } + } } } } From 8efe13a55ab1e13ed6c2b57170ab4d455c545e2d Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 15:24:58 +0100 Subject: [PATCH 067/266] CURA-4606 fix profiles page Active button --- cura/Settings/MachineManager.py | 2 ++ resources/qml/Menus/ProfileMenu.qml | 6 +++--- resources/qml/Preferences/ProfilesPage.qml | 13 ++++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3c35aaad64..68fbf19c13 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1148,6 +1148,7 @@ class MachineManager(QObject): def _setEmptyQuality(self): self._current_quality_group = None + self._current_quality_changes_group = None self._global_container_stack.quality = self._empty_quality_container self._global_container_stack.qualityChanges = self._empty_quality_changes_container for extruder in self._global_container_stack.extruders.values(): @@ -1158,6 +1159,7 @@ class MachineManager(QObject): def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group + self._current_quality_changes_group = None # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 8d26bfc982..5924ad5322 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -19,7 +19,7 @@ Menu { text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name checkable: true - checked: Cura.MachineManager.activeQualityGroup && (Cura.MachineManager.activeQualityGroup.getName() == model.name) + checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name exclusiveGroup: group onTriggered: { Cura.MachineManager.setQualityGroup(model.quality_group) @@ -52,9 +52,9 @@ Menu { text: model.name checkable: model.available - checked: Cura.MachineManager.activeQualityChangesId == model.id // TODO: fix for new + checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name exclusiveGroup: group - onTriggered: Cura.MachineManager.setActiveQuality(model.id) // TODO: fix for new + onTriggered: Cura.MachineManager.setQualityChangesGroup(model.quality_changes_group) } onObjectAdded: diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index f2a442debe..0424dd823f 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -44,7 +44,10 @@ Item } property var isCurrentItemActivated: { - // TODO + if (!base.currentItem) { + return false; + } + return base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; } Row // Button Row @@ -62,9 +65,13 @@ Item { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" - enabled: base.currentItem != null ? base.currentItem.name != Cura.MachineManager.activeQualityOrQualityChangesName : false; + enabled: !isCurrentItemActivated onClicked: { - // TODO + if (base.currentItem.is_read_only) { + Cura.MachineManager.setQualityGroup(base.currentItem.quality_group); + } else { + Cura.MachineManager.setQualityChangesGroup(base.currentItem.quality_changes_group); + } } } From 7a78f9821f6fa04a963f4ff730dc135be72f7e6e Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 16:15:35 +0100 Subject: [PATCH 068/266] CURA-4606 fixed Create profile --- .../Machines/Models/QualityManagementModel.py | 2 +- cura/Machines/Models/QualityProfilesModel.py | 1 + cura/Machines/Models/QualitySettingsModel.py | 2 ++ cura/Machines/QualityManager.py | 6 ++++ cura/Settings/ContainerManager.py | 16 ++++++---- resources/qml/Preferences/ProfilesPage.qml | 32 +++++++++++++------ 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 589fec3440..cf7a163d9c 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -27,7 +27,7 @@ class QualityManagementModel(ListModel): self._quality_manager = CuraApplication.getInstance()._quality_manager self._machine_manager.globalContainerChanged.connect(self._update) - #self._quality_manager.materialsUpdated.connect(self._update) # TODO + self._quality_manager.qualitiesUpdated.connect(self._update) self._update() diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 19262bf75a..11127190e1 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -37,6 +37,7 @@ class QualityProfilesModel(ListModel): Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) self._quality_manager = Application.getInstance()._quality_manager + self._quality_manager.qualitiesUpdated.connect(self._update) self._layer_height_unit = "" # This is cached diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index d3a177c3eb..6353ec841e 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -26,6 +26,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): self._container_registry = ContainerRegistry.getInstance() self._application = Application.getInstance() + self._quality_manager = self._application._quality_manager self._extruder_position = "" self._quality = None @@ -42,6 +43,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] self._update() + self._quality_manager.qualitiesUpdated.connect(self._update) def setExtruderPosition(self, extruder_position): if extruder_position != self._extruder_position: diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index c2481af85e..a5457344f1 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,5 +1,6 @@ from typing import Optional +from PyQt5.Qt import pyqtSignal from PyQt5.QtCore import QObject, QTimer from UM.Application import Application @@ -111,6 +112,8 @@ class QualityNode(ContainerNode): class QualityManager(QObject): + qualitiesUpdated = pyqtSignal() + def __init__(self, container_registry, parent = None): super().__init__(parent) self._application = Application.getInstance() @@ -213,6 +216,9 @@ class QualityManager(QObject): machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id] machine_node.addQualityChangesMetadata(quality_type, metadata) + Logger.log("d", "Lookup tables updated.") + self.qualitiesUpdated.emit() + def _updateMaps(self): self.initialize() diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c420f5b49e..f6ce1bfaf7 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -398,16 +398,16 @@ class ContainerManager(QObject): # stack and clear the user settings. # # \return \type{bool} True if the operation was successfully, False if not. - @pyqtSlot(str, result = bool) + @pyqtSlot(str) def createQualityChanges(self, base_name): global_stack = Application.getInstance().getGlobalContainerStack() if not global_stack: - return False + return active_quality_name = self._machine_manager.activeQualityName if active_quality_name == "": Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) - return False + return self._machine_manager.blurSettings.emit() if base_name is None or base_name == "": @@ -416,7 +416,7 @@ class ContainerManager(QObject): # Go through the active stacks and create quality_changes containers from the user containers. for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): - user_container = stack.getTop() + user_container = stack.userChanges quality_container = stack.quality quality_changes_container = stack.qualityChanges if not quality_container or not quality_changes_container: @@ -431,10 +431,12 @@ class ContainerManager(QObject): self._performMerge(new_changes, user_container) self._container_registry.addContainer(new_changes) - stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) + #stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) - self._machine_manager.activeQualityChanged.emit() - return True + #self._machine_manager.activeQualityChanged.emit() + + #self._machine_manager.activeQualityGroupChanged.emit() + #self._machine_manager.activeQualityChangesGroupChanged.emit() ## Remove all quality changes containers matching a specified name. # diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 0424dd823f..5452648187 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -50,6 +50,10 @@ Item return base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName; } + property var canCreateProfile: { + return isCurrentItemActivated && Cura.MachineManager.hasUserSettings; + } + Row // Button Row { id: buttonRow @@ -80,13 +84,13 @@ Item { text: catalog.i18nc("@label", "Create") iconName: "list-add" - //enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors - enabled: true // TODO - //visible: base.canCreateProfile() - visible: true // TODO + enabled: base.canCreateProfile && !Cura.MachineManager.stacksHaveErrors + visible: base.canCreateProfile onClicked: { - // TODO + newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(Cura.MachineManager.activeQualityOrQualityChangesName) : ""; + newNameDialog.open(); + newNameDialog.selectText(); } } @@ -95,10 +99,8 @@ Item { text: catalog.i18nc("@label", "Duplicate") iconName: "list-add" - //enabled: ! base.canCreateProfile() - enabled: true // TODO - //visible: ! base.canCreateProfile() - visible: true // TODO + enabled: !base.canCreateProfile + visible: !base.canCreateProfile onClicked: { // TODO @@ -153,6 +155,18 @@ Item } + // Dialog to request a name when creating a new profile + UM.RenameDialog + { + title: catalog.i18nc("@title:window", "Create Profile") + id: newNameDialog; + object: ""; + onAccepted: + { + var selectedContainer = Cura.ContainerManager.createQualityChanges(newName); + objectList.currentIndex = -1 //Reset selection. + } + } Item { id: contentsItem From bd10f23311d1738c7d5487117f414289fe941820 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 19 Feb 2018 16:47:04 +0100 Subject: [PATCH 069/266] CURA-4606 reimplemented duplicate profile --- cura/Machines/ContainerGroup.py | 10 +- cura/Settings/ContainerManager.py | 108 ++++----------------- resources/qml/Preferences/ProfilesPage.qml | 20 +++- 3 files changed, 46 insertions(+), 92 deletions(-) diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index d1ceb81dec..b7ad634f3c 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import List, Optional from PyQt5.Qt import QObject, pyqtSlot @@ -25,3 +25,11 @@ class ContainerGroup(QObject): for key in node.getContainer().getAllKeys(): result.add(key) return result + + def getAllNodes(self) -> List[ContainerNode]: + result = [] + if self.node_for_global is not None: + result.append(self.node_for_global) + for extruder_node in self.nodes_for_extruders.values(): + result.append(extruder_node) + return result diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index f6ce1bfaf7..f58dcab640 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -424,7 +424,8 @@ class ContainerManager(QObject): continue extruder_id = None if stack is global_stack else QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId() - new_changes = self._createQualityChanges(quality_container, unique_name, + quality_type = quality_container.getMetaDataEntry("quality_type") + new_changes = self._createQualityChanges(quality_type, unique_name, Application.getInstance().getGlobalContainerStack().getBottom(), extruder_id) self._performMerge(new_changes, quality_changes_container, clear_settings = False) @@ -526,91 +527,22 @@ class ContainerManager(QObject): self._machine_manager.activeQualityChanged.emit() return True - ## Duplicate a specified set of quality or quality_changes containers. - # - # This will search for containers matching the specified name. If the container is a "quality" type container, a new - # quality_changes container will be created with the specified quality as base. If the container is a "quality_changes" - # container, it is simply duplicated and renamed. - # - # \param quality_name The name of the quality to duplicate. - # - # \return A string containing the name of the duplicated containers, or an empty string if it failed. - @pyqtSlot(str, str, result = str) - def duplicateQualityOrQualityChanges(self, quality_name, base_name): - global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack or not quality_name: - return "" - machine_definition = global_stack.definition - - active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() - if active_stacks is None: - return "" - material_metadatas = [stack.material.getMetaData() for stack in active_stacks] - - result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name, - QualityManager.getInstance().getParentMachineDefinition(machine_definition), - material_metadatas) - return result[0].getName() if result else "" - - ## Duplicate a quality or quality changes profile specific to a machine type - # - # \param quality_name The name of the quality or quality changes container to duplicate. - # \param base_name The desired name for the new container. - # \param machine_definition The machine with the specific machine type. - # \param material_metadatas Metadata of materials - # \return List of duplicated quality profiles. - def _duplicateQualityOrQualityChangesForMachineType(self, quality_name: str, base_name: str, machine_definition: DefinitionContainer, material_metadatas: List[Dict[str, Any]]) -> List[InstanceContainer]: - Logger.log("d", "Attempting to duplicate the quality %s", quality_name) - - if base_name is None: - base_name = quality_name - # Try to find a Quality with the name. - container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_metadatas) - if container: - Logger.log("d", "We found a quality to duplicate.") - return self._duplicateQualityForMachineType(container, base_name, machine_definition) - Logger.log("d", "We found a quality_changes to duplicate.") - # Assume it is a quality changes. - return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition) - - # Duplicate a quality profile - def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition) -> List[InstanceContainer]: - if base_name is None: - base_name = quality_container.getName() - new_name = self._container_registry.uniqueName(base_name) - - new_change_instances = [] - - # Handle the global stack first. - global_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None) - new_change_instances.append(global_changes) - self._container_registry.addContainer(global_changes) - - # Handle the extruders if present. - extruders = machine_definition.getMetaDataEntry("machine_extruder_trains") - if extruders: - for extruder_id in extruders: - extruder = extruders[extruder_id] - new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, extruder) - new_change_instances.append(new_changes) - self._container_registry.addContainer(new_changes) - - return new_change_instances - - # Duplicate a quality changes container - def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition) -> List[InstanceContainer]: - new_change_instances = [] - for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name, - machine_definition): - base_id = container.getMetaDataEntry("extruder") - if not base_id: - base_id = container.getDefinition().getId() - new_unique_id = self._createUniqueId(base_id, base_name) - new_container = container.duplicate(new_unique_id, base_name) - new_change_instances.append(new_container) - self._container_registry.addContainer(new_container) - - return new_change_instances + @pyqtSlot(str, dict) + def duplicateQualityChanges(self, quality_changes_name, quality_model_item): + quality_group = quality_model_item["quality_group"] + quality_changes_group = quality_model_item["quality_changes_group"] + if quality_changes_group is None: + # create global quality changes only + new_quality_changes = self._createQualityChanges( + quality_group.quality_type, quality_changes_name, + Application.getInstance().getGlobalContainerStack().definition, + extruder_id = None) + self._container_registry.addContainer(new_quality_changes) + else: + for node in quality_changes_group.getAllNodes(): + container = node.getContainer() + new_id = self._container_registry.uniqueName(container.getId()) + self._container_registry.addContainer(container.duplicate(new_id, quality_changes_name)) @pyqtSlot("QVariant") def removeMaterial(self, material_node): @@ -832,14 +764,14 @@ class ContainerManager(QObject): # \param extruder_id # # \return A new quality_changes container with the specified container as base. - def _createQualityChanges(self, quality_container, new_name, machine_definition, extruder_id): + def _createQualityChanges(self, quality_type, new_name, machine_definition, extruder_id): base_id = machine_definition.getId() if extruder_id is None else extruder_id # Create a new quality_changes container for the quality. quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name)) quality_changes.setName(new_name) quality_changes.addMetaDataEntry("type", "quality_changes") - quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type")) + quality_changes.addMetaDataEntry("quality_type", quality_type) # If we are creating a container for an extruder, ensure we add that to the container if extruder_id is not None: diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 5452648187..096d37e50b 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -103,7 +103,9 @@ Item visible: !base.canCreateProfile onClicked: { - // TODO + newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); + newDuplicateNameDialog.open(); + newDuplicateNameDialog.selectText(); } } @@ -154,8 +156,7 @@ Item } } - - // Dialog to request a name when creating a new profile + // Dialog to request a name when creating a new profile UM.RenameDialog { title: catalog.i18nc("@title:window", "Create Profile") @@ -168,6 +169,19 @@ Item } } + // Dialog to request a name when duplicating a new profile + UM.RenameDialog + { + title: catalog.i18nc("@title:window", "Duplicate Profile") + id: newDuplicateNameDialog; + object: ""; + onAccepted: + { + Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem); + objectList.currentIndex = -1 //Reset selection. + } + } + Item { id: contentsItem From faf02424a7add957291fa54b5c96e9e8e28fe7ba Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 16:50:18 +0100 Subject: [PATCH 070/266] WIP: Cleanup MachineManager --- cura/Settings/MachineManager.py | 201 -------------------------------- 1 file changed, 201 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 68fbf19c13..de8f6328f7 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -609,78 +609,6 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved - ## set the active quality - # \param quality_id The quality_id of either a quality or a quality_changes - @pyqtSlot(str) - def setActiveQuality(self, quality_id: str, always_discard_changes = False): - with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): - self.blurSettings.emit() - - Logger.log("d", "Attempting to change the active quality to %s", quality_id) - - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = quality_id) - if not containers or not self._global_container_stack: - return - - # Quality profile come in two flavours: type=quality and type=quality_changes - # If we found a quality_changes profile then look up its parent quality profile. - container_type = containers[0].get("type") - quality_name = containers[0]["name"] - quality_type = containers[0].get("quality_type") - - # Get quality container and optionally the quality_changes container. - if container_type == "quality": - new_quality_settings_list = self.determineQualityAndQualityChangesForQualityType(quality_type) - elif container_type == "quality_changes": - new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name) - else: - Logger.log("e", "Tried to set quality to a container that is not of the right type: {container_id}".format(container_id = containers[0]["id"])) - return - - # Check if it was at all possible to find new settings - if new_quality_settings_list is None: - return - - # check if any of the stacks have a not supported profile - # if that is the case, all stacks should have a not supported state (otherwise it will show quality_type normal) - has_not_supported_quality = False - - # check all stacks for not supported - for setting_info in new_quality_settings_list: - if setting_info["quality"].getMetaDataEntry("quality_type") == "not_supported": - has_not_supported_quality = True - break - - # set all stacks to not supported if that's the case - if has_not_supported_quality: - for setting_info in new_quality_settings_list: - setting_info["quality"] = self._empty_quality_container - - self._new_quality_containers.clear() - - # store the upcoming quality profile changes per stack for later execution - # this prevents re-slicing before the user has made a choice in the discard or keep dialog - # (see _executeDelayedActiveContainerStackChanges) - for setting_info in new_quality_settings_list: - stack = setting_info["stack"] - stack_quality = setting_info["quality"] - stack_quality_changes = setting_info["quality_changes"] - - self._new_quality_containers.append({ - "stack": stack, - "quality": stack_quality, - "quality_changes": stack_quality_changes - }) - - Logger.log("d", "Active quality changed") - - # show the keep/discard dialog after the containers have been switched. Otherwise, the default values on - # the dialog will be the those before the switching. - self._executeDelayedActiveContainerStackChanges() - - if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1 and not always_discard_changes: - Application.getInstance().discardOrKeepProfileChanges() - ## Used to update material and variant in the active container stack with a delay. # This delay prevents the stack from triggering a lot of signals (eventually resulting in slicing) # before the user decided to keep or discard any of their changes using the dialog. @@ -721,135 +649,6 @@ class MachineManager(QObject): self._new_buildplate_container = None self._new_variant_container = None - ## Determine the quality and quality changes settings for the current machine for a quality name. - # - # \param quality_name \type{str} the name of the quality. - # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". - @UM.FlameProfiler.profile - def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]: - quality_manager = QualityManager.getInstance() - result = [] - empty_quality_changes = self._empty_quality_changes_container - global_container_stack = self._global_container_stack - if not global_container_stack: - return [] - - global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition) - extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - - # find qualities for extruders - for extruder_stack in extruder_stacks: - material_metadata = extruder_stack.material.getMetaData() - - # TODO: fix this - if self._new_material_container and extruder_stack.getId() == self._active_container_stack.getId(): - material_metadata = self._new_material_container.getMetaData() - - quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata]) - - if not quality: - # No quality profile is found for this quality type. - quality = self._empty_quality_container - - result.append({ - "stack": extruder_stack, - "quality": quality, - "quality_changes": empty_quality_changes - }) - - # also find a global quality for the machine - global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = "True") - - # if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482 - if not global_quality and len(extruder_stacks) == 1: - global_quality = result[0]["quality"] - - # if there is still no global quality, set it to empty (not supported) - if not global_quality: - global_quality = self._empty_quality_container - - result.append({ - "stack": global_container_stack, - "quality": global_quality, - "quality_changes": empty_quality_changes - }) - - return result - - ## Determine the quality and quality changes settings for the current machine for a quality changes name. - # - # \param quality_changes_name \type{str} the name of the quality changes. - # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes". - def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str) -> Optional[List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]]: - result = [] - quality_manager = QualityManager.getInstance() - - global_container_stack = self._global_container_stack - global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition) - quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, global_machine_definition) - - global_quality_changes = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") is None] - if global_quality_changes: - global_quality_changes = global_quality_changes[0] - else: - Logger.log("e", "Could not find the global quality changes container with name %s", quality_changes_name) - return None - - # For the global stack, find a quality which matches the quality_type in - # the quality changes profile and also satisfies any material constraints. - quality_type = global_quality_changes.getMetaDataEntry("quality_type") - - extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - - # append the extruder quality changes - for extruder_stack in extruder_stacks: - extruder_definition = quality_manager.getParentMachineDefinition(extruder_stack.definition) - - quality_changes_list = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") == extruder_definition.getId()] - - if quality_changes_list: - quality_changes = quality_changes_list[0] - else: - quality_changes = global_quality_changes - if not quality_changes: - quality_changes = self._empty_quality_changes_container - - material_metadata = extruder_stack.material.getMetaData() - - if self._new_material_container and self._active_container_stack.getId() == extruder_stack.getId(): - material_metadata = self._new_material_container.getMetaData() - - quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata]) - - if not quality: - # No quality profile found for this quality type. - quality = self._empty_quality_container - - result.append({ - "stack": extruder_stack, - "quality": quality, - "quality_changes": quality_changes - }) - - # append the global quality changes - global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, global_quality = "True") - - # if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482 - if not global_quality and len(extruder_stacks) == 1: - global_quality = result[0]["quality"] - - # if still no global quality changes are found we set it to empty (not supported) - if not global_quality: - global_quality = self._empty_quality_container - - result.append({ - "stack": global_container_stack, - "quality": global_quality, - "quality_changes": global_quality_changes - }) - - return result - def _replaceQualityOrQualityChangesInStack(self, stack: "CuraContainerStack", container: "InstanceContainer", postpone_emit = False): # Disconnect the signal handling from the old container. container_type = container.getMetaDataEntry("type") From 3546e54c95215be59e96c6a64be1b00753104f42 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 17:01:26 +0100 Subject: [PATCH 071/266] WIP: Cleanup --- .../Models/CustomQualityProfilesModel.py | 3 +-- cura/Machines/Models/QualityProfilesModel.py | 3 +-- cura/Machines/Models/QualitySettingsModel.py | 16 ++++++---------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/cura/Machines/Models/CustomQualityProfilesModel.py b/cura/Machines/Models/CustomQualityProfilesModel.py index 8b6fc2deb6..71a6b6c0f7 100644 --- a/cura/Machines/Models/CustomQualityProfilesModel.py +++ b/cura/Machines/Models/CustomQualityProfilesModel.py @@ -24,8 +24,7 @@ class CustomQualityProfilesModel(QualityProfilesModel): for key in sorted(quality_changes_group_dict): quality_changes_group = quality_changes_group_dict[key] - item = {"id": "TODO", # TODO: probably will be removed - "name": quality_changes_group.name, + item = {"name": quality_changes_group.name, "layer_height": "", "layer_height_without_unit": "", "available": quality_changes_group.is_available, diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 11127190e1..b30daa85f6 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -58,8 +58,7 @@ class QualityProfilesModel(ListModel): layer_height = self._fetchLayerHeight(quality_group) - item = {"id": "TODO", # TODO: probably will be removed - "name": quality_group.name, + item = {"name": quality_group.name, "quality_type": quality_group.quality_type, "layer_height": layer_height + self._layer_height_unit, "layer_height_without_unit": layer_height, diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 6353ec841e..6336549270 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -1,18 +1,14 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt -from UM.Logger import Logger -import UM.Qt from UM.Application import Application +from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry -import os - -from UM.i18n import i18nCatalog -class QualitySettingsModel(UM.Qt.ListModel.ListModel): +class QualitySettingsModel(ListModel): KeyRole = Qt.UserRole + 1 LabelRole = Qt.UserRole + 2 UnitRole = Qt.UserRole + 3 @@ -45,13 +41,15 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): self._update() self._quality_manager.qualitiesUpdated.connect(self._update) + extruderPositionChanged = pyqtSignal() + qualityChanged = pyqtSignal() + def setExtruderPosition(self, extruder_position): if extruder_position != self._extruder_position: self._extruder_position = extruder_position self._update() self.extruderPositionChanged.emit() - extruderPositionChanged = pyqtSignal() @pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged) def extruderPosition(self): return self._extruder_position @@ -62,7 +60,6 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): self._update() self.qualityChanged.emit() - qualityChanged = pyqtSignal() @pyqtProperty(dict, fset = setQuality, notify = qualityChanged) def quality(self): return self._quality @@ -122,7 +119,6 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): if profile_value is not None: break - user_value = None if not self._extruder_position: user_value = global_container_stack.userChanges.getProperty(definition.key, "value") else: From 251fe8a3a6975c83258237f7f58515601644ce9a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 17:03:30 +0100 Subject: [PATCH 072/266] WIP: Remove ContainerSettingModel --- cura/CuraApplication.py | 2 - cura/Settings/ContainerSettingsModel.py | 97 ------------------------- 2 files changed, 99 deletions(-) delete mode 100644 cura/Settings/ContainerSettingsModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 57054c5d3b..795c254d8c 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -81,7 +81,6 @@ from cura.Settings.MachineManager import MachineManager from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.UserChangesModel import UserChangesModel from cura.Settings.ExtrudersModel import ExtrudersModel -from cura.Settings.ContainerSettingsModel import ContainerSettingsModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel from cura.Settings.ContainerManager import ContainerManager @@ -942,7 +941,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel", self.getMultiBuildPlateModel) qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") - qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") diff --git a/cura/Settings/ContainerSettingsModel.py b/cura/Settings/ContainerSettingsModel.py deleted file mode 100644 index 2c4bef6464..0000000000 --- a/cura/Settings/ContainerSettingsModel.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from UM.Application import Application -from UM.Qt.ListModel import ListModel - -from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl - -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer -from UM.Settings.SettingFunction import SettingFunction - -class ContainerSettingsModel(ListModel): - LabelRole = Qt.UserRole + 1 - CategoryRole = Qt.UserRole + 2 - UnitRole = Qt.UserRole + 3 - ValuesRole = Qt.UserRole + 4 - - def __init__(self, parent = None): - super().__init__(parent) - self.addRoleName(self.LabelRole, "label") - self.addRoleName(self.CategoryRole, "category") - self.addRoleName(self.UnitRole, "unit") - self.addRoleName(self.ValuesRole, "values") - - self._container_ids = [] - self._containers = [] - - def _onPropertyChanged(self, key, property_name): - if property_name == "value": - self._update() - - def _update(self): - items = [] - - if len(self._container_ids) == 0: - return - - keys = [] - for container in self._containers: - keys = keys + list(container.getAllKeys()) - - keys = list(set(keys)) # remove duplicate keys - - for key in keys: - definition = None - category = None - values = [] - for container in self._containers: - instance = container.getInstance(key) - if instance: - definition = instance.definition - - # Traverse up to find the category - category = definition - while category.type != "category": - category = category.parent - - value = container.getProperty(key, "value") - if type(value) == SettingFunction: - values.append("=\u0192") - else: - values.append(container.getProperty(key, "value")) - else: - values.append("") - - items.append({ - "key": key, - "values": values, - "label": definition.label, - "unit": definition.unit, - "category": category.label - }) - items.sort(key = lambda k: (k["category"], k["key"])) - self.setItems(items) - - ## Set the ids of the containers which have the settings this model should list. - # Also makes sure the model updates when the containers have property changes - def setContainers(self, container_ids): - for container in self._containers: - container.propertyChanged.disconnect(self._onPropertyChanged) - - self._container_ids = container_ids - self._containers = [] - - for container_id in self._container_ids: - containers = ContainerRegistry.getInstance().findContainers(id = container_id) - if containers: - containers[0].propertyChanged.connect(self._onPropertyChanged) - self._containers.append(containers[0]) - - self._update() - - containersChanged = pyqtSignal() - @pyqtProperty("QVariantList", fset = setContainers, notify = containersChanged) - def containers(self): - return self.container_ids From c29f3130a7f8891e0e73932d2b99f9ee127c8cfd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 19:55:09 +0100 Subject: [PATCH 073/266] WIP: Fix QualitySettingsModel --- cura/Machines/Models/QualitySettingsModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 6336549270..a39396c324 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -60,7 +60,7 @@ class QualitySettingsModel(ListModel): self._update() self.qualityChanged.emit() - @pyqtProperty(dict, fset = setQuality, notify = qualityChanged) + @pyqtProperty("QVariantMap", fset = setQuality, notify = qualityChanged) def quality(self): return self._quality From 65e01d62033a99830861cc480aaa74e7c983a03a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 19:58:02 +0100 Subject: [PATCH 074/266] WIP: Refactor Profile management code --- cura/Machines/Models/QualitySettingsModel.py | 43 ++++++++++---------- resources/qml/Preferences/ProfileTab.qml | 6 +-- resources/qml/Preferences/ProfilesPage.qml | 41 ++++++++----------- 3 files changed, 40 insertions(+), 50 deletions(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index a39396c324..e91897b632 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -20,14 +20,6 @@ class QualitySettingsModel(ListModel): def __init__(self, parent = None): super().__init__(parent = parent) - self._container_registry = ContainerRegistry.getInstance() - self._application = Application.getInstance() - self._quality_manager = self._application._quality_manager - - self._extruder_position = "" - self._quality = None - self._i18n_catalog = None - self.addRoleName(self.KeyRole, "key") self.addRoleName(self.LabelRole, "label") self.addRoleName(self.UnitRole, "unit") @@ -36,36 +28,43 @@ class QualitySettingsModel(ListModel): self.addRoleName(self.UserValueRole, "user_value") self.addRoleName(self.CategoryRole, "category") - self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] + self._container_registry = ContainerRegistry.getInstance() + self._application = Application.getInstance() + self._quality_manager = self._application._quality_manager + + self._extruder_position = "" + self._quality_item = None + self._i18n_catalog = None - self._update() self._quality_manager.qualitiesUpdated.connect(self._update) + self._update() + extruderPositionChanged = pyqtSignal() - qualityChanged = pyqtSignal() + qualityItemChanged = pyqtSignal() def setExtruderPosition(self, extruder_position): if extruder_position != self._extruder_position: self._extruder_position = extruder_position - self._update() self.extruderPositionChanged.emit() + self._update() @pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged) def extruderPosition(self): return self._extruder_position - def setQuality(self, quality): - if quality != self._quality: - self._quality = quality + def setQualityItem(self, quality_item): + if quality_item != self._quality_item: + self._quality_item = quality_item + self.qualityItemChanged.emit() self._update() - self.qualityChanged.emit() - @pyqtProperty("QVariantMap", fset = setQuality, notify = qualityChanged) - def quality(self): - return self._quality + @pyqtProperty("QVariantMap", fset = setQualityItem, notify = qualityItemChanged) + def qualityItem(self): + return self._quality_item def _update(self): - if self._quality is None: + if self._quality_item is None: self.setItems([]) return @@ -74,8 +73,8 @@ class QualitySettingsModel(ListModel): global_container_stack = Application.getInstance().getGlobalContainerStack() definition_container = global_container_stack.definition - quality_group = self._quality["quality_group"] - quality_changes_group = self._quality["quality_changes_group"] + quality_group = self._quality_item["quality_group"] + quality_changes_group = self._quality_item["quality_changes_group"] if self._extruder_position == "": quality_node = quality_group.node_for_global diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 0ea84dbc83..5acbeecda9 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -11,8 +11,8 @@ Tab { id: base - property string extruderPosition: ""; - property var quality: null; + property string extruderPosition: "" + property var qualityItem: null TableView { @@ -86,7 +86,7 @@ Tab { id: qualitySettings extruderPosition: base.extruderPosition - quality: base.quality != null ? base.quality : "" + qualityItem: base.qualityItem } SystemPalette { id: palette } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 096d37e50b..f675453d67 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -14,7 +14,7 @@ Item { id: base property var resetEnabled: false // Keep PreferencesDialog happy - property var extrudersModel: Cura.ExtrudersModel{} + property var extrudersModel: Cura.ExtrudersModel {} UM.I18nCatalog { id: catalog; name: "cura"; } @@ -24,14 +24,12 @@ Item Label { id: titleLabel - anchors { top: parent.top left: parent.left right: parent.right margins: 5 * screenScaleFactor } - font.pointSize: 18 text: catalog.i18nc("@title:tab", "Profiles") } @@ -160,12 +158,12 @@ Item UM.RenameDialog { title: catalog.i18nc("@title:window", "Create Profile") - id: newNameDialog; - object: ""; + id: newNameDialog + object: "" onAccepted: { var selectedContainer = Cura.ContainerManager.createQualityChanges(newName); - objectList.currentIndex = -1 //Reset selection. + qualityListView.currentIndex = -1 // TODO: Reset selection. } } @@ -173,12 +171,12 @@ Item UM.RenameDialog { title: catalog.i18nc("@title:window", "Duplicate Profile") - id: newDuplicateNameDialog; - object: ""; + id: newDuplicateNameDialog + object: "" onAccepted: { Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem); - objectList.currentIndex = -1 //Reset selection. + qualityListView.currentIndex = -1; // TODO: Reset selection. } } @@ -217,10 +215,7 @@ Item left: parent.left } visible: text != "" - text: { - // OLD STUFF - return catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachineName); - } + text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachineName) width: profileScrollView.width elide: Text.ElideRight } @@ -280,10 +275,8 @@ Item width: Math.floor((parent.width * 0.3)) text: model.name elide: Text.ElideRight - font.italic: { // TODO: make it easier - return model.name == Cura.MachineManager.activeQualityOrQualityChangesName; - } - color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; + font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName // TODO: make it easier + color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text } } @@ -345,9 +338,7 @@ Item Button { - text: { - return catalog.i18nc("@action:button", "Update profile with current settings/overrides"); - } + text: catalog.i18nc("@action:button", "Update profile with current settings/overrides") enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) onClicked: Cura.ContainerManager.updateQualityChanges() } @@ -397,8 +388,8 @@ Item ProfileTab { - title: catalog.i18nc("@title:tab", "Global Settings"); - quality: base.currentItem; + title: catalog.i18nc("@title:tab", "Global Settings") + qualityItem: base.currentItem } Repeater @@ -407,9 +398,9 @@ Item ProfileTab { - title: model.name; - extruderPosition: model.index; - quality: base.currentItem; + title: model.name + extruderPosition: model.index + qualityItem: base.currentItem } } } From 486bcae677763584019e92b05fec216d9c20bc2a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 20:21:02 +0100 Subject: [PATCH 075/266] WIP: Fix remove quality --- cura/Settings/ContainerManager.py | 49 ++++------------------ resources/qml/Preferences/ProfilesPage.qml | 27 ++++++++++-- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index f58dcab640..c21e7899ed 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -439,49 +439,14 @@ class ContainerManager(QObject): #self._machine_manager.activeQualityGroupChanged.emit() #self._machine_manager.activeQualityChangesGroupChanged.emit() - ## Remove all quality changes containers matching a specified name. # - # This will search for quality_changes containers matching the supplied name and remove them. - # Note that if the machine specifies that qualities should be filtered by machine and/or material - # only the containers related to the active machine/material are removed. + # Remove the given quality changes group # - # \param quality_name The name of the quality changes to remove. - # - # \return \type{bool} True if successful, False if not. - @pyqtSlot(str, result = bool) - def removeQualityChanges(self, quality_name): - Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name) - containers_found = False - - if not quality_name: - return containers_found # Without a name we will never find a container to remove. - - # If the container that is being removed is the currently active quality, set another quality as the active quality - activate_quality = quality_name == self._machine_manager.activeQualityName - activate_quality_type = None - - global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack or not quality_name: - return "" - machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_stack.getBottom()) - - for container in QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition): - containers_found = True - if activate_quality and not activate_quality_type: - activate_quality_type = container.getMetaDataEntry("quality") - self._container_registry.removeContainer(container.getId()) - - if not containers_found: - Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name) - - elif activate_quality: - definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId - containers = self._container_registry.findInstanceContainersMetadata(type = "quality", definition = definition_id, quality_type = activate_quality_type) - if containers: - self._machine_manager.setActiveQuality(containers[0]["id"]) - self._machine_manager.activeQualityChanged.emit() - - return containers_found + @pyqtSlot(QObject) + def removeQualityChangesGroup(self, quality_changes_group): + Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name) + for node in quality_changes_group.getAllNodes(): + self._container_registry.removeContainer(node.metadata["id"]) ## Rename a set of quality changes containers. # @@ -527,7 +492,7 @@ class ContainerManager(QObject): self._machine_manager.activeQualityChanged.emit() return True - @pyqtSlot(str, dict) + @pyqtSlot(str, "QVariantMap") def duplicateQualityChanges(self, quality_changes_name, quality_model_item): quality_group = quality_model_item["quality_group"] quality_changes_group = quality_model_item["quality_changes_group"] diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index f675453d67..a469426519 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -112,10 +112,10 @@ Item { text: catalog.i18nc("@action:button", "Remove") iconName: "list-remove" - //enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false; - enabled: true // TODO + enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated onClicked: { - // TODO + forceActiveFocus(); + confirmRemoveQualityDialog.open(); } } @@ -162,7 +162,7 @@ Item object: "" onAccepted: { - var selectedContainer = Cura.ContainerManager.createQualityChanges(newName); + Cura.ContainerManager.createQualityChanges(newName); qualityListView.currentIndex = -1 // TODO: Reset selection. } } @@ -180,6 +180,25 @@ Item } } + // Confirmation dialog for removing a profile + MessageDialog + { + id: confirmRemoveQualityDialog + + icon: StandardIcon.Question; + title: catalog.i18nc("@title:window", "Confirm Remove") + text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name) + standardButtons: StandardButton.Yes | StandardButton.No + modality: Qt.ApplicationModal + + onYes: + { + Cura.ContainerManager.removeQualityChangesGroup(base.currentItem.quality_changes_group); + // reset current item to the first if available + qualityListView.currentIndex = -1; + } + } + Item { id: contentsItem From 5b37de8adbc689093ae1330818a55038164b5ef8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 20:33:36 +0100 Subject: [PATCH 076/266] WIP: Fix quality renaming --- cura/Settings/ContainerManager.py | 38 ++++++-------------- resources/qml/Preferences/ProfilesPage.qml | 42 ++++++++++++++-------- 2 files changed, 38 insertions(+), 42 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c21e7899ed..9486fbbdee 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -458,39 +458,21 @@ class ContainerManager(QObject): # \param new_name The new name of the quality changes. # # \return True if successful, False if not. - @pyqtSlot(str, str, result = bool) - def renameQualityChanges(self, quality_name, new_name): - Logger.log("d", "User requested QualityChanges container rename of %s to %s", quality_name, new_name) - if not quality_name or not new_name: - return False - - if quality_name == new_name: - Logger.log("w", "Unable to rename %s to %s, because they are the same.", quality_name, new_name) - return True - - global_stack = Application.getInstance().getGlobalContainerStack() - if not global_stack: - return False - + @pyqtSlot(QObject, str) + def renameQualityChangesGroup(self, quality_changes_group, new_name): + Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name) self._machine_manager.blurSettings.emit() + if new_name == quality_changes_group.name: + Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name) + return + new_name = self._container_registry.uniqueName(new_name) - - container_registry = self._container_registry - - containers_to_rename = self._container_registry.findInstanceContainersMetadata(type = "quality_changes", name = quality_name) - - for container in containers_to_rename: - stack_id = global_stack.getId() - if "extruder" in container: - stack_id = container["extruder"] - container_registry.renameContainer(container["id"], new_name, self._createUniqueId(stack_id, new_name)) - - if not containers_to_rename: - Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name) + for node in quality_changes_group.getAllNodes(): + node.getContainer().setName(new_name) self._machine_manager.activeQualityChanged.emit() - return True + self._machine_manager.activeQualityGroupChanged.emit() @pyqtSlot(str, "QVariantMap") def duplicateQualityChanges(self, quality_changes_name, quality_model_item): diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index a469426519..6c58a1e69d 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -86,9 +86,9 @@ Item visible: base.canCreateProfile onClicked: { - newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(Cura.MachineManager.activeQualityOrQualityChangesName) : ""; - newNameDialog.open(); - newNameDialog.selectText(); + createQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); + createQualityDialog.open(); + createQualityDialog.selectText(); } } @@ -101,9 +101,9 @@ Item visible: !base.canCreateProfile onClicked: { - newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); - newDuplicateNameDialog.open(); - newDuplicateNameDialog.selectText(); + duplicateQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); + duplicateQualityDialog.open(); + duplicateQualityDialog.selectText(); } } @@ -124,10 +124,11 @@ Item { text: catalog.i18nc("@action:button", "Rename") iconName: "edit-rename" - //enabled: base.currentItem != null ? !base.currentItem.readOnly : false; - enabled: true // TODO + enabled: base.hasCurrentItem && !base.currentItem.is_read_only onClicked: { - // TODO + renameQualityDialog.object = base.currentItem.name; + renameQualityDialog.open(); + renameQualityDialog.selectText(); } } @@ -157,26 +158,26 @@ Item // Dialog to request a name when creating a new profile UM.RenameDialog { + id: createQualityDialog title: catalog.i18nc("@title:window", "Create Profile") - id: newNameDialog object: "" onAccepted: { Cura.ContainerManager.createQualityChanges(newName); - qualityListView.currentIndex = -1 // TODO: Reset selection. + qualityListView.currentIndex = -1; // TODO: Reset selection. } } // Dialog to request a name when duplicating a new profile UM.RenameDialog { + id: duplicateQualityDialog title: catalog.i18nc("@title:window", "Duplicate Profile") - id: newDuplicateNameDialog object: "" onAccepted: { Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem); - qualityListView.currentIndex = -1; // TODO: Reset selection. + qualityListView.currentIndex = -1; // TODO: Reset selection. } } @@ -195,7 +196,20 @@ Item { Cura.ContainerManager.removeQualityChangesGroup(base.currentItem.quality_changes_group); // reset current item to the first if available - qualityListView.currentIndex = -1; + qualityListView.currentIndex = -1; // TODO: Reset selection. + } + } + + // Dialog to rename a quality profile + UM.RenameDialog + { + id: renameQualityDialog + title: catalog.i18nc("@title:window", "Rename Profile") + object: "" + onAccepted: + { + Cura.ContainerManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName); + qualityListView.currentIndex = -1; // TODO: Reset selection. } } From d4db41503f991a1ee7d0ec5977a2bb843b2efff9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 20:43:05 +0100 Subject: [PATCH 077/266] WIP: Cleanup ContainerManager --- cura/Settings/ContainerManager.py | 58 ++++++++----------------------- 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 9486fbbdee..d16bdca8a7 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -5,12 +5,11 @@ import copy import os.path import urllib.parse import uuid -from typing import Any, Dict, List, Union +from typing import Dict, Union from PyQt5.QtCore import QObject, QUrl, QVariant from UM.FlameProfiler import pyqtSlot from PyQt5.QtWidgets import QMessageBox -from UM.Util import parseBool from UM.PluginRegistry import PluginRegistry from UM.SaveFile import SaveFile @@ -22,7 +21,6 @@ from UM.Application import Application from UM.Settings.ContainerStack import ContainerStack from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Settings.InstanceContainer import InstanceContainer -from cura.QualityManager import QualityManager from UM.MimeTypeDatabase import MimeTypeNotFoundError from UM.Settings.ContainerRegistry import ContainerRegistry @@ -30,6 +28,8 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog from cura.Settings.ExtruderManager import ExtruderManager +from cura.Settings.ExtruderStack import ExtruderStack +from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch catalog = i18nCatalog("cura") @@ -183,32 +183,6 @@ class ContainerManager(QObject): def findInstanceContainers(self, criteria): return [entry["id"] for entry in self._container_registry.findInstanceContainersMetadata(**criteria)] - @pyqtSlot(str, result = bool) - def isContainerUsed(self, container_id): - Logger.log("d", "Checking if container %s is currently used", container_id) - # check if this is a material container. If so, check if any material with the same base is being used by any - # stacks. - container_ids_to_check = [container_id] - container_results = self._container_registry.findInstanceContainersMetadata(id = container_id, type = "material") - if container_results: - this_container = container_results[0] - material_base_file = this_container["id"] - if "base_file" in this_container: - material_base_file = this_container["base_file"] - # check all material container IDs with the same base - material_containers = self._container_registry.findInstanceContainersMetadata(base_file = material_base_file, - type = "material") - if material_containers: - container_ids_to_check = [container["id"] for container in material_containers] - - all_stacks = self._container_registry.findContainerStacks() - for stack in all_stacks: - for used_container_id in container_ids_to_check: - if used_container_id in [child.getId() for child in stack.getContainers()]: - Logger.log("d", "The container is in use by %s", stack.getId()) - return True - return False - @pyqtSlot(str, result = str) def makeUniqueName(self, original_name): return self._container_registry.uniqueName(original_name) @@ -423,11 +397,11 @@ class ContainerManager(QObject): Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) continue - extruder_id = None if stack is global_stack else QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId() + extruder_definition_id = None + if isinstance(stack, ExtruderStack): + extruder_definition_id = stack.definition.getId() quality_type = quality_container.getMetaDataEntry("quality_type") - new_changes = self._createQualityChanges(quality_type, unique_name, - Application.getInstance().getGlobalContainerStack().getBottom(), - extruder_id) + new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id) self._performMerge(new_changes, quality_changes_container, clear_settings = False) self._performMerge(new_changes, user_container) @@ -476,14 +450,14 @@ class ContainerManager(QObject): @pyqtSlot(str, "QVariantMap") def duplicateQualityChanges(self, quality_changes_name, quality_model_item): + global_stack = Application.getInstance().getGlobalContainerStack() + quality_group = quality_model_item["quality_group"] quality_changes_group = quality_model_item["quality_changes_group"] if quality_changes_group is None: # create global quality changes only - new_quality_changes = self._createQualityChanges( - quality_group.quality_type, quality_changes_name, - Application.getInstance().getGlobalContainerStack().definition, - extruder_id = None) + new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name, + global_stack, extruder_id = None) self._container_registry.addContainer(new_quality_changes) else: for node in quality_changes_group.getAllNodes(): @@ -711,8 +685,8 @@ class ContainerManager(QObject): # \param extruder_id # # \return A new quality_changes container with the specified container as base. - def _createQualityChanges(self, quality_type, new_name, machine_definition, extruder_id): - base_id = machine_definition.getId() if extruder_id is None else extruder_id + def _createQualityChanges(self, quality_type, new_name, machine, extruder_id): + base_id = machine.definition.getId() if extruder_id is None else extruder_id # Create a new quality_changes container for the quality. quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name)) @@ -725,10 +699,8 @@ class ContainerManager(QObject): quality_changes.addMetaDataEntry("extruder", extruder_id) # If the machine specifies qualities should be filtered, ensure we match the current criteria. - if not machine_definition.getMetaDataEntry("has_machine_quality"): - quality_changes.setDefinition("fdmprinter") - else: - quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition).getId()) + machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) + quality_changes.setDefinition(machine_definition_id) from cura.CuraApplication import CuraApplication quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) From 3fffc2c6213af5769a2cfd7a261086c16cfef768 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 20:50:14 +0100 Subject: [PATCH 078/266] WIP: Cleanup old QualityManager --- cura/QualityManager.py | 36 ------------------------------ cura/Settings/ContainerManager.py | 2 +- plugins/3MFReader/ThreeMFReader.py | 16 +++++++------ 3 files changed, 10 insertions(+), 44 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 76a0c86a5f..358bf4e422 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -27,42 +27,6 @@ class QualityManager: __instance = None # type: "QualityManager" - ## Find a quality by name for a specific machine definition and materials. - # - # \param quality_name - # \param machine_definition (Optional) \type{DefinitionContainerInterface} If nothing is - # specified then the currently selected machine definition is used. - # \param material_containers_metadata If nothing is specified then the - # current set of selected materials is used. - # \return the matching quality container \type{InstanceContainer} - def findQualityByName(self, quality_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None) -> Optional[InstanceContainer]: - criteria = {"type": "quality", "name": quality_name} - result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria) - - # Fall back to using generic materials and qualities if nothing could be found. - if not result and material_containers_metadata and len(material_containers_metadata) == 1: - basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0]) - result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - - return result[0] if result else None - - ## Find a quality changes container by name. - # - # \param quality_changes_name \type{str} the name of the quality changes container. - # \param machine_definition (Optional) \type{DefinitionContainer} If nothing is - # specified then the currently selected machine definition is used.. - # \return the matching quality changes containers \type{List[InstanceContainer]} - def findQualityChangesByName(self, quality_changes_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None): - if not machine_definition: - global_stack = Application.getGlobalContainerStack() - if not global_stack: - return [] #No stack, so no current definition could be found, so there are no quality changes either. - machine_definition = global_stack.definition - - result = self.findAllQualityChangesForMachine(machine_definition) - result = [quality_change for quality_change in result if quality_change.getName() == quality_changes_name] - return result - ## Fetch the list of available quality types for this combination of machine definition and materials. # # \param machine_definition \type{DefinitionContainer} diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d16bdca8a7..759c5d5be7 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -161,7 +161,7 @@ class ContainerManager(QObject): return container.getProperty(setting_key, property_name) ## Set the name of the specified material. - @pyqtSlot("QVariant", str) + @pyqtSlot(QObject, str) def setMaterialName(self, material_node, new_name): root_material_id = material_node.metadata["base_file"] if self._container_registry.isReadOnly(root_material_id): diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 907c1c44b7..b81fd435b9 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -4,26 +4,28 @@ import os.path import zipfile +import numpy + +import Savitar + +from UM.Application import Application from UM.Logger import Logger from UM.Math.Matrix import Matrix from UM.Math.Vector import Vector from UM.Mesh.MeshBuilder import MeshBuilder from UM.Mesh.MeshReader import MeshReader from UM.Scene.GroupDecorator import GroupDecorator + from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator -from UM.Application import Application from cura.Settings.ExtruderManager import ExtruderManager -from cura.QualityManager import QualityManager from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Scene.BuildPlateDecorator import BuildPlateDecorator from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.ZOffsetDecorator import ZOffsetDecorator +from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch MYPY = False -import Savitar -import numpy - try: if not MYPY: import xml.etree.cElementTree as ET @@ -120,8 +122,8 @@ class ThreeMFReader(MeshReader): um_node.callDecoration("setActiveExtruder", default_stack.getId()) # Get the definition & set it - definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom()) - um_node.callDecoration("getStack").getTop().setDefinition(definition.getId()) + definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack.definition) + um_node.callDecoration("getStack").getTop().setDefinition(definition_id) setting_container = um_node.callDecoration("getStack").getTop() From 2cd98910005ab0d696e42f93485f6e204fded452 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 21:00:49 +0100 Subject: [PATCH 079/266] WIP: Fix material QVariant type --- cura/Settings/ContainerManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 759c5d5be7..d16bdca8a7 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -161,7 +161,7 @@ class ContainerManager(QObject): return container.getProperty(setting_key, property_name) ## Set the name of the specified material. - @pyqtSlot(QObject, str) + @pyqtSlot("QVariant", str) def setMaterialName(self, material_node, new_name): root_material_id = material_node.metadata["base_file"] if self._container_registry.isReadOnly(root_material_id): From 7e84e7570fb5087d495760ddf4b1950921e17fb8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 21:02:33 +0100 Subject: [PATCH 080/266] WIP: Cleanup ContainerManager --- cura/Settings/ContainerManager.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d16bdca8a7..af4924b8b3 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -706,34 +706,6 @@ class ContainerManager(QObject): quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) return quality_changes - - ## Import profiles from a list of file_urls. - # Each QUrl item must end with .curaprofile, or it will not be imported. - # - # \param QVariant, essentially a list with QUrl objects. - # \return Dict with keys status, text - @pyqtSlot("QVariantList", result="QVariantMap") - def importProfiles(self, file_urls): - status = "ok" - results = {"ok": [], "error": []} - for file_url in file_urls: - if not file_url.isValid(): - continue - path = file_url.toLocalFile() - if not path: - continue - if not path.endswith(".curaprofile"): - continue - - single_result = self._container_registry.importProfile(path) - if single_result["status"] == "error": - status = "error" - results[single_result["status"]].append(single_result["message"]) - - return { - "status": status, - "message": "\n".join(results["ok"] + results["error"])} - ## Import single profile, file_url does not have to end with curaprofile @pyqtSlot(QUrl, result="QVariantMap") def importProfile(self, file_url): From 0c3ac090c9001b05f4b6834f6f5b8d20f9cd83ee Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 21:11:01 +0100 Subject: [PATCH 081/266] WIP: Cleanup --- cura/Settings/CuraContainerRegistry.py | 19 +++++----------- cura/Settings/MachineManager.py | 26 ++-------------------- resources/qml/Preferences/ProfilesPage.qml | 3 +-- 3 files changed, 8 insertions(+), 40 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 393e36db30..29ee5c4b95 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -28,6 +28,7 @@ from . import GlobalStack from .ExtruderManager import ExtruderManager from cura.CuraApplication import CuraApplication +from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -296,7 +297,7 @@ class CuraContainerRegistry(ContainerRegistry): elif profile_index < len(machine_extruders) + 1: # This is assumed to be an extruder profile - extruder_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_extruders[profile_index - 1].getBottom()) + extruder_id = machine_extruders[profile_index - 1].definition.getId() if not profile.getMetaDataEntry("extruder"): profile.addMetaDataEntry("extruder", extruder_id) else: @@ -356,7 +357,9 @@ class CuraContainerRegistry(ContainerRegistry): quality_type_criteria = {"quality_type": quality_type} if self._machineHasOwnQualities(): - profile.setDefinition(self._activeQualityDefinition().getId()) + global_container_stack = Application.getInstance().getGlobalContainerStack() + definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack) + profile.setDefinition(definition_id) if self._machineHasOwnMaterials(): active_material_id = self._activeMaterialId() if active_material_id and active_material_id != "empty": # only update if there is an active material @@ -407,18 +410,6 @@ class CuraContainerRegistry(ContainerRegistry): result.append( (plugin_id, meta_data) ) return result - ## Get the definition to use to select quality profiles for the active machine - # \return the active quality definition object or None if there is no quality definition - def _activeQualityDefinition(self): - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack: - definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(global_container_stack.getBottom()) - definition = self.findDefinitionContainers(id = definition_id)[0] - - if definition: - return definition - return None - ## Returns true if the current machine requires its own materials # \return True if the current machine requires its own materials def _machineHasOwnMaterials(self): diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index de8f6328f7..31deb91c34 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -24,6 +24,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique +from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch from cura.QualityManager import QualityManager from cura.PrinterOutputDevice import PrinterOutputDevice @@ -698,35 +699,12 @@ class MachineManager(QObject): ## Get the Definition ID to use to select quality profiles for the currently active machine # \returns DefinitionID (string) if found, empty string otherwise - # \sa getQualityDefinitionId @pyqtProperty(str, notify = globalContainerChanged) def activeQualityDefinitionId(self) -> str: if self._global_container_stack: - return self.getQualityDefinitionId(self._global_container_stack.definition) + return getMachineDefinitionIDForQualitySearch(self._global_container_stack) return "" - ## Get the Definition ID to use to select quality profiles for machines of the specified definition - # This is normally the id of the definition itself, but machines can specify a different definition to inherit qualities from - # \param definition (DefinitionContainer) machine definition - # \returns DefinitionID (string) if found, empty string otherwise - def getQualityDefinitionId(self, definition: "DefinitionContainer") -> str: - return QualityManager.getInstance().getParentMachineDefinition(definition).getId() - - ## Get the Variant ID to use to select quality profiles for variants of the specified definitions - # This is normally the id of the variant itself, but machines can specify a different definition - # to inherit qualities from, which has consequences for the variant to use as well - # \param definition (DefinitionContainer) machine definition - # \param variant (InstanceContainer) variant definition - # \returns VariantID (string) if found, empty string otherwise - def getQualityVariantId(self, definition: "DefinitionContainer", variant: "InstanceContainer") -> str: - variant_id = variant.getId() - definition_id = definition.getId() - quality_definition_id = self.getQualityDefinitionId(definition) - - if definition_id != quality_definition_id: - variant_id = variant_id.replace(definition_id, quality_definition_id, 1) - return variant_id - ## Gets how the active definition calls variants # Caveat: per-definition-variant-title is currently not translated (though the fallback is) @pyqtProperty(str, notify = globalContainerChanged) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 6c58a1e69d..57ec7a1222 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -147,8 +147,7 @@ Item { text: catalog.i18nc("@action:button", "Export") iconName: "document-export" - //enabled: currentItem != null && !base.currentItem.readOnly - enabled: true // TODO + enabled: base.hasCurrentItem && !base.currentItem.is_read_only onClicked: { // TODO } From 5bb6efcb3e26aecef839311ad16a97d10201f120 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 21:20:10 +0100 Subject: [PATCH 082/266] WIP: Cleanup MachineManager --- cura/Settings/MachineManager.py | 15 --------------- resources/qml/WorkspaceSummaryDialog.qml | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 31deb91c34..3ff5cb1011 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -586,14 +586,6 @@ class MachineManager(QObject): return False return True - @pyqtProperty(str, notify = activeQualityChanged) - def activeQualityChangesId(self) -> str: - if self._active_container_stack: - quality_changes = self._active_container_stack.qualityChanges - if quality_changes and not isinstance(quality_changes, type(self._empty_quality_changes_container)): - return quality_changes.getId() - return "" - ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id: str) -> bool: @@ -690,13 +682,6 @@ class MachineManager(QObject): return "" - @pyqtProperty(str, notify=globalContainerChanged) - def activeDefinitionName(self) -> str: - if self._global_container_stack: - return self._global_container_stack.definition.getName() - - return "" - ## Get the Definition ID to use to select quality profiles for the currently active machine # \returns DefinitionID (string) if found, empty string otherwise @pyqtProperty(str, notify = globalContainerChanged) diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml index a05dee5a9a..8f00377d58 100644 --- a/resources/qml/WorkspaceSummaryDialog.qml +++ b/resources/qml/WorkspaceSummaryDialog.qml @@ -101,7 +101,7 @@ UM.Dialog } Label { - text: Cura.MachineManager.activeDefinitionName + text: Cura.MachineManager.activeMachine.definition.name width: (parent.width / 3) | 0 } } From 27f7d16a57b86cb7b1eeabd16d7090a27b26f61f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 21:47:12 +0100 Subject: [PATCH 083/266] WIP: Make import/export profile work --- .../Machines/Models/QualityManagementModel.py | 44 ++++++++++++++- cura/Settings/ContainerManager.py | 20 ++----- cura/Settings/CuraContainerRegistry.py | 25 +-------- resources/qml/Preferences/ProfilesPage.qml | 55 ++++++++++++++++++- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index cf7a163d9c..6e5b37bbfa 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSlot from UM.Qt.ListModel import ListModel @@ -74,3 +74,45 @@ class QualityManagementModel(ListModel): item_list += quality_changes_item_list self.setItems(item_list) + + # TODO: Duplicated code here from InstanceContainersModel. Refactor and remove this later. + # + ## Gets a list of the possible file filters that the plugins have + # registered they can read or write. The convenience meta-filters + # "All Supported Types" and "All Files" are added when listing + # readers, but not when listing writers. + # + # \param io_type \type{str} name of the needed IO type + # \return A list of strings indicating file name filters for a file + # dialog. + @pyqtSlot(str, result = "QVariantList") + def getFileNameFilters(self, io_type): + from UM.i18n import i18nCatalog + catalog = i18nCatalog("uranium") + #TODO: This function should be in UM.Resources! + filters = [] + all_types = [] + for plugin_id, meta_data in self._getIOPlugins(io_type): + for io_plugin in meta_data[io_type]: + filters.append(io_plugin["description"] + " (*." + io_plugin["extension"] + ")") + all_types.append("*.{0}".format(io_plugin["extension"])) + + if "_reader" in io_type: + # if we're listing readers, add the option to show all supported files as the default option + filters.insert(0, catalog.i18nc("@item:inlistbox", "All Supported Types ({0})", " ".join(all_types))) + filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) # Also allow arbitrary files, if the user so prefers. + return filters + + ## Gets a list of profile reader or writer plugins + # \return List of tuples of (plugin_id, meta_data). + def _getIOPlugins(self, io_type): + from UM.PluginRegistry import PluginRegistry + pr = PluginRegistry.getInstance() + active_plugin_ids = pr.getActivePlugins() + + result = [] + for plugin_id in active_plugin_ids: + meta_data = pr.getMetaData(plugin_id) + if io_type in meta_data: + result.append( (plugin_id, meta_data) ) + return result diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index af4924b8b3..6eb9aa0311 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -171,18 +171,6 @@ class ContainerManager(QObject): material_group = self._material_manager.getMaterialGroup(root_material_id) material_group.root_material_node.getContainer().setName(new_name) - ## Find instance containers matching certain criteria. - # - # This effectively forwards to - # ContainerRegistry::findInstanceContainersMetadata. - # - # \param criteria A dict of key - value pairs to search for. - # - # \return A list of container IDs that match the given criteria. - @pyqtSlot("QVariantMap", result = "QVariantList") - def findInstanceContainers(self, criteria): - return [entry["id"] for entry in self._container_registry.findInstanceContainersMetadata(**criteria)] - @pyqtSlot(str, result = str) def makeUniqueName(self, original_name): return self._container_registry.uniqueName(original_name) @@ -716,11 +704,13 @@ class ContainerManager(QObject): return return self._container_registry.importProfile(path) - @pyqtSlot("QVariantList", QUrl, str) - def exportProfile(self, instance_id: str, file_url: QUrl, file_type: str) -> None: + @pyqtSlot(QObject, QUrl, str) + def exportQualityChangesGroup(self, quality_changes_group, file_url: QUrl, file_type: str): if not file_url.isValid(): return path = file_url.toLocalFile() if not path: return - self._container_registry.exportProfile(instance_id, path, file_type) + + container_list = [n.getContainer() for n in quality_changes_group.getAllNodes()] + self._container_registry.exportQualityProfile(container_list, path, file_type) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 29ee5c4b95..7103167b9c 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -103,7 +103,7 @@ class CuraContainerRegistry(ContainerRegistry): # \param instance_ids \type{list} the IDs of the profiles to export. # \param file_name \type{str} the full path and filename to export to. # \param file_type \type{str} the file type with the format " (*.)" - def exportProfile(self, instance_ids, file_name, file_type): + def exportQualityProfile(self, container_list, file_name, file_type): # Parse the fileType to deduce what plugin can save the file format. # fileType has the format " (*.)" split = file_type.rfind(" (*.") # Find where the description ends and the extension starts. @@ -122,31 +122,10 @@ class CuraContainerRegistry(ContainerRegistry): catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name)) if result == QMessageBox.No: return - found_containers = [] - extruder_positions = [] - for instance_id in instance_ids: - containers = ContainerRegistry.getInstance().findInstanceContainers(id = instance_id) - if containers: - found_containers.append(containers[0]) - - # Determine the position of the extruder of this container - extruder_id = containers[0].getMetaDataEntry("extruder", "") - if extruder_id == "": - # Global stack - extruder_positions.append(-1) - else: - extruder_containers = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = extruder_id) - if extruder_containers: - extruder_positions.append(int(extruder_containers[0].get("position", 0))) - else: - extruder_positions.append(0) - # Ensure the profiles are always exported in order (global, extruder 0, extruder 1, ...) - found_containers = [containers for (positions, containers) in sorted(zip(extruder_positions, found_containers))] profile_writer = self._findProfileWriter(extension, description) - try: - success = profile_writer.write(file_name, found_containers) + success = profile_writer.write(file_name, container_list) except Exception as e: Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e)) m = Message(catalog.i18nc("@info:status Don't translate the XML tags or !", "Failed to export profile to {0}: {1}", file_name, str(e)), diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 57ec7a1222..ce8bd7dd3c 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -138,7 +138,7 @@ Item text: catalog.i18nc("@action:button", "Import") iconName: "document-import" onClicked: { - // TODO + importDialog.open(); } } @@ -149,7 +149,7 @@ Item iconName: "document-export" enabled: base.hasCurrentItem && !base.currentItem.is_read_only onClicked: { - // TODO + exportDialog.open(); } } } @@ -212,6 +212,57 @@ Item } } + // Dialog for importing a quality profile + FileDialog + { + id: importDialog + title: catalog.i18nc("@title:window", "Import Profile") + selectExisting: true + nameFilters: qualitiesModel.getFileNameFilters("profile_reader") // TODO: make this easier + folder: CuraApplication.getDefaultPath("dialog_profile_path") + onAccepted: + { + var result = Cura.ContainerManager.importProfile(fileUrl); + messageDialog.text = result.message; + if (result.status == "ok") { + messageDialog.icon = StandardIcon.Information; + } + else if (result.status == "duplicate") { + messageDialog.icon = StandardIcon.Warning; + } + else { + messageDialog.icon = StandardIcon.Critical; + } + messageDialog.open(); + CuraApplication.setDefaultPath("dialog_profile_path", folder); + } + } + + // Dialog for exporting a quality profile + FileDialog + { + id: exportDialog + title: catalog.i18nc("@title:window", "Export Profile") + selectExisting: false + nameFilters: qualitiesModel.getFileNameFilters("profile_writer") // TODO: make this easier + folder: CuraApplication.getDefaultPath("dialog_profile_path") + onAccepted: + { + // TODO: make this easier + var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group, + fileUrl, selectedNameFilter); + + if (result && result.status == "error") { + messageDialog.icon = StandardIcon.Critical; + messageDialog.text = result.message; + messageDialog.open(); + } + + // else pop-up Message thing from python code + CuraApplication.setDefaultPath("dialog_profile_path", folder); + } + } + Item { id: contentsItem From 62c31c2f6ce84edcf7565d20e1aca8add9295e03 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 19 Feb 2018 22:11:47 +0100 Subject: [PATCH 084/266] WIP: Remove old QualityManager --- cura/Machines/QualityManager.py | 24 ++ cura/QualityManager.py | 296 -------------------- cura/Settings/CuraContainerRegistry.py | 37 +-- cura/Settings/MachineManager.py | 2 - plugins/3MFReader/ThreeMFWorkspaceReader.py | 10 +- 5 files changed, 34 insertions(+), 335 deletions(-) delete mode 100644 cura/QualityManager.py diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index a5457344f1..f7ca84e83d 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -360,3 +360,27 @@ class QualityManager(QObject): self._updateQualityGroupsAvailability(machine, quality_group_dict.values()) return quality_group_dict + + def getQualityGroupsForMachineDefinition(self, machine: str) -> dict: + # Get machine definition ID for quality search + machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) + + # To find the quality container for the GlobalStack, check in the following fall-back manner: + # (1) the machine-specific node + # (2) the generic node + machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id) + default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get( + self._default_machine_definition_id) + nodes_to_check = [machine_node, default_machine_node] + + # Iterate over all quality_types in the machine node + quality_group_dict = dict() + for node in nodes_to_check: + if node and node.quality_type_map: + for quality_type, quality_node in node.quality_type_map.items(): + quality_group = QualityGroup(quality_node.metadata["name"], quality_type) + quality_group.node_for_global = quality_node + quality_group_dict[quality_type] = quality_group + break + + return quality_group_dict diff --git a/cura/QualityManager.py b/cura/QualityManager.py deleted file mode 100644 index 358bf4e422..0000000000 --- a/cura/QualityManager.py +++ /dev/null @@ -1,296 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -# This collects a lot of quality and quality changes related code which was split between ContainerManager -# and the MachineManager and really needs to usable from both. -from typing import Any, Dict, List, Optional, TYPE_CHECKING - -from UM.Application import Application -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer -from cura.Settings.ExtruderManager import ExtruderManager - -if TYPE_CHECKING: - from cura.Settings.GlobalStack import GlobalStack - from cura.Settings.ExtruderStack import ExtruderStack - from UM.Settings.DefinitionContainer import DefinitionContainerInterface - -class QualityManager: - - ## Get the singleton instance for this class. - @classmethod - def getInstance(cls) -> "QualityManager": - # Note: Explicit use of class name to prevent issues with inheritance. - if not QualityManager.__instance: - QualityManager.__instance = cls() - return QualityManager.__instance - - __instance = None # type: "QualityManager" - - ## Fetch the list of available quality types for this combination of machine definition and materials. - # - # \param machine_definition \type{DefinitionContainer} - # \param material_containers \type{List[InstanceContainer]} - # \return \type{List[str]} - def findAllQualityTypesForMachineAndMaterials(self, machine_definition: "DefinitionContainerInterface", material_containers: List[InstanceContainer]) -> List[str]: - # Determine the common set of quality types which can be - # applied to all of the materials for this machine. - quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0]) - common_quality_types = set(quality_type_dict.keys()) - for material_container in material_containers[1:]: - next_quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_container) - common_quality_types.intersection_update(set(next_quality_type_dict.keys())) - - return list(common_quality_types) - - def findAllQualitiesForMachineAndMaterials(self, machine_definition: "DefinitionContainerInterface", material_containers: List[InstanceContainer]) -> List[InstanceContainer]: - # Determine the common set of quality types which can be - # applied to all of the materials for this machine. - quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0]) - qualities = set(quality_type_dict.values()) - for material_container in material_containers[1:]: - next_quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_container) - qualities.intersection_update(set(next_quality_type_dict.values())) - - return list(qualities) - - ## Fetches a dict of quality types names to quality profiles for a combination of machine and material. - # - # \param machine_definition \type{DefinitionContainer} the machine definition. - # \param material \type{InstanceContainer} the material. - # \return \type{Dict[str, InstanceContainer]} the dict of suitable quality type names mapping to qualities. - def __fetchQualityTypeDictForMaterial(self, machine_definition: "DefinitionContainerInterface", material: InstanceContainer) -> Dict[str, InstanceContainer]: - qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material) - quality_type_dict = {} - for quality in qualities: - quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality - return quality_type_dict - - ## Find a quality container by quality type. - # - # \param quality_type \type{str} the name of the quality type to search for. - # \param machine_definition (Optional) \type{InstanceContainer} If nothing is - # specified then the currently selected machine definition is used. - # \param material_containers_metadata If nothing is specified then the - # current set of selected materials is used. - # \return the matching quality container \type{InstanceContainer} - def findQualityByQualityType(self, quality_type: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs) -> InstanceContainer: - criteria = kwargs - criteria["type"] = "quality" - if quality_type: - criteria["quality_type"] = quality_type - result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria) - # Fall back to using generic materials and qualities if nothing could be found. - if not result and material_containers_metadata and len(material_containers_metadata) == 1: - basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0]) - if basic_materials: - result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - return result[0] if result else None - - ## Find all suitable qualities for a combination of machine and material. - # - # \param machine_definition \type{DefinitionContainer} the machine definition. - # \param material_container \type{InstanceContainer} the material. - # \return \type{List[InstanceContainer]} the list of suitable qualities. - def findAllQualitiesForMachineMaterial(self, machine_definition: "DefinitionContainerInterface", material_container: InstanceContainer) -> List[InstanceContainer]: - criteria = {"type": "quality"} - result = self._getFilteredContainersForStack(machine_definition, [material_container.getMetaData()], **criteria) - if not result: - basic_materials = self._getBasicMaterialMetadatas(material_container.getMetaData()) - if basic_materials: - result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - - return result - - ## Find all quality changes for a machine. - # - # \param machine_definition \type{DefinitionContainer} the machine definition. - # \return \type{List[InstanceContainer]} the list of quality changes - def findAllQualityChangesForMachine(self, machine_definition: "DefinitionContainerInterface") -> List[InstanceContainer]: - if machine_definition.getMetaDataEntry("has_machine_quality"): - definition_id = machine_definition.getId() - else: - definition_id = "fdmprinter" - - filter_dict = { "type": "quality_changes", "definition": definition_id } - quality_changes_list = ContainerRegistry.getInstance().findInstanceContainers(**filter_dict) - return quality_changes_list - - def findAllExtruderDefinitionsForMachine(self, machine_definition: "DefinitionContainerInterface") -> List["DefinitionContainerInterface"]: - filter_dict = { "machine": machine_definition.getId() } - return ContainerRegistry.getInstance().findDefinitionContainers(**filter_dict) - - ## Find all quality changes for a given extruder. - # - # \param extruder_definition The extruder to find the quality changes for. - # \return The list of quality changes for the given extruder. - def findAllQualityChangesForExtruder(self, extruder_definition: "DefinitionContainerInterface") -> List[InstanceContainer]: - filter_dict = {"type": "quality_changes", "extruder": extruder_definition.getId()} - return ContainerRegistry.getInstance().findInstanceContainers(**filter_dict) - - ## Find all usable qualities for a machine and extruders. - # - # Finds all of the qualities for this combination of machine and extruders. - # Only one quality per quality type is returned. i.e. if there are 2 qualities with quality_type=normal - # then only one of then is returned (at random). - # - # \param global_container_stack \type{GlobalStack} the global machine definition - # \param extruder_stacks \type{List[ExtruderStack]} the list of extruder stacks - # \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles - # return come from the first extruder in the given list of extruders. - def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack: "GlobalStack", extruder_stacks: List["ExtruderStack"]) -> List[InstanceContainer]: - global_machine_definition = global_container_stack.getBottom() - - machine_manager = Application.getInstance().getMachineManager() - active_stack_id = machine_manager.activeStackId - - materials = [] - - for stack in extruder_stacks: - if stack.getId() == active_stack_id and machine_manager.newMaterial: - materials.append(machine_manager.newMaterial) - else: - materials.append(stack.material) - - quality_types = self.findAllQualityTypesForMachineAndMaterials(global_machine_definition, materials) - - # Map the list of quality_types to InstanceContainers - qualities = self.findAllQualitiesForMachineMaterial(global_machine_definition, materials[0]) - quality_type_dict = {} - for quality in qualities: - quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality - - return [quality_type_dict[quality_type] for quality_type in quality_types] - - ## Fetch more basic versions of a material. - # - # This tries to find a generic or basic version of the given material. - # \param material_container \type{Dict[str, Any]} The metadata of a - # material to find the basic versions of. - # \return \type{List[Dict[str, Any]]} A list of the metadata of basic - # materials, or an empty list if none could be found. - def _getBasicMaterialMetadatas(self, material_container: Dict[str, Any]) -> List[Dict[str, Any]]: - if "definition" not in material_container: - definition_id = "fdmprinter" - else: - material_container_definition = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = material_container["definition"]) - if not material_container_definition: - definition_id = "fdmprinter" - else: - material_container_definition = material_container_definition[0] - if "has_machine_quality" not in material_container_definition: - definition_id = "fdmprinter" - else: - definition_id = material_container_definition.get("quality_definition", material_container_definition["id"]) - - base_material = material_container.get("material") - if base_material: - # There is a basic material specified - criteria = { - "type": "material", - "name": base_material, - "definition": definition_id, - "variant": material_container.get("variant") - } - containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(**criteria) - return containers - - return [] - - def _getFilteredContainers(self, **kwargs): - return self._getFilteredContainersForStack(None, None, **kwargs) - - def _getFilteredContainersForStack(self, machine_definition: "DefinitionContainerInterface" = None, material_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs): - # Fill in any default values. - if machine_definition is None: - machine_definition = Application.getInstance().getGlobalContainerStack().getBottom() - quality_definition_id = machine_definition.getMetaDataEntry("quality_definition") - if quality_definition_id is not None: - machine_definition = ContainerRegistry.getInstance().findDefinitionContainers(id = quality_definition_id)[0] - - if not material_metadata: - active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() - if active_stacks: - material_metadata = [stack.material.getMetaData() for stack in active_stacks] - - criteria = kwargs - filter_by_material = False - - machine_definition = self.getParentMachineDefinition(machine_definition) - criteria["definition"] = machine_definition.getId() - found_containers_with_machine_definition = ContainerRegistry.getInstance().findInstanceContainersMetadata(**criteria) - whole_machine_definition = self.getWholeMachineDefinition(machine_definition) - if whole_machine_definition.getMetaDataEntry("has_machine_quality"): - definition_id = machine_definition.getMetaDataEntry("quality_definition", whole_machine_definition.getId()) - criteria["definition"] = definition_id - - filter_by_material = whole_machine_definition.getMetaDataEntry("has_materials") - # only fall back to "fdmprinter" when there is no container for this machine - elif not found_containers_with_machine_definition: - criteria["definition"] = "fdmprinter" - - # Stick the material IDs in a set - material_ids = set() - - for material_instance in material_metadata: - if material_instance is not None: - # Add the parent material too. - for basic_material in self._getBasicMaterialMetadatas(material_instance): - material_ids.add(basic_material["id"]) - material_ids.add(material_instance["id"]) - containers = ContainerRegistry.getInstance().findInstanceContainers(**criteria) - - result = [] - for container in containers: - # If the machine specifies we should filter by material, exclude containers that do not match any active material. - if filter_by_material and container.getMetaDataEntry("material") not in material_ids and "global_quality" not in kwargs: - continue - result.append(container) - - return result - - ## Get the parent machine definition of a machine definition. - # - # \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or - # an extruder definition. - # \return \type{DefinitionContainer} the parent machine definition. If the given machine - # definition doesn't have a parent then it is simply returned. - def getParentMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface": - container_registry = ContainerRegistry.getInstance() - - machine_entry = machine_definition.getMetaDataEntry("machine") - if machine_entry is None: - # We have a normal (whole) machine defintion - quality_definition = machine_definition.getMetaDataEntry("quality_definition") - if quality_definition is not None: - parent_machine_definition = container_registry.findDefinitionContainers(id = quality_definition)[0] - return self.getParentMachineDefinition(parent_machine_definition) - else: - return machine_definition - else: - # This looks like an extruder. Find the rest of the machine. - whole_machine = container_registry.findDefinitionContainers(id = machine_entry)[0] - parent_machine = self.getParentMachineDefinition(whole_machine) - if whole_machine is parent_machine: - # This extruder already belongs to a 'parent' machine def. - return machine_definition - else: - # Look up the corresponding extruder definition in the parent machine definition. - extruder_position = machine_definition.getMetaDataEntry("position") - parent_extruder_id = parent_machine.getMetaDataEntry("machine_extruder_trains")[extruder_position] - return container_registry.findDefinitionContainers(id = parent_extruder_id)[0] - - ## Get the whole/global machine definition from an extruder definition. - # - # \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or - # an extruder definition. - # \return \type{DefinitionContainerInterface} - def getWholeMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface": - machine_entry = machine_definition.getMetaDataEntry("machine") - if machine_entry is None: - # This already is a 'global' machine definition. - return machine_definition - else: - container_registry = ContainerRegistry.getInstance() - whole_machine = container_registry.findDefinitionContainers(id = machine_entry)[0] - return whole_machine diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 7103167b9c..329fbe77b7 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -335,41 +335,16 @@ class CuraContainerRegistry(ContainerRegistry): return catalog.i18nc("@info:status", "Profile is missing a quality type.") quality_type_criteria = {"quality_type": quality_type} - if self._machineHasOwnQualities(): - global_container_stack = Application.getInstance().getGlobalContainerStack() - definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack) - profile.setDefinition(definition_id) - if self._machineHasOwnMaterials(): - active_material_id = self._activeMaterialId() - if active_material_id and active_material_id != "empty": # only update if there is an active material - profile.addMetaDataEntry("material", active_material_id) - quality_type_criteria["material"] = active_material_id - - quality_type_criteria["definition"] = profile.getDefinition().getId() - - else: - profile.setDefinition("fdmprinter") - quality_type_criteria["definition"] = "fdmprinter" - - machine_definition = Application.getInstance().getGlobalContainerStack().getBottom() - del quality_type_criteria["definition"] - - # materials = None - - if "material" in quality_type_criteria: - # materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"]) - del quality_type_criteria["material"] - - # Do not filter quality containers here with materials because we are trying to import a profile, so it should - # NOT be restricted by the active materials on the current machine. - materials = None + global_stack = Application.getInstance().getGlobalContainerStack() + definition_id = getMachineDefinitionIDForQualitySearch(global_stack) + profile.setDefinition(definition_id) # Check to make sure the imported profile actually makes sense in context of the current configuration. # This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as # successfully imported but then fail to show up. - from cura.QualityManager import QualityManager - qualities = QualityManager.getInstance()._getFilteredContainersForStack(machine_definition, materials, **quality_type_criteria) - if not qualities: + quality_manager = CuraApplication.getInstance()._quality_manager + quality_group_dict = quality_manager.getQualityGroupsForMachineDefinition(global_stack) + if quality_type not in quality_group_dict: return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type) ContainerRegistry.getInstance().addContainer(profile) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3ff5cb1011..7be3f0798e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -26,7 +26,6 @@ from UM.Signal import postponeSignals, CompressTechnique from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch -from cura.QualityManager import QualityManager from cura.PrinterOutputDevice import PrinterOutputDevice from cura.Settings.ExtruderManager import ExtruderManager @@ -36,7 +35,6 @@ from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") if TYPE_CHECKING: - from UM.Settings.DefinitionContainer import DefinitionContainer from cura.Settings.CuraContainerStack import CuraContainerStack from cura.Settings.GlobalStack import GlobalStack diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 8291ca3b52..d584a0efd6 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -23,7 +23,6 @@ from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderStack import ExtruderStack from cura.Settings.GlobalStack import GlobalStack from cura.Settings.CuraContainerStack import _ContainerIndexes -from cura.QualityManager import QualityManager from cura.CuraApplication import CuraApplication from configparser import ConfigParser @@ -858,10 +857,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if machine_extruder_count is not None: extruder_stacks_in_use = extruder_stacks[:machine_extruder_count] - available_quality = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_stack, - extruder_stacks_in_use) + quality_manager = CuraApplication.getInstance()._quality_manager + all_quality_groups = quality_manager.getQualityGroups(global_stack) + available_quality_types = [qt for qt, qg in all_quality_groups.items() if qg.is_available] if not has_not_supported: - has_not_supported = not available_quality + has_not_supported = not available_quality_types quality_has_been_changed = False @@ -875,8 +875,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # The machine in the project has non-empty quality and there are usable qualities for this machine. # We need to check if the current quality_type is still usable for this machine, if not, then the quality # will be reset to the "preferred quality" if present, otherwise "normal". - available_quality_types = [q.getMetaDataEntry("quality_type") for q in available_quality] - if global_stack.quality.getMetaDataEntry("quality_type") not in available_quality_types: # We are here because the quality_type specified in the project is not supported any more, # so we need to switch it to the "preferred quality" if present, otherwise "normal". From 6cc65e97f202c1b982b0836ef9ba7eda32be90dd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 20 Feb 2018 09:13:11 +0100 Subject: [PATCH 085/266] WIP: Cleanup MaterialsModel --- cura/CuraApplication.py | 5 ++- .../Models}/MaterialsModel.py | 34 +------------------ resources/qml/Preferences/MaterialsPage.qml | 2 +- 3 files changed, 4 insertions(+), 37 deletions(-) rename cura/{Settings => Machines/Models}/MaterialsModel.py (88%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 795c254d8c..41f5fbc4b2 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -60,7 +60,7 @@ from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfile from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel -from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel +from cura.Machines.Models.MaterialsModel import BrandMaterialsModel, GenericMaterialsModel, MaterialsModel from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager @@ -944,7 +944,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") - qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel") + qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") # TODO: make this singleton? qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") @@ -953,7 +953,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(CustomQualityProfilesModel, "Cura", 1, 0, "CustomQualityProfilesModel", self.getCustomQualityProfilesModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") - qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") diff --git a/cura/Settings/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py similarity index 88% rename from cura/Settings/MaterialsModel.py rename to cura/Machines/Models/MaterialsModel.py index 72b39a90aa..7d390277d6 100644 --- a/cura/Settings/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -189,7 +189,7 @@ class BrandMaterialsModel(ListModel): # # This model is for the Material management page. # -class NewMaterialsModel(ListModel): +class MaterialsModel(ListModel): RootMaterialIdRole = Qt.UserRole + 1 DisplayNameRole = Qt.UserRole + 2 BrandRole = Qt.UserRole + 3 @@ -272,35 +272,3 @@ class NewMaterialsModel(ListModel): material_list = sorted(material_list, key = lambda k: (k["brand"], k["name"])) self.setItems(material_list) - - -## A model that shows a list of currently valid materials. Used by management page. -class MaterialsModel(InstanceContainersModel): - def __init__(self, parent = None): - super().__init__(parent) - - ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerMetaDataChanged) - - ## Called when the metadata of the container was changed. - # - # This makes sure that we only update when it was a material that changed. - # - # \param container The container whose metadata was changed. - def _onContainerMetaDataChanged(self, container): - if container.getMetaDataEntry("type") == "material": #Only need to update if a material was changed. - self._container_change_timer.start() - - def _onContainerChanged(self, container): - if container.getMetaDataEntry("type", "") == "material": - super()._onContainerChanged(container) - - ## Group brand together - def _sortKey(self, item) -> List[Any]: - result = [] - result.append(item["metadata"]["brand"]) - result.append(item["metadata"]["material"]) - result.append(item["metadata"]["name"]) - result.append(item["metadata"]["color_name"]) - result.append(item["metadata"]["id"]) - result.extend(super()._sortKey(item)) - return result diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 4eddc45d76..8d14ada759 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -17,7 +17,7 @@ Item UM.I18nCatalog { id: catalog; name: "cura"; } - Cura.NewMaterialsModel { + Cura.MaterialsModel { id: materialsModel } From 21c475344306726cc365022f9f3bf355578226e0 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 09:54:22 +0100 Subject: [PATCH 086/266] CURA-4606 fallback value for layer height must come from definition --- cura/Machines/Models/QualityProfilesModel.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index b30daa85f6..88a999b6ad 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -90,9 +90,7 @@ class QualityProfilesModel(ListModel): layer_height = str(container.getProperty("layer_height", "value")) else: # Look for layer_height in the GlobalStack from material -> definition - for idx in range(4): - container = active_global_stack.getContainer(idx) - if container.hasProperty("layer_height", "value"): - layer_height = container.getProperty("layer_height", "value") - break + container = active_global_stack.definition + if container.hasProperty("layer_height", "value"): + layer_height = container.getProperty("layer_height", "value") return str(layer_height) From c432d4ffbbb8cbcbf38e040a3161e6c21106ae8d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 20 Feb 2018 11:16:32 +0100 Subject: [PATCH 087/266] WIP: Simplify global stack and extruder stack activation and fixes --- cura/Settings/CuraStackBuilder.py | 5 +++-- cura/Settings/ExtruderManager.py | 13 ++----------- cura/Settings/ExtruderStack.py | 3 +-- cura/Settings/MachineManager.py | 6 ++++-- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 - resources/qml/Menus/NozzleMenu.qml | 7 ++++--- 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index c396a4a2be..f5e08b766a 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -102,6 +102,7 @@ class CuraStackBuilder: variant_container = variant_container, material_container = material_container, quality_container = application.empty_quality_container, + global_stack = new_global_stack, ) new_extruder.setNextStack(new_global_stack) new_global_stack.addExtruder(new_extruder) @@ -133,11 +134,11 @@ class CuraStackBuilder: @classmethod def createExtruderStack(cls, new_stack_id: str, extruder_definition: DefinitionContainerInterface, machine_definition_id: str, position: int, - variant_container, material_container, quality_container) -> ExtruderStack: + variant_container, material_container, quality_container, global_stack) -> ExtruderStack: from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() - stack = ExtruderStack(new_stack_id) + stack = ExtruderStack(new_stack_id, parent = global_stack) stack.setName(extruder_definition.getName()) stack.setDefinition(extruder_definition) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 35b5b1320b..56834ca32a 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -36,22 +36,15 @@ class ExtruderManager(QObject): self._global_container_stack_definition_id = None self._addCurrentMachineExtruders() - Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged) + #Application.getInstance().globalContainerStackChanged.connect(self._globalContainerStackChanged) Selection.selectionChanged.connect(self.resetSelectedObjectExtruders) ## Signal to notify other components when the list of extruders for a machine definition changes. extrudersChanged = pyqtSignal(QVariant) - ## Signal to notify other components when the global container stack is switched to a definition - # that has different extruders than the previous global container stack - globalContainerStackDefinitionChanged = pyqtSignal() - ## Notify when the user switches the currently active extruder. activeExtruderChanged = pyqtSignal() - ## The signal notifies subscribers if extruders are added - extrudersAdded = pyqtSignal() - ## Gets the unique identifier of the currently active extruder stack. # # The currently active extruder stack is the stack that is currently being @@ -371,11 +364,10 @@ class ExtruderManager(QObject): return result[:machine_extruder_count] - def __globalContainerStackChanged(self) -> None: + def _globalContainerStackChanged(self) -> None: global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack and global_container_stack.getBottom() and global_container_stack.getBottom().getId() != self._global_container_stack_definition_id: self._global_container_stack_definition_id = global_container_stack.getBottom().getId() - self.globalContainerStackDefinitionChanged.emit() # If the global container changed, the machine changed and might have extruders that were not registered yet self._addCurrentMachineExtruders() @@ -415,7 +407,6 @@ class ExtruderManager(QObject): if extruders_changed: self.extrudersChanged.emit(global_stack_id) - self.extrudersAdded.emit() self.setActiveExtruderIndex(0) ## Get all extruder values for a certain setting. diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index a2ff092143..5a3ac85d75 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -3,7 +3,6 @@ from typing import Any, TYPE_CHECKING, Optional -from UM.Application import Application from UM.Decorators import override from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.Settings.ContainerStack import ContainerStack @@ -34,7 +33,7 @@ class ExtruderStack(CuraContainerStack): # # This will set the next stack and ensure that we register this stack as an extruder. @override(ContainerStack) - def setNextStack(self, stack: ContainerStack) -> None: + def setNextStack(self, stack: CuraContainerStack) -> None: super().setNextStack(stack) stack.addExtruder(self) self.addMetaDataEntry("machine", stack.id) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7be3f0798e..45c7648916 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -283,6 +283,7 @@ class MachineManager(QObject): containers = container_registry.findContainerStacks(id = stack_id) if containers: Application.getInstance().setGlobalContainerStack(containers[0]) + ExtruderManager.getInstance()._globalContainerStackChanged() self.__emitChangedSignals() @@ -877,9 +878,10 @@ class MachineManager(QObject): @pyqtSlot(int, result = QObject) def getExtruder(self, position: int): + extruder = None if self._global_container_stack: - return self._global_container_stack.extruders.get(str(position)) - return None + extruder = self._global_container_stack.extruders.get(str(position)) + return extruder def _onMachineNameChanged(self): self.globalContainerChanged.emit() diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index cd4f74141b..ea3ac3c0f8 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -88,7 +88,6 @@ class CuraEngineBackend(QObject, Backend): # self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) - Application.getInstance().getExtruderManager().extrudersAdded.connect(self._onGlobalStackChanged) self._onGlobalStackChanged() Application.getInstance().stacksValidationFinished.connect(self._onStackErrorCheckFinished) diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index ea1c0000f4..153bd88220 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -13,7 +13,8 @@ Menu title: "Nozzle" property int extruderIndex: 0 - property var extruderStack: Cura.MachineManager.getExtruder(menu.extruderIndex) + property QtObject extruderStack: Cura.MachineManager.getExtruder(menu.extruderIndex) + property bool hasExtruderStack: extruderStack != null Cura.NozzleModel { @@ -24,7 +25,7 @@ Menu { target: Cura.MachineManager onGlobalContainerChanged: { - menu.extruderStack = Cura.MachineManager.getExtruder(extruderIndex); + menu.extruderStack = Cura.MachineManager.getExtruder(menu.extruderIndex); } } @@ -36,7 +37,7 @@ Menu { text: model.hotend_name checkable: true - checked: extruderStack.variant.name == model.hotend_name + checked: menu.hasExtruderStack && extruderStack.variant.name == model.hotend_name exclusiveGroup: group onTriggered: { Cura.MachineManager.setVariantGroup(extruderIndex, model.container_node); From fa37a48caae47ff0777fbcf747f153ce8d19ec52 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 20 Feb 2018 11:25:42 +0100 Subject: [PATCH 088/266] WIP: Fix default buildplate lookup --- cura/Settings/CuraStackBuilder.py | 43 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index f5e08b766a..0348d6855f 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -1,16 +1,17 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.Logger import Logger +from typing import Optional +from UM.Logger import Logger from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Util import parseBool +from cura.Machines.VariantManager import VariantType from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack -from typing import Optional ## Contains helper functions to create new machines. @@ -37,18 +38,32 @@ class CuraStackBuilder: machine_definition = definitions[0] + # get variant container for the global stack + global_variant_container = application.empty_variant_container + if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)): + global_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name") + if global_variant_name: + variant_node = variant_manager.getVariantNode(definition_id, global_variant_name, + variant_type = VariantType.BUILD_PLATE) + if variant_node is None: + raise RuntimeError("Cannot find buildplate variant with definition [%s] and variant name [%s]" % + (definition_id, global_variant_name)) + global_variant_container = variant_node.getContainer() + + # get variant container for extruders - variant_container = application.empty_variant_container + extruder_variant_container = application.empty_variant_container # Only look for the preferred variant if this machine has variants - variant_name = None + extruder_variant_name = None if parseBool(machine_definition.getMetaDataEntry("has_variants", False)): - variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") - if variant_name: - variant_node = variant_manager.getVariantNode(definition_id, variant_name) + extruder_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") + if extruder_variant_name: + variant_node = variant_manager.getVariantNode(definition_id, extruder_variant_name) # Sanity check. If you see this error, the related definition files should be fixed. if variant_node is None: - raise RuntimeError("Cannot find variant with definition [%s] and variant name [%s]" % (definition_id, variant_name)) - variant_container = variant_node.getContainer() + raise RuntimeError("Cannot find extruder variant with definition [%s] and variant name [%s]" % + (definition_id, extruder_variant_name)) + extruder_variant_container = variant_node.getContainer() # get material container for extruders material_container = application.empty_material_container @@ -58,11 +73,11 @@ class CuraStackBuilder: approximate_material_diameter = str(round(material_diameter)) root_material_id = machine_definition.getMetaDataEntry("preferred_material") root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) - material_node = material_manager.getMaterialNode(definition_id, variant_name, material_diameter, root_material_id) + material_node = material_manager.getMaterialNode(definition_id, extruder_variant_name, material_diameter, root_material_id) # Sanity check. If you see this error, the related definition files should be fixed. if not material_node: - raise RuntimeError("Cannot find material with definition [%s], variant_name [%s], and root_material_id [%s]" % - (definition_id, variant_name, root_material_id)) + raise RuntimeError("Cannot find material with definition [%s], extruder_variant_name [%s], and root_material_id [%s]" % + (definition_id, extruder_variant_name, root_material_id)) material_container = material_node.getContainer() generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) @@ -75,7 +90,7 @@ class CuraStackBuilder: new_global_stack = cls.createGlobalStack( new_stack_id = generated_name, definition = machine_definition, - variant_container = application.empty_variant_container, # TODO: fix for build plate + variant_container = global_variant_container, material_container = application.empty_material_container, quality_container = application.empty_quality_container, ) @@ -99,7 +114,7 @@ class CuraStackBuilder: extruder_definition = extruder_definition, machine_definition_id = definition_id, position = position, - variant_container = variant_container, + variant_container = extruder_variant_container, material_container = material_container, quality_container = application.empty_quality_container, global_stack = new_global_stack, From 605043235a620b6d3530eded0320e6223e78015b Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 11:36:51 +0100 Subject: [PATCH 089/266] CURA-4606 fixed create profile from profile context menu --- resources/qml/Preferences/ProfilesPage.qml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index ce8bd7dd3c..2a6bd9c6f2 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -154,6 +154,15 @@ Item } } + // Click create profile from ... in Profile context menu + signal createProfile() + onCreateProfile: + { + createQualityDialog.object = Cura.ContainerManager.makeUniqueName(Cura.MachineManager.activeQualityOrQualityChangesName); + createQualityDialog.open(); + createQualityDialog.selectText(); + } + // Dialog to request a name when creating a new profile UM.RenameDialog { From c76995c926352e93637cec963ea4d59a45da551e Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 11:39:59 +0100 Subject: [PATCH 090/266] CURA-4606 update quality profiles model with field LayerHeightWithoutUnitRole --- cura/Machines/Models/QualityProfilesModel.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 88a999b6ad..28edf9c888 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -17,9 +17,10 @@ class QualityProfilesModel(ListModel): NameRole = Qt.UserRole + 2 QualityTypeRole = Qt.UserRole + 3 LayerHeightRole = Qt.UserRole + 4 - AvailableRole = Qt.UserRole + 5 - QualityGroupRole = Qt.UserRole + 6 - QualityChangesGroupRole = Qt.UserRole + 7 + LayerHeightWithoutUnitRole = Qt.UserRole + 5 + AvailableRole = Qt.UserRole + 6 + QualityGroupRole = Qt.UserRole + 7 + QualityChangesGroupRole = Qt.UserRole + 8 def __init__(self, parent = None): super().__init__(parent) @@ -28,6 +29,7 @@ class QualityProfilesModel(ListModel): self.addRoleName(self.NameRole, "name") self.addRoleName(self.QualityTypeRole, "quality_type") self.addRoleName(self.LayerHeightRole, "layer_height") + self.addRoleName(self.LayerHeightWithoutUnitRole, "layer_height_without_unit") self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.QualityGroupRole, "quality_group") self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") From 3619f5aef32199269b956d2e2086601f9c3ee9a9 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 11:57:05 +0100 Subject: [PATCH 091/266] CURA-4606 update initial materials menu --- cura/Machines/Models/MaterialsModel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py index 7d390277d6..e79ebe36bc 100644 --- a/cura/Machines/Models/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -74,6 +74,8 @@ class GenericMaterialsModel(BaseMaterialsModel): extruder_manager.activeExtruderChanged.connect(self._update) material_manager.materialsUpdated.connect(self._update) + self._update() + def _update(self): item_list = [] result_dict = getAvailableMaterials() From b2ca8565c985e7d4634aaa0d3ac6fc8a1ff0b34d Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 13:02:39 +0100 Subject: [PATCH 092/266] CURA-4606 fix startup crash --- cura/BuildVolume.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 60e7a32857..6401ad77af 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -936,8 +936,8 @@ class BuildVolume(SceneNode): # stack. # # \return A sequence of setting values, one for each extruder. - def _getSettingFromAllExtruders(self, setting_key, property = "value"): - all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property) + def _getSettingFromAllExtruders(self, setting_key): + all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "value") all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type") for i in range(len(all_values)): if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"): @@ -950,7 +950,7 @@ class BuildVolume(SceneNode): # not part of the collision radius, such as bed adhesion (skirt/brim/raft) # and travel avoid distance. def _getEdgeDisallowedSize(self): - if not self._global_container_stack: + if not self._global_container_stack or not self._global_container_stack.extruders: return 0 container_stack = self._global_container_stack From b9e7ee18a6cc2b12388925f79d2f6db6a2a64774 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 13:06:54 +0100 Subject: [PATCH 093/266] CURA-4606 fixed menu setting nozzle --- resources/qml/Menus/MaterialMenu.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index e77ab2861a..ac398356fd 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -21,12 +21,11 @@ Menu { text: model.name checkable: true - checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[Cura.ExtruderManager.activeExtruderIndex] + checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[extruderIndex] exclusiveGroup: group onTriggered: { - var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; - Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node); + Cura.MachineManager.setMaterial(extruderIndex, model.container_node); } } onObjectAdded: menu.insertItem(index, object) From 9e9d981acd6d444f5bd906c7cfedc839100c60a7 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 15:17:19 +0100 Subject: [PATCH 094/266] CURA-4606 ensure that setting a new machine ends with correct quality (changes) group --- cura/Settings/MachineManager.py | 38 +++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 45c7648916..37fc3add7a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -47,6 +47,10 @@ class MachineManager(QObject): self._active_container_stack = None # type: CuraContainerStack self._global_container_stack = None # type: GlobalStack + self._current_root_material_id = {} + self._current_quality_group = None + self._current_quality_changes_group = None + self.machine_extruder_material_update_dict = collections.defaultdict(list) # Used to store the new containers until after confirming the dialog @@ -65,8 +69,9 @@ class MachineManager(QObject): self._instance_container_timer.setSingleShot(True) self._instance_container_timer.timeout.connect(self.__emitChangedSignals) - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) - Application.getInstance().getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged) + self._application = Application.getInstance() + self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self._application.getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged) ## When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) @@ -123,10 +128,6 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - ### NEW - self._current_root_material_id = {} - self._current_quality_group = None - self._current_quality_changes_group = None ### NEW activeQualityGroupChanged = pyqtSignal() @@ -273,6 +274,30 @@ class MachineManager(QObject): elif property_name == "validationState": self._error_check_timer.start() + ## Given a global_stack, make sure that it's all valid by searching for this quality group and applying it again + def _initMachineState(self, global_stack): + material_dict = {} + for position, extruder in global_stack.extruders.items(): + material_dict[position] = extruder.material.getMetaDataEntry("base_file") + self._current_root_material_id = material_dict + global_quality = global_stack.quality + global_quality_changes = global_stack.qualityChanges + + quality_groups = self._application._quality_manager.getQualityGroups(global_stack) + quality_type = global_quality.getMetaDataEntry("quality_type") + if quality_type in quality_groups: + new_quality_group = quality_groups[quality_type] + else: + new_quality_group = quality_groups.values()[0] + Logger.log("e", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) + self._setQualityGroup(new_quality_group) + + if global_quality_changes.getId() != "empty_quality_changes": + quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack) + if quality_type in quality_changes_groups: + new_quality_changes_group = quality_changes_groups[quality_type] + self._setQualityChangesGroup(new_quality_changes_group) + @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: self.blurSettings.emit() # Ensure no-one has focus. @@ -284,6 +309,7 @@ class MachineManager(QObject): if containers: Application.getInstance().setGlobalContainerStack(containers[0]) ExtruderManager.getInstance()._globalContainerStackChanged() + self._initMachineState(containers[0]) self.__emitChangedSignals() From 4ba7ce0890b43b31c711689b9665bbe70968786a Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 15:26:20 +0100 Subject: [PATCH 095/266] CURA-4606 fix pyqt cleaning up by setting extruder stack parent --- cura/Settings/ExtruderManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 56834ca32a..3bf248970e 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -396,6 +396,7 @@ class ExtruderManager(QObject): self._extruder_trains[global_stack_id][extruder_train.getMetaDataEntry("position")] = extruder_train # regardless of what the next stack is, we have to set it again, because of signal routing. ??? + extruder_train.setParent(global_stack) extruder_train.setNextStack(global_stack) extruders_changed = True From c56b3bc7bd1312507b7725286aff3f3b1c7acca1 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 15:35:17 +0100 Subject: [PATCH 096/266] CURA-4606 add the discard or keep changes screen --- cura/Settings/MachineManager.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 37fc3add7a..c35c8dc004 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1110,8 +1110,13 @@ class MachineManager(QObject): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) + Logger.log("d", "Quality set!") + # See if we need to show the Discard or Keep changes screen + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + Application.getInstance().discardOrKeepProfileChanges() + @pyqtProperty("QVariant", fset = setQualityGroup, notify = activeQualityGroupChanged) def activeQualityGroup(self): return self._current_quality_group From b96d49c0103fa728daeda89108e15174f4c5c9f7 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 20 Feb 2018 16:04:41 +0100 Subject: [PATCH 097/266] CURA-4606 ensure startup order for machine manager before build volume to prevent errors there --- cura/CuraApplication.py | 2 ++ cura/Machines/Models/QualityProfilesModel.py | 2 ++ cura/Settings/MachineManager.py | 25 ++++++++++---------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 41f5fbc4b2..b66bdcb6a8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -754,6 +754,8 @@ class CuraApplication(QtApplication): self._quality_manager = QualityManager(container_registry) self._quality_manager.initialize() + self.getMachineManager() # ensure creation of machine manager + # Check if we should run as single instance or not self._setUpSingleInstanceServer() diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 28edf9c888..034852a101 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -43,6 +43,8 @@ class QualityProfilesModel(ListModel): self._layer_height_unit = "" # This is cached + self._update() + def _update(self): Logger.log("d", "Updating quality profile model ...") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c35c8dc004..3844879081 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -107,18 +107,12 @@ class MachineManager(QObject): self._global_event_keys = set() - active_machine_id = Preferences.getInstance().getValue("cura/active_machine") - self._printer_output_devices = [] Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged) # There might already be some output devices by the time the signal is connected self._onOutputDevicesChanged() - if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id): - # An active machine was saved, so restore it. - self.setActiveMachine(active_machine_id) - # Make sure _active_container_stack is properly initiated - ExtruderManager.getInstance().setActiveExtruderIndex(0) + self._application.callLater(self.setInitialActiveMachine) self._material_incompatible_message = Message(catalog.i18nc("@info:status", "The selected material is incompatible with the selected machine or configuration."), @@ -150,6 +144,14 @@ class MachineManager(QObject): rootMaterialChanged = pyqtSignal() + def setInitialActiveMachine(self): + active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id): + # An active machine was saved, so restore it. + self.setActiveMachine(active_machine_id) + # Make sure _active_container_stack is properly initiated + ExtruderManager.getInstance().setActiveExtruderIndex(0) + def _onOutputDevicesChanged(self) -> None: self._printer_output_devices = [] for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices(): @@ -285,11 +287,10 @@ class MachineManager(QObject): quality_groups = self._application._quality_manager.getQualityGroups(global_stack) quality_type = global_quality.getMetaDataEntry("quality_type") - if quality_type in quality_groups: - new_quality_group = quality_groups[quality_type] - else: - new_quality_group = quality_groups.values()[0] - Logger.log("e", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) + if not quality_type in quality_groups: + Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) + return + new_quality_group = quality_groups[quality_type] self._setQualityGroup(new_quality_group) if global_quality_changes.getId() != "empty_quality_changes": From 8401e1c7f76d3c7ecc72cd4bf55bf9205206b7ce Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 09:13:42 +0100 Subject: [PATCH 098/266] CURA-4606 incompatible material(s) now results in an empty quality list --- cura/Machines/Models/QualityProfilesModel.py | 8 +++++++- cura/Settings/MachineManager.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 034852a101..2f1374cc8b 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -48,12 +48,18 @@ class QualityProfilesModel(ListModel): def _update(self): Logger.log("d", "Updating quality profile model ...") - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + machine_manager = Application.getInstance().getMachineManager() + active_global_stack = machine_manager._global_container_stack if active_global_stack is None: self.setItems([]) Logger.log("d", "No active GlobalStack, set quality profile model as empty.") return + # Check for material compatibility + if not machine_manager.activeMaterialsCompatible(): + self.setItems([]) + return + quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) item_list = [] diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3844879081..5673039497 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1018,6 +1018,13 @@ class MachineManager(QObject): self._current_root_material_id[position] = root_material_id self.rootMaterialChanged.emit() + def activeMaterialsCompatible(self): + # check material - variant compatibility + for position, extruder in self._global_container_stack.extruders.items(): + if not extruder.material.getMetaDataEntry("compatible"): + return False + return True + ## Update current quality type and machine after setting material def _updateQualityWithMaterial(self): current_quality = None @@ -1027,6 +1034,11 @@ class MachineManager(QObject): candidate_quality_groups = quality_manager.getQualityGroups(self._global_container_stack) available_quality_types = {qt for qt, g in candidate_quality_groups.items() if g.is_available} + if not self.activeMaterialsCompatible: + Logger.log("d", "Material [%s] is not compatible, setting empty material." % str(extruder.material)) + self._setEmptyQuality() + return + if not available_quality_types: self._setEmptyQuality() return From f9e2d7fe2cc5813f8b1c954cac6fc37c120849c4 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 09:17:31 +0100 Subject: [PATCH 099/266] CURA-4606 changing current print core now always updates the correct one --- cura/Settings/MachineManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5673039497..c864eaaac5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1003,6 +1003,7 @@ class MachineManager(QObject): def _setVariantNode(self, position, container_node): self._global_container_stack.extruders[position].variant = container_node.getContainer() + self.activeVariantChanged.emit() def _setGlobalVariant(self, container_node): self._global_container_stack.variant = container_node.getContainer() From ad6548a5dc98c0f203089dea8a526faefcafaa55 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 10:35:17 +0100 Subject: [PATCH 100/266] CURA-4606 factored activeMaterialName out --- cura/Settings/MachineManager.py | 32 ++++++++++---------------- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/SidebarHeader.qml | 4 ++-- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c864eaaac5..5a04d498af 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -48,6 +48,7 @@ class MachineManager(QObject): self._global_container_stack = None # type: GlobalStack self._current_root_material_id = {} + self._current_root_material_name = {} self._current_quality_group = None self._current_quality_changes_group = None @@ -445,15 +446,6 @@ class MachineManager(QObject): return "" - @pyqtProperty(str, notify = activeMaterialChanged) - def activeMaterialName(self) -> str: - if self._active_container_stack: - material = self._active_container_stack.material - if material: - return material.getName() - - return "" - @pyqtProperty("QVariantList", notify=activeVariantChanged) def activeVariantNames(self) -> List[str]: result = [] @@ -533,17 +525,6 @@ class MachineManager(QObject): return 0 # No quality profile. - @pyqtProperty(str, notify=activeQualityChanged) - def activeQualityName(self) -> str: - if self._active_container_stack and self._global_container_stack: - quality = self._global_container_stack.qualityChanges - if quality and not isinstance(quality, type(self._empty_quality_changes_container)): - return quality.getName() - quality = self._active_container_stack.quality - if quality: - return quality.getName() - return "" - @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self) -> str: if self._active_container_stack: @@ -935,6 +916,15 @@ class MachineManager(QObject): self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") return self._current_root_material_id + @pyqtProperty("QVariant", notify = rootMaterialChanged) + def currentRootMaterialName(self): + # initial filling the current_root_material_name + for position in self._global_container_stack.extruders: + if position not in self._current_root_material_name: + material = self._global_container_stack.extruders[position].material + self._current_root_material_name[position] = material.getName() + return self._current_root_material_name + def _setEmptyQuality(self): self._current_quality_group = None self._current_quality_changes_group = None @@ -1015,8 +1005,10 @@ class MachineManager(QObject): self._global_container_stack.extruders[position].material = self._empty_material_container # The _current_root_material_id is used in the MaterialMenu to see which material is selected root_material_id = container_node.metadata["base_file"] + root_material_name = container_node.getContainer().getName() if root_material_id != self._current_root_material_id[position]: self._current_root_material_id[position] = root_material_id + self._current_root_material_name[position] = root_material_name self.rootMaterialChanged.emit() def activeMaterialsCompatible(self): diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 47c8b188ad..e03cb4977f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -544,4 +544,4 @@ Item } } } -} \ No newline at end of file +} diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index d43b8d3752..2c99ce2dd3 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -252,8 +252,8 @@ Column { id: materialSelection - text: Cura.MachineManager.activeMaterialName - tooltip: Cura.MachineManager.activeMaterialName + text: Cura.MachineManager.currentRootMaterialName[base.currentExtruderIndex] + tooltip: Cura.MachineManager.currentRootMaterialName[base.currentExtruderIndex] visible: Cura.MachineManager.hasMaterials enabled: !extrudersList.visible || base.currentExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height From 363db9e536d1bc93d2084ddc48b25e03ad972740 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 10:35:48 +0100 Subject: [PATCH 101/266] CURA-4606 no stack checking for errors on active extruder switch --- cura/Settings/MachineManager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5a04d498af..20e453d431 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -250,8 +250,6 @@ class MachineManager(QObject): self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() - self._error_check_timer.start() - if old_active_container_stack != self._active_container_stack: # Many methods and properties related to the active quality actually depend # on _active_container_stack. If it changes, then the properties change. From c3349baf391a112ac5c86b36e75d3be6bf76c759 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 10:36:11 +0100 Subject: [PATCH 102/266] CURA-4606 fix bug concerning activeMaterialsCompatible; factor out activeQualityName --- cura/Settings/MachineManager.py | 5 ++--- resources/qml/Settings/SettingView.qml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 20e453d431..ec024f7b49 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1025,8 +1025,7 @@ class MachineManager(QObject): candidate_quality_groups = quality_manager.getQualityGroups(self._global_container_stack) available_quality_types = {qt for qt, g in candidate_quality_groups.items() if g.is_available} - if not self.activeMaterialsCompatible: - Logger.log("d", "Material [%s] is not compatible, setting empty material." % str(extruder.material)) + if not self.activeMaterialsCompatible(): self._setEmptyQuality() return @@ -1139,7 +1138,7 @@ class MachineManager(QObject): @pyqtProperty(str, notify = activeQualityGroupChanged) def activeQualityOrQualityChangesName(self): - name = "" + name = self._empty_quality_container.getName() if self._current_quality_changes_group: name = self._current_quality_changes_group.name elif self._current_quality_group: diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index e03cb4977f..8ff4c33244 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -63,7 +63,7 @@ Item menu: ProfileMenu { } function generateActiveQualityText () { - var result = Cura.MachineManager.activeQualityName; + var result = Cura.MachineManager.activeQualityOrQualityChangesName; if (Cura.MachineManager.isActiveQualitySupported) { if (Cura.MachineManager.activeQualityLayerHeight > 0) { From 471182333d218190c99c42427d29e82fd12b06c6 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 10:41:39 +0100 Subject: [PATCH 103/266] CURA-4606 refactored activeMaterialNames --- cura/Settings/MachineManager.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ec024f7b49..e34b1a0763 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -460,15 +460,7 @@ class MachineManager(QObject): @pyqtProperty("QVariantList", notify = activeMaterialChanged) def activeMaterialNames(self) -> List[str]: - result = [] - - active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() - if active_stacks is not None: - for stack in active_stacks: - material_container = stack.material - if material_container and material_container != self._empty_material_container: - result.append(material_container.getName()) - return result + return list(self._current_root_material_name.values()) @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self) -> str: From c338e1b7d69c252ae80d9590700823108a37f320 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 10:44:51 +0100 Subject: [PATCH 104/266] WIP: Fix quality profiles for abax_pri3 - Fixed duplicated quality_type and name for qualities "Fast" and "Fine" - Moved global settings to separate global quality files - Fix abax_pri3 definition file: has_machine_quality = true - MAYBE FIXME: Normal and Fast have the same layer height. Don't know if that's intended. They are kept as before. --- resources/definitions/abax_pri3.def.json | 3 ++- resources/quality/abax_pri3/apri3_fast.inst.cfg | 14 ++++++++++++++ resources/quality/abax_pri3/apri3_high.inst.cfg | 14 ++++++++++++++ resources/quality/abax_pri3/apri3_normal.inst.cfg | 14 ++++++++++++++ .../quality/abax_pri3/apri3_pla_fast.inst.cfg | 5 ++--- .../quality/abax_pri3/apri3_pla_high.inst.cfg | 1 - .../quality/abax_pri3/apri3_pla_normal.inst.cfg | 1 - 7 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 resources/quality/abax_pri3/apri3_fast.inst.cfg create mode 100644 resources/quality/abax_pri3/apri3_high.inst.cfg create mode 100644 resources/quality/abax_pri3/apri3_normal.inst.cfg diff --git a/resources/definitions/abax_pri3.def.json b/resources/definitions/abax_pri3.def.json index 2fa648096f..f91a501a6f 100644 --- a/resources/definitions/abax_pri3.def.json +++ b/resources/definitions/abax_pri3.def.json @@ -6,7 +6,8 @@ "visible": true, "author": "ABAX 3d Technologies", "manufacturer": "ABAX 3d Technologies", - "file_formats": "text/x-gcode" + "file_formats": "text/x-gcode", + "has_machine_quality": true }, "overrides": { "machine_start_gcode": { diff --git a/resources/quality/abax_pri3/apri3_fast.inst.cfg b/resources/quality/abax_pri3/apri3_fast.inst.cfg new file mode 100644 index 0000000000..7db569ec72 --- /dev/null +++ b/resources/quality/abax_pri3/apri3_fast.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 2 +name = Fast +definition = abax_pri3 + +[metadata] +setting_version = 4 +type = quality +quality_type = fast +weight = -1 +global_quality = True + +[values] +layer_height = 0.2 diff --git a/resources/quality/abax_pri3/apri3_high.inst.cfg b/resources/quality/abax_pri3/apri3_high.inst.cfg new file mode 100644 index 0000000000..8a95b71a88 --- /dev/null +++ b/resources/quality/abax_pri3/apri3_high.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 2 +name = Extra Fine +definition = abax_pri3 + +[metadata] +setting_version = 4 +type = quality +quality_type = high +weight = 1 +global_quality = True + +[values] +layer_height = 0.1 diff --git a/resources/quality/abax_pri3/apri3_normal.inst.cfg b/resources/quality/abax_pri3/apri3_normal.inst.cfg new file mode 100644 index 0000000000..29b25d889f --- /dev/null +++ b/resources/quality/abax_pri3/apri3_normal.inst.cfg @@ -0,0 +1,14 @@ +[general] +version = 2 +name = Fine +definition = abax_pri3 + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 0 +global_quality = True + +[values] +layer_height = 0.2 diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 7d1c1bf588..f24f198b2e 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -1,17 +1,16 @@ [general] version = 2 -name = Fine +name = Fast definition = abax_pri3 [metadata] setting_version = 4 type = quality -quality_type = normal +quality_type = fast weight = -1 material = generic_pla [values] -layer_height = 0.2 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 46a4178dd9..5b4c470842 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -11,7 +11,6 @@ weight = 1 material = generic_pla [values] -layer_height = 0.1 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 3f6f36cfe6..2df629af38 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -11,7 +11,6 @@ weight = 0 material = generic_pla [values] -layer_height = 0.2 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 From be211b73114cf3a8dbd0b2963b833a606779c280 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:04:29 +0100 Subject: [PATCH 105/266] WIP: Fix quality profiles for abax_pri5 - Removed redundant quality profiles for abax_pri5 and reuse the abax_pri3 ones - Fix abax_pri5 definition file: has_machine_quality = true --- resources/definitions/abax_pri5.def.json | 4 +++- .../quality/abax_pri5/apri5_pla_fast.inst.cfg | 22 ------------------- .../quality/abax_pri5/apri5_pla_high.inst.cfg | 22 ------------------- .../abax_pri5/apri5_pla_normal.inst.cfg | 22 ------------------- 4 files changed, 3 insertions(+), 67 deletions(-) delete mode 100644 resources/quality/abax_pri5/apri5_pla_fast.inst.cfg delete mode 100644 resources/quality/abax_pri5/apri5_pla_high.inst.cfg delete mode 100644 resources/quality/abax_pri5/apri5_pla_normal.inst.cfg diff --git a/resources/definitions/abax_pri5.def.json b/resources/definitions/abax_pri5.def.json index cbebb576b0..b8310221b1 100644 --- a/resources/definitions/abax_pri5.def.json +++ b/resources/definitions/abax_pri5.def.json @@ -6,7 +6,9 @@ "visible": true, "author": "ABAX 3d Technologies", "manufacturer": "ABAX 3d Technologies", - "file_formats": "text/x-gcode" + "file_formats": "text/x-gcode", + "quality_definition": "abax_pri3", + "has_machine_quality": true }, "overrides": { "machine_start_gcode": { diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg deleted file mode 100644 index 517c767ac5..0000000000 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = Fine -definition = abax_pri5 - -[metadata] -setting_version = 4 -type = quality -quality_type = normal -weight = -1 -material = generic_pla - -[values] -layer_height = 0.2 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 80 -speed_layer_0 = =round(speed_print * 30 / 50) -speed_topbottom = 20 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg deleted file mode 100644 index 01699e39f6..0000000000 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = Extra Fine -definition = abax_pri5 - -[metadata] -setting_version = 4 -type = quality -quality_type = high -weight = 1 -material = generic_pla - -[values] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 50 -speed_layer_0 = =round(speed_print * 30 / 50) -speed_topbottom = 20 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg deleted file mode 100644 index ea1023dc43..0000000000 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = Fine -definition = abax_pri5 - -[metadata] -setting_version = 4 -type = quality -quality_type = normal -weight = 0 -material = generic_pla - -[values] -layer_height = 0.2 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 50 -speed_layer_0 = =round(speed_print * 30 / 50) -speed_topbottom = 20 -cool_min_layer_time = 5 -cool_min_speed = 10 From 76f431af76229fdb4fbe1eaaf07cce70a4a941eb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:06:08 +0100 Subject: [PATCH 106/266] WIP: Only fetch variants if the machine has any --- cura/Machines/Models/BuildPlateModel.py | 6 ++++++ cura/Machines/Models/NozzleModel.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py index ff623eeca7..fccf4fa44e 100644 --- a/cura/Machines/Models/BuildPlateModel.py +++ b/cura/Machines/Models/BuildPlateModel.py @@ -2,6 +2,7 @@ from PyQt5.QtCore import Qt from UM.Application import Application from UM.Qt.ListModel import ListModel +from UM.Util import parseBool from cura.Machines.VariantManager import VariantType @@ -30,6 +31,11 @@ class BuildPlateModel(ListModel): self.setItems([]) return + has_variants = parseBool(global_stack.getMetaDataEntry("has_variant_buildplates", False)) + if not has_variants: + self.setItems([]) + return + variant_dict = self._variant_manager.getVariantNodes(global_stack, variant_type = VariantType.BUILD_PLATE) item_list = [] diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 9d1be393cf..19d4a800c8 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import Qt from UM.Application import Application from UM.Qt.ListModel import ListModel +from UM.Util import parseBool class NozzleModel(ListModel): @@ -33,6 +34,11 @@ class NozzleModel(ListModel): self.setItems([]) return + has_variants = parseBool(active_global_stack.getMetaDataEntry("has_variants", False)) + if not has_variants: + self.setItems([]) + return + variant_node_dict = variant_manager.getVariantNodes(active_global_stack) if not variant_node_dict: self.setItems([]) From 2e3e01ff95fc5a022c3ed7dab062ab81f950ae13 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 11:13:35 +0100 Subject: [PATCH 107/266] CURA-4606 Cleanup WorkspaceSummaryDialog and prepare for single extrusion mode --- cura/Settings/MachineManager.py | 49 +++++++++++++----------- resources/qml/WorkspaceSummaryDialog.qml | 8 ++-- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e34b1a0763..4fe47ba466 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -444,24 +444,6 @@ class MachineManager(QObject): return "" - @pyqtProperty("QVariantList", notify=activeVariantChanged) - def activeVariantNames(self) -> List[str]: - result = [] - - # Just return the variants in the extruder stack(s). For the variant in the global stack, use activeVariantBuildplateName - active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - if active_stacks is not None: - for stack in active_stacks: - variant_container = stack.variant - if variant_container and variant_container != self._empty_variant_container: - result.append(variant_container.getName()) - - return result - - @pyqtProperty("QVariantList", notify = activeMaterialChanged) - def activeMaterialNames(self) -> List[str]: - return list(self._current_root_material_name.values()) - @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self) -> str: if self._active_container_stack: @@ -898,6 +880,12 @@ class MachineManager(QObject): # # New # + + # We not fetch it from _current_root_material_id, but later we can get it from somewhere else + @pyqtProperty("QVariantList", notify = rootMaterialChanged) + def currentExtruderPositions(self): + return sorted(list(self._current_root_material_id.keys())) + @pyqtProperty("QVariant", notify = rootMaterialChanged) def currentRootMaterialId(self): # initial filling the current_root_material_id @@ -909,12 +897,29 @@ class MachineManager(QObject): @pyqtProperty("QVariant", notify = rootMaterialChanged) def currentRootMaterialName(self): # initial filling the current_root_material_name - for position in self._global_container_stack.extruders: - if position not in self._current_root_material_name: - material = self._global_container_stack.extruders[position].material - self._current_root_material_name[position] = material.getName() + if self._global_container_stack: + for position in self._global_container_stack.extruders: + if position not in self._current_root_material_name: + material = self._global_container_stack.extruders[position].material + self._current_root_material_name[position] = material.getName() return self._current_root_material_name + ## Return the variant names in the extruder stack(s). + ## For the variant in the global stack, use activeVariantBuildplateName + @pyqtProperty("QVariant", notify = activeVariantChanged) + def activeVariantNames(self): + result = {} + + active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() + if active_stacks is not None: + for stack in active_stacks: + variant_container = stack.variant + position = stack.getMetaDataEntry("position") + if variant_container and variant_container != self._empty_variant_container: + result[position] = variant_container.getName() + + return result + def _setEmptyQuality(self): self._current_quality_group = None self._current_quality_changes_group = None diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml index 8f00377d58..b9ea77fa70 100644 --- a/resources/qml/WorkspaceSummaryDialog.qml +++ b/resources/qml/WorkspaceSummaryDialog.qml @@ -148,7 +148,7 @@ UM.Dialog Repeater { - model: Cura.MachineManager.activeMaterialNames + model: Cura.MachineManager.currentExtruderPositions delegate: Column { Item // Spacer @@ -158,7 +158,7 @@ UM.Dialog } Label { - text: catalog.i18nc("@action:label", "Extruder %1").arg(index+1) + text: catalog.i18nc("@action:label", "Extruder %1").arg(modelData) } height: childrenRect.height width: parent.width @@ -173,7 +173,7 @@ UM.Dialog } Label { - text: Cura.MachineManager.activeVariantNames[index] + ", " + modelData + text: Cura.MachineManager.activeVariantNames[modelData] + ", " + Cura.MachineManager.currentRootMaterialName[modelData] width: (parent.width / 3) | 0 } } @@ -294,4 +294,4 @@ UM.Dialog } } } -} \ No newline at end of file +} From 628d0315421111f47b56d2bcb581af9cc464b9d1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:14:07 +0100 Subject: [PATCH 108/266] WIP: Fix models to check if global stack exists --- cura/Machines/Models/MaterialsModel.py | 39 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py index e79ebe36bc..97a1d27a31 100644 --- a/cura/Machines/Models/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -66,23 +66,28 @@ class GenericMaterialsModel(BaseMaterialsModel): super().__init__(parent) from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager + self._machine_manager = CuraApplication.getInstance().getMachineManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._material_manager = CuraApplication.getInstance()._material_manager - machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) + self._machine_manager.globalContainerChanged.connect(self._update) + self._extruder_manager.activeExtruderChanged.connect(self._update) + self._material_manager.materialsUpdated.connect(self._update) self._update() def _update(self): - item_list = [] + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + result_dict = getAvailableMaterials() if result_dict is None: self.setItems([]) return + item_list = [] for root_material_id, container_node in result_dict.items(): metadata = container_node.metadata # Only add results for generic materials @@ -128,21 +133,26 @@ class BrandMaterialsModel(ListModel): self.addRoleName(self.MaterialsRole, "materials") from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() + self._machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() material_manager = CuraApplication.getInstance()._material_manager - machine_manager.globalContainerChanged.connect(self._update) + self._machine_manager.globalContainerChanged.connect(self._update) extruder_manager.activeExtruderChanged.connect(self._update) material_manager.materialsUpdated.connect(self._update) def _update(self): - brand_item_list = [] + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + result_dict = getAvailableMaterials() if result_dict is None: self.setItems([]) return + brand_item_list = [] brand_group_dict = {} for root_material_id, container_node in result_dict.items(): metadata = container_node.metadata @@ -231,17 +241,22 @@ class MaterialsModel(ListModel): from cura.CuraApplication import CuraApplication self._container_registry = CuraApplication.getInstance().getContainerRegistry() - machine_manager = CuraApplication.getInstance().getMachineManager() + self._machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() material_manager = CuraApplication.getInstance()._material_manager - machine_manager.globalContainerChanged.connect(self._update) + self._machine_manager.globalContainerChanged.connect(self._update) extruder_manager.activeExtruderChanged.connect(self._update) material_manager.materialsUpdated.connect(self._update) self._update() def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + result_dict = getAvailableMaterials() if result_dict is None: self.setItems([]) From c65192000e08ace9005018fe50b2f038f9c16749 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:19:18 +0100 Subject: [PATCH 109/266] WIP: Fix material name fetching in QML --- resources/qml/SidebarHeader.qml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 2c99ce2dd3..b78cade1de 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -252,8 +252,18 @@ Column { id: materialSelection - text: Cura.MachineManager.currentRootMaterialName[base.currentExtruderIndex] - tooltip: Cura.MachineManager.currentRootMaterialName[base.currentExtruderIndex] + property var currentRootMaterialName: + { + var materials = Cura.MachineManager.currentRootMaterialName; + var materialName = ""; + if (base.currentExtruderIndex in materials) { + materialName = materials[base.currentExtruderIndex]; + } + return materialName; + } + + text: currentRootMaterialName + tooltip: currentRootMaterialName visible: Cura.MachineManager.hasMaterials enabled: !extrudersList.visible || base.currentExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height From 6e5fed6b5ec3cb689e84157ee08ea74dc2b56ba9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:21:16 +0100 Subject: [PATCH 110/266] WIP: Fix quality name in SettingView --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 8ff4c33244..cef7ce9077 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -57,7 +57,7 @@ Item height: UM.Theme.getSize("setting_control").height anchors.left: globalProfileLabel.right anchors.right: parent.right - tooltip: Cura.MachineManager.activeQualityName + tooltip: Cura.MachineManager.activeQualityOrQualityChangesName style: UM.Theme.styles.sidebar_header_button activeFocusOnPress: true menu: ProfileMenu { } From ec8ee6e31a8a7ee5a9d83d239e7d13e2c9728718 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:22:10 +0100 Subject: [PATCH 111/266] WIP: Fix quality name in workspace summary dialog --- resources/qml/WorkspaceSummaryDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml index b9ea77fa70..1cfe36d14b 100644 --- a/resources/qml/WorkspaceSummaryDialog.qml +++ b/resources/qml/WorkspaceSummaryDialog.qml @@ -217,7 +217,7 @@ UM.Dialog } Label { - text: Cura.MachineManager.activeQualityName + text: Cura.MachineManager.activeQualityOrQualityChangesName width: (parent.width / 3) | 0 } From 6cd47453bb4ac0be7182010d946e2619c7013e79 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:36:46 +0100 Subject: [PATCH 112/266] WIP: Fix activeMaterialsCompatible() --- cura/Settings/MachineManager.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4fe47ba466..c570f0649a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1008,9 +1008,10 @@ class MachineManager(QObject): def activeMaterialsCompatible(self): # check material - variant compatibility - for position, extruder in self._global_container_stack.extruders.items(): - if not extruder.material.getMetaDataEntry("compatible"): - return False + if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)): + for position, extruder in self._global_container_stack.extruders.items(): + if not extruder.material.getMetaDataEntry("compatible"): + return False return True ## Update current quality type and machine after setting material From a4a1babc5949d8e47783069981363736d02987aa Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:37:14 +0100 Subject: [PATCH 113/266] WIP: Fix UM2 quality profiles - Remove layer_height from the profiles because they are not global qualities - The layer_heights are the same as the default ones so no need to make specific global qualities for UM2 --- resources/quality/ultimaker2/um2_draft.inst.cfg | 1 - resources/quality/ultimaker2/um2_fast.inst.cfg | 1 - resources/quality/ultimaker2/um2_high.inst.cfg | 1 - 3 files changed, 3 deletions(-) diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 821c864bb8..1115deacd9 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -10,4 +10,3 @@ quality_type = draft weight = -2 [values] -layer_height = 0.2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 1292613642..8bc5b7dee3 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -11,7 +11,6 @@ weight = -1 [values] infill_sparse_density = 10 -layer_height = 0.15 cool_min_layer_time = 3 speed_wall_0 = 40 speed_wall_x = 80 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 54119933b5..8d6573b2be 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -10,6 +10,5 @@ quality_type = high weight = 1 [values] -layer_height = 0.06 speed_topbottom = 15 speed_infill = 80 From c411091fde958dd02298b17a3efe8f7a486fae17 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 11:47:08 +0100 Subject: [PATCH 114/266] WIP: Only add global_quality containers for global stack qualities --- cura/Machines/QualityManager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index f7ca84e83d..a98a698cb6 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import QObject, QTimer from UM.Application import Application from UM.Logger import Logger +from UM.Util import parseBool from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerNode import ContainerNode @@ -294,6 +295,12 @@ class QualityManager(QObject): quality_group_dict = {} for node in nodes_to_check: if node and node.quality_type_map: + # Only include global qualities + quality_node = list(node.quality_type_map.values())[0] + is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) + if not is_global_quality: + continue + for quality_type, quality_node in node.quality_type_map.items(): quality_group = QualityGroup(quality_node.metadata["name"], quality_type) quality_group.node_for_global = quality_node From 02472f6ad2c84c43717a3a6896ebbec78d243345 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 12:39:04 +0100 Subject: [PATCH 115/266] WIP: Fix material name update upon machine switching --- cura/Settings/MachineManager.py | 13 +++++++++---- resources/qml/SidebarHeader.qml | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index c570f0649a..6cb6724a5a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -259,10 +259,10 @@ class MachineManager(QObject): self.activeQualityChanged.emit() self.activeVariantChanged.emit() self.activeMaterialChanged.emit() - self._error_check_timer.start() - def _onProfilesModelChanged(self, *args) -> None: - self.__emitChangedSignals() + self.rootMaterialChanged.emit() + + self._error_check_timer.start() def _onInstanceContainersChanged(self, container) -> None: self._instance_container_timer.start() @@ -307,7 +307,11 @@ class MachineManager(QObject): containers = container_registry.findContainerStacks(id = stack_id) if containers: - Application.getInstance().setGlobalContainerStack(containers[0]) + global_stack = containers[0] + Application.getInstance().setGlobalContainerStack(global_stack) + self._global_container_stack = global_stack + self.globalContainerChanged.emit() + self._onGlobalContainerChanged() ExtruderManager.getInstance()._globalContainerStackChanged() self._initMachineState(containers[0]) @@ -898,6 +902,7 @@ class MachineManager(QObject): def currentRootMaterialName(self): # initial filling the current_root_material_name if self._global_container_stack: + self._current_root_material_name = {} for position in self._global_container_stack.extruders: if position not in self._current_root_material_name: material = self._global_container_stack.extruders[position].material diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b78cade1de..5d9cbe2ad1 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -265,7 +265,7 @@ Column text: currentRootMaterialName tooltip: currentRootMaterialName visible: Cura.MachineManager.hasMaterials - enabled: !extrudersList.visible || base.currentExtruderIndex > -1 + enabled: !extrudersList.visible || base.currentExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width anchors.right: parent.right From 3364e24988baa009f33bdc9bb1f51492aeb9cea1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 12:39:54 +0100 Subject: [PATCH 116/266] WIP: Be less wordy --- cura/Machines/Models/QualityProfilesModel.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 2f1374cc8b..4b5e3bdf86 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -49,8 +49,8 @@ class QualityProfilesModel(ListModel): Logger.log("d", "Updating quality profile model ...") machine_manager = Application.getInstance().getMachineManager() - active_global_stack = machine_manager._global_container_stack - if active_global_stack is None: + global_stack = machine_manager._global_container_stack + if global_stack is None: self.setItems([]) Logger.log("d", "No active GlobalStack, set quality profile model as empty.") return @@ -60,7 +60,7 @@ class QualityProfilesModel(ListModel): self.setItems([]) return - quality_group_dict = self._quality_manager.getQualityGroups(active_global_stack) + quality_group_dict = self._quality_manager.getQualityGroups(global_stack) item_list = [] for key in sorted(quality_group_dict): @@ -83,14 +83,14 @@ class QualityProfilesModel(ListModel): self.setItems(item_list) def _fetchLayerHeight(self, quality_group: "QualityGroup"): - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + global_stack = Application.getInstance().getMachineManager()._global_container_stack if not self._layer_height_unit: - unit = active_global_stack.definition.getProperty("layer_height", "unit") + unit = global_stack.definition.getProperty("layer_height", "unit") if not unit: unit = "" self._layer_height_unit = unit - default_layer_height = active_global_stack.definition.getProperty("layer_height", "value") + default_layer_height = global_stack.definition.getProperty("layer_height", "value") # Get layer_height from the quality profile for the GlobalStack container = quality_group.node_for_global.getContainer() @@ -100,7 +100,7 @@ class QualityProfilesModel(ListModel): layer_height = str(container.getProperty("layer_height", "value")) else: # Look for layer_height in the GlobalStack from material -> definition - container = active_global_stack.definition + container = global_stack.definition if container.hasProperty("layer_height", "value"): layer_height = container.getProperty("layer_height", "value") return str(layer_height) From b7659edd3bd15930b6c4c6832cf1036c8058bf9d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 12:40:56 +0100 Subject: [PATCH 117/266] WIP: Remove unused ID role in QualityProfilesModel --- cura/Machines/Models/QualityProfilesModel.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 4b5e3bdf86..3bfccd409d 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -13,19 +13,17 @@ from cura.Machines.QualityManager import QualityGroup # QML Model for all built-in quality profiles. # class QualityProfilesModel(ListModel): - IdRole = Qt.UserRole + 1 - NameRole = Qt.UserRole + 2 - QualityTypeRole = Qt.UserRole + 3 - LayerHeightRole = Qt.UserRole + 4 - LayerHeightWithoutUnitRole = Qt.UserRole + 5 - AvailableRole = Qt.UserRole + 6 - QualityGroupRole = Qt.UserRole + 7 - QualityChangesGroupRole = Qt.UserRole + 8 + NameRole = Qt.UserRole + 1 + QualityTypeRole = Qt.UserRole + 2 + LayerHeightRole = Qt.UserRole + 3 + LayerHeightWithoutUnitRole = Qt.UserRole + 4 + AvailableRole = Qt.UserRole + 5 + QualityGroupRole = Qt.UserRole + 6 + QualityChangesGroupRole = Qt.UserRole + 7 def __init__(self, parent = None): super().__init__(parent) - self.addRoleName(self.IdRole, "id") self.addRoleName(self.NameRole, "name") self.addRoleName(self.QualityTypeRole, "quality_type") self.addRoleName(self.LayerHeightRole, "layer_height") From b3ef4a05d54b267d67d5c56a973e123cdae3c6b1 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 13:18:59 +0100 Subject: [PATCH 118/266] CURA-4606 skip non global qualities when looking for extruder qualities --- cura/Machines/QualityManager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index a98a698cb6..078de762d4 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -354,6 +354,12 @@ class QualityManager(QObject): nodes_to_check += [machine_node, default_machine_node] for node in nodes_to_check: if node and node.quality_type_map: + # Only include variant qualities; skip non global qualities + quality_node = list(node.quality_type_map.values())[0] + is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) + if is_global_quality: + continue + for quality_type, quality_node in node.quality_type_map.items(): if quality_type not in quality_group_dict: quality_group = QualityGroup(quality_node.metadata["name"], quality_type) From 631b72c007c04a542b9f8d1cb2ec1a866f3caf24 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 14:16:26 +0100 Subject: [PATCH 119/266] CURA-4606 in all quality profiles, rename all the specific 1.75mm materials back to the generic material --- cura/Settings/CuraStackBuilder.py | 5 ++++- .../quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg | 2 +- .../cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg | 2 +- .../cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg | 2 +- .../cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg | 2 +- .../cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg | 2 +- .../cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg | 2 +- .../cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_normal.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_draft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_fast.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_high.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_normal.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_ultra.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_high.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg | 2 +- .../monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_draft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_fast.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_high.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_normal.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_ultra.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_draft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_fast.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_high.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_normal.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_ultra.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_draft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_fast.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_normal.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_ultra.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg | 2 +- 139 files changed, 142 insertions(+), 139 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 0348d6855f..fc0d4f6f8e 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -129,7 +129,10 @@ class CuraStackBuilder: new_global_stack.quality = quality_group.node_for_global.getContainer() for position, extruder_stack in new_global_stack.extruders.items(): - extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() + if position in quality_group.nodes_for_extruders: + extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() + else: + extruder_stack.quality = application.empty_quality_container # Register the global stack after the extruder stacks are created. This prevents the registry from adding another # extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1). diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index ce9e58ea04..736defd5c6 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = -1 -material = generic_petg_175 +material = generic_petg [values] material_print_temperature = =default_material_print_temperature - 5 diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index cbde2790df..82c7fa7baf 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg [values] acceleration_print = 2000 diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index af122db9cc..b1e9ff91df 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_petg_175 +material = generic_petg [values] material_print_temperature = =default_material_print_temperature - 5 diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index d8baf277a9..9b8078e266 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = -1 -material = generic_pla_175 +material = generic_pla [values] material_print_temperature = =default_material_print_temperature + 15 diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 49675e25d9..2bbfb02e0d 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla [values] acceleration_print = 2000 diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index 113bdba605..b77ac747a8 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla [values] material_print_temperature = =default_material_print_temperature + 15 diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index 059f25a70f..f626604f70 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = -1 -material = generic_pva_175 +material = generic_pva [values] material_print_temperature = =default_material_print_temperature + 10 diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index 5da254aa9b..caf0bd4bd7 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pva_175 +material = generic_pva [values] acceleration_print = 2000 diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index 562b2257f5..4f08010a6f 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pva_175 +material = generic_pva [values] material_print_temperature = =default_material_print_temperature + 10 diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index 89ab9a09d4..996c8e400b 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index a83a6d1e31..5fdbaab51a 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_abs_175 +material = generic_abs variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index b5281407dd..66fa5e4c30 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index b366026793..31cb6adc72 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_abs_175 +material = generic_abs variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index 0f4896ea74..7bc7791bfa 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_abs_175 +material = generic_abs variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index 5f3f20c9ee..137bd8cd7b 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_abs_175 +material = generic_abs variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index 2a5b873dd4..96c0009578 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 887a252e06..10389823eb 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_abs_175 +material = generic_abs variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index b4417d4bcf..fb76afc867 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_hips_175 +material = generic_hips variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index b669f21a2b..8fb06f3bbc 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_hips_175 +material = generic_hips variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index c88f8be029..ec29af6c6e 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_hips_175 +material = generic_hips variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index 4790926e3b..61a48e0c61 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_hips_175 +material = generic_hips variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index e096fbb3a4..1bafda10fa 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_hips_175 +material = generic_hips variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index 80a44678ca..0f77442040 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_hips_175 +material = generic_hips variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index e1754d5ba0..0edcffa05c 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_hips_175 +material = generic_hips variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index b728e01c99..a50a7015d5 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_hips_175 +material = generic_hips variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index b81a053cd3..50bb6532bd 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_nylon_175 +material = generic_nylon variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index b09e2ac794..649018bd89 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_nylon_175 +material = generic_nylon variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index b43839439f..17b274c05d 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_nylon_175 +material = generic_nylon variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index 36cfe49afb..0d7d1963cc 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_nylon_175 +material = generic_nylon variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index ef3185814b..bbab5caee1 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_nylon_175 +material = generic_nylon variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index af57d6f3ab..568eb59e32 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_nylon_175 +material = generic_nylon variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index 99e932c954..b6ef10e5df 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_nylon_175 +material = generic_nylon variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index a0fef367a6..d05407393a 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_nylon_175 +material = generic_nylon variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index ac0f7a35fa..adb88df236 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pc_175 +material = generic_pc variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index 5f77a2a91e..92b5fc08a7 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pc_175 +material = generic_pc variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 835c94e5fd..c00437edd9 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pc_175 +material = generic_pc variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index 7e48b4a94c..c0257a19e1 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pc_175 +material = generic_pc variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index e857476b8b..8b89c00c72 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_pc_175 +material = generic_pc variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 0fc24de569..1f5491f65f 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_pc_175 +material = generic_pc variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index 3c58129546..3d0d49617e 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pc_175 +material = generic_pc variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 3b8765b21a..7a8d77df37 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pc_175 +material = generic_pc variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index 94bf52b2a4..4e0d95ec9b 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index d5517b57b5..2903b8d658 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_petg_175 +material = generic_petg variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 33b3bfa99d..bd0e7af5c7 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index 1bdbe32229..a97e82542f 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_petg_175 +material = generic_petg variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index 20b2d38856..41392abb37 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_petg_175 +material = generic_petg variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index cdb4d08dd0..fc425bfeaa 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_petg_175 +material = generic_petg variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index e125e9dd63..0925e920a6 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index 91a513d171..a70eb22797 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_petg_175 +material = generic_petg variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index cbd40f3f8f..a2e3492051 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index 3eed8df302..3f5d23f800 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index 0822ab8c07..5e747adb32 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index 80fb24553f..7318dd3bf6 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index c6b92d50a7..cbdf5887b4 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = -3 -material = generic_pla_175 +material = generic_pla variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index cb2633313a..622c6f0d51 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = -4 -material = generic_pla_175 +material = generic_pla variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index de0298f57e..8fbd09497d 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index c6f4e012b6..247d2ed5f7 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index 22fdd98317..28a5694246 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pva_175 +material = generic_pva variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index 8288294d0c..cfc2d92399 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pva_175 +material = generic_pva variant = 0.25 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index 2719eb458e..aec07d46dc 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pva_175 +material = generic_pva variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index 6a97ec860f..85c5f20fa9 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pva_175 +material = generic_pva variant = 0.4 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index 12ca609a7b..f1d05741a6 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = coarse weight = 3 -material = generic_pva_175 +material = generic_pva variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index d793282c41..1e261c93cc 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = extra coarse weight = 4 -material = generic_pva_175 +material = generic_pva variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index a43689e7c9..d7697c643f 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pva_175 +material = generic_pva variant = 0.8 mm [values] diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index f9ead11d79..8a2705fdfa 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 2 -material = generic_pva_175 +material = generic_pva variant = 0.8 mm [values] diff --git a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg index aebb72d610..75774fc000 100644 --- a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_abs_175 +material = generic_abs [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg index 05b54eb81e..65542f114a 100644 --- a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg index 67c8525b4f..55248345fa 100644 --- a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_abs_175 +material = generic_abs [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg index 511ee2712f..5986c65872 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_nylon_175 +material = generic_nylon [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg index 47c3e26782..158f903bab 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_nylon_175 +material = generic_nylon [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg index 49ffada336..89024f30b7 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_nylon_175 +material = generic_nylon [values] adhesion_type = raft diff --git a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg index 684b72587c..98a5578d89 100644 --- a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_pla_175 +material = generic_pla [values] adhesion_type = skirt diff --git a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg index a80f23fa9b..554312ce7b 100644 --- a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla [values] adhesion_type = skirt diff --git a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg index 8a02873fa2..3f22aa1200 100644 --- a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla [values] adhesion_type = skirt diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index 084094f5e7..c02e789dfe 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index 1e3419dc7e..7f4f368e06 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 0758cd6630..37335b61ee 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index da347ac13c..138c31ab14 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index cc25431062..2d748bd698 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index 2b7f830b3f..ebf7798733 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index 73abddc696..5be92914be 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 22adb14e71..bfe92a98e1 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index 9d3e31cb16..038af5eec0 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index 9d68dee0bf..df341d195c 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index 63aefb027b..ff9dbc8227 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 402c87886c..8531bbf98b 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index 9029b4508a..8b065ecea8 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index e9b440e1f6..97672ee1c7 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index 1517f7d340..7b92f9d454 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index 3d3346eac5..1a1b59d90f 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index b05a336aee..f3ef39f009 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index e45fe903e2..0e047b140e 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index adeae8ae33..e68ad90c6c 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index 0c0f9fcb5a..78bdc826ba 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index e5e5d6d40d..cc24c4a0b2 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index 95323181d7..5bfb82ee90 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 8b0005e60d..d042fc7978 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index cc8ef3c9cd..8e79071db4 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_pla_175 +material = generic_pla [values] material_bed_temperature = 60 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index b75f20a1a6..3387b51d7d 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index e06394dea5..da187c85ea 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index 7249fb039c..a2efa54353 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index a0237b3af2..a331a63aaf 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index c858d341d2..d328e353ac 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index 9996338c79..8e64dae5aa 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index 5d94f941c8..5757e57a3b 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = 2 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 0635565027..77810c8809 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_abs_175 +material = generic_abs [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index 42e0d69476..80905c64f7 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index e62e654fc3..eab42b728e 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index cca4b98678..1261eff697 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 56c28e372f..6cf8709bf6 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index 14375b3c41..3cf4efb73b 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index 01c45f2401..22f27ab084 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index 205915cd7c..b3b80d651f 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index 124121c35c..efd93a5381 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_nylon_175 +material = generic_nylon diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index ae69e5fe46..05283042c2 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index 8e78ee7827..07319fe4db 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index 761859e1a5..668040c851 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index 91575da188..e9d907fabd 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index 9295b6b6d1..5d1af5a430 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index 02ba4841e8..06c4b4f405 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index 8b3833371b..821658554d 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index f0ada1c6a8..93dc04e13c 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -8,7 +8,7 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_pc_175 +material = generic_pc [values] material_bed_temperature = 70 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index 9278a6920a..917e8b98a3 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index 503362f755..aa98ea4de0 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = fast weight = -1 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index 3d8ae1d5d0..3db3af0db2 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = high weight = 1 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index 66c69b237e..e39fd54550 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 2b517e1521..6d9e99d365 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index 969bd71f1a..5227aac686 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index ef97518e2a..a58c05b004 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index 7d338616dd..0fe38fb5df 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = verydraft weight = -4 -material = generic_petg_175 +material = generic_petg diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index b3ccc9f82b..0b9f10a790 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = draft weight = -2 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index 67ed46db58..d831890413 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = fast weight = 0 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index 17b8f7a8b7..f5049308f3 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = high weight = 0 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index 7852138707..f63c87a52c 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = normal weight = 0 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index aa46df06b6..a8bd9a5179 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = superdraft weight = -5 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index 39cf607b25..df1ae97a16 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = thickerdraft weight = -3 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index 18d93dac2d..3b3ec79692 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -8,4 +8,4 @@ setting_version = 4 type = quality quality_type = ultra weight = 2 -material = generic_pla_175 +material = generic_pla diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index e8fff16371..5e63de3952 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -6,6 +6,6 @@ definition = monoprice_select_mini_v2 [metadata] setting_version = 4 type = quality -material = generic_pla_175 +material = generic_pla weight = 0 quality_type = verydraft From 70d5cd246234518209fcd70e180e41200451c81e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 14:30:29 +0100 Subject: [PATCH 120/266] Fix: Replace all activeQualityName with activeQualityOrQualityChangesName --- cura/Settings/ContainerManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 6eb9aa0311..ea82af8d7f 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -366,7 +366,7 @@ class ContainerManager(QObject): if not global_stack: return - active_quality_name = self._machine_manager.activeQualityName + active_quality_name = self._machine_manager.activeQualityOrQualityChangesName if active_quality_name == "": Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) return From d72f8e87505d150c7f8c9009263f263988c7db06 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 14:41:45 +0100 Subject: [PATCH 121/266] CURA-4606 fix warning materials on machines that do not have has_variant_materials --- cura/Machines/QualityManager.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 078de762d4..a9aa6e9dcf 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -283,6 +283,8 @@ class QualityManager(QObject): # TODO: How to make this simpler, including the fall backs. # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) + # This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks + has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False)) # To find the quality container for the GlobalStack, check in the following fall-back manner: # (1) the machine-specific node @@ -296,10 +298,11 @@ class QualityManager(QObject): for node in nodes_to_check: if node and node.quality_type_map: # Only include global qualities - quality_node = list(node.quality_type_map.values())[0] - is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) - if not is_global_quality: - continue + if has_variant_materials: + quality_node = list(node.quality_type_map.values())[0] + is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) + if not is_global_quality: + continue for quality_type, quality_node in node.quality_type_map.items(): quality_group = QualityGroup(quality_node.metadata["name"], quality_type) @@ -354,11 +357,12 @@ class QualityManager(QObject): nodes_to_check += [machine_node, default_machine_node] for node in nodes_to_check: if node and node.quality_type_map: - # Only include variant qualities; skip non global qualities - quality_node = list(node.quality_type_map.values())[0] - is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) - if is_global_quality: - continue + if has_variant_materials: + # Only include variant qualities; skip non global qualities + quality_node = list(node.quality_type_map.values())[0] + is_global_quality = parseBool(quality_node.metadata.get("global_quality", False)) + if is_global_quality: + continue for quality_type, quality_node in node.quality_type_map.items(): if quality_type not in quality_group_dict: From 5ba0ac8a43a10dd5191c13d3d23da19517951aa9 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 15:59:49 +0100 Subject: [PATCH 122/266] CURA-4606 switch to first extruder when switching machines; this prevents crashing when switching to single extruder machine --- cura/Settings/MachineManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6cb6724a5a..85a02a8a30 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -308,6 +308,7 @@ class MachineManager(QObject): containers = container_registry.findContainerStacks(id = stack_id) if containers: global_stack = containers[0] + ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder Application.getInstance().setGlobalContainerStack(global_stack) self._global_container_stack = global_stack self.globalContainerChanged.emit() From 244b10940333c763315818770bd746252aa08dcc Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 21 Feb 2018 16:30:45 +0100 Subject: [PATCH 123/266] CURA-4606 CURA-4995 switching print core now correctly updates the material --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 85a02a8a30..cbb201610b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1063,7 +1063,7 @@ class MachineManager(QObject): material_manager = Application.getInstance()._material_manager material_diameter = self._global_container_stack.getProperty("material_diameter", "value") candidate_materials = material_manager.getAvailableMaterials( - self._global_container_stack.getId(), + self._global_container_stack.definition.getId(), current_variant_name, material_diameter) From 7a3ebe1a42ed992bf0fda1f56a9d9d8b168a5ffb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 16:28:11 +0100 Subject: [PATCH 124/266] Fix NozzleMenu active nozzle bullet --- cura/Settings/ExtruderManager.py | 9 +++------ cura/Settings/MachineManager.py | 5 +++-- resources/qml/Menus/NozzleMenu.qml | 16 ++++------------ 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 3bf248970e..fa045e9496 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -30,10 +30,11 @@ class ExtruderManager(QObject): def __init__(self, parent = None): super().__init__(parent) + self._application = Application.getInstance() + self._extruder_trains = {} # Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders. self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack self._selected_object_extruders = [] - self._global_container_stack_definition_id = None self._addCurrentMachineExtruders() #Application.getInstance().globalContainerStackChanged.connect(self._globalContainerStackChanged) @@ -365,10 +366,6 @@ class ExtruderManager(QObject): return result[:machine_extruder_count] def _globalContainerStackChanged(self) -> None: - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack and global_container_stack.getBottom() and global_container_stack.getBottom().getId() != self._global_container_stack_definition_id: - self._global_container_stack_definition_id = global_container_stack.getBottom().getId() - # If the global container changed, the machine changed and might have extruders that were not registered yet self._addCurrentMachineExtruders() @@ -376,7 +373,7 @@ class ExtruderManager(QObject): ## Adds the extruders of the currently active machine. def _addCurrentMachineExtruders(self) -> None: - global_stack = Application.getInstance().getGlobalContainerStack() + global_stack = self._application.getGlobalContainerStack() extruders_changed = False if global_stack: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index cbb201610b..6fc9245ffc 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -311,10 +311,11 @@ class MachineManager(QObject): ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder Application.getInstance().setGlobalContainerStack(global_stack) self._global_container_stack = global_stack - self.globalContainerChanged.emit() - self._onGlobalContainerChanged() + Application.getInstance().setGlobalContainerStack(global_stack) ExtruderManager.getInstance()._globalContainerStackChanged() self._initMachineState(containers[0]) + self.globalContainerChanged.emit() + self._onGlobalContainerChanged() self.__emitChangedSignals() diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 153bd88220..0b961a5a11 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -13,22 +13,12 @@ Menu title: "Nozzle" property int extruderIndex: 0 - property QtObject extruderStack: Cura.MachineManager.getExtruder(menu.extruderIndex) - property bool hasExtruderStack: extruderStack != null Cura.NozzleModel { id: nozzleModel } - Connections - { - target: Cura.MachineManager - onGlobalContainerChanged: { - menu.extruderStack = Cura.MachineManager.getExtruder(menu.extruderIndex); - } - } - Instantiator { model: nozzleModel @@ -37,10 +27,12 @@ Menu { text: model.hotend_name checkable: true - checked: menu.hasExtruderStack && extruderStack.variant.name == model.hotend_name + checked: { + return Cura.MachineManager.activeVariantNames[extruderIndex] == model.hotend_name + } exclusiveGroup: group onTriggered: { - Cura.MachineManager.setVariantGroup(extruderIndex, model.container_node); + Cura.MachineManager.setVariantGroup(menu.extruderIndex, model.container_node); } } From 4b1ec905c1a887f73ebe3c2a32ac50ba7b010005 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 16:39:34 +0100 Subject: [PATCH 125/266] Fix UM2 qualities --- resources/quality/ultimaker2/um2_draft.inst.cfg | 2 ++ resources/quality/ultimaker2/um2_fast.inst.cfg | 2 ++ resources/quality/ultimaker2/um2_high.inst.cfg | 2 ++ resources/quality/ultimaker2/um2_normal.inst.cfg | 1 + 4 files changed, 7 insertions(+) diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index 1115deacd9..88d3ed3520 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -8,5 +8,7 @@ setting_version = 4 type = quality quality_type = draft weight = -2 +global_quality = True [values] +layer_height = 0.2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 8bc5b7dee3..36e4fe03c2 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -8,9 +8,11 @@ setting_version = 4 type = quality quality_type = fast weight = -1 +global_quality = True [values] infill_sparse_density = 10 +layer_height = 0.15 cool_min_layer_time = 3 speed_wall_0 = 40 speed_wall_x = 80 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 8d6573b2be..2fb7ead455 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -8,7 +8,9 @@ setting_version = 4 type = quality quality_type = high weight = 1 +global_quality = True [values] +layer_height = 0.06 speed_topbottom = 15 speed_infill = 80 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index ea7efc64ac..51fe1f317c 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -8,5 +8,6 @@ setting_version = 4 type = quality quality_type = normal weight = 0 +global_quality = True [values] From d83b803fe0d5096f4ce7ed9d8a6820989e8b0bd6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 16:47:12 +0100 Subject: [PATCH 126/266] Fix: Update active material names if materials lookup table gets updated --- cura/Settings/MachineManager.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6fc9245ffc..7ca9040d2a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -123,6 +123,14 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) + # NEW + self._material_manager = self._application._material_manager + self._material_manager.materialsUpdated.connect(self._onMaterialsUpdated) + + def _onMaterialsUpdated(self): + # When the materials lookup table gets updated, it can mean that a material has its name changed, which should + # be reflected on the GUI. This signal emission makes sure that it happens. + self.rootMaterialChanged.emit() ### NEW activeQualityGroupChanged = pyqtSignal() From 7ea245a57dd8672b84fdaae5aac52586e3164b9d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 17:28:28 +0100 Subject: [PATCH 127/266] Fix: Show longer names on profile management page --- resources/qml/Preferences/ProfilesPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 2a6bd9c6f2..bcf624eb87 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -364,7 +364,7 @@ Item anchors.right: parent.right Label { - width: Math.floor((parent.width * 0.3)) + width: Math.floor((parent.width * 0.8)) text: model.name elide: Text.ElideRight font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName // TODO: make it easier From 47e4b35e700a52fc6e9289edd348a72974ee8bfa Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 19:44:42 +0100 Subject: [PATCH 128/266] WIP: Cleanup --- resources/qml/Preferences/ProfilesPage.qml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index bcf624eb87..1d29b26e50 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -367,7 +367,7 @@ Item width: Math.floor((parent.width * 0.8)) text: model.name elide: Text.ElideRight - font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName // TODO: make it easier + font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text } } @@ -380,16 +380,9 @@ Item } } } - - onCurrentIndexChanged: - { - var model = qualitiesModel.getItem(currentIndex); - // TODO - } } } - // details panel on the right Item { From f946f62db187030b50d6afacafce276e6a4838e9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 21 Feb 2018 20:27:33 +0100 Subject: [PATCH 129/266] WIP: Cleanup Upgrade 30 to 31 --- .../VersionUpgrade30to31.py | 74 ------------------- 1 file changed, 74 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py index d7b2c1a001..a88ff5ac1c 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py @@ -3,14 +3,9 @@ import configparser #To parse preference files. import io #To serialise the preference files afterwards. -import os -from urllib.parse import quote_plus -from UM.Resources import Resources from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. -from cura.CuraApplication import CuraApplication - # a list of all legacy "Not Supported" quality profiles _OLD_NOT_SUPPORTED_PROFILES = [ @@ -130,7 +125,6 @@ class VersionUpgrade30to31(VersionUpgrade): parser.write(output) return [filename], [output.getvalue()] - ## Upgrades a container stack from version 3.0 to 3.1. # # \param serialised The serialised form of a container stack. @@ -172,71 +166,3 @@ class VersionUpgrade30to31(VersionUpgrade): output = io.StringIO() parser.write(output) return [filename], [output.getvalue()] - - def _getSingleExtrusionMachineQualityChanges(self, quality_changes_container): - quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) - quality_changes_containers = [] - - for item in os.listdir(quality_changes_dir): - file_path = os.path.join(quality_changes_dir, item) - if not os.path.isfile(file_path): - continue - - parser = configparser.ConfigParser(interpolation = None) - try: - parser.read([file_path]) - except: - # skip, it is not a valid stack file - continue - - if not parser.has_option("metadata", "type"): - continue - if "quality_changes" != parser["metadata"]["type"]: - continue - - if not parser.has_option("general", "name"): - continue - if quality_changes_container["general"]["name"] != parser["general"]["name"]: - continue - - quality_changes_containers.append(parser) - - return quality_changes_containers - - def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes): - suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower()) - machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "") - - # Why is this here?! - # When we load a .curaprofile file the deserialize will trigger a version upgrade, creating a dangling file. - # This file can be recognized by it's lack of a machine name in the target filename. - # So when we detect that situation here, we don't create the file and return. - if machine_name == "": - return - - new_filename = machine_name + "_" + "fdmextruder" + suffix - - extruder_quality_changes_parser = configparser.ConfigParser(interpolation = None) - extruder_quality_changes_parser.add_section("general") - extruder_quality_changes_parser["general"]["version"] = str(2) - extruder_quality_changes_parser["general"]["name"] = global_quality_changes["general"]["name"] - extruder_quality_changes_parser["general"]["definition"] = global_quality_changes["general"]["definition"] - - # check renamed definition - if extruder_quality_changes_parser["general"]["definition"] in _RENAMED_DEFINITION_DICT: - extruder_quality_changes_parser["general"]["definition"] = _RENAMED_DEFINITION_DICT[extruder_quality_changes_parser["general"]["definition"]] - - extruder_quality_changes_parser.add_section("metadata") - extruder_quality_changes_parser["metadata"]["quality_type"] = global_quality_changes["metadata"]["quality_type"] - extruder_quality_changes_parser["metadata"]["type"] = global_quality_changes["metadata"]["type"] - extruder_quality_changes_parser["metadata"]["setting_version"] = str(4) - extruder_quality_changes_parser["metadata"]["extruder"] = "fdmextruder" - - extruder_quality_changes_output = io.StringIO() - extruder_quality_changes_parser.write(extruder_quality_changes_output) - extruder_quality_changes_filename = quote_plus(new_filename) + ".inst.cfg" - - quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) - - with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w", encoding = "utf-8") as f: - f.write(extruder_quality_changes_output.getvalue()) From 3591e01b251afd3e93cc5994380106c5547a2324 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 09:20:33 +0100 Subject: [PATCH 130/266] CURA-4606 CURA-5002 fix crash with machine with variants, but no variants defined --- cura/Machines/MaterialManager.py | 5 +++-- cura/Machines/VariantManager.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 664d55a4c1..54216972a4 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -256,8 +256,9 @@ class MaterialManager(QObject): material_id_metadata_dict = dict() for node in nodes_to_check: if node is not None: - material_id_metadata_dict = {mid: node for mid, node in node.material_map.items()} - break + for material_id, node in node.material_map.items(): + if material_id not in material_id_metadata_dict: + material_id_metadata_dict[material_id] = node return material_id_metadata_dict diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 05ddfe869c..834b47dd0f 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -83,4 +83,4 @@ class VariantManager: def getVariantNodes(self, machine: "GlobalStack", variant_type: Optional[str] = VariantType.NOZZLE) -> dict: machine_definition_id = machine.definition.getId() - return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}) + return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}) From 3095140bc338f7c4f6b8138a30562fc64510680f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 10:22:13 +0100 Subject: [PATCH 131/266] Fix quality/qualityChanges group initialization --- cura/Settings/MachineManager.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7ca9040d2a..4204beb6a4 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -290,21 +290,21 @@ class MachineManager(QObject): material_dict[position] = extruder.material.getMetaDataEntry("base_file") self._current_root_material_id = material_dict global_quality = global_stack.quality - global_quality_changes = global_stack.qualityChanges - - quality_groups = self._application._quality_manager.getQualityGroups(global_stack) quality_type = global_quality.getMetaDataEntry("quality_type") - if not quality_type in quality_groups: - Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) - return - new_quality_group = quality_groups[quality_type] - self._setQualityGroup(new_quality_group) + global_quality_changes = global_stack.qualityChanges if global_quality_changes.getId() != "empty_quality_changes": quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack) if quality_type in quality_changes_groups: new_quality_changes_group = quality_changes_groups[quality_type] self._setQualityChangesGroup(new_quality_changes_group) + else: + quality_groups = self._application._quality_manager.getQualityGroups(global_stack) + if quality_type not in quality_groups: + Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) + return + new_quality_group = quality_groups[quality_type] + self._setQualityGroup(new_quality_group) @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: From b014800eac3bacea790693ee04cb4984e761698e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 11:00:32 +0100 Subject: [PATCH 132/266] Fix various quality related issues --- cura/Settings/MachineManager.py | 35 ++++++++-------------- resources/qml/Preferences/ProfileTab.qml | 6 ++-- resources/qml/Preferences/ProfilesPage.qml | 8 ++--- resources/qml/SidebarAdvanced.qml | 2 +- 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4204beb6a4..7f74df60eb 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -527,18 +527,7 @@ class MachineManager(QObject): return quality_changes.getId() return "" - @pyqtProperty(str, notify=activeQualityChanged) - def globalQualityId(self) -> str: - if self._global_container_stack: - quality = self._global_container_stack.qualityChanges - if quality and not isinstance(quality, type(self._empty_quality_changes_container)): - return quality.getId() - quality = self._global_container_stack.quality - if quality: - return quality.getId() - return "" - - @pyqtProperty(str, notify=activeVariantChanged) + @pyqtProperty(str, notify = activeVariantChanged) def globalVariantName(self) -> str: if self._global_container_stack: variant = self._global_container_stack.variant @@ -546,21 +535,21 @@ class MachineManager(QObject): return variant.getName() return "" - @pyqtProperty(str, notify = activeQualityChanged) + @pyqtProperty(str, notify = activeQualityGroupChanged) def activeQualityType(self) -> str: + quality_type = "" if self._active_container_stack: - quality = self._active_container_stack.quality - if quality: - return quality.getMetaDataEntry("quality_type") - return "" + if self._current_quality_group: + quality_type = self._current_quality_group.quality_type + return quality_type - @pyqtProperty(bool, notify = activeQualityChanged) + @pyqtProperty(bool, notify = activeQualityGroupChanged) def isActiveQualitySupported(self) -> bool: - if self._active_container_stack: - quality = self._active_container_stack.quality - if quality: - return Util.parseBool(quality.getMetaDataEntry("supported", True)) - return False + is_supported = False + if self._global_container_stack: + if self._current_quality_group: + is_supported = self._current_quality_group.is_available + return is_supported ## Returns whether there is anything unsupported in the current set-up. # diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 5acbeecda9..b4b2299c15 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -36,8 +36,8 @@ Tab anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value - font.strikeout: styleData.column == 1 && setting.user_value != "" // TODO && quality == Cura.MachineManager.globalQualityId - font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "") // TODO: (setting.user_value != "" && quality == Cura.MachineManager.globalQualityId) + font.strikeout: styleData.column == 1 && setting.user_value != "" && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName + font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName) opacity: font.strikeout ? 0.5 : 1 color: styleData.textColor elide: Text.ElideRight @@ -63,7 +63,7 @@ Tab { role: "user_value" title: catalog.i18nc("@title:column", "Current"); - visible: true // TODO quality == Cura.MachineManager.globalQualityId + visible: qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName width: (parent.width * 0.18) | 0 delegate: itemDelegate } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 1d29b26e50..6a42034846 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -408,14 +408,14 @@ Item height: childrenRect.height Label { - text: base.currentItem.name // TODO + text: base.currentItem.name font: UM.Theme.getFont("large") } } Flow { id: currentSettingsActions - visible: true // TODO //currentItem && currentItem.id == Cura.MachineManager.activeQualityId + visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName anchors.left: parent.left anchors.right: parent.right anchors.top: profileName.bottom @@ -424,7 +424,7 @@ Item Button { text: catalog.i18nc("@action:button", "Update profile with current settings/overrides") - enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + enabled: Cura.MachineManager.hasUserSettings && !base.currentItem.is_read_only onClicked: Cura.ContainerManager.updateQualityChanges() } @@ -453,7 +453,7 @@ Item } Label { id: noCurrentSettingsMessage - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings + visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:label", "Your current settings match the selected profile.") wrapMode: Text.WordWrap width: parent.width diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/SidebarAdvanced.qml index ff5f545c80..ae77bc8d1b 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/SidebarAdvanced.qml @@ -1,7 +1,7 @@ // Copyright (c) 2015 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.8 import QtQuick.Controls 2.0 import "Settings" From 7a2c25226a1ebc150ceb7b4200ebe7ed3e621f32 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 12:59:26 +0100 Subject: [PATCH 133/266] Fix initial quality_changes group setup --- cura/Settings/MachineManager.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 7f74df60eb..47877c8a7f 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -79,6 +79,9 @@ class MachineManager(QObject): self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + self.globalContainerChanged.connect(self.activeQualityChangesGroupChanged) + self.globalContainerChanged.connect(self.activeQualityGroupChanged) + self._stacks_have_errors = None # type:Optional[bool] self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0] @@ -242,6 +245,7 @@ class MachineManager(QObject): Application.getInstance().callLater(func) del self.machine_extruder_material_update_dict[self._global_container_stack.getId()] + self.activeQualityGroupChanged.emit() self._error_check_timer.start() ## Update self._stacks_valid according to _checkStacksForErrors and emit if change. @@ -292,11 +296,12 @@ class MachineManager(QObject): global_quality = global_stack.quality quality_type = global_quality.getMetaDataEntry("quality_type") global_quality_changes = global_stack.qualityChanges + global_quality_changes_name = global_quality_changes.getName() if global_quality_changes.getId() != "empty_quality_changes": quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack) - if quality_type in quality_changes_groups: - new_quality_changes_group = quality_changes_groups[quality_type] + if global_quality_changes_name in quality_changes_groups: + new_quality_changes_group = quality_changes_groups[global_quality_changes_name] self._setQualityChangesGroup(new_quality_changes_group) else: quality_groups = self._application._quality_manager.getQualityGroups(global_stack) From 25dd63dc215247e50518488090c25c2c5aad60ee Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 13:45:46 +0100 Subject: [PATCH 134/266] WIP: Cleanup MachineManager --- cura/Settings/MachineManager.py | 19 ++----------------- resources/qml/Actions.qml | 2 +- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 47877c8a7f..76aefb3c0b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -496,7 +496,7 @@ class MachineManager(QObject): # # \return The layer height of the currently active quality profile. If # there is no quality profile, this returns 0. - @pyqtProperty(float, notify=activeQualityChanged) + @pyqtProperty(float, notify = activeQualityGroupChanged) def activeQualityLayerHeight(self) -> float: if not self._global_container_stack: return 0 @@ -516,22 +516,6 @@ class MachineManager(QObject): return 0 # No quality profile. - @pyqtProperty(str, notify=activeQualityChanged) - def activeQualityId(self) -> str: - if self._active_container_stack: - quality = self._active_container_stack.quality - if isinstance(quality, type(self._empty_quality_container)): - return "" - quality_changes = self._active_container_stack.qualityChanges - if quality and quality_changes: - if isinstance(quality_changes, type(self._empty_quality_changes_container)): - # It's a built-in profile - return quality.getId() - else: - # Custom profile - return quality_changes.getId() - return "" - @pyqtProperty(str, notify = activeVariantChanged) def globalVariantName(self) -> str: if self._global_container_stack: @@ -939,6 +923,7 @@ class MachineManager(QObject): extruder.qualityChanges = self._empty_quality_changes_container self.activeQualityGroupChanged.emit() + self.activeQualityChangesGroupChanged.emit() def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 05ff5050e9..23c19bece8 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -173,7 +173,7 @@ Item Action { id: updateProfileAction; - enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityChangesGroup != null text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings/overrides"); onTriggered: Cura.ContainerManager.updateQualityChanges(); } From b415a361101cffec1eaafcb4a3fd179d3aa9f212 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 13:58:35 +0100 Subject: [PATCH 135/266] WIP: Remove delayed update in MachineManager --- cura/CuraApplication.py | 3 -- cura/Settings/MachineManager.py | 77 --------------------------------- 2 files changed, 80 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 464694dbcd..a1a2f52305 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -540,8 +540,6 @@ class CuraApplication(QtApplication): has_user_interaction = True return has_user_interaction - onDiscardOrKeepProfileChangesClosed = pyqtSignal() # Used to notify other managers that the dialog was closed - @pyqtSlot(str) def discardOrKeepProfileChangesClosed(self, option): if option == "discard": @@ -564,7 +562,6 @@ class CuraApplication(QtApplication): user_global_container.update() # notify listeners that quality has changed (after user selected discard or keep) - self.onDiscardOrKeepProfileChangesClosed.emit() self.getMachineManager().activeQualityChanged.emit() @pyqtSlot(int) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 76aefb3c0b..f2446b8017 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -54,12 +54,6 @@ class MachineManager(QObject): self.machine_extruder_material_update_dict = collections.defaultdict(list) - # Used to store the new containers until after confirming the dialog - self._new_variant_container = None # type: Optional[InstanceContainer] - self._new_buildplate_container = None # type: Optional[InstanceContainer] - self._new_material_container = None # type: Optional[InstanceContainer] - self._new_quality_containers = [] # type: List[Dict] - self._error_check_timer = QTimer() self._error_check_timer.setInterval(250) self._error_check_timer.setSingleShot(True) @@ -104,9 +98,6 @@ class MachineManager(QObject): ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged) self.activeStackChanged.connect(self.activeStackValueChanged) - # when a user closed dialog check if any delayed material or variant changes need to be applied - Application.getInstance().onDiscardOrKeepProfileChangesClosed.connect(self._executeDelayedActiveContainerStackChanges) - Preferences.getInstance().addPreference("cura/active_machine", "") self._global_event_keys = set() @@ -172,18 +163,6 @@ class MachineManager(QObject): self.outputDevicesChanged.emit() - @property - def newVariant(self): - return self._new_variant_container - - @property - def newBuildplate(self): - return self._new_buildplate_container - - @property - def newMaterial(self): - return self._new_material_container - @pyqtProperty("QVariantList", notify = outputDevicesChanged) def printerOutputDevices(self): return self._printer_output_devices @@ -314,7 +293,6 @@ class MachineManager(QObject): @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: self.blurSettings.emit() # Ensure no-one has focus. - self._cancelDelayedActiveContainerStackChanges() container_registry = ContainerRegistry.getInstance() @@ -573,61 +551,6 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved - ## Used to update material and variant in the active container stack with a delay. - # This delay prevents the stack from triggering a lot of signals (eventually resulting in slicing) - # before the user decided to keep or discard any of their changes using the dialog. - # The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method. - def _executeDelayedActiveContainerStackChanges(self): - Logger.log("d", "Applying configuration changes...") - - if self._new_variant_container is not None: - self._active_container_stack.variant = self._new_variant_container - self._new_variant_container = None - - if self._new_buildplate_container is not None: - self._global_container_stack.variant = self._new_buildplate_container - self._new_buildplate_container = None - - if self._new_material_container is not None: - self._active_container_stack.material = self._new_material_container - self._new_material_container = None - - # apply the new quality to all stacks - if self._new_quality_containers: - for new_quality in self._new_quality_containers: - self._replaceQualityOrQualityChangesInStack(new_quality["stack"], new_quality["quality"], postpone_emit = True) - self._replaceQualityOrQualityChangesInStack(new_quality["stack"], new_quality["quality_changes"], postpone_emit = True) - - for new_quality in self._new_quality_containers: - new_quality["stack"].nameChanged.connect(self._onQualityNameChanged) - new_quality["stack"].sendPostponedEmits() # Send the signals that were postponed in _replaceQualityOrQualityChangesInStack - - self._new_quality_containers.clear() - - Logger.log("d", "New configuration applied") - - ## Cancel set changes for material and variant in the active container stack. - # Used for ignoring any changes when switching between printers (setActiveMachine) - def _cancelDelayedActiveContainerStackChanges(self): - self._new_material_container = None - self._new_buildplate_container = None - self._new_variant_container = None - - def _replaceQualityOrQualityChangesInStack(self, stack: "CuraContainerStack", container: "InstanceContainer", postpone_emit = False): - # Disconnect the signal handling from the old container. - container_type = container.getMetaDataEntry("type") - if container_type == "quality": - stack.quality.nameChanged.disconnect(self._onQualityNameChanged) - stack.setQuality(container, postpone_emit = postpone_emit) - stack.quality.nameChanged.connect(self._onQualityNameChanged) - elif container_type == "quality_changes" or container_type is None: - # If the container is an empty container, we need to change the quality_changes. - # Quality can never be set to empty. - stack.qualityChanges.nameChanged.disconnect(self._onQualityNameChanged) - stack.setQualityChanges(container, postpone_emit = postpone_emit) - stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged) - self._onQualityNameChanged() - @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self) -> str: if self._active_container_stack: From 392f7297318b62ded0f02c3fcc3b6a4aaa7e8814 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 14:21:10 +0100 Subject: [PATCH 136/266] Reduce number of QML singletons --- cura/CuraApplication.py | 8 ++++++-- resources/qml/Menus/BuildplateMenu.qml | 8 +++++--- resources/qml/Menus/ContextMenu.qml | 12 +++++++----- resources/qml/Menus/ViewMenu.qml | 10 ++++++---- resources/qml/ObjectsList.qml | 14 ++++++-------- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a1a2f52305..a2dc27f483 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -2,6 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. #Type hinting. from typing import Dict + +from PyQt5.QtCore import QObject from PyQt5.QtNetwork import QLocalServer from PyQt5.QtNetwork import QLocalSocket @@ -859,11 +861,13 @@ class CuraApplication(QtApplication): self._object_manager = ObjectsModel.createObjectsModel() return self._object_manager + @pyqtSlot(result = QObject) def getMultiBuildPlateModel(self, *args): if self._multi_build_plate_model is None: self._multi_build_plate_model = MultiBuildPlateModel(self) return self._multi_build_plate_model + @pyqtSlot(result = QObject) def getBuildPlateModel(self, *args): if self._build_plate_model is None: self._build_plate_model = BuildPlateModel(self) @@ -936,8 +940,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 0, "ObjectsModel", self.getObjectsModel) - qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel", self.getBuildPlateModel) - qmlRegisterSingletonType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel", self.getMultiBuildPlateModel) + qmlRegisterType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel") + qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel") qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer") qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel") diff --git a/resources/qml/Menus/BuildplateMenu.qml b/resources/qml/Menus/BuildplateMenu.qml index 8dfc3ced6c..0b67b37cc1 100644 --- a/resources/qml/Menus/BuildplateMenu.qml +++ b/resources/qml/Menus/BuildplateMenu.qml @@ -12,17 +12,19 @@ Menu id: menu title: "Build plate" + property Cura.BuildPlateModel buildPlateModel: CuraApplication.getBuildPlateModel() + Instantiator { - model: Cura.BuildPlateModel + model: menu.buildPlateModel MenuItem { text: model.name checkable: true - checked: model.name == Cura.MachineManager.globalVariantName // TODO + checked: model.name == Cura.MachineManager.globalVariantName exclusiveGroup: group onTriggered: { - Cura.MachineManager.setGlobalVariant(model.container_node); // TODO + Cura.MachineManager.setGlobalVariant(model.container_node); } } diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index a37204d255..656e94b336 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -15,6 +15,8 @@ Menu property bool shouldShowExtruders: machineExtruderCount.properties.value > 1; + property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + // Selection-related actions. MenuItem { action: Cura.Actions.centerSelection; } MenuItem { action: Cura.Actions.deleteSelection; } @@ -45,13 +47,13 @@ Menu Instantiator { - model: Cura.MultiBuildPlateModel + model: base.multiBuildPlateModel MenuItem { enabled: UM.Selection.hasSelection - text: Cura.MultiBuildPlateModel.getItem(index).name; - onTriggered: CuraActions.setBuildPlateForSelection(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber); + text: base.multiBuildPlateModel.getItem(index).name; + onTriggered: CuraActions.setBuildPlateForSelection(base.multiBuildPlateModel.getItem(index).buildPlateNumber); checkable: true - checked: Cura.MultiBuildPlateModel.selectionBuildPlates.indexOf(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber) != -1; + checked: base.multiBuildPlateModel.selectionBuildPlates.indexOf(base.multiBuildPlateModel.getItem(index).buildPlateNumber) != -1; visible: UM.Preferences.getValue("cura/use_multi_build_plate") } onObjectAdded: base.insertItem(index, object); @@ -62,7 +64,7 @@ Menu enabled: UM.Selection.hasSelection text: "New build plate"; onTriggered: { - CuraActions.setBuildPlateForSelection(Cura.MultiBuildPlateModel.maxBuildPlate + 1); + CuraActions.setBuildPlateForSelection(base.multiBuildPlateModel.maxBuildPlate + 1); checked = false; } checkable: true diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index ff749bec90..fc0339e0c6 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -13,6 +13,8 @@ Menu id: base enabled: !PrintInformation.preSliced + property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + // main views Instantiator { @@ -53,12 +55,12 @@ Menu visible: UM.Preferences.getValue("cura/use_multi_build_plate") Instantiator { - model: Cura.MultiBuildPlateModel + model: base.multiBuildPlateModel MenuItem { - text: Cura.MultiBuildPlateModel.getItem(index).name; - onTriggered: Cura.SceneController.setActiveBuildPlate(Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber); + text: base.multiBuildPlateModel.getItem(index).name; + onTriggered: Cura.SceneController.setActiveBuildPlate(base.multiBuildPlateModel.getItem(index).buildPlateNumber); checkable: true; - checked: Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber == Cura.MultiBuildPlateModel.activeBuildPlate; + checked: base.multiBuildPlateModel.getItem(index).buildPlateNumber == base.multiBuildPlateModel.activeBuildPlate; exclusiveGroup: buildPlateGroup; visible: UM.Preferences.getValue("cura/use_multi_build_plate") } diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index f51e1081e6..e7dd63ea05 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -33,6 +33,8 @@ Rectangle property bool collapsed: true; + property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel() + SystemPalette { id: palette } Button { @@ -67,7 +69,7 @@ Rectangle Rectangle { height: childrenRect.height - color: Cura.MultiBuildPlateModel.getItem(index).buildPlateNumber == Cura.MultiBuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase + color: multiBuildPlateModel.getItem(index).buildPlateNumber == multiBuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase width: parent.width Label { @@ -75,8 +77,8 @@ Rectangle anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30 - text: Cura.MultiBuildPlateModel.getItem(index) ? Cura.MultiBuildPlateModel.getItem(index).name : ""; - color: Cura.MultiBuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text + text: multiBuildPlateModel.getItem(index) ? multiBuildPlateModel.getItem(index).name : ""; + color: multiBuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text elide: Text.ElideRight } @@ -118,13 +120,12 @@ Rectangle ListView { id: buildPlateListView - model: Cura.MultiBuildPlateModel + model: multiBuildPlateModel width: parent.width delegate: buildPlateDelegate } } - Component { id: objectDelegate Rectangle @@ -200,7 +201,6 @@ Rectangle } } - CheckBox { id: filterBuildPlateCheckbox @@ -260,6 +260,4 @@ Rectangle } action: Cura.Actions.arrangeAll; } - - } From 32afa9bfd4e544402a207e95ef78da9dba6c4d63 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 14:27:58 +0100 Subject: [PATCH 137/266] CURA-4606 CURA-5003 fixed sometimes crash material management page upon opening, provide correct containerId to MaterialView --- resources/qml/Preferences/MaterialsPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 8d14ada759..22d906ac62 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -433,8 +433,8 @@ Item editingEnabled: base.currentItem != null && !base.currentItem.is_read_only properties: materialProperties - containerId: base.currentItem != null ? base.currentItem.id : "" - currentMaterialNode: base.currentItem + containerId: base.currentItem != null ? base.currentItem.container_id : "" + currentMaterialNode: base.currentItem.container_node property alias pane: base } From a88e69d109fcf643980a50d8b9823695be348ef8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 15:00:12 +0100 Subject: [PATCH 138/266] Revert "WIP: Fix quality profiles for abax_pri5" Keep the old quality profiles for now to make it safe. --- resources/definitions/abax_pri5.def.json | 4 +--- .../quality/abax_pri5/apri5_pla_fast.inst.cfg | 22 +++++++++++++++++++ .../quality/abax_pri5/apri5_pla_high.inst.cfg | 22 +++++++++++++++++++ .../abax_pri5/apri5_pla_normal.inst.cfg | 22 +++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 resources/quality/abax_pri5/apri5_pla_fast.inst.cfg create mode 100644 resources/quality/abax_pri5/apri5_pla_high.inst.cfg create mode 100644 resources/quality/abax_pri5/apri5_pla_normal.inst.cfg diff --git a/resources/definitions/abax_pri5.def.json b/resources/definitions/abax_pri5.def.json index b8310221b1..cbebb576b0 100644 --- a/resources/definitions/abax_pri5.def.json +++ b/resources/definitions/abax_pri5.def.json @@ -6,9 +6,7 @@ "visible": true, "author": "ABAX 3d Technologies", "manufacturer": "ABAX 3d Technologies", - "file_formats": "text/x-gcode", - "quality_definition": "abax_pri3", - "has_machine_quality": true + "file_formats": "text/x-gcode" }, "overrides": { "machine_start_gcode": { diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg new file mode 100644 index 0000000000..517c767ac5 --- /dev/null +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Fine +definition = abax_pri5 + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = -1 +material = generic_pla + +[values] +layer_height = 0.2 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 80 +speed_layer_0 = =round(speed_print * 30 / 50) +speed_topbottom = 20 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg new file mode 100644 index 0000000000..01699e39f6 --- /dev/null +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Extra Fine +definition = abax_pri5 + +[metadata] +setting_version = 4 +type = quality +quality_type = high +weight = 1 +material = generic_pla + +[values] +layer_height = 0.1 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 50 +speed_layer_0 = =round(speed_print * 30 / 50) +speed_topbottom = 20 +cool_min_layer_time = 5 +cool_min_speed = 10 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg new file mode 100644 index 0000000000..ea1023dc43 --- /dev/null +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -0,0 +1,22 @@ +[general] +version = 2 +name = Fine +definition = abax_pri5 + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 0 +material = generic_pla + +[values] +layer_height = 0.2 +wall_thickness = 1.05 +top_bottom_thickness = 0.8 +infill_sparse_density = 20 +speed_print = 50 +speed_layer_0 = =round(speed_print * 30 / 50) +speed_topbottom = 20 +cool_min_layer_time = 5 +cool_min_speed = 10 From 0846021b674fa672a5842559479c708ce8d0b5a1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 15:12:15 +0100 Subject: [PATCH 139/266] Fix imade3d jellybox quality profiles --- .../generic_petg_0.4_coarse.inst.cfg | 3 --- .../generic_petg_0.4_coarse_2-fans.inst.cfg | 3 --- .../generic_petg_0.4_medium.inst.cfg | 3 --- .../generic_petg_0.4_medium_2-fans.inst.cfg | 3 --- .../generic_pla_0.4_coarse.inst.cfg | 3 --- .../generic_pla_0.4_coarse_2-fans.inst.cfg | 3 --- .../generic_pla_0.4_fine.inst.cfg | 3 --- .../generic_pla_0.4_fine_2-fans.inst.cfg | 3 --- .../generic_pla_0.4_medium.inst.cfg | 3 --- .../generic_pla_0.4_medium_2-fans.inst.cfg | 3 --- .../generic_pla_0.4_ultrafine.inst.cfg | 3 --- .../generic_pla_0.4_ultrafine_2-fans.inst.cfg | 2 -- .../imade3d_jellybox_coarse.inst.cfg | 16 ++++++++++++++++ .../imade3d_jellybox_fine.inst.cfg | 16 ++++++++++++++++ .../imade3d_jellybox_normal.inst.cfg | 16 ++++++++++++++++ .../imade3d_jellybox_ultrafine.inst.cfg | 16 ++++++++++++++++ 16 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg create mode 100644 resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg create mode 100644 resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg create mode 100644 resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index e5b3aed52b..f300f5d95b 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -12,7 +12,6 @@ material = generic_petg variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.3 -layer_height_0 = 0.3 line_width = 0.4 material_bed_temperature = 50 material_bed_temperature_layer_0 = 55 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index e7f2d5d60a..804807184b 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -12,7 +12,6 @@ material = generic_petg variant = 0.4 mm 2-fans [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.3 -layer_height_0 = 0.3 line_width = 0.4 material_bed_temperature = 50 material_bed_temperature_layer_0 = 55 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index 4d122f1ac2..c39c8a7a98 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -12,7 +12,6 @@ material = generic_petg variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.2 -layer_height_0 = 0.3 line_width = 0.4 material_bed_temperature = 50 material_bed_temperature_layer_0 = 55 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index 9646b0bb5f..17cc1493e1 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -12,7 +12,6 @@ material = generic_petg variant = 0.4 mm 2-fans [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.2 -layer_height_0 = 0.3 line_width = 0.4 material_bed_temperature = 50 material_bed_temperature_layer_0 = 55 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 8ecfa927a7..738eb627fe 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.3 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 meshfix_union_all = False diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 52c7df70f3..4f44559fbc 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm 2-fans [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.3 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 meshfix_union_all = False diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index a48dbe2f81..f9f32237b0 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.1 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 material_print_temperature = 205 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index 4707337611..82f5a4fa32 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm 2-fans [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.1 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 material_print_temperature = 205 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 2f5a0f33a8..5ee2111c3a 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.2 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 meshfix_union_all = False diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index f0451fc9be..5d34259ccd 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm 2-fans [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.2 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 meshfix_union_all = False diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index 179623153a..1826e69513 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -12,7 +12,6 @@ material = generic_pla variant = 0.4 mm [values] -adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 @@ -27,8 +26,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.05 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 material_print_temperature = 202 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index b35db0fde6..5b05c10604 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -27,8 +27,6 @@ infill_line_width = 0.6 infill_overlap = 15 infill_pattern = zigzag infill_sparse_density = 20 -layer_height = 0.05 -layer_height_0 = 0.3 line_width = 0.4 material_flow = 90 material_print_temperature = 202 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg new file mode 100644 index 0000000000..2e940ea646 --- /dev/null +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg @@ -0,0 +1,16 @@ +[general] +version = 2 +name = Coarse +definition = imade3d_jellybox + +[metadata] +setting_version = 4 +type = quality +quality_type = fast +weight = -1 +global_quality = True + +[values] +adhesion_type = skirt +layer_height = 0.3 +layer_height_0 = 0.3 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg new file mode 100644 index 0000000000..9979558963 --- /dev/null +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg @@ -0,0 +1,16 @@ +[general] +version = 2 +name = Fine +definition = imade3d_jellybox + +[metadata] +setting_version = 4 +type = quality +quality_type = high +weight = 1 +global_quality = True + +[values] +adhesion_type = skirt +layer_height = 0.1 +layer_height_0 = 0.3 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg new file mode 100644 index 0000000000..0574099b63 --- /dev/null +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg @@ -0,0 +1,16 @@ +[general] +version = 2 +name = Medium +definition = imade3d_jellybox + +[metadata] +setting_version = 4 +type = quality +quality_type = normal +weight = 0 +global_quality = True + +[values] +adhesion_type = skirt +layer_height = 0.2 +layer_height_0 = 0.3 diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg new file mode 100644 index 0000000000..39344ce7f4 --- /dev/null +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg @@ -0,0 +1,16 @@ +[general] +version = 2 +name = UltraFine +definition = imade3d_jellybox + +[metadata] +setting_version = 4 +type = quality +quality_type = ultrahigh +weight = 2 +global_quality = True + +[values] +adhesion_type = skirt +layer_height = 0.05 +layer_height_0 = 0.3 From 21e4ed1ae9bed29307c336139c74f19def3fc52a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 14 Feb 2018 20:48:21 +0100 Subject: [PATCH 140/266] Fix punchtec extruder IDs --- ...uder_left.def.json => punchtec_connect_xl_extruder_0.def.json} | 0 ...der_right.def.json => punchtec_connect_xl_extruder_1.def.json} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename resources/extruders/{punchtec_connect_xl_extruder_left.def.json => punchtec_connect_xl_extruder_0.def.json} (100%) rename resources/extruders/{punchtec_connect_xl_extruder_right.def.json => punchtec_connect_xl_extruder_1.def.json} (100%) diff --git a/resources/extruders/punchtec_connect_xl_extruder_left.def.json b/resources/extruders/punchtec_connect_xl_extruder_0.def.json similarity index 100% rename from resources/extruders/punchtec_connect_xl_extruder_left.def.json rename to resources/extruders/punchtec_connect_xl_extruder_0.def.json diff --git a/resources/extruders/punchtec_connect_xl_extruder_right.def.json b/resources/extruders/punchtec_connect_xl_extruder_1.def.json similarity index 100% rename from resources/extruders/punchtec_connect_xl_extruder_right.def.json rename to resources/extruders/punchtec_connect_xl_extruder_1.def.json From ab8fda8812684bad30d84128d9dfad041afb448d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 15:21:48 +0100 Subject: [PATCH 141/266] Fix createMachine: evaluate material diameter if it is a function --- cura/Settings/CuraStackBuilder.py | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index fc0d4f6f8e..9273b272c1 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -7,6 +7,7 @@ from UM.Logger import Logger from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.SettingFunction import SettingFunction from UM.Util import parseBool from cura.Machines.VariantManager import VariantType @@ -50,7 +51,6 @@ class CuraStackBuilder: (definition_id, global_variant_name)) global_variant_container = variant_node.getContainer() - # get variant container for extruders extruder_variant_container = application.empty_variant_container # Only look for the preferred variant if this machine has variants @@ -65,21 +65,6 @@ class CuraStackBuilder: (definition_id, extruder_variant_name)) extruder_variant_container = variant_node.getContainer() - # get material container for extruders - material_container = application.empty_material_container - # Only look for the preferred material if this machine has materials - if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): - material_diameter = machine_definition.getProperty("material_diameter", "value") - approximate_material_diameter = str(round(material_diameter)) - root_material_id = machine_definition.getMetaDataEntry("preferred_material") - root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) - material_node = material_manager.getMaterialNode(definition_id, extruder_variant_name, material_diameter, root_material_id) - # Sanity check. If you see this error, the related definition files should be fixed. - if not material_node: - raise RuntimeError("Cannot find material with definition [%s], extruder_variant_name [%s], and root_material_id [%s]" % - (definition_id, extruder_variant_name, root_material_id)) - material_container = material_node.getContainer() - generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) # Make sure the new name does not collide with any definition or (quality) profile # createUniqueName() only looks at other stacks, but not at definitions or quality profiles @@ -96,6 +81,23 @@ class CuraStackBuilder: ) new_global_stack.setName(generated_name) + # get material container for extruders + material_container = application.empty_material_container + # Only look for the preferred material if this machine has materials + if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): + material_diameter = machine_definition.getProperty("material_diameter", "value") + if isinstance(material_diameter, SettingFunction): + material_diameter = material_diameter(new_global_stack) + approximate_material_diameter = str(round(material_diameter)) + root_material_id = machine_definition.getMetaDataEntry("preferred_material") + root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) + material_node = material_manager.getMaterialNode(definition_id, extruder_variant_name, material_diameter, root_material_id) + # Sanity check. If you see this error, the related definition files should be fixed. + if not material_node: + raise RuntimeError("Cannot find material with definition [%s], extruder_variant_name [%s], and root_material_id [%s]" % + (definition_id, extruder_variant_name, root_material_id)) + material_container = material_node.getContainer() + # Create ExtruderStacks extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains") From c7499d6e1714a983c1a2072981af6176c76e40f5 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 15:52:02 +0100 Subject: [PATCH 142/266] CURA-4606 CURA-5003 fix saving material metadata when switching material; fix crashing on fallback material on materials without fallback --- cura/Machines/MaterialManager.py | 3 ++- resources/qml/Preferences/MaterialsPage.qml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 54216972a4..ae679a5ee6 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -314,7 +314,8 @@ class MaterialManager(QObject): def getFallbackMaterialId(self, material_type: str) -> str: # For safety if material_type not in self._fallback_materials_map: - raise RuntimeError("Material type [%s] is not in the fallback materials table." % material_type) + Logger.log("w", "The material type [%s] does not have a fallback material" % material_type) + return None fallback_material = self._fallback_materials_map[material_type] if fallback_material: return self.getRootMaterialIDWithoutDiameter(fallback_material["id"]) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 22d906ac62..de7b629f48 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -350,6 +350,7 @@ Item onCurrentIndexChanged: { + forceActiveFocus(); // causes the changed fields to be saved var model = materialsModel.getItem(currentIndex); materialDetailsView.containerId = model.container_id; materialDetailsView.currentMaterialNode = model.container_node; From 32e1015f25cc3f0ae76db086066c937e09cc50d7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 16:02:41 +0100 Subject: [PATCH 143/266] WIP: Cleanup PrintInformation --- cura/PrintInformation.py | 60 +++++++--------------- cura/Settings/MachineManager.py | 19 +++---- resources/qml/Preferences/MachinesPage.qml | 5 +- 3 files changed, 27 insertions(+), 57 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 9cbd7aec7e..d1ab8506ab 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -1,27 +1,22 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty -from UM.FlameProfiler import pyqtSlot +from typing import Dict +import math +import os.path +import unicodedata +import json +import re # To create abbreviations for printer names. + +from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from UM.Application import Application from UM.Logger import Logger from UM.Qt.Duration import Duration from UM.Preferences import Preferences from UM.Scene.SceneNode import SceneNode -from UM.Settings.ContainerRegistry import ContainerRegistry -from cura.Scene.CuraSceneNode import CuraSceneNode - -from cura.Settings.ExtruderManager import ExtruderManager -from typing import Dict - -import math -import os.path -import unicodedata -import json -import re #To create abbreviations for printer names. - from UM.i18n import i18nCatalog + catalog = i18nCatalog("cura") ## A class for processing and calculating minimum, current and maximum print time as well as managing the job name @@ -86,9 +81,8 @@ class PrintInformation(QObject): Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) - self._active_material_container = None - self._application.getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged) - self._onActiveMaterialChanged() + self._application.getMachineManager().rootMaterialChanged.connect(self._onActiveMaterialsChanged) + self._onActiveMaterialsChanged() self._material_amounts = [] @@ -203,7 +197,8 @@ class PrintInformation(QObject): self._current_print_time[build_plate_number].setDuration(total_estimated_time) def _calculateInformation(self, build_plate_number): - if Application.getInstance().getGlobalContainerStack() is None: + global_stack = Application.getInstance().getGlobalContainerStack() + if global_stack is None: return # Material amount is sent as an amount of mm^3, so calculate length from that @@ -215,18 +210,13 @@ class PrintInformation(QObject): material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings")) - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId())) + extruder_stacks = global_stack.extruders for index, amount in enumerate(self._material_amounts): ## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some # list comprehension filtering to solve this for us. - material = None - if extruder_stacks: # Multi extrusion machine - extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0] - density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0) - material = extruder_stack.findContainer({"type": "material"}) - else: # Machine with no extruder stacks - density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0) - material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"}) + extruder_stack = extruder_stacks[str(index)] + density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0) + material = extruder_stack.findContainer({"type": "material"}) weight = float(amount) * float(density) / 1000 cost = 0 @@ -266,20 +256,6 @@ class PrintInformation(QObject): for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1): self._calculateInformation(build_plate_number) - def _onActiveMaterialChanged(self): - if self._active_material_container: - try: - self._active_material_container.metaDataChanged.disconnect(self._onMaterialMetaDataChanged) - except TypeError: #pyQtSignal gives a TypeError when disconnecting from something that is already disconnected. - pass - - active_material_id = Application.getInstance().getMachineManager().activeMaterialId - active_material_containers = ContainerRegistry.getInstance().findInstanceContainers(id = active_material_id) - - if active_material_containers: - self._active_material_container = active_material_containers[0] - self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged) - def _onActiveBuildPlateChanged(self): new_active_build_plate = self._multi_build_plate_model.activeBuildPlate if new_active_build_plate != self._active_build_plate: @@ -293,7 +269,7 @@ class PrintInformation(QObject): self.materialNamesChanged.emit() self.currentPrintTimeChanged.emit() - def _onMaterialMetaDataChanged(self, *args, **kwargs): + def _onActiveMaterialsChanged(self, *args, **kwargs): for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1): self._calculateInformation(build_plate_number) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f2446b8017..4013b1e1cd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -409,25 +409,16 @@ class MachineManager(QObject): def stacksHaveErrors(self) -> bool: return bool(self._stacks_have_errors) - @pyqtProperty(str, notify = activeStackChanged) - def activeUserProfileId(self) -> str: - if self._active_container_stack: - return self._active_container_stack.getTop().getId() - - return "" - @pyqtProperty(str, notify = globalContainerChanged) def activeMachineName(self) -> str: if self._global_container_stack: return self._global_container_stack.getName() - return "" @pyqtProperty(str, notify = globalContainerChanged) def activeMachineId(self) -> str: if self._global_container_stack: return self._global_container_stack.getId() - return "" @pyqtProperty(QObject, notify = globalContainerChanged) @@ -438,16 +429,18 @@ class MachineManager(QObject): def activeStackId(self) -> str: if self._active_container_stack: return self._active_container_stack.getId() - return "" + @pyqtProperty(QObject, notify = activeStackChanged) + def activeStack(self) -> Optional["ExtruderStack"]: + return self._active_container_stack + @pyqtProperty(str, notify=activeMaterialChanged) def activeMaterialId(self) -> str: if self._active_container_stack: material = self._active_container_stack.material if material: return material.getId() - return "" ## Gets a dict with the active materials ids set in all extruder stacks and the global stack @@ -804,9 +797,9 @@ class MachineManager(QObject): @pyqtProperty("QVariant", notify = rootMaterialChanged) def currentRootMaterialId(self): # initial filling the current_root_material_id + self._current_root_material_id = {} for position in self._global_container_stack.extruders: - if position not in self._current_root_material_id: - self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") + self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file") return self._current_root_material_id @pyqtProperty("QVariant", notify = rootMaterialChanged) diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 889dfa8d5b..49a8d286a8 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -1,13 +1,14 @@ // Copyright (c) 2016 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 import QtQuick.Window 2.1 import UM 1.2 as UM import Cura 1.0 as Cura + UM.ManagementPage { id: base; From b209badf6868e915a689cd6def63ad3b200eb537 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 16:14:01 +0100 Subject: [PATCH 144/266] CURA-4606 CURA-5003 fix density and diameter in material manager --- resources/qml/Preferences/MaterialsPage.qml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index de7b629f48..e4856a2d4b 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -388,18 +388,9 @@ Item materialProperties.description = currentItem.description ? currentItem.description : ""; materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : ""; - if(currentItem.properties != undefined && currentItem.properties != null) - { - materialProperties.density = currentItem.density ? currentItem.density : 0.0; - materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0; - materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0"; - } - else - { - materialProperties.density = 0.0; - materialProperties.diameter = 0.0; - materialProperties.approximate_diameter = "0"; - } + materialProperties.density = currentItem.density ? currentItem.density : 0.0; + materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0; + materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0"; } Item From a8bd57a9ebc1737869b2957fc21bb0888908f11c Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 16:17:32 +0100 Subject: [PATCH 145/266] CURA-4606 CURA-5003 brands sections in materials management page are now case insensitive --- cura/Machines/Models/MaterialsModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py index 97a1d27a31..6b253790f1 100644 --- a/cura/Machines/Models/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -287,5 +287,5 @@ class MaterialsModel(ListModel): material_list.append(item) - material_list = sorted(material_list, key = lambda k: (k["brand"], k["name"])) + material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"])) self.setItems(material_list) From d2ffd59431fc8f94cc6bcb7decd17cf85c02f8f8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 16:52:54 +0100 Subject: [PATCH 146/266] Switch to the new quality profile when it is created --- cura/CuraApplication.py | 21 ++++++++++----- cura/Settings/ContainerManager.py | 8 +----- resources/qml/Preferences/ProfilesPage.qml | 30 +++++++++++++++++++++- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a2dc27f483..152ad05f9a 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -240,8 +240,7 @@ class CuraApplication(QtApplication): if kwargs["parsed_command_line"].get("trigger_early_crash", False): assert not "This crash is triggered by the trigger_early_crash command line argument." - # new stuff - self._variant_manager = VariantManager(ContainerRegistry.getInstance()) + self._variant_manager = None self.default_theme = "cura-light" @@ -723,9 +722,6 @@ class CuraApplication(QtApplication): return False return True - def getVariantManager(self): - return self._variant_manager - def preRun(self): # Last check for unknown commandline arguments parser = self.getCommandlineParser() @@ -743,14 +739,15 @@ class CuraApplication(QtApplication): self.preRun() container_registry = ContainerRegistry.getInstance() + self._variant_manager = VariantManager(container_registry) self._variant_manager.initialize() from cura.Machines.MaterialManager import MaterialManager - self._material_manager = MaterialManager(container_registry) + self._material_manager = MaterialManager(container_registry, parent = self) self._material_manager.initialize() from cura.Machines.QualityManager import QualityManager - self._quality_manager = QualityManager(container_registry) + self._quality_manager = QualityManager(container_registry, parent = self) self._quality_manager.initialize() self.getMachineManager() # ensure creation of machine manager @@ -856,6 +853,16 @@ class CuraApplication(QtApplication): self._extruder_manager = ExtruderManager.createExtruderManager() return self._extruder_manager + def getVariantManager(self, *args): + return self._variant_manager + + def getMaterialManager(self, *args): + return self._material_manager + + @pyqtSlot(result = QObject) + def getQualityManager(self, *args): + return self._quality_manager + def getObjectsModel(self, *args): if self._object_manager is None: self._object_manager = ObjectsModel.createObjectsModel() diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index ea82af8d7f..10934e7275 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -333,7 +333,7 @@ class ContainerManager(QObject): self._performMerge(quality_changes, stack.getTop()) - self._machine_manager.activeQualityChanged.emit() + self._machine_manager.activeQualityChangesGroupChanged.emit() return True @@ -394,12 +394,6 @@ class ContainerManager(QObject): self._performMerge(new_changes, user_container) self._container_registry.addContainer(new_changes) - #stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) - - #self._machine_manager.activeQualityChanged.emit() - - #self._machine_manager.activeQualityGroupChanged.emit() - #self._machine_manager.activeQualityChangesGroupChanged.emit() # # Remove the given quality changes group diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 6a42034846..cdd87058f0 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -171,8 +171,36 @@ Item object: "" onAccepted: { + base.newQualityChangesNameToSwitchTo = newName; // We want to switch to the new profile once it's created Cura.ContainerManager.createQualityChanges(newName); - qualityListView.currentIndex = -1; // TODO: Reset selection. + } + } + + property string newQualityChangesNameToSwitchTo: "" + + // This connection makes sure that we will switch to the new + Connections + { + target: qualitiesModel + onItemsChanged: { + var currentItemName = base.currentItem == null ? "" : base.currentItem.name; + + for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { + var item = qualitiesModel.getItem(idx); + if (base.newQualityChangesNameToSwitchTo != "") { + if (item.name == base.newQualityChangesNameToSwitchTo) { + // Switch to the newly created profile if needed + qualityListView.currentIndex = idx; + if (item.is_read_only) { + Cura.MachineManager.setQualityGroup(item.quality_group); + } else { + Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); + } + base.newQualityChangesNameToSwitchTo = ""; + } + break; + } + } } } From cad6a3bb3dcd0d3b11b359bf586f2e56e983367e Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 22 Feb 2018 17:14:23 +0100 Subject: [PATCH 147/266] CURA-4606 CURA-5003 select and activate material after create, duplicate --- cura/Settings/ContainerManager.py | 3 ++- resources/qml/Preferences/MaterialsPage.qml | 28 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 10934e7275..fc9253ef1e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -518,7 +518,7 @@ class ContainerManager(QObject): ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # # \return \type{str} the id of the newly created container. - @pyqtSlot() + @pyqtSlot(result = str) def createMaterial(self): # Ensure all settings are saved. Application.getInstance().saveSettings() @@ -539,6 +539,7 @@ class ContainerManager(QObject): self.duplicateMaterial(material_group.root_material_node, new_base_id = new_id, new_metadata = new_metadata) + return new_id ## Get a list of materials that have the same GUID as the reference material # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index e4856a2d4b..0e40785ca3 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -77,7 +77,7 @@ Item iconName: "list-add" onClicked: { forceActiveFocus(); - Cura.ContainerManager.createMaterial(); + base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.createMaterial(); } } @@ -88,6 +88,7 @@ Item enabled: base.hasCurrentItem onClicked: { forceActiveFocus(); + base.newRootMaterialIdToSwitchTo = base.currentItem.root_material_id; Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); } } @@ -126,6 +127,31 @@ Item } } + property string newRootMaterialIdToSwitchTo: "" + + // This connection makes sure that we will switch to the new + Connections + { + target: materialsModel + onItemsChanged: { + var currentItemName = base.currentItem == null ? "" : base.currentItem.name; + var position = Cura.ExtruderManager.activeExtruderIndex; + + if (base.newRootMaterialIdToSwitchTo != "") { + for (var idx = 0; idx < materialsModel.rowCount(); ++idx) { + var item = materialsModel.getItem(idx); + if (item.root_material_id == base.newRootMaterialIdToSwitchTo) { + // Switch to the newly created profile if needed + materialListView.currentIndex = idx; + Cura.MachineManager.setMaterial(position, item.container_node); + base.newRootMaterialIdToSwitchTo = ""; + break; + } + } + } + } + } + MessageDialog { id: confirmRemoveMaterialDialog From 8dfa52f15c1b9119c0f298c93882657c6bdd4a00 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 20:58:41 +0100 Subject: [PATCH 148/266] Fix material menu model extruder binding and initial update --- cura/CuraApplication.py | 2 -- cura/Machines/Models/MaterialsModel.py | 42 +++++++++++++++++++++----- resources/qml/Menus/MaterialMenu.qml | 3 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 152ad05f9a..3cb78c01b2 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -955,8 +955,6 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") - - # TODO: make this singleton? qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py index 6b253790f1..616903062e 100644 --- a/cura/Machines/Models/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -1,13 +1,11 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, List, Optional -from PyQt5.QtCore import Qt +from typing import Optional +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty from UM.Logger import Logger from UM.Qt.ListModel import ListModel -from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel def getAvailableMaterials(extruder_position: Optional[int] = None): @@ -48,6 +46,8 @@ class BaseMaterialsModel(ListModel): ColorRole = Qt.UserRole + 6 ContainerNodeRole = Qt.UserRole + 7 + extruderPositionChanged = pyqtSignal() + def __init__(self, parent = None): super().__init__(parent) @@ -59,6 +59,17 @@ class BaseMaterialsModel(ListModel): self.addRoleName(self.ColorRole, "color_name") self.addRoleName(self.ContainerNodeRole, "container_node") + self._extruder_position = 0 + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_positoin + class GenericMaterialsModel(BaseMaterialsModel): @@ -82,7 +93,7 @@ class GenericMaterialsModel(BaseMaterialsModel): self.setItems([]) return - result_dict = getAvailableMaterials() + result_dict = getAvailableMaterials(self._extruder_position) if result_dict is None: self.setItems([]) return @@ -126,12 +137,16 @@ class BrandMaterialsModel(ListModel): NameRole = Qt.UserRole + 1 MaterialsRole = Qt.UserRole + 2 + extruderPositionChanged = pyqtSignal() + def __init__(self, parent = None): super().__init__(parent) self.addRoleName(self.NameRole, "name") self.addRoleName(self.MaterialsRole, "materials") + self._extruder_position = 0 + from cura.CuraApplication import CuraApplication self._machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() @@ -141,13 +156,24 @@ class BrandMaterialsModel(ListModel): extruder_manager.activeExtruderChanged.connect(self._update) material_manager.materialsUpdated.connect(self._update) + self._update() + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_position + def _update(self): global_stack = self._machine_manager.activeMachine if global_stack is None: self.setItems([]) return - result_dict = getAvailableMaterials() + result_dict = getAvailableMaterials(self._extruder_position) if result_dict is None: self.setItems([]) return @@ -180,7 +206,7 @@ class BrandMaterialsModel(ListModel): for brand, material_dict in brand_group_dict.items(): brand_item = {"name": brand, - "materials": MaterialsModelGroupedByType(self)} # TODO + "materials": MaterialsModelGroupedByType(self)} material_type_item_list = [] for material_type, material_list in material_dict.items(): diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index ac398356fd..25fa221e9a 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -82,12 +82,13 @@ Menu Cura.GenericMaterialsModel { id: genericMaterialsModel - //Component.onCompleted: populateMenuModels() + extruderPosition: menu.extruderIndex } Cura.BrandMaterialsModel { id: brandModel + extruderPosition: menu.extruderIndex } ExclusiveGroup { id: group } From f51129b1036bbfc460e32b3ade95009c16046892 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 21:47:06 +0100 Subject: [PATCH 149/266] Remove TestTools plugin --- plugins/TestTools/TestTool.py | 38 ----------------------------------- plugins/TestTools/__init__.py | 13 ------------ plugins/TestTools/plugin.json | 7 ------- 3 files changed, 58 deletions(-) delete mode 100644 plugins/TestTools/TestTool.py delete mode 100644 plugins/TestTools/__init__.py delete mode 100644 plugins/TestTools/plugin.json diff --git a/plugins/TestTools/TestTool.py b/plugins/TestTools/TestTool.py deleted file mode 100644 index a8812c21ba..0000000000 --- a/plugins/TestTools/TestTool.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv2 or higher. -from UM.Extension import Extension - -from PyQt5.QtCore import QObject - - -class TestTool(Extension, QObject): - def __init__(self, parent = None): - QObject.__init__(self, parent) - Extension.__init__(self) - - self.addMenuItem("Test material manager", self._testMaterialManager) - self.addMenuItem("Test get quality", self._testGetQuality) - self.addMenuItem("Test get quality changes", self.testGetQualityChanges) - - def _testMaterialManager(self): - print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - from cura.CuraApplication import CuraApplication - CuraApplication.getInstance()._material_manager._test_metadata() - - def _testGetQuality(self): - print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - from cura.CuraApplication import CuraApplication - result_dict = {} - global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack - result = CuraApplication.getInstance()._quality_manager.getQualityGroups(global_stack) - print("!!!!!!!!!!!!!!!!!!!") - - def testGetQualityChanges(self): - print("!!!!!!!!!!!!!!!!!!!") - - from cura.CuraApplication import CuraApplication - result_dict = {} - global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack - result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroups(global_stack) - for name, r in result.items(): - print("!!!!!!!!!! [%s] - %s" % (name, r)) diff --git a/plugins/TestTools/__init__.py b/plugins/TestTools/__init__.py deleted file mode 100644 index 7d41651404..0000000000 --- a/plugins/TestTools/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the AGPLv3 or higher. - -from . import TestTool - -from UM.i18n import i18nCatalog -catalog = i18nCatalog("cura") - -def getMetaData(): - return {} - -def register(app): - return {"extension": TestTool.TestTool()} diff --git a/plugins/TestTools/plugin.json b/plugins/TestTools/plugin.json deleted file mode 100644 index 846e39bf09..0000000000 --- a/plugins/TestTools/plugin.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Test Tools", - "author": "Ultimaker", - "version": "1.0", - "description": "Dump the contents of all settings to a HTML file.", - "api": 4 -} \ No newline at end of file From e53048079d362d19efcc4388f262b7844e10d621 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 23:04:59 +0100 Subject: [PATCH 150/266] Remove debugging logs --- cura/Settings/MachineManager.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4013b1e1cd..6aa137016e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -989,7 +989,6 @@ class MachineManager(QObject): @pyqtSlot("QVariant") def setGlobalVariant(self, container_node): - Logger.log("d", "---------------- container = [%s]", container_node) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setGlobalVariant(container_node) @@ -998,7 +997,6 @@ class MachineManager(QObject): @pyqtSlot(str, "QVariant") def setMaterial(self, position, container_node): - Logger.log("d", "---------------- container = [%s]", container_node) position = str(position) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): @@ -1007,7 +1005,6 @@ class MachineManager(QObject): @pyqtSlot(str, "QVariant") def setVariantGroup(self, position, container_node): - Logger.log("d", "---------------- container = [%s]", container_node) position = str(position) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): @@ -1017,13 +1014,10 @@ class MachineManager(QObject): @pyqtSlot("QVariant") def setQualityGroup(self, quality_group): - Logger.log("d", "---------------- qg = [%s]", quality_group.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityGroup(quality_group) - Logger.log("d", "Quality set!") - # See if we need to show the Discard or Keep changes screen if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: Application.getInstance().discardOrKeepProfileChanges() @@ -1034,11 +1028,9 @@ class MachineManager(QObject): @pyqtSlot("QVariant") def setQualityChangesGroup(self, quality_changes_group): - Logger.log("d", "---------------- qcg = [%s]", quality_changes_group.name) self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityChangesGroup(quality_changes_group) - Logger.log("d", "Quality changes set!") @pyqtProperty("QVariant", fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) def activeQualityChangesGroup(self): From a3a206c6dd58edd6177b7a171a2674d545278f12 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 23:07:49 +0100 Subject: [PATCH 151/266] Quality groups are QObjects --- cura/Settings/MachineManager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6aa137016e..6569fa5cb2 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1012,7 +1012,7 @@ class MachineManager(QObject): self._updateMaterialWithVariant(position) self._updateQualityWithMaterial() - @pyqtSlot("QVariant") + @pyqtSlot(QObject) def setQualityGroup(self, quality_group): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): @@ -1022,17 +1022,17 @@ class MachineManager(QObject): if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: Application.getInstance().discardOrKeepProfileChanges() - @pyqtProperty("QVariant", fset = setQualityGroup, notify = activeQualityGroupChanged) + @pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged) def activeQualityGroup(self): return self._current_quality_group - @pyqtSlot("QVariant") + @pyqtSlot(QObject) def setQualityChangesGroup(self, quality_changes_group): self.blurSettings.emit() with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityChangesGroup(quality_changes_group) - @pyqtProperty("QVariant", fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) + @pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) def activeQualityChangesGroup(self): return self._current_quality_changes_group From dec7ad25e2d0e9decfcd65e0766ea78582ef7436 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 23:08:26 +0100 Subject: [PATCH 152/266] Fix activate newly created custom quality profile --- resources/qml/Preferences/ProfilesPage.qml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index cdd87058f0..224c8f1b3d 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -185,20 +185,16 @@ Item onItemsChanged: { var currentItemName = base.currentItem == null ? "" : base.currentItem.name; - for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { - var item = qualitiesModel.getItem(idx); - if (base.newQualityChangesNameToSwitchTo != "") { + if (base.newQualityChangesNameToSwitchTo != "") { + for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { + var item = qualitiesModel.getItem(idx); if (item.name == base.newQualityChangesNameToSwitchTo) { // Switch to the newly created profile if needed qualityListView.currentIndex = idx; - if (item.is_read_only) { - Cura.MachineManager.setQualityGroup(item.quality_group); - } else { - Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); - } + Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); base.newQualityChangesNameToSwitchTo = ""; + break; } - break; } } } From f487c5b084eb9a857cb3636d8cd2dcfff5d947fb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 22 Feb 2018 23:31:41 +0100 Subject: [PATCH 153/266] Fix profile management page --- cura/Machines/Models/QualitySettingsModel.py | 6 +++- cura/Settings/ContainerManager.py | 17 ++++----- resources/qml/Preferences/ProfilesPage.qml | 37 +++++++++++++------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index e91897b632..304e2f36f0 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -89,7 +89,11 @@ class QualitySettingsModel(ListModel): else: quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._extruder_position) if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime - quality_containers.insert(0, quality_changes_node.getContainer()) + try: + quality_containers.insert(0, quality_changes_node.getContainer()) + except: + # FIXME: This is to prevent incomplete update of QualityManager + return settings_keys.update(quality_changes_group.getAllKeys()) current_category = "" diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 10934e7275..730800af77 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -404,24 +404,17 @@ class ContainerManager(QObject): for node in quality_changes_group.getAllNodes(): self._container_registry.removeContainer(node.metadata["id"]) - ## Rename a set of quality changes containers. # - # This will search for quality_changes containers matching the supplied name and rename them. - # Note that if the machine specifies that qualities should be filtered by machine and/or material - # only the containers related to the active machine/material are renamed. + # Rename a set of quality changes containers. Returns the new name. # - # \param quality_name The name of the quality changes containers to rename. - # \param new_name The new name of the quality changes. - # - # \return True if successful, False if not. - @pyqtSlot(QObject, str) - def renameQualityChangesGroup(self, quality_changes_group, new_name): + @pyqtSlot(QObject, str, result = str) + def renameQualityChangesGroup(self, quality_changes_group, new_name) -> str: Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name) self._machine_manager.blurSettings.emit() if new_name == quality_changes_group.name: Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name) - return + return new_name new_name = self._container_registry.uniqueName(new_name) for node in quality_changes_group.getAllNodes(): @@ -430,6 +423,8 @@ class ContainerManager(QObject): self._machine_manager.activeQualityChanged.emit() self._machine_manager.activeQualityGroupChanged.emit() + return new_name + @pyqtSlot(str, "QVariantMap") def duplicateQualityChanges(self, quality_changes_name, quality_model_item): global_stack = Application.getInstance().getGlobalContainerStack() diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 224c8f1b3d..e5c7e3662a 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -171,32 +171,46 @@ Item object: "" onAccepted: { - base.newQualityChangesNameToSwitchTo = newName; // We want to switch to the new profile once it's created + base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created + base.toActivateNewQuality = true; Cura.ContainerManager.createQualityChanges(newName); } } - property string newQualityChangesNameToSwitchTo: "" + property string newQualityNameToSelect: "" + property bool toActivateNewQuality: false - // This connection makes sure that we will switch to the new + // This connection makes sure that we will switch to the correct quality after the model gets updated Connections { target: qualitiesModel onItemsChanged: { - var currentItemName = base.currentItem == null ? "" : base.currentItem.name; + var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name; + if (newQualityNameToSelect != "") { + toSelectItemName = newQualityNameToSelect; + } - if (base.newQualityChangesNameToSwitchTo != "") { + var newIdx = -1; // Default to nothing if nothing can be found + if (toSelectItemName != "") { + // Select the required quality name if given for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) { var item = qualitiesModel.getItem(idx); - if (item.name == base.newQualityChangesNameToSwitchTo) { + if (item.name == toSelectItemName) { // Switch to the newly created profile if needed - qualityListView.currentIndex = idx; - Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); - base.newQualityChangesNameToSwitchTo = ""; + newIdx = idx; + if (base.toActivateNewQuality) { + // Activate this custom quality if required + Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group); + } break; } } } + qualityListView.currentIndex = newIdx; + + // Reset states + base.newQualityNameToSelect = ""; + base.toActivateNewQuality = false; } } @@ -209,7 +223,6 @@ Item onAccepted: { Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem); - qualityListView.currentIndex = -1; // TODO: Reset selection. } } @@ -240,8 +253,8 @@ Item object: "" onAccepted: { - Cura.ContainerManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName); - qualityListView.currentIndex = -1; // TODO: Reset selection. + var actualNewName = Cura.ContainerManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName); + base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated } } From 2df9802ba5c49f7666fcfcb64b9c1ba0760d4f88 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 26 Feb 2018 09:57:16 +0100 Subject: [PATCH 154/266] CURA-4606 CURA-5010 fix print information crashing on printer switch --- cura/PrintInformation.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index d1ab8506ab..e7db889b8f 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -75,6 +75,7 @@ class PrintInformation(QObject): self._multi_build_plate_model = self._application.getMultiBuildPlateModel() self._application.globalContainerStackChanged.connect(self._updateJobName) + self._application.globalContainerStackChanged.connect(self.setToZeroPrintInformation) self._application.fileLoaded.connect(self.setBaseName) self._application.workspaceLoaded.connect(self.setProjectName) self._multi_build_plate_model.activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged) @@ -211,7 +212,12 @@ class PrintInformation(QObject): material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings")) extruder_stacks = global_stack.extruders - for index, amount in enumerate(self._material_amounts): + #for index, amount in enumerate(self._material_amounts): + for extruder_key in global_stack.extruders.keys(): + index = int(extruder_key) + if index >= len(self._material_amounts): # Right now the _material_amounts is a list, where the index is the extruder number + continue + amount = self._material_amounts[index] ## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some # list comprehension filtering to solve this for us. extruder_stack = extruder_stacks[str(index)] @@ -375,7 +381,9 @@ class PrintInformation(QObject): return result # Simulate message with zero time duration - def setToZeroPrintInformation(self, build_plate): + def setToZeroPrintInformation(self, build_plate = None): + if build_plate is None: + build_plate = self._active_build_plate # Construct the 0-time message temp_message = {} From 9ddc6a52b716b5dc5e373d11d1a44a17bfaea500 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 11:40:21 +0100 Subject: [PATCH 155/266] Refactor fix for extruder stack material diameters and nozzle sizes --- cura/Settings/ExtruderManager.py | 71 ++++++++++++++++++++++++++++---- cura/Settings/ExtruderStack.py | 69 ------------------------------- 2 files changed, 62 insertions(+), 78 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index fa045e9496..178cf31e3f 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -12,6 +12,7 @@ from UM.Scene.Selection import Selection from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID. from UM.Settings.SettingFunction import SettingFunction +from UM.Settings.SettingInstance import SettingInstance from UM.Settings.ContainerStack import ContainerStack from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext from typing import Optional, List, TYPE_CHECKING, Union @@ -397,16 +398,67 @@ class ExtruderManager(QObject): extruder_train.setNextStack(global_stack) extruders_changed = True - # FIX: We have to remove those settings here because we know that those values have been copied to all - # the extruders at this point. - for key in ("material_diameter", "machine_nozzle_size"): - if global_stack.definitionChanges.hasProperty(key, "value"): - global_stack.definitionChanges.removeInstance(key, postpone_emit = True) - + self._fixMaterialDiameterAndNozzleSize(global_stack, extruder_trains) if extruders_changed: self.extrudersChanged.emit(global_stack_id) self.setActiveExtruderIndex(0) + def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list): + keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders + + extruder_positions_to_update = set() + for extruder_stack in extruder_stack_list: + for key in keys_to_copy: + # Only copy the value when this extruder doesn't have the value. + if extruder_stack.definitionChanges.hasProperty(key, "value"): + continue + + # + # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime + # because all other machines which uses "fdmextruder" as the extruder definition will be affected. + # + # The problem is that single extrusion machines have their default material diameter defined in the global + # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder" + # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for + # each machine. This results in wrong values which can be found in the MachineSettings dialog. + # + # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in + # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now + # we also check the value defined in the machine definition. If present, the value defined in the global + # stack's definition changes container will be copied. Otherwise, we will check if the default values in the + # machine definition and the extruder definition are the same, and if not, the default value in the machine + # definition will be copied to the extruder stack's definition changes. + # + setting_value_in_global_def_changes = global_stack.definitionChanges.getProperty(key, "value") + setting_value_in_global_def = global_stack.definition.getProperty(key, "value") + setting_value = setting_value_in_global_def + if setting_value_in_global_def_changes is not None: + setting_value = setting_value_in_global_def_changes + if setting_value == extruder_stack.definition.getProperty(key, "value"): + continue + + setting_definition = global_stack.getSettingDefinition(key) + new_instance = SettingInstance(setting_definition, extruder_stack.definitionChanges) + new_instance.setProperty("value", setting_value) + new_instance.resetState() # Ensure that the state is not seen as a user state. + extruder_stack.definitionChanges.addInstance(new_instance) + extruder_stack.definitionChanges.setDirty(True) + + # Make sure the material diameter is up to date for the extruder stack. + if key == "material_diameter": + position = int(extruder_stack.getMetaDataEntry("position")) + extruder_positions_to_update.add(position) + + # We have to remove those settings here because we know that those values have been copied to all + # the extruders at this point. + for key in keys_to_copy: + if global_stack.definitionChanges.hasProperty(key, "value"): + global_stack.definitionChanges.removeInstance(key, postpone_emit = True) + + # Update material diameter for extruders + for position in extruder_positions_to_update: + self.updateMaterialForDiameter(position, global_stack = global_stack) + ## Get all extruder values for a certain setting. # # This is exposed to SettingFunction so it can be used in value functions. @@ -492,10 +544,11 @@ class ExtruderManager(QObject): return ExtruderManager.getExtruderValues(key) ## Updates the material container to a material that matches the material diameter set for the printer - def updateMaterialForDiameter(self, extruder_position: int): - global_stack = Application.getInstance().getGlobalContainerStack() + def updateMaterialForDiameter(self, extruder_position: int, global_stack = None): if not global_stack: - return + global_stack = Application.getInstance().getGlobalContainerStack() + if not global_stack: + return if not global_stack.getMetaDataEntry("has_materials", False): return diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 5a3ac85d75..870de62c98 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -41,75 +41,6 @@ class ExtruderStack(CuraContainerStack): # For backward compatibility: Register the extruder with the Extruder Manager ExtruderManager.getInstance().registerExtruder(self, stack.id) - # Now each machine will have at least one extruder stack. If this is the first extruder, the extruder-specific - # settings such as nozzle size and material diameter should be moved from the machine's definition_changes to - # the this extruder's definition_changes. - # - # We do this here because it is tooooo expansive to do it in the version upgrade: During the version upgrade, - # when we are upgrading a definition_changes container file, there is NO guarantee that other files such as - # machine an extruder stack files are upgraded before this, so we cannot read those files assuming they are in - # the latest format. - # - # MORE: - # For single-extrusion machines, nozzle size is saved in the global stack, so the nozzle size value should be - # carried to the first extruder. - # For material diameter, it was supposed to be applied to all extruders, so its value should be copied to all - # extruders. - - keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders - - for key in keys_to_copy: - # Only copy the value when this extruder doesn't have the value. - if self.definitionChanges.hasProperty(key, "value"): - continue - - # WARNING: this might be very dangerous and should be refactored ASAP! - # - # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime - # because all other machines which uses "fdmextruder" as the extruder definition will be affected. - # - # The problem is that single extrusion machines have their default material diameter defined in the global - # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder" - # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for - # each machine. This results in wrong values which can be found in the MachineSettings dialog. - # - # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in - # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now - # we also check the value defined in the machine definition. If present, the value defined in the global - # stack's definition changes container will be copied. Otherwise, we will check if the default values in the - # machine definition and the extruder definition are the same, and if not, the default value in the machine - # definition will be copied to the extruder stack's definition changes. - # - setting_value_in_global_def_changes = stack.definitionChanges.getProperty(key, "value") - setting_value_in_global_def = stack.definition.getProperty(key, "value") - setting_value = setting_value_in_global_def - if setting_value_in_global_def_changes is not None: - setting_value = setting_value_in_global_def_changes - if setting_value == self.definition.getProperty(key, "value"): - continue - - setting_definition = stack.getSettingDefinition(key) - new_instance = SettingInstance(setting_definition, self.definitionChanges) - new_instance.setProperty("value", setting_value) - new_instance.resetState() # Ensure that the state is not seen as a user state. - self.definitionChanges.addInstance(new_instance) - self.definitionChanges.setDirty(True) - - # Make sure the material diameter is up to date for the extruder stack. - if key == "material_diameter": - from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() - position = self.getMetaDataEntry("position", "0") - func = lambda p = position: CuraApplication.getInstance().getExtruderManager().updateMaterialForDiameter(p) - machine_manager.machine_extruder_material_update_dict[stack.getId()].append(func) - - # NOTE: We cannot remove the setting from the global stack's definition changes container because for - # material diameter, it needs to be applied to all extruders, but here we don't know how many extruders - # a machine actually has and how many extruders has already been loaded for that machine, so we have to - # keep this setting for any remaining extruders that haven't been loaded yet. - # - # Those settings will be removed in ExtruderManager which knows all those info. - @override(ContainerStack) def getNextStack(self) -> Optional["GlobalStack"]: return super().getNextStack() From c23827cfa17c08f1e674c4ec49f36aa451cb3bbd Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 26 Feb 2018 16:33:25 +0100 Subject: [PATCH 156/266] CURA-4606 CURA-5003 activate duplicated material and always switch to correct material after some material change --- cura/Settings/ContainerManager.py | 3 +- resources/qml/Preferences/MaterialsPage.qml | 56 ++++++++++++++------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 3a352d370c..e1364581f6 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -458,7 +458,7 @@ class ContainerManager(QObject): ## Create a duplicate of a material, which has the same GUID and base_file metadata # # \return \type{str} the id of the newly created container. - @pyqtSlot("QVariant") + @pyqtSlot("QVariant", result = str) def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None): root_material_id = material_node.metadata["base_file"] @@ -509,6 +509,7 @@ class ContainerManager(QObject): for container_to_add in new_containers: container_to_add.setDirty(True) ContainerRegistry.getInstance().addContainer(container_to_add) + return new_base_id ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 0e40785ca3..671b5c6b9b 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -37,7 +37,7 @@ Item property var hasCurrentItem: materialListView.currentItem != null - property var currentItem: { + property var currentItem: { // is soon to be overwritten var current_index = materialListView.currentIndex; return materialsModel.getItem(current_index); } @@ -78,6 +78,7 @@ Item onClicked: { forceActiveFocus(); base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.createMaterial(); + base.toActivateNewMaterial = true; } } @@ -88,8 +89,8 @@ Item enabled: base.hasCurrentItem onClicked: { forceActiveFocus(); - base.newRootMaterialIdToSwitchTo = base.currentItem.root_material_id; - Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); + base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); + base.toActivateNewMaterial = true; } } @@ -128,27 +129,43 @@ Item } property string newRootMaterialIdToSwitchTo: "" + property bool toActivateNewMaterial: false // This connection makes sure that we will switch to the new Connections { target: materialsModel onItemsChanged: { - var currentItemName = base.currentItem == null ? "" : base.currentItem.name; + var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id; var position = Cura.ExtruderManager.activeExtruderIndex; - if (base.newRootMaterialIdToSwitchTo != "") { - for (var idx = 0; idx < materialsModel.rowCount(); ++idx) { - var item = materialsModel.getItem(idx); - if (item.root_material_id == base.newRootMaterialIdToSwitchTo) { - // Switch to the newly created profile if needed - materialListView.currentIndex = idx; + // try to pick the currently selected item; it may have been moved + if (base.newRootMaterialIdToSwitchTo == "") { + base.newRootMaterialIdToSwitchTo = currentItemId; + } + + for (var idx = 0; idx < materialsModel.rowCount(); ++idx) { + var item = materialsModel.getItem(idx); + if (item.root_material_id == base.newRootMaterialIdToSwitchTo) { + // Switch to the newly created profile if needed + materialListView.currentIndex = idx; + materialListView.activateDetailsWithIndex(materialListView.currentIndex); + if (base.toActivateNewMaterial) { Cura.MachineManager.setMaterial(position, item.container_node); - base.newRootMaterialIdToSwitchTo = ""; - break; } + base.newRootMaterialIdToSwitchTo = ""; + base.toActivateNewMaterial = false; + return } } + + materialListView.currentIndex = 0; + materialListView.activateDetailsWithIndex(materialListView.currentIndex); + if (base.toActivateNewMaterial) { + Cura.MachineManager.setMaterial(position, materialsModel.getItem(0).container_node); + } + base.newRootMaterialIdToSwitchTo = ""; + base.toActivateNewMaterial = false; } } @@ -165,8 +182,6 @@ Item onYes: { Cura.ContainerManager.removeMaterial(base.currentItem.container_node); - // reset current item to the first if available - materialListView.currentIndex = 0; } } @@ -374,15 +389,20 @@ Item } } - onCurrentIndexChanged: - { - forceActiveFocus(); // causes the changed fields to be saved - var model = materialsModel.getItem(currentIndex); + function activateDetailsWithIndex(index) { + var model = materialsModel.getItem(index); + base.currentItem = model; materialDetailsView.containerId = model.container_id; materialDetailsView.currentMaterialNode = model.container_node; detailsPanel.updateMaterialPropertiesObject(); } + + onCurrentIndexChanged: + { + forceActiveFocus(); // causes the changed fields to be saved + activateDetailsWithIndex(currentIndex); + } } } From 12c51f40668f818dbd070c35286ba4f4d2db7129 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 17:05:55 +0100 Subject: [PATCH 157/266] Use setActiveMachine() in project loading --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index d584a0efd6..1c1d2f30a4 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -1057,7 +1057,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader): CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit() # Actually change the active machine. - Application.getInstance().setGlobalContainerStack(global_stack) + machine_manager = Application.getInstance().getMachineManager() + machine_manager.setActiveMachine(global_stack.getId()) # Notify everything/one that is to notify about changes. global_stack.containersChanged.emit(global_stack.getTop()) From 0b8678d2ae29cb58b3f16a6df7efd4fe2cf28138 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 19:33:16 +0100 Subject: [PATCH 158/266] Explicitly create MachineManager --- cura/CuraApplication.py | 4 ++-- cura/Settings/MachineManager.py | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3cb78c01b2..eb09f1ed82 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -750,7 +750,7 @@ class CuraApplication(QtApplication): self._quality_manager = QualityManager(container_registry, parent = self) self._quality_manager.initialize() - self.getMachineManager() # ensure creation of machine manager + self._machine_manager = MachineManager(self) # Check if we should run as single instance or not self._setUpSingleInstanceServer() @@ -845,7 +845,7 @@ class CuraApplication(QtApplication): def getMachineManager(self, *args) -> MachineManager: if self._machine_manager is None: - self._machine_manager = MachineManager.createMachineManager() + self._machine_manager = MachineManager(self) return self._machine_manager def getExtruderManager(self, *args): diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 6569fa5cb2..b75f805d73 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -760,10 +760,6 @@ class MachineManager(QObject): # Signal that the global stack has changed Application.getInstance().globalContainerStackChanged.emit() - @staticmethod - def createMachineManager(): - return MachineManager() - @pyqtSlot(int, result = QObject) def getExtruder(self, position: int): extruder = None From a74f84fce7fbbbbde957fb7716ecc2e57ca28bfa Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 19:35:56 +0100 Subject: [PATCH 159/266] Add comment why sorting the material group map --- cura/Machines/MaterialManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index ae679a5ee6..cbfc822303 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -90,6 +90,7 @@ class MaterialManager(QObject): else: new_node = MaterialNode(material_metadata) group.derived_material_node_list.append(new_node) + # Order this map alphabetically so it's easier to navigate in a debugger self._material_group_map = OrderedDict(sorted(self._material_group_map.items(), key = lambda x: x[0])) # Map #1.5 From d9d2cc90693ce2cfc232f2906ce0a9c7578fd9a2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 19:37:29 +0100 Subject: [PATCH 160/266] Remove unused code in PrintInformation --- cura/PrintInformation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index e7db889b8f..279e7e0c03 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -212,7 +212,6 @@ class PrintInformation(QObject): material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings")) extruder_stacks = global_stack.extruders - #for index, amount in enumerate(self._material_amounts): for extruder_key in global_stack.extruders.keys(): index = int(extruder_key) if index >= len(self._material_amounts): # Right now the _material_amounts is a list, where the index is the extruder number From 17d3be03b4bc8d0ea6558c0127180a96fc17de81 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 19:38:44 +0100 Subject: [PATCH 161/266] Use getMaterialManager() in ContainerManager --- cura/Settings/ContainerManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index e1364581f6..9701a7b406 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -45,7 +45,7 @@ class ContainerManager(QObject): self._application = Application.getInstance() self._container_registry = ContainerRegistry.getInstance() self._machine_manager = self._application.getMachineManager() - self._material_manager = self._application._material_manager + self._material_manager = self._application.getMaterialManager() self._container_name_filters = {} @pyqtSlot(str, str, result=str) From ccd4bb285beb44d792e6ee56a8aaf0e71d66ffa7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 26 Feb 2018 19:40:31 +0100 Subject: [PATCH 162/266] Use userChanges instead of getTop() --- plugins/3MFReader/ThreeMFReader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index b81fd435b9..80ef913b54 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -123,9 +123,9 @@ class ThreeMFReader(MeshReader): # Get the definition & set it definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack.definition) - um_node.callDecoration("getStack").getTop().setDefinition(definition_id) + um_node.callDecoration("getStack").userChanges.setDefinition(definition_id) - setting_container = um_node.callDecoration("getStack").getTop() + setting_container = um_node.callDecoration("getStack").userChanges for key in settings: setting_value = settings[key] From d79206301d847de4ff94739e6a9f20253fa187e7 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 11:43:54 +0100 Subject: [PATCH 163/266] CURA-4606 CURA-5012 fix incompatible diameter update message in materialview --- resources/qml/Preferences/MaterialView.qml | 47 +++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 6e3d04fa2c..3dc16c5a86 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -41,6 +41,10 @@ TabView return linkedMaterials.join(", "); } + function getApproximateDiameter(diameter) { + return Math.round(diameter); + } + Tab { title: catalog.i18nc("@title", "Information") @@ -67,6 +71,34 @@ TabView width: base.width property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height + MessageDialog + { + id: confirmDiameterChangeDialog + + icon: StandardIcon.Question; + title: catalog.i18nc("@title:window", "Confirm Diameter Change") + text: catalog.i18nc("@label (%1 is object name)", "The new material diameter is set to %1 mm, which is not compatible to the current machine. Do you wish to continue?".arg(new_diameter_value)) + standardButtons: StandardButton.Yes | StandardButton.No + modality: Qt.ApplicationModal + + property var new_diameter_value: null; + property var old_diameter_value: null; + property var old_approximate_diameter_value: null; + + onYes: + { + Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", new_diameter_value); + base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString()); + base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value); + } + + onNo: + { + properties.diameter = old_diameter_value; + diameterSpinBox.value = properties.diameter; + } + } + Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } ReadOnlyTextField { @@ -174,14 +206,19 @@ TabView // which derive from the same base_file var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString(); var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); - base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString()); - base.setMetaDataEntry("properties/diameter", properties.diameter, value); - var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); + var new_approximate_diameter = getApproximateDiameter(value); if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter) { - Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter); + confirmDiameterChangeDialog.old_diameter_value = old_diameter; + confirmDiameterChangeDialog.new_diameter_value = value; + confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter; + + confirmDiameterChangeDialog.open() + } else { + Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value); + base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString()); + base.setMetaDataEntry("properties/diameter", properties.diameter, value); } - Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value); } onValueChanged: updateCostPerMeter() } From df462412254d804aeb2ff7b376326e2a500983d0 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 13:03:08 +0100 Subject: [PATCH 164/266] CURA-4606 CURA-5012 corrected and moved approximateMaterialDiameter to ExtruderStack --- cura/Machines/Models/MaterialsModel.py | 2 +- cura/Settings/ExtruderManager.py | 1 + cura/Settings/ExtruderStack.py | 29 ++++++++++++++++++++++ cura/Settings/GlobalStack.py | 15 ----------- resources/qml/Preferences/MaterialView.qml | 2 +- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py index 616903062e..5ef5845371 100644 --- a/cura/Machines/Models/MaterialsModel.py +++ b/cura/Machines/Models/MaterialsModel.py @@ -30,7 +30,7 @@ def getAvailableMaterials(extruder_position: Optional[int] = None): variant_name = None if extruder_stack.variant.getId() != "empty_variant": variant_name = extruder_stack.variant.getName() - diameter = extruder_stack.getProperty("material_diameter", "value") + diameter = extruder_stack.approximateMaterialDiameter # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 178cf31e3f..fe1bb6a990 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -179,6 +179,7 @@ class ExtruderManager(QObject): self._selected_object_extruders = [] self.selectedObjectExtrudersChanged.emit() + @pyqtSlot(result = QObject) def getActiveExtruderStack(self) -> Optional["ExtruderStack"]: global_container_stack = Application.getInstance().getGlobalContainerStack() diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 870de62c98..2995aae795 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -3,6 +3,8 @@ from typing import Any, TYPE_CHECKING, Optional +from PyQt5.QtCore import pyqtProperty + from UM.Decorators import override from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.Settings.ContainerStack import ContainerStack @@ -49,6 +51,33 @@ class ExtruderStack(CuraContainerStack): def getLoadingPriority(cls) -> int: return 3 + ## Return the filament diameter that the machine requires. + # + # If the machine has no requirement for the diameter, -1 is returned. + # \return The filament diameter for the printer + @property + def materialDiameter(self) -> float: + containers_to_check = [self.variant, self.definitionChanges, self.definition] + + for container in containers_to_check: + if container is not None: + material_diameter = container.getProperty("material_diameter", "value") + if material_diameter is not None: + return material_diameter + return -1 + + ## Return the approximate filament diameter that the machine requires. + # + # The approximate material diameter is the material diameter rounded to + # the nearest millimetre. + # + # If the machine has no requirement for the diameter, -1 is returned. + # + # \return The approximate filament diameter for the printer + @pyqtProperty(float) + def approximateMaterialDiameter(self) -> float: + return round(float(self.materialDiameter)) + ## Overridden from ContainerStack # # It will perform a few extra checks when trying to get properties. diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index 6d18bf615b..ae1f1370ed 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -125,21 +125,6 @@ class GlobalStack(CuraContainerStack): def setNextStack(self, next_stack: ContainerStack) -> None: raise Exceptions.InvalidOperationError("Global stack cannot have a next stack!") - ## Gets the approximate filament diameter that the machine requires. - # - # The approximate material diameter is the material diameter rounded to - # the nearest millimetre. - # - # If the machine has no requirement for the diameter, -1 is returned. - # - # \return The approximate filament diameter for the printer, as a string. - @pyqtProperty(str) - def approximateMaterialDiameter(self) -> str: - material_diameter = self.definition.getProperty("material_diameter", "value") - if material_diameter is None: - return "-1" - return str(round(float(material_diameter))) #Round, then convert back to string. - # protected: # Determine whether or not we should try to get the "resolve" property instead of the diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 3dc16c5a86..021fcc02e1 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -207,7 +207,7 @@ TabView var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString(); var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter"); var new_approximate_diameter = getApproximateDiameter(value); - if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter) + if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter) { confirmDiameterChangeDialog.old_diameter_value = old_diameter; confirmDiameterChangeDialog.new_diameter_value = value; From 5412a29ef9962c33145edf3f59341abd9f221c2f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 13:04:18 +0100 Subject: [PATCH 165/266] Fix update quality upon material change --- cura/Settings/MachineManager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index b75f805d73..fd4b5b455c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -839,7 +839,8 @@ class MachineManager(QObject): def _setQualityGroup(self, quality_group, empty_quality_changes = True): self._current_quality_group = quality_group - self._current_quality_changes_group = None + if empty_quality_changes: + self._current_quality_changes_group = None # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() @@ -946,7 +947,7 @@ class MachineManager(QObject): if preferred_quality_type in available_quality_types: quality_type = preferred_quality_type - self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = False) + self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = True) def _updateMaterialWithVariant(self, position: Optional[str]): if position is None: From dfa870b6a9521d4eac7084d089ffdffce7998b75 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 13:15:03 +0100 Subject: [PATCH 166/266] Remove approximate diameter unit tests because the function/property is gone --- tests/Settings/TestGlobalStack.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 45ff13aaf3..6bf10dd8c1 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -116,31 +116,6 @@ def test_addExtruder(global_stack): # global_stack.addExtruder(unittest.mock.MagicMock()) assert len(global_stack.extruders) == 2 #Didn't add the faulty extruder. -## Tests getting the approximate material diameter. -@pytest.mark.parametrize("diameter, approximate_diameter", [ - #Some real-life cases that are common in printers. - (2.85, 3), - (1.75, 2), - (3.0, 3), - (2.0, 2), - #Exceptional cases. - (0, 0), - (-10.1, -10), - (-1, -1), - (9000.1, 9000) -]) -def test_approximateMaterialDiameter(diameter, approximate_diameter, global_stack): - global_stack.definition = DefinitionContainer(container_id = "TestDefinition") - material_diameter = UM.Settings.SettingDefinition.SettingDefinition(key = "material_diameter", container = global_stack.definition) - material_diameter.addSupportedProperty("value", UM.Settings.SettingDefinition.DefinitionPropertyType.Any, default = diameter) - global_stack.definition.definitions.append(material_diameter) - assert float(global_stack.approximateMaterialDiameter) == approximate_diameter - -## Tests getting the material diameter when there is no material diameter. -def test_approximateMaterialDiameterNoDiameter(global_stack): - global_stack.definition = DefinitionContainer(container_id = "TestDefinition") - assert global_stack.approximateMaterialDiameter == "-1" - #Tests setting user changes profiles to invalid containers. @pytest.mark.parametrize("container", [ getInstanceContainer(container_type = "wrong container type"), From a2e84bbe9734ccbe28902dd543533c6d3876cb04 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 13:49:20 +0100 Subject: [PATCH 167/266] Fix set quality group in init machine --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index fd4b5b455c..6a39ce127b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -288,7 +288,7 @@ class MachineManager(QObject): Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) return new_quality_group = quality_groups[quality_type] - self._setQualityGroup(new_quality_group) + self._setQualityGroup(new_quality_group, empty_quality_changes = True) @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: From 2f866873209accda80921308e9cb07db9d46aecc Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 13:49:45 +0100 Subject: [PATCH 168/266] Fix init machine for machines loaded from project files --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 5d34e4b059..6dd20b66e0 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -1082,11 +1082,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit() # Actually change the active machine. - machine_manager = Application.getInstance().getMachineManager() - machine_manager.setActiveMachine(global_stack.getId()) - - # Notify everything/one that is to notify about changes. - global_stack.containersChanged.emit(global_stack.getTop()) + CuraApplication.getInstance().callLater(self._updateActiveMachine, global_stack) # Load all the nodes / meshdata of the workspace nodes = self._3mf_mesh_reader.read(file_name) @@ -1099,6 +1095,14 @@ class ThreeMFWorkspaceReader(WorkspaceReader): self.setWorkspaceName(base_file_name) return nodes + def _updateActiveMachine(self, global_stack): + # Actually change the active machine. + machine_manager = Application.getInstance().getMachineManager() + machine_manager.setActiveMachine(global_stack.getId()) + + # Notify everything/one that is to notify about changes. + global_stack.containersChanged.emit(global_stack.getTop()) + ## HACK: Replaces the material container in the given stack with a newly created material container. # This function is used when the user chooses to resolve material conflicts by creating new ones. def _replaceStackMaterialWithNew(self, stack, old_new_material_dict): From 08bfe933856ef14eaed42198029a13ef6cb8c76e Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 13:57:30 +0100 Subject: [PATCH 169/266] CURA-4606 CURA-5020 switching to quality changes now also checks and shows keep or discard user settings --- cura/Settings/MachineManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index fd4b5b455c..4e1d88a3b1 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1029,6 +1029,10 @@ class MachineManager(QObject): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self._setQualityChangesGroup(quality_changes_group) + # See if we need to show the Discard or Keep changes screen + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + Application.getInstance().discardOrKeepProfileChanges() + @pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged) def activeQualityChangesGroup(self): return self._current_quality_changes_group From 950f6708c4a108c3ea4bf2e2340ea5e8bf0c0e5b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 14:20:17 +0100 Subject: [PATCH 170/266] Make sure to generate unique name for duplicated quality changes --- cura/Settings/ContainerManager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 9701a7b406..d49ec79037 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -437,10 +437,11 @@ class ContainerManager(QObject): global_stack, extruder_id = None) self._container_registry.addContainer(new_quality_changes) else: + new_name = self._container_registry.uniqueName(quality_changes_name) for node in quality_changes_group.getAllNodes(): container = node.getContainer() new_id = self._container_registry.uniqueName(container.getId()) - self._container_registry.addContainer(container.duplicate(new_id, quality_changes_name)) + self._container_registry.addContainer(container.duplicate(new_id, new_name)) @pyqtSlot("QVariant") def removeMaterial(self, material_node): From cbeaf3b2872abd40e97ef6b9ef6b0dddb2139903 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 15:14:34 +0100 Subject: [PATCH 171/266] CURA-4606 set empty quality when setting active machine when the current quality type is not in the available qualities --- cura/Settings/MachineManager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index a710d74238..627e7661ba 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -286,6 +286,7 @@ class MachineManager(QObject): quality_groups = self._application._quality_manager.getQualityGroups(global_stack) if quality_type not in quality_groups: Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values())) + self._setEmptyQuality() return new_quality_group = quality_groups[quality_type] self._setQualityGroup(new_quality_group, empty_quality_changes = True) From ae00fc2a7eca8c7754dc29031937890590ba81fe Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 15:15:04 +0100 Subject: [PATCH 172/266] CURA-4606 change activeQualityLayerHeight to use self._current_quality(_changes)_group --- cura/Settings/MachineManager.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 627e7661ba..5abd5d4649 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -472,21 +472,17 @@ class MachineManager(QObject): def activeQualityLayerHeight(self) -> float: if not self._global_container_stack: return 0 - - quality_changes = self._global_container_stack.qualityChanges - if quality_changes: - value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality_changes.getId()) + if self._current_quality_changes_group: + value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.qualityChanges.getId()) if isinstance(value, SettingFunction): value = value(self._global_container_stack) return value - quality = self._global_container_stack.quality - if quality: - value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality.getId()) + elif self._current_quality_group: + value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.quality.getId()) if isinstance(value, SettingFunction): value = value(self._global_container_stack) return value - - return 0 # No quality profile. + return 0 @pyqtProperty(str, notify = activeVariantChanged) def globalVariantName(self) -> str: From f304e7f2e73828c4d2f1c5ceeb15c3f6196bbc66 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 15:58:34 +0100 Subject: [PATCH 173/266] Revert "Use userChanges instead of getTop()" PerObjectContainerStacks are not CuraContainerStacks, so we cannot use "userChanges" with it. --- plugins/3MFReader/ThreeMFReader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 80ef913b54..b81fd435b9 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -123,9 +123,9 @@ class ThreeMFReader(MeshReader): # Get the definition & set it definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack.definition) - um_node.callDecoration("getStack").userChanges.setDefinition(definition_id) + um_node.callDecoration("getStack").getTop().setDefinition(definition_id) - setting_container = um_node.callDecoration("getStack").userChanges + setting_container = um_node.callDecoration("getStack").getTop() for key in settings: setting_value = settings[key] From 632e0469fb5d818431a78d5b065adc3f9fdf724e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 15:59:39 +0100 Subject: [PATCH 174/266] Fix 3MF Reader --- plugins/3MFReader/ThreeMFReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index b81fd435b9..95d8146d32 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -122,7 +122,7 @@ class ThreeMFReader(MeshReader): um_node.callDecoration("setActiveExtruder", default_stack.getId()) # Get the definition & set it - definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack.definition) + definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack) um_node.callDecoration("getStack").getTop().setDefinition(definition_id) setting_container = um_node.callDecoration("getStack").getTop() From 9dcd72fb36b4ee6f95eeb1d06cf1fb10b7f239ad Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 16:06:09 +0100 Subject: [PATCH 175/266] Remove outdated TODOs --- cura/Machines/QualityManager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index a9aa6e9dcf..eb8a3611c1 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -256,7 +256,6 @@ class QualityManager(QObject): # Returns a dict of "custom profile name" -> QualityChangesGroup def getQualityChangesGroups(self, machine: "GlobalStack") -> dict: - # TODO: How to make this simpler? # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) @@ -280,7 +279,6 @@ class QualityManager(QObject): return quality_changes_group_dict def getQualityGroups(self, machine: "GlobalStack") -> dict: - # TODO: How to make this simpler, including the fall backs. # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) # This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks From 85e3857785168648449dd45d0aa37af10f4ce8fd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 27 Feb 2018 16:12:28 +0100 Subject: [PATCH 176/266] Use getters to get managers for CuraStackBuilder --- cura/Settings/CuraStackBuilder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 9273b272c1..4d103d2537 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -27,9 +27,9 @@ class CuraStackBuilder: def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]: from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() - variant_manager = CuraApplication.getInstance()._variant_manager - material_manager = CuraApplication.getInstance()._material_manager - quality_manager = CuraApplication.getInstance()._quality_manager + variant_manager = application.getVariantManager() + material_manager = application.getMaterialManager() + quality_manager = application.getQualityManager() registry = ContainerRegistry.getInstance() definitions = registry.findDefinitionContainers(id = definition_id) From 01071da4c17f7517eda0fd68fe523eaf3444287e Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 27 Feb 2018 16:33:37 +0100 Subject: [PATCH 177/266] CURA-4606 corrected slider bar, it now updates correctly from 0 available qualities to 1 available quality --- resources/qml/SidebarSimple.qml | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 0f9c8b0e55..877e3a1557 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -137,7 +137,7 @@ Item // Set total available ticks for active slider part if (availableMin != -1) { - qualityModel.availableTotalTicks = availableMax - availableMin + qualityModel.availableTotalTicks = availableMax - availableMin + 1 } // Calculate slider values @@ -164,7 +164,7 @@ Item function reset () { qualityModel.clear() - qualityModel.availableTotalTicks = -1 + qualityModel.availableTotalTicks = 0 qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero @@ -273,32 +273,24 @@ Item } } - Rectangle { - id: disabledHandleButton - visible: !qualitySlider.visible - anchors.centerIn: parent - color: UM.Theme.getColor("quality_slider_unavailable") - implicitWidth: 10 * screenScaleFactor - implicitHeight: implicitWidth - radius: Math.round(width / 2) - } - Slider { id: qualitySlider height: UM.Theme.getSize("sidebar_margin").height anchors.bottom: speedSlider.bottom - enabled: qualityModel.availableTotalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized - visible: qualityModel.totalTicks > 0 + enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized + visible: qualityModel.availableTotalTicks > 0 updateValueWhileDragging : false minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0 - maximumValue: qualityModel.qualitySliderAvailableMax >= 0 ? qualityModel.qualitySliderAvailableMax : 0 + // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly + // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available) + maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1 stepSize: 1 value: qualityModel.qualitySliderActiveIndex - width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks + width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1) anchors.right: parent.right anchors.rightMargin: qualityModel.qualitySliderMarginRight @@ -376,7 +368,7 @@ Item text: catalog.i18nc("@label", "Slower") font: UM.Theme.getFont("default") - color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") horizontalAlignment: Text.AlignLeft } @@ -387,7 +379,7 @@ Item text: catalog.i18nc("@label", "Faster") font: UM.Theme.getFont("default") - color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") horizontalAlignment: Text.AlignRight } From c5d443109bb05a07f10da99232e7f94e2ceb635f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:12:44 +0100 Subject: [PATCH 178/266] Split MaterialGroup and MaterialNode --- cura/Machines/MaterialGroup.py | 25 +++++++++++++++++++++++++ cura/Machines/MaterialManager.py | 24 ++---------------------- cura/Machines/MaterialNode.py | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 cura/Machines/MaterialGroup.py create mode 100644 cura/Machines/MaterialNode.py diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py new file mode 100644 index 0000000000..9111cc3a80 --- /dev/null +++ b/cura/Machines/MaterialGroup.py @@ -0,0 +1,25 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +# +# A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile. +# The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For +# example: "generic_abs" is the root material (ID) of "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4", +# and "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4" are derived materials of "generic_abs". +# +# Using "generic_abs" as an example, the MaterialGroup for "generic_abs" will contain the following information: +# - name: "generic_abs", root_material_id +# - root_material_node: MaterialNode of "generic_abs" +# - derived_material_node_list: A list of MaterialNodes that are derived from "generic_abs", +# so "generic_abs_ultimaker3", "generic_abs_ultimaker3_AA_0.4", etc. +# +class MaterialGroup: + __slots__ = ("name", "root_material_node", "derived_material_node_list") + + def __init__(self, name: str): + self.name = name + self.root_material_node = None + self.derived_material_node_list = [] + + def __str__(self) -> str: + return "%s[%s]" % (self.__class__.__name__, self.name) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index cbfc822303..44e3468c63 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -6,28 +6,8 @@ from PyQt5.Qt import QTimer, QObject, pyqtSignal from UM.Logger import Logger from UM.Settings import ContainerRegistry -from cura.Machines.ContainerNode import ContainerNode - - -class MaterialGroup: - __slots__ = ("name", "root_material_node", "derived_material_node_list") - - def __init__(self, name: str): - self.name = name - self.root_material_node = None - self.derived_material_node_list = [] - - def __str__(self) -> str: - return "%s[%s]" % (self.__class__.__name__, self.name) - - -class MaterialNode(ContainerNode): - __slots__ = ("material_map", "children_map") - - def __init__(self, metadata: Optional[dict] = None): - super().__init__(metadata = metadata) - self.material_map = {} - self.children_map = {} +from .MaterialNode import MaterialNode +from .MaterialGroup import MaterialGroup class MaterialManager(QObject): diff --git a/cura/Machines/MaterialNode.py b/cura/Machines/MaterialNode.py new file mode 100644 index 0000000000..fde11186c2 --- /dev/null +++ b/cura/Machines/MaterialNode.py @@ -0,0 +1,21 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional + +from .ContainerNode import ContainerNode + + +# +# A MaterialNode is a node in the material lookup tree/map/table. It contains 2 (extra) fields: +# - material_map: a one-to-one map of "material_root_id" to material_node. +# - children_map: the key-value map for child nodes of this node. This is used in a lookup tree. +# +# +class MaterialNode(ContainerNode): + __slots__ = ("material_map", "children_map") + + def __init__(self, metadata: Optional[dict] = None): + super().__init__(metadata = metadata) + self.material_map = {} # material_root_id -> material_node + self.children_map = {} # mapping for the child nodes From c143cd97c82a2034d8e80e5800c78e9be98a9fcd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:15:43 +0100 Subject: [PATCH 179/266] More accurate doc for material maps --- cura/Machines/MaterialManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 44e3468c63..07b83853cf 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -20,12 +20,12 @@ class MaterialManager(QObject): self._fallback_materials_map = dict() # material_type -> generic material metadata self._material_group_map = dict() # root_material_id -> MaterialGroup - self._diameter_machine_variant_material_map = dict() # diameter -> dict(machine_definition_id -> MaterialNode) + self._diameter_machine_variant_material_map = dict() # approximate diameter str -> dict(machine_definition_id -> MaterialNode) # We're using these two maps to convert between the specific diameter material id and the generic material id # because the generic material ids are used in qualities and definitions, while the specific diameter material is meant # i.e. generic_pla -> generic_pla_175 - self._material_diameter_map = defaultdict(dict) # root_material_id -> diameter -> root_material_id for that diameter + self._material_diameter_map = defaultdict(dict) # root_material_id -> approximate diameter str -> root_material_id for that diameter self._diameter_material_map = dict() # material id including diameter (generic_pla_175) -> material root id (generic_pla) # This is used in Legacy UM3 send material function and the material management page. From a0acf8631d4e774c6398b5b581beacfd54a6c12e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:18:01 +0100 Subject: [PATCH 180/266] Add copyright headers --- cura/Machines/ContainerGroup.py | 3 +++ cura/Machines/ContainerNode.py | 3 +++ cura/Machines/MaterialManager.py | 3 +++ cura/Machines/Models/BuildPlateModel.py | 3 +++ cura/Machines/QualityManager.py | 3 +++ 5 files changed, 15 insertions(+) diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index b7ad634f3c..a722b5b4f1 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from typing import List, Optional from PyQt5.Qt import QObject, pyqtSlot diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py index 4d8d663284..6a839fb921 100644 --- a/cura/Machines/ContainerNode.py +++ b/cura/Machines/ContainerNode.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from typing import Optional from collections import OrderedDict diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 07b83853cf..997d37a672 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from collections import defaultdict, OrderedDict from typing import Optional diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py index fccf4fa44e..1cb94216a6 100644 --- a/cura/Machines/Models/BuildPlateModel.py +++ b/cura/Machines/Models/BuildPlateModel.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from PyQt5.QtCore import Qt from UM.Application import Application diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index eb8a3611c1..7e2f738890 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from typing import Optional from PyQt5.Qt import pyqtSignal From 025239c26ea99d7c9ea982221b5b1e9daed1bd85 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:24:31 +0100 Subject: [PATCH 181/266] Add documentation for ContainerGroup --- cura/Machines/ContainerGroup.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py index a722b5b4f1..0167b3eebe 100644 --- a/cura/Machines/ContainerGroup.py +++ b/cura/Machines/ContainerGroup.py @@ -8,6 +8,19 @@ from PyQt5.Qt import QObject, pyqtSlot from cura.Machines.ContainerNode import ContainerNode +# +# A ContainerGroup represents a group of containers that must be applied to each ContainerStack when it's used. +# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type +# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3 +# as an example, suppose we choose quality type "normal", the actual InstanceConstainers on each stack may look +# as below: +# GlobalStack ExtruderStack 1 ExtruderStack 2 +# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal +# +# This ContainerGroup is mainly used in quality and quality_changes to group the containers that can be applied to +# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead +# of looking them up again. +# class ContainerGroup(QObject): def __init__(self, name: str, parent = None): From 4a202d67288d2e31aab1635ff105e4165df5f109 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:42:26 +0100 Subject: [PATCH 182/266] Use getMultiBuildPlateModel() --- cura/CuraApplication.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eb09f1ed82..34f2fb5744 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1046,7 +1046,7 @@ class CuraApplication(QtApplication): count = 0 scene_bounding_box = None is_block_slicing_node = False - active_build_plate = self._multi_build_plate_model.activeBuildPlate + active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate for node in DepthFirstIterator(self.getController().getScene().getRoot()): if ( not issubclass(type(node), CuraSceneNode) or @@ -1295,7 +1295,7 @@ class CuraApplication(QtApplication): @pyqtSlot() def arrangeAll(self): nodes = [] - active_build_plate = self._multi_build_plate_model.activeBuildPlate + active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate for node in DepthFirstIterator(self.getController().getScene().getRoot()): if not isinstance(node, SceneNode): continue @@ -1444,7 +1444,7 @@ class CuraApplication(QtApplication): group_decorator = GroupDecorator() group_node.addDecorator(group_decorator) group_node.addDecorator(ConvexHullDecorator()) - group_node.addDecorator(BuildPlateDecorator(self._multi_build_plate_model.activeBuildPlate)) + group_node.addDecorator(BuildPlateDecorator(self.getMultiBuildPlateModel().activeBuildPlate)) group_node.setParent(self.getController().getScene().getRoot()) group_node.setSelectable(True) center = Selection.getSelectionCenter() @@ -1589,7 +1589,7 @@ class CuraApplication(QtApplication): arrange_objects_on_load = ( not Preferences.getInstance().getValue("cura/use_multi_build_plate") or not Preferences.getInstance().getValue("cura/not_arrange_objects_on_load")) - target_build_plate = self._multi_build_plate_model.activeBuildPlate if arrange_objects_on_load else -1 + target_build_plate = self.getMultiBuildPlateModel().activeBuildPlate if arrange_objects_on_load else -1 root = self.getController().getScene().getRoot() fixed_nodes = [] From 07824c21e103bcf43bf102c98793fc0c220110b9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:48:20 +0100 Subject: [PATCH 183/266] Move getMachineDefinitionIDForQualitySearch() into QualityManager.py --- cura/Machines/MachineTools.py | 25 ------------------------- cura/Machines/QualityManager.py | 25 ++++++++++++++++++++++++- cura/Settings/ContainerManager.py | 2 +- cura/Settings/CuraContainerRegistry.py | 2 +- cura/Settings/MachineManager.py | 2 +- plugins/3MFReader/ThreeMFReader.py | 2 +- 6 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 cura/Machines/MachineTools.py diff --git a/cura/Machines/MachineTools.py b/cura/Machines/MachineTools.py deleted file mode 100644 index 91daa2490b..0000000000 --- a/cura/Machines/MachineTools.py +++ /dev/null @@ -1,25 +0,0 @@ -from UM.Util import parseBool - - -# -# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given -# machine. The rule is as follows: -# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic -# machine. -# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's -# own machine definition ID for quality search. -# Example: for an Ultimaker 3, the definition ID should be "ultimaker3". -# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the -# definition ID specified in "quality_definition" should be used. -# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended -# shares the same set of qualities profiles as Ultimaker 3. -# -def getMachineDefinitionIDForQualitySearch(machine: "GlobalStack", default_definition_id: str = "fdmprinter") -> str: - machine_definition_id = default_definition_id - if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): - # Only use the machine's own quality definition ID if this machine has machine quality. - machine_definition_id = machine.getMetaDataEntry("quality_definition") - if machine_definition_id is None: - machine_definition_id = machine.definition.getId() - - return machine_definition_id diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 7e2f738890..f5051a5a5a 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -12,7 +12,6 @@ from UM.Util import parseBool from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerNode import ContainerNode -from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch # @@ -402,3 +401,27 @@ class QualityManager(QObject): break return quality_group_dict + + +# +# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given +# machine. The rule is as follows: +# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic +# machine. +# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's +# own machine definition ID for quality search. +# Example: for an Ultimaker 3, the definition ID should be "ultimaker3". +# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the +# definition ID specified in "quality_definition" should be used. +# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended +# shares the same set of qualities profiles as Ultimaker 3. +# +def getMachineDefinitionIDForQualitySearch(machine: "GlobalStack", default_definition_id: str = "fdmprinter") -> str: + machine_definition_id = default_definition_id + if parseBool(machine.getMetaDataEntry("has_machine_quality", False)): + # Only use the machine's own quality definition ID if this machine has machine quality. + machine_definition_id = machine.getMetaDataEntry("quality_definition") + if machine_definition_id is None: + machine_definition_id = machine.definition.getId() + + return machine_definition_id diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d49ec79037..96fff61b0b 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -29,7 +29,7 @@ from UM.i18n import i18nCatalog from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderStack import ExtruderStack -from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch +from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch catalog = i18nCatalog("cura") diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index d6faf214dd..e79cfa5335 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -28,7 +28,7 @@ from . import GlobalStack from .ExtruderManager import ExtruderManager from cura.CuraApplication import CuraApplication -from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch +from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 5abd5d4649..c155783417 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -24,7 +24,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique -from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch +from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch from cura.PrinterOutputDevice import PrinterOutputDevice from cura.Settings.ExtruderManager import ExtruderManager diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 95d8146d32..ec590a0212 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -22,7 +22,7 @@ from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Scene.BuildPlateDecorator import BuildPlateDecorator from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.ZOffsetDecorator import ZOffsetDecorator -from cura.Machines.MachineTools import getMachineDefinitionIDForQualitySearch +from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch MYPY = False From 37f86a43deef089391d4a308499bed47bc269fc9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:49:03 +0100 Subject: [PATCH 184/266] Fix type hinting for getQualityGroupsForMachineDefinition() --- cura/Machines/QualityManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index f5051a5a5a..be8488fa61 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -378,7 +378,7 @@ class QualityManager(QObject): return quality_group_dict - def getQualityGroupsForMachineDefinition(self, machine: str) -> dict: + def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> dict: # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) From 741dc8b8a3aad1a679e18dbfe3943c7adedaa2e2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 28 Feb 2018 11:56:12 +0100 Subject: [PATCH 185/266] Remove ContainerGroup in favour of QualityGroup --- cura/Machines/ContainerGroup.py | 51 --------------------------------- cura/Machines/QualityManager.py | 48 ++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 58 deletions(-) delete mode 100644 cura/Machines/ContainerGroup.py diff --git a/cura/Machines/ContainerGroup.py b/cura/Machines/ContainerGroup.py deleted file mode 100644 index 0167b3eebe..0000000000 --- a/cura/Machines/ContainerGroup.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from typing import List, Optional - -from PyQt5.Qt import QObject, pyqtSlot - -from cura.Machines.ContainerNode import ContainerNode - - -# -# A ContainerGroup represents a group of containers that must be applied to each ContainerStack when it's used. -# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type -# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3 -# as an example, suppose we choose quality type "normal", the actual InstanceConstainers on each stack may look -# as below: -# GlobalStack ExtruderStack 1 ExtruderStack 2 -# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal -# -# This ContainerGroup is mainly used in quality and quality_changes to group the containers that can be applied to -# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead -# of looking them up again. -# -class ContainerGroup(QObject): - - def __init__(self, name: str, parent = None): - super().__init__(parent) - self.name = name - self.node_for_global = None # type: Optional[ContainerNode] - self.nodes_for_extruders = dict() - - @pyqtSlot(result = str) - def getName(self) -> str: - return self.name - - def getAllKeys(self) -> set: - result = set() - for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): - if node is None: - continue - for key in node.getContainer().getAllKeys(): - result.add(key) - return result - - def getAllNodes(self) -> List[ContainerNode]: - result = [] - if self.node_for_global is not None: - result.append(self.node_for_global) - for extruder_node in self.nodes_for_extruders.values(): - result.append(extruder_node) - return result diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index be8488fa61..0bb2be1f89 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,16 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional +from typing import Optional, List -from PyQt5.Qt import pyqtSignal -from PyQt5.QtCore import QObject, QTimer +from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot from UM.Application import Application from UM.Logger import Logger from UM.Util import parseBool -from cura.Machines.ContainerGroup import ContainerGroup from cura.Machines.ContainerNode import ContainerNode @@ -29,14 +27,50 @@ from cura.Machines.ContainerNode import ContainerNode # + # - -class QualityGroup(ContainerGroup): +# +# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used. +# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type +# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3 +# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look +# as below: +# GlobalStack ExtruderStack 1 ExtruderStack 2 +# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal +# +# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to +# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead +# of looking them up again. +# +class QualityGroup(QObject): def __init__(self, name: str, quality_type: str, parent = None): - super().__init__(name, parent) + super().__init__(parent) + self.name = name + self.node_for_global = None # type: Optional["QualityGroup"] + self.nodes_for_extruders = dict() # position str -> QualityGroup self.quality_type = quality_type self.is_available = False + @pyqtSlot(result = str) + def getName(self) -> str: + return self.name + + def getAllKeys(self) -> set: + result = set() + for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): + if node is None: + continue + for key in node.getContainer().getAllKeys(): + result.add(key) + return result + + def getAllNodes(self) -> List["QualityGroup"]: + result = [] + if self.node_for_global is not None: + result.append(self.node_for_global) + for extruder_node in self.nodes_for_extruders.values(): + result.append(extruder_node) + return result + class QualityChangesGroup(QualityGroup): From 2dd7be12714c268a82ff319b081ea50f7eec743e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 10:59:39 +0100 Subject: [PATCH 186/266] Add documentation for timers in Material and Quality managers --- cura/Machines/MaterialManager.py | 3 +++ cura/Machines/QualityManager.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 997d37a672..5b07811d34 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -39,6 +39,9 @@ class MaterialManager(QObject): self._default_machine_definition_id = "fdmprinter" self._default_approximate_diameter_for_quality_search = "3" + # When a material gets added/imported, there can be more than one InstanceContainers. In those cases, we don't + # want to react on every container/metadata changed signal. The timer here is to buffer it a bit so we don't + # react too many time. self._update_timer = QTimer(self) self._update_timer.setInterval(300) self._update_timer.setSingleShot(True) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 0bb2be1f89..5783f54064 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -169,6 +169,9 @@ class QualityManager(QObject): self._container_registry.containerAdded.connect(self._onContainerMetadataChanged) self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged) + # When a custom quality gets added/imported, there can be more than one InstanceContainers. In those cases, + # we don't want to react on every container/metadata changed signal. The timer here is to buffer it a bit so + # we don't react too many time. self._update_timer = QTimer(self) self._update_timer.setInterval(300) self._update_timer.setSingleShot(True) From d4cb10b0614f94e8031d9de15bd40e1ef07e2d7c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:03:42 +0100 Subject: [PATCH 187/266] Add doc for model update --- cura/Machines/MaterialManager.py | 5 +++++ cura/Machines/QualityManager.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 5b07811d34..5e674965b3 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -13,6 +13,11 @@ from .MaterialNode import MaterialNode from .MaterialGroup import MaterialGroup +# +# MaterialManager maintains a number of maps and trees for material lookup. +# The models GUI and QML use are now only dependent on the MaterialManager. That means as long as the data in +# MaterialManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. +# class MaterialManager(QObject): materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 5783f54064..4115b710e0 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -147,6 +147,11 @@ class QualityNode(ContainerNode): quality_changes_group.addNode(QualityNode(metadata)) +# +# Similar to MaterialManager, QualityManager maintains a number of maps and trees for material lookup. +# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in +# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. +# class QualityManager(QObject): qualitiesUpdated = pyqtSignal() From b8ac5b296ba0b66358741ea34cbb2c797f5f0358 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:10:05 +0100 Subject: [PATCH 188/266] Add doc for map/tree update/recreation --- cura/Machines/MaterialManager.py | 5 +++++ cura/Machines/QualityManager.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 5e674965b3..896d309d7e 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -18,6 +18,11 @@ from .MaterialGroup import MaterialGroup # The models GUI and QML use are now only dependent on the MaterialManager. That means as long as the data in # MaterialManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. # +# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them +# again. This means the update is exactly the same as initialization. There are performance concerns about this approach +# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this +# because it's simple. +# class MaterialManager(QObject): materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated. diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 4115b710e0..68a6a344ba 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -152,6 +152,11 @@ class QualityNode(ContainerNode): # The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in # QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. # +# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them +# again. This means the update is exactly the same as initialization. There are performance concerns about this approach +# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this +# because it's simple. +# class QualityManager(QObject): qualitiesUpdated = pyqtSignal() From b5cf6b7531596a38171d6a561693040eb484fac3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:16:22 +0100 Subject: [PATCH 189/266] Rename selectedQualityItem and add docs --- cura/Machines/Models/QualitySettingsModel.py | 27 +++++++++++--------- resources/qml/Preferences/ProfileTab.qml | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 304e2f36f0..a62654ad2c 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -8,6 +8,9 @@ from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry +# +# This model is used to show details settings of the selected quality in the quality management page. +# class QualitySettingsModel(ListModel): KeyRole = Qt.UserRole + 1 LabelRole = Qt.UserRole + 2 @@ -33,7 +36,7 @@ class QualitySettingsModel(ListModel): self._quality_manager = self._application._quality_manager self._extruder_position = "" - self._quality_item = None + self._selected_quality_item = None # The selected quality in the quality management page self._i18n_catalog = None self._quality_manager.qualitiesUpdated.connect(self._update) @@ -41,7 +44,7 @@ class QualitySettingsModel(ListModel): self._update() extruderPositionChanged = pyqtSignal() - qualityItemChanged = pyqtSignal() + selectedQualityItemChanged = pyqtSignal() def setExtruderPosition(self, extruder_position): if extruder_position != self._extruder_position: @@ -53,18 +56,18 @@ class QualitySettingsModel(ListModel): def extruderPosition(self): return self._extruder_position - def setQualityItem(self, quality_item): - if quality_item != self._quality_item: - self._quality_item = quality_item - self.qualityItemChanged.emit() + def setSelectedQualityItem(self, selected_quality_item): + if selected_quality_item != self._selected_quality_item: + self._selected_quality_item = selected_quality_item + self.selectedQualityItemChanged.emit() self._update() - @pyqtProperty("QVariantMap", fset = setQualityItem, notify = qualityItemChanged) - def qualityItem(self): - return self._quality_item + @pyqtProperty("QVariantMap", fset = setSelectedQualityItem, notify = selectedQualityItemChanged) + def selectedQualityItem(self): + return self._selected_quality_item def _update(self): - if self._quality_item is None: + if self._selected_quality_item is None: self.setItems([]) return @@ -73,8 +76,8 @@ class QualitySettingsModel(ListModel): global_container_stack = Application.getInstance().getGlobalContainerStack() definition_container = global_container_stack.definition - quality_group = self._quality_item["quality_group"] - quality_changes_group = self._quality_item["quality_changes_group"] + quality_group = self._selected_quality_item["quality_group"] + quality_changes_group = self._selected_quality_item["quality_changes_group"] if self._extruder_position == "": quality_node = quality_group.node_for_global diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index b4b2299c15..82671f306f 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -86,7 +86,7 @@ Tab { id: qualitySettings extruderPosition: base.extruderPosition - qualityItem: base.qualityItem + selectedQualityItem: base.qualityItem } SystemPalette { id: palette } From ea2b076dbd73a219f940e1cb1c7d67af24c1d04b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:19:46 +0100 Subject: [PATCH 190/266] Rename to extruder_variant_name in MaterialManager --- cura/Machines/MaterialManager.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 896d309d7e..cc606d216f 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -229,7 +229,8 @@ class MaterialManager(QObject): # # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup. # - def getAvailableMaterials(self, machine_definition_id: str, variant_name: Optional[str], diameter: float) -> dict: + def getAvailableMaterials(self, machine_definition_id: str, extruder_variant_name: Optional[str], + diameter: float) -> dict: # round the diameter to get the approximate diameter rounded_diameter = str(round(diameter)) if rounded_diameter not in self._diameter_machine_variant_material_map: @@ -241,8 +242,8 @@ class MaterialManager(QObject): machine_node = machine_variant_material_map.get(machine_definition_id) default_machine_node = machine_variant_material_map.get(self._default_machine_definition_id) variant_node = None - if variant_name is not None and machine_node is not None: - variant_node = machine_node.getChildNode(variant_name) + if extruder_variant_name is not None and machine_node is not None: + variant_node = machine_node.getChildNode(extruder_variant_name) nodes_to_check = [variant_node, machine_node, default_machine_node] @@ -265,7 +266,8 @@ class MaterialManager(QObject): # 1. the given machine doesn't have materials; # 2. cannot find any material InstanceContainers with the given settings. # - def getMaterialNode(self, machine_definition_id: str, variant_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]: + def getMaterialNode(self, machine_definition_id: str, extruder_variant_name: Optional[str], + diameter: float, root_material_id: str) -> Optional["InstanceContainer"]: # round the diameter to get the approximate diameter rounded_diameter = str(round(diameter)) if rounded_diameter not in self._diameter_machine_variant_material_map: @@ -281,8 +283,8 @@ class MaterialManager(QObject): # Fallback for "fdmprinter" if the machine-specific materials cannot be found if machine_node is None: machine_node = machine_variant_material_map.get(self._default_machine_definition_id) - if machine_node is not None and variant_name is not None: - variant_node = machine_node.getChildNode(variant_name) + if machine_node is not None and extruder_variant_name is not None: + variant_node = machine_node.getChildNode(extruder_variant_name) # Fallback mechanism of finding materials: # 1. variant-specific material From 50c61c99347399bff8f43c07a27bc76c0fa78a55 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:31:18 +0100 Subject: [PATCH 191/266] Document and rename getFallbackMaterialIdByMaterialType() --- cura/Machines/MaterialManager.py | 7 ++++++- cura/Machines/QualityManager.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index cc606d216f..ffb796a705 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -307,10 +307,15 @@ class MaterialManager(QObject): # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use # the generic material IDs to search for qualities. # + # An example would be, suppose we have machine with preferred material set to "filo3d_pla" (1.75mm), but its + # extruders only use 2.85mm materials, then we won't be able to find the preferred material for this machine. + # A fallback would be to fetch a generic material of the same type "PLA" as "filo3d_pla", and in this case it will + # be "generic_pla". This function is intended to get a generic fallback material for the given material type. + # # This function returns the generic root material ID for the given material type, where material types are "PLA", # "ABS", etc. # - def getFallbackMaterialId(self, material_type: str) -> str: + def getFallbackMaterialIdByMaterialType(self, material_type: str) -> str: # For safety if material_type not in self._fallback_materials_map: Logger.log("w", "The material type [%s] does not have a fallback material" % material_type) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 68a6a344ba..90ba7d8da3 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -376,7 +376,7 @@ class QualityManager(QObject): # Also try to get the fallback material material_type = extruder.material.getMetaDataEntry("material") - fallback_root_material_id = self._material_manager.getFallbackMaterialId(material_type) + fallback_root_material_id = self._material_manager.getFallbackMaterialIdByMaterialType(material_type) if fallback_root_material_id: root_material_id_list.append(fallback_root_material_id) From 154d104f9506150ca68fb99553a686abf74c1552 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:40:22 +0100 Subject: [PATCH 192/266] Fix the using of protected property in CustomQualityProfilesModel --- cura/Machines/Models/CustomQualityProfilesModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/Models/CustomQualityProfilesModel.py b/cura/Machines/Models/CustomQualityProfilesModel.py index 71a6b6c0f7..f4325bef71 100644 --- a/cura/Machines/Models/CustomQualityProfilesModel.py +++ b/cura/Machines/Models/CustomQualityProfilesModel.py @@ -12,7 +12,7 @@ class CustomQualityProfilesModel(QualityProfilesModel): def _update(self): Logger.log("d", "Updating %s ...", self.__class__.__name__) - active_global_stack = Application.getInstance().getMachineManager()._global_container_stack + active_global_stack = Application.getInstance().getMachineManager().activeMachine if active_global_stack is None: self.setItems([]) Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) From f485702e58a34f2bd6d5f2f5e7446347394defaf Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:41:41 +0100 Subject: [PATCH 193/266] Add doc for CustomQualityProfilesModel --- cura/Machines/Models/CustomQualityProfilesModel.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Machines/Models/CustomQualityProfilesModel.py b/cura/Machines/Models/CustomQualityProfilesModel.py index f4325bef71..4c88d83fdc 100644 --- a/cura/Machines/Models/CustomQualityProfilesModel.py +++ b/cura/Machines/Models/CustomQualityProfilesModel.py @@ -7,6 +7,9 @@ from UM.Logger import Logger from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel +# +# This model is used for the custom profile items in the profile drop down menu. +# class CustomQualityProfilesModel(QualityProfilesModel): def _update(self): From 580244a5467ffaadb765e08ea9e89f0e439b1597 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:50:55 +0100 Subject: [PATCH 194/266] Split material models into separate files --- cura/CuraApplication.py | 7 +- cura/Machines/Models/BaseMaterialsModel.py | 71 ++++ cura/Machines/Models/BrandMaterialsModel.py | 112 +++++++ cura/Machines/Models/GenericMaterialsModel.py | 54 +++ .../Models/MaterialManagementModel.py | 101 ++++++ cura/Machines/Models/MaterialsModel.py | 317 ------------------ resources/qml/Preferences/MaterialsPage.qml | 2 +- 7 files changed, 344 insertions(+), 320 deletions(-) create mode 100644 cura/Machines/Models/BaseMaterialsModel.py create mode 100644 cura/Machines/Models/BrandMaterialsModel.py create mode 100644 cura/Machines/Models/GenericMaterialsModel.py create mode 100644 cura/Machines/Models/MaterialManagementModel.py delete mode 100644 cura/Machines/Models/MaterialsModel.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 34f2fb5744..a4e86626dc 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -62,7 +62,10 @@ from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfile from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel -from cura.Machines.Models.MaterialsModel import BrandMaterialsModel, GenericMaterialsModel, MaterialsModel +from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel +from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel +from cura.Machines.Models.BrandMaterialsModel import BrandMaterialsModel + from cura.Settings.SettingInheritanceManager import SettingInheritanceManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager @@ -954,7 +957,7 @@ class CuraApplication(QtApplication): qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel") - qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel") + qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel") qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py new file mode 100644 index 0000000000..1ad4da8513 --- /dev/null +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -0,0 +1,71 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty + +from UM.Logger import Logger +from UM.Qt.ListModel import ListModel + + +def getAvailableMaterials(extruder_position: Optional[int] = None): + from cura.CuraApplication import CuraApplication + machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + + material_manager = CuraApplication.getInstance()._material_manager + + active_global_stack = machine_manager._global_container_stack + extruder_stack = extruder_manager.getActiveExtruderStack() + if extruder_position is not None: + if active_global_stack is not None: + extruder_stack = active_global_stack.extruders.get(str(extruder_position)) + + if active_global_stack is None or extruder_stack is None: + Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", + active_global_stack, extruder_stack) + return + + machine_definition_id = active_global_stack.definition.getId() + variant_name = None + if extruder_stack.variant.getId() != "empty_variant": + variant_name = extruder_stack.variant.getName() + diameter = extruder_stack.approximateMaterialDiameter + + # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. + result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) + return result_dict + + +class BaseMaterialsModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + IdRole = Qt.UserRole + 2 + NameRole = Qt.UserRole + 3 + BrandRole = Qt.UserRole + 4 + MaterialRole = Qt.UserRole + 5 + ColorRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 + + extruderPositionChanged = pyqtSignal() + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.IdRole, "id") + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialRole, "material") + self.addRoleName(self.ColorRole, "color_name") + self.addRoleName(self.ContainerNodeRole, "container_node") + + self._extruder_position = 0 + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_positoin diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py new file mode 100644 index 0000000000..9e2aaa02e8 --- /dev/null +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -0,0 +1,112 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty + +from UM.Qt.ListModel import ListModel + +from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials + + +class MaterialsModelGroupedByType(ListModel): + NameRole = Qt.UserRole + 1 + ColorsRole = Qt.UserRole + 2 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.ColorsRole, "colors") + + +## Brand --> Material Type -> list of materials +class BrandMaterialsModel(ListModel): + NameRole = Qt.UserRole + 1 + MaterialsRole = Qt.UserRole + 2 + + extruderPositionChanged = pyqtSignal() + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.NameRole, "name") + self.addRoleName(self.MaterialsRole, "materials") + + self._extruder_position = 0 + + from cura.CuraApplication import CuraApplication + self._machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + self._update() + + def setExtruderPosition(self, position: int): + if self._extruder_position != position: + self._extruder_position = position + self.extruderPositionChanged.emit() + + @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) + def extruderPosition(self) -> int: + return self._extruder_position + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials(self._extruder_position) + if result_dict is None: + self.setItems([]) + return + + brand_item_list = [] + brand_group_dict = {} + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + brand = metadata["brand"] + # Only add results for generic materials + if brand.lower() == "generic": + continue + + if brand not in brand_group_dict: + brand_group_dict[brand] = {} + + material_type = metadata["material"] + if material_type not in brand_group_dict[brand]: + brand_group_dict[brand][material_type] = [] + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + brand_group_dict[brand][material_type].append(item) + + for brand, material_dict in brand_group_dict.items(): + brand_item = {"name": brand, + "materials": MaterialsModelGroupedByType(self)} + + material_type_item_list = [] + for material_type, material_list in material_dict.items(): + material_type_item = {"name": material_type, + "colors": BaseMaterialsModel(self)} + material_type_item["colors"].clear() + material_type_item["colors"].setItems(material_list) + + material_type_item_list.append(material_type_item) + + brand_item["materials"].setItems(material_type_item_list) + + brand_item_list.append(brand_item) + + self.setItems(brand_item_list) + diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py new file mode 100644 index 0000000000..dd18abe7c3 --- /dev/null +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -0,0 +1,54 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials + + +class GenericMaterialsModel(BaseMaterialsModel): + + def __init__(self, parent = None): + super().__init__(parent) + + from cura.CuraApplication import CuraApplication + self._machine_manager = CuraApplication.getInstance().getMachineManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + self._extruder_manager.activeExtruderChanged.connect(self._update) + self._material_manager.materialsUpdated.connect(self._update) + + self._update() + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials(self._extruder_position) + if result_dict is None: + self.setItems([]) + return + + item_list = [] + for root_material_id, container_node in result_dict.items(): + metadata = container_node.metadata + # Only add results for generic materials + if metadata["brand"].lower() != "generic": + continue + + item = {"root_material_id": root_material_id, + "id": metadata["id"], + "name": metadata["name"], + "brand": metadata["brand"], + "material": metadata["material"], + "color_name": metadata["color_name"], + "container_node": container_node + } + item_list.append(item) + + # Sort the item list by material name alphabetically + item_list = sorted(item_list, key = lambda d: d["name"]) + + self.setItems(item_list) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py new file mode 100644 index 0000000000..35173129e0 --- /dev/null +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -0,0 +1,101 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import Qt, pyqtProperty + +from UM.Qt.ListModel import ListModel + +from .BaseMaterialsModel import getAvailableMaterials + + +# +# This model is for the Material management page. +# +class MaterialManagementModel(ListModel): + RootMaterialIdRole = Qt.UserRole + 1 + DisplayNameRole = Qt.UserRole + 2 + BrandRole = Qt.UserRole + 3 + MaterialTypeRole = Qt.UserRole + 4 + ColorNameRole = Qt.UserRole + 5 + ColorCodeRole = Qt.UserRole + 6 + ContainerNodeRole = Qt.UserRole + 7 + ContainerIdRole = Qt.UserRole + 8 + + DescriptionRole = Qt.UserRole + 9 + AdhesionInfoRole = Qt.UserRole + 10 + ApproximateDiameterRole = Qt.UserRole + 11 + GuidRole = Qt.UserRole + 12 + DensityRole = Qt.UserRole + 13 + DiameterRole = Qt.UserRole + 14 + IsReadOnlyRole = Qt.UserRole + 15 + + def __init__(self, parent = None): + super().__init__(parent) + + self.addRoleName(self.RootMaterialIdRole, "root_material_id") + self.addRoleName(self.DisplayNameRole, "name") + self.addRoleName(self.BrandRole, "brand") + self.addRoleName(self.MaterialTypeRole, "material") + self.addRoleName(self.ColorNameRole, "color_name") + self.addRoleName(self.ColorCodeRole, "color_code") + self.addRoleName(self.ContainerNodeRole, "container_node") + self.addRoleName(self.ContainerIdRole, "container_id") + + self.addRoleName(self.DescriptionRole, "description") + self.addRoleName(self.AdhesionInfoRole, "adhesion_info") + self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter") + self.addRoleName(self.GuidRole, "guid") + self.addRoleName(self.DensityRole, "density") + self.addRoleName(self.DiameterRole, "diameter") + self.addRoleName(self.IsReadOnlyRole, "is_read_only") + + from cura.CuraApplication import CuraApplication + self._container_registry = CuraApplication.getInstance().getContainerRegistry() + self._machine_manager = CuraApplication.getInstance().getMachineManager() + extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance()._material_manager + + self._machine_manager.globalContainerChanged.connect(self._update) + extruder_manager.activeExtruderChanged.connect(self._update) + material_manager.materialsUpdated.connect(self._update) + + self._update() + + def _update(self): + global_stack = self._machine_manager.activeMachine + if global_stack is None: + self.setItems([]) + return + + result_dict = getAvailableMaterials() + if result_dict is None: + self.setItems([]) + return + + material_list = [] + for root_material_id, container_node in result_dict.items(): + keys_to_fetch = ("name", + "brand", + "material", + "color_name", + "color_code", + "description", + "adhesion_info", + "approximate_diameter",) + + item = {"root_material_id": container_node.metadata["base_file"], + "container_node": container_node, + "guid": container_node.metadata["GUID"], + "container_id": container_node.metadata["id"], + "density": container_node.metadata.get("properties", {}).get("density", ""), + "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), + "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]), + } + + for key in keys_to_fetch: + item[key] = container_node.metadata.get(key, "") + + material_list.append(item) + + material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"])) + self.setItems(material_list) diff --git a/cura/Machines/Models/MaterialsModel.py b/cura/Machines/Models/MaterialsModel.py deleted file mode 100644 index 5ef5845371..0000000000 --- a/cura/Machines/Models/MaterialsModel.py +++ /dev/null @@ -1,317 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from typing import Optional -from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty - -from UM.Logger import Logger -from UM.Qt.ListModel import ListModel - - -def getAvailableMaterials(extruder_position: Optional[int] = None): - from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - - material_manager = CuraApplication.getInstance()._material_manager - - active_global_stack = machine_manager._global_container_stack - extruder_stack = extruder_manager.getActiveExtruderStack() - if extruder_position is not None: - if active_global_stack is not None: - extruder_stack = active_global_stack.extruders.get(str(extruder_position)) - - if active_global_stack is None or extruder_stack is None: - Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", - active_global_stack, extruder_stack) - return - - machine_definition_id = active_global_stack.definition.getId() - variant_name = None - if extruder_stack.variant.getId() != "empty_variant": - variant_name = extruder_stack.variant.getName() - diameter = extruder_stack.approximateMaterialDiameter - - # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. - result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) - return result_dict - - -class BaseMaterialsModel(ListModel): - RootMaterialIdRole = Qt.UserRole + 1 - IdRole = Qt.UserRole + 2 - NameRole = Qt.UserRole + 3 - BrandRole = Qt.UserRole + 4 - MaterialRole = Qt.UserRole + 5 - ColorRole = Qt.UserRole + 6 - ContainerNodeRole = Qt.UserRole + 7 - - extruderPositionChanged = pyqtSignal() - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.RootMaterialIdRole, "root_material_id") - self.addRoleName(self.IdRole, "id") - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.BrandRole, "brand") - self.addRoleName(self.MaterialRole, "material") - self.addRoleName(self.ColorRole, "color_name") - self.addRoleName(self.ContainerNodeRole, "container_node") - - self._extruder_position = 0 - - def setExtruderPosition(self, position: int): - if self._extruder_position != position: - self._extruder_position = position - self.extruderPositionChanged.emit() - - @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) - def extruderPosition(self) -> int: - return self._extruder_positoin - - -class GenericMaterialsModel(BaseMaterialsModel): - - def __init__(self, parent = None): - super().__init__(parent) - - from cura.CuraApplication import CuraApplication - self._machine_manager = CuraApplication.getInstance().getMachineManager() - self._extruder_manager = CuraApplication.getInstance().getExtruderManager() - self._material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - self._extruder_manager.activeExtruderChanged.connect(self._update) - self._material_manager.materialsUpdated.connect(self._update) - - self._update() - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials(self._extruder_position) - if result_dict is None: - self.setItems([]) - return - - item_list = [] - for root_material_id, container_node in result_dict.items(): - metadata = container_node.metadata - # Only add results for generic materials - if metadata["brand"].lower() != "generic": - continue - - item = {"root_material_id": root_material_id, - "id": metadata["id"], - "name": metadata["name"], - "brand": metadata["brand"], - "material": metadata["material"], - "color_name": metadata["color_name"], - "container_node": container_node - } - item_list.append(item) - - # Sort the item list by material name alphabetically - item_list = sorted(item_list, key = lambda d: d["name"]) - - self.setItems(item_list) - - -class MaterialsModelGroupedByType(ListModel): - NameRole = Qt.UserRole + 1 - ColorsRole = Qt.UserRole + 2 - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.ColorsRole, "colors") - - -## Brand --> Material Type -> list of materials -class BrandMaterialsModel(ListModel): - NameRole = Qt.UserRole + 1 - MaterialsRole = Qt.UserRole + 2 - - extruderPositionChanged = pyqtSignal() - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.MaterialsRole, "materials") - - self._extruder_position = 0 - - from cura.CuraApplication import CuraApplication - self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) - - self._update() - - def setExtruderPosition(self, position: int): - if self._extruder_position != position: - self._extruder_position = position - self.extruderPositionChanged.emit() - - @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged) - def extruderPosition(self) -> int: - return self._extruder_position - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials(self._extruder_position) - if result_dict is None: - self.setItems([]) - return - - brand_item_list = [] - brand_group_dict = {} - for root_material_id, container_node in result_dict.items(): - metadata = container_node.metadata - brand = metadata["brand"] - # Only add results for generic materials - if brand.lower() == "generic": - continue - - if brand not in brand_group_dict: - brand_group_dict[brand] = {} - - material_type = metadata["material"] - if material_type not in brand_group_dict[brand]: - brand_group_dict[brand][material_type] = [] - - item = {"root_material_id": root_material_id, - "id": metadata["id"], - "name": metadata["name"], - "brand": metadata["brand"], - "material": metadata["material"], - "color_name": metadata["color_name"], - "container_node": container_node - } - brand_group_dict[brand][material_type].append(item) - - for brand, material_dict in brand_group_dict.items(): - brand_item = {"name": brand, - "materials": MaterialsModelGroupedByType(self)} - - material_type_item_list = [] - for material_type, material_list in material_dict.items(): - material_type_item = {"name": material_type, - "colors": BaseMaterialsModel(self)} - material_type_item["colors"].clear() - material_type_item["colors"].setItems(material_list) - - material_type_item_list.append(material_type_item) - - brand_item["materials"].setItems(material_type_item_list) - - brand_item_list.append(brand_item) - - self.setItems(brand_item_list) - - -# -# This model is for the Material management page. -# -class MaterialsModel(ListModel): - RootMaterialIdRole = Qt.UserRole + 1 - DisplayNameRole = Qt.UserRole + 2 - BrandRole = Qt.UserRole + 3 - MaterialTypeRole = Qt.UserRole + 4 - ColorNameRole = Qt.UserRole + 5 - ColorCodeRole = Qt.UserRole + 6 - ContainerNodeRole = Qt.UserRole + 7 - ContainerIdRole = Qt.UserRole + 8 - - DescriptionRole = Qt.UserRole + 9 - AdhesionInfoRole = Qt.UserRole + 10 - ApproximateDiameterRole = Qt.UserRole + 11 - GuidRole = Qt.UserRole + 12 - DensityRole = Qt.UserRole + 13 - DiameterRole = Qt.UserRole + 14 - IsReadOnlyRole = Qt.UserRole + 15 - - def __init__(self, parent = None): - super().__init__(parent) - - self.addRoleName(self.RootMaterialIdRole, "root_material_id") - self.addRoleName(self.DisplayNameRole, "name") - self.addRoleName(self.BrandRole, "brand") - self.addRoleName(self.MaterialTypeRole, "material") - self.addRoleName(self.ColorNameRole, "color_name") - self.addRoleName(self.ColorCodeRole, "color_code") - self.addRoleName(self.ContainerNodeRole, "container_node") - self.addRoleName(self.ContainerIdRole, "container_id") - - self.addRoleName(self.DescriptionRole, "description") - self.addRoleName(self.AdhesionInfoRole, "adhesion_info") - self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter") - self.addRoleName(self.GuidRole, "guid") - self.addRoleName(self.DensityRole, "density") - self.addRoleName(self.DiameterRole, "diameter") - self.addRoleName(self.IsReadOnlyRole, "is_read_only") - - from cura.CuraApplication import CuraApplication - self._container_registry = CuraApplication.getInstance().getContainerRegistry() - self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager - - self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) - - self._update() - - def _update(self): - global_stack = self._machine_manager.activeMachine - if global_stack is None: - self.setItems([]) - return - - result_dict = getAvailableMaterials() - if result_dict is None: - self.setItems([]) - return - - material_list = [] - for root_material_id, container_node in result_dict.items(): - keys_to_fetch = ("name", - "brand", - "material", - "color_name", - "color_code", - "description", - "adhesion_info", - "approximate_diameter",) - - item = {"root_material_id": container_node.metadata["base_file"], - "container_node": container_node, - "guid": container_node.metadata["GUID"], - "container_id": container_node.metadata["id"], - "density": container_node.metadata.get("properties", {}).get("density", ""), - "diameter": container_node.metadata.get("properties", {}).get("diameter", ""), - "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]), - } - - for key in keys_to_fetch: - item[key] = container_node.metadata.get(key, "") - - material_list.append(item) - - material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"])) - self.setItems(material_list) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 671b5c6b9b..1177f20334 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -17,7 +17,7 @@ Item UM.I18nCatalog { id: catalog; name: "cura"; } - Cura.MaterialsModel { + Cura.MaterialManagementModel { id: materialsModel } From c21174eea8a2684b659de03cc4a0b45b372ed8eb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 11:55:29 +0100 Subject: [PATCH 195/266] Fix the usage of protected variables in material models --- cura/Machines/Models/BaseMaterialsModel.py | 5 ++--- cura/Machines/Models/BrandMaterialsModel.py | 2 +- cura/Machines/Models/GenericMaterialsModel.py | 2 +- cura/Machines/Models/MaterialManagementModel.py | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 1ad4da8513..1b06fa5d1a 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -12,10 +12,9 @@ def getAvailableMaterials(extruder_position: Optional[int] = None): from cura.CuraApplication import CuraApplication machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() + material_manager = CuraApplication.getInstance().getMaterialManager() - material_manager = CuraApplication.getInstance()._material_manager - - active_global_stack = machine_manager._global_container_stack + active_global_stack = machine_manager.activeMachine extruder_stack = extruder_manager.getActiveExtruderStack() if extruder_position is not None: if active_global_stack is not None: diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index 9e2aaa02e8..1edef672d4 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -37,7 +37,7 @@ class BrandMaterialsModel(ListModel): from cura.CuraApplication import CuraApplication self._machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager + material_manager = CuraApplication.getInstance().getMaterialManager() self._machine_manager.globalContainerChanged.connect(self._update) extruder_manager.activeExtruderChanged.connect(self._update) diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index dd18abe7c3..c15f88d59a 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -12,7 +12,7 @@ class GenericMaterialsModel(BaseMaterialsModel): from cura.CuraApplication import CuraApplication self._machine_manager = CuraApplication.getInstance().getMachineManager() self._extruder_manager = CuraApplication.getInstance().getExtruderManager() - self._material_manager = CuraApplication.getInstance()._material_manager + self._material_manager = CuraApplication.getInstance().getMaterialManager() self._machine_manager.globalContainerChanged.connect(self._update) self._extruder_manager.activeExtruderChanged.connect(self._update) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index 35173129e0..cd1aa12427 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -53,7 +53,7 @@ class MaterialManagementModel(ListModel): self._container_registry = CuraApplication.getInstance().getContainerRegistry() self._machine_manager = CuraApplication.getInstance().getMachineManager() extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance()._material_manager + material_manager = CuraApplication.getInstance().getMaterialManager() self._machine_manager.globalContainerChanged.connect(self._update) extruder_manager.activeExtruderChanged.connect(self._update) From b4c353699960ae39d129159fefc7e587a5eee68b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:02:57 +0100 Subject: [PATCH 196/266] Move getAvailableMaterials() into MaterialManager --- cura/Machines/MaterialManager.py | 14 +++++++++ cura/Machines/Models/BaseMaterialsModel.py | 30 ------------------- cura/Machines/Models/BrandMaterialsModel.py | 13 ++++---- cura/Machines/Models/GenericMaterialsModel.py | 5 ++-- .../Models/MaterialManagementModel.py | 14 ++++----- 5 files changed, 31 insertions(+), 45 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index ffb796a705..2dd39d1fe1 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -260,6 +260,20 @@ class MaterialManager(QObject): return material_id_metadata_dict + # + # A convenience function to get available materials for the given machine with the extruder position. + # + def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack", + extruder_stack: "ExtruderStack") -> Optional[dict]: + machine_definition_id = machine.definition.getId() + variant_name = None + if extruder_stack.variant.getId() != "empty_variant": + variant_name = extruder_stack.variant.getName() + diameter = extruder_stack.approximateMaterialDiameter + + # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. + return self.getAvailableMaterials(machine_definition_id, variant_name, diameter) + # # Gets MaterialNode for the given extruder and machine with the given material name. # Returns None if: diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 1b06fa5d1a..c93473031a 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -1,41 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty -from UM.Logger import Logger from UM.Qt.ListModel import ListModel -def getAvailableMaterials(extruder_position: Optional[int] = None): - from cura.CuraApplication import CuraApplication - machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance().getMaterialManager() - - active_global_stack = machine_manager.activeMachine - extruder_stack = extruder_manager.getActiveExtruderStack() - if extruder_position is not None: - if active_global_stack is not None: - extruder_stack = active_global_stack.extruders.get(str(extruder_position)) - - if active_global_stack is None or extruder_stack is None: - Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.", - active_global_stack, extruder_stack) - return - - machine_definition_id = active_global_stack.definition.getId() - variant_name = None - if extruder_stack.variant.getId() != "empty_variant": - variant_name = extruder_stack.variant.getName() - diameter = extruder_stack.approximateMaterialDiameter - - # Fetch the available materials (ContainerNode) for the current active machine and extruder setup. - result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter) - return result_dict - - class BaseMaterialsModel(ListModel): RootMaterialIdRole = Qt.UserRole + 1 IdRole = Qt.UserRole + 2 diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index 1edef672d4..74518adcd6 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty from UM.Qt.ListModel import ListModel -from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials +from .BaseMaterialsModel import BaseMaterialsModel class MaterialsModelGroupedByType(ListModel): @@ -36,12 +36,12 @@ class BrandMaterialsModel(ListModel): from cura.CuraApplication import CuraApplication self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance().getMaterialManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._material_manager = CuraApplication.getInstance().getMaterialManager() self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) + self._extruder_manager.activeExtruderChanged.connect(self._update) + self._material_manager.materialsUpdated.connect(self._update) self._update() @@ -59,8 +59,9 @@ class BrandMaterialsModel(ListModel): if global_stack is None: self.setItems([]) return + extruder_stack = global_stack.extruders[str(self._extruder_position)] - result_dict = getAvailableMaterials(self._extruder_position) + result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) if result_dict is None: self.setItems([]) return diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index c15f88d59a..da7ef686d3 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials +from .BaseMaterialsModel import BaseMaterialsModel class GenericMaterialsModel(BaseMaterialsModel): @@ -25,8 +25,9 @@ class GenericMaterialsModel(BaseMaterialsModel): if global_stack is None: self.setItems([]) return + extruder_stack = global_stack.extruders[str(self._extruder_position)] - result_dict = getAvailableMaterials(self._extruder_position) + result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) if result_dict is None: self.setItems([]) return diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index cd1aa12427..abff1d6010 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -5,8 +5,6 @@ from PyQt5.QtCore import Qt, pyqtProperty from UM.Qt.ListModel import ListModel -from .BaseMaterialsModel import getAvailableMaterials - # # This model is for the Material management page. @@ -52,12 +50,12 @@ class MaterialManagementModel(ListModel): from cura.CuraApplication import CuraApplication self._container_registry = CuraApplication.getInstance().getContainerRegistry() self._machine_manager = CuraApplication.getInstance().getMachineManager() - extruder_manager = CuraApplication.getInstance().getExtruderManager() - material_manager = CuraApplication.getInstance().getMaterialManager() + self._extruder_manager = CuraApplication.getInstance().getExtruderManager() + self._material_manager = CuraApplication.getInstance().getMaterialManager() self._machine_manager.globalContainerChanged.connect(self._update) - extruder_manager.activeExtruderChanged.connect(self._update) - material_manager.materialsUpdated.connect(self._update) + self._extruder_manager.activeExtruderChanged.connect(self._update) + self._material_manager.materialsUpdated.connect(self._update) self._update() @@ -66,8 +64,10 @@ class MaterialManagementModel(ListModel): if global_stack is None: self.setItems([]) return + active_extruder_stack = self._machine_manager.activeStack - result_dict = getAvailableMaterials() + result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, + active_extruder_stack) if result_dict is None: self.setItems([]) return From 4b7c8a8a80b27a00590a4c42beda39acd3031071 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:09:58 +0100 Subject: [PATCH 197/266] Add doc for BaseMaterialsModel --- cura/Machines/Models/BaseMaterialsModel.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index c93473031a..de0c68d60a 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -6,6 +6,12 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty from UM.Qt.ListModel import ListModel +# +# This is the base model class for GenericMaterialsModel and BrandMaterialsModel +# Those 2 models are used by the material drop down menu to show generic materials and branded materials separately. +# The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top +# bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu +# class BaseMaterialsModel(ListModel): RootMaterialIdRole = Qt.UserRole + 1 IdRole = Qt.UserRole + 2 From d6f6dbe45efd799b987928cbc679bd2850ae2c66 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:12:34 +0100 Subject: [PATCH 198/266] Rename to available_material_dict --- cura/Machines/Models/BrandMaterialsModel.py | 8 ++++---- cura/Machines/Models/GenericMaterialsModel.py | 7 ++++--- cura/Machines/Models/MaterialManagementModel.py | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index 74518adcd6..ec1e3c7ebe 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -61,14 +61,15 @@ class BrandMaterialsModel(ListModel): return extruder_stack = global_stack.extruders[str(self._extruder_position)] - result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) - if result_dict is None: + available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, + extruder_stack) + if available_material_dict is None: self.setItems([]) return brand_item_list = [] brand_group_dict = {} - for root_material_id, container_node in result_dict.items(): + for root_material_id, container_node in available_material_dict.items(): metadata = container_node.metadata brand = metadata["brand"] # Only add results for generic materials @@ -110,4 +111,3 @@ class BrandMaterialsModel(ListModel): brand_item_list.append(brand_item) self.setItems(brand_item_list) - diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index da7ef686d3..f5b18adde9 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -27,13 +27,14 @@ class GenericMaterialsModel(BaseMaterialsModel): return extruder_stack = global_stack.extruders[str(self._extruder_position)] - result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) - if result_dict is None: + available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, + extruder_stack) + if available_material_dict is None: self.setItems([]) return item_list = [] - for root_material_id, container_node in result_dict.items(): + for root_material_id, container_node in available_material_dict.items(): metadata = container_node.metadata # Only add results for generic materials if metadata["brand"].lower() != "generic": diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index abff1d6010..b250232282 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -66,14 +66,14 @@ class MaterialManagementModel(ListModel): return active_extruder_stack = self._machine_manager.activeStack - result_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, - active_extruder_stack) - if result_dict is None: + available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, + active_extruder_stack) + if available_material_dict is None: self.setItems([]) return material_list = [] - for root_material_id, container_node in result_dict.items(): + for root_material_id, container_node in available_material_dict.items(): keys_to_fetch = ("name", "brand", "material", From 72b42113b3ca16e801ae9aea866533912d4f00f0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:19:01 +0100 Subject: [PATCH 199/266] Add doc for BrandMaterialsModel --- cura/Machines/Models/BrandMaterialsModel.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index ec1e3c7ebe..f6430b39da 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -8,6 +8,9 @@ from UM.Qt.ListModel import ListModel from .BaseMaterialsModel import BaseMaterialsModel +# +# This is an intermediate model to group materials with different colours for a same brand and type. +# class MaterialsModelGroupedByType(ListModel): NameRole = Qt.UserRole + 1 ColorsRole = Qt.UserRole + 2 @@ -19,7 +22,18 @@ class MaterialsModelGroupedByType(ListModel): self.addRoleName(self.ColorsRole, "colors") -## Brand --> Material Type -> list of materials +# +# This model is used to show branded materials in the material drop down menu. +# The structure of the menu looks like this: +# Brand -> Material Type -> list of materials +# +# To illustrate, a branded material menu may look like this: +# Ultimaker -> PLA -> Yellow PLA +# -> Black PLA +# -> ... +# -> ABS -> White ABS +# ... +# class BrandMaterialsModel(ListModel): NameRole = Qt.UserRole + 1 MaterialsRole = Qt.UserRole + 2 From c0604e5c759ab003a3d09728a7024a29ae9e0079 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:25:11 +0100 Subject: [PATCH 200/266] Move MultiBuildPlateModel into Models folder --- cura/CuraApplication.py | 2 +- cura/Machines/Models/{Other => }/MultiBuildPlateModel.py | 0 cura/Machines/Models/Other/__init__.py | 0 cura/Scene/CuraSceneController.py | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename cura/Machines/Models/{Other => }/MultiBuildPlateModel.py (100%) delete mode 100644 cura/Machines/Models/Other/__init__.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a4e86626dc..2aa1f8db3a 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -60,7 +60,7 @@ from cura.Machines.Models.NozzleModel import NozzleModel from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfilesModel -from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel +from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel diff --git a/cura/Machines/Models/Other/MultiBuildPlateModel.py b/cura/Machines/Models/MultiBuildPlateModel.py similarity index 100% rename from cura/Machines/Models/Other/MultiBuildPlateModel.py rename to cura/Machines/Models/MultiBuildPlateModel.py diff --git a/cura/Machines/Models/Other/__init__.py b/cura/Machines/Models/Other/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/cura/Scene/CuraSceneController.py b/cura/Scene/CuraSceneController.py index d60179ae08..749c5257a2 100644 --- a/cura/Scene/CuraSceneController.py +++ b/cura/Scene/CuraSceneController.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QObject from PyQt5.QtWidgets import QApplication from cura.ObjectsModel import ObjectsModel -from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel +from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel from UM.Application import Application from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator From 52da140833dd84e5a28c502e2a30fcf9e30e5d2d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:27:13 +0100 Subject: [PATCH 201/266] Add doc and copyright headers for MultiBuildPlateModel --- cura/Machines/Models/MultiBuildPlateModel.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cura/Machines/Models/MultiBuildPlateModel.py b/cura/Machines/Models/MultiBuildPlateModel.py index 78ad458a99..f0f4997014 100644 --- a/cura/Machines/Models/MultiBuildPlateModel.py +++ b/cura/Machines/Models/MultiBuildPlateModel.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + from PyQt5.QtCore import pyqtSignal, pyqtProperty from UM.Application import Application @@ -5,6 +8,10 @@ from UM.Scene.Selection import Selection from UM.Qt.ListModel import ListModel +# +# This is the model for multi build plate feature. +# This has nothing to do with the build plate types you can choose on the sidebar for a machine. +# class MultiBuildPlateModel(ListModel): maxBuildPlateChanged = pyqtSignal() From a395f93706d5eea2b4279b7c06bad55d773d1c36 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:28:58 +0100 Subject: [PATCH 202/266] Add docs for quality models --- cura/Machines/Models/QualityManagementModel.py | 3 +++ cura/Machines/Models/QualityProfilesModel.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 6e5b37bbfa..ab0101cfc6 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -6,6 +6,9 @@ from PyQt5.QtCore import Qt, pyqtSlot from UM.Qt.ListModel import ListModel +# +# This the QML model for the quality management page. +# class QualityManagementModel(ListModel): NameRole = Qt.UserRole + 1 IsReadOnlyRole = Qt.UserRole + 2 diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesModel.py index 3bfccd409d..6452f848ed 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesModel.py @@ -6,11 +6,12 @@ from PyQt5.QtCore import Qt from UM.Application import Application from UM.Logger import Logger from UM.Qt.ListModel import ListModel + from cura.Machines.QualityManager import QualityGroup # -# QML Model for all built-in quality profiles. +# QML Model for all built-in quality profiles. This model is used for the drop-down quality menu. # class QualityProfilesModel(ListModel): NameRole = Qt.UserRole + 1 From 06ec16d6271aadb59d1de5a3dc7b9b6706bbe9db Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:37:48 +0100 Subject: [PATCH 203/266] Rename quality drop down menu models --- cura/CuraApplication.py | 30 ++++++++++--------- ...CustomQualityProfilesDropDownMenuModel.py} | 4 +-- ...py => QualityProfilesDropDownMenuModel.py} | 2 +- resources/qml/Menus/ProfileMenu.qml | 10 +++---- resources/qml/SidebarSimple.qml | 18 +++++------ 5 files changed, 33 insertions(+), 31 deletions(-) rename cura/Machines/Models/{CustomQualityProfilesModel.py => CustomQualityProfilesDropDownMenuModel.py} (87%) rename cura/Machines/Models/{QualityProfilesModel.py => QualityProfilesDropDownMenuModel.py} (98%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2aa1f8db3a..de5d46ba96 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -57,8 +57,8 @@ from cura.Settings.MachineNameValidator import MachineNameValidator from cura.Machines.Models.BuildPlateModel import BuildPlateModel from cura.Machines.Models.NozzleModel import NozzleModel -from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel -from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfilesModel +from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel +from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel @@ -399,8 +399,8 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize - self._quality_profile_model = None - self._custom_quality_profile_model = None + self._quality_profile_drop_down_menu_model = None + self._custom_quality_profile_drop_down_menu_model = None CuraApplication.Created = True @@ -918,15 +918,15 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information - def getQualityProfileModel(self, *args, **kwargs): - if self._quality_profile_model is None: - self._quality_profile_model = QualityProfilesModel(self) - return self._quality_profile_model + def getQualityProfilesDropDownMenuModel(self, *args, **kwargs): + if self._quality_profile_drop_down_menu_model is None: + self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self) + return self._quality_profile_drop_down_menu_model - def getCustomQualityProfilesModel(self, *args, **kwargs): - if self._custom_quality_profile_model is None: - self._custom_quality_profile_model = CustomQualityProfilesModel(self) - return self._custom_quality_profile_model + def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs): + if self._custom_quality_profile_drop_down_menu_model is None: + self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self) + return self._custom_quality_profile_drop_down_menu_model ## Registers objects for the QML engine to use. # @@ -960,8 +960,10 @@ class CuraApplication(QtApplication): qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel") qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") - qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel) - qmlRegisterSingletonType(CustomQualityProfilesModel, "Cura", 1, 0, "CustomQualityProfilesModel", self.getCustomQualityProfilesModel) + qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, + "QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel) + qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, + "CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel) qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") diff --git a/cura/Machines/Models/CustomQualityProfilesModel.py b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py similarity index 87% rename from cura/Machines/Models/CustomQualityProfilesModel.py rename to cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py index 4c88d83fdc..f2b164703f 100644 --- a/cura/Machines/Models/CustomQualityProfilesModel.py +++ b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py @@ -4,13 +4,13 @@ from UM.Application import Application from UM.Logger import Logger -from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel +from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel # # This model is used for the custom profile items in the profile drop down menu. # -class CustomQualityProfilesModel(QualityProfilesModel): +class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel): def _update(self): Logger.log("d", "Updating %s ...", self.__class__.__name__) diff --git a/cura/Machines/Models/QualityProfilesModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py similarity index 98% rename from cura/Machines/Models/QualityProfilesModel.py rename to cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 6452f848ed..30b8634294 100644 --- a/cura/Machines/Models/QualityProfilesModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -13,7 +13,7 @@ from cura.Machines.QualityManager import QualityGroup # # QML Model for all built-in quality profiles. This model is used for the drop-down quality menu. # -class QualityProfilesModel(ListModel): +class QualityProfilesDropDownMenuModel(ListModel): NameRole = Qt.UserRole + 1 QualityTypeRole = Qt.UserRole + 2 LayerHeightRole = Qt.UserRole + 3 diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 5924ad5322..7a78b7a911 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -13,7 +13,7 @@ Menu Instantiator { - model: Cura.QualityProfilesModel + model: Cura.QualityProfilesDropDownMenuModel MenuItem { @@ -34,18 +34,18 @@ Menu MenuSeparator { id: customSeparator - visible: Cura.CustomQualityProfilesModel.rowCount > 0 + visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0 } Instantiator { id: customProfileInstantiator - model: Cura.CustomQualityProfilesModel + model: Cura.CustomQualityProfilesDropDownMenuModel Connections { - target: Cura.CustomQualityProfilesModel - onModelReset: customSeparator.visible = Cura.CustomQualityProfilesModel.rowCount() > 0 + target: Cura.CustomQualityProfilesDropDownMenuModel + onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0 } MenuItem diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 507091a721..fa8f253452 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -58,7 +58,7 @@ Item running: false repeat: false onTriggered: { - var item = Cura.QualityProfilesModel.getItem(qualitySlider.value); + var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value); Cura.MachineManager.activeQualityGroup = item.quality_group; } } @@ -105,8 +105,8 @@ Item var availableMin = -1 var availableMax = -1 - for (var i = 0; i < Cura.QualityProfilesModel.rowCount(); i++) { - var qualityItem = Cura.QualityProfilesModel.getItem(i) + for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) { + var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i) // Add each quality item to the UI quality model qualityModel.append(qualityItem) @@ -168,7 +168,7 @@ Item qualityModel.existingQualityProfile = 0 // check, the ticks count cannot be less than zero - qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesModel.rowCount() - 1) + qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1) } } @@ -194,13 +194,13 @@ Item anchors.verticalCenter: parent.verticalCenter anchors.top: parent.top anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) - color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") text: { var result = "" if(Cura.MachineManager.activeMachine != null) { - result = Cura.QualityProfilesModel.getItem(index).layer_height_without_unit + result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height_without_unit if(result == undefined) { @@ -265,7 +265,7 @@ Item Rectangle { anchors.verticalCenter: parent.verticalCenter - color: Cura.QualityProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") + color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") width: 1 * screenScaleFactor height: 6 * screenScaleFactor y: 0 @@ -403,9 +403,9 @@ Item // if the current profile is user-created, switch to a built-in quality if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { - if (Cura.QualityProfilesModel.rowCount() > 0) + if (Cura.QualityProfilesDropDownMenuModel.rowCount() > 0) { - var item = Cura.QualityProfilesModel.getItem(0); + var item = Cura.QualityProfilesDropDownMenuModel.getItem(0); Cura.MachineManager.activeQualityGroup = item.quality_group; } } From d1c518f6d7882426a1306b4fe50a995b3acd6030 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:44:06 +0100 Subject: [PATCH 204/266] Fix the usage of protected variables in quality models --- .../CustomQualityProfilesDropDownMenuModel.py | 3 +-- cura/Machines/Models/QualityManagementModel.py | 4 ++-- .../Models/QualityProfilesDropDownMenuModel.py | 17 +++++++++-------- cura/Machines/Models/QualitySettingsModel.py | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py index f2b164703f..0d297379cd 100644 --- a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.Application import Application from UM.Logger import Logger from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel @@ -15,7 +14,7 @@ class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel): def _update(self): Logger.log("d", "Updating %s ...", self.__class__.__name__) - active_global_stack = Application.getInstance().getMachineManager().activeMachine + active_global_stack = self._machine_manager.activeMachine if active_global_stack is None: self.setItems([]) Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index ab0101cfc6..a3c321815a 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -27,7 +27,7 @@ class QualityManagementModel(ListModel): self._container_registry = CuraApplication.getInstance().getContainerRegistry() self._machine_manager = CuraApplication.getInstance().getMachineManager() self._extruder_manager = CuraApplication.getInstance().getExtruderManager() - self._quality_manager = CuraApplication.getInstance()._quality_manager + self._quality_manager = CuraApplication.getInstance().getQualityManager() self._machine_manager.globalContainerChanged.connect(self._update) self._quality_manager.qualitiesUpdated.connect(self._update) @@ -35,7 +35,7 @@ class QualityManagementModel(ListModel): self._update() def _update(self): - global_stack = self._machine_manager._global_container_stack + global_stack = self._machine_manager.activeMachine quality_group_dict = self._quality_manager.getQualityGroups(global_stack) quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 30b8634294..9e38184ce7 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -33,11 +33,13 @@ class QualityProfilesDropDownMenuModel(ListModel): self.addRoleName(self.QualityGroupRole, "quality_group") self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") - # connect signals - Application.getInstance().globalContainerStackChanged.connect(self._update) - Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update) + self._application = Application.getInstance() + self._machine_manager = self._application.getMachineManager() + self._quality_manager = Application.getInstance().getQualityManager() - self._quality_manager = Application.getInstance()._quality_manager + # connect signals + self._application.globalContainerStackChanged.connect(self._update) + self._machine_manager.activeQualityGroupChanged.connect(self._update) self._quality_manager.qualitiesUpdated.connect(self._update) self._layer_height_unit = "" # This is cached @@ -47,15 +49,14 @@ class QualityProfilesDropDownMenuModel(ListModel): def _update(self): Logger.log("d", "Updating quality profile model ...") - machine_manager = Application.getInstance().getMachineManager() - global_stack = machine_manager._global_container_stack + global_stack = self._machine_manager.activeMachine if global_stack is None: self.setItems([]) Logger.log("d", "No active GlobalStack, set quality profile model as empty.") return # Check for material compatibility - if not machine_manager.activeMaterialsCompatible(): + if not self._machine_manager.activeMaterialsCompatible(): self.setItems([]) return @@ -82,7 +83,7 @@ class QualityProfilesDropDownMenuModel(ListModel): self.setItems(item_list) def _fetchLayerHeight(self, quality_group: "QualityGroup"): - global_stack = Application.getInstance().getMachineManager()._global_container_stack + global_stack = self._machine_manager.activeMachine if not self._layer_height_unit: unit = global_stack.definition.getProperty("layer_height", "unit") if not unit: diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index a62654ad2c..9e18261d32 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -33,7 +33,7 @@ class QualitySettingsModel(ListModel): self._container_registry = ContainerRegistry.getInstance() self._application = Application.getInstance() - self._quality_manager = self._application._quality_manager + self._quality_manager = self._application.getQualityManager() self._extruder_position = "" self._selected_quality_item = None # The selected quality in the quality management page @@ -73,7 +73,7 @@ class QualitySettingsModel(ListModel): items = [] - global_container_stack = Application.getInstance().getGlobalContainerStack() + global_container_stack = self._application.getGlobalContainerStack() definition_container = global_container_stack.definition quality_group = self._selected_quality_item["quality_group"] From b74e2553e79453caef751dcaa80827033b662b61 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:47:52 +0100 Subject: [PATCH 205/266] Use more descriptive variable names --- cura/Machines/Models/QualityManagementModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index a3c321815a..e089f92329 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -40,7 +40,8 @@ class QualityManagementModel(ListModel): quality_group_dict = self._quality_manager.getQualityGroups(global_stack) quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack) - available_quality_types = set(qt for qt, qg in quality_group_dict.items() if qg.is_available) + available_quality_types = set(quality_type for quality_type, quality_group in quality_group_dict.items() + if quality_group.is_available) if not available_quality_types and not quality_changes_group_dict: # Nothing to show self.setItems([]) From e87077802f941f0435b3730901fbbc7b75fa7e7e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 15:55:44 +0100 Subject: [PATCH 206/266] Change to layer_height and layer_height_unit --- .../Models/QualityProfilesDropDownMenuModel.py | 10 +++++----- resources/qml/Menus/ProfileMenu.qml | 2 +- resources/qml/SidebarSimple.qml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 9e38184ce7..8fd6f2afb7 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -17,7 +17,7 @@ class QualityProfilesDropDownMenuModel(ListModel): NameRole = Qt.UserRole + 1 QualityTypeRole = Qt.UserRole + 2 LayerHeightRole = Qt.UserRole + 3 - LayerHeightWithoutUnitRole = Qt.UserRole + 4 + LayerHeightUnitRole = Qt.UserRole + 4 AvailableRole = Qt.UserRole + 5 QualityGroupRole = Qt.UserRole + 6 QualityChangesGroupRole = Qt.UserRole + 7 @@ -28,7 +28,7 @@ class QualityProfilesDropDownMenuModel(ListModel): self.addRoleName(self.NameRole, "name") self.addRoleName(self.QualityTypeRole, "quality_type") self.addRoleName(self.LayerHeightRole, "layer_height") - self.addRoleName(self.LayerHeightWithoutUnitRole, "layer_height_without_unit") + self.addRoleName(self.LayerHeightUnitRole, "layer_height_unit") self.addRoleName(self.AvailableRole, "available") self.addRoleName(self.QualityGroupRole, "quality_group") self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group") @@ -70,15 +70,15 @@ class QualityProfilesDropDownMenuModel(ListModel): item = {"name": quality_group.name, "quality_type": quality_group.quality_type, - "layer_height": layer_height + self._layer_height_unit, - "layer_height_without_unit": layer_height, + "layer_height": layer_height, + "layer_height_unit": self._layer_height_unit, "available": quality_group.is_available, "quality_group": quality_group} item_list.append(item) # Sort items based on layer_height - item_list = sorted(item_list, key = lambda x: float(x["layer_height_without_unit"])) + item_list = sorted(item_list, key = lambda x: float(x["layer_height"])) self.setItems(item_list) diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 7a78b7a911..19461f6005 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -17,7 +17,7 @@ Menu MenuItem { - text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name + text: (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name checkable: true checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name exclusiveGroup: group diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index fa8f253452..1991a9fa57 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -200,7 +200,7 @@ Item var result = "" if(Cura.MachineManager.activeMachine != null) { - result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height_without_unit + result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height if(result == undefined) { From afae550b5a48e16e3efeebb8fee7cd4e0ccc02db Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 16:00:46 +0100 Subject: [PATCH 207/266] Store layer_height as float --- cura/Machines/Models/QualityProfilesDropDownMenuModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 8fd6f2afb7..d3135b31c6 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -78,7 +78,7 @@ class QualityProfilesDropDownMenuModel(ListModel): item_list.append(item) # Sort items based on layer_height - item_list = sorted(item_list, key = lambda x: float(x["layer_height"])) + item_list = sorted(item_list, key = lambda x: x["layer_height"]) self.setItems(item_list) @@ -97,10 +97,10 @@ class QualityProfilesDropDownMenuModel(ListModel): layer_height = default_layer_height if container.hasProperty("layer_height", "value"): - layer_height = str(container.getProperty("layer_height", "value")) + layer_height = container.getProperty("layer_height", "value") else: # Look for layer_height in the GlobalStack from material -> definition container = global_stack.definition if container.hasProperty("layer_height", "value"): layer_height = container.getProperty("layer_height", "value") - return str(layer_height) + return float(layer_height) From 71e84784191abe2d0b3cf51cb0017a2f498ef695 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 16:26:12 +0100 Subject: [PATCH 208/266] Rename to selected_position --- cura/Machines/Models/QualitySettingsModel.py | 33 ++++++++++---------- resources/qml/Preferences/ProfileTab.qml | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 9e18261d32..1221b1b14b 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -35,7 +35,8 @@ class QualitySettingsModel(ListModel): self._application = Application.getInstance() self._quality_manager = self._application.getQualityManager() - self._extruder_position = "" + self._selected_position = "" # empty string means GlobalStack + # strings such as "0", "1", etc. mean extruder positions self._selected_quality_item = None # The selected quality in the quality management page self._i18n_catalog = None @@ -43,18 +44,18 @@ class QualitySettingsModel(ListModel): self._update() - extruderPositionChanged = pyqtSignal() + selectedPositionChanged = pyqtSignal() selectedQualityItemChanged = pyqtSignal() - def setExtruderPosition(self, extruder_position): - if extruder_position != self._extruder_position: - self._extruder_position = extruder_position - self.extruderPositionChanged.emit() + def setSelectedPosition(self, selected_position): + if selected_position != self._selected_position: + self._selected_position = selected_position + self.selectedPositionChanged.emit() self._update() - @pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged) - def extruderPosition(self): - return self._extruder_position + @pyqtProperty(str, fset = setSelectedPosition, notify = selectedPositionChanged) + def selectedPosition(self): + return self._selected_position def setSelectedQualityItem(self, selected_quality_item): if selected_quality_item != self._selected_quality_item: @@ -79,18 +80,18 @@ class QualitySettingsModel(ListModel): quality_group = self._selected_quality_item["quality_group"] quality_changes_group = self._selected_quality_item["quality_changes_group"] - if self._extruder_position == "": + if self._selected_position == "": quality_node = quality_group.node_for_global else: - quality_node = quality_group.nodes_for_extruders.get(self._extruder_position) + quality_node = quality_group.nodes_for_extruders.get(self._selected_position) settings_keys = quality_group.getAllKeys() quality_containers = [quality_node.getContainer()] if quality_changes_group is not None: - if self._extruder_position == "": + if self._selected_position == "": quality_changes_node = quality_changes_group.node_for_global else: - quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._extruder_position) + quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._selected_position) if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime try: quality_containers.insert(0, quality_changes_node.getContainer()) @@ -117,7 +118,7 @@ class QualitySettingsModel(ListModel): profile_value = new_value # Global tab should use resolve (if there is one) - if self._extruder_position == "": + if self._selected_position == "": resolve_value = global_container_stack.getProperty(definition.key, "resolve") if resolve_value is not None and definition.key in settings_keys: profile_value = resolve_value @@ -125,10 +126,10 @@ class QualitySettingsModel(ListModel): if profile_value is not None: break - if not self._extruder_position: + if not self._selected_position: user_value = global_container_stack.userChanges.getProperty(definition.key, "value") else: - extruder_stack = global_container_stack.extruders[self._extruder_position] + extruder_stack = global_container_stack.extruders[self._selected_position] user_value = extruder_stack.userChanges.getProperty(definition.key, "value") if profile_value is None and user_value is None: diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 82671f306f..dcabf012b7 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -85,7 +85,7 @@ Tab model: Cura.QualitySettingsModel { id: qualitySettings - extruderPosition: base.extruderPosition + selectedPosition: base.extruderPosition selectedQualityItem: base.qualityItem } From 59f31c9fe06a80d9b637fd0ee4257fb85f8613bc Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 16:29:56 +0100 Subject: [PATCH 209/266] Add doc for quality settings model grouping --- cura/Machines/Models/QualitySettingsModel.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 1221b1b14b..b1f30e84ee 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -100,6 +100,9 @@ class QualitySettingsModel(ListModel): return settings_keys.update(quality_changes_group.getAllKeys()) + # We iterate over all definitions instead of settings in a quality/qualtiy_changes group is because in the GUI, + # the settings are grouped together by categories, and we had to go over all the definitions to figure out + # which setting belongs in which category. current_category = "" for definition in definition_container.findDefinitions(): if definition.type == "category": From 31d1a3b5dbec39ea93cf78e0117dddfcce944d9b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 16:31:00 +0100 Subject: [PATCH 210/266] Code style fix --- cura/Machines/MaterialGroup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py index 9111cc3a80..009778943a 100644 --- a/cura/Machines/MaterialGroup.py +++ b/cura/Machines/MaterialGroup.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. + # # A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile. # The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For From 97059daf6ab0e7e1d209efaf770424375ef49153 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Mar 2018 16:37:01 +0100 Subject: [PATCH 211/266] Separate quality manager related classes into separate files --- cura/Machines/QualityChangesGroup.py | 53 +++++++++++ cura/Machines/QualityGroup.py | 51 +++++++++++ cura/Machines/QualityManager.py | 129 +-------------------------- cura/Machines/QualityNode.py | 35 ++++++++ 4 files changed, 143 insertions(+), 125 deletions(-) create mode 100644 cura/Machines/QualityChangesGroup.py create mode 100644 cura/Machines/QualityGroup.py create mode 100644 cura/Machines/QualityNode.py diff --git a/cura/Machines/QualityChangesGroup.py b/cura/Machines/QualityChangesGroup.py new file mode 100644 index 0000000000..f8de3d2011 --- /dev/null +++ b/cura/Machines/QualityChangesGroup.py @@ -0,0 +1,53 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Application import Application + +from .QualityGroup import QualityGroup + + +class QualityChangesGroup(QualityGroup): + + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(name, quality_type, parent) + self._container_registry = Application.getInstance().getContainerRegistry() + + def addNode(self, node: "QualityNode"): + # TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the + # extruder definition ID it belongs to. But, in fact, we only need to know the following things: + # 1. which machine a custom profile is suitable for, + # 2. if this profile is for the GlobalStack, + # 3. if this profile is for an ExtruderStack and which one (the position). + # + # So, it is preferred to have a field like this: + # extruder_position = 1 + # instead of this: + # extruder = custom_extruder_1 + # + # An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition + # to figure out its position. + # + extruder_definition_id = node.metadata.get("extruder") + if extruder_definition_id: + metadata_list = self._container_registry.findDefinitionContainersMetadata(id = extruder_definition_id) + if not metadata_list: + raise RuntimeError("%s cannot get metadata for extruder definition [%s]" % + (self, extruder_definition_id)) + extruder_definition_metadata = metadata_list[0] + extruder_position = str(extruder_definition_metadata["position"]) + + if extruder_position in self.nodes_for_extruders: + raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" % + (self, extruder_position, self.node_for_global, node)) + + self.nodes_for_extruders[extruder_position] = node + + else: + # This is a quality_changes for the GlobalStack + if self.node_for_global is not None: + raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" % + (self, self.node_for_global, node)) + self.node_for_global = node + + def __str__(self) -> str: + return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available) diff --git a/cura/Machines/QualityGroup.py b/cura/Machines/QualityGroup.py new file mode 100644 index 0000000000..6067f04038 --- /dev/null +++ b/cura/Machines/QualityGroup.py @@ -0,0 +1,51 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional, List + +from PyQt5.QtCore import QObject, pyqtSlot + + +# +# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used. +# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type +# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3 +# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look +# as below: +# GlobalStack ExtruderStack 1 ExtruderStack 2 +# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal +# +# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to +# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead +# of looking them up again. +# +class QualityGroup(QObject): + + def __init__(self, name: str, quality_type: str, parent = None): + super().__init__(parent) + self.name = name + self.node_for_global = None # type: Optional["QualityGroup"] + self.nodes_for_extruders = dict() # position str -> QualityGroup + self.quality_type = quality_type + self.is_available = False + + @pyqtSlot(result = str) + def getName(self) -> str: + return self.name + + def getAllKeys(self) -> set: + result = set() + for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): + if node is None: + continue + for key in node.getContainer().getAllKeys(): + result.add(key) + return result + + def getAllNodes(self) -> List["QualityGroup"]: + result = [] + if self.node_for_global is not None: + result.append(self.node_for_global) + for extruder_node in self.nodes_for_extruders.values(): + result.append(extruder_node) + return result diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 90ba7d8da3..e587816dff 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,16 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional, List - -from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QObject, QTimer, pyqtSignal from UM.Application import Application from UM.Logger import Logger from UM.Util import parseBool -from cura.Machines.ContainerNode import ContainerNode - +from .QualityGroup import QualityGroup +from .QualityNode import QualityNode # # Quality lookup tree structure: @@ -27,125 +25,6 @@ from cura.Machines.ContainerNode import ContainerNode # + # -# -# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used. -# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type -# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3 -# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look -# as below: -# GlobalStack ExtruderStack 1 ExtruderStack 2 -# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal -# -# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to -# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead -# of looking them up again. -# -class QualityGroup(QObject): - - def __init__(self, name: str, quality_type: str, parent = None): - super().__init__(parent) - self.name = name - self.node_for_global = None # type: Optional["QualityGroup"] - self.nodes_for_extruders = dict() # position str -> QualityGroup - self.quality_type = quality_type - self.is_available = False - - @pyqtSlot(result = str) - def getName(self) -> str: - return self.name - - def getAllKeys(self) -> set: - result = set() - for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): - if node is None: - continue - for key in node.getContainer().getAllKeys(): - result.add(key) - return result - - def getAllNodes(self) -> List["QualityGroup"]: - result = [] - if self.node_for_global is not None: - result.append(self.node_for_global) - for extruder_node in self.nodes_for_extruders.values(): - result.append(extruder_node) - return result - - -class QualityChangesGroup(QualityGroup): - - def __init__(self, name: str, quality_type: str, parent = None): - super().__init__(name, quality_type, parent) - - def addNode(self, node: "QualityNode"): - # TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the - # extruder definition ID it belongs to. But, in fact, we only need to know the following things: - # 1. which machine a custom profile is suitable for, - # 2. if this profile is for the GlobalStack, - # 3. if this profile is for an ExtruderStack and which one (the position). - # - # So, it is preferred to have a field like this: - # extruder_position = 1 - # instead of this: - # extruder = custom_extruder_1 - # - # An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition - # to figure out its position. - # - extruder_definition_id = node.metadata.get("extruder") - if extruder_definition_id: - container_registry = Application.getInstance().getContainerRegistry() - metadata_list = container_registry.findDefinitionContainersMetadata(id = extruder_definition_id) - if not metadata_list: - raise RuntimeError("%s cannot get metadata for extruder definition [%s]" % - (self, extruder_definition_id)) - extruder_definition_metadata = metadata_list[0] - extruder_position = str(extruder_definition_metadata["position"]) - - if extruder_position in self.nodes_for_extruders: - raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" % - (self, extruder_position, self.node_for_global, node)) - - self.nodes_for_extruders[extruder_position] = node - - else: - # This is a quality_changes for the GlobalStack - if self.node_for_global is not None: - raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" % - (self, self.node_for_global, node)) - self.node_for_global = node - - def __str__(self) -> str: - return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available) - - -# -# QualityNode is used for BOTH quality and quality_changes containers. -# -class QualityNode(ContainerNode): - - def __init__(self, metadata: Optional[dict] = None): - super().__init__(metadata = metadata) - self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer - - def addQualityMetadata(self, quality_type: str, metadata: dict): - if quality_type not in self.quality_type_map: - self.quality_type_map[quality_type] = QualityNode(metadata) - - def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]: - return self.quality_type_map.get(quality_type) - - def addQualityChangesMetadata(self, quality_type: str, metadata: dict): - if quality_type not in self.quality_type_map: - self.quality_type_map[quality_type] = QualityNode() - quality_type_node = self.quality_type_map[quality_type] - - name = metadata["name"] - if name not in quality_type_node.children_map: - quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type) - quality_changes_group = quality_type_node.children_map[name] - quality_changes_group.addNode(QualityNode(metadata)) - # # Similar to MaterialManager, QualityManager maintains a number of maps and trees for material lookup. @@ -164,7 +43,7 @@ class QualityManager(QObject): def __init__(self, container_registry, parent = None): super().__init__(parent) self._application = Application.getInstance() - self._material_manager = self._application._material_manager + self._material_manager = self._application.getMaterialManager() self._container_registry = container_registry self._empty_quality_container = self._application.empty_quality_container diff --git a/cura/Machines/QualityNode.py b/cura/Machines/QualityNode.py new file mode 100644 index 0000000000..a30e219da3 --- /dev/null +++ b/cura/Machines/QualityNode.py @@ -0,0 +1,35 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional + +from .ContainerNode import ContainerNode +from .QualityChangesGroup import QualityChangesGroup + + +# +# QualityNode is used for BOTH quality and quality_changes containers. +# +class QualityNode(ContainerNode): + + def __init__(self, metadata: Optional[dict] = None): + super().__init__(metadata = metadata) + self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer + + def addQualityMetadata(self, quality_type: str, metadata: dict): + if quality_type not in self.quality_type_map: + self.quality_type_map[quality_type] = QualityNode(metadata) + + def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]: + return self.quality_type_map.get(quality_type) + + def addQualityChangesMetadata(self, quality_type: str, metadata: dict): + if quality_type not in self.quality_type_map: + self.quality_type_map[quality_type] = QualityNode() + quality_type_node = self.quality_type_map[quality_type] + + name = metadata["name"] + if name not in quality_type_node.children_map: + quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type) + quality_changes_group = quality_type_node.children_map[name] + quality_changes_group.addNode(QualityNode(metadata)) From 844a597e082e00a98002984ba741493004560a69 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 09:28:25 +0100 Subject: [PATCH 212/266] Fix materials models --- cura/Machines/Models/BrandMaterialsModel.py | 4 ++++ cura/Machines/Models/GenericMaterialsModel.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py index f6430b39da..6628d924f1 100644 --- a/cura/Machines/Models/BrandMaterialsModel.py +++ b/cura/Machines/Models/BrandMaterialsModel.py @@ -73,6 +73,10 @@ class BrandMaterialsModel(ListModel): if global_stack is None: self.setItems([]) return + extruder_position = str(self._extruder_position) + if extruder_position not in global_stack.extruders: + self.setItems([]) + return extruder_stack = global_stack.extruders[str(self._extruder_position)] available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py index f5b18adde9..d20fc05b6e 100644 --- a/cura/Machines/Models/GenericMaterialsModel.py +++ b/cura/Machines/Models/GenericMaterialsModel.py @@ -25,7 +25,11 @@ class GenericMaterialsModel(BaseMaterialsModel): if global_stack is None: self.setItems([]) return - extruder_stack = global_stack.extruders[str(self._extruder_position)] + extruder_position = str(self._extruder_position) + if extruder_position not in global_stack.extruders: + self.setItems([]) + return + extruder_stack = global_stack.extruders[extruder_position] available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack) From 2135e30aadffd3832eea43dc16245490c331f436 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:10:06 +0100 Subject: [PATCH 213/266] Simplify for loop in _calculateInformation() --- cura/PrintInformation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 279e7e0c03..50d80e11bb 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -212,14 +212,13 @@ class PrintInformation(QObject): material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings")) extruder_stacks = global_stack.extruders - for extruder_key in global_stack.extruders.keys(): - index = int(extruder_key) + for position, extruder_stack in extruder_stacks.keys(): + index = int(position) if index >= len(self._material_amounts): # Right now the _material_amounts is a list, where the index is the extruder number continue amount = self._material_amounts[index] ## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some # list comprehension filtering to solve this for us. - extruder_stack = extruder_stacks[str(index)] density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0) material = extruder_stack.findContainer({"type": "material"}) From a6f22fd9cc058ebf4f7c99e715d2a182ddba2e0a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:10:59 +0100 Subject: [PATCH 214/266] Remove unnecessary comments --- cura/PrintInformation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index 50d80e11bb..fe30db08b3 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -214,7 +214,7 @@ class PrintInformation(QObject): extruder_stacks = global_stack.extruders for position, extruder_stack in extruder_stacks.keys(): index = int(position) - if index >= len(self._material_amounts): # Right now the _material_amounts is a list, where the index is the extruder number + if index >= len(self._material_amounts): continue amount = self._material_amounts[index] ## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some From d372fc75e723f364d8639d51a9b22afc81e47def Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:16:51 +0100 Subject: [PATCH 215/266] Fix type hinting for getFallbackMaterialIdByMaterialType() --- cura/Machines/MaterialManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 2dd39d1fe1..faaabb01e5 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -329,7 +329,7 @@ class MaterialManager(QObject): # This function returns the generic root material ID for the given material type, where material types are "PLA", # "ABS", etc. # - def getFallbackMaterialIdByMaterialType(self, material_type: str) -> str: + def getFallbackMaterialIdByMaterialType(self, material_type: str) -> Optional[str]: # For safety if material_type not in self._fallback_materials_map: Logger.log("w", "The material type [%s] does not have a fallback material" % material_type) From f7377e6321eea9970f47cb42c090b70c2d6c54f9 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:20:03 +0100 Subject: [PATCH 216/266] Fix extruder_stacks.items() --- cura/PrintInformation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index fe30db08b3..b52b61fcac 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -212,7 +212,7 @@ class PrintInformation(QObject): material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings")) extruder_stacks = global_stack.extruders - for position, extruder_stack in extruder_stacks.keys(): + for position, extruder_stack in extruder_stacks.items(): index = int(position) if index >= len(self._material_amounts): continue From c6128ef5ba48f6189d7054c56c9e8995e0c01952 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:22:22 +0100 Subject: [PATCH 217/266] Move setMaterialName() into MaterialManager --- cura/CuraApplication.py | 1 + cura/Machines/MaterialManager.py | 19 ++++++++++++++++++- cura/Settings/ContainerManager.py | 11 ----------- resources/qml/Preferences/MaterialView.qml | 4 +++- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index de5d46ba96..2ca321e4cc 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -859,6 +859,7 @@ class CuraApplication(QtApplication): def getVariantManager(self, *args): return self._variant_manager + @pyqtSlot(result = QObject) def getMaterialManager(self, *args): return self._material_manager diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index faaabb01e5..a318e67a0f 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -4,7 +4,7 @@ from collections import defaultdict, OrderedDict from typing import Optional -from PyQt5.Qt import QTimer, QObject, pyqtSignal +from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot from UM.Logger import Logger from UM.Settings import ContainerRegistry @@ -339,3 +339,20 @@ class MaterialManager(QObject): return self.getRootMaterialIDWithoutDiameter(fallback_material["id"]) else: return None + + # + # Methods for GUI + # + + # + # Sets the new name for the given material. + # + @pyqtSlot("QVariant", str) + def setMaterialName(self, material_node: "MaterialNode", name: str): + root_material_id = material_node.metadata["base_file"] + if self._container_registry.isReadOnly(root_material_id): + Logger.log("w", "Cannot set name of read-only container %s.", root_material_id) + return + + material_group = self.getMaterialGroup(root_material_id) + material_group.root_material_node.getContainer().setName(name) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 96fff61b0b..c0451b4b5e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -160,17 +160,6 @@ class ContainerManager(QObject): return container.getProperty(setting_key, property_name) - ## Set the name of the specified material. - @pyqtSlot("QVariant", str) - def setMaterialName(self, material_node, new_name): - root_material_id = material_node.metadata["base_file"] - if self._container_registry.isReadOnly(root_material_id): - Logger.log("w", "Cannot set name of read-only container %s.", root_material_id) - return - - material_group = self._material_manager.getMaterialGroup(root_material_id) - material_group.root_material_node.getContainer().setName(new_name) - @pyqtSlot(str, result = str) def makeUniqueName(self, original_name): return self._container_registry.uniqueName(original_name) diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 021fcc02e1..7e0efd56de 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -12,6 +12,8 @@ TabView { id: base + property QtObject materialManager: CuraApplication.getMaterialManager() + property QtObject properties property var currentMaterialNode: null @@ -497,7 +499,7 @@ TabView } // update the values - Cura.ContainerManager.setMaterialName(base.currentMaterialNode, new_name) + base.materialManager.setMaterialName(base.currentMaterialNode, new_name) materialProperties.name = new_name } From 29631fa8eb29a19a82f2bcc91af6ae4e5d7490ae Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:25:16 +0100 Subject: [PATCH 218/266] Fix QualityManager doc --- cura/Machines/QualityManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index e587816dff..00393d1e8f 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -27,7 +27,7 @@ from .QualityNode import QualityNode # -# Similar to MaterialManager, QualityManager maintains a number of maps and trees for material lookup. +# Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup. # The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in # QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI. # From 27f45742237e3d6099c4daedfcd7f786408dda25 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:31:57 +0100 Subject: [PATCH 219/266] Remove some superfluous comments in QualityManager --- cura/Machines/QualityManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 00393d1e8f..fe7b52d50b 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -184,7 +184,6 @@ class QualityManager(QObject): # Returns a dict of "custom profile name" -> QualityChangesGroup def getQualityChangesGroups(self, machine: "GlobalStack") -> dict: - # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id) @@ -207,8 +206,8 @@ class QualityManager(QObject): return quality_changes_group_dict def getQualityGroups(self, machine: "GlobalStack") -> dict: - # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) + # This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False)) From e340f8e53460cebb80aa120f0b2aef81eff84521 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:34:42 +0100 Subject: [PATCH 220/266] Add documentation for getQualityGroups() --- cura/Machines/QualityManager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index fe7b52d50b..924521a076 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -205,6 +205,12 @@ class QualityManager(QObject): return quality_changes_group_dict + # + # Gets all quality groups for the given machine. Both available and none available ones will be included. + # It returns a dictionary with "quality_type"s as keys and "QualityGroup"s as values. + # Whether a QualityGroup is available can be unknown via the field QualityGroup.is_available. + # For more details, see QualityGroup. + # def getQualityGroups(self, machine: "GlobalStack") -> dict: machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) From fc36df2bea6b700aebe4775126e0889252112c41 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:37:23 +0100 Subject: [PATCH 221/266] Remove unnecessary comments in getQualityGroupsForMachineDefinition() --- cura/Machines/QualityManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 924521a076..e7c4157868 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -310,7 +310,6 @@ class QualityManager(QObject): return quality_group_dict def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> dict: - # Get machine definition ID for quality search machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) # To find the quality container for the GlobalStack, check in the following fall-back manner: From 0944653412886111007f1c01bb8d7046bfc87fdd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:41:19 +0100 Subject: [PATCH 222/266] Change VariantType to an Enum --- cura/Machines/VariantManager.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index 834b47dd0f..f7d80100a8 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from enum import Enum from collections import OrderedDict from typing import Optional @@ -11,7 +12,7 @@ from cura.Machines.ContainerNode import ContainerNode from cura.Settings.GlobalStack import GlobalStack -class VariantType: +class VariantType(Enum): BUILD_PLATE = "buildplate" NOZZLE = "nozzle" @@ -64,6 +65,7 @@ class VariantManager: self._machine_to_variant_dict_map[variant_definition][variant_type] = dict() variant_type = variant_metadata["hardware_type"] + variant_type = VariantType(variant_type) variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type] if variant_name in variant_dict: # ERROR: duplicated variant name. @@ -77,10 +79,10 @@ class VariantManager: # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present. # def getVariantNode(self, machine_definition_id: str, variant_name: str, - variant_type: Optional[str] = VariantType.NOZZLE) -> Optional["ContainerNode"]: + variant_type: Optional["VariantType"] = VariantType.NOZZLE) -> Optional["ContainerNode"]: return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name) def getVariantNodes(self, machine: "GlobalStack", - variant_type: Optional[str] = VariantType.NOZZLE) -> dict: + variant_type: Optional["VariantType"] = VariantType.NOZZLE) -> dict: machine_definition_id = machine.definition.getId() return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}) From 6cae82a64ebba4999a699952ba5cd5c1af2bde4a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:42:07 +0100 Subject: [PATCH 223/266] Fix comments for createQualityChanges() --- cura/Settings/ContainerManager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c0451b4b5e..22f890c6ac 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -347,8 +347,6 @@ class ContainerManager(QObject): # This will go through the global and extruder stacks and create quality_changes containers from # the user containers in each stack. These then replace the quality_changes containers in the # stack and clear the user settings. - # - # \return \type{bool} True if the operation was successfully, False if not. @pyqtSlot(str) def createQualityChanges(self, base_name): global_stack = Application.getInstance().getGlobalContainerStack() From 8324f4f44e247e96c87225ae028db1334abcb76e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:47:25 +0100 Subject: [PATCH 224/266] Move removeQualityChangesGroup() into QualityManager --- cura/Machines/QualityManager.py | 20 +++++++++++++++++++- cura/Settings/ContainerManager.py | 9 --------- resources/qml/Preferences/ProfilesPage.qml | 6 ++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index e7c4157868..ed64fe92b6 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,7 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, QTimer, pyqtSignal +from typing import TYPE_CHECKING +from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot from UM.Application import Application from UM.Logger import Logger @@ -10,6 +11,10 @@ from UM.Util import parseBool from .QualityGroup import QualityGroup from .QualityNode import QualityNode +if TYPE_CHECKING: + from cura.Settings.GlobalStack import GlobalStack + from .QualityChangesGroup import QualityChangesGroup + # # Quality lookup tree structure: # @@ -332,6 +337,19 @@ class QualityManager(QObject): return quality_group_dict + # + # Methods for GUI + # + + # + # Remove the given quality changes group. + # + @pyqtSlot(QObject) + def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup"): + Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name) + for node in quality_changes_group.getAllNodes(): + self._container_registry.removeContainer(node.metadata["id"]) + # # Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 22f890c6ac..d4f72139b1 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -382,15 +382,6 @@ class ContainerManager(QObject): self._container_registry.addContainer(new_changes) - # - # Remove the given quality changes group - # - @pyqtSlot(QObject) - def removeQualityChangesGroup(self, quality_changes_group): - Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name) - for node in quality_changes_group.getAllNodes(): - self._container_registry.removeContainer(node.metadata["id"]) - # # Rename a set of quality changes containers. Returns the new name. # diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index e5c7e3662a..7beb96a535 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -13,6 +13,8 @@ import Cura 1.0 as Cura Item { id: base + + property QtObject qualityManager: CuraApplication.getQualityManager() property var resetEnabled: false // Keep PreferencesDialog happy property var extrudersModel: Cura.ExtrudersModel {} @@ -239,9 +241,9 @@ Item onYes: { - Cura.ContainerManager.removeQualityChangesGroup(base.currentItem.quality_changes_group); + base.qualityManager.removeQualityChangesGroup(base.currentItem.quality_changes_group); // reset current item to the first if available - qualityListView.currentIndex = -1; // TODO: Reset selection. + qualityListView.currentIndex = -1; // Reset selection. } } From 355b8cbac3189354454ad1aa16b1d687dbf1b0c6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 16:58:50 +0100 Subject: [PATCH 225/266] Move renameQualityChangesGroup() into QualityManager --- cura/Machines/QualityManager.py | 22 ++++++++++++++++++++++ cura/Settings/ContainerManager.py | 21 --------------------- resources/qml/Preferences/ProfilesPage.qml | 2 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index ed64fe92b6..4b0d54671a 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -2,6 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import TYPE_CHECKING + from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot from UM.Application import Application @@ -350,6 +351,27 @@ class QualityManager(QObject): for node in quality_changes_group.getAllNodes(): self._container_registry.removeContainer(node.metadata["id"]) + # + # Rename a set of quality changes containers. Returns the new name. + # + @pyqtSlot(QObject, str, result = str) + def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str: + Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name) + if new_name == quality_changes_group.name: + Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name) + return new_name + + new_name = self._container_registry.uniqueName(new_name) + for node in quality_changes_group.getAllNodes(): + node.getContainer().setName(new_name) + + quality_changes_group.name = new_name + + self._application.getMachineManager().activeQualityChanged.emit() + self._application.getMachineManager().activeQualityGroupChanged.emit() + + return new_name + # # Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index d4f72139b1..1356df3dd1 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -382,27 +382,6 @@ class ContainerManager(QObject): self._container_registry.addContainer(new_changes) - # - # Rename a set of quality changes containers. Returns the new name. - # - @pyqtSlot(QObject, str, result = str) - def renameQualityChangesGroup(self, quality_changes_group, new_name) -> str: - Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name) - self._machine_manager.blurSettings.emit() - - if new_name == quality_changes_group.name: - Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name) - return new_name - - new_name = self._container_registry.uniqueName(new_name) - for node in quality_changes_group.getAllNodes(): - node.getContainer().setName(new_name) - - self._machine_manager.activeQualityChanged.emit() - self._machine_manager.activeQualityGroupChanged.emit() - - return new_name - @pyqtSlot(str, "QVariantMap") def duplicateQualityChanges(self, quality_changes_name, quality_model_item): global_stack = Application.getInstance().getGlobalContainerStack() diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 7beb96a535..07b703dfcd 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -255,7 +255,7 @@ Item object: "" onAccepted: { - var actualNewName = Cura.ContainerManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName); + var actualNewName = base.qualityManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName); base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated } } From ca785c9df30a7b79a7a6b7d7f9a07774b53257c6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 17:08:58 +0100 Subject: [PATCH 226/266] Move duplicateQualityChanges() to QualityManager --- cura/Machines/QualityManager.py | 54 ++++++++++++++++++- cura/Settings/ContainerManager.py | 63 ---------------------- resources/qml/Preferences/ProfilesPage.qml | 2 +- 3 files changed, 54 insertions(+), 65 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 4b0d54671a..794ea19c14 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,13 +1,14 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot from UM.Application import Application from UM.Logger import Logger from UM.Util import parseBool +from UM.Settings.InstanceContainer import InstanceContainer from .QualityGroup import QualityGroup from .QualityNode import QualityNode @@ -372,6 +373,57 @@ class QualityManager(QObject): return new_name + # + # Duplicates the given quality. + # + @pyqtSlot(str, "QVariantMap") + def duplicateQualityChanges(self, quality_changes_name, quality_model_item): + global_stack = self._application.getGlobalContainerStack() + if not global_stack: + Logger.log("i", "No active global stack, cannot duplicate quality changes.") + return + + quality_group = quality_model_item["quality_group"] + quality_changes_group = quality_model_item["quality_changes_group"] + if quality_changes_group is None: + # create global quality changes only + new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name, + global_stack, extruder_id = None) + self._container_registry.addContainer(new_quality_changes) + else: + new_name = self._container_registry.uniqueName(quality_changes_name) + for node in quality_changes_group.getAllNodes(): + container = node.getContainer() + new_id = self._container_registry.uniqueName(container.getId()) + self._container_registry.addContainer(container.duplicate(new_id, new_name)) + + # + # Create a quality changes container with the given setup. + # + def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack", + extruder_id: Optional[str]) -> "InstanceContainer": + base_id = machine.definition.getId() if extruder_id is None else extruder_id + new_id = base_id + "_" + new_name + new_id = new_id.lower().replace(" ", "_") + new_id = self._container_registry.uniqueName(new_id) + + # Create a new quality_changes container for the quality. + quality_changes = InstanceContainer(new_id) + quality_changes.setName(new_name) + quality_changes.addMetaDataEntry("type", "quality_changes") + quality_changes.addMetaDataEntry("quality_type", quality_type) + + # If we are creating a container for an extruder, ensure we add that to the container + if extruder_id is not None: + quality_changes.addMetaDataEntry("extruder", extruder_id) + + # If the machine specifies qualities should be filtered, ensure we match the current criteria. + machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) + quality_changes.setDefinition(machine_definition_id) + + quality_changes.addMetaDataEntry("setting_version", self._application.SettingVersion) + return quality_changes + # # Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 1356df3dd1..c81292c46e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -382,24 +382,6 @@ class ContainerManager(QObject): self._container_registry.addContainer(new_changes) - @pyqtSlot(str, "QVariantMap") - def duplicateQualityChanges(self, quality_changes_name, quality_model_item): - global_stack = Application.getInstance().getGlobalContainerStack() - - quality_group = quality_model_item["quality_group"] - quality_changes_group = quality_model_item["quality_changes_group"] - if quality_changes_group is None: - # create global quality changes only - new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name, - global_stack, extruder_id = None) - self._container_registry.addContainer(new_quality_changes) - else: - new_name = self._container_registry.uniqueName(quality_changes_name) - for node in quality_changes_group.getAllNodes(): - container = node.getContainer() - new_id = self._container_registry.uniqueName(container.getId()) - self._container_registry.addContainer(container.duplicate(new_id, new_name)) - @pyqtSlot("QVariant") def removeMaterial(self, material_node): root_material_id = material_node.metadata["base_file"] @@ -598,51 +580,6 @@ class ContainerManager(QObject): name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) self._container_name_filters[name_filter] = entry - ## Creates a unique ID for a container by prefixing the name with the stack ID. - # - # This method creates a unique ID for a container by prefixing it with a specified stack ID. - # This is done to ensure we have an easily identified ID for quality changes, which have the - # same name across several stacks. - # - # \param stack_id The ID of the stack to prepend. - # \param container_name The name of the container that we are creating a unique ID for. - # - # \return Container name prefixed with stack ID, in lower case with spaces replaced by underscores. - def _createUniqueId(self, stack_id, container_name): - result = stack_id + "_" + container_name - result = result.lower() - result.replace(" ", "_") - return result - - ## Create a quality changes container for a specified quality container. - # - # \param quality_container The quality container to create a changes container for. - # \param new_name The name of the new quality_changes container. - # \param machine_definition The machine definition this quality changes container is specific to. - # \param extruder_id - # - # \return A new quality_changes container with the specified container as base. - def _createQualityChanges(self, quality_type, new_name, machine, extruder_id): - base_id = machine.definition.getId() if extruder_id is None else extruder_id - - # Create a new quality_changes container for the quality. - quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name)) - quality_changes.setName(new_name) - quality_changes.addMetaDataEntry("type", "quality_changes") - quality_changes.addMetaDataEntry("quality_type", quality_type) - - # If we are creating a container for an extruder, ensure we add that to the container - if extruder_id is not None: - quality_changes.addMetaDataEntry("extruder", extruder_id) - - # If the machine specifies qualities should be filtered, ensure we match the current criteria. - machine_definition_id = getMachineDefinitionIDForQualitySearch(machine) - quality_changes.setDefinition(machine_definition_id) - - from cura.CuraApplication import CuraApplication - quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) - return quality_changes - ## Import single profile, file_url does not have to end with curaprofile @pyqtSlot(QUrl, result="QVariantMap") def importProfile(self, file_url): diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 07b703dfcd..aaf9bdac0e 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -224,7 +224,7 @@ Item object: "" onAccepted: { - Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem); + base.qualityManager.duplicateQualityChanges(newName, base.currentItem); } } From 7642afb9feaa4ec212c0f6f66f9d234f20e713a8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 17:16:35 +0100 Subject: [PATCH 227/266] Move duplicateMaterial() to MaterialManager --- cura/Machines/MaterialManager.py | 60 +++++++++++++++++++++ cura/Settings/ContainerManager.py | 55 ------------------- resources/qml/Preferences/MaterialsPage.qml | 4 +- 3 files changed, 63 insertions(+), 56 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index a318e67a0f..95540a9a41 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -2,10 +2,12 @@ # Cura is released under the terms of the LGPLv3 or higher. from collections import defaultdict, OrderedDict +import copy from typing import Optional from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot +from UM.Application import Application from UM.Logger import Logger from UM.Settings import ContainerRegistry @@ -29,6 +31,7 @@ class MaterialManager(QObject): def __init__(self, container_registry, parent = None): super().__init__(parent) + self._application = Application.getInstance() self._container_registry = container_registry # type: ContainerRegistry self._fallback_materials_map = dict() # material_type -> generic material metadata @@ -356,3 +359,60 @@ class MaterialManager(QObject): material_group = self.getMaterialGroup(root_material_id) material_group.root_material_node.getContainer().setName(name) + + # + # Creates a duplicate of a material, which has the same GUID and base_file metadata. + # Returns the root material ID of the duplicated material if successful. + # + @pyqtSlot("QVariant", result = str) + def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None) -> Optional[str]: + root_material_id = material_node.metadata["base_file"] + + material_group = self.getMaterialGroup(root_material_id) + if not material_group: + Logger.log("i", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) + return None + + base_container = material_group.root_material_node.getContainer() + containers_to_copy = [] + for node in material_group.derived_material_node_list: + containers_to_copy.append(node.getContainer()) + + # Ensure all settings are saved. + self._application.saveSettings() + + # Create a new ID & container to hold the data. + new_containers = [] + if new_base_id is None: + new_base_id = self._container_registry.uniqueName(base_container.getId()) + new_base_container = copy.deepcopy(base_container) + new_base_container.getMetaData()["id"] = new_base_id + new_base_container.getMetaData()["base_file"] = new_base_id + if new_metadata is not None: + for key, value in new_metadata.items(): + new_base_container.getMetaData()[key] = value + new_containers.append(new_base_container) + + # Clone all of them. + for container_to_copy in containers_to_copy: + # Create unique IDs for every clone. + new_id = new_base_id + if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": + new_id += "_" + container_to_copy.getMetaDataEntry("definition") + if container_to_copy.getMetaDataEntry("variant_name"): + variant_name = container_to_copy.getMetaDataEntry("variant_name") + new_id += "_" + variant_name.replace(" ", "_") + + new_container = copy.deepcopy(container_to_copy) + new_container.getMetaData()["id"] = new_id + new_container.getMetaData()["base_file"] = new_base_id + if new_metadata is not None: + for key, value in new_metadata.items(): + new_container.getMetaData()[key] = value + + new_containers.append(new_container) + + for container_to_add in new_containers: + container_to_add.setDirty(True) + self._container_registry.addContainer(container_to_add) + return new_base_id diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index c81292c46e..b3bb9a594e 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -395,61 +395,6 @@ class ContainerManager(QObject): self._container_registry.removeContainer(node.metadata["id"]) - ## Create a duplicate of a material, which has the same GUID and base_file metadata - # - # \return \type{str} the id of the newly created container. - @pyqtSlot("QVariant", result = str) - def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None): - root_material_id = material_node.metadata["base_file"] - - material_group = self._material_manager.getMaterialGroup(root_material_id) - if not material_group: - Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) - return - - base_container = material_group.root_material_node.getContainer() - containers_to_copy = [] - for node in material_group.derived_material_node_list: - containers_to_copy.append(node.getContainer()) - - # Ensure all settings are saved. - Application.getInstance().saveSettings() - - # Create a new ID & container to hold the data. - new_containers = [] - if new_base_id is None: - new_base_id = self._container_registry.uniqueName(base_container.getId()) - new_base_container = copy.deepcopy(base_container) - new_base_container.getMetaData()["id"] = new_base_id - new_base_container.getMetaData()["base_file"] = new_base_id - if new_metadata is not None: - for key, value in new_metadata.items(): - new_base_container.getMetaData()[key] = value - new_containers.append(new_base_container) - - # Clone all of them. - for container_to_copy in containers_to_copy: - # Create unique IDs for every clone. - new_id = new_base_id - if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": - new_id += "_" + container_to_copy.getMetaDataEntry("definition") - if container_to_copy.getMetaDataEntry("variant_name"): - variant_name = container_to_copy.getMetaDataEntry("variant_name") - new_id += "_" + variant_name.replace(" ", "_") - - new_container = copy.deepcopy(container_to_copy) - new_container.getMetaData()["id"] = new_id - new_container.getMetaData()["base_file"] = new_base_id - if new_metadata is not None: - for key, value in new_metadata.items(): - new_container.getMetaData()[key] = value - - new_containers.append(new_container) - - for container_to_add in new_containers: - container_to_add.setDirty(True) - ContainerRegistry.getInstance().addContainer(container_to_add) - return new_base_id ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 1177f20334..224bc66f3c 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -13,6 +13,8 @@ import Cura 1.0 as Cura Item { id: base + + property QtObject materialManager: CuraApplication.getMaterialManager() property var resetEnabled: false // Keep PreferencesDialog happy UM.I18nCatalog { id: catalog; name: "cura"; } @@ -89,7 +91,7 @@ Item enabled: base.hasCurrentItem onClicked: { forceActiveFocus(); - base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node); + base.newRootMaterialIdToSwitchTo = base.materialManager.duplicateMaterial(base.currentItem.container_node); base.toActivateNewMaterial = true; } } From 5f0bb3a2837d9b7d3de7706882dcca4e9857c74e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 17:20:26 +0100 Subject: [PATCH 228/266] Move removeMaterial() to MaterialManager --- cura/Machines/MaterialManager.py | 15 +++++++++++++++ cura/Settings/ContainerManager.py | 14 -------------- resources/qml/Preferences/MaterialsPage.qml | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 95540a9a41..3665a9a423 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -360,6 +360,21 @@ class MaterialManager(QObject): material_group = self.getMaterialGroup(root_material_id) material_group.root_material_node.getContainer().setName(name) + # + # Removes the given material. + # + @pyqtSlot("QVariant") + def removeMaterial(self, material_node: "MaterialNode"): + root_material_id = material_node.metadata["base_file"] + material_group = self.getMaterialGroup(root_material_id) + if not material_group: + Logger.log("d", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id) + return + + nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list + for node in nodes_to_remove: + self._container_registry.removeContainer(node.metadata["id"]) + # # Creates a duplicate of a material, which has the same GUID and base_file metadata. # Returns the root material ID of the duplicated material if successful. diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index b3bb9a594e..ce641eb2f0 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -382,20 +382,6 @@ class ContainerManager(QObject): self._container_registry.addContainer(new_changes) - @pyqtSlot("QVariant") - def removeMaterial(self, material_node): - root_material_id = material_node.metadata["base_file"] - material_group = self._material_manager.getMaterialGroup(root_material_id) - if not material_group: - Logger.log("d", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id) - return - - nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list - for node in nodes_to_remove: - self._container_registry.removeContainer(node.metadata["id"]) - - - ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue # # \return \type{str} the id of the newly created container. diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 224bc66f3c..71cf584997 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -183,7 +183,7 @@ Item onYes: { - Cura.ContainerManager.removeMaterial(base.currentItem.container_node); + base.materialManager.removeMaterial(base.currentItem.container_node); } } From cf2252f4f9255ced5f8f5a9c45493013526d35d5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 17:22:19 +0100 Subject: [PATCH 229/266] Simplify for loop in duplicateMaterial() --- cura/Machines/MaterialManager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 3665a9a423..ac2d8ed895 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -389,9 +389,6 @@ class MaterialManager(QObject): return None base_container = material_group.root_material_node.getContainer() - containers_to_copy = [] - for node in material_group.derived_material_node_list: - containers_to_copy.append(node.getContainer()) # Ensure all settings are saved. self._application.saveSettings() @@ -409,7 +406,8 @@ class MaterialManager(QObject): new_containers.append(new_base_container) # Clone all of them. - for container_to_copy in containers_to_copy: + for node in material_group.derived_material_node_list: + container_to_copy = node.getContainer() # Create unique IDs for every clone. new_id = new_base_id if container_to_copy.getMetaDataEntry("definition") != "fdmprinter": From c93643bc2f95b5292a2132a1bfdb8373e1539201 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 2 Mar 2018 17:30:19 +0100 Subject: [PATCH 230/266] Move createMaterial() to MaterialManager --- cura/Machines/MaterialManager.py | 29 +++++++++++++++++++++ cura/Settings/ContainerManager.py | 26 ------------------ resources/qml/Preferences/MaterialsPage.qml | 2 +- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index ac2d8ed895..5998e8b020 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -3,6 +3,7 @@ from collections import defaultdict, OrderedDict import copy +import uuid from typing import Optional from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot @@ -429,3 +430,31 @@ class MaterialManager(QObject): container_to_add.setDirty(True) self._container_registry.addContainer(container_to_add) return new_base_id + + # + # Create a new material by cloning Generic PLA for the current material diameter and generate a new GUID. + # + @pyqtSlot(result = str) + def createMaterial(self) -> str: + from UM.i18n import i18nCatalog + catalog = i18nCatalog("cura") + # Ensure all settings are saved. + self._application.saveSettings() + + global_stack = self._application.getGlobalContainerStack() + approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value"))) + root_material_id = "generic_pla" + root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_diameter) + material_group = self.getMaterialGroup(root_material_id) + + # Create a new ID & container to hold the data. + new_id = self._container_registry.uniqueName("custom_material") + new_metadata = {"name": catalog.i18nc("@label", "Custom Material"), + "brand": catalog.i18nc("@label", "Custom"), + "GUID": str(uuid.uuid4()), + } + + self.duplicateMaterial(material_group.root_material_node, + new_base_id = new_id, + new_metadata = new_metadata) + return new_id diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index ce641eb2f0..19a010fe2a 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -382,32 +382,6 @@ class ContainerManager(QObject): self._container_registry.addContainer(new_changes) - ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue - # - # \return \type{str} the id of the newly created container. - @pyqtSlot(result = str) - def createMaterial(self): - # Ensure all settings are saved. - Application.getInstance().saveSettings() - - global_stack = Application.getInstance().getGlobalContainerStack() - approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value"))) - root_material_id = "generic_pla" - root_material_id = self._material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_diameter) - material_group = self._material_manager.getMaterialGroup(root_material_id) - - # Create a new ID & container to hold the data. - new_id = self._container_registry.uniqueName("custom_material") - new_metadata = {"name": catalog.i18nc("@label", "Custom Material"), - "brand": catalog.i18nc("@label", "Custom"), - "GUID": str(uuid.uuid4()), - } - - self.duplicateMaterial(material_group.root_material_node, - new_base_id = new_id, - new_metadata = new_metadata) - return new_id - ## Get a list of materials that have the same GUID as the reference material # # \param material_id \type{str} the id of the material for which to get the linked materials. diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 71cf584997..c833d8d1f5 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -79,7 +79,7 @@ Item iconName: "list-add" onClicked: { forceActiveFocus(); - base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.createMaterial(); + base.newRootMaterialIdToSwitchTo = base.materialManager.createMaterial(); base.toActivateNewMaterial = true; } } From e3e470cb960db2318a27800cdcad2d9366645873 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 14:48:08 +0100 Subject: [PATCH 231/266] Simplify set update --- cura/Machines/QualityGroup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Machines/QualityGroup.py b/cura/Machines/QualityGroup.py index 6067f04038..6945162401 100644 --- a/cura/Machines/QualityGroup.py +++ b/cura/Machines/QualityGroup.py @@ -38,8 +38,7 @@ class QualityGroup(QObject): for node in [self.node_for_global] + list(self.nodes_for_extruders.values()): if node is None: continue - for key in node.getContainer().getAllKeys(): - result.add(key) + result.update(node.getContainer().getAllKeys()) return result def getAllNodes(self) -> List["QualityGroup"]: From aa49b0131ee7c98b49f50d668546920b8a0cdde7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 14:54:21 +0100 Subject: [PATCH 232/266] Remove outdated doc in QualityManager --- cura/Machines/QualityManager.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 794ea19c14..60ed15a9c3 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -17,21 +17,6 @@ if TYPE_CHECKING: from cura.Settings.GlobalStack import GlobalStack from .QualityChangesGroup import QualityChangesGroup -# -# Quality lookup tree structure: -# -# ------| -# | | -# -# | -# -# | -# -# | -# -# + -# - # # Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup. From 41b74684606a4dfdb3f77f0e419d28a7cccc156e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:03:54 +0100 Subject: [PATCH 233/266] Add comments for quality search priorities --- cura/Machines/QualityManager.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 60ed15a9c3..dc9dba8c4b 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -256,6 +256,17 @@ class QualityManager(QObject): if fallback_root_material_id: root_material_id_list.append(fallback_root_material_id) + # Here we construct a list of nodes we want to look for qualities with the highest priority first. + # The use case is that, when we look for qualities for a machine, we first want to search in the following + # order: + # 1. machine-variant-and-material-specific qualities if exist + # 2. machine-variant-specific qualities if exist + # 3. machine-material-specific qualities if exist + # 4. machine-specific qualities if exist + # 5. generic qualities if exist + # Each points above can be represented as a node in the lookup tree, so here we simply put those nodes into + # the list with priorities as the order. Later, we just need to loop over each node in this list and fetch + # qualities from there. nodes_to_check = [] if variant_name: From 5d5932547c672754bc45e2f151eb752cd4f8fd01 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:07:42 +0100 Subject: [PATCH 234/266] Cleanup imports for ContainerManager --- cura/Settings/ContainerManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 19a010fe2a..b833e1f1e9 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -1,7 +1,6 @@ # Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import copy import os.path import urllib.parse import uuid @@ -29,10 +28,10 @@ from UM.i18n import i18nCatalog from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderStack import ExtruderStack -from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch catalog = i18nCatalog("cura") + ## Manager class that contains common actions to deal with containers in Cura. # # This is primarily intended as a class to be able to perform certain actions From 86e12fc4378d583e144a69b34b569066286f50b6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:21:29 +0100 Subject: [PATCH 235/266] Add getDefaultVariantNode() in VariantManager --- cura/Machines/VariantManager.py | 25 ++++++++++++++++++++++++- cura/Settings/CuraStackBuilder.py | 26 +++++++------------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py index f7d80100a8..6cb0a3d7b2 100644 --- a/cura/Machines/VariantManager.py +++ b/cura/Machines/VariantManager.py @@ -3,14 +3,18 @@ from enum import Enum from collections import OrderedDict -from typing import Optional +from typing import Optional, TYPE_CHECKING from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Util import parseBool from cura.Machines.ContainerNode import ContainerNode from cura.Settings.GlobalStack import GlobalStack +if TYPE_CHECKING: + from UM.Settings.DefinitionContainer import DefinitionContainer + class VariantType(Enum): BUILD_PLATE = "buildplate" @@ -86,3 +90,22 @@ class VariantManager: variant_type: Optional["VariantType"] = VariantType.NOZZLE) -> dict: machine_definition_id = machine.definition.getId() return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}) + + # + # Gets the default variant for the given machine definition. + # + def getDefaultVariantNode(self, machine_definition: "DefinitionContainer", + variant_type: VariantType) -> Optional["ContainerNode"]: + machine_definition_id = machine_definition.getId() + preferred_variant_name = None + if variant_type == VariantType.BUILD_PLATE: + if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)): + preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name") + else: + if parseBool(machine_definition.getMetaDataEntry("has_variants", False)): + preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") + + node = None + if preferred_variant_name: + node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type) + return node diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 4d103d2537..efdfa677fc 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -41,29 +41,17 @@ class CuraStackBuilder: # get variant container for the global stack global_variant_container = application.empty_variant_container - if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)): - global_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name") - if global_variant_name: - variant_node = variant_manager.getVariantNode(definition_id, global_variant_name, - variant_type = VariantType.BUILD_PLATE) - if variant_node is None: - raise RuntimeError("Cannot find buildplate variant with definition [%s] and variant name [%s]" % - (definition_id, global_variant_name)) - global_variant_container = variant_node.getContainer() + global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE) + if global_variant_node: + global_variant_container = global_variant_node.getContainer() # get variant container for extruders extruder_variant_container = application.empty_variant_container - # Only look for the preferred variant if this machine has variants + extruder_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.NOZZLE) extruder_variant_name = None - if parseBool(machine_definition.getMetaDataEntry("has_variants", False)): - extruder_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name") - if extruder_variant_name: - variant_node = variant_manager.getVariantNode(definition_id, extruder_variant_name) - # Sanity check. If you see this error, the related definition files should be fixed. - if variant_node is None: - raise RuntimeError("Cannot find extruder variant with definition [%s] and variant name [%s]" % - (definition_id, extruder_variant_name)) - extruder_variant_container = variant_node.getContainer() + if extruder_variant_node: + extruder_variant_container = extruder_variant_node.getContainer() + extruder_variant_name = extruder_variant_container.getName() generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) # Make sure the new name does not collide with any definition or (quality) profile From 6db26eaca5053c5cabace4000a268fa0113b11a3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:29:49 +0100 Subject: [PATCH 236/266] Add getDefaultMaterial() in MaterialManager --- cura/Machines/MaterialManager.py | 23 +++++++++++++++++++++-- cura/Settings/CuraStackBuilder.py | 15 ++------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 5998e8b020..98e4f67f82 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -4,17 +4,22 @@ from collections import defaultdict, OrderedDict import copy import uuid -from typing import Optional +from typing import Optional, TYPE_CHECKING from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot from UM.Application import Application from UM.Logger import Logger -from UM.Settings import ContainerRegistry +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.SettingFunction import SettingFunction +from UM.Util import parseBool from .MaterialNode import MaterialNode from .MaterialGroup import MaterialGroup +if TYPE_CHECKING: + from cura.Settings.GlobalStack import GlobalStack + # # MaterialManager maintains a number of maps and trees for material lookup. @@ -344,6 +349,20 @@ class MaterialManager(QObject): else: return None + def getDefaultMaterial(self, global_stack: "GlobalStack", extruder_variant_name: str) -> Optional["MaterialNode"]: + node = None + machine_definition = global_stack.definition + if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): + material_diameter = machine_definition.getProperty("material_diameter", "value") + if isinstance(material_diameter, SettingFunction): + material_diameter = material_diameter(global_stack) + approximate_material_diameter = str(round(material_diameter)) + root_material_id = machine_definition.getMetaDataEntry("preferred_material") + root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) + node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name, + material_diameter, root_material_id) + return node + # # Methods for GUI # diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index efdfa677fc..a8234b9de9 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -71,19 +71,8 @@ class CuraStackBuilder: # get material container for extruders material_container = application.empty_material_container - # Only look for the preferred material if this machine has materials - if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): - material_diameter = machine_definition.getProperty("material_diameter", "value") - if isinstance(material_diameter, SettingFunction): - material_diameter = material_diameter(new_global_stack) - approximate_material_diameter = str(round(material_diameter)) - root_material_id = machine_definition.getMetaDataEntry("preferred_material") - root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter) - material_node = material_manager.getMaterialNode(definition_id, extruder_variant_name, material_diameter, root_material_id) - # Sanity check. If you see this error, the related definition files should be fixed. - if not material_node: - raise RuntimeError("Cannot find material with definition [%s], extruder_variant_name [%s], and root_material_id [%s]" % - (definition_id, extruder_variant_name, root_material_id)) + material_node = material_manager.getDefaultMaterial(new_global_stack, extruder_variant_name) + if material_node: material_container = material_node.getContainer() # Create ExtruderStacks From a09bf7faa651bd09a4e0494a06660fba910ec18c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:31:59 +0100 Subject: [PATCH 237/266] Move comments for _fixMaterialDiameterAndNozzleSize() --- cura/Settings/ExtruderManager.py | 35 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index fe1bb6a990..a38e5cbfe1 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -404,6 +404,25 @@ class ExtruderManager(QObject): self.extrudersChanged.emit(global_stack_id) self.setActiveExtruderIndex(0) + # + # This function tries to fix the problem with per-extruder-settable nozzle size and material diameter problems + # in early versions (3.0 - 3.2.1). + # + # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime + # because all other machines which uses "fdmextruder" as the extruder definition will be affected. + # + # The problem is that single extrusion machines have their default material diameter defined in the global + # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder" + # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for + # each machine. This results in wrong values which can be found in the MachineSettings dialog. + # + # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in + # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now + # we also check the value defined in the machine definition. If present, the value defined in the global + # stack's definition changes container will be copied. Otherwise, we will check if the default values in the + # machine definition and the extruder definition are the same, and if not, the default value in the machine + # definition will be copied to the extruder stack's definition changes. + # def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list): keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders @@ -414,22 +433,6 @@ class ExtruderManager(QObject): if extruder_stack.definitionChanges.hasProperty(key, "value"): continue - # - # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime - # because all other machines which uses "fdmextruder" as the extruder definition will be affected. - # - # The problem is that single extrusion machines have their default material diameter defined in the global - # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder" - # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for - # each machine. This results in wrong values which can be found in the MachineSettings dialog. - # - # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in - # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now - # we also check the value defined in the machine definition. If present, the value defined in the global - # stack's definition changes container will be copied. Otherwise, we will check if the default values in the - # machine definition and the extruder definition are the same, and if not, the default value in the machine - # definition will be copied to the extruder stack's definition changes. - # setting_value_in_global_def_changes = global_stack.definitionChanges.getProperty(key, "value") setting_value_in_global_def = global_stack.definition.getProperty(key, "value") setting_value = setting_value_in_global_def From 7216641fad0c034a8db78070e9ec120460265d77 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:44:20 +0100 Subject: [PATCH 238/266] Update doc for _fixMaterialDiameterAndNozzleSize() --- cura/Settings/ExtruderManager.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index a38e5cbfe1..06342b68e5 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -408,20 +408,28 @@ class ExtruderManager(QObject): # This function tries to fix the problem with per-extruder-settable nozzle size and material diameter problems # in early versions (3.0 - 3.2.1). # - # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime - # because all other machines which uses "fdmextruder" as the extruder definition will be affected. + # In earlier versions, "nozzle size" and "material diameter" are only applicable to the complete machine, so all + # extruders share the same values. In this case, "nozzle size" and "material diameter" are saved in the + # GlobalStack's DefinitionChanges container. # - # The problem is that single extrusion machines have their default material diameter defined in the global - # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder" - # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for - # each machine. This results in wrong values which can be found in the MachineSettings dialog. + # Later, we could have different "nozzle size" for each extruder, but "material diameter" could only be set for + # the entire machine. In this case, "nozzle size" should be saved in each ExtruderStack's DefinitionChanges, but + # "material diameter" still remains in the GlobalStack's DefinitionChanges. # - # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in - # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now - # we also check the value defined in the machine definition. If present, the value defined in the global - # stack's definition changes container will be copied. Otherwise, we will check if the default values in the - # machine definition and the extruder definition are the same, and if not, the default value in the machine - # definition will be copied to the extruder stack's definition changes. + # Lateer, both "nozzle size" and "material diameter" are settable per-extruder, and both settings should be saved + # in the ExtruderStack's DefinitionChanges. + # + # There were some bugs in upgrade so the data weren't saved correct as described above. This function tries fix + # this. + # + # One more thing is about material diameter and single-extrusion machines. Most single-extrusion machines don't + # specifically define their extruder definition, so they reuse "fdmextruder", but for those machines, they may + # define "material diameter = 1.75" in their machine definition, but in "fdmextruder", it's still "2.85". This + # causes a problem with incorrect default values. + # + # This is also fixed here in this way: If no "material diameter" is specified, it will look for the default value + # in both the Extruder's definition and the Global's definition. If 2 values don't match, we will use the value + # from the Global definition by setting it in the Extruder's DefinitionChanges container. # def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list): keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders From a2c2282b44dece50f9548a36fc4d747371ffd1a8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:50:33 +0100 Subject: [PATCH 239/266] Use context to evaluate materialDiameter --- cura/Settings/ExtruderStack.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 2995aae795..4400f621c6 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -10,10 +10,9 @@ from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.Settings.ContainerStack import ContainerStack from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext -from UM.Settings.SettingInstance import SettingInstance from . import Exceptions -from .CuraContainerStack import CuraContainerStack +from .CuraContainerStack import CuraContainerStack, _ContainerIndexes from .ExtruderManager import ExtruderManager if TYPE_CHECKING: @@ -57,14 +56,10 @@ class ExtruderStack(CuraContainerStack): # \return The filament diameter for the printer @property def materialDiameter(self) -> float: - containers_to_check = [self.variant, self.definitionChanges, self.definition] + context = PropertyEvaluationContext(self) + context.context["evaluate_from_container_index"] = _ContainerIndexes.Variant - for container in containers_to_check: - if container is not None: - material_diameter = container.getProperty("material_diameter", "value") - if material_diameter is not None: - return material_diameter - return -1 + return self.getProperty("material_diameter", "value", context = context) ## Return the approximate filament diameter that the machine requires. # From 632be11323815be21d6ce1257abddc24ba1aa6ed Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:51:51 +0100 Subject: [PATCH 240/266] Remove "#NEW"s --- cura/Settings/MachineManager.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index fe35673f16..0091de5e24 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -117,7 +117,6 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - # NEW self._material_manager = self._application._material_manager self._material_manager.materialsUpdated.connect(self._onMaterialsUpdated) @@ -126,7 +125,6 @@ class MachineManager(QObject): # be reflected on the GUI. This signal emission makes sure that it happens. self.rootMaterialChanged.emit() - ### NEW activeQualityGroupChanged = pyqtSignal() activeQualityChangesGroupChanged = pyqtSignal() @@ -784,10 +782,6 @@ class MachineManager(QObject): container = extruder.userChanges container.setProperty(setting_name, property_name, property_value) - # - # New - # - # We not fetch it from _current_root_material_id, but later we can get it from somewhere else @pyqtProperty("QVariantList", notify = rootMaterialChanged) def currentExtruderPositions(self): From 51fadc98687085496b718d2a398518fd995509c6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:53:46 +0100 Subject: [PATCH 241/266] Remove unnecessary _onMaterialsUpdated() --- cura/Settings/MachineManager.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0091de5e24..efcfaca4ea 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -118,12 +118,10 @@ class MachineManager(QObject): containers[0].nameChanged.connect(self._onMaterialNameChanged) self._material_manager = self._application._material_manager - self._material_manager.materialsUpdated.connect(self._onMaterialsUpdated) - def _onMaterialsUpdated(self): # When the materials lookup table gets updated, it can mean that a material has its name changed, which should # be reflected on the GUI. This signal emission makes sure that it happens. - self.rootMaterialChanged.emit() + self._material_manager.materialsUpdated.connect(self.rootMaterialChanged) activeQualityGroupChanged = pyqtSignal() activeQualityChangesGroupChanged = pyqtSignal() From 89716acc11d5b53683c347cf45a4bc05a9224d26 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:56:05 +0100 Subject: [PATCH 242/266] Remove redundant code in MachineManager --- cura/Settings/MachineManager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index efcfaca4ea..33a52528fd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -297,12 +297,10 @@ class MachineManager(QObject): if containers: global_stack = containers[0] ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder - Application.getInstance().setGlobalContainerStack(global_stack) self._global_container_stack = global_stack Application.getInstance().setGlobalContainerStack(global_stack) ExtruderManager.getInstance()._globalContainerStackChanged() self._initMachineState(containers[0]) - self.globalContainerChanged.emit() self._onGlobalContainerChanged() self.__emitChangedSignals() From bb04afa2ab3b6c8ab3c442d6fb9e1ca26c42ebb4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:57:28 +0100 Subject: [PATCH 243/266] Remove non-sense comments in MachineManager --- cura/Settings/MachineManager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 33a52528fd..744d9c69c5 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -778,7 +778,6 @@ class MachineManager(QObject): container = extruder.userChanges container.setProperty(setting_name, property_name, property_value) - # We not fetch it from _current_root_material_id, but later we can get it from somewhere else @pyqtProperty("QVariantList", notify = rootMaterialChanged) def currentExtruderPositions(self): return sorted(list(self._current_root_material_id.keys())) From 413e4ca55dc6fe2ddf9802ac136213c370f9795c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 15:59:59 +0100 Subject: [PATCH 244/266] Add doc for _setEmptyQuality() --- cura/Settings/MachineManager.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 744d9c69c5..ded507fc94 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -817,6 +817,10 @@ class MachineManager(QObject): return result + # + # Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers + # for all stacks in the currently active machine. + # def _setEmptyQuality(self): self._current_quality_group = None self._current_quality_changes_group = None From a220b55856dc27fa50d19e8b87e6fa2a0c4efd33 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:01:59 +0100 Subject: [PATCH 245/266] Simplify code in MachineManager --- cura/Settings/MachineManager.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ded507fc94..0e21a7e4bd 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -118,6 +118,7 @@ class MachineManager(QObject): containers[0].nameChanged.connect(self._onMaterialNameChanged) self._material_manager = self._application._material_manager + self._quality_manager = self._application.getQualityManager() # When the materials lookup table gets updated, it can mean that a material has its name changed, which should # be reflected on the GUI. This signal emission makes sure that it happens. @@ -853,11 +854,8 @@ class MachineManager(QObject): self.activeQualityChangesGroupChanged.emit() def _setQualityChangesGroup(self, quality_changes_group): - # TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time. - # Can we do this better, like caching the quality group a quality_changes group depends on? quality_type = quality_changes_group.quality_type - quality_manager = Application.getInstance()._quality_manager - quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack) + quality_group_dict = self._quality_manager.getQualityGroups(self._global_container_stack) quality_group = quality_group_dict[quality_type] quality_changes_container = self._empty_quality_changes_container From 174bc7dbd7588e7bc31801cdd2bfeb61bfc75b63 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:04:30 +0100 Subject: [PATCH 246/266] Remove commented code in MachineManager --- cura/Settings/MachineManager.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0e21a7e4bd..e357d778ca 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -971,13 +971,6 @@ class MachineManager(QObject): self._setMaterial(position, new_material) continue - # # Find a fallback material - # preferred_material_query = self._global_container_stack.getMetaDataEntry("preferred_material") - # preferred_material_key = preferred_material_query.replace("*", "") - # if preferred_material_key in candidate_materials: - # self._setMaterial(position, candidate_materials[preferred_material_key]) - # return - @pyqtSlot("QVariant") def setGlobalVariant(self, container_node): self.blurSettings.emit() From ca88e0df88df888329bb1c54b4b23a25587c8046 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:12:33 +0100 Subject: [PATCH 247/266] Add doc for calllater active machine in project loading --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 6dd20b66e0..cbe882f253 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -1082,6 +1082,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader): CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit() # Actually change the active machine. + # + # This is scheduled for later is because it depends on the Variant/Material/Qualitiy Managers to have the latest + # data, but those managers will only update upon a container/container metadata changed signal. Because this + # function is running on the main thread (Qt thread), although those "changed" signals have been emitted, but + # they won't take effect until this function is done. + # To solve this, we schedule _updateActiveMachine() for later so it will have the latest data. CuraApplication.getInstance().callLater(self._updateActiveMachine, global_stack) # Load all the nodes / meshdata of the workspace From 25676426269ab2b688a42e9dffc249c002cda5c0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:13:35 +0100 Subject: [PATCH 248/266] Remove outdated TODO --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 80e3e3b721..ff9df1a055 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -606,8 +606,6 @@ class XmlMaterialProfile(InstanceContainer): if not variant_node: continue - # TODO: check if build plate variant exists - buildplate_compatibility = machine_compatibility buildplate_recommended = machine_compatibility settings = buildplate.iterfind("./um:setting", self.__namespaces) From d24bc0b41b7a6c9f15e5e76d6db0c60c26c089bb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:23:54 +0100 Subject: [PATCH 249/266] Fix code style in MaterialView.qml --- resources/qml/Preferences/MaterialView.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 7e0efd56de..6cea001450 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -216,7 +216,8 @@ TabView confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter; confirmDiameterChangeDialog.open() - } else { + } + else { Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value); base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString()); base.setMetaDataEntry("properties/diameter", properties.diameter, value); From 575f38e63e55d195214bbddec9290c441b473f28 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:25:09 +0100 Subject: [PATCH 250/266] Fix code style in MaterialView.qml --- resources/qml/Preferences/MaterialView.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 6cea001450..0016f211e7 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -399,13 +399,15 @@ TabView onEditingFinished: materialPropertyProvider.setPropertyValue("value", value) } - UM.ContainerPropertyProvider { + UM.ContainerPropertyProvider + { id: materialPropertyProvider containerId: base.containerId watchedProperties: [ "value" ] key: model.key } - UM.ContainerPropertyProvider { + UM.ContainerPropertyProvider + { id: machinePropertyProvider containerId: Cura.MachineManager.activeDefinitionId watchedProperties: [ "value" ] From 0e5aff84e9b71df180df297169f751e5810c13d5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:26:00 +0100 Subject: [PATCH 251/266] Remove outdated comment in MaterialsPage.qml --- resources/qml/Preferences/MaterialsPage.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index c833d8d1f5..48259e51ca 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -283,7 +283,6 @@ Item } visible: text != "" text: { - // OLD STUFF var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; if (Cura.MachineManager.hasVariants) { From 86b75ae3b6807834c7940c6d7a0a169016d3b816 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:29:31 +0100 Subject: [PATCH 252/266] Remove outdated TODO --- resources/qml/Preferences/MaterialsPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 48259e51ca..cd72ef81b0 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -361,7 +361,7 @@ Item width: Math.floor((parent.width * 0.3)) text: model.material elide: Text.ElideRight - font.italic: { // TODO: make it easier + font.italic: { const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; return model.root_material_id == root_material_id @@ -372,7 +372,7 @@ Item { text: (model.name != model.material) ? model.name : "" elide: Text.ElideRight - font.italic: { // TODO: make it easier + font.italic: { const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; return model.root_material_id == root_material_id; From 730048d2b28aab42b6e05b3799422cc1b959dd46 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:32:29 +0100 Subject: [PATCH 253/266] Simplify code in MaterialsPage.qml --- resources/qml/Preferences/MaterialsPage.qml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index cd72ef81b0..b9b9207d1d 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -344,10 +344,19 @@ Item Row { + id: materialRow spacing: (UM.Theme.getSize("default_margin").width / 2) | 0 anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right + + property bool isItemActivated: + { + const extruder_position = Cura.ExtruderManager.activeExtruderIndex; + const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; + return model.root_material_id == root_material_id; + } + Rectangle { width: Math.floor(parent.height * 0.8) @@ -361,22 +370,14 @@ Item width: Math.floor((parent.width * 0.3)) text: model.material elide: Text.ElideRight - font.italic: { - const extruder_position = Cura.ExtruderManager.activeExtruderIndex; - const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; - return model.root_material_id == root_material_id - } + font.italic: materialRow.isItemActivated color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; } Label { text: (model.name != model.material) ? model.name : "" elide: Text.ElideRight - font.italic: { - const extruder_position = Cura.ExtruderManager.activeExtruderIndex; - const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; - return model.root_material_id == root_material_id; - } + font.italic: materialRow.isItemActivated color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text; } } From 6a14e396105c96035e15235d880ac2ee9dfc982f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Sat, 3 Mar 2018 16:34:31 +0100 Subject: [PATCH 254/266] Remove outdated TODOs in ProfilesPage --- resources/qml/Preferences/ProfilesPage.qml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index aaf9bdac0e..e9bbb4bc66 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -266,7 +266,7 @@ Item id: importDialog title: catalog.i18nc("@title:window", "Import Profile") selectExisting: true - nameFilters: qualitiesModel.getFileNameFilters("profile_reader") // TODO: make this easier + nameFilters: qualitiesModel.getFileNameFilters("profile_reader") folder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { @@ -292,11 +292,10 @@ Item id: exportDialog title: catalog.i18nc("@title:window", "Export Profile") selectExisting: false - nameFilters: qualitiesModel.getFileNameFilters("profile_writer") // TODO: make this easier + nameFilters: qualitiesModel.getFileNameFilters("profile_writer") folder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { - // TODO: make this easier var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group, fileUrl, selectedNameFilter); From 1e467b66c03414d1a1c35651dc06a03759228bc8 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:22:11 +0100 Subject: [PATCH 255/266] Fix protected variable access --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index ff9df1a055..a23d5f590a 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -59,7 +59,7 @@ class XmlMaterialProfile(InstanceContainer): return # Get the MaterialGroup - material_manager = CuraApplication.getInstance()._material_manager + material_manager = CuraApplication.getInstance().getMaterialManager() root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile. material_group = material_manager.getMaterialGroup(root_material_id) From b4deb3e82823d8309f9ff834e48985a49546a0c3 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:23:36 +0100 Subject: [PATCH 256/266] Better logging in quality profile model --- cura/Machines/Models/QualityProfilesDropDownMenuModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index d3135b31c6..081badc604 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -57,6 +57,7 @@ class QualityProfilesDropDownMenuModel(ListModel): # Check for material compatibility if not self._machine_manager.activeMaterialsCompatible(): + Logger.log("d", "No active material compatibility, set quality profile model as empty.") self.setItems([]) return From 2255dc628be27e95a39a2dbf59af5ec3806a754b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:31:04 +0100 Subject: [PATCH 257/266] Remove unnecessary comments --- cura/Machines/Models/QualityProfilesDropDownMenuModel.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index 081badc604..fd919639c3 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -37,7 +37,6 @@ class QualityProfilesDropDownMenuModel(ListModel): self._machine_manager = self._application.getMachineManager() self._quality_manager = Application.getInstance().getQualityManager() - # connect signals self._application.globalContainerStackChanged.connect(self._update) self._machine_manager.activeQualityGroupChanged.connect(self._update) self._quality_manager.qualitiesUpdated.connect(self._update) From f86c2a2f8aec4d152376c1b53730ee2a24edb1fa Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:32:59 +0100 Subject: [PATCH 258/266] Add comments for quality settings model --- cura/Machines/Models/QualitySettingsModel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index b1f30e84ee..be00298c6f 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -87,6 +87,8 @@ class QualitySettingsModel(ListModel): settings_keys = quality_group.getAllKeys() quality_containers = [quality_node.getContainer()] + # Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch + # the settings in that quality_changes_group. if quality_changes_group is not None: if self._selected_position == "": quality_changes_node = quality_changes_group.node_for_global From d79a9f644972987f0e85f7933a9294b9597154ac Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:35:54 +0100 Subject: [PATCH 259/266] Add logging for quality settings model --- cura/Machines/Models/QualitySettingsModel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index be00298c6f..38b7ec28e4 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -4,6 +4,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt from UM.Application import Application +from UM.Logger import Logger from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry @@ -99,6 +100,7 @@ class QualitySettingsModel(ListModel): quality_containers.insert(0, quality_changes_node.getContainer()) except: # FIXME: This is to prevent incomplete update of QualityManager + Logger.logException("d", "Failed to get container for quality changes node %s", quality_changes_node) return settings_keys.update(quality_changes_group.getAllKeys()) From 6781627672465d7214e7287cc00fefbadc130295 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Mon, 5 Mar 2018 10:42:09 +0100 Subject: [PATCH 260/266] Fix: Flat model and reset all rotation did not work CURA-5039 --- plugins/PerObjectSettingsTool/PerObjectItem.qml | 4 ++-- plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml index 89679b57a2..1317c00b19 100644 --- a/plugins/PerObjectSettingsTool/PerObjectItem.qml +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -32,11 +32,11 @@ UM.TooltipArea if(checked) { addedSettingsModel.setVisible(model.key, checked); - UM.ActiveTool.triggerAction("subscribeForSettingValidation", model.key) + UM.ActiveTool.triggerActionWithData("subscribeForSettingValidation", model.key) } else { - UM.ActiveTool.triggerAction("unsubscribeForSettingValidation", model.key) + UM.ActiveTool.triggerActionWithData("unsubscribeForSettingValidation", model.key) addedSettingsModel.setVisible(model.key, checked); } UM.ActiveTool.forceUpdate(); diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 4b5d2a5708..e72e1224df 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -242,7 +242,7 @@ Item { onClicked: { addedSettingsModel.setVisible(model.key, false) - UM.ActiveTool.triggerAction("unsubscribeForSettingValidation", model.key) + UM.ActiveTool.triggerActionWithData("unsubscribeForSettingValidation", model.key) } style: ButtonStyle From 6c42b662c85408c844792edeb60d084a21a8e8a5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:53:40 +0100 Subject: [PATCH 261/266] Add doc for apply_to_all in XMLMaterialProfile --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index a23d5f590a..edc782cc9e 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -48,6 +48,12 @@ class XmlMaterialProfile(InstanceContainer): ## Overridden from InstanceContainer # set the meta data for all machine / variant combinations + # + # The "apply_to_all" flag indicates whether this piece of metadata should be applied to all material containers + # or just this specific container. + # For example, when you change the material name, you want to apply it to all its derived containers, but for + # some specific settings, they should only be applied to a machine/variant-specific container. + # def setMetaDataEntry(self, key, value, apply_to_all = True): registry = ContainerRegistry.getInstance() if registry.isReadOnly(self.getId()): From caca5e502172e24c581c57de0af7fd4e9106e4fc Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:57:36 +0100 Subject: [PATCH 262/266] Fix code style in materialspage --- resources/qml/Preferences/MaterialsPage.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index b9b9207d1d..396cf58aa4 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -39,12 +39,14 @@ Item property var hasCurrentItem: materialListView.currentItem != null - property var currentItem: { // is soon to be overwritten + property var currentItem: + { // is soon to be overwritten var current_index = materialListView.currentIndex; return materialsModel.getItem(current_index); } - property var isCurrentItemActivated: { + property var isCurrentItemActivated: + { const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; return base.currentItem.root_material_id == root_material_id; From eb5ce04229c6383dbac84dcf48c308eff69ebf50 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 10:59:10 +0100 Subject: [PATCH 263/266] Fix code style in materialspage --- resources/qml/Preferences/MaterialsPage.qml | 39 ++++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index 396cf58aa4..a5bb2f9883 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -55,7 +55,8 @@ Item Row // Button Row { id: buttonRow - anchors { + anchors + { left: parent.left right: parent.right top: titleLabel.bottom @@ -63,11 +64,13 @@ Item height: childrenRect.height // Activate button - Button { + Button + { text: catalog.i18nc("@action:button", "Activate") iconName: "list-activate" enabled: !isCurrentItemActivated - onClicked: { + onClicked: + { forceActiveFocus() const extruder_position = Cura.ExtruderManager.activeExtruderIndex; @@ -76,10 +79,12 @@ Item } // Create button - Button { + Button + { text: catalog.i18nc("@action:button", "Create") iconName: "list-add" - onClicked: { + onClicked: + { forceActiveFocus(); base.newRootMaterialIdToSwitchTo = base.materialManager.createMaterial(); base.toActivateNewMaterial = true; @@ -87,11 +92,13 @@ Item } // Duplicate button - Button { + Button + { text: catalog.i18nc("@action:button", "Duplicate"); iconName: "list-add" enabled: base.hasCurrentItem - onClicked: { + onClicked: + { forceActiveFocus(); base.newRootMaterialIdToSwitchTo = base.materialManager.duplicateMaterial(base.currentItem.container_node); base.toActivateNewMaterial = true; @@ -99,21 +106,25 @@ Item } // Remove button - Button { + Button + { text: catalog.i18nc("@action:button", "Remove") iconName: "list-remove" enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated - onClicked: { + onClicked: + { forceActiveFocus(); confirmRemoveMaterialDialog.open(); } } // Import button - Button { + Button + { text: catalog.i18nc("@action:button", "Import") iconName: "document-import" - onClicked: { + onClicked: + { forceActiveFocus(); importMaterialDialog.open(); } @@ -121,10 +132,12 @@ Item } // Export button - Button { + Button + { text: catalog.i18nc("@action:button", "Export") iconName: "document-export" - onClicked: { + onClicked: + { forceActiveFocus(); exportMaterialDialog.open(); } From 6d97fd8dc20d25df6fd25d161d56847fe90242bd Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 11:01:52 +0100 Subject: [PATCH 264/266] Revert "WIP: Fix quality profiles for abax_pri3" This reverts commit c338e1b7d69c252ae80d9590700823108a37f320. --- resources/definitions/abax_pri3.def.json | 3 +-- resources/quality/abax_pri3/apri3_fast.inst.cfg | 14 -------------- resources/quality/abax_pri3/apri3_high.inst.cfg | 14 -------------- resources/quality/abax_pri3/apri3_normal.inst.cfg | 14 -------------- .../quality/abax_pri3/apri3_pla_fast.inst.cfg | 5 +++-- .../quality/abax_pri3/apri3_pla_high.inst.cfg | 1 + .../quality/abax_pri3/apri3_pla_normal.inst.cfg | 1 + 7 files changed, 6 insertions(+), 46 deletions(-) delete mode 100644 resources/quality/abax_pri3/apri3_fast.inst.cfg delete mode 100644 resources/quality/abax_pri3/apri3_high.inst.cfg delete mode 100644 resources/quality/abax_pri3/apri3_normal.inst.cfg diff --git a/resources/definitions/abax_pri3.def.json b/resources/definitions/abax_pri3.def.json index f91a501a6f..2fa648096f 100644 --- a/resources/definitions/abax_pri3.def.json +++ b/resources/definitions/abax_pri3.def.json @@ -6,8 +6,7 @@ "visible": true, "author": "ABAX 3d Technologies", "manufacturer": "ABAX 3d Technologies", - "file_formats": "text/x-gcode", - "has_machine_quality": true + "file_formats": "text/x-gcode" }, "overrides": { "machine_start_gcode": { diff --git a/resources/quality/abax_pri3/apri3_fast.inst.cfg b/resources/quality/abax_pri3/apri3_fast.inst.cfg deleted file mode 100644 index 7db569ec72..0000000000 --- a/resources/quality/abax_pri3/apri3_fast.inst.cfg +++ /dev/null @@ -1,14 +0,0 @@ -[general] -version = 2 -name = Fast -definition = abax_pri3 - -[metadata] -setting_version = 4 -type = quality -quality_type = fast -weight = -1 -global_quality = True - -[values] -layer_height = 0.2 diff --git a/resources/quality/abax_pri3/apri3_high.inst.cfg b/resources/quality/abax_pri3/apri3_high.inst.cfg deleted file mode 100644 index 8a95b71a88..0000000000 --- a/resources/quality/abax_pri3/apri3_high.inst.cfg +++ /dev/null @@ -1,14 +0,0 @@ -[general] -version = 2 -name = Extra Fine -definition = abax_pri3 - -[metadata] -setting_version = 4 -type = quality -quality_type = high -weight = 1 -global_quality = True - -[values] -layer_height = 0.1 diff --git a/resources/quality/abax_pri3/apri3_normal.inst.cfg b/resources/quality/abax_pri3/apri3_normal.inst.cfg deleted file mode 100644 index 29b25d889f..0000000000 --- a/resources/quality/abax_pri3/apri3_normal.inst.cfg +++ /dev/null @@ -1,14 +0,0 @@ -[general] -version = 2 -name = Fine -definition = abax_pri3 - -[metadata] -setting_version = 4 -type = quality -quality_type = normal -weight = 0 -global_quality = True - -[values] -layer_height = 0.2 diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index f24f198b2e..7d1c1bf588 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -1,16 +1,17 @@ [general] version = 2 -name = Fast +name = Fine definition = abax_pri3 [metadata] setting_version = 4 type = quality -quality_type = fast +quality_type = normal weight = -1 material = generic_pla [values] +layer_height = 0.2 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 5b4c470842..46a4178dd9 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -11,6 +11,7 @@ weight = 1 material = generic_pla [values] +layer_height = 0.1 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 2df629af38..3f6f36cfe6 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -11,6 +11,7 @@ weight = 0 material = generic_pla [values] +layer_height = 0.2 wall_thickness = 1.05 top_bottom_thickness = 0.8 infill_sparse_density = 20 From c99fca0890fd8c32b8146fce8c378add23faf974 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 11:09:54 +0100 Subject: [PATCH 265/266] Put adhesion_type back to imade3d profiles --- .../quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg | 1 + .../imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg | 1 + .../quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg | 1 + .../imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg | 1 + .../quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg | 1 + .../imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg | 1 + resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg | 1 + .../imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg | 1 + .../quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg | 1 + .../imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg | 1 + .../quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg | 1 + 11 files changed, 11 insertions(+) diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index f300f5d95b..4d0493ae8b 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -12,6 +12,7 @@ material = generic_petg variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 804807184b..9251ae43b4 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -12,6 +12,7 @@ material = generic_petg variant = 0.4 mm 2-fans [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index c39c8a7a98..a10a3bcf0a 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -12,6 +12,7 @@ material = generic_petg variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index 17cc1493e1..b851c2e17c 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -12,6 +12,7 @@ material = generic_petg variant = 0.4 mm 2-fans [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 738eb627fe..bc86119eb8 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 4f44559fbc..c05927fad5 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm 2-fans [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index f9f32237b0..1bec96f05c 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index 82f5a4fa32..609662a149 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm 2-fans [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index 5ee2111c3a..5249f2dc2b 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index 5d34259ccd..1534d3a6fb 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm 2-fans [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index 1826e69513..1166bd70c9 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -12,6 +12,7 @@ material = generic_pla variant = 0.4 mm [values] +adhesion_type = skirt bottom_thickness = 0.6 coasting_enable = True coasting_speed = 95 From 072c85bacfb06cfaa13151809787ba86f040ac33 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 5 Mar 2018 11:16:45 +0100 Subject: [PATCH 266/266] Put authors back for 3rd party variants --- resources/variants/cartesio_0.25.inst.cfg | 1 + resources/variants/cartesio_0.4.inst.cfg | 1 + resources/variants/cartesio_0.8.inst.cfg | 1 + resources/variants/fabtotum_hyb35.inst.cfg | 1 + resources/variants/fabtotum_lite04.inst.cfg | 1 + resources/variants/fabtotum_lite06.inst.cfg | 1 + resources/variants/fabtotum_pro02.inst.cfg | 1 + resources/variants/fabtotum_pro04.inst.cfg | 1 + resources/variants/fabtotum_pro06.inst.cfg | 1 + resources/variants/fabtotum_pro08.inst.cfg | 1 + resources/variants/gmax15plus_025_e3d.inst.cfg | 1 + resources/variants/gmax15plus_04_e3d.inst.cfg | 1 + resources/variants/gmax15plus_05_e3d.inst.cfg | 1 + resources/variants/gmax15plus_05_jhead.inst.cfg | 1 + resources/variants/gmax15plus_06_e3d.inst.cfg | 1 + resources/variants/gmax15plus_08_e3d.inst.cfg | 1 + resources/variants/gmax15plus_10_jhead.inst.cfg | 1 + resources/variants/gmax15plus_dual_025_e3d.inst.cfg | 1 + resources/variants/gmax15plus_dual_04_e3d.inst.cfg | 1 + resources/variants/gmax15plus_dual_05_e3d.inst.cfg | 1 + resources/variants/gmax15plus_dual_05_jhead.inst.cfg | 1 + resources/variants/gmax15plus_dual_06_e3d.inst.cfg | 1 + resources/variants/gmax15plus_dual_08_e3d.inst.cfg | 1 + resources/variants/gmax15plus_dual_10_jhead.inst.cfg | 1 + resources/variants/imade3d_jellybox_0.4.inst.cfg | 1 + resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg | 1 + 26 files changed, 26 insertions(+) diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index 2272aebde5..014069451c 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = cartesio [metadata] +author = Cartesio setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index bd3302da03..7b5dccd980 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = cartesio [metadata] +author = Cartesio setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index eda8248584..70271dbf75 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = cartesio [metadata] +author = Cartesio setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index 6d699f6df8..e036b2e474 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 5d376de4a1..defa6692a8 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index 0181461613..d269092b42 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index c63ed6d982..b705929c35 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index 6fc2d7c4f7..b835312324 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index bf48b91965..140b6618cf 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index 83f13ef8fc..421cd0b662 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = fabtotum [metadata] +author = FABtotum setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index 88730e6722..3c7b2e4949 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index f107d2ab16..e9c0cf1b18 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 72081a4b3d..8575f3c539 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index ca086fca96..14d6ab5e9d 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index bbb5d18df1..5d3f5c63a9 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index 944420e064..af08cd2c7c 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index 832861a98a..df61d9729f 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index b80074479e..07bdfca9b7 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index 3f25835e3a..966fe9f224 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index c7dccfd7c7..85464bd733 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index 0cffafee3b..689c76541a 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index a0dc450ec0..57641a4244 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index 547cee823d..11523ccd67 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index a565c073af..26721d0169 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = gmax15plus_dual [metadata] +author = gcreate setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index cb20dadbf7..5baa8123f2 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = imade3d_jellybox [metadata] +author = IMADE3D setting_version = 4 type = variant hardware_type = nozzle diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index 95b696f432..5d1a01c366 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -4,6 +4,7 @@ version = 2 definition = imade3d_jellybox [metadata] +author = IMADE3D setting_version = 4 type = variant hardware_type = nozzle