VersionUpgrade21to22.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import configparser #To get version numbers from config files.
  4. from typing import Dict, Iterable, List, Optional, Set, Tuple
  5. from UM.VersionUpgrade import VersionUpgrade # Superclass of the plugin.
  6. from . import MachineInstance # To upgrade machine instances.
  7. from . import Preferences #To upgrade preferences.
  8. from . import Profile # To upgrade profiles.
  9. ## Which machines have material-specific profiles in the new version?
  10. #
  11. # These are the 2.1 machine identities with "has_machine_materials": true in
  12. # their definitions in Cura 2.2. So these are the machines for which profiles
  13. # need to split into multiple profiles, one for each material and variant.
  14. #
  15. # Each machine has the materials and variants listed in which it needs to
  16. # split, since those might be different per machine.
  17. #
  18. # This should contain the definition as they are stated in the profiles. The
  19. # inheritance structure cannot be found at this stage, since the definitions
  20. # may have changed in later versions than 2.2.
  21. _machines_with_machine_quality = {
  22. "ultimaker2plus": {
  23. "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva", "generic_cpe_plus", "generic_nylon", "generic_pc", "generic_tpu" },
  24. "variants": { "0.25 mm", "0.4 mm", "0.6 mm", "0.8 mm" }
  25. },
  26. "ultimaker2_extended_plus": {
  27. "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva", "generic_cpe_plus", "generic_nylon", "generic_pc", "generic_tpu" },
  28. "variants": { "0.25 mm", "0.4 mm", "0.6 mm", "0.8 mm" }
  29. }
  30. } # type: Dict[str, Dict[str, Set[str]]]
  31. ## How to translate material names from the old version to the new.
  32. _material_translations = {
  33. "PLA": "generic_pla",
  34. "ABS": "generic_abs",
  35. "CPE": "generic_cpe",
  36. "CPE+": "generic_cpe_plus",
  37. "Nylon": "generic_nylon",
  38. "PC": "generic_pc",
  39. "TPU": "generic_tpu",
  40. } # type: Dict[str, str]
  41. ## How to translate material names for in the profile names.
  42. _material_translations_profiles = {
  43. "PLA": "pla",
  44. "ABS": "abs",
  45. "CPE": "cpe",
  46. "CPE+": "cpep",
  47. "Nylon": "nylon",
  48. "PC": "pc",
  49. "TPU": "tpu",
  50. } # type: Dict[str, str]
  51. ## How to translate printer names from the old version to the new.
  52. _printer_translations = {
  53. "ultimaker2plus": "ultimaker2_plus"
  54. } # type: Dict[str, str]
  55. _printer_translations_profiles = {
  56. "ultimaker2plus": "um2p", #Does NOT get included in PLA profiles!
  57. "ultimaker2_extended_plus": "um2ep" #Has no profiles for CPE+, Nylon, PC and TPU!
  58. } # type: Dict[str, str]
  59. ## How to translate profile names from the old version to the new.
  60. #
  61. # This must have an entry for every built-in profile, since it also services
  62. # as a set for which profiles were built-in.
  63. _profile_translations = {
  64. "Low Quality": "low",
  65. "Normal Quality": "normal",
  66. "High Quality": "high",
  67. "Ulti Quality": "high", #This one doesn't have an equivalent. Map it to high.
  68. "abs_0.25_normal": "um2p_abs_0.25_normal",
  69. "abs_0.4_fast": "um2p_abs_0.4_fast",
  70. "abs_0.4_high": "um2p_abs_0.4_high",
  71. "abs_0.4_normal": "um2p_abs_0.4_normal",
  72. "abs_0.6_normal": "um2p_abs_0.6_normal",
  73. "abs_0.8_normal": "um2p_abs_0.8_normal",
  74. "cpe_0.25_normal": "um2p_cpe_0.25_normal",
  75. "cpe_0.4_fast": "um2p_cpe_0.4_fast",
  76. "cpe_0.4_high": "um2p_cpe_0.4_high",
  77. "cpe_0.4_normal": "um2p_cpe_0.4_normal",
  78. "cpe_0.6_normal": "um2p_cpe_0.6_normal",
  79. "cpe_0.8_normal": "um2p_cpe_0.8_normal",
  80. "cpep_0.4_draft": "um2p_cpep_0.4_draft",
  81. "cpep_0.4_normal": "um2p_cpep_0.4_normal",
  82. "cpep_0.6_draft": "um2p_cpep_0.6_draft",
  83. "cpep_0.6_normal": "um2p_cpep_0.6_normal",
  84. "cpep_0.8_draft": "um2p_cpep_0.8_draft",
  85. "cpep_0.8_normal": "um2p_cpep_0.8_normal",
  86. "nylon_0.25_high": "um2p_nylon_0.25_high",
  87. "nylon_0.25_normal": "um2p_nylon_0.25_normal",
  88. "nylon_0.4_fast": "um2p_nylon_0.4_fast",
  89. "nylon_0.4_normal": "um2p_nylon_0.4_normal",
  90. "nylon_0.6_fast": "um2p_nylon_0.6_fast",
  91. "nylon_0.6_normal": "um2p_nylon_0.6_normal",
  92. "nylon_0.8_draft": "um2p_nylon_0.8_draft",
  93. "nylon_0.8_normal": "um2p_nylon_0.8_normal",
  94. "pc_0.25_high": "um2p_pc_0.25_high",
  95. "pc_0.25_normal": "um2p_pc_0.25_normal",
  96. "pc_0.4_fast": "um2p_pc_0.4_fast",
  97. "pc_0.4_normal": "um2p_pc_0.4_normal",
  98. "pc_0.6_fast": "um2p_pc_0.6_fast",
  99. "pc_0.6_normal": "um2p_pc_0.6_normal",
  100. "pc_0.8_draft": "um2p_pc_0.8_draft",
  101. "pc_0.8_normal": "um2p_pc_0.8_normal",
  102. "pla_0.25_normal": "pla_0.25_normal", #Note that the PLA profiles don't get the um2p_ prefix, though they are for UM2+.
  103. "pla_0.4_fast": "pla_0.4_fast",
  104. "pla_0.4_high": "pla_0.4_high",
  105. "pla_0.4_normal": "pla_0.4_normal",
  106. "pla_0.6_normal": "pla_0.6_normal",
  107. "pla_0.8_normal": "pla_0.8_normal",
  108. "tpu_0.25_high": "um2p_tpu_0.25_high",
  109. "tpu_0.4_normal": "um2p_tpu_0.4_normal",
  110. "tpu_0.6_fast": "um2p_tpu_0.6_fast"
  111. } # type: Dict[str, str]
  112. ## Settings that are no longer in the new version.
  113. _removed_settings = {
  114. "fill_perimeter_gaps",
  115. "support_area_smoothing"
  116. } # type: Set[str]
  117. ## How to translate setting names from the old version to the new.
  118. _setting_name_translations = {
  119. "remove_overlapping_walls_0_enabled": "travel_compensate_overlapping_walls_0_enabled",
  120. "remove_overlapping_walls_enabled": "travel_compensate_overlapping_walls_enabled",
  121. "remove_overlapping_walls_x_enabled": "travel_compensate_overlapping_walls_x_enabled",
  122. "retraction_hop": "retraction_hop_enabled",
  123. "skin_overlap": "infill_overlap",
  124. "skirt_line_width": "skirt_brim_line_width",
  125. "skirt_minimal_length": "skirt_brim_minimal_length",
  126. "skirt_speed": "skirt_brim_speed",
  127. "speed_support_lines": "speed_support_infill",
  128. "speed_support_roof": "speed_support_interface",
  129. "support_roof_density": "support_interface_density",
  130. "support_roof_enable": "support_interface_enable",
  131. "support_roof_extruder_nr": "support_interface_extruder_nr",
  132. "support_roof_line_distance": "support_interface_line_distance",
  133. "support_roof_line_width": "support_interface_line_width",
  134. "support_roof_pattern": "support_interface_pattern"
  135. } # type: Dict[str, str]
  136. ## Custom profiles become quality_changes. This dictates which quality to base
  137. # the quality_changes profile on.
  138. #
  139. # Which quality profile to base the quality_changes on depends on the machine,
  140. # material and nozzle.
  141. #
  142. # If a current configuration is missing, fall back to "normal".
  143. _quality_fallbacks = {
  144. "ultimaker2_plus": {
  145. "ultimaker2_plus_0.25": {
  146. "generic_abs": "um2p_abs_0.25_normal",
  147. "generic_cpe": "um2p_cpe_0.25_normal",
  148. #No CPE+.
  149. "generic_nylon": "um2p_nylon_0.25_normal",
  150. "generic_pc": "um2p_pc_0.25_normal",
  151. "generic_pla": "pla_0.25_normal",
  152. "generic_tpu": "um2p_tpu_0.25_high"
  153. },
  154. "ultimaker2_plus_0.4": {
  155. "generic_abs": "um2p_abs_0.4_normal",
  156. "generic_cpe": "um2p_cpe_0.4_normal",
  157. "generic_cpep": "um2p_cpep_0.4_normal",
  158. "generic_nylon": "um2p_nylon_0.4_normal",
  159. "generic_pc": "um2p_pc_0.4_normal",
  160. "generic_pla": "pla_0.4_normal",
  161. "generic_tpu": "um2p_tpu_0.4_normal"
  162. },
  163. "ultimaker2_plus_0.6": {
  164. "generic_abs": "um2p_abs_0.6_normal",
  165. "generic_cpe": "um2p_cpe_0.6_normal",
  166. "generic_cpep": "um2p_cpep_0.6_normal",
  167. "generic_nylon": "um2p_nylon_0.6_normal",
  168. "generic_pc": "um2p_pc_0.6_normal",
  169. "generic_pla": "pla_0.6_normal",
  170. "generic_tpu": "um2p_tpu_0.6_fast",
  171. },
  172. "ultimaker2_plus_0.8": {
  173. "generic_abs": "um2p_abs_0.8_normal",
  174. "generic_cpe": "um2p_cpe_0.8_normal",
  175. "generic_cpep": "um2p_cpep_0.8_normal",
  176. "generic_nylon": "um2p_nylon_0.8_normal",
  177. "generic_pc": "um2p_pc_0.8_normal",
  178. "generic_pla": "pla_0.8_normal",
  179. #No TPU.
  180. }
  181. }
  182. } # type: Dict[str, Dict[str, Dict[str, str]]]
  183. ## How to translate variants of specific machines from the old version to the
  184. # new.
  185. _variant_translations = {
  186. "ultimaker2_plus": {
  187. "0.25 mm": "ultimaker2_plus_0.25",
  188. "0.4 mm": "ultimaker2_plus_0.4",
  189. "0.6 mm": "ultimaker2_plus_0.6",
  190. "0.8 mm": "ultimaker2_plus_0.8"
  191. },
  192. "ultimaker2_extended_plus": {
  193. "0.25 mm": "ultimaker2_extended_plus_0.25",
  194. "0.4 mm": "ultimaker2_extended_plus_0.4",
  195. "0.6 mm": "ultimaker2_extended_plus_0.6",
  196. "0.8 mm": "ultimaker2_extended_plus_0.8"
  197. }
  198. } # type: Dict[str, Dict[str, str]]
  199. ## How to translate variant names for in the profile names.
  200. _variant_translations_profiles = {
  201. "0.25 mm": "0.25",
  202. "0.4 mm": "0.4",
  203. "0.6 mm": "0.6",
  204. "0.8 mm": "0.8"
  205. } # type: Dict[str, str]
  206. ## Cura 2.2's material profiles use a different naming scheme for variants.
  207. #
  208. # Getting pretty stressed out by this sort of thing...
  209. _variant_translations_materials = {
  210. "ultimaker2_plus": {
  211. "0.25 mm": "ultimaker2_plus_0.25_mm",
  212. "0.4 mm": "ultimaker2_plus_0.4_mm",
  213. "0.6 mm": "ultimaker2_plus_0.6_mm",
  214. "0.8 mm": "ultimaker2_plus_0.8_mm"
  215. },
  216. "ultimaker2_extended_plus": {
  217. "0.25 mm": "ultimaker2_plus_0.25_mm",
  218. "0.4 mm": "ultimaker2_plus_0.4_mm",
  219. "0.6 mm": "ultimaker2_plus_0.6_mm",
  220. "0.8 mm": "ultimaker2_plus_0.8_mm"
  221. }
  222. } # type: Dict[str, Dict[str, str]]
  223. ## Converts configuration from Cura 2.1's file formats to Cura 2.2's.
  224. #
  225. # It converts the machine instances and profiles.
  226. class VersionUpgrade21to22(VersionUpgrade):
  227. ## Gets the fallback quality to use for a specific machine-variant-material
  228. # combination.
  229. #
  230. # For custom profiles we fall back onto this quality profile, since we
  231. # don't know which quality profile it was based on.
  232. #
  233. # \param machine The machine ID of the user's configuration in 2.2.
  234. # \param variant The variant ID of the user's configuration in 2.2.
  235. # \param material The material ID of the user's configuration in 2.2.
  236. @staticmethod
  237. def getQualityFallback(machine: str, variant: str, material: str) -> str:
  238. if machine not in _quality_fallbacks:
  239. return "normal"
  240. if variant not in _quality_fallbacks[machine]:
  241. return "normal"
  242. if material not in _quality_fallbacks[machine][variant]:
  243. return "normal"
  244. return _quality_fallbacks[machine][variant][material]
  245. ## Gets the set of built-in profile names in Cura 2.1.
  246. #
  247. # This is required to test if profiles should be converted to a quality
  248. # profile or a quality-changes profile.
  249. @staticmethod
  250. def builtInProfiles() -> Iterable[str]:
  251. return _profile_translations.keys()
  252. ## Gets a set of the machines which now have per-material quality profiles.
  253. #
  254. # \return A set of machine identifiers.
  255. @staticmethod
  256. def machinesWithMachineQuality() -> Dict[str, Dict[str, Set[str]]]:
  257. return _machines_with_machine_quality
  258. ## Converts machine instances from format version 1 to version 2.
  259. #
  260. # \param serialised The serialised machine instance in version 1.
  261. # \param filename The supposed file name of the machine instance, without
  262. # extension.
  263. # \return A tuple containing the new filename and the serialised machine
  264. # instance in version 2, or None if the input was not of the correct
  265. # format.
  266. def upgradeMachineInstance(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]:
  267. machine_instance = MachineInstance.importFrom(serialised, filename)
  268. if not machine_instance: #Invalid file format.
  269. return None
  270. return machine_instance.export()
  271. ## Converts preferences from format version 2 to version 3.
  272. #
  273. # \param serialised The serialised preferences file in version 2.
  274. # \param filename The supposed file name of the preferences file, without
  275. # extension.
  276. # \return A tuple containing the new filename and the serialised
  277. # preferences in version 3, or None if the input was not of the correct
  278. # format.
  279. def upgradePreferences(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]:
  280. preferences = Preferences.importFrom(serialised, filename)
  281. if not preferences: #Invalid file format.
  282. return None
  283. return preferences.export()
  284. ## Converts profiles from format version 1 to version 2.
  285. #
  286. # \param serialised The serialised profile in version 1.
  287. # \param filename The supposed file name of the profile, without
  288. # extension.
  289. # \return A tuple containing the new filename and the serialised profile
  290. # in version 2, or None if the input was not of the correct format.
  291. def upgradeProfile(self, serialised: str, filename: str) -> Optional[Tuple[List[str], List[str]]]:
  292. profile = Profile.importFrom(serialised, filename)
  293. if not profile: # Invalid file format.
  294. return None
  295. return profile.export()
  296. ## Translates a material name for the change from Cura 2.1 to 2.2.
  297. #
  298. # \param material A material name in Cura 2.1.
  299. # \return The name of the corresponding material in Cura 2.2.
  300. @staticmethod
  301. def translateMaterial(material: str) -> str:
  302. if material in _material_translations:
  303. return _material_translations[material]
  304. return material
  305. ## Translates a material name for the change from Cura 2.1 to 2.2 in
  306. # quality profile names.
  307. #
  308. # \param material A material name in Cura 2.1.
  309. # \return The name of the corresponding material in the quality profiles
  310. # in Cura 2.2.
  311. @staticmethod
  312. def translateMaterialForProfiles(material: str) -> str:
  313. if material in _material_translations_profiles:
  314. return _material_translations_profiles[material]
  315. return material
  316. ## Translates a printer name that might have changed since the last
  317. # version.
  318. #
  319. # \param printer A printer name in Cura 2.1.
  320. # \return The name of the corresponding printer in Cura 2.2.
  321. @staticmethod
  322. def translatePrinter(printer: str) -> str:
  323. if printer in _printer_translations:
  324. return _printer_translations[printer]
  325. return printer #Doesn't need to be translated.
  326. ## Translates a printer name for the change from Cura 2.1 to 2.2 in quality
  327. # profile names.
  328. #
  329. # \param printer A printer name in 2.1.
  330. # \return The name of the corresponding printer in Cura 2.2.
  331. @staticmethod
  332. def translatePrinterForProfile(printer: str) -> str:
  333. if printer in _printer_translations_profiles:
  334. return _printer_translations_profiles[printer]
  335. return printer
  336. ## Translates a built-in profile name that might have changed since the
  337. # last version.
  338. #
  339. # \param profile A profile name in the old version.
  340. # \return The corresponding profile name in the new version.
  341. @staticmethod
  342. def translateProfile(profile: str) -> str:
  343. if profile in _profile_translations:
  344. return _profile_translations[profile]
  345. return profile #Doesn't need to be translated.
  346. ## Updates settings for the change from Cura 2.1 to 2.2.
  347. #
  348. # The keys and values of settings are changed to what they should be in
  349. # the new version. Each setting is changed in-place in the provided
  350. # dictionary. This changes the input parameter.
  351. #
  352. # \param settings A dictionary of settings (as key-value pairs) to update.
  353. # \return The same dictionary.
  354. @staticmethod
  355. def translateSettings(settings: Dict[str, str]) -> Dict[str, str]:
  356. new_settings = {}
  357. for key, value in settings.items():
  358. if key in _removed_settings:
  359. continue
  360. if key == "retraction_combing": #Combing was made into an enum instead of a boolean.
  361. new_settings[key] = "off" if (value == "False") else "all"
  362. continue
  363. if key == "cool_fan_full_layer": #Layer counting was made one-indexed.
  364. new_settings[key] = str(int(value) + 1)
  365. continue
  366. if key in _setting_name_translations:
  367. new_settings[_setting_name_translations[key]] = value
  368. continue
  369. new_settings[key] = value
  370. return new_settings
  371. ## Translates a setting name for the change from Cura 2.1 to 2.2.
  372. #
  373. # \param setting The name of a setting in Cura 2.1.
  374. # \return The name of the corresponding setting in Cura 2.2.
  375. @staticmethod
  376. def translateSettingName(setting: str) -> str:
  377. if setting in _setting_name_translations:
  378. return _setting_name_translations[setting]
  379. return setting #Doesn't need to be translated.
  380. ## Translates a variant name for the change from Cura 2.1 to 2.2
  381. #
  382. # \param variant The name of a variant in Cura 2.1.
  383. # \param machine The name of the machine this variant is part of in Cura
  384. # 2.2's naming.
  385. # \return The name of the corresponding variant in Cura 2.2.
  386. @staticmethod
  387. def translateVariant(variant: str, machine: str) -> str:
  388. if machine in _variant_translations and variant in _variant_translations[machine]:
  389. return _variant_translations[machine][variant]
  390. return variant
  391. ## Translates a variant name for the change from Cura 2.1 to 2.2 in
  392. # material profiles.
  393. #
  394. # \param variant The name of the variant in Cura 2.1.
  395. # \param machine The name of the machine this variant is part of in Cura
  396. # 2.2's naming.
  397. # \return The name of the corresponding variant for in material profiles
  398. # in Cura 2.2.
  399. @staticmethod
  400. def translateVariantForMaterials(variant: str, machine: str) -> str:
  401. if machine in _variant_translations_materials and variant in _variant_translations_materials[machine]:
  402. return _variant_translations_materials[machine][variant]
  403. return variant
  404. ## Translates a variant name for the change from Cura 2.1 to 2.2 in quality
  405. # profiles.
  406. #
  407. # \param variant The name of the variant in Cura 2.1.
  408. # \return The name of the corresponding variant for in quality profiles in
  409. # Cura 2.2.
  410. @staticmethod
  411. def translateVariantForProfiles(variant: str) -> str:
  412. if variant in _variant_translations_profiles:
  413. return _variant_translations_profiles[variant]
  414. return variant