Files
grotti/tests/test_paint_index.py
T

172 lines
6.8 KiB
Python

"""Sparse paint_index / Bambu-T-Nummern für ACE-Map."""
import json
import unittest
from grotti import acm, parse, usage
PAINT_SPARSE = json.dumps(
[
{"material_type": "PLA", "paint_color": [255, 128, 0], "paint_index": 1},
{"material_type": "PLA", "paint_color": [0, 0, 0], "paint_index": 10},
]
)
class PaintIndexTests(unittest.TestCase):
def test_filaments_keep_slicer_paint_index(self):
rows = parse.filaments_from_paint_info(PAINT_SPARSE)
self.assertEqual(len(rows), 2)
self.assertEqual(rows[0]["paint_index"], 1)
self.assertEqual(rows[0]["type"], "PLA")
self.assertEqual(rows[0]["color"], "#ff8000")
self.assertEqual(rows[1]["paint_index"], 10)
self.assertEqual(rows[1]["color"], "#000000")
def test_build_acm_uses_paint_index_not_array_slot(self):
filaments = parse.filaments_from_paint_info(PAINT_SPARSE)
mapping = [
{"paint_index": 1, "ams_index": 3},
{"paint_index": 10, "ams_index": 2},
]
slots = [
{"index": 2, "type": "PLA", "color": "#f4f4f4"},
{"index": 3, "type": "PLA", "color": "#c23b3b"},
]
payload = acm.build_acm(filaments, mapping, slots)
paints = [item["paint_index"] for item in payload["ams_box_mapping"]]
self.assertEqual(paints, [1, 10])
by_paint = {item["paint_index"]: item for item in payload["ams_box_mapping"]}
self.assertEqual(by_paint[1]["ams_index"], 3)
self.assertEqual(by_paint[10]["ams_index"], 2)
self.assertEqual(by_paint[1]["paint_color"], [255, 128, 0])
self.assertEqual(by_paint[10]["paint_color"], [0, 0, 0])
def test_densify_mapping_and_rewrite_avoids_invalid_filament_id(self):
mapping = [
{"paint_index": 1, "ams_index": 3},
{"paint_index": 10, "ams_index": 2},
]
remap, dense = acm.densify_mapping(mapping)
self.assertEqual(remap, {1: 0, 10: 1})
self.assertEqual(
dense,
[
{"paint_index": 0, "ams_index": 3},
{"paint_index": 1, "ams_index": 2},
],
)
gcode = b"; hdr\nT10\nG1 X0\nT1 ; change\n; referenced_tools = 1,10\n"
out = acm.rewrite_gcode_tools(gcode, remap)
self.assertIn(b"T1\n", out)
self.assertIn(b"T0 ; change", out)
self.assertNotIn(b"T10", out)
self.assertIn(b"; referenced_tools = 0,1", out)
filaments = acm.remap_filaments(
parse.filaments_from_paint_info(PAINT_SPARSE), remap
)
slots = [
{"index": 2, "type": "PLA", "color": "#f4f4f4"},
{"index": 3, "type": "PLA", "color": "#c23b3b"},
]
payload = acm.build_acm(filaments, dense, slots)
paints = [item["paint_index"] for item in payload["ams_box_mapping"]]
self.assertEqual(paints, [0, 1])
self.assertEqual(payload["ams_box_mapping"][0]["paint_color"], [255, 128, 0])
def test_densify_identity_when_already_dense(self):
mapping = [{"paint_index": 0, "ams_index": 1}, {"paint_index": 1, "ams_index": 2}]
remap, dense = acm.densify_mapping(mapping)
self.assertEqual(remap, {})
self.assertEqual(dense, mapping)
def test_align_rewrites_when_ui_map_is_already_dense(self):
"""Regression 10011700: UI schickt 0/1, G-code hat noch T1/T10."""
gcode = b"; hdr\nT10\nG1 X0\nT1 ; change\n; referenced_tools = 1,10\n"
mapping = [
{"paint_index": 0, "ams_index": 3},
{"paint_index": 1, "ams_index": 2},
]
filaments = [
{"type": "PLA", "color": "#ff8000", "paint_index": 0},
{"type": "PLA", "color": "#000000", "paint_index": 1},
]
out, dense, fils, remap = acm.align_tools_for_ace(gcode, mapping, filaments)
self.assertEqual(remap, {1: 0, 10: 1})
self.assertEqual(
dense,
[
{"paint_index": 0, "ams_index": 3},
{"paint_index": 1, "ams_index": 2},
],
)
self.assertIn(b"T1\n", out)
self.assertIn(b"T0 ; change", out)
self.assertNotIn(b"T10", out)
self.assertIn(b"; referenced_tools = 0,1", out)
self.assertEqual([row["paint_index"] for row in fils], [0, 1])
self.assertEqual(fils[0]["color"], "#ff8000")
self.assertEqual(fils[1]["color"], "#000000")
def test_align_with_sparse_ui_map(self):
gcode = b"T10\nT1\n"
mapping = [
{"paint_index": 1, "ams_index": 3},
{"paint_index": 10, "ams_index": 2},
]
out, dense, fils, remap = acm.align_tools_for_ace(
gcode, mapping, parse.filaments_from_paint_info(PAINT_SPARSE)
)
self.assertEqual(remap, {1: 0, 10: 1})
self.assertEqual(dense[0]["ams_index"], 3)
self.assertEqual(dense[1]["ams_index"], 2)
self.assertNotIn(b"T10", out)
self.assertEqual([row["paint_index"] for row in fils], [0, 1])
def test_tools_used_finds_t10(self):
gcode = b"; header\nT10\nG1 X0\nT1 ; change\n"
self.assertEqual(parse.tools_used_in_gcode(gcode), {1, 10})
def test_planned_shares_sparse_paint_falls_back_to_order(self):
meta = {"filament_weight_total": [12.0, 8.0]}
mapping = [
{"paint_index": 1, "ams_index": 0},
{"paint_index": 10, "ams_index": 1},
]
self.assertEqual(usage.planned_shares(meta, mapping, 2), [12.0, 8.0])
def test_profile_name_strips_machine(self):
self.assertEqual(parse.profile_name('Sunlu PLA Meta @Kobra 3'), "Sunlu PLA Meta")
self.assertEqual(parse.profile_name('"Sunlu PLA Matte @Kobra S1"'), "Sunlu PLA Matte")
def test_filaments_of_attaches_settings_id_profiles(self):
# Slot 1 = PLA, Slot 10 = Matte — wie sparse paint_info
profiles = ";".join(
['"Sunlu PLA @Kobra 3"' if i not in (1, 10) else (
'"Sunlu PLA @Kobra 3"' if i == 1 else '"Sunlu PLA Matte @Kobra 3"'
) for i in range(15)]
)
comments = {
"paint_info": PAINT_SPARSE,
"filament_settings_id": profiles,
}
rows = parse.filaments_of(comments)
self.assertEqual(rows[0]["profile"], "Sunlu PLA")
self.assertEqual(rows[1]["profile"], "Sunlu PLA Matte")
def test_filaments_of_single_without_paint(self):
comments = {
"filament_type": "PLA",
"filament_colour": "#00FF00",
"filament_settings_id": '"Sunlu PLA Meta @Kobra 3"',
}
rows = parse.filaments_of(comments)
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["profile"], "Sunlu PLA Meta")
self.assertEqual(rows[0]["type"], "PLA")
if __name__ == "__main__":
unittest.main()