From 791a9a3c56579999a595c0cb2f355a371d91be18 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Tue, 14 Jul 2026 22:16:25 +0200 Subject: [PATCH 01/11] Load and show tool geometry in the 3D viewer --- carveracontroller/GcodeViewer.py | 215 +++----- .../addons/tool_visualization/__init__.py | 14 + .../addons/tool_visualization/extractor.py | 40 ++ .../addons/tool_visualization/icon_builder.py | 24 + .../addons/tool_visualization/mesh_builder.py | 513 ++++++++++++++++++ .../tool_visualization/parsers/__init__.py | 7 + .../addons/tool_visualization/parsers/base.py | 51 ++ .../parsers/fusion360_makera.py | 120 ++++ .../tool_visualization/tool_definition.py | 54 ++ .../tool_visualization/tooltip_builder.py | 58 ++ .../data/GcodeViewer/pointer.obj | 259 --------- .../data/GcodeViewer/tools/ball_end_mill.png | Bin 0 -> 1194 bytes .../GcodeViewer/tools/bull_nose_end_mill.png | Bin 0 -> 1073 bytes .../data/GcodeViewer/tools/flat_end_mill.png | Bin 0 -> 963 bytes .../data/GcodeViewer/tools/lollipop_mill.png | Bin 0 -> 1319 bytes .../data/GcodeViewer/tools/pointed_mill.png | Bin 0 -> 1224 bytes .../data/GcodeViewer/tools/radius_mill.png | Bin 0 -> 1151 bytes .../data/GcodeViewer/tools/thread_mill.png | Bin 0 -> 1316 bytes carveracontroller/main.py | 60 +- carveracontroller/makera.kv | 41 +- carveracontroller/pointer2.obj | 103 ---- carveracontroller/shaders/tool_pointer.glsl | 2 +- tests/unit/test_tool_visualization.py | 366 +++++++++++++ 23 files changed, 1417 insertions(+), 510 deletions(-) create mode 100644 carveracontroller/addons/tool_visualization/__init__.py create mode 100644 carveracontroller/addons/tool_visualization/extractor.py create mode 100644 carveracontroller/addons/tool_visualization/icon_builder.py create mode 100644 carveracontroller/addons/tool_visualization/mesh_builder.py create mode 100644 carveracontroller/addons/tool_visualization/parsers/__init__.py create mode 100644 carveracontroller/addons/tool_visualization/parsers/base.py create mode 100644 carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py create mode 100644 carveracontroller/addons/tool_visualization/tool_definition.py create mode 100644 carveracontroller/addons/tool_visualization/tooltip_builder.py delete mode 100755 carveracontroller/data/GcodeViewer/pointer.obj create mode 100644 carveracontroller/data/GcodeViewer/tools/ball_end_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/flat_end_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/lollipop_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/pointed_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/radius_mill.png create mode 100644 carveracontroller/data/GcodeViewer/tools/thread_mill.png delete mode 100755 carveracontroller/pointer2.obj create mode 100644 tests/unit/test_tool_visualization.py diff --git a/carveracontroller/GcodeViewer.py b/carveracontroller/GcodeViewer.py index 79a3ba96..3aefdc47 100644 --- a/carveracontroller/GcodeViewer.py +++ b/carveracontroller/GcodeViewer.py @@ -42,6 +42,7 @@ def get_elapsed(str): # input from kivy.input.provider import MotionEventProvider +from .addons.tool_visualization.mesh_builder import build_tool_meshes from .arcball_from_cpp import * from .Objloader import ObjFile from .ui.ViewCube import ( @@ -326,7 +327,6 @@ def _gcode_viewer_asset(name): VIEW_CUBE_ATLAS_PATH = _gcode_viewer_asset("view_cube_atlas.png") VIEW_CUBE_MODEL_PATH = _gcode_viewer_asset("view_cube_model.obj") -POINTER_OBJ_PATH = _gcode_viewer_asset("pointer.obj") AXIS_OBJ_PATH = _gcode_viewer_asset("axis.obj") @@ -345,6 +345,8 @@ def __init__(self): self.raw_linenumbers = [] # feed rate (mm/min) per vertex, from CNC parser self.raw_feed_rates = [] + # active tool number per vertex, used to pick the tool mesh to display + self.raw_tools = [] # angles of vertices [4 axis] self.angles_of_vertices = [] @@ -378,6 +380,7 @@ def clear(self): # raw numbers self.raw_linenumbers.clear() self.raw_feed_rates.clear() + self.raw_tools.clear() # angles of vertices [4 axis] self.angles_of_vertices.clear() # mesh container @@ -397,13 +400,6 @@ def clear(self): def get_pt_count(self): return len(self.positions) - def map_color(self, color_str): - if color_str == "Green": - return [0.0, 1.0, 0.0] - if color_str == "Red": - return [1.0, 0.0, 0.0] - return [1.0, 1.0, 1.0] - # get center of meshes def get_center(self): if self.area_center_sum_index == 0: @@ -418,109 +414,6 @@ def get_vertex_position(self, idx): base = idx * VERTEX_FLOAT_NUM return [self.vertices[base], self.vertices[base + 1], self.vertices[base + 2]] - # parse single line - def parse_line(self, line): - arr_pt = line.split(" ") - - # position (raw G-code coordinates) - raw_pos = [float(arr_pt[1]), float(arr_pt[3]), float(arr_pt[5])] - - # Store raw positions before rotation - self.raw_positions.append(raw_pos[0]) - self.raw_positions.append(raw_pos[1]) - self.raw_positions.append(raw_pos[2]) - - pos = raw_pos - if self.is_4_axis: - angle = float(arr_pt[7]) - pos = rotate_pt_by_x_axis_angle(pos[0], pos[1], pos[2], angle) - - self.positions.append(pos[0]) - self.positions.append(pos[1]) - self.positions.append(pos[2]) - self.min_pt = vec3_min(self.min_pt, pos) - self.max_pt = vec3_max(self.max_pt, pos) - - # for center calculating - self.area_center_sum = vec3_add(self.area_center_sum, pos) - self.area_center_sum_index += 1 - - # get attributes of this point - vertex = [0] * VERTEX_FLOAT_NUM - if self.is_4_axis: - # 1 position - vertex[0] = pos[0] - vertex[1] = pos[1] - vertex[2] = pos[2] - - # angle - angle = float(arr_pt[7]) - - # 2 color - color = self.map_color(arr_pt[9]) - vertex[3] = color[0] - vertex[4] = color[1] - vertex[5] = color[2] - - # 3 line number in gcode - vertex[6] = float(arr_pt[11]) - - # 4 type id - vertex[7] = len(self.positions) - 1 - - # 5 distance attribute - vertex[8] = 0 # set after length is calculated - - # 6 set tool knife id - vertex[9] = float(arr_pt[13]) - - # 7 feed rate (mm/min) - is_rapid = arr_pt[9] == "Red" - feed = feed_mm_min_for_move(is_rapid) - vertex[10] = feed - - # push this vertex to container - self.vertices.extend(vertex) - self.vertex_types.append(1.0 if arr_pt[9] == "Green" else 2.0) # line type[red | green] - self.raw_linenumbers.append(vertex[6]) - self.raw_feed_rates.append(feed) - self.angles_of_vertices.append(angle) - else: - # 1 position - vertex[0] = pos[0] - vertex[1] = pos[1] - vertex[2] = pos[2] - - # 2 color - color = self.map_color(arr_pt[7]) - vertex[3] = color[0] - vertex[4] = color[1] - vertex[5] = color[2] - - # 3 line number in gcode - vertex[6] = float(arr_pt[9]) - - # 4 type id - vertex[7] = len(self.positions) - 1 - - # 5 distance attribute - vertex[8] = 0 # set after length is calculated - - # 6 set tool knife id - vertex[9] = float(arr_pt[11]) - - # 7 feed rate (mm/min) - is_rapid = arr_pt[7] == "Red" - feed = feed_mm_min_for_move(is_rapid) - vertex[10] = feed - - # push this vertex to container - self.vertices.extend(vertex) - - self.vertex_types.append(1.0 if arr_pt[7] == "Green" else 2.0) # line type[red | green] - self.raw_linenumbers.append(vertex[6]) - self.raw_feed_rates.append(feed) - def parse_line_data(self, linedata): # position (raw G-code coordinates) raw_pos = [linedata[0], linedata[1], linedata[2]] @@ -578,6 +471,7 @@ def parse_line_data(self, linedata): self.vertex_types.append(1.0 if linedata[4] > 0.5 else 2.0) # line type[red | green] self.raw_linenumbers.append(vertex[6]) self.raw_feed_rates.append(feed) + self.raw_tools.append(vertex[9]) self.angles_of_vertices.append(angle) def generate_meshes(self): @@ -639,25 +533,6 @@ def generate_meshes(self): mesh_start_id = mesh_end_id - 1 mesh_end_id = min(mesh_start_id + self.seg_mesh_vertex_count, vertex_count) - def add_lines(self, rawlines): - # parse line - - # 1 check gcode type - is_4_axis = False - if len(rawlines) > 0 and "A:" in rawlines[0]: - is_4_axis = True - - if self.is_4_axis is None: - self.is_4_axis = is_4_axis - elif self.is_4_axis != is_4_axis: - print("conflict line type!") - - # 2 parse single line - for line in rawlines: - self.parse_line(line.strip()) - - self.generate_meshes() - def add_data_arrs(self, rawdata, is_end=True): # parse line @@ -710,7 +585,12 @@ class GCodeViewer(Widget): raw_linenumbers = [] raw_positions = [] raw_feed_rates = [] + raw_tools = [] frame_callback = None + + # Tool number -> ToolDefinition extracted from the loaded file's CAM comments. + # Set from outside (see main.py) before/at the final load_array() call. + tool_table = {} time_estimate_progress_callback = None log_callback = None error_popup_callback = None @@ -791,6 +671,14 @@ def __init__(self): self.meshmanager = MeshManager() self.positions = [] + # Per-tool generated meshes (tool number -> (vertices, indices, vertex_format)), + # rebuilt whenever a new file finishes loading. `pointer_mesh_instr` is the Mesh + # instruction whose geometry gets swapped as the active tool changes. + self._tool_meshes = {} + self._default_tool_mesh = None + self.pointer_mesh_instr = None + self._active_tool_number = None + # Dirty flags: set True whenever the scene must be re-rendered. # _scene_dirty covers view/pointer/axis uniform changes; _proj_dirty # covers the projection matrix (zoom, pan, resize). @@ -1000,6 +888,11 @@ def clearDisplay(self): self.line_times = [] self.total_time = 0.0 self.raw_feed_rates = [] + self.raw_tools = [] + self._tool_meshes = {} + self._default_tool_mesh = None + self.pointer_mesh_instr = None + self._active_tool_number = None self.linemesh.clear() self.canvas.remove(self.linemesh) self.canvas.remove(self.gridmesh) @@ -1031,6 +924,46 @@ def clear_loaded_memery(self): self.meshmanager.clear() + def _tool_number_at_index(self, vertex_idx): + """Return the active tool number (int) at a given vertex index, or None.""" + if not self.raw_tools: + return None + vertex_idx = max(0, min(vertex_idx, len(self.raw_tools) - 1)) + return int(self.raw_tools[vertex_idx]) + + def _get_tool_mesh(self, tool_number): + """Return the (vertices, indices, vertex_format) mesh for a tool number. + + Falls back to the default (basic pointed) mesh when the tool number + is unknown or has no metadata in the loaded file. + """ + if tool_number is not None and tool_number in self._tool_meshes: + return self._tool_meshes[tool_number] + return self._default_tool_mesh + + def _log_tool_mesh_summary(self): + """Log which tools used in the loaded file have real geometry vs. a fallback mesh.""" + used_tool_numbers = sorted({int(t) for t in self.raw_tools}) if self.raw_tools else [] + known = [t for t in used_tool_numbers if t in self._tool_meshes] + unknown = [t for t in used_tool_numbers if t not in self._tool_meshes] + logger.info( + f"Tool meshes ready: {len(known)}/{len(used_tool_numbers)} used tools have geometry " + f"from the tool table ({known}); using default (pointed) mesh for {unknown}" + ) + + def _update_pointer_tool_mesh(self, vertex_idx): + """Swap the pointer mesh geometry if the active tool changed.""" + if self.pointer_mesh_instr is None: + return + tool_number = self._tool_number_at_index(vertex_idx) + if tool_number == self._active_tool_number: + return + vertices, indices, _fmt = self._get_tool_mesh(tool_number) + self.pointer_mesh_instr.vertices = vertices + self.pointer_mesh_instr.indices = indices + self._active_tool_number = tool_number + self._scene_dirty = True + def load_array(self, tmpdataarrs, is_end=True): self.clear_loaded_memery() @@ -1077,6 +1010,7 @@ def load_array(self, tmpdataarrs, is_end=True): self.raw_positions = self.meshmanager.raw_positions self.raw_linenumbers = self.meshmanager.raw_linenumbers self.raw_feed_rates = self.meshmanager.raw_feed_rates + self.raw_tools = self.meshmanager.raw_tools self.angles_of_vertices = self.meshmanager.angles_of_vertices self.total_line_count = self.meshmanager.get_pt_count() @@ -1091,9 +1025,16 @@ def load_array(self, tmpdataarrs, is_end=True): self._update_feed_range_uniforms() - self.pointer = ObjFile(POINTER_OBJ_PATH) self.axis_obj = ObjFile(AXIS_OBJ_PATH) + # Build a basic 3D mesh per known tool (from CAM comments), plus a + # default (basic pointed) mesh used for tools with no metadata. + self._tool_meshes, self._default_tool_mesh = build_tool_meshes( + self.tool_table or {}, scale=self.move_scale_by_positon + ) + self._active_tool_number = self._tool_number_at_index(0) + self._log_tool_mesh_summary() + # 4-axis: rotate toolhead mesh instead of the toolpath self.rotate_line_or_knife = False if self.is_4_axis: @@ -1109,11 +1050,11 @@ def load_array(self, tmpdataarrs, is_end=True): with self.pointermesh: self.cb = Callback(None) - m = list(self.pointer.objects.values())[0] - self.mesh = Mesh( - vertices=m.vertices, - indices=m.indices, - fmt=m.vertex_format, + verts, idxs, fmt = self._get_tool_mesh(self._active_tool_number) + self.pointer_mesh_instr = Mesh( + vertices=verts, + indices=idxs, + fmt=fmt, mode="triangles", ) self.cb = Callback(None) @@ -1562,6 +1503,8 @@ def _on_frame_tick(self, _): self.cur_line_index = line_index_withratio + self._update_pointer_tool_mesh(int(line_index_withratio)) + # Per-frame callback during toolpath playback only if self.frame_callback is not None and self.dynamic_display: [cur_distance, linenumber] = self.get_cur_pos_index() diff --git a/carveracontroller/addons/tool_visualization/__init__.py b/carveracontroller/addons/tool_visualization/__init__.py new file mode 100644 index 00000000..c5fa821e --- /dev/null +++ b/carveracontroller/addons/tool_visualization/__init__.py @@ -0,0 +1,14 @@ +"""Tool metadata extraction and 3D mesh generation for the G-code viewer. + +This package parses CAM-generated comments in loaded G-code files to build a +per-tool description (type + geometry), then generates a basic 3D mesh for +each tool so the viewer can display a shape that roughly matches the tool +that is currently active instead of a single generic cylinder. +""" + +from carveracontroller.addons.tool_visualization.extractor import extract_tool_table +from carveracontroller.addons.tool_visualization.icon_builder import get_tool_icon_path +from carveracontroller.addons.tool_visualization.tool_definition import ToolDefinition, ToolType +from carveracontroller.addons.tool_visualization.tooltip_builder import format_tool_tooltip + +__all__ = ["extract_tool_table", "format_tool_tooltip", "get_tool_icon_path", "ToolDefinition", "ToolType"] diff --git a/carveracontroller/addons/tool_visualization/extractor.py b/carveracontroller/addons/tool_visualization/extractor.py new file mode 100644 index 00000000..b0cb22c4 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/extractor.py @@ -0,0 +1,40 @@ +"""Registry of CAM tool table parsers and the extraction entry point.""" + +import logging + +from carveracontroller.addons.tool_visualization.parsers.fusion360_makera import Fusion360MakeraParser + +logger = logging.getLogger(__name__) + +# Ordered list of parsers to try when extracting a tool table from a loaded +# G-code file. Add new CAM/post-processor parsers here. +TOOL_TABLE_PARSERS = [ + Fusion360MakeraParser(), +] + + +def extract_tool_table(lines): + """Try each registered parser and return the first non-empty tool table. + + `lines` is passed as-is to each parser; well-behaved parsers bail out + early (e.g. via `ToolTableParser.iter_header_lines`) instead of scanning + the whole file, so this stays cheap even for very large files. + + Returns a dict mapping tool number (int) -> ToolDefinition. If no parser + recognises the file (or the file has no tool table at all), an empty + dict is returned; callers should then fall back to default tool + geometry for every tool. + """ + for parser in TOOL_TABLE_PARSERS: + try: + tool_table = parser.parse(lines) + except Exception: + logger.exception(f"Tool table parser '{parser.name}' raised an exception, skipping it") + tool_table = {} + if tool_table: + tool_numbers = ", ".join(f"T{number}" for number in sorted(tool_table)) + logger.info(f"Tool table extracted using parser '{parser.name}': {tool_numbers}") + return tool_table + + logger.debug("No tool table detected in loaded file (no parser recognised it); using default tool geometry") + return {} diff --git a/carveracontroller/addons/tool_visualization/icon_builder.py b/carveracontroller/addons/tool_visualization/icon_builder.py new file mode 100644 index 00000000..ffe0b247 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/icon_builder.py @@ -0,0 +1,24 @@ +"""Map tool definitions to toolbar icon paths for the G-code viewer.""" + +from carveracontroller.addons.tool_visualization.tool_definition import ToolType + +TOOLS_ICON_DIR = "data/GcodeViewer/tools" +DEFAULT_ICON = f"{TOOLS_ICON_DIR}/pointed_mill.png" +TOOL_TYPE_ICONS = { + ToolType.FLAT_END_MILL: f"{TOOLS_ICON_DIR}/flat_end_mill.png", + ToolType.BALL_END_MILL: f"{TOOLS_ICON_DIR}/ball_end_mill.png", + ToolType.BULL_NOSE_END_MILL: f"{TOOLS_ICON_DIR}/bull_nose_end_mill.png", + ToolType.RADIUS_MILL: f"{TOOLS_ICON_DIR}/radius_mill.png", + ToolType.CHAMFER_MILL: DEFAULT_ICON, + ToolType.TAPERED_MILL: DEFAULT_ICON, + ToolType.LOLLIPOP_MILL: f"{TOOLS_ICON_DIR}/lollipop_mill.png", + ToolType.THREAD_MILL: f"{TOOLS_ICON_DIR}/thread_mill.png", + ToolType.UNKNOWN: DEFAULT_ICON, +} + + +def get_tool_icon_path(tool_def): + """Return the toolbar icon path for a tool definition.""" + if tool_def is None: + return DEFAULT_ICON + return TOOL_TYPE_ICONS.get(tool_def.tool_type, DEFAULT_ICON) diff --git a/carveracontroller/addons/tool_visualization/mesh_builder.py b/carveracontroller/addons/tool_visualization/mesh_builder.py new file mode 100644 index 00000000..47cf3093 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/mesh_builder.py @@ -0,0 +1,513 @@ +"""Procedural generation of very basic 3D tool meshes. +Each tool is approximated by revolving a simple 2D profile. +""" + +import math + +from carveracontroller.addons.tool_visualization.tool_definition import ToolType + +VERTEX_FORMAT = [(b"v_pos", 3, "float"), (b"v_normal", 3, "float"), (b"v_tc0", 2, "float")] +RADIAL_SEGMENTS = 20 +ROUND_SEGMENTS = 10 +DEFAULT_TAPER_ANGLE_DEG = 30.0 + +# Factor used to compute the shared tool height from the largest diameter in the table. +LENGTH_DIAMETER_FACTOR = 3.0 + +# Minimum radius and length for tools to be visible on screen. +MIN_VISIBLE_RADIUS = 0.02 +MIN_SHANK_LENGTH = 0.05 + +# Fixed on-screen size for tools with no CAM metadata (scaled viewer coordinates). +FALLBACK_TOOL_DISPLAY_RADIUS = 0.04 +FALLBACK_TOOL_DISPLAY_HEIGHT = 1.3 + + +def _segment_tangent(profile, start, end): + z0, r0 = profile[start] + z1, r1 = profile[end] + return (z1 - z0, r1 - r0) + + +def _ring_tangent(profile, index): + """Tangent in the (z, radius) plane used for normals at a profile ring.""" + z, r = profile[index] + if r <= 1e-9: + if index + 1 < len(profile): + return _segment_tangent(profile, index, index + 1) + return _segment_tangent(profile, index - 1, index) + if index > 0 and profile[index - 1][1] <= 1e-9: + return _segment_tangent(profile, index - 1, index) + if index + 1 < len(profile) and profile[index + 1][1] <= 1e-9: + return _segment_tangent(profile, index, index + 1) + if index == 0: + return _segment_tangent(profile, index, index + 1) + if index == len(profile) - 1: + return _segment_tangent(profile, index - 1, index) + z_prev, r_prev = profile[index - 1] + z_next, r_next = profile[index + 1] + return (z_next - z_prev, r_next - r_prev) + + +def _surface_normal(dz, dr, theta): + """Outward normal for a surface of revolution at angle theta. + + Derived from cross(circumferential_tangent, profile_tangent) for a profile + segment with delta (dz, dr) in the (z, radius) plane. + """ + nx = dz * math.cos(theta) + ny = dz * math.sin(theta) + nz = -dr + length = math.sqrt(nx * nx + ny * ny + nz * nz) + if length < 1e-12: + return (0.0, 0.0, 1.0) + return (nx / length, ny / length, nz / length) + + +def _add_vertex(positions, normals, x, y, z, nx, ny, nz): + positions.extend([x, y, z]) + normals.extend([nx, ny, nz]) + return (len(positions) // 3) - 1 + + +def _build_side_ring(positions, normals, z, radius, dz, dr, segments): + """Add one ring of side-wall vertices with smooth analytical normals.""" + ring_indices = [] + for j in range(segments): + theta = 2.0 * math.pi * j / segments + cos_t = math.cos(theta) + sin_t = math.sin(theta) + nx, ny, nz = _surface_normal(dz, dr, theta) + idx = _add_vertex(positions, normals, radius * cos_t, radius * sin_t, z, nx, ny, nz) + ring_indices.append(idx) + return ring_indices + + +def _build_cap_ring(positions, normals, z, radius, nz_sign, segments): + """Add a ring of cap vertices with a flat face normal (±Z).""" + ring_indices = [] + for j in range(segments): + theta = 2.0 * math.pi * j / segments + cos_t = math.cos(theta) + sin_t = math.sin(theta) + idx = _add_vertex(positions, normals, radius * cos_t, radius * sin_t, z, 0.0, 0.0, nz_sign) + ring_indices.append(idx) + return ring_indices + + +def _pack_vertices(positions, normals): + vertices = [] + for i in range(len(positions) // 3): + base = 3 * i + vertices.extend( + [ + positions[base], + positions[base + 1], + positions[base + 2], + normals[base], + normals[base + 1], + normals[base + 2], + 0.0, + 0.0, + ] + ) + return vertices + + +def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): + """Revolve a `(z, radius)` profile (sorted by increasing z) into a triangle mesh. + + A profile point with `radius <= 0` is treated as a single point on the + axis (e.g. a pointed tip, or the pole of a ball nose) rather than a ring. + + Vertices are indexed and share smooth analytical normals derived from the + profile tangent. Flat end caps use separate vertices with ±Z normals. + """ + if len(profile) < 2: + raise ValueError("A tool profile needs at least two points") + + positions = [] + normals = [] + indices = [] + + side_rings = [] + for i, (z, r) in enumerate(profile): + if r <= 1e-9: + side_rings.append(None) + else: + dz, dr = _ring_tangent(profile, i) + side_rings.append(_build_side_ring(positions, normals, z, r, dz, dr, segments)) + + # Side walls, connecting each consecutive pair of profile points. + for i in range(len(profile) - 1): + ring_a = side_rings[i] + ring_b = side_rings[i + 1] + if ring_a is None and ring_b is None: + continue + if ring_a is None: + z_apex = profile[i][0] + dz, dr = _segment_tangent(profile, i, i + 1) + nx, ny, nz = _surface_normal(dz, dr, 0.0) + apex_idx = _add_vertex(positions, normals, 0.0, 0.0, z_apex, nx, ny, nz) + for j in range(segments): + b0 = ring_b[j] + b1 = ring_b[(j + 1) % segments] + indices.extend([apex_idx, b0, b1]) + elif ring_b is None: + z_apex = profile[i + 1][0] + dz, dr = _segment_tangent(profile, i, i + 1) + nx, ny, nz = _surface_normal(dz, dr, 0.0) + apex_idx = _add_vertex(positions, normals, 0.0, 0.0, z_apex, nx, ny, nz) + for j in range(segments): + a0 = ring_a[j] + a1 = ring_a[(j + 1) % segments] + indices.extend([a0, a1, apex_idx]) + else: + for j in range(segments): + a0 = ring_a[j] + a1 = ring_a[(j + 1) % segments] + b1 = ring_b[(j + 1) % segments] + b0 = ring_b[j] + indices.extend([a0, a1, b1, a0, b1, b0]) + + # Flat caps use their own vertices so side-wall normals are not overwritten. + z_bottom, r_bottom = profile[0] + if r_bottom > 1e-9: + center_idx = _add_vertex(positions, normals, 0.0, 0.0, z_bottom, 0.0, 0.0, -1.0) + cap_ring = _build_cap_ring(positions, normals, z_bottom, r_bottom, -1.0, segments) + for j in range(segments): + indices.extend([center_idx, cap_ring[(j + 1) % segments], cap_ring[j]]) + + z_top, r_top = profile[-1] + if r_top > 1e-9: + center_idx = _add_vertex(positions, normals, 0.0, 0.0, z_top, 0.0, 0.0, 1.0) + cap_ring = _build_cap_ring(positions, normals, z_top, r_top, 1.0, segments) + for j in range(segments): + indices.extend([center_idx, cap_ring[j], cap_ring[(j + 1) % segments]]) + + return _pack_vertices(positions, normals), indices, VERTEX_FORMAT + + +def _tool_diameter(tool_def, scale): + diameter = getattr(tool_def, "diameter", None) if tool_def else None + if diameter and diameter > 0: + return diameter + return fallback_tool_dimensions(scale)[0] + + +def _effective_tool_diameter(tool_def, scale): + """Return the outer cutting diameter used for sizing and proportions.""" + diameter = _tool_diameter(tool_def, scale) + if tool_def and getattr(tool_def, "tool_type", None) is ToolType.RADIUS_MILL: + corner_radius = getattr(tool_def, "corner_radius", None) or 0.0 + if corner_radius > 0: + return diameter + 2.0 * corner_radius + return diameter + + +def _profile_length(tool_def, scale, diameter, shared_length=None): + if shared_length is not None and shared_length > 0: + return shared_length + if tool_def and getattr(tool_def, "diameter", None) and tool_def.diameter > 0: + return diameter * LENGTH_DIAMETER_FACTOR + return fallback_tool_dimensions(scale)[1] + + +def _safe_corner_radius(tool_def, diameter, tool_type=None): + corner_radius = getattr(tool_def, "corner_radius", None) if tool_def else None + if not corner_radius or corner_radius <= 0: + return 0.0 + if tool_type is ToolType.RADIUS_MILL: + return corner_radius + return min(corner_radius, diameter / 2.0) + + +def _safe_taper_angle_deg(tool_def): + angle = getattr(tool_def, "taper_angle_deg", None) if tool_def else None + if not angle or angle <= 0 or angle >= 180: + return DEFAULT_TAPER_ANGLE_DEG + return angle + + +def _safe_thread_depth(tool_def, diameter): + thread_depth = getattr(tool_def, "thread_depth", None) if tool_def else None + if not thread_depth or thread_depth <= 0: + # No parser-provided value: assume a sensible depth based on diameter. + thread_depth = diameter / 10.0 + return min(thread_depth, diameter / 2.0) + + +def _safe_thread_pitch(tool_def, diameter): + thread_pitch = getattr(tool_def, "thread_pitch", None) if tool_def else None + if not thread_pitch or thread_pitch <= 0: + # No parser-provided value: assume a sensible pitch based on diameter. + thread_pitch = diameter / 5.0 + return thread_pitch + + +def _flat_end_mill_profile(diameter, length, **_kwargs): + radius = diameter / 2.0 + return [(0.0, radius), (length, radius)] + + +def _thread_mill_profile(diameter, length, thread_depth=0.0, thread_pitch=0.0, **_kwargs): + # Thread mills are represented as basic single-point cutters: a flat + # minor-diameter base, rising over half a pitch to the major diameter + # (the single cutting tooth), then back down to the minor diameter + # before continuing as a plain cylindrical shank. + major_radius = diameter / 2.0 + depth = thread_depth if thread_depth > 0 else diameter / 10.0 + depth = min(depth, major_radius) + minor_radius = major_radius - depth + + pitch = thread_pitch if thread_pitch > 0 else diameter / 5.0 + pitch = min(pitch, length) if length > 0 else pitch + half_pitch = pitch / 2.0 + + points = [(0.0, minor_radius), (half_pitch, major_radius), (pitch, minor_radius)] + if length > pitch: + points.append((length, minor_radius)) + return points + + +def _ball_end_mill_profile(diameter, length, **_kwargs): + radius = diameter / 2.0 + length = max(length, diameter) + points = [] + for i in range(ROUND_SEGMENTS + 1): + theta = -math.pi / 2.0 + (math.pi / 2.0) * (i / ROUND_SEGMENTS) + z = radius + radius * math.sin(theta) + r = radius * math.cos(theta) + points.append((z, r)) + points.append((length, radius)) + return points + + +def _bull_nose_profile(diameter, length, corner_radius=0.0, **_kwargs): + radius = diameter / 2.0 + corner_radius = corner_radius if corner_radius else radius * 0.25 + corner_radius = min(corner_radius, radius) + flat_radius = radius - corner_radius + + points = [(0.0, max(flat_radius, 0.0))] + for i in range(1, ROUND_SEGMENTS + 1): + theta = -math.pi / 2.0 + (math.pi / 2.0) * (i / ROUND_SEGMENTS) + z = corner_radius + corner_radius * math.sin(theta) + r = flat_radius + corner_radius * math.cos(theta) + points.append((z, r)) + + min_length = points[-1][0] + diameter * 0.5 + points.append((max(length, min_length), radius)) + return points + + +def _radius_mill_profile(diameter, length, corner_radius=0.0, **_kwargs): + # For radius mills the supplied `diameter` is the flat-bottom diameter. + # The outer cutting diameter is flat_diameter + 2 * corner_radius. + flat_radius = diameter / 2.0 + corner_radius = corner_radius if corner_radius else flat_radius * 0.25 + full_radius = flat_radius + corner_radius + full_diameter = diameter + 2.0 * corner_radius + + if corner_radius <= 1e-9: + return _flat_end_mill_profile(diameter, length) + + # Concave corner arc: centre at (z=0, r=full_radius), sweeping from + # the flat bottom out to the full cutting diameter. + points = [(0.0, flat_radius)] + for i in range(1, ROUND_SEGMENTS + 1): + theta = math.pi - (math.pi / 2.0) * (i / ROUND_SEGMENTS) + z = corner_radius * math.sin(theta) + r = full_radius + corner_radius * math.cos(theta) + points.append((z, r)) + + min_length = points[-1][0] + full_diameter * 0.5 + points.append((max(length, min_length), full_radius)) + return points + + +def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, **_kwargs): + radius = diameter / 2.0 + half_angle_rad = math.radians(taper_angle_deg) / 2.0 + half_angle_rad = min(max(half_angle_rad, math.radians(5.0)), math.radians(85.0)) + cone_height = radius / math.tan(half_angle_rad) + + points = [(0.0, 0.0), (cone_height, radius)] + if length > cone_height: + points.append((length, radius)) + return points + + +def _lollipop_profile(diameter, length, **_kwargs): + radius = diameter / 2.0 + points = [] + for i in range(ROUND_SEGMENTS * 2 + 1): + theta = -math.pi / 2.0 + math.pi * (i / (ROUND_SEGMENTS * 2)) + z = radius + radius * math.sin(theta) + r = max(radius * math.cos(theta), 0.0) + points.append((z, r)) + + neck_radius = max(radius * 0.35, diameter * 0.15) + neck_transition_len = max(radius * 0.5, diameter * 0.25) + ball_top_z = points[-1][0] + total_length = max(length, ball_top_z + neck_transition_len * 2.0) + + points.append((ball_top_z + neck_transition_len, neck_radius)) + points.append((total_length, neck_radius)) + return points + + +DEFAULT_PROFILE_BUILDER = _chamfer_or_tapered_profile +PROFILE_BUILDERS = { + ToolType.FLAT_END_MILL: _flat_end_mill_profile, + ToolType.THREAD_MILL: _thread_mill_profile, + ToolType.BALL_END_MILL: _ball_end_mill_profile, + ToolType.BULL_NOSE_END_MILL: _bull_nose_profile, + ToolType.RADIUS_MILL: _radius_mill_profile, + ToolType.CHAMFER_MILL: _chamfer_or_tapered_profile, + ToolType.TAPERED_MILL: _chamfer_or_tapered_profile, + ToolType.LOLLIPOP_MILL: _lollipop_profile, +} + + +def fallback_tool_dimensions(scale): + """Return (diameter, length) in file units for the no-metadata fallback mesh. + + Values are chosen so that, after multiplication by `scale`, the mesh keeps + a constant on-screen footprint regardless of file units or job bbox. + """ + if not scale or scale <= 0: + scale = 1.0 + diameter = FALLBACK_TOOL_DISPLAY_RADIUS * 2.0 / scale + length = FALLBACK_TOOL_DISPLAY_HEIGHT / scale + return diameter, length + + +def fallback_tool_profile(scale): + """Pointed fallback profile with a fixed on-screen size.""" + diameter, length = fallback_tool_dimensions(scale) + return _chamfer_or_tapered_profile(diameter, length) + + +def _reference_length(tool_table, scale): + """Compute the shared tool height used for every tool in `tool_table`. + This is required since the unit system of the document can vary. + """ + diameters = [ + _effective_tool_diameter(tool_def, scale) + for tool_def in tool_table.values() + if tool_def and getattr(tool_def, "diameter", None) and tool_def.diameter > 0 + ] + if diameters: + return max(diameters) * LENGTH_DIAMETER_FACTOR + return fallback_tool_dimensions(scale)[1] + + +def tool_profile(tool_def, length=None, scale=1.0): + """Return the (unscaled) profile for a tool definition. + Falls back to a basic pointed (chamfer-like) profile when `tool_def` is + None or its type is unknown/unsupported (see DEFAULT_PROFILE_BUILDER). + Missing diameters use the fixed on-screen fallback size. + """ + diameter = _tool_diameter(tool_def, scale) + effective_diameter = _effective_tool_diameter(tool_def, scale) + length = _profile_length(tool_def, scale, effective_diameter, length) + tool_type = getattr(tool_def, "tool_type", ToolType.UNKNOWN) if tool_def else ToolType.UNKNOWN + corner_radius = _safe_corner_radius(tool_def, diameter, tool_type) + taper_angle_deg = _safe_taper_angle_deg(tool_def) + thread_depth = _safe_thread_depth(tool_def, diameter) + thread_pitch = _safe_thread_pitch(tool_def, diameter) + + builder = PROFILE_BUILDERS.get(tool_type, DEFAULT_PROFILE_BUILDER) + + return builder( + diameter, + length, + corner_radius=corner_radius, + taper_angle_deg=taper_angle_deg, + thread_depth=thread_depth, + thread_pitch=thread_pitch, + ) + + +def _scale_profile(profile, scale, radius_boost): + """Scale the profile by the given scale and radius boost.""" + factor = scale * radius_boost + scaled_profile = [(z * factor, r * factor) for z, r in profile] + + total_length = scaled_profile[-1][0] if scaled_profile else 0.0 + if total_length < MIN_SHANK_LENGTH: + shank_radius = scaled_profile[-1][1] + scaled_profile = scaled_profile[:-1] + [(MIN_SHANK_LENGTH, shank_radius)] + + return scaled_profile + + +def _compute_radius_boost(profiles, scale): + """Compute a single boost factor shared by every tool in `profiles`. + + Boosting each tool independently (to the same MIN_VISIBLE_RADIUS floor) + would make different-sized tools appear identical on screen whenever + they're all small enough to hit the floor. Instead we look at the + *smallest* tool of the batch and compute one factor that makes it meet + the visibility floor, then apply that same factor to every tool so their + relative sizes stay accurate to each other. + """ + radii = [max((r for _, r in profile), default=0.0) * scale for profile in profiles] + radii = [r for r in radii if r > 1e-9] + if not radii: + return 1.0 + + smallest_radius = min(radii) + if smallest_radius < MIN_VISIBLE_RADIUS: + return MIN_VISIBLE_RADIUS / smallest_radius + return 1.0 + + +def build_tool_mesh(tool_def, scale=1.0, radius_boost=1.0, length=None): + profile = tool_profile(tool_def, length=length, scale=scale) + scaled_profile = _scale_profile(profile, scale, radius_boost) + return _build_revolve_mesh(scaled_profile) + + +def build_default_tool_mesh(scale=1.0, radius_boost=1.0): + """Mesh used for tools with no metadata (fixed on-screen size).""" + profile = fallback_tool_profile(scale) + scaled_profile = _scale_profile(profile, scale, radius_boost) + return _build_revolve_mesh(scaled_profile) + + +def build_tool_meshes(tool_table, scale=1.0): + """Build a mesh for every tool in `tool_table`, plus a default mesh for + tools with no metadata. + + Known tools share: + - the same overall height, derived from the largest diameter in the + table (see `_reference_length`) so it scales sensibly with the + document's unit system instead of using a fixed absolute value. + - a single radius boost factor derived from the smallest tool in the + batch, so tiny tools stay visible without making unrelated tools look + like they share the same diameter. + + The default (no-metadata) mesh keeps a fixed on-screen size, independent + of file units. + + Returns `(tool_meshes, default_mesh)`. + """ + default_profile = fallback_tool_profile(scale) + + if tool_table: + shared_length = _reference_length(tool_table, scale) + profiles = { + number: tool_profile(tool_def, length=shared_length, scale=scale) for number, tool_def in tool_table.items() + } + radius_boost = _compute_radius_boost(list(profiles.values()), scale) + tool_meshes = { + number: _build_revolve_mesh(_scale_profile(profile, scale, radius_boost)) + for number, profile in profiles.items() + } + else: + tool_meshes = {} + + default_mesh = _build_revolve_mesh(_scale_profile(default_profile, scale, 1.0)) + return tool_meshes, default_mesh diff --git a/carveracontroller/addons/tool_visualization/parsers/__init__.py b/carveracontroller/addons/tool_visualization/parsers/__init__.py new file mode 100644 index 00000000..597f0696 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/parsers/__init__.py @@ -0,0 +1,7 @@ +"""CAM-specific tool table parsers. + +Each parser knows how to recognise and extract tool metadata from the +comments a particular CAM software / post processor writes at the top of a +G-code file. Add new parsers here and register them in +`carveracontroller.addons.tool_visualization.extractor.TOOL_TABLE_PARSERS`. +""" diff --git a/carveracontroller/addons/tool_visualization/parsers/base.py b/carveracontroller/addons/tool_visualization/parsers/base.py new file mode 100644 index 00000000..34f98069 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/parsers/base.py @@ -0,0 +1,51 @@ +"""Base class for CAM tool table parsers.""" + +from abc import ABC, abstractmethod + +# Characters that make a line "safe" to skip over while looking for a tool +# table header (comment, blank, program-marker or variable-assignment lines). +# Mirrors the characters CNC.parseLine() itself treats as non-motion lines. +HEADER_SAFE_PREFIXES = ("%", "(", "#", ";") + +# Hard cap on how many lines a header scan will ever look at, in case a file +# has an unusually long run of leading comments with no actual G-code. +MAX_HEADER_LINES = 5000 + + +class ToolTableParser(ABC): + """Extracts a tool table from the raw lines of a G-code file. + + Implementations should be conservative: if the file does not look like + it was produced by the CAM/post processor they support, `parse()` should + return an empty dict rather than guessing. + """ + + name = "base" + + @abstractmethod + def parse(self, lines): + """Parse (an iterable of) raw G-code file lines. + + Returns a dict mapping tool number (int) -> ToolDefinition. If a + tool number appears in multiple comments, only the first occurrence + found in the file should be kept. + """ + raise NotImplementedError + + @staticmethod + def iter_header_lines(lines, max_lines=MAX_HEADER_LINES): + """Lazily yield the leading blank/comment-only lines of a file. + + CAM post processors write tool tables as a block of comments at the + very top of the file, before any real G-code. So instead of scanning + the whole (potentially huge) file, parsers that rely on this stop + pulling from `lines` as soon as the first "real" line is seen (or + after `max_lines`), without ever materialising a separate list. + """ + for count, line in enumerate(lines): + if count >= max_lines: + return + stripped = line.strip() + if stripped and stripped[0] not in HEADER_SAFE_PREFIXES: + return + yield line diff --git a/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py b/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py new file mode 100644 index 00000000..d3b8bedf --- /dev/null +++ b/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py @@ -0,0 +1,120 @@ +"""Parser for tool tables written by the Fusion 360 Makera post processor. + +The post processor's `dumpToolInformation()` CPS function writes one comment +line per tool, on its own line, with the following layout: + +T D= CR=[ TAPER=deg][ - ZMIN=] - +""" + +import logging +import re + +from carveracontroller.addons.tool_visualization.parsers.base import ToolTableParser +from carveracontroller.addons.tool_visualization.tool_definition import ToolDefinition, ToolType, resolve_tool_type + +logger = logging.getLogger(__name__) + +# Tool type names as exported by the Fusion 360 Makera post processor's getToolTypeName() +TOOL_TYPE_NAME_MAP = { + "flat end mill": ToolType.FLAT_END_MILL, + "ball end mill": ToolType.BALL_END_MILL, + "bull nose end mill": ToolType.BULL_NOSE_END_MILL, + "radius mill": ToolType.RADIUS_MILL, + "chamfer mill": ToolType.CHAMFER_MILL, + "tapered mill": ToolType.TAPERED_MILL, + "lollipop mill": ToolType.LOLLIPOP_MILL, + "thread mill": ToolType.THREAD_MILL, +} + +_NUMBER = r"[-+]?\d+\.?\d*" + +TOOL_LINE_RE = re.compile( + r"^T(?P\d+)\s+(?P.*?)\s+D=(?P" + _NUMBER + r")\s+CR=(?P" + _NUMBER + r")" + r"(?:\s+TAPER=(?P" + _NUMBER + r")deg)?" + r"(?:\s*-\s*ZMIN=" + _NUMBER + r")?" + r"\s*-\s*(?P.+?)\s*$", + re.IGNORECASE, +) + +_FIELD_SPLIT_RE = re.compile(r"\s{2,}") + + +def _to_float(value): + if value is None: + return None + try: + return float(value) + except ValueError: + return None + + +def _extract_full_line_comment(line): + """Return the text of a comment if the whole (stripped) line is one, else None.""" + if len(line) >= 2 and line[0] == "(" and line[-1] == ")": + return line[1:-1] + if line.startswith(";"): + return line[1:] + return None + + +class Fusion360MakeraParser(ToolTableParser): + name = "fusion360_makera" + + def parse(self, lines): + tool_table = {} + for raw_line in self.iter_header_lines(lines): + line = raw_line.strip() + if not line: + continue + + comment_text = _extract_full_line_comment(line) + if comment_text is None: + continue + + match = TOOL_LINE_RE.match(comment_text.strip()) + if not match: + continue + + number = int(match.group("number")) + if number in tool_table: + # Only the first occurrence of a given tool should be used. + logger.debug(f"Ignoring duplicate tool table comment for T{number}: {line}") + continue + + tool_def = self._build_tool_definition(number, match) + tool_table[number] = tool_def + + if tool_def.tool_type is ToolType.UNKNOWN: + logger.warning( + f"Detected T{number} ({tool_def.description!r}, D={tool_def.diameter}) " + f"with unrecognised tool type {tool_def.type_name!r}; defaulting to a basic pointed mesh" + ) + else: + dims = f"D={tool_def.diameter}, CR={tool_def.corner_radius}" + if tool_def.taper_angle_deg is not None: + dims += f", TAPER={tool_def.taper_angle_deg}" + logger.info(f"Detected T{number}: {tool_def.tool_type.value} ({dims}) - {tool_def.description!r}") + + return tool_table + + @staticmethod + def _build_tool_definition(number, match): + middle = match.group("middle").strip() + fields = [field for field in _FIELD_SPLIT_RE.split(middle) if field] + description = fields[0] if len(fields) > 0 else "" + vendor = fields[1] if len(fields) > 1 else "" + product_id = fields[2] if len(fields) > 2 else "" + + type_name = match.group("type_name").strip() + + return ToolDefinition( + number=number, + tool_type=resolve_tool_type(type_name, TOOL_TYPE_NAME_MAP), + diameter=_to_float(match.group("diameter")), + corner_radius=_to_float(match.group("corner_radius")), + taper_angle_deg=_to_float(match.group("taper")), + description=description, + vendor=vendor, + product_id=product_id, + type_name=type_name, + ) diff --git a/carveracontroller/addons/tool_visualization/tool_definition.py b/carveracontroller/addons/tool_visualization/tool_definition.py new file mode 100644 index 00000000..e2957757 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/tool_definition.py @@ -0,0 +1,54 @@ +"""Common data structures describing a CNC tool for 3D visualization purposes.""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum + + +class ToolType(Enum): + """Basic tool shapes that can be visualised in the 3D viewer.""" + + FLAT_END_MILL = "flat_end_mill" + BALL_END_MILL = "ball_end_mill" + BULL_NOSE_END_MILL = "bull_nose_end_mill" + RADIUS_MILL = "radius_mill" # Note: Represents a concave radius mill + CHAMFER_MILL = "chamfer_mill" + TAPERED_MILL = "tapered_mill" + LOLLIPOP_MILL = "lollipop_mill" + THREAD_MILL = "thread_mill" + UNKNOWN = "unknown" + + +def normalize_tool_type_name(type_name): + """Normalise a raw tool type name for lookup (strip, lowercase, collapse whitespace).""" + if not type_name: + return "" + return " ".join(type_name.strip().lower().split()) + + +def resolve_tool_type(type_name, name_map): + """Resolve a raw (untrusted) tool type name to a ToolType using a parser-specific map.""" + normalised = normalize_tool_type_name(type_name) + if not normalised: + return ToolType.UNKNOWN + return name_map.get(normalised, ToolType.UNKNOWN) + + +@dataclass +class ToolDefinition: + """Geometry/metadata for a single tool, as extracted from a G-code comment. + Important: All dimensions are in the same units as the loaded G-code file (mm or in). + """ + + number: int + tool_type: ToolType = ToolType.UNKNOWN + diameter: float | None = None + corner_radius: float | None = None + taper_angle_deg: float | None = None + thread_depth: float | None = None + thread_pitch: float | None = None + description: str = "" + vendor: str = "" + product_id: str = "" + type_name: str = "" diff --git a/carveracontroller/addons/tool_visualization/tooltip_builder.py b/carveracontroller/addons/tool_visualization/tooltip_builder.py new file mode 100644 index 00000000..2d23d572 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/tooltip_builder.py @@ -0,0 +1,58 @@ +"""Format tool definitions as toolbar tooltip text for the G-code viewer.""" + +from carveracontroller.addons.tool_visualization.tool_definition import ToolType +from carveracontroller.translation import tr + +TOOL_TYPE_MSGIDS = { + ToolType.FLAT_END_MILL: "Flat End Mill", + ToolType.BALL_END_MILL: "Ball End Mill", + ToolType.BULL_NOSE_END_MILL: "Bull Nose End Mill", + ToolType.RADIUS_MILL: "Radius Mill", + ToolType.CHAMFER_MILL: "Chamfer Mill", + ToolType.TAPERED_MILL: "Tapered Mill", + ToolType.LOLLIPOP_MILL: "Lollipop Mill", + ToolType.THREAD_MILL: "Thread Mill", +} + + +def _format_tool_type_label(tool_def): + if tool_def.type_name: + return tool_def.type_name + msgid = TOOL_TYPE_MSGIDS.get(tool_def.tool_type) + return tr._(msgid) if msgid else "" + + +def format_tool_tooltip(tool_def): + """Return multi-line tooltip text for a parsed tool, or an empty string.""" + if tool_def is None: + return "" + + title = f"T{tool_def.number}" + type_label = _format_tool_type_label(tool_def) + if type_label: + title = f"{title} - {type_label}" + + lines = [title] + + dimensions = [] + if tool_def.diameter is not None: + dimensions.append(tr._("D={value:g}").format(value=tool_def.diameter)) + if tool_def.corner_radius is not None: + dimensions.append(tr._("CR={value:g}").format(value=tool_def.corner_radius)) + if tool_def.taper_angle_deg is not None: + dimensions.append(tr._("TAPER={value:g}°").format(value=tool_def.taper_angle_deg)) + if tool_def.thread_depth is not None: + dimensions.append(tr._("Thread depth={value:g}").format(value=tool_def.thread_depth)) + if tool_def.thread_pitch is not None: + dimensions.append(tr._("Pitch={value:g}").format(value=tool_def.thread_pitch)) + if dimensions: + lines.append(" ".join(dimensions)) + + if tool_def.description: + lines.append(tool_def.description) + + vendor_parts = [part for part in (tool_def.vendor, tool_def.product_id) if part] + if vendor_parts: + lines.append(" - ".join(vendor_parts)) + + return "\n".join(lines) diff --git a/carveracontroller/data/GcodeViewer/pointer.obj b/carveracontroller/data/GcodeViewer/pointer.obj deleted file mode 100755 index 6edc8153..00000000 --- a/carveracontroller/data/GcodeViewer/pointer.obj +++ /dev/null @@ -1,259 +0,0 @@ -# Blender v2.80 (sub 75) OBJ File: '' -# www.blender.org -o Cylinder -v 0.000000 0.040000 1.300000 -v 0.000000 0.040000 0.600000 -v 0.007804 0.039232 1.300000 -v 0.007804 0.039232 0.600000 -v 0.015307 0.036955 1.300000 -v 0.015307 0.036955 0.600000 -v 0.022223 0.033259 1.300000 -v 0.022223 0.033259 0.600000 -v 0.028284 0.028285 1.300000 -v 0.028284 0.028285 0.600000 -v 0.033259 0.022223 1.300000 -v 0.033259 0.022223 0.600000 -v 0.036955 0.015308 1.300000 -v 0.036955 0.015308 0.600000 -v 0.039232 0.007804 1.300000 -v 0.039232 0.007804 0.600000 -v 0.040000 0.000000 1.300000 -v 0.040000 0.000000 0.600000 -v 0.039232 -0.007803 1.300000 -v 0.039232 -0.007803 0.600000 -v 0.036955 -0.015307 1.300000 -v 0.036955 -0.015307 0.600000 -v 0.033259 -0.022223 1.300000 -v 0.033259 -0.022223 0.600000 -v 0.028284 -0.028284 1.300000 -v 0.028284 -0.028284 0.600000 -v 0.022223 -0.033259 1.300000 -v 0.022223 -0.033259 0.600000 -v 0.015307 -0.036955 1.300000 -v 0.015307 -0.036955 0.600000 -v 0.007804 -0.039231 1.300000 -v 0.007804 -0.039231 0.600000 -v 0.000000 -0.040000 1.300000 -v 0.000000 -0.040000 0.600000 -v -0.007804 -0.039231 1.300000 -v -0.007804 -0.039231 0.600000 -v -0.015307 -0.036955 1.300000 -v -0.015307 -0.036955 0.600000 -v -0.022223 -0.033259 1.300000 -v -0.022223 -0.033259 0.600000 -v -0.028284 -0.028284 1.300000 -v -0.028284 -0.028284 0.600000 -v -0.033259 -0.022223 1.300000 -v -0.033259 -0.022223 0.600000 -v -0.036955 -0.015307 1.300000 -v -0.036955 -0.015307 0.600000 -v -0.039231 -0.007803 1.300000 -v -0.039231 -0.007803 0.600000 -v -0.040000 0.000000 1.300000 -v -0.040000 0.000000 0.600000 -v -0.039231 0.007804 1.300000 -v -0.039231 0.007804 0.600000 -v -0.036955 0.015308 1.300000 -v -0.036955 0.015308 0.600000 -v -0.033259 0.022223 1.300000 -v -0.033259 0.022223 0.600000 -v -0.028284 0.028285 1.300000 -v -0.028284 0.028285 0.600000 -v -0.022223 0.033259 1.300000 -v -0.022223 0.033259 0.600000 -v -0.015307 0.036955 1.300000 -v -0.015307 0.036955 0.600000 -v -0.007803 0.039232 1.300000 -v -0.007803 0.039232 0.600000 -v 0.000000 0.000000 0.000000 -vn 0.0980 0.9952 0.0000 -vn 0.2903 0.9569 0.0000 -vn 0.4714 0.8819 0.0000 -vn 0.6344 0.7730 0.0000 -vn 0.7730 0.6344 0.0000 -vn 0.8819 0.4714 0.0000 -vn 0.9569 0.2903 0.0000 -vn 0.9952 0.0980 0.0000 -vn 0.9952 -0.0980 -0.0000 -vn 0.9569 -0.2903 -0.0000 -vn 0.8819 -0.4714 -0.0000 -vn 0.7730 -0.6344 -0.0000 -vn 0.6344 -0.7730 -0.0000 -vn 0.4714 -0.8819 -0.0000 -vn 0.2903 -0.9569 -0.0000 -vn 0.0980 -0.9952 -0.0000 -vn -0.0980 -0.9952 -0.0000 -vn -0.2903 -0.9569 -0.0000 -vn -0.4714 -0.8819 -0.0000 -vn -0.6344 -0.7730 -0.0000 -vn -0.7730 -0.6344 -0.0000 -vn -0.8819 -0.4714 -0.0000 -vn -0.9569 -0.2903 -0.0000 -vn -0.9952 -0.0980 -0.0000 -vn -0.9952 0.0980 0.0000 -vn -0.9569 0.2903 0.0000 -vn -0.8819 0.4714 0.0000 -vn -0.7730 0.6344 0.0000 -vn -0.6344 0.7730 0.0000 -vn -0.4714 0.8819 0.0000 -vn 0.0000 0.0000 1.0000 -vn -0.2903 0.9569 0.0000 -vn -0.0980 0.9952 0.0000 -vn -0.0000 0.0000 -1.0000 -vn -0.0002 0.0000 1.0000 -vn 0.0001 0.0000 1.0000 -s off -f 2//1 3//1 1//1 -f 4//2 5//2 3//2 -f 6//3 7//3 5//3 -f 8//4 9//4 7//4 -f 10//5 11//5 9//5 -f 12//6 13//6 11//6 -f 14//7 15//7 13//7 -f 16//8 17//8 15//8 -f 18//9 19//9 17//9 -f 20//10 21//10 19//10 -f 22//11 23//11 21//11 -f 24//12 25//12 23//12 -f 26//13 27//13 25//13 -f 28//14 29//14 27//14 -f 30//15 31//15 29//15 -f 32//16 33//16 31//16 -f 34//17 35//17 33//17 -f 36//18 37//18 35//18 -f 38//19 39//19 37//19 -f 40//20 41//20 39//20 -f 42//21 43//21 41//21 -f 44//22 45//22 43//22 -f 46//23 47//23 45//23 -f 48//24 49//24 47//24 -f 50//25 51//25 49//25 -f 52//26 53//26 51//26 -f 54//27 55//27 53//27 -f 56//28 57//28 55//28 -f 58//29 59//29 57//29 -f 60//30 61//30 59//30 -f 38//31 22//31 6//31 -f 62//32 63//32 61//32 -f 64//33 1//33 63//33 -f 31//34 47//34 63//34 -f 2//1 4//1 3//1 -f 4//2 6//2 5//2 -f 6//3 8//3 7//3 -f 8//4 10//4 9//4 -f 10//5 12//5 11//5 -f 12//6 14//6 13//6 -f 14//7 16//7 15//7 -f 16//8 18//8 17//8 -f 18//9 20//9 19//9 -f 20//10 22//10 21//10 -f 22//11 24//11 23//11 -f 24//12 26//12 25//12 -f 26//13 28//13 27//13 -f 28//14 30//14 29//14 -f 30//15 32//15 31//15 -f 32//16 34//16 33//16 -f 34//17 36//17 35//17 -f 36//18 38//18 37//18 -f 38//19 40//19 39//19 -f 40//20 42//20 41//20 -f 42//21 44//21 43//21 -f 44//22 46//22 45//22 -f 46//23 48//23 47//23 -f 48//24 50//24 49//24 -f 50//25 52//25 51//25 -f 52//26 54//26 53//26 -f 54//27 56//27 55//27 -f 56//28 58//28 57//28 -f 58//29 60//29 59//29 -f 60//30 62//30 61//30 -f 6//31 4//31 2//31 -f 2//31 64//31 6//31 -f 64//31 62//31 6//31 -f 62//31 60//31 58//31 -f 58//31 56//31 62//31 -f 56//31 54//31 62//31 -f 54//35 52//35 50//35 -f 50//31 48//31 54//31 -f 48//31 46//31 54//31 -f 46//31 44//31 42//31 -f 42//31 40//31 38//31 -f 38//31 36//31 34//31 -f 34//31 32//31 30//31 -f 30//31 28//31 22//31 -f 28//36 26//36 22//36 -f 26//31 24//31 22//31 -f 22//35 20//35 18//35 -f 18//31 16//31 22//31 -f 16//31 14//31 22//31 -f 14//31 12//31 10//31 -f 10//31 8//31 14//31 -f 8//31 6//31 14//31 -f 46//31 42//31 54//31 -f 42//31 38//31 54//31 -f 38//31 34//31 22//31 -f 34//31 30//31 22//31 -f 6//31 62//31 54//31 -f 22//31 14//31 6//31 -f 6//31 54//31 38//31 -f 62//32 64//32 63//32 -f 64//33 2//33 1//33 -f 63//34 1//34 3//34 -f 3//34 5//34 7//34 -f 7//34 9//34 15//34 -f 9//34 11//34 15//34 -f 11//34 13//34 15//34 -f 15//34 17//34 19//34 -f 19//34 21//34 15//34 -f 21//34 23//34 15//34 -f 23//34 25//34 31//34 -f 25//34 27//34 31//34 -f 27//34 29//34 31//34 -f 31//34 33//34 35//34 -f 35//34 37//34 39//34 -f 39//34 41//34 43//34 -f 43//34 45//34 47//34 -f 47//34 49//34 51//34 -f 51//34 53//34 47//34 -f 53//34 55//34 47//34 -f 55//34 57//34 59//34 -f 59//34 61//34 63//34 -f 63//34 3//34 15//34 -f 3//34 7//34 15//34 -f 31//34 35//34 39//34 -f 39//34 43//34 47//34 -f 55//34 59//34 47//34 -f 59//34 63//34 47//34 -f 15//34 23//34 63//34 -f 23//34 31//34 63//34 -f 31//34 39//34 47//34 -f 2//1 4//1 65//1 -f 4//2 6//2 65//2 -f 6//3 8//3 65//3 -f 8//4 10//4 65//4 -f 10//5 12//5 65//5 -f 12//6 14//6 65//6 -f 14//7 16//7 65//7 -f 16//8 18//8 65//8 -f 18//9 20//9 65//9 -f 20//10 22//10 65//10 -f 22//11 24//11 65//11 -f 24//12 26//12 65//12 -f 26//13 28//13 65//13 -f 28//14 30//14 65//14 -f 30//15 32//15 65//15 -f 32//16 34//16 65//16 -f 34//17 36//17 65//17 -f 36//18 38//18 65//18 -f 38//19 40//19 65//19 -f 40//20 42//20 65//20 -f 42//21 44//21 65//21 -f 44//22 46//22 65//22 -f 46//23 48//23 65//23 -f 48//24 50//24 65//24 -f 50//25 52//25 65//25 -f 52//26 54//26 65//26 -f 54//27 56//27 65//27 -f 56//28 58//28 65//28 -f 58//29 60//29 65//29 -f 60//30 2//30 65//30 diff --git a/carveracontroller/data/GcodeViewer/tools/ball_end_mill.png b/carveracontroller/data/GcodeViewer/tools/ball_end_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..1e7a917aa0f438333b7829b9a63d584f028111e0 GIT binary patch literal 1194 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NS2ic{vM085o!=JzX3_DsH{K;hh)kDBy6>Ea^XY8WXdyA)}LB z|Mjci=deaBU3J^<$?@%5H@+|D|KKSHB+}#G$u(4SD)=!JGIa<$%wc%MBB0)2!FXg; zi2fn5?)#4FhW$6K8`g%Gx9w$qPy~sRb=!XaH{8v>;peYsw{02p)EajDWuEcZJ>mDu z@B9tkoDaNi@Bc5!$P@86Mwsb=lQGkbpRxu?uOt}@W@<9_RQL+3&l6%0pDBD`g1Bk! zElWlpqi26MGf8Z@W~s(%pxP)I{Le(YfzxeneH_E#YrFSnGQOF2;NIoG$M!Ik#eLd0 z`R~Oe3}vxj<^}IfN@K9rtKQ%F@8lJRvgjXim-igJ!%!CW%Wm?Xn@@|Cv5}RDnYMv}m4SidThSyG4Y~O#nQ4`1 z8Vt;>j7%UJY*sE5JR)z4*}Q$iB} Dn+}lu literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill.png b/carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..6a10410c28535f76f0878d8242163c9801853401 GIT binary patch literal 1073 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NS2ic{vM085o!uJY5_^DsH{KW*FpbD8TAi+x1(1#t{~g2{$-X zr*HB3&N(kU`S90`d}X(7A9$|2%Pd!Y+qPjZi-3BA1>+G;1wV#DrVe3;ISh|Rg@#B- z%#}T`wfeyS|03z^2Tp@xaDCYq`G(KT7Jq6!&y{1)FRNqNT+iGWUthww`bF*c2K$}YqPE{vewQPak;afcSLEP@<^PS$8@AT@@7Hd*=>I>p zjN$&jgU)Y^KF)WT=Rv literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/flat_end_mill.png b/carveracontroller/data/GcodeViewer/tools/flat_end_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..8f42e331778da993ff959a590738e2a675fe05c3 GIT binary patch literal 963 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D1k^Oi)5S5Q;?~JWCA!|;ejKz&qb7>2|hGusE( zX32f1m7{ND?-0InocZtM8&-zE1gl!&8c~vxSdwa$T$Bo=7>o>z%ybRRbq!5IjEt>} zjjT+}v<(cb3=ACKiYB3G$jwj5OshoGU|?otXavz9Bj$Jss6hj6LrG?CYH>+oZULGe aV-uk95Iwz$$J>B<7(8A5T-G@yGywqbbqa(4 literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/lollipop_mill.png b/carveracontroller/data/GcodeViewer/tools/lollipop_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..20d5e15d849b5cfc8f1c4f0319ba7b31a306ab3f GIT binary patch literal 1319 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D#K6G(&C|s(q~g}wy9e{490gb}s(t!jUto5QY2k@U zs?CWrs+X^-JK+1h@_fbQn1AOOYx92XoPJmS&(D8v~UOMRo&!{8L=4No~4 z<}p0LO(fJ_{6C|_tl`Dgxq)U3(J-}3nP2>ulK97YiSfoG76yHJhacKoYJb%*Y%^gz zkj)_QUn+Or9>xaUHOvkNCttBDWoL*E<8J6$zOwL<7{j&|atx~eA-A{KGURyrGGxtL zwFv0REg>cU%osvfzg@xYz})zUbN>}Kh1!ERFV_akH#~WD?mp*&g0nkKnLJb{SYG8X zW%7tAyXR7Vl}jP_VdQ0-0R4s~OP~9EDmcqvBv#)!eu&+$!ejv-`XCGGokc*-vpC4TtY1 zG3;Qqdb4-#*YpLpbMS>I{_rLsd(Ylg-av+HQcg3lP*5##jVMV;EJ?LWE=mPb3`Pb< zX1WIEx`rkpM#fggMph=~+6D$z1_sY($z4Oykei>9nO2FW!NAhW#0a8c>0c3Rpau=N m4JDbmsl_FUxdmu?j7@;XL-h129&ZEcVeoYIb6Mw<&;$VII?lrY literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/pointed_mill.png b/carveracontroller/data/GcodeViewer/tools/pointed_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..21fe35ee3ca9de3f350379e061c26e48a5688515 GIT binary patch literal 1224 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D#K6Ej-P6S}q~g}wE8cw~jsmO)<&OO2Kf`9Gz?d{6 z{(FeqjNhD#KFxgf^7h*Y`{HX4%&pq>tKs?YqOXjlxr_(68R8f|Fg1uX>|uDo%An6s zF)Bp+keJK+;N>gkZ}mrSGVs;!;f*h_YIrPP@ayYyW{D3SllA8_Bph+}+grufpxAHu z@sTFOF`E}#vY#_Zd|A<~C(D{}>hQT8pVBuo_*C5atp8_mCWBx7gU#!IyMJbw^XJ6# zxNkYajB|cnNRRvKWXw3{$BpN)Usf$+vUq#&{H|xbXITp_EuLR|a`tSV2UFVZA9t0T zNgv?sum8&`pJmmsnq9)~KN~}MpF!O}S%!5|NeBN#GsGAk>-zbf;l~@tX=nCx9!T%o zl=d%{!7h7->*svt50a19%&M1faOdBW^RJgd&hpZ(pXE#yR|2@7-{*QDn7npQy?#SA z|F)8UXBpmE-n#X(oO#Ffg6`+{`5wqUUOTVezM-FQM@=2$0e80;`~8d$_Bu0t)@Hb8 ztY)~M`N7&|rO)0B_l&fR_p?6Odf4f6Hbb1Tp6Pz}2TL0_{&Z#dFFkYieU=Y*E`g?7jOQ2o1u=E|9t)K+P%LTx)&ecfA@>M1FHkwl6W1%s*^17 zH{PFi0OnfN64!{5l*E!$tK_0oAjM#0U}UCiV6JOu5@KX*Wo%?+VyXgowuuj27GpdJQK LS3j3^P6a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NUO?)A!jXGcYjwdAc};RNQ)d$2w2iQH1s4vWI{5Z*o>#Je8vOZ3~>w}m>R?x_AoqP zWzc7+7!{&-NPMq;&s=l!<)io8_wtuK-Wk8+I$OcbpUt(Q9PCp6?rdb3bKCAkcv8WE zm)rX|6JDE2$dvtBtIT}EYVBVEnVLUa)fghO%a5;It;!a9Q@h>2OC7#SFu=^B{p8k&R{8Cw~fS(%z?8yHv_7__X}+J>SbH$Npa ztrAUxfrXW^0Yt;~)O1sz1`W6kC7HRY#U+Wk1!#JV&8L7(8A5T-G@y GGywnxZheIS literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/thread_mill.png b/carveracontroller/data/GcodeViewer/tools/thread_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..34cc00cafa69573fd809992925da5c79963d8d85 GIT binary patch literal 1316 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D#K6G(+0(@_q~g}wJKjOkjsgw`Cm#N8zrnoX;Gu{7 z5-q!SJL!LBxqLOBOGj|u-yLk#mVX)ei>&`L@bJn5sQF&g9YOe zP6fYFAsUB-xn;xj%lrWrC%<3j|Il_&dG~Ld?U(sK>KmIM*c|)+LGanz49ds99N5fz zoB6WY0ps}pCxrcOF&uW={AEt^w*zx{19tvPTt0UrE;f9f5pqrJ+zbe!KZr59qfL&4A=iJcNVtX$Qbi)zwAxs-{uXk>(76C z`Q|Qz-v9q*?;GbzANX2-<(TK&TR?&0ZEqWGfdcoFPhYu~&oI4yKW}xySGIz`@mnjJ zw9Ok%*Y_-~PPhvc=--kvE87exu*bDJ;V4jGwa$z;E%qD_7l_(3lkf-~9CH&Cm1& zwjU~It8IH<%)nW5=a_ifb9TpX2ae~=z4XqXN%h0NxB4gl^*6n3+%7xg%*^*pDj&8x z>mOUG-~6WWzU=H{C-a$AKfHQzy5QUEgz5)BvJ3vbXFSEpQ^9zS-5`ml{haNA7KU}% zCk(dDD?ib>oW&qRCHkDzu{l7oD+yxr3a@CUvl`^taGx_jvjr&jV1iuPx<>Wc5(h2> z*8cQSKFjl9*D<~~H~or#*>}~Pzp>DE@=oanT{>nUd&ZY4=4MHfnTfy>LAAs+q9i4; zB-JXpC>2OC7#SFu=^B{p8k&R{8Cw|}S(%t?8yHv_7(AaPcMU~DZhlH;S|yqW14}Cd xBZvmY?NSGU8Z_WGlw{_n7MCRE7NF@dHUSzB(bKDVybY*_!PC{xWt~$(69DC;-7f$D literal 0 HcmV?d00001 diff --git a/carveracontroller/main.py b/carveracontroller/main.py index be17e511..f4fedd59 100644 --- a/carveracontroller/main.py +++ b/carveracontroller/main.py @@ -83,7 +83,14 @@ def is_ios(): from kivy.factory import Factory from kivy.graphics import Color, Ellipse, Line, PopMatrix, PushMatrix, Rectangle, Rotate, Translate from kivy.metrics import Metrics, dp -from kivy.properties import BooleanProperty, ListProperty, NumericProperty, ObjectProperty, StringProperty +from kivy.properties import ( + BooleanProperty, + DictProperty, + ListProperty, + NumericProperty, + ObjectProperty, + StringProperty, +) from kivy.uix.behaviors import FocusBehavior from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button @@ -188,6 +195,7 @@ def ios_webbrowser_open(url, new=None): from . import Utils, custom_widgets from .__version__ import __version__ from .addons.probing.ProbingControls import ProbeButton +from .addons.tool_visualization import extract_tool_table, format_tool_tooltip, get_tool_icon_path from .addons.tooltips.Tooltips import Tooltip, ToolTipButton, ToolTipDropDown from .CNC import ( CNC, @@ -2918,6 +2926,9 @@ class Makera(RelativeLayout): upcoming_tool = 0 file_has_ocodes = False tool_change_markers = [] + tool_table = {} + tool_icons = DictProperty({}) + show_tool_button_icons = BooleanProperty(False) # Custom property to monitor CNC light state light_state = LightProperty(False) @@ -3095,6 +3106,12 @@ def __init__(self, ctl_version): self.gcode_viewer.time_estimate_progress_callback = self._on_time_estimate_progress self.float_layout.tool_bar.show_grid = self.gcode_viewer.is_grid_visible() + # Handle tool button icons visibility when the window is resized + self.bind(show_tool_button_icons=self._refresh_tool_filter_buttons) + self.float_layout.tool_bar.bind(width=self._update_tool_button_icon_visibility) + Window.bind(on_resize=self._update_tool_button_icon_visibility) + Clock.schedule_once(lambda _dt: self._refresh_tool_filter_buttons(), 0) + # init settings self.config = ConfigParser() self.config_popup = ConfigPopup() @@ -6941,6 +6958,9 @@ def clear_selection(self): self.wpb_play.value = 0 self.used_tools = [] self.upcoming_tool = 0 + self.tool_table = {} + self.gcode_viewer.tool_table = {} + self._refresh_tool_filter_buttons() self._clear_tool_change_markers() app = App.get_running_app() app.curr_page = 1 @@ -7133,6 +7153,8 @@ def load_gcode_file(self, filepath): self.file_has_ocodes = False self.used_tools = [] self.tool_change_markers = [] + self.tool_table = {} + self.gcode_viewer.tool_table = {} Clock.schedule_once(self.load_start) f = None try: @@ -7157,6 +7179,9 @@ def load_gcode_file(self, filepath): self.lines = f.readlines() self.selected_file_line_count = len(self.lines) f.close() + self.tool_table = extract_tool_table(self.lines) + self.gcode_viewer.tool_table = self.tool_table + self._refresh_tool_filter_buttons() app = App.get_running_app() app.total_pages = int(self.selected_file_line_count / MAX_LOAD_LINES) + ( 0 if self.selected_file_line_count % MAX_LOAD_LINES == 0 else 1 @@ -7224,6 +7249,39 @@ def load_gcode_file(self, filepath): Clock.schedule_once(self.load_end, 0) + # ----------------------------------------------------------------------- + def _update_tool_button_icon_visibility(self, *_args): + tool_bar = self.float_layout.tool_bar + tool_bar_icons_required_width = dp(438 + 6 * 58) + if tool_bar.width <= 0: + return + has_parsed_tools = bool(self.tool_table) + show_icons = has_parsed_tools and tool_bar.width >= tool_bar_icons_required_width + if show_icons != self.show_tool_button_icons: + self.show_tool_button_icons = show_icons + + @mainthread + def _refresh_tool_filter_buttons(self, *_args): + """Update T1..T6 toolbar icons and tooltips from the current tool table.""" + self.tool_icons = {number: get_tool_icon_path(tool_def) for number, tool_def in self.tool_table.items()} + self._update_tool_button_icon_visibility() + default_icon = get_tool_icon_path(None) + tool_buttons = [ + self.float_layout.t1, + self.float_layout.t2, + self.float_layout.t3, + self.float_layout.t4, + self.float_layout.t5, + self.float_layout.t6, + ] + for number, tool_button in enumerate(tool_buttons, start=1): + if self.show_tool_button_icons: + tool_button.icon = self.tool_icons.get(number, default_icon) + else: + tool_button.icon = "" + tool_def = self.tool_table.get(number) + tool_button.tooltip_txt = format_tool_tooltip(tool_def) if tool_def else "" + # ----------------------------------------------------------------------- def init_tool_filter(self): tool_buttons = [ diff --git a/carveracontroller/makera.kv b/carveracontroller/makera.kv index d00ff6d7..5f145542 100644 --- a/carveracontroller/makera.kv +++ b/carveracontroller/makera.kv @@ -91,6 +91,9 @@ width: '60dp' icon_size: 24 icon: '' + # 'center' (default): icon centered behind the text, like the existing icon-only buttons. + # 'left': icon placed to the left of the text, side by side (used by the tool buttons). + icon_align: 'center' text: '' min_icon: '' min_icon_size: 12 @@ -102,16 +105,16 @@ disabled_color: 0, 0, 0, 0 Label: text: root.text if root.text else '' - halign: 'center' - valign: 'top' if root.min_icon else 'middle' - text_size: self.width, self.height - dp(root.min_icon_size + 12) if root.min_icon else None + halign: 'right' if root.icon_align == 'left' and root.icon else 'center' + valign: 'middle' if root.icon_align == 'left' else ('top' if root.min_icon else 'middle') + text_size: (self.width - dp(root.icon_size + 8), self.height - dp(root.min_icon_size + 8) if root.min_icon else self.height) if root.icon_align == 'left' and root.icon else (self.width, self.height - dp(root.min_icon_size + 12) if root.min_icon else None) color: tuple(app.active_color) if (root.active and not root.disabled) else ((110/255, 110/255, 110/255, 1) if root.disabled else (250/255, 250/255, 250/255, 1)) canvas.before: Color: rgba: tuple(app.active_color) if (root.active and not root.disabled) else ((110/255, 110/255, 110/255, 1) if root.disabled else (250/255, 250/255, 250/255, 1)) Rectangle: source: root.icon - pos: self.center_x - dp(root.icon_size / 2), self.center_y - dp(root.icon_size / 2) + pos: (self.x + dp(4), self.center_y - dp(root.icon_size / 2)) if root.icon_align == 'left' else (self.center_x - dp(root.icon_size / 2), self.center_y - dp(root.icon_size / 2)) size: dp(root.icon_size) if root.icon else 0, dp(root.icon_size) if root.icon else 0 Color: rgba: (250/255, 250/255, 250/255, 1) if root.min_active else (60/255, 60/255, 60/255, 1) @@ -4260,9 +4263,12 @@ # tools GcodeViewerToolBarButton: id: t1 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T1' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 1 disabled: 1 not in root.used_tools min_icon: 'data/eye.png' @@ -4271,9 +4277,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t2 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T2' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 2 disabled: 2 not in root.used_tools min_icon: 'data/eye.png' @@ -4282,9 +4291,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t3 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T3' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 3 disabled: 3 not in root.used_tools min_icon: 'data/eye.png' @@ -4293,9 +4305,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t4 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T4' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 4 disabled: 4 not in root.used_tools min_icon: 'data/eye.png' @@ -4304,9 +4319,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t5 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T5' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 5 disabled: 5 not in root.used_tools min_icon: 'data/eye.png' @@ -4315,9 +4333,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t6 - width: '44dp' + width: '58dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T6' + icon: '' + icon_align: 'left' + icon_size: 20 active: app.tool == 6 disabled: 6 not in root.used_tools min_icon: 'data/eye.png' diff --git a/carveracontroller/pointer2.obj b/carveracontroller/pointer2.obj deleted file mode 100755 index d0bd459f..00000000 --- a/carveracontroller/pointer2.obj +++ /dev/null @@ -1,103 +0,0 @@ -# Blender v2.80 (sub 75) OBJ File: '' -# www.blender.org -o Cone -v -0.357218 0.000000 2.000000 -v -0.350355 0.069690 2.000000 -v -0.330027 0.136702 2.000000 -v -0.297016 0.198460 2.000000 -v -0.252592 0.252591 2.000000 -v -0.198460 0.297016 2.000000 -v -0.136702 0.330027 2.000000 -v -0.069690 0.350354 2.000000 -v -0.000000 0.357218 2.000000 -v 0.069690 0.350354 2.000000 -v 0.136701 0.330027 2.000000 -v 0.198460 0.297016 2.000000 -v 0.252591 0.252591 2.000000 -v 0.297016 0.198460 2.000000 -v 0.330026 0.136701 2.000000 -v 0.350354 0.069690 2.000000 -v 0.357218 -0.000000 2.000000 -v 0.350354 -0.069690 2.000000 -v 0.330026 -0.136702 2.000000 -v 0.297016 -0.198460 2.000000 -v 0.252591 -0.252591 2.000000 -v 0.198459 -0.297016 2.000000 -v 0.136701 -0.330027 2.000000 -v 0.000000 0.000000 0.000000 -v 0.069689 -0.350354 2.000000 -v -0.000001 -0.357218 2.000000 -v -0.069690 -0.350354 2.000000 -v -0.136702 -0.330026 2.000000 -v -0.198460 -0.297016 2.000000 -v -0.252592 -0.252591 2.000000 -v -0.297017 -0.198459 2.000000 -v -0.330027 -0.136701 2.000000 -v -0.350355 -0.069689 2.000000 -vn -0.9798 0.0965 -0.1750 -vn -0.9422 0.2858 -0.1750 -vn -0.8683 0.4641 -0.1750 -vn -0.7611 0.6246 -0.1750 -vn -0.6246 0.7611 -0.1750 -vn -0.4641 0.8683 -0.1750 -vn -0.2858 0.9422 -0.1750 -vn -0.0965 0.9798 -0.1750 -vn 0.0965 0.9798 -0.1750 -vn 0.2858 0.9422 -0.1750 -vn 0.4641 0.8683 -0.1750 -vn 0.6246 0.7611 -0.1750 -vn 0.7611 0.6246 -0.1750 -vn 0.8683 0.4641 -0.1750 -vn 0.9422 0.2858 -0.1750 -vn 0.9798 0.0965 -0.1750 -vn 0.9798 -0.0965 -0.1750 -vn 0.9422 -0.2858 -0.1750 -vn 0.8683 -0.4641 -0.1750 -vn 0.7611 -0.6246 -0.1750 -vn 0.6246 -0.7611 -0.1750 -vn 0.4641 -0.8683 -0.1750 -vn 0.2858 -0.9422 -0.1750 -vn 0.0965 -0.9798 -0.1750 -vn -0.0965 -0.9798 -0.1750 -vn -0.2858 -0.9422 -0.1750 -vn -0.4641 -0.8683 -0.1750 -vn -0.6246 -0.7611 -0.1750 -vn -0.7611 -0.6246 -0.1750 -vn -0.8683 -0.4641 -0.1750 -vn -0.9422 -0.2858 -0.1750 -vn -0.9798 -0.0965 -0.1750 -vn -0.0000 0.0000 1.0000 -s off -f 1//1 2//1 24//1 -f 2//2 3//2 24//2 -f 3//3 4//3 24//3 -f 4//4 5//4 24//4 -f 5//5 6//5 24//5 -f 6//6 7//6 24//6 -f 7//7 8//7 24//7 -f 8//8 9//8 24//8 -f 9//9 10//9 24//9 -f 10//10 11//10 24//10 -f 11//11 12//11 24//11 -f 12//12 13//12 24//12 -f 13//13 14//13 24//13 -f 14//14 15//14 24//14 -f 15//15 16//15 24//15 -f 16//16 17//16 24//16 -f 17//17 18//17 24//17 -f 18//18 19//18 24//18 -f 19//19 20//19 24//19 -f 20//20 21//20 24//20 -f 21//21 22//21 24//21 -f 22//22 23//22 24//22 -f 23//23 25//23 24//23 -f 25//24 26//24 24//24 -f 26//25 27//25 24//25 -f 27//26 28//26 24//26 -f 28//27 29//27 24//27 -f 29//28 30//28 24//28 -f 30//29 31//29 24//29 -f 31//30 32//30 24//30 -f 32//31 33//31 24//31 -f 33//32 1//32 24//32 -f 1//33 33//33 32//33 31//33 30//33 29//33 28//33 27//33 26//33 25//33 23//33 22//33 21//33 20//33 19//33 18//33 17//33 16//33 15//33 14//33 13//33 12//33 11//33 10//33 9//33 8//33 7//33 6//33 5//33 4//33 3//33 2//33 diff --git a/carveracontroller/shaders/tool_pointer.glsl b/carveracontroller/shaders/tool_pointer.glsl index 689432cb..78aa8ebb 100644 --- a/carveracontroller/shaders/tool_pointer.glsl +++ b/carveracontroller/shaders/tool_pointer.glsl @@ -1,4 +1,4 @@ -// Tool position pointer mesh (pointer.obj) with simple diffuse shading +// Tool position pointer mesh with simple diffuse shading ---vertex $HEADER$ diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py new file mode 100644 index 00000000..82275705 --- /dev/null +++ b/tests/unit/test_tool_visualization.py @@ -0,0 +1,366 @@ +"""Tests for CAM tool metadata extraction and procedural tool mesh generation.""" + +import math + +import pytest + +from carveracontroller.addons.tool_visualization import ( + ToolDefinition, + ToolType, + extract_tool_table, + format_tool_tooltip, + get_tool_icon_path, +) +from carveracontroller.addons.tool_visualization.mesh_builder import ( + FALLBACK_TOOL_DISPLAY_HEIGHT, + FALLBACK_TOOL_DISPLAY_RADIUS, + LENGTH_DIAMETER_FACTOR, + MIN_VISIBLE_RADIUS, + VERTEX_FORMAT, + _reference_length, + build_tool_mesh, + build_tool_meshes, + tool_profile, +) +from carveracontroller.addons.tool_visualization.parsers.fusion360_makera import ( + TOOL_TYPE_NAME_MAP, + Fusion360MakeraParser, +) +from carveracontroller.addons.tool_visualization.tool_definition import resolve_tool_type + + +def _max_xy_radius(vertices): + radii = [] + for i in range(0, len(vertices), 8): + x = vertices[i] + y = vertices[i + 1] + radii.append(math.hypot(x, y)) + return max(radii) if radii else 0.0 + + +def _mesh_height(vertices): + zs = [vertices[i + 2] for i in range(0, len(vertices), 8)] + return max(zs) - min(zs) if zs else 0.0 + + +def _apex_vertex_indices(vertices, tol=1e-6): + zs = [vertices[i + 2] for i in range(0, len(vertices), 8)] + z_min = min(zs) + return [ + i // 8 + for i in range(0, len(vertices), 8) + if abs(vertices[i + 2] - z_min) < tol and math.hypot(vertices[i], vertices[i + 1]) < tol + ] + + +class TestFusion360MakeraParser: + @pytest.fixture + def parser(self): + return Fusion360MakeraParser() + + def test_parses_basic_flat_end_mill_comment(self, parser): + lines = ["(T1 Flat end mill Vendor PID D=6 CR=0 - flat end mill)\n", "G0 X0\n"] + table = parser.parse(lines) + + assert table[1].number == 1 + assert table[1].tool_type == ToolType.FLAT_END_MILL + assert table[1].diameter == 6.0 + assert table[1].corner_radius == 0.0 + assert table[1].description == "Flat end mill" + assert table[1].vendor == "Vendor" + assert table[1].product_id == "PID" + + def test_parses_optional_taper_and_ignored_zmin(self, parser): + lines = ["(T2 Bull tool D=3.175 CR=0.5 TAPER=45deg - ZMIN=-5 - bull nose end mill)\n"] + table = parser.parse(lines) + + assert table[2].tool_type == ToolType.BULL_NOSE_END_MILL + assert table[2].taper_angle_deg == 45.0 + + def test_parses_semicolon_comments(self, parser): + lines = [";T3 Thread cutter D=4 CR=0 - thread mill\n"] + table = parser.parse(lines) + + assert table[3].tool_type == ToolType.THREAD_MILL + + def test_ignores_duplicate_tool_entries(self, parser): + lines = [ + "(T1 First D=6 CR=0 - flat end mill)\n", + "(T1 Second D=8 CR=0 - ball end mill)\n", + ] + table = parser.parse(lines) + + assert table[1].diameter == 6.0 + assert table[1].tool_type == ToolType.FLAT_END_MILL + + def test_unknown_tool_type_falls_back_to_unknown(self, parser): + lines = ["(T4 Mystery D=6 CR=0 - mystery cutter)\n"] + table = parser.parse(lines) + + assert table[4].tool_type == ToolType.UNKNOWN + assert table[4].type_name == "mystery cutter" + + +class TestToolDefinitionHelpers: + def test_resolve_tool_type_normalises_names(self): + assert resolve_tool_type(" Flat End Mill ", TOOL_TYPE_NAME_MAP) == ToolType.FLAT_END_MILL + assert resolve_tool_type("", TOOL_TYPE_NAME_MAP) == ToolType.UNKNOWN + + +class TestIconBuilder: + def test_default_icon_for_missing_tool(self): + assert get_tool_icon_path(None) == "data/GcodeViewer/tools/pointed_mill.png" + + def test_maps_known_tool_types(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL) + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/ball_end_mill.png" + + +class TestTooltipBuilder: + def test_empty_tooltip_for_missing_tool(self): + assert format_tool_tooltip(None) == "" + + def test_formats_full_tool_definition(self): + tool_def = ToolDefinition( + number=2, + tool_type=ToolType.BULL_NOSE_END_MILL, + diameter=6.0, + corner_radius=0.5, + taper_angle_deg=5.0, + description="Roughing endmill", + vendor="Makera", + product_id="EM-6-05", + type_name="Bull nose end mill", + ) + tooltip = format_tool_tooltip(tool_def) + + assert tooltip == ("T2 - Bull nose end mill\nD=6 CR=0.5 TAPER=5°\nRoughing endmill\nMakera - EM-6-05") + + def test_uses_enum_label_when_type_name_missing(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0) + assert format_tool_tooltip(tool_def) == "T1 - Flat End Mill\nD=3" + + +def _vertex_normal(vertices, index): + base = index * 8 + return (vertices[base + 3], vertices[base + 4], vertices[base + 5]) + + +class TestMeshBuilder: + def test_build_tool_mesh_uses_expected_vertex_layout(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0) + vertices, indices, fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // 8 + + assert fmt == VERTEX_FORMAT + assert len(vertices) % 8 == 0 + assert len(indices) % 3 == 0 + assert all(0 <= index < vertex_count for index in indices) + assert len(indices) > vertex_count + + def test_shared_reference_length_uses_largest_diameter(self): + tool_table = { + 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0), + 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=10.0), + } + shared_length = _reference_length(tool_table, scale=1.0) + + assert shared_length == 10.0 * LENGTH_DIAMETER_FACTOR + profile_small = tool_profile(tool_table[1], length=shared_length, scale=1.0) + profile_large = tool_profile(tool_table[2], length=shared_length, scale=1.0) + assert profile_small[-1][0] == profile_large[-1][0] + + def test_radius_boost_preserves_relative_sizes(self): + tool_table = { + 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=0.01), + 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=1.0), + } + meshes, _ = build_tool_meshes(tool_table, scale=0.01) + small_radius = _max_xy_radius(meshes[1][0]) + large_radius = _max_xy_radius(meshes[2][0]) + + assert small_radius >= MIN_VISIBLE_RADIUS + assert large_radius > small_radius + assert math.isclose(large_radius / small_radius, 100.0, rel_tol=1e-6) + + def test_default_mesh_unaffected_by_radius_boost(self): + """Default mesh keeps fixed on-screen size when known tools need boost.""" + tool_table = { + 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=0.01), + 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=1.0), + } + _meshes, default_mesh = build_tool_meshes(tool_table, scale=0.01) + vertices = default_mesh[0] + + assert _max_xy_radius(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_RADIUS, rel=1e-4) + assert _mesh_height(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_HEIGHT, rel=1e-4) + + def test_default_mesh_is_generated_for_empty_tool_table(self): + meshes, default_mesh = build_tool_meshes({}) + + assert meshes == {} + assert len(default_mesh[0]) > 0 + assert len(default_mesh[1]) > 0 + + @pytest.mark.parametrize("scale", [0.02, 0.5, 1.0, 2.0]) + def test_fallback_mesh_has_fixed_display_size(self, scale): + """No-metadata fallback keeps a constant on-screen footprint.""" + _meshes, default_mesh = build_tool_meshes({}, scale=scale) + vertices = default_mesh[0] + + assert _max_xy_radius(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_RADIUS, rel=1e-4) + assert _mesh_height(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_HEIGHT, rel=1e-4) + + @pytest.mark.parametrize("scale", [0.02, 0.5]) + def test_missing_diameter_uses_fixed_display_size(self, scale): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=None) + meshes, _ = build_tool_meshes({1: tool_def}, scale=scale) + vertices = meshes[1][0] + + assert _max_xy_radius(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_RADIUS, rel=1e-4) + assert _mesh_height(vertices) == pytest.approx(FALLBACK_TOOL_DISPLAY_HEIGHT, rel=1e-4) + + def test_ball_end_mill_profile_has_more_detail_than_flat_end_mill(self): + shared_length = 18.0 + flat_profile = tool_profile( + ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0), + length=shared_length, + ) + ball_profile = tool_profile( + ToolDefinition(number=2, tool_type=ToolType.BALL_END_MILL, diameter=6.0), + length=shared_length, + ) + + assert flat_profile[0] == (0.0, 3.0) + assert ball_profile[0][0] == pytest.approx(0.0) + assert ball_profile[0][1] == pytest.approx(0.0) + assert ball_profile[-1][0] == flat_profile[-1][0] + assert len(ball_profile) > len(flat_profile) + + def test_build_tool_meshes_scales_geometry(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0) + mesh_a, _ = build_tool_meshes({1: tool_def}, scale=1.0) + mesh_b, _ = build_tool_meshes({1: tool_def}, scale=2.0) + + assert _mesh_height(mesh_b[1][0]) == pytest.approx(_mesh_height(mesh_a[1][0]) * 2.0) + + def test_flat_end_mill_side_normals_are_radial(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0) + vertices, indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // 8 + + assert vertex_count < len(indices) + + for index in range(vertex_count): + nx, ny, nz = _vertex_normal(vertices, index) + length = math.hypot(nx, ny, nz) + assert length == pytest.approx(1.0, abs=1e-6) + if abs(nz) < 0.5: + assert abs(nz) == pytest.approx(0.0, abs=1e-6) + assert math.hypot(nx, ny) == pytest.approx(1.0, abs=1e-6) + + def test_ball_end_mill_reuses_vertices_across_triangles(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL, diameter=6.0) + vertices, indices, _fmt = build_tool_mesh(tool_def) + + assert len(indices) > len(vertices) // 8 + + def test_pointed_tip_mesh_shares_single_apex_vertex(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.CHAMFER_MILL, diameter=6.0) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + + assert len(_apex_vertex_indices(vertices)) == 1 + + @pytest.mark.parametrize( + "tool_type", + [ + ToolType.BULL_NOSE_END_MILL, + ToolType.RADIUS_MILL, + ToolType.CHAMFER_MILL, + ToolType.TAPERED_MILL, + ToolType.LOLLIPOP_MILL, + ToolType.THREAD_MILL, + ], + ) + def test_tool_profiles_have_expected_shape(self, tool_type): + diameter = 6.0 + shared_length = diameter * LENGTH_DIAMETER_FACTOR + profile = tool_profile( + ToolDefinition(number=1, tool_type=tool_type, diameter=diameter, corner_radius=0.5), + length=shared_length, + ) + + assert profile[-1][0] == shared_length + + if tool_type == ToolType.BULL_NOSE_END_MILL: + assert profile[0][1] < diameter / 2.0 + assert len(profile) > 2 + elif tool_type == ToolType.RADIUS_MILL: + corner_radius = 0.5 + assert profile[0] == (0.0, pytest.approx(diameter / 2.0)) + assert profile[-1][1] == pytest.approx(diameter / 2.0 + corner_radius) + assert len(profile) > 2 + elif tool_type in (ToolType.CHAMFER_MILL, ToolType.TAPERED_MILL): + assert profile[0] == (0.0, 0.0) + assert len(profile) >= 2 + elif tool_type == ToolType.LOLLIPOP_MILL: + assert len(profile) > 4 + assert profile[-1][1] < diameter / 2.0 + elif tool_type == ToolType.THREAD_MILL: + assert profile[0][1] < diameter / 2.0 + assert max(r for _, r in profile) == pytest.approx(diameter / 2.0) + assert len(profile) >= 3 + + def test_radius_mill_interprets_diameter_as_flat_bottom(self): + profile = tool_profile( + ToolDefinition(number=2, tool_type=ToolType.RADIUS_MILL, diameter=2.0, corner_radius=2.0), + length=20.0, + ) + + assert profile[0] == (0.0, 1.0) + assert profile[-1][1] == pytest.approx(3.0) + + def test_radius_mill_corner_arc_is_reversed_from_bull_nose(self): + flat_diameter = 4.0 + full_diameter = 6.0 + corner_radius = 1.0 + shared_length = full_diameter * LENGTH_DIAMETER_FACTOR + radius_profile = tool_profile( + ToolDefinition( + number=1, tool_type=ToolType.RADIUS_MILL, diameter=flat_diameter, corner_radius=corner_radius + ), + length=shared_length, + ) + bull_profile = tool_profile( + ToolDefinition( + number=2, tool_type=ToolType.BULL_NOSE_END_MILL, diameter=full_diameter, corner_radius=corner_radius + ), + length=shared_length, + ) + + assert radius_profile[0] == bull_profile[0] + assert radius_profile[-1] == bull_profile[-1] + + mid_z = corner_radius / 2.0 + full_radius = full_diameter / 2.0 + radius_mid_r = full_radius + corner_radius * math.cos(5.0 * math.pi / 6.0) + bull_mid_r = (full_radius - corner_radius) + corner_radius * math.cos(-math.pi / 6.0) + profile_radius_mid_r = min(radius_profile, key=lambda point: abs(point[0] - mid_z))[1] + profile_bull_mid_r = min(bull_profile, key=lambda point: abs(point[0] - mid_z))[1] + + assert profile_radius_mid_r == pytest.approx(radius_mid_r, abs=0.05) + assert profile_bull_mid_r == pytest.approx(bull_mid_r, abs=0.05) + assert profile_radius_mid_r < profile_bull_mid_r + + +class TestExtractor: + def test_extract_tool_table_returns_first_non_empty_parser_result(self): + lines = ["(T1 End mill D=6 CR=0 - flat end mill)\n", "G0 X0\n"] + table = extract_tool_table(lines) + + assert 1 in table + assert table[1].tool_type == ToolType.FLAT_END_MILL + + def test_extract_tool_table_returns_empty_dict_when_unrecognised(self): + lines = ["G0 X0 Y0\n", "G1 X1 F100\n"] + assert extract_tool_table(lines) == {} From 4059ea3df986f6be453e9da600b8aa1a64dd5958 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:04:30 +0200 Subject: [PATCH 02/11] Add tool description in tool change modal + add/fix tapered/lollipop mills --- .../addons/tool_visualization/icon_builder.py | 2 +- .../addons/tool_visualization/mesh_builder.py | 70 ++++++++++-- .../data/GcodeViewer/tools/tapered_mill.png | Bin 0 -> 1214 bytes carveracontroller/main.py | 29 +++-- carveracontroller/makera.kv | 9 +- tests/unit/test_tool_visualization.py | 107 +++++++++++++++++- 6 files changed, 193 insertions(+), 24 deletions(-) create mode 100644 carveracontroller/data/GcodeViewer/tools/tapered_mill.png diff --git a/carveracontroller/addons/tool_visualization/icon_builder.py b/carveracontroller/addons/tool_visualization/icon_builder.py index ffe0b247..5b4d7130 100644 --- a/carveracontroller/addons/tool_visualization/icon_builder.py +++ b/carveracontroller/addons/tool_visualization/icon_builder.py @@ -10,7 +10,7 @@ ToolType.BULL_NOSE_END_MILL: f"{TOOLS_ICON_DIR}/bull_nose_end_mill.png", ToolType.RADIUS_MILL: f"{TOOLS_ICON_DIR}/radius_mill.png", ToolType.CHAMFER_MILL: DEFAULT_ICON, - ToolType.TAPERED_MILL: DEFAULT_ICON, + ToolType.TAPERED_MILL: f"{TOOLS_ICON_DIR}/tapered_mill.png", ToolType.LOLLIPOP_MILL: f"{TOOLS_ICON_DIR}/lollipop_mill.png", ToolType.THREAD_MILL: f"{TOOLS_ICON_DIR}/thread_mill.png", ToolType.UNKNOWN: DEFAULT_ICON, diff --git a/carveracontroller/addons/tool_visualization/mesh_builder.py b/carveracontroller/addons/tool_visualization/mesh_builder.py index 47cf3093..e2178d39 100644 --- a/carveracontroller/addons/tool_visualization/mesh_builder.py +++ b/carveracontroller/addons/tool_visualization/mesh_builder.py @@ -224,7 +224,7 @@ def _safe_corner_radius(tool_def, diameter, tool_type=None): def _safe_taper_angle_deg(tool_def): angle = getattr(tool_def, "taper_angle_deg", None) if tool_def else None - if not angle or angle <= 0 or angle >= 180: + if angle is None or angle < 0 or angle >= 180: return DEFAULT_TAPER_ANGLE_DEG return angle @@ -327,6 +327,7 @@ def _radius_mill_profile(diameter, length, corner_radius=0.0, **_kwargs): def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, **_kwargs): + """Pointed conical profile used for chamfer mills (and as the generic fallback).""" radius = diameter / 2.0 half_angle_rad = math.radians(taper_angle_deg) / 2.0 half_angle_rad = min(max(half_angle_rad, math.radians(5.0)), math.radians(85.0)) @@ -338,21 +339,72 @@ def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ return points +def _tapered_mill_profile(diameter, length, corner_radius=0.0, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, **_kwargs): + """Bull-nose tip of diameter `D`, then a conical taper.""" + tip_radius = diameter / 2.0 + # Per-side angle from the axis (Fusion "Taper angle"). + alpha = math.radians(taper_angle_deg) + alpha = min(max(alpha, 0.0), math.radians(85.0)) + + max_corner = tip_radius / max(math.cos(alpha), 1e-6) + corner_radius = min(max(corner_radius or 0.0, 0.0), max_corner) + + if corner_radius <= 1e-9: + # Sharp flat tip at diameter D, then straight taper. + points = [(0.0, tip_radius)] + end_radius = tip_radius + length * math.tan(alpha) + points.append((max(length, diameter * 0.5), end_radius)) + return points + + # Fillet between the flat tip and the cone: same construction as a bull + # nose, but the arc stops at theta=-alpha where it meets the taper. + flat_radius = tip_radius - corner_radius * math.cos(alpha) + theta_start = -math.pi / 2.0 + theta_end = -alpha + + points = [(0.0, max(flat_radius, 0.0))] + for i in range(1, ROUND_SEGMENTS + 1): + t = i / ROUND_SEGMENTS + theta = theta_start + (theta_end - theta_start) * t + z = corner_radius + corner_radius * math.sin(theta) + r = flat_radius + corner_radius * math.cos(theta) + points.append((z, max(r, 0.0))) + + z_tan, r_tan = points[-1] + # Continue along the taper for the remaining tool length. + total_length = max(length, z_tan + diameter * 0.5) + end_radius = r_tan + (total_length - z_tan) * math.tan(alpha) + points.append((total_length, end_radius)) + return points + + def _lollipop_profile(diameter, length, **_kwargs): + """Full spherical cutter with a thinner cylindrical neck above the undercut.""" radius = diameter / 2.0 + neck_radius = max(radius * 0.35, diameter * 0.15) + neck_radius = min(neck_radius, radius * 0.95) + theta_join = math.acos(neck_radius / radius) + points = [] - for i in range(ROUND_SEGMENTS * 2 + 1): - theta = -math.pi / 2.0 + math.pi * (i / (ROUND_SEGMENTS * 2)) + # Lower hemisphere: south pole → equator (guarantees full cutting diameter). + for i in range(ROUND_SEGMENTS + 1): + theta = -math.pi / 2.0 + (math.pi / 2.0) * (i / ROUND_SEGMENTS) z = radius + radius * math.sin(theta) r = max(radius * math.cos(theta), 0.0) points.append((z, r)) - neck_radius = max(radius * 0.35, diameter * 0.15) - neck_transition_len = max(radius * 0.5, diameter * 0.25) - ball_top_z = points[-1][0] - total_length = max(length, ball_top_z + neck_transition_len * 2.0) + # Upper hemisphere: equator → neck join (skip duplicate equator point). + for i in range(1, ROUND_SEGMENTS + 1): + theta = theta_join * (i / ROUND_SEGMENTS) + z = radius + radius * math.sin(theta) + r = max(radius * math.cos(theta), 0.0) + points.append((z, r)) + + # Snap the join so the cylinder meets the ball at exactly neck_radius. + ball_join_z = points[-1][0] + points[-1] = (ball_join_z, neck_radius) - points.append((ball_top_z + neck_transition_len, neck_radius)) + total_length = max(length, ball_join_z + diameter * 0.5) points.append((total_length, neck_radius)) return points @@ -365,7 +417,7 @@ def _lollipop_profile(diameter, length, **_kwargs): ToolType.BULL_NOSE_END_MILL: _bull_nose_profile, ToolType.RADIUS_MILL: _radius_mill_profile, ToolType.CHAMFER_MILL: _chamfer_or_tapered_profile, - ToolType.TAPERED_MILL: _chamfer_or_tapered_profile, + ToolType.TAPERED_MILL: _tapered_mill_profile, ToolType.LOLLIPOP_MILL: _lollipop_profile, } diff --git a/carveracontroller/data/GcodeViewer/tools/tapered_mill.png b/carveracontroller/data/GcodeViewer/tools/tapered_mill.png new file mode 100644 index 0000000000000000000000000000000000000000..70b9de63125aebb93d50fb740777ab9ef3b7aa49 GIT binary patch literal 1214 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G!U;i$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBK4*bPWHAE+-yslY6xHx*0ICW0ba4!+hlPLtIhYs{ znGOiwII+)zLBR)#_MO{3`88P8_RXDp9S{;g6>*Olj$UPHn9cd2n}y*J0zD|@3ykq* z*fI43p8|t`8UiI-coeEKHW)BIa5G!yh|rKA^FC;uGDzK>W6Mk@FgVOWpq{4=M?-;@ zaJ)$XxetyE<~fUA7hvEJX2?t2JPXNT&pyOGB(SsF5e)TiyC6p78Qjo zj1O3vc66dx{^s$Aqh(-E=9w+*MRKtI`}l1_pin8>#F&c|^gu8Cwrtth%dnyQgDg^L z0iAR1fxC740N_dH?yQSCxbTUokWD?z%=l{ zhA&k|nPH7m4m;QtK!<=)gR$j|jV&NAY-s9z7Jw391$ynq%Y+%ygf}G~uR3p2bJ zW_TXpQ%8xd=fxh$QXuCfh|NCDim?9y-@VH|iXf$D5|Vdtc=o literal 0 HcmV?d00001 diff --git a/carveracontroller/main.py b/carveracontroller/main.py index f4fedd59..9b15ba03 100644 --- a/carveracontroller/main.py +++ b/carveracontroller/main.py @@ -4260,21 +4260,30 @@ def open_sleep_confirm_popup(self): self.confirm_popup.confirm = partial(self.resetMachine) self.confirm_popup.open(self) + # ----------------------------------------------------------------------- + def _format_target_tool_text(self): + """Return display text for the tool being requested in a tool-change popup.""" + tool_number = CNC.vars["target_tool"] + if tool_number == ZPROBE_TOOL_NUMBER: + return "Probe" + if tool_number == LASER_TOOL_NUMBER: + return "Laser" + if tool_number == PROBE_3D_TOOL_NUMBER: + return "3D Probe" + if is_probe_tools_range(tool_number): + return "Custom Probe" + + tool_def = self.tool_table.get(tool_number) + tooltip = format_tool_tooltip(tool_def) if tool_def else "" + return tooltip if tooltip else str(tool_number) + # ----------------------------------------------------------------------- def open_tool_confirm_popup(self): if self.confirm_popup.showing: return - target_tool = str(CNC.vars["target_tool"]) + target_tool = self._format_target_tool_text() target_collet_type = CNC.vars["target_collet_type"] target_collet_type_text = ["Undefined", "3mm", '1/8"', "4mm", "6mm", '1/4"', "8mm"] - if CNC.vars["target_tool"] == ZPROBE_TOOL_NUMBER: - target_tool = "Probe" - elif CNC.vars["target_tool"] == LASER_TOOL_NUMBER: - target_tool = "Laser" - elif CNC.vars["target_tool"] == PROBE_3D_TOOL_NUMBER: - target_tool = "3D Probe" - elif is_probe_tools_range(CNC.vars["target_tool"]): - target_tool = "Custom Probe" app = App.get_running_app() if app.has_atc: @@ -4285,7 +4294,7 @@ def open_tool_confirm_popup(self): self.confirm_popup.lb_title.text = tr._("Manual toolchange") self.confirm_popup.lb_content.text = ( tr._("Insert tool: ") - + "%s\n" % (target_tool) + + "%s\n\n" % (target_tool) + tr._("Then press ' Confirm' or main button to clamp.\n") ) else: diff --git a/carveracontroller/makera.kv b/carveracontroller/makera.kv index 5f145542..cd50a94b 100644 --- a/carveracontroller/makera.kv +++ b/carveracontroller/makera.kv @@ -1439,22 +1439,25 @@ : lb_title: lb_title lb_content: lb_content - size_hint: 0.5, 0.4 + size_hint: 0.5, 0.45 pos_hint: {"right": 0.75, "top": 0.7} auto_dismiss: False BoxLayout: padding: '15dp' orientation: 'vertical' Label: - size_hint_y: 0.4 + size_hint_y: 0.25 id: lb_title text: tr._('Confirm Box') bold: True Label: id: lb_content text: tr._('Confirm to continue?') + text_size: self.size + halign: 'center' + valign: 'middle' BoxLayout: - size_hint_y: 0.4 + size_hint_y: 0.3 Button: text: tr._('Cancel') on_release: diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index 82275705..e5674546 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -77,6 +77,16 @@ def test_parses_optional_taper_and_ignored_zmin(self, parser): assert table[2].tool_type == ToolType.BULL_NOSE_END_MILL assert table[2].taper_angle_deg == 45.0 + def test_parses_tapered_mill_comment(self, parser): + lines = ["(T12 D=1.872 CR=1. TAPER=3.8deg - ZMIN=-0.7 - tapered mill)\n"] + table = parser.parse(lines) + + assert table[12].tool_type == ToolType.TAPERED_MILL + assert table[12].diameter == 1.872 + assert table[12].corner_radius == 1.0 + assert table[12].taper_angle_deg == 3.8 + assert table[12].type_name == "tapered mill" + def test_parses_semicolon_comments(self, parser): lines = [";T3 Thread cutter D=4 CR=0 - thread mill\n"] table = parser.parse(lines) @@ -115,6 +125,10 @@ def test_maps_known_tool_types(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL) assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/ball_end_mill.png" + def test_maps_tapered_mill_icon(self): + tool_def = ToolDefinition(number=12, tool_type=ToolType.TAPERED_MILL) + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/tapered_mill.png" + class TestTooltipBuilder: def test_empty_tooltip_for_missing_tool(self): @@ -300,17 +314,108 @@ def test_tool_profiles_have_expected_shape(self, tool_type): assert profile[0] == (0.0, pytest.approx(diameter / 2.0)) assert profile[-1][1] == pytest.approx(diameter / 2.0 + corner_radius) assert len(profile) > 2 - elif tool_type in (ToolType.CHAMFER_MILL, ToolType.TAPERED_MILL): + elif tool_type == ToolType.CHAMFER_MILL: assert profile[0] == (0.0, 0.0) assert len(profile) >= 2 + elif tool_type == ToolType.TAPERED_MILL: + # Tip diameter D with a bull-nose corner; sides widen above the tip. + assert profile[0][0] == pytest.approx(0.0) + assert 0.0 < profile[0][1] < diameter / 2.0 + assert profile[-1][1] > diameter / 2.0 + assert len(profile) > 3 elif tool_type == ToolType.LOLLIPOP_MILL: assert len(profile) > 4 + assert profile[0] == (0.0, pytest.approx(0.0)) + assert max(r for _, r in profile) == pytest.approx(diameter / 2.0) + # Neck is a plain cylinder: last two points share the undercut radius. assert profile[-1][1] < diameter / 2.0 + assert profile[-2][1] == pytest.approx(profile[-1][1]) + assert profile[-1][0] == shared_length elif tool_type == ToolType.THREAD_MILL: assert profile[0][1] < diameter / 2.0 assert max(r for _, r in profile) == pytest.approx(diameter / 2.0) assert len(profile) >= 3 + def test_tapered_mill_is_bull_nose_tip_with_taper(self): + diameter = 6.0 + corner_radius = 1.0 + taper_angle_deg = 30.0 + shared_length = diameter * LENGTH_DIAMETER_FACTOR + profile = tool_profile( + ToolDefinition( + number=12, + tool_type=ToolType.TAPERED_MILL, + diameter=diameter, + corner_radius=corner_radius, + taper_angle_deg=taper_angle_deg, + ), + length=shared_length, + ) + + alpha = math.radians(taper_angle_deg) + flat_radius = diameter / 2.0 - corner_radius * math.cos(alpha) + z_tan = corner_radius * (1.0 - math.sin(alpha)) + r_tan = diameter / 2.0 + end_radius = r_tan + (shared_length - z_tan) * math.tan(alpha) + + assert profile[0] == (0.0, pytest.approx(flat_radius)) + assert any(math.isclose(z, z_tan, abs_tol=1e-6) and math.isclose(r, r_tan, abs_tol=1e-6) for z, r in profile) + assert profile[-1][0] == pytest.approx(shared_length) + assert profile[-1][1] == pytest.approx(end_radius) + assert profile[-1][1] > diameter / 2.0 + + def test_tapered_mill_without_corner_radius_has_flat_tip(self): + diameter = 6.0 + taper_angle_deg = 30.0 + shared_length = diameter * LENGTH_DIAMETER_FACTOR + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.TAPERED_MILL, + diameter=diameter, + corner_radius=0.0, + taper_angle_deg=taper_angle_deg, + ), + length=shared_length, + ) + + tip_radius = diameter / 2.0 + end_radius = tip_radius + shared_length * math.tan(math.radians(taper_angle_deg)) + assert profile[0] == (0.0, tip_radius) + assert profile[-1][0] == pytest.approx(shared_length) + assert profile[-1][1] == pytest.approx(end_radius) + + def test_tapered_mill_with_zero_taper_matches_bull_nose(self): + diameter = 6.0 + corner_radius = 1.0 + shared_length = diameter * LENGTH_DIAMETER_FACTOR + tapered = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.TAPERED_MILL, + diameter=diameter, + corner_radius=corner_radius, + taper_angle_deg=0.0, + ), + length=shared_length, + ) + bull = tool_profile( + ToolDefinition( + number=2, + tool_type=ToolType.BULL_NOSE_END_MILL, + diameter=diameter, + corner_radius=corner_radius, + ), + length=shared_length, + ) + + assert tapered[0] == bull[0] + assert tapered[-1] == bull[-1] + assert len(tapered) == len(bull) + for (z0, r0), (z1, r1) in zip(tapered, bull): + assert z0 == pytest.approx(z1) + assert r0 == pytest.approx(r1) + def test_radius_mill_interprets_diameter_as_flat_bottom(self): profile = tool_profile( ToolDefinition(number=2, tool_type=ToolType.RADIUS_MILL, diameter=2.0, corner_radius=2.0), From b4cdf9ba9f2e95953928f335456b6bda6b53a501 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:19:36 +0200 Subject: [PATCH 03/11] Initialize Makera Studio parser --- .../addons/tool_visualization/extractor.py | 2 + .../addons/tool_visualization/icon_builder.py | 1 + .../addons/tool_visualization/mesh_builder.py | 152 +++++++++++-- .../tool_visualization/parsers/__init__.py | 4 + .../parsers/fusion360_makera.py | 25 ++- .../parsers/makera_studio.py | 159 +++++++++++++ .../tool_visualization/tool_definition.py | 5 + .../tool_visualization/tooltip_builder.py | 12 +- tests/unit/test_tool_visualization.py | 211 ++++++++++++++++++ 9 files changed, 545 insertions(+), 26 deletions(-) create mode 100644 carveracontroller/addons/tool_visualization/parsers/makera_studio.py diff --git a/carveracontroller/addons/tool_visualization/extractor.py b/carveracontroller/addons/tool_visualization/extractor.py index b0cb22c4..c954d84c 100644 --- a/carveracontroller/addons/tool_visualization/extractor.py +++ b/carveracontroller/addons/tool_visualization/extractor.py @@ -3,12 +3,14 @@ import logging from carveracontroller.addons.tool_visualization.parsers.fusion360_makera import Fusion360MakeraParser +from carveracontroller.addons.tool_visualization.parsers.makera_studio import MakeraStudioParser logger = logging.getLogger(__name__) # Ordered list of parsers to try when extracting a tool table from a loaded # G-code file. Add new CAM/post-processor parsers here. TOOL_TABLE_PARSERS = [ + MakeraStudioParser(), Fusion360MakeraParser(), ] diff --git a/carveracontroller/addons/tool_visualization/icon_builder.py b/carveracontroller/addons/tool_visualization/icon_builder.py index 5b4d7130..bdb40dee 100644 --- a/carveracontroller/addons/tool_visualization/icon_builder.py +++ b/carveracontroller/addons/tool_visualization/icon_builder.py @@ -10,6 +10,7 @@ ToolType.BULL_NOSE_END_MILL: f"{TOOLS_ICON_DIR}/bull_nose_end_mill.png", ToolType.RADIUS_MILL: f"{TOOLS_ICON_DIR}/radius_mill.png", ToolType.CHAMFER_MILL: DEFAULT_ICON, + ToolType.ENGRAVING: DEFAULT_ICON, ToolType.TAPERED_MILL: f"{TOOLS_ICON_DIR}/tapered_mill.png", ToolType.LOLLIPOP_MILL: f"{TOOLS_ICON_DIR}/lollipop_mill.png", ToolType.THREAD_MILL: f"{TOOLS_ICON_DIR}/thread_mill.png", diff --git a/carveracontroller/addons/tool_visualization/mesh_builder.py b/carveracontroller/addons/tool_visualization/mesh_builder.py index e2178d39..63d47947 100644 --- a/carveracontroller/addons/tool_visualization/mesh_builder.py +++ b/carveracontroller/addons/tool_visualization/mesh_builder.py @@ -205,7 +205,22 @@ def _effective_tool_diameter(tool_def, scale): return diameter +def _has_explicit_length(tool_def): + if not tool_def: + return False + length = getattr(tool_def, "length", None) + flute_length = getattr(tool_def, "flute_length", None) + return (length is not None and length > 0) or (flute_length is not None and flute_length > 0) + + def _profile_length(tool_def, scale, diameter, shared_length=None): + if tool_def: + length = getattr(tool_def, "length", None) + if length is not None and length > 0: + return length + flute_length = getattr(tool_def, "flute_length", None) + if flute_length is not None and flute_length > 0: + return flute_length if shared_length is not None and shared_length > 0: return shared_length if tool_def and getattr(tool_def, "diameter", None) and tool_def.diameter > 0: @@ -213,6 +228,54 @@ def _profile_length(tool_def, scale, diameter, shared_length=None): return fallback_tool_dimensions(scale)[1] +def _resolve_cutting_overall_length(tool_def, overall_length): + """Return (cutting_length, overall_length), splitting on flute when possible.""" + if not tool_def: + return overall_length, overall_length + length = getattr(tool_def, "length", None) + flute_length = getattr(tool_def, "flute_length", None) + if length is not None and length > 0 and flute_length is not None and flute_length > 0 and length > flute_length: + return flute_length, length + return overall_length, overall_length + + +def _shank_radius(tool_def, cutting_radius): + shank_diameter = getattr(tool_def, "shank_diameter", None) if tool_def else None + if shank_diameter is not None and shank_diameter > 0: + return shank_diameter / 2.0 + return cutting_radius + + +def _safe_tip_diameter(tool_def, diameter): + tip_diameter = getattr(tool_def, "tip_diameter", None) if tool_def else None + if tip_diameter is None or tip_diameter < 0: + return 0.0 + return min(tip_diameter, diameter) + + +def _append_shank_section(points, cutting_length, overall_length, shank_radius): + """Extend a cutting profile with an optional cylindrical shank above it.""" + if not points: + return points + + last_z, last_r = points[-1] + # Tip geometry may already exceed the requested flute length (e.g. ball nose). + cutting_z = max(cutting_length, last_z) + if cutting_z > last_z + 1e-9: + points = list(points) + [(cutting_z, last_r)] + last_z, last_r = cutting_z, last_r + else: + points = list(points) + + if overall_length <= cutting_z + 1e-9: + return points + + if abs(shank_radius - last_r) > 1e-9: + points.append((cutting_z, shank_radius)) + points.append((overall_length, shank_radius)) + return points + + def _safe_corner_radius(tool_def, diameter, tool_type=None): corner_radius = getattr(tool_def, "corner_radius", None) if tool_def else None if not corner_radius or corner_radius <= 0: @@ -326,15 +389,26 @@ def _radius_mill_profile(diameter, length, corner_radius=0.0, **_kwargs): return points -def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, **_kwargs): - """Pointed conical profile used for chamfer mills (and as the generic fallback).""" +def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, tip_diameter=0.0, **_kwargs): + """Flat-tip (or pointed) conical profile for chamfer mills and engraving bits.""" radius = diameter / 2.0 + tip_radius = max(tip_diameter or 0.0, 0.0) / 2.0 + tip_radius = min(tip_radius, radius) + half_angle_rad = math.radians(taper_angle_deg) / 2.0 half_angle_rad = min(max(half_angle_rad, math.radians(5.0)), math.radians(85.0)) - cone_height = radius / math.tan(half_angle_rad) - points = [(0.0, 0.0), (cone_height, radius)] - if length > cone_height: + if tip_radius <= 1e-9: + cone_height = radius / math.tan(half_angle_rad) + points = [(0.0, 0.0), (cone_height, radius)] + else: + radial_rise = radius - tip_radius + cone_height = radial_rise / math.tan(half_angle_rad) if radial_rise > 1e-9 else 0.0 + points = [(0.0, tip_radius)] + if cone_height > 1e-9: + points.append((cone_height, radius)) + + if length > points[-1][0]: points.append((length, radius)) return points @@ -417,6 +491,7 @@ def _lollipop_profile(diameter, length, **_kwargs): ToolType.BULL_NOSE_END_MILL: _bull_nose_profile, ToolType.RADIUS_MILL: _radius_mill_profile, ToolType.CHAMFER_MILL: _chamfer_or_tapered_profile, + ToolType.ENGRAVING: _chamfer_or_tapered_profile, ToolType.TAPERED_MILL: _tapered_mill_profile, ToolType.LOLLIPOP_MILL: _lollipop_profile, } @@ -442,9 +517,23 @@ def fallback_tool_profile(scale): def _reference_length(tool_table, scale): - """Compute the shared tool height used for every tool in `tool_table`. - This is required since the unit system of the document can vary. + """Compute the shared fallback height for tools without explicit length metadata. + + Derived from the largest diameter among tools that lack length/flute_length, + so it scales with the document's unit system instead of a fixed absolute value. """ + diameters = [ + _effective_tool_diameter(tool_def, scale) + for tool_def in tool_table.values() + if tool_def + and not _has_explicit_length(tool_def) + and getattr(tool_def, "diameter", None) + and tool_def.diameter > 0 + ] + if diameters: + return max(diameters) * LENGTH_DIAMETER_FACTOR + + # Every tool already has an explicit length (or none have a usable diameter). diameters = [ _effective_tool_diameter(tool_def, scale) for tool_def in tool_table.values() @@ -463,24 +552,46 @@ def tool_profile(tool_def, length=None, scale=1.0): """ diameter = _tool_diameter(tool_def, scale) effective_diameter = _effective_tool_diameter(tool_def, scale) - length = _profile_length(tool_def, scale, effective_diameter, length) + overall_length = _profile_length(tool_def, scale, effective_diameter, length) + cutting_length, overall_length = _resolve_cutting_overall_length(tool_def, overall_length) tool_type = getattr(tool_def, "tool_type", ToolType.UNKNOWN) if tool_def else ToolType.UNKNOWN corner_radius = _safe_corner_radius(tool_def, diameter, tool_type) taper_angle_deg = _safe_taper_angle_deg(tool_def) + tip_diameter = _safe_tip_diameter(tool_def, diameter) thread_depth = _safe_thread_depth(tool_def, diameter) thread_pitch = _safe_thread_pitch(tool_def, diameter) builder = PROFILE_BUILDERS.get(tool_type, DEFAULT_PROFILE_BUILDER) - return builder( + profile = builder( diameter, - length, + cutting_length, corner_radius=corner_radius, taper_angle_deg=taper_angle_deg, + tip_diameter=tip_diameter, thread_depth=thread_depth, thread_pitch=thread_pitch, ) + # Tapered mills and lollipops already encode body/neck geometry; only append + # a constant shank when the parser provided an explicit shank diameter, or + # for other tool types that use a cylindrical shaft above the flute. + cutting_radius = profile[-1][1] if profile else effective_diameter / 2.0 + if tool_type in (ToolType.TAPERED_MILL, ToolType.LOLLIPOP_MILL): + shank_diameter = getattr(tool_def, "shank_diameter", None) if tool_def else None + if shank_diameter is None or shank_diameter <= 0: + if overall_length > profile[-1][0] + 1e-9: + # Extend along the existing end radius without inventing a shank step. + profile = list(profile) + [(overall_length, profile[-1][1])] + return profile + + return _append_shank_section( + profile, + cutting_length, + overall_length, + _shank_radius(tool_def, cutting_radius), + ) + def _scale_profile(profile, scale, radius_boost): """Scale the profile by the given scale and radius boost.""" @@ -533,13 +644,13 @@ def build_tool_meshes(tool_table, scale=1.0): """Build a mesh for every tool in `tool_table`, plus a default mesh for tools with no metadata. - Known tools share: - - the same overall height, derived from the largest diameter in the - table (see `_reference_length`) so it scales sensibly with the - document's unit system instead of using a fixed absolute value. - - a single radius boost factor derived from the smallest tool in the - batch, so tiny tools stay visible without making unrelated tools look - like they share the same diameter. + Tools without explicit length/flute metadata share a fallback height derived + from the largest diameter among those tools (see `_reference_length`). + Tools that provide length or flute_length use their own heights. + + A single radius boost factor is derived from the smallest tool in the batch, + so tiny tools stay visible without making unrelated tools look like they + share the same diameter. The default (no-metadata) mesh keeps a fixed on-screen size, independent of file units. @@ -550,9 +661,10 @@ def build_tool_meshes(tool_table, scale=1.0): if tool_table: shared_length = _reference_length(tool_table, scale) - profiles = { - number: tool_profile(tool_def, length=shared_length, scale=scale) for number, tool_def in tool_table.items() - } + profiles = {} + for number, tool_def in tool_table.items(): + length_hint = None if _has_explicit_length(tool_def) else shared_length + profiles[number] = tool_profile(tool_def, length=length_hint, scale=scale) radius_boost = _compute_radius_boost(list(profiles.values()), scale) tool_meshes = { number: _build_revolve_mesh(_scale_profile(profile, scale, radius_boost)) diff --git a/carveracontroller/addons/tool_visualization/parsers/__init__.py b/carveracontroller/addons/tool_visualization/parsers/__init__.py index 597f0696..45001ce2 100644 --- a/carveracontroller/addons/tool_visualization/parsers/__init__.py +++ b/carveracontroller/addons/tool_visualization/parsers/__init__.py @@ -4,4 +4,8 @@ comments a particular CAM software / post processor writes at the top of a G-code file. Add new parsers here and register them in `carveracontroller.addons.tool_visualization.extractor.TOOL_TABLE_PARSERS`. + +Available parsers: +- fusion360_makera: Fusion 360 Makera post processor tool comments +- makera_studio: Makera Studio `;@MKR|TOOL|...` metadata block """ diff --git a/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py b/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py index d3b8bedf..202dd8b5 100644 --- a/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py +++ b/carveracontroller/addons/tool_visualization/parsers/fusion360_makera.py @@ -48,6 +48,21 @@ def _to_float(value): return None +def _infer_shank_diameter(tool_type, diameter, corner_radius=None): + """Infer shank diameter from Fusion cutting geometry. + + Returns None when diameter is missing or the type's shaft cannot be derived + from cutting geometry alone (tapered tip/lollipop ball). + """ + if diameter is None or diameter <= 0: + return None + if tool_type is ToolType.RADIUS_MILL: + return diameter + 2.0 * (corner_radius or 0.0) + if tool_type in (ToolType.TAPERED_MILL, ToolType.LOLLIPOP_MILL): + return None + return diameter + + def _extract_full_line_comment(line): """Return the text of a comment if the whole (stripped) line is one, else None.""" if len(line) >= 2 and line[0] == "(" and line[-1] == ")": @@ -106,12 +121,16 @@ def _build_tool_definition(number, match): product_id = fields[2] if len(fields) > 2 else "" type_name = match.group("type_name").strip() + tool_type = resolve_tool_type(type_name, TOOL_TYPE_NAME_MAP) + diameter = _to_float(match.group("diameter")) + corner_radius = _to_float(match.group("corner_radius")) return ToolDefinition( number=number, - tool_type=resolve_tool_type(type_name, TOOL_TYPE_NAME_MAP), - diameter=_to_float(match.group("diameter")), - corner_radius=_to_float(match.group("corner_radius")), + tool_type=tool_type, + diameter=diameter, + shank_diameter=_infer_shank_diameter(tool_type, diameter, corner_radius), + corner_radius=corner_radius, taper_angle_deg=_to_float(match.group("taper")), description=description, vendor=vendor, diff --git a/carveracontroller/addons/tool_visualization/parsers/makera_studio.py b/carveracontroller/addons/tool_visualization/parsers/makera_studio.py new file mode 100644 index 00000000..7e4e2948 --- /dev/null +++ b/carveracontroller/addons/tool_visualization/parsers/makera_studio.py @@ -0,0 +1,159 @@ +"""Parser for tool tables written by Makera Studio. + +Makera Studio writes a `;@MKR|...` metadata block at the top of the G-code +file. Each tool is one line: + +;@MKR|TOOL|number=|id=|name=|type=|handlediameter=|sticklength=|shoulderlength=|flutelength=|diameter=|tipdiameter=|cornerradius=|angle=|halfAngle= +""" + +import logging + +from carveracontroller.addons.tool_visualization.parsers.base import ToolTableParser +from carveracontroller.addons.tool_visualization.tool_definition import ToolDefinition, ToolType, resolve_tool_type + +logger = logging.getLogger(__name__) + +# Tool type names as exported by Makera Studio +# TODO Update with confirmed IDs from Makera Studio. +TOOL_TYPE_NAME_MAP = { + "flat end": ToolType.FLAT_END_MILL, + "ball end": ToolType.BALL_END_MILL, + "bull nose": ToolType.BULL_NOSE_END_MILL, + "bullnose": ToolType.BULL_NOSE_END_MILL, + "radius": ToolType.RADIUS_MILL, + "radius mill": ToolType.RADIUS_MILL, + "engraving": ToolType.ENGRAVING, + "chamfer": ToolType.CHAMFER_MILL, + "chamfer mill": ToolType.CHAMFER_MILL, + "tapered": ToolType.TAPERED_MILL, + "tapered mill": ToolType.TAPERED_MILL, + "lollipop": ToolType.LOLLIPOP_MILL, + "lollipop mill": ToolType.LOLLIPOP_MILL, + "thread": ToolType.THREAD_MILL, + "thread mill": ToolType.THREAD_MILL, +} + +_MKR_PREFIX = ";@MKR|" +_TOOL_TAG = "TOOL" + + +def _to_float(value): + if value is None or value == "": + return None + try: + return float(value) + except ValueError: + return None + + +def _to_int(value): + if value is None or value == "": + return None + try: + return int(float(value)) + except ValueError: + return None + + +def _positive_or_none(value): + if value is None or value <= 0: + return None + return value + + +def _parse_mkr_fields(line): + """Return (tag, fields_dict) for a `;@MKR|TAG|k=v|...` line, or None.""" + stripped = line.strip() + if not stripped.startswith(_MKR_PREFIX): + return None + + parts = stripped[len(_MKR_PREFIX) :].split("|") + if not parts: + return None + + tag = parts[0] + fields = {} + for part in parts[1:]: + if not part: + continue + key, sep, value = part.partition("=") + if not sep: + continue + fields[key] = value + return tag, fields + + +def _taper_angle_from_fields(fields): + angle = _to_float(fields.get("angle")) + if angle is not None and angle > 0: + return angle + half_angle = _to_float(fields.get("halfAngle")) + if half_angle is not None and half_angle > 0: + return 2.0 * half_angle + return None + + +def _length_from_fields(fields): + for key in ("sticklength", "shoulderlength"): + length = _positive_or_none(_to_float(fields.get(key))) + if length is not None: + return length + return None + + +class MakeraStudioParser(ToolTableParser): + name = "makera_studio" + + def parse(self, lines): + tool_table = {} + for raw_line in self.iter_header_lines(lines): + parsed = _parse_mkr_fields(raw_line) + if parsed is None: + continue + + tag, fields = parsed + if tag != _TOOL_TAG: + continue + + number = _to_int(fields.get("number")) + if number is None: + continue + if number in tool_table: + logger.debug(f"Ignoring duplicate Makera Studio tool comment for T{number}: {raw_line.strip()}") + continue + + tool_def = self._build_tool_definition(number, fields) + tool_table[number] = tool_def + + if tool_def.tool_type is ToolType.UNKNOWN: + logger.warning( + f"Detected T{number} ({tool_def.description!r}, D={tool_def.diameter}) " + f"with unrecognised tool type {tool_def.type_name!r}; defaulting to a basic pointed mesh" + ) + else: + dims = f"D={tool_def.diameter}, CR={tool_def.corner_radius}" + if tool_def.taper_angle_deg is not None: + dims += f", TAPER={tool_def.taper_angle_deg}" + logger.info(f"Detected T{number}: {tool_def.tool_type.value} ({dims}) - {tool_def.description!r}") + + return tool_table + + @staticmethod + def _build_tool_definition(number, fields): + type_name = fields.get("type", "") or "" + handle_diameter = _positive_or_none(_to_float(fields.get("handlediameter"))) + + return ToolDefinition( + number=number, + tool_type=resolve_tool_type(type_name, TOOL_TYPE_NAME_MAP), + diameter=_to_float(fields.get("diameter")), + shank_diameter=handle_diameter, + tip_diameter=_to_float(fields.get("tipdiameter")), + corner_radius=_to_float(fields.get("cornerradius")), + taper_angle_deg=_taper_angle_from_fields(fields), + length=_length_from_fields(fields), + flute_length=_positive_or_none(_to_float(fields.get("flutelength"))), + description=fields.get("name", "") or "", + product_id=fields.get("id", "") or "", + type_name=type_name, + ) diff --git a/carveracontroller/addons/tool_visualization/tool_definition.py b/carveracontroller/addons/tool_visualization/tool_definition.py index e2957757..43a18a4f 100644 --- a/carveracontroller/addons/tool_visualization/tool_definition.py +++ b/carveracontroller/addons/tool_visualization/tool_definition.py @@ -14,6 +14,7 @@ class ToolType(Enum): BULL_NOSE_END_MILL = "bull_nose_end_mill" RADIUS_MILL = "radius_mill" # Note: Represents a concave radius mill CHAMFER_MILL = "chamfer_mill" + ENGRAVING = "engraving" TAPERED_MILL = "tapered_mill" LOLLIPOP_MILL = "lollipop_mill" THREAD_MILL = "thread_mill" @@ -44,8 +45,12 @@ class ToolDefinition: number: int tool_type: ToolType = ToolType.UNKNOWN diameter: float | None = None + shank_diameter: float | None = None + tip_diameter: float | None = None corner_radius: float | None = None taper_angle_deg: float | None = None + length: float | None = None + flute_length: float | None = None thread_depth: float | None = None thread_pitch: float | None = None description: str = "" diff --git a/carveracontroller/addons/tool_visualization/tooltip_builder.py b/carveracontroller/addons/tool_visualization/tooltip_builder.py index 2d23d572..3fdb42ee 100644 --- a/carveracontroller/addons/tool_visualization/tooltip_builder.py +++ b/carveracontroller/addons/tool_visualization/tooltip_builder.py @@ -9,6 +9,7 @@ ToolType.BULL_NOSE_END_MILL: "Bull Nose End Mill", ToolType.RADIUS_MILL: "Radius Mill", ToolType.CHAMFER_MILL: "Chamfer Mill", + ToolType.ENGRAVING: "Engraving", ToolType.TAPERED_MILL: "Tapered Mill", ToolType.LOLLIPOP_MILL: "Lollipop Mill", ToolType.THREAD_MILL: "Thread Mill", @@ -37,10 +38,16 @@ def format_tool_tooltip(tool_def): dimensions = [] if tool_def.diameter is not None: dimensions.append(tr._("D={value:g}").format(value=tool_def.diameter)) + if tool_def.shank_diameter is not None: + dimensions.append(tr._("SD={value:g}").format(value=tool_def.shank_diameter)) if tool_def.corner_radius is not None: dimensions.append(tr._("CR={value:g}").format(value=tool_def.corner_radius)) if tool_def.taper_angle_deg is not None: dimensions.append(tr._("TAPER={value:g}°").format(value=tool_def.taper_angle_deg)) + if tool_def.length is not None: + dimensions.append(tr._("L={value:g}").format(value=tool_def.length)) + if tool_def.flute_length is not None: + dimensions.append(tr._("FL={value:g}").format(value=tool_def.flute_length)) if tool_def.thread_depth is not None: dimensions.append(tr._("Thread depth={value:g}").format(value=tool_def.thread_depth)) if tool_def.thread_pitch is not None: @@ -51,8 +58,7 @@ def format_tool_tooltip(tool_def): if tool_def.description: lines.append(tool_def.description) - vendor_parts = [part for part in (tool_def.vendor, tool_def.product_id) if part] - if vendor_parts: - lines.append(" - ".join(vendor_parts)) + if tool_def.vendor: + lines.append(" - {vendor}".format(vendor=tool_def.vendor)) return "\n".join(lines) diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index e5674546..ba20f872 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -25,6 +25,13 @@ from carveracontroller.addons.tool_visualization.parsers.fusion360_makera import ( TOOL_TYPE_NAME_MAP, Fusion360MakeraParser, + _infer_shank_diameter, +) +from carveracontroller.addons.tool_visualization.parsers.makera_studio import ( + TOOL_TYPE_NAME_MAP as MAKERA_STUDIO_TOOL_TYPE_NAME_MAP, +) +from carveracontroller.addons.tool_visualization.parsers.makera_studio import ( + MakeraStudioParser, ) from carveracontroller.addons.tool_visualization.tool_definition import resolve_tool_type @@ -65,10 +72,14 @@ def test_parses_basic_flat_end_mill_comment(self, parser): assert table[1].number == 1 assert table[1].tool_type == ToolType.FLAT_END_MILL assert table[1].diameter == 6.0 + assert table[1].shank_diameter == 6.0 assert table[1].corner_radius == 0.0 assert table[1].description == "Flat end mill" assert table[1].vendor == "Vendor" assert table[1].product_id == "PID" + assert table[1].length is None + assert table[1].flute_length is None + assert table[1].tip_diameter is None def test_parses_optional_taper_and_ignored_zmin(self, parser): lines = ["(T2 Bull tool D=3.175 CR=0.5 TAPER=45deg - ZMIN=-5 - bull nose end mill)\n"] @@ -76,6 +87,7 @@ def test_parses_optional_taper_and_ignored_zmin(self, parser): assert table[2].tool_type == ToolType.BULL_NOSE_END_MILL assert table[2].taper_angle_deg == 45.0 + assert table[2].shank_diameter == 3.175 def test_parses_tapered_mill_comment(self, parser): lines = ["(T12 D=1.872 CR=1. TAPER=3.8deg - ZMIN=-0.7 - tapered mill)\n"] @@ -86,12 +98,39 @@ def test_parses_tapered_mill_comment(self, parser): assert table[12].corner_radius == 1.0 assert table[12].taper_angle_deg == 3.8 assert table[12].type_name == "tapered mill" + assert table[12].shank_diameter is None + + def test_infers_radius_mill_shank_from_outer_diameter(self, parser): + lines = ["(T5 Concave D=2 CR=2 - radius mill)\n"] + table = parser.parse(lines) + + assert table[5].tool_type == ToolType.RADIUS_MILL + assert table[5].shank_diameter == 6.0 + + def test_chamfer_mill_keeps_chamfer_type(self, parser): + lines = [ + "(T1 Single Flute Engraving Metal 60 deg*.1mm D=3.175 CR=0. " + "TAPER=30deg - ZMIN=0. - chamfer mill)\n" + ] + table = parser.parse(lines) + + assert table[1].tool_type == ToolType.CHAMFER_MILL + assert table[1].shank_diameter == 3.175 + assert table[1].taper_angle_deg == 30.0 + + def test_lollipop_leaves_shank_unset(self, parser): + lines = ["(T8 Under D=6 CR=0 - lollipop mill)\n"] + table = parser.parse(lines) + + assert table[8].tool_type == ToolType.LOLLIPOP_MILL + assert table[8].shank_diameter is None def test_parses_semicolon_comments(self, parser): lines = [";T3 Thread cutter D=4 CR=0 - thread mill\n"] table = parser.parse(lines) assert table[3].tool_type == ToolType.THREAD_MILL + assert table[3].shank_diameter == 4.0 def test_ignores_duplicate_tool_entries(self, parser): lines = [ @@ -109,12 +148,80 @@ def test_unknown_tool_type_falls_back_to_unknown(self, parser): assert table[4].tool_type == ToolType.UNKNOWN assert table[4].type_name == "mystery cutter" + assert table[4].shank_diameter == 6.0 + + +class TestMakeraStudioParser: + @pytest.fixture + def parser(self): + return MakeraStudioParser() + + def test_parses_sample_flat_end_header(self, parser): + lines = [ + ";@MKR|BEGIN\n", + ";@MKR|SCHEMA|v=1.0.0\n", + ";@MKR|TOOL|number=1|id=111011203812|name=3.175*2*12mm Flat End|type=Flat End|" + "handlediameter=3.175|sticklength=0|shoulderlength=12|flutelength=12|diameter=2|" + "tipdiameter=2|cornerradius=0|angle=0|halfAngle=0\n", + ";@MKR|END\n", + "G0 X0\n", + ] + table = parser.parse(lines) + + tool = table[1] + assert tool.tool_type == ToolType.FLAT_END_MILL + assert tool.diameter == 2.0 + assert tool.shank_diameter == 3.175 + assert tool.tip_diameter == 2.0 + assert tool.corner_radius == 0.0 + assert tool.length == 12.0 + assert tool.flute_length == 12.0 + assert tool.description == "3.175*2*12mm Flat End" + assert tool.product_id == "111011203812" + assert tool.type_name == "Flat End" + assert tool.taper_angle_deg is None + + def test_parses_engraving_half_angle_as_included_taper(self, parser): + lines = [ + ";@MKR|TOOL|number=2|id=abc|name=V-bit|type=Engraving|handlediameter=3.175|" + "sticklength=20|shoulderlength=0|flutelength=12|diameter=3.175|tipdiameter=0.1|" + "cornerradius=0|angle=0|halfAngle=15\n" + ] + table = parser.parse(lines) + + tool = table[2] + assert tool.tool_type == ToolType.ENGRAVING + assert tool.taper_angle_deg == 30.0 + assert tool.tip_diameter == 0.1 + assert tool.length == 20.0 + assert tool.flute_length == 12.0 + assert tool.shank_diameter == 3.175 + + def test_unknown_type_falls_back_to_unknown(self, parser): + lines = [";@MKR|TOOL|number=3|id=x|name=Mystery|type=Mystery Cutter|diameter=6|cornerradius=0\n"] + table = parser.parse(lines) + + assert table[3].tool_type == ToolType.UNKNOWN + assert table[3].type_name == "Mystery Cutter" + + def test_returns_empty_for_non_mkr_header(self, parser): + lines = ["(T1 Flat end mill D=6 CR=0 - flat end mill)\n", "G0 X0\n"] + assert parser.parse(lines) == {} class TestToolDefinitionHelpers: def test_resolve_tool_type_normalises_names(self): assert resolve_tool_type(" Flat End Mill ", TOOL_TYPE_NAME_MAP) == ToolType.FLAT_END_MILL assert resolve_tool_type("", TOOL_TYPE_NAME_MAP) == ToolType.UNKNOWN + assert resolve_tool_type("Flat End", MAKERA_STUDIO_TOOL_TYPE_NAME_MAP) == ToolType.FLAT_END_MILL + assert resolve_tool_type("Engraving", MAKERA_STUDIO_TOOL_TYPE_NAME_MAP) == ToolType.ENGRAVING + + def test_infer_shank_diameter(self): + assert _infer_shank_diameter(ToolType.FLAT_END_MILL, 6.0) == 6.0 + assert _infer_shank_diameter(ToolType.RADIUS_MILL, 2.0, 2.0) == 6.0 + assert _infer_shank_diameter(ToolType.TAPERED_MILL, 1.5) is None + assert _infer_shank_diameter(ToolType.LOLLIPOP_MILL, 6.0) is None + assert _infer_shank_diameter(ToolType.CHAMFER_MILL, None) is None class TestIconBuilder: @@ -129,6 +236,10 @@ def test_maps_tapered_mill_icon(self): tool_def = ToolDefinition(number=12, tool_type=ToolType.TAPERED_MILL) assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/tapered_mill.png" + def test_maps_engraving_to_default_pointed_icon(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.ENGRAVING) + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/pointed_mill.png" + class TestTooltipBuilder: def test_empty_tooltip_for_missing_tool(self): @@ -154,6 +265,23 @@ def test_uses_enum_label_when_type_name_missing(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0) assert format_tool_tooltip(tool_def) == "T1 - Flat End Mill\nD=3" + def test_includes_shank_length_and_flute_when_present(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.ENGRAVING, + diameter=3.175, + shank_diameter=3.175, + length=20.0, + flute_length=12.0, + type_name="Engraving", + ) + tooltip = format_tool_tooltip(tool_def) + + assert "SD=3.175" in tooltip + assert "L=20" in tooltip + assert "FL=12" in tooltip + assert "Engraving" in tooltip + def _vertex_normal(vertices, index): base = index * 8 @@ -457,6 +585,73 @@ def test_radius_mill_corner_arc_is_reversed_from_bull_nose(self): assert profile_bull_mid_r == pytest.approx(bull_mid_r, abs=0.05) assert profile_radius_mid_r < profile_bull_mid_r + def test_explicit_length_and_flute_produce_shank_step(self): + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + shank_diameter=3.175, + length=20.0, + flute_length=12.0, + ) + ) + + assert profile[0] == (0.0, 1.0) + assert (12.0, 1.0) in profile + assert profile[-1] == (20.0, pytest.approx(3.175 / 2.0)) + assert any(math.isclose(z, 12.0) and math.isclose(r, 3.175 / 2.0) for z, r in profile) + + def test_missing_lengths_still_use_diameter_factor(self): + profile = tool_profile( + ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0), + length=None, + ) + assert profile[-1][0] == pytest.approx(6.0 * LENGTH_DIAMETER_FACTOR) + + def test_engraving_tip_diameter_zero_is_pointed(self): + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.ENGRAVING, + diameter=6.0, + tip_diameter=0.0, + taper_angle_deg=30.0, + ), + length=18.0, + ) + assert profile[0] == (0.0, 0.0) + + def test_engraving_with_flat_tip(self): + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.ENGRAVING, + diameter=6.0, + tip_diameter=1.0, + taper_angle_deg=30.0, + ), + length=18.0, + ) + assert profile[0] == (0.0, 0.5) + assert profile[0][1] > 0.0 + + def test_build_tool_meshes_uses_per_tool_explicit_lengths(self): + tool_table = { + 1: ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + length=12.0, + flute_length=12.0, + ), + 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=10.0), + } + meshes, _ = build_tool_meshes(tool_table, scale=1.0) + + assert _mesh_height(meshes[1][0]) == pytest.approx(12.0) + assert _mesh_height(meshes[2][0]) == pytest.approx(10.0 * LENGTH_DIAMETER_FACTOR) + class TestExtractor: def test_extract_tool_table_returns_first_non_empty_parser_result(self): @@ -469,3 +664,19 @@ def test_extract_tool_table_returns_first_non_empty_parser_result(self): def test_extract_tool_table_returns_empty_dict_when_unrecognised(self): lines = ["G0 X0 Y0\n", "G1 X1 F100\n"] assert extract_tool_table(lines) == {} + + def test_extract_prefers_makera_studio_when_mkr_header_present(self): + lines = [ + ";@MKR|BEGIN\n", + ";@MKR|TOOL|number=1|id=1|name=Flat|type=Flat End|handlediameter=3.175|" + "sticklength=0|shoulderlength=12|flutelength=12|diameter=2|tipdiameter=2|" + "cornerradius=0|angle=0|halfAngle=0\n", + ";@MKR|END\n", + "(T1 Should be ignored D=99 CR=0 - flat end mill)\n", + "G0 X0\n", + ] + table = extract_tool_table(lines) + + assert table[1].diameter == 2.0 + assert table[1].shank_diameter == 3.175 + assert table[1].product_id == "1" From f4698675220e1ba4a447104a2b709dc5f65bc772 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:23:25 +0200 Subject: [PATCH 04/11] Fix formatting issues --- carveracontroller/addons/tool_visualization/tooltip_builder.py | 2 +- tests/unit/test_tool_visualization.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/carveracontroller/addons/tool_visualization/tooltip_builder.py b/carveracontroller/addons/tool_visualization/tooltip_builder.py index 3fdb42ee..0251bab1 100644 --- a/carveracontroller/addons/tool_visualization/tooltip_builder.py +++ b/carveracontroller/addons/tool_visualization/tooltip_builder.py @@ -59,6 +59,6 @@ def format_tool_tooltip(tool_def): lines.append(tool_def.description) if tool_def.vendor: - lines.append(" - {vendor}".format(vendor=tool_def.vendor)) + lines.append(f" - {tool_def.vendor}") return "\n".join(lines) diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index ba20f872..5934aec1 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -109,8 +109,7 @@ def test_infers_radius_mill_shank_from_outer_diameter(self, parser): def test_chamfer_mill_keeps_chamfer_type(self, parser): lines = [ - "(T1 Single Flute Engraving Metal 60 deg*.1mm D=3.175 CR=0. " - "TAPER=30deg - ZMIN=0. - chamfer mill)\n" + "(T1 Single Flute Engraving Metal 60 deg*.1mm D=3.175 CR=0. TAPER=30deg - ZMIN=0. - chamfer mill)\n" ] table = parser.parse(lines) From 14ca1c4c2f6aba1db7fd5d40f43831d3afcb5ed3 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Thu, 16 Jul 2026 19:34:15 +0200 Subject: [PATCH 05/11] Update unit test --- tests/unit/test_tool_visualization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index 5934aec1..13ccee51 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -258,7 +258,7 @@ def test_formats_full_tool_definition(self): ) tooltip = format_tool_tooltip(tool_def) - assert tooltip == ("T2 - Bull nose end mill\nD=6 CR=0.5 TAPER=5°\nRoughing endmill\nMakera - EM-6-05") + assert tooltip == ("T2 - Bull nose end mill\nD=6 CR=0.5 TAPER=5°\nRoughing endmill\n - Makera") def test_uses_enum_label_when_type_name_missing(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0) From 1f24fe5822c69f7661c66d473fb501df9cf3720c Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Fri, 17 Jul 2026 20:18:18 +0200 Subject: [PATCH 06/11] Fix tool mesh transparency rendering issues --- carveracontroller/GcodeViewer.py | 45 ++++++++++++++++----- carveracontroller/shaders/tool_pointer.glsl | 15 ++++--- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/carveracontroller/GcodeViewer.py b/carveracontroller/GcodeViewer.py index 3aefdc47..0dc5f079 100644 --- a/carveracontroller/GcodeViewer.py +++ b/carveracontroller/GcodeViewer.py @@ -672,11 +672,11 @@ def __init__(self): self.positions = [] # Per-tool generated meshes (tool number -> (vertices, indices, vertex_format)), - # rebuilt whenever a new file finishes loading. `pointer_mesh_instr` is the Mesh - # instruction whose geometry gets swapped as the active tool changes. + # rebuilt whenever a new file finishes loading. `pointer_mesh_instrs` holds the + # back-face then front-face Mesh pair whose geometry is swapped on tool change. self._tool_meshes = {} self._default_tool_mesh = None - self.pointer_mesh_instr = None + self.pointer_mesh_instrs = [] self._active_tool_number = None # Dirty flags: set True whenever the scene must be re-rendered. @@ -891,7 +891,7 @@ def clearDisplay(self): self.raw_tools = [] self._tool_meshes = {} self._default_tool_mesh = None - self.pointer_mesh_instr = None + self.pointer_mesh_instrs = [] self._active_tool_number = None self.linemesh.clear() self.canvas.remove(self.linemesh) @@ -951,16 +951,30 @@ def _log_tool_mesh_summary(self): f"from the tool table ({known}); using default (pointed) mesh for {unknown}" ) + def _setup_pointer_gl_back(self, *args): + """Draw back faces first so translucent tool surfaces sort correctly.""" + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) + + def _setup_pointer_gl_front(self, *args): + """Draw front faces second, blending over the back faces.""" + glCullFace(GL_BACK) + + def _reset_pointer_gl(self, *args): + glDisable(GL_CULL_FACE) + glCullFace(GL_BACK) + def _update_pointer_tool_mesh(self, vertex_idx): """Swap the pointer mesh geometry if the active tool changed.""" - if self.pointer_mesh_instr is None: + if not self.pointer_mesh_instrs: return tool_number = self._tool_number_at_index(vertex_idx) if tool_number == self._active_tool_number: return vertices, indices, _fmt = self._get_tool_mesh(tool_number) - self.pointer_mesh_instr.vertices = vertices - self.pointer_mesh_instr.indices = indices + for mesh in self.pointer_mesh_instrs: + mesh.vertices = vertices + mesh.indices = indices self._active_tool_number = tool_number self._scene_dirty = True @@ -1049,15 +1063,26 @@ def load_array(self, tmpdataarrs, is_end=True): self.cb = Callback(None) with self.pointermesh: - self.cb = Callback(None) + # Two-pass translucent draw: back faces, then front faces. + # A single pass fights the depth buffer and makes one side of the + # tool look hollow depending on camera orientation. verts, idxs, fmt = self._get_tool_mesh(self._active_tool_number) - self.pointer_mesh_instr = Mesh( + Callback(self._setup_pointer_gl_back) + back_mesh = Mesh( vertices=verts, indices=idxs, fmt=fmt, mode="triangles", ) - self.cb = Callback(None) + Callback(self._setup_pointer_gl_front) + front_mesh = Mesh( + vertices=verts, + indices=idxs, + fmt=fmt, + mode="triangles", + ) + Callback(self._reset_pointer_gl) + self.pointer_mesh_instrs = [back_mesh, front_mesh] # axis with self.axisxmesh: diff --git a/carveracontroller/shaders/tool_pointer.glsl b/carveracontroller/shaders/tool_pointer.glsl index 78aa8ebb..a7e955d1 100644 --- a/carveracontroller/shaders/tool_pointer.glsl +++ b/carveracontroller/shaders/tool_pointer.glsl @@ -1,4 +1,5 @@ -// Tool position pointer mesh with simple diffuse shading +// Tool position pointer mesh with simple diffuse shading. +// Drawn in two passes (back faces, then front faces) for correct translucency. ---vertex $HEADER$ @@ -9,14 +10,15 @@ attribute vec3 v_normal; uniform vec3 offset; uniform mat4 rotation; -varying vec4 normal_vec; +varying vec3 normal_vec; void main() { vec4 rotated = rotation * vec4(v_pos, 1.0); vec3 world_pos = rotated.xyz + offset; vec4 eye_pos = modelview_mat * vec4(world_pos, 1.0); - normal_vec = vec4(v_normal, 0.0); + // Transform normals with the same rotation + view as positions (w=0 skips translation). + normal_vec = (modelview_mat * rotation * vec4(v_normal, 0.0)).xyz; tex_coord0 = vec2(0.0); gl_Position = projection_mat * eye_pos; } @@ -24,11 +26,14 @@ void main() ---fragment $HEADER$ -varying vec4 normal_vec; +varying vec3 normal_vec; void main() { - float shade = abs(dot(normal_vec.xyz, vec3(1.0, 1.0, 1.0))); + // abs() keeps both shell passes lit; light is fixed in view space so shading + // stays stable while orbiting the camera. + vec3 n = normalize(normal_vec); + float shade = 0.35 + 0.65 * abs(dot(n, normalize(vec3(0.35, 0.55, 1.0)))); vec3 color = vec3(0.3, 0.3, 1.0) * shade; gl_FragColor = vec4(color, 0.3) * texture2D(texture0, tex_coord0); } From 3382e0160cfcb664ee4c068cbb938fa1b8e8be07 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Sat, 18 Jul 2026 15:52:52 +0200 Subject: [PATCH 07/11] Add flute/shoulder/shank transition support (mesh + color) --- .../addons/tool_visualization/mesh_builder.py | 366 ++++++++++++++---- .../parsers/makera_studio.py | 15 +- .../tool_visualization/tool_definition.py | 1 + .../tool_visualization/tooltip_builder.py | 2 + carveracontroller/shaders/tool_pointer.glsl | 7 +- tests/unit/test_tool_visualization.py | 283 +++++++++++++- 6 files changed, 573 insertions(+), 101 deletions(-) diff --git a/carveracontroller/addons/tool_visualization/mesh_builder.py b/carveracontroller/addons/tool_visualization/mesh_builder.py index 63d47947..d0ba3b7d 100644 --- a/carveracontroller/addons/tool_visualization/mesh_builder.py +++ b/carveracontroller/addons/tool_visualization/mesh_builder.py @@ -6,7 +6,17 @@ from carveracontroller.addons.tool_visualization.tool_definition import ToolType -VERTEX_FORMAT = [(b"v_pos", 3, "float"), (b"v_normal", 3, "float"), (b"v_tc0", 2, "float")] +FLUTE_COLOR = (0.3, 0.3, 1.0) +SHANK_COLOR = (0.15, 0.55, 0.55) + +VERTEX_FORMAT = [ + (b"v_pos", 3, "float"), + (b"v_normal", 3, "float"), + (b"v_color", 3, "float"), + (b"v_tc0", 2, "float"), +] + +FLOATS_PER_VERTEX = 11 RADIAL_SEGMENTS = 20 ROUND_SEGMENTS = 10 DEFAULT_TAPER_ANGLE_DEG = 30.0 @@ -14,6 +24,17 @@ # Factor used to compute the shared tool height from the largest diameter in the table. LENGTH_DIAMETER_FACTOR = 3.0 +# Flute -> shank blend: axial rise per unit radial change (~45°), capped as a +# fraction of the available shank length so some cylinder remains above. +SHANK_TRANSITION_SLOPE = 1.0 +SHANK_TRANSITION_MAX_FRACTION = 0.5 + +# When flute is tip-inferred and shoulder metadata is missing, extend +# a short cutting-diameter body before the shank so the tip does not +# jump straight into the handle. Capped to half the remaining stick-out. +INFERRED_SHOULDER_DIAMETER_FACTOR = 1.0 +INFERRED_SHOULDER_MAX_FRACTION = 0.5 + # Minimum radius and length for tools to be visible on screen. MIN_VISIBLE_RADIUS = 0.02 MIN_SHANK_LENGTH = 0.05 @@ -64,13 +85,18 @@ def _surface_normal(dz, dr, theta): return (nx / length, ny / length, nz / length) -def _add_vertex(positions, normals, x, y, z, nx, ny, nz): +def _profile_color(index, shank_start_index): + return SHANK_COLOR if index >= shank_start_index else FLUTE_COLOR + + +def _add_vertex(positions, normals, colors, x, y, z, nx, ny, nz, color): positions.extend([x, y, z]) normals.extend([nx, ny, nz]) + colors.extend(color) return (len(positions) // 3) - 1 -def _build_side_ring(positions, normals, z, radius, dz, dr, segments): +def _build_side_ring(positions, normals, colors, z, radius, dz, dr, segments, color): """Add one ring of side-wall vertices with smooth analytical normals.""" ring_indices = [] for j in range(segments): @@ -78,24 +104,24 @@ def _build_side_ring(positions, normals, z, radius, dz, dr, segments): cos_t = math.cos(theta) sin_t = math.sin(theta) nx, ny, nz = _surface_normal(dz, dr, theta) - idx = _add_vertex(positions, normals, radius * cos_t, radius * sin_t, z, nx, ny, nz) + idx = _add_vertex(positions, normals, colors, radius * cos_t, radius * sin_t, z, nx, ny, nz, color) ring_indices.append(idx) return ring_indices -def _build_cap_ring(positions, normals, z, radius, nz_sign, segments): +def _build_cap_ring(positions, normals, colors, z, radius, nz_sign, segments, color): """Add a ring of cap vertices with a flat face normal (±Z).""" ring_indices = [] for j in range(segments): theta = 2.0 * math.pi * j / segments cos_t = math.cos(theta) sin_t = math.sin(theta) - idx = _add_vertex(positions, normals, radius * cos_t, radius * sin_t, z, 0.0, 0.0, nz_sign) + idx = _add_vertex(positions, normals, colors, radius * cos_t, radius * sin_t, z, 0.0, 0.0, nz_sign, color) ring_indices.append(idx) return ring_indices -def _pack_vertices(positions, normals): +def _pack_vertices(positions, normals, colors): vertices = [] for i in range(len(positions) // 3): base = 3 * i @@ -107,6 +133,9 @@ def _pack_vertices(positions, normals): normals[base], normals[base + 1], normals[base + 2], + colors[base], + colors[base + 1], + colors[base + 2], 0.0, 0.0, ] @@ -114,7 +143,13 @@ def _pack_vertices(positions, normals): return vertices -def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): +def _coincident_profile_points(profile, start, end): + z0, r0 = profile[start] + z1, r1 = profile[end] + return abs(z0 - z1) <= 1e-9 and abs(r0 - r1) <= 1e-9 + + +def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS, shank_start_index=None): """Revolve a `(z, radius)` profile (sorted by increasing z) into a triangle mesh. A profile point with `radius <= 0` is treated as a single point on the @@ -122,12 +157,20 @@ def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): Vertices are indexed and share smooth analytical normals derived from the profile tangent. Flat end caps use separate vertices with ±Z normals. + + Profile points at index >= `shank_start_index` are colored as SHANK_COLOR; + earlier points keep the flute FLUTE_COLOR. When omitted, the whole tool is color + using FLUTE_COLOR. """ if len(profile) < 2: raise ValueError("A tool profile needs at least two points") + if shank_start_index is None: + shank_start_index = len(profile) + positions = [] normals = [] + colors = [] indices = [] side_rings = [] @@ -136,10 +179,15 @@ def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): side_rings.append(None) else: dz, dr = _ring_tangent(profile, i) - side_rings.append(_build_side_ring(positions, normals, z, r, dz, dr, segments)) + color = _profile_color(i, shank_start_index) + side_rings.append(_build_side_ring(positions, normals, colors, z, r, dz, dr, segments, color)) # Side walls, connecting each consecutive pair of profile points. for i in range(len(profile) - 1): + # Duplicate rings at the flute/shank boundary create a hard color edge + # without emitting a degenerate zero-area quad. + if _coincident_profile_points(profile, i, i + 1): + continue ring_a = side_rings[i] ring_b = side_rings[i + 1] if ring_a is None and ring_b is None: @@ -148,7 +196,8 @@ def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): z_apex = profile[i][0] dz, dr = _segment_tangent(profile, i, i + 1) nx, ny, nz = _surface_normal(dz, dr, 0.0) - apex_idx = _add_vertex(positions, normals, 0.0, 0.0, z_apex, nx, ny, nz) + color = _profile_color(i, shank_start_index) + apex_idx = _add_vertex(positions, normals, colors, 0.0, 0.0, z_apex, nx, ny, nz, color) for j in range(segments): b0 = ring_b[j] b1 = ring_b[(j + 1) % segments] @@ -157,7 +206,8 @@ def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): z_apex = profile[i + 1][0] dz, dr = _segment_tangent(profile, i, i + 1) nx, ny, nz = _surface_normal(dz, dr, 0.0) - apex_idx = _add_vertex(positions, normals, 0.0, 0.0, z_apex, nx, ny, nz) + color = _profile_color(i + 1, shank_start_index) + apex_idx = _add_vertex(positions, normals, colors, 0.0, 0.0, z_apex, nx, ny, nz, color) for j in range(segments): a0 = ring_a[j] a1 = ring_a[(j + 1) % segments] @@ -173,19 +223,21 @@ def _build_revolve_mesh(profile, segments=RADIAL_SEGMENTS): # Flat caps use their own vertices so side-wall normals are not overwritten. z_bottom, r_bottom = profile[0] if r_bottom > 1e-9: - center_idx = _add_vertex(positions, normals, 0.0, 0.0, z_bottom, 0.0, 0.0, -1.0) - cap_ring = _build_cap_ring(positions, normals, z_bottom, r_bottom, -1.0, segments) + bottom_color = _profile_color(0, shank_start_index) + center_idx = _add_vertex(positions, normals, colors, 0.0, 0.0, z_bottom, 0.0, 0.0, -1.0, bottom_color) + cap_ring = _build_cap_ring(positions, normals, colors, z_bottom, r_bottom, -1.0, segments, bottom_color) for j in range(segments): indices.extend([center_idx, cap_ring[(j + 1) % segments], cap_ring[j]]) z_top, r_top = profile[-1] if r_top > 1e-9: - center_idx = _add_vertex(positions, normals, 0.0, 0.0, z_top, 0.0, 0.0, 1.0) - cap_ring = _build_cap_ring(positions, normals, z_top, r_top, 1.0, segments) + top_color = _profile_color(len(profile) - 1, shank_start_index) + center_idx = _add_vertex(positions, normals, colors, 0.0, 0.0, z_top, 0.0, 0.0, 1.0, top_color) + cap_ring = _build_cap_ring(positions, normals, colors, z_top, r_top, 1.0, segments, top_color) for j in range(segments): indices.extend([center_idx, cap_ring[j], cap_ring[(j + 1) % segments]]) - return _pack_vertices(positions, normals), indices, VERTEX_FORMAT + return _pack_vertices(positions, normals, colors), indices, VERTEX_FORMAT def _tool_diameter(tool_def, scale): @@ -210,7 +262,12 @@ def _has_explicit_length(tool_def): return False length = getattr(tool_def, "length", None) flute_length = getattr(tool_def, "flute_length", None) - return (length is not None and length > 0) or (flute_length is not None and flute_length > 0) + shoulder_length = getattr(tool_def, "shoulder_length", None) + return ( + (length is not None and length > 0) + or (flute_length is not None and flute_length > 0) + or (shoulder_length is not None and shoulder_length > 0) + ) def _profile_length(tool_def, scale, diameter, shared_length=None): @@ -218,6 +275,9 @@ def _profile_length(tool_def, scale, diameter, shared_length=None): length = getattr(tool_def, "length", None) if length is not None and length > 0: return length + shoulder_length = getattr(tool_def, "shoulder_length", None) + if shoulder_length is not None and shoulder_length > 0: + return shoulder_length flute_length = getattr(tool_def, "flute_length", None) if flute_length is not None and flute_length > 0: return flute_length @@ -228,15 +288,132 @@ def _profile_length(tool_def, scale, diameter, shared_length=None): return fallback_tool_dimensions(scale)[1] -def _resolve_cutting_overall_length(tool_def, overall_length): - """Return (cutting_length, overall_length), splitting on flute when possible.""" +def _chamfer_cone_height(diameter, taper_angle_deg=DEFAULT_TAPER_ANGLE_DEG, tip_diameter=0.0): + """Axial height of the conical cutting tip for chamfer / engraving tools.""" + radius = diameter / 2.0 + tip_radius = max(tip_diameter or 0.0, 0.0) / 2.0 + tip_radius = min(tip_radius, radius) + + half_angle_rad = math.radians(taper_angle_deg) / 2.0 + half_angle_rad = min(max(half_angle_rad, math.radians(5.0)), math.radians(85.0)) + + if tip_radius <= 1e-9: + return radius / math.tan(half_angle_rad) + radial_rise = radius - tip_radius + if radial_rise <= 1e-9: + return 0.0 + return radial_rise / math.tan(half_angle_rad) + + +def _lollipop_neck_radius(diameter): + radius = diameter / 2.0 + neck_radius = max(radius * 0.35, diameter * 0.15) + return min(neck_radius, radius * 0.95) + + +def _lollipop_ball_join_z(diameter): + """Z where the spherical cutter meets the neck cylinder.""" + radius = diameter / 2.0 + neck_radius = _lollipop_neck_radius(diameter) + theta_join = math.acos(neck_radius / radius) + return radius + radius * math.sin(theta_join) + + +def _infer_flute_length(tool_def): + """Guess flute length from tip geometry when CAM metadata omits it: + - Chamfer / engraving: Cone height from diameter + taper (+ tip Ø) + - Lollipop: Sphere -> neck join + - Ball end: One diameter (hemisphere + short cylinder) + - Thread mill: One tooth ≈ pitch + + Returns None when the type has no reliable tip-only cue (e.g. flat end mill). + Only used when building the mesh, this doesn't change tool definitions. + """ if not tool_def: - return overall_length, overall_length - length = getattr(tool_def, "length", None) - flute_length = getattr(tool_def, "flute_length", None) - if length is not None and length > 0 and flute_length is not None and flute_length > 0 and length > flute_length: - return flute_length, length - return overall_length, overall_length + return None + + tool_type = getattr(tool_def, "tool_type", None) + diameter = getattr(tool_def, "diameter", None) + if diameter is None or diameter <= 0: + return None + + if tool_type is ToolType.LOLLIPOP_MILL: + return _lollipop_ball_join_z(diameter) + + if tool_type in (ToolType.CHAMFER_MILL, ToolType.ENGRAVING): + taper = _safe_taper_angle_deg(tool_def) + tip_diameter = _safe_tip_diameter(tool_def, diameter) + height = _chamfer_cone_height(diameter, taper, tip_diameter) + return height if height > 1e-9 else None + + if tool_type is ToolType.BALL_END_MILL: + # Hemisphere plus a short matching cylinder — distinctive tip region. + return diameter + + if tool_type is ToolType.THREAD_MILL: + return _safe_thread_pitch(tool_def, diameter) + + return None + + +def _inferred_shoulder_length(tool_def, flute, overall): + """Short cutting-diameter body above an inferred flute tip.""" + available = overall - flute + if available <= 1e-9: + return flute + + diameter = getattr(tool_def, "diameter", None) or 0.0 + extra = min( + max(diameter, 0.0) * INFERRED_SHOULDER_DIAMETER_FACTOR, + available * INFERRED_SHOULDER_MAX_FRACTION, + available, + ) + return flute + extra + + +def _resolve_section_lengths(tool_def, fallback_overall): + """Return `(flute_z, shoulder_z, overall_z)` in file units. + + - flute_z: cutting flutes (blue) + - shoulder_z: end of cutting-diameter body; shank blend starts here + - overall_z: total stick-out (sticklength) + + When flute length is missing, tip-defined tools (chamfer, lollipop, etc.) get a + geometry-based guess. When shoulder is also missing after a tip inference, + a short cutting-diameter shoulder is added so the shank does not start at + the tip. Explicit flute with no shoulder still steps at the flute length. + """ + if not tool_def: + return fallback_overall, fallback_overall, fallback_overall + + overall = getattr(tool_def, "length", None) + flute = getattr(tool_def, "flute_length", None) + shoulder = getattr(tool_def, "shoulder_length", None) + + if overall is None or overall <= 0: + overall = fallback_overall + + flute_was_inferred = False + if flute is None or flute <= 0: + inferred = _infer_flute_length(tool_def) + if inferred is not None and inferred > 0: + flute = inferred + flute_was_inferred = True + elif shoulder is not None and shoulder > 0: + flute = shoulder + else: + flute = overall + + flute = min(flute, overall) + + if shoulder is None or shoulder <= 0: + if flute_was_inferred: + shoulder = _inferred_shoulder_length(tool_def, flute, overall) + else: + shoulder = flute + + shoulder = min(max(shoulder, flute), overall) + return flute, shoulder, overall def _shank_radius(tool_def, cutting_radius): @@ -253,26 +430,39 @@ def _safe_tip_diameter(tool_def, diameter): return min(tip_diameter, diameter) -def _append_shank_section(points, cutting_length, overall_length, shank_radius): - """Extend a cutting profile with an optional cylindrical shank above it.""" +def _append_shank_geometry(points, shoulder_z, overall_z, shank_radius): + """Append a conical blend + cylindrical shank above `shoulder_z`. + + When the shank radius differs from the body, a short ~45° cone joins them + instead of a hard radial step. Returns the extended profile list. + """ if not points: return points + points = list(points) last_z, last_r = points[-1] - # Tip geometry may already exceed the requested flute length (e.g. ball nose). - cutting_z = max(cutting_length, last_z) - if cutting_z > last_z + 1e-9: - points = list(points) + [(cutting_z, last_r)] - last_z, last_r = cutting_z, last_r - else: - points = list(points) + shoulder_z = max(shoulder_z, last_z) + if shoulder_z > last_z + 1e-9: + points.append((shoulder_z, last_r)) + last_z, last_r = shoulder_z, last_r - if overall_length <= cutting_z + 1e-9: + if overall_z <= shoulder_z + 1e-9: return points - if abs(shank_radius - last_r) > 1e-9: - points.append((cutting_z, shank_radius)) - points.append((overall_length, shank_radius)) + available = overall_z - shoulder_z + radial_delta = abs(shank_radius - last_r) + if radial_delta > 1e-9: + transition = min( + radial_delta * SHANK_TRANSITION_SLOPE, + available * SHANK_TRANSITION_MAX_FRACTION, + available, + ) + if transition > 1e-9: + points.append((shoulder_z + transition, shank_radius)) + else: + points.append((shoulder_z, shank_radius)) + + points.append((overall_z, shank_radius)) return points @@ -335,14 +525,14 @@ def _thread_mill_profile(diameter, length, thread_depth=0.0, thread_pitch=0.0, * def _ball_end_mill_profile(diameter, length, **_kwargs): radius = diameter / 2.0 - length = max(length, diameter) points = [] for i in range(ROUND_SEGMENTS + 1): theta = -math.pi / 2.0 + (math.pi / 2.0) * (i / ROUND_SEGMENTS) z = radius + radius * math.sin(theta) r = radius * math.cos(theta) points.append((z, r)) - points.append((length, radius)) + if length > radius + 1e-9: + points.append((length, radius)) return points @@ -394,16 +584,11 @@ def _chamfer_or_tapered_profile(diameter, length, taper_angle_deg=DEFAULT_TAPER_ radius = diameter / 2.0 tip_radius = max(tip_diameter or 0.0, 0.0) / 2.0 tip_radius = min(tip_radius, radius) - - half_angle_rad = math.radians(taper_angle_deg) / 2.0 - half_angle_rad = min(max(half_angle_rad, math.radians(5.0)), math.radians(85.0)) + cone_height = _chamfer_cone_height(diameter, taper_angle_deg, tip_diameter) if tip_radius <= 1e-9: - cone_height = radius / math.tan(half_angle_rad) points = [(0.0, 0.0), (cone_height, radius)] else: - radial_rise = radius - tip_radius - cone_height = radial_rise / math.tan(half_angle_rad) if radial_rise > 1e-9 else 0.0 points = [(0.0, tip_radius)] if cone_height > 1e-9: points.append((cone_height, radius)) @@ -455,8 +640,7 @@ def _tapered_mill_profile(diameter, length, corner_radius=0.0, taper_angle_deg=D def _lollipop_profile(diameter, length, **_kwargs): """Full spherical cutter with a thinner cylindrical neck above the undercut.""" radius = diameter / 2.0 - neck_radius = max(radius * 0.35, diameter * 0.15) - neck_radius = min(neck_radius, radius * 0.95) + neck_radius = _lollipop_neck_radius(diameter) theta_join = math.acos(neck_radius / radius) points = [] @@ -478,8 +662,10 @@ def _lollipop_profile(diameter, length, **_kwargs): ball_join_z = points[-1][0] points[-1] = (ball_join_z, neck_radius) - total_length = max(length, ball_join_z + diameter * 0.5) - points.append((total_length, neck_radius)) + # Neck extension is optional: overall stick-out above the ball is added by + # the shoulder/shank pass when flute length ends at the sphere. + if length > ball_join_z + 1e-9: + points.append((length, neck_radius)) return points @@ -544,16 +730,22 @@ def _reference_length(tool_table, scale): return fallback_tool_dimensions(scale)[1] -def tool_profile(tool_def, length=None, scale=1.0): - """Return the (unscaled) profile for a tool definition. +def _tool_profile_with_shank(tool_def, length=None, scale=1.0): + """Return `(profile, color_shank_start_index)` for a tool definition. + + Geometry sections (when metadata allows): + - tip → flute_z: cutting flutes at tool diameter (blue) + - flute_z → shoulder_z: same diameter body / shoulder (teal) + - shoulder_z → overall_z: blend + handle/shank diameter (teal) + Falls back to a basic pointed (chamfer-like) profile when `tool_def` is None or its type is unknown/unsupported (see DEFAULT_PROFILE_BUILDER). Missing diameters use the fixed on-screen fallback size. """ diameter = _tool_diameter(tool_def, scale) effective_diameter = _effective_tool_diameter(tool_def, scale) - overall_length = _profile_length(tool_def, scale, effective_diameter, length) - cutting_length, overall_length = _resolve_cutting_overall_length(tool_def, overall_length) + fallback_overall = _profile_length(tool_def, scale, effective_diameter, length) + flute_z, shoulder_z, overall_z = _resolve_section_lengths(tool_def, fallback_overall) tool_type = getattr(tool_def, "tool_type", ToolType.UNKNOWN) if tool_def else ToolType.UNKNOWN corner_radius = _safe_corner_radius(tool_def, diameter, tool_type) taper_angle_deg = _safe_taper_angle_deg(tool_def) @@ -565,7 +757,7 @@ def tool_profile(tool_def, length=None, scale=1.0): profile = builder( diameter, - cutting_length, + flute_z, corner_radius=corner_radius, taper_angle_deg=taper_angle_deg, tip_diameter=tip_diameter, @@ -573,24 +765,44 @@ def tool_profile(tool_def, length=None, scale=1.0): thread_pitch=thread_pitch, ) - # Tapered mills and lollipops already encode body/neck geometry; only append - # a constant shank when the parser provided an explicit shank diameter, or - # for other tool types that use a cylindrical shaft above the flute. - cutting_radius = profile[-1][1] if profile else effective_diameter / 2.0 - if tool_type in (ToolType.TAPERED_MILL, ToolType.LOLLIPOP_MILL): - shank_diameter = getattr(tool_def, "shank_diameter", None) if tool_def else None - if shank_diameter is None or shank_diameter <= 0: - if overall_length > profile[-1][0] + 1e-9: - # Extend along the existing end radius without inventing a shank step. - profile = list(profile) + [(overall_length, profile[-1][1])] - return profile - - return _append_shank_section( + profile = list(profile) + last_z, last_r = profile[-1] + # Tip geometry (e.g. ball nose) may already exceed the requested flute length. + flute_tip_z = max(flute_z, last_z) + if flute_tip_z > last_z + 1e-9: + profile.append((flute_tip_z, last_r)) + last_z, last_r = flute_tip_z, last_r + else: + flute_tip_z = last_z + + shoulder_z = max(shoulder_z, flute_tip_z) + overall_z = max(overall_z, shoulder_z) + + has_non_flute = overall_z > flute_tip_z + 1e-9 + if has_non_flute: + color_start = len(profile) + # Coincident ring → hard blue/teal edge at the end of the flutes. + profile.append((flute_tip_z, last_r)) + else: + color_start = len(profile) + + if shoulder_z > flute_tip_z + 1e-9: + profile.append((shoulder_z, last_r)) + + cutting_radius = last_r + profile = _append_shank_geometry( profile, - cutting_length, - overall_length, + shoulder_z, + overall_z, _shank_radius(tool_def, cutting_radius), ) + return profile, color_start + + +def tool_profile(tool_def, length=None, scale=1.0): + """Return the (unscaled) profile for a tool definition.""" + profile, _shank_start = _tool_profile_with_shank(tool_def, length=length, scale=scale) + return profile def _scale_profile(profile, scale, radius_boost): @@ -628,9 +840,9 @@ def _compute_radius_boost(profiles, scale): def build_tool_mesh(tool_def, scale=1.0, radius_boost=1.0, length=None): - profile = tool_profile(tool_def, length=length, scale=scale) + profile, shank_start = _tool_profile_with_shank(tool_def, length=length, scale=scale) scaled_profile = _scale_profile(profile, scale, radius_boost) - return _build_revolve_mesh(scaled_profile) + return _build_revolve_mesh(scaled_profile, shank_start_index=shank_start) def build_default_tool_mesh(scale=1.0, radius_boost=1.0): @@ -662,12 +874,18 @@ def build_tool_meshes(tool_table, scale=1.0): if tool_table: shared_length = _reference_length(tool_table, scale) profiles = {} + shank_starts = {} for number, tool_def in tool_table.items(): length_hint = None if _has_explicit_length(tool_def) else shared_length - profiles[number] = tool_profile(tool_def, length=length_hint, scale=scale) + profile, shank_start = _tool_profile_with_shank(tool_def, length=length_hint, scale=scale) + profiles[number] = profile + shank_starts[number] = shank_start radius_boost = _compute_radius_boost(list(profiles.values()), scale) tool_meshes = { - number: _build_revolve_mesh(_scale_profile(profile, scale, radius_boost)) + number: _build_revolve_mesh( + _scale_profile(profile, scale, radius_boost), + shank_start_index=shank_starts[number], + ) for number, profile in profiles.items() } else: diff --git a/carveracontroller/addons/tool_visualization/parsers/makera_studio.py b/carveracontroller/addons/tool_visualization/parsers/makera_studio.py index 7e4e2948..b64e4602 100644 --- a/carveracontroller/addons/tool_visualization/parsers/makera_studio.py +++ b/carveracontroller/addons/tool_visualization/parsers/makera_studio.py @@ -93,12 +93,12 @@ def _taper_angle_from_fields(fields): return None -def _length_from_fields(fields): - for key in ("sticklength", "shoulderlength"): - length = _positive_or_none(_to_float(fields.get(key))) - if length is not None: - return length - return None +def _stick_length_from_fields(fields): + """Overall stick-out: prefer sticklength, fall back to shoulderlength.""" + stick = _positive_or_none(_to_float(fields.get("sticklength"))) + if stick is not None: + return stick + return _positive_or_none(_to_float(fields.get("shoulderlength"))) class MakeraStudioParser(ToolTableParser): @@ -151,8 +151,9 @@ def _build_tool_definition(number, fields): tip_diameter=_to_float(fields.get("tipdiameter")), corner_radius=_to_float(fields.get("cornerradius")), taper_angle_deg=_taper_angle_from_fields(fields), - length=_length_from_fields(fields), + length=_stick_length_from_fields(fields), flute_length=_positive_or_none(_to_float(fields.get("flutelength"))), + shoulder_length=_positive_or_none(_to_float(fields.get("shoulderlength"))), description=fields.get("name", "") or "", product_id=fields.get("id", "") or "", type_name=type_name, diff --git a/carveracontroller/addons/tool_visualization/tool_definition.py b/carveracontroller/addons/tool_visualization/tool_definition.py index 43a18a4f..cc7aeed7 100644 --- a/carveracontroller/addons/tool_visualization/tool_definition.py +++ b/carveracontroller/addons/tool_visualization/tool_definition.py @@ -51,6 +51,7 @@ class ToolDefinition: taper_angle_deg: float | None = None length: float | None = None flute_length: float | None = None + shoulder_length: float | None = None thread_depth: float | None = None thread_pitch: float | None = None description: str = "" diff --git a/carveracontroller/addons/tool_visualization/tooltip_builder.py b/carveracontroller/addons/tool_visualization/tooltip_builder.py index 0251bab1..6194743f 100644 --- a/carveracontroller/addons/tool_visualization/tooltip_builder.py +++ b/carveracontroller/addons/tool_visualization/tooltip_builder.py @@ -48,6 +48,8 @@ def format_tool_tooltip(tool_def): dimensions.append(tr._("L={value:g}").format(value=tool_def.length)) if tool_def.flute_length is not None: dimensions.append(tr._("FL={value:g}").format(value=tool_def.flute_length)) + if tool_def.shoulder_length is not None: + dimensions.append(tr._("SH={value:g}").format(value=tool_def.shoulder_length)) if tool_def.thread_depth is not None: dimensions.append(tr._("Thread depth={value:g}").format(value=tool_def.thread_depth)) if tool_def.thread_pitch is not None: diff --git a/carveracontroller/shaders/tool_pointer.glsl b/carveracontroller/shaders/tool_pointer.glsl index a7e955d1..9611ad51 100644 --- a/carveracontroller/shaders/tool_pointer.glsl +++ b/carveracontroller/shaders/tool_pointer.glsl @@ -1,16 +1,19 @@ // Tool position pointer mesh with simple diffuse shading. // Drawn in two passes (back faces, then front faces) for correct translucency. +// Vertex colors distinguish flute (blue) from shank (teal) when available. ---vertex $HEADER$ attribute vec3 v_pos; attribute vec3 v_normal; +attribute vec3 v_color; uniform vec3 offset; uniform mat4 rotation; varying vec3 normal_vec; +varying vec3 tool_color; void main() { @@ -19,6 +22,7 @@ void main() vec4 eye_pos = modelview_mat * vec4(world_pos, 1.0); // Transform normals with the same rotation + view as positions (w=0 skips translation). normal_vec = (modelview_mat * rotation * vec4(v_normal, 0.0)).xyz; + tool_color = v_color; tex_coord0 = vec2(0.0); gl_Position = projection_mat * eye_pos; } @@ -27,6 +31,7 @@ void main() $HEADER$ varying vec3 normal_vec; +varying vec3 tool_color; void main() { @@ -34,6 +39,6 @@ void main() // stays stable while orbiting the camera. vec3 n = normalize(normal_vec); float shade = 0.35 + 0.65 * abs(dot(n, normalize(vec3(0.35, 0.55, 1.0)))); - vec3 color = vec3(0.3, 0.3, 1.0) * shade; + vec3 color = tool_color * shade; gl_FragColor = vec4(color, 0.3) * texture2D(texture0, tex_coord0); } diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index 13ccee51..4a2c0599 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -14,8 +14,12 @@ from carveracontroller.addons.tool_visualization.mesh_builder import ( FALLBACK_TOOL_DISPLAY_HEIGHT, FALLBACK_TOOL_DISPLAY_RADIUS, + FLOATS_PER_VERTEX, + FLUTE_COLOR, + INFERRED_SHOULDER_DIAMETER_FACTOR, LENGTH_DIAMETER_FACTOR, MIN_VISIBLE_RADIUS, + SHANK_COLOR, VERTEX_FORMAT, _reference_length, build_tool_mesh, @@ -38,7 +42,7 @@ def _max_xy_radius(vertices): radii = [] - for i in range(0, len(vertices), 8): + for i in range(0, len(vertices), FLOATS_PER_VERTEX): x = vertices[i] y = vertices[i + 1] radii.append(math.hypot(x, y)) @@ -46,20 +50,34 @@ def _max_xy_radius(vertices): def _mesh_height(vertices): - zs = [vertices[i + 2] for i in range(0, len(vertices), 8)] + zs = [vertices[i + 2] for i in range(0, len(vertices), FLOATS_PER_VERTEX)] return max(zs) - min(zs) if zs else 0.0 def _apex_vertex_indices(vertices, tol=1e-6): - zs = [vertices[i + 2] for i in range(0, len(vertices), 8)] + zs = [vertices[i + 2] for i in range(0, len(vertices), FLOATS_PER_VERTEX)] z_min = min(zs) return [ - i // 8 - for i in range(0, len(vertices), 8) + i // FLOATS_PER_VERTEX + for i in range(0, len(vertices), FLOATS_PER_VERTEX) if abs(vertices[i + 2] - z_min) < tol and math.hypot(vertices[i], vertices[i + 1]) < tol ] +def _vertex_normal(vertices, index): + base = index * FLOATS_PER_VERTEX + return (vertices[base + 3], vertices[base + 4], vertices[base + 5]) + + +def _vertex_color(vertices, index): + base = index * FLOATS_PER_VERTEX + return (vertices[base + 6], vertices[base + 7], vertices[base + 8]) + + +def _vertex_z(vertices, index): + return vertices[index * FLOATS_PER_VERTEX + 2] + + class TestFusion360MakeraParser: @pytest.fixture def parser(self): @@ -175,11 +193,38 @@ def test_parses_sample_flat_end_header(self, parser): assert tool.corner_radius == 0.0 assert tool.length == 12.0 assert tool.flute_length == 12.0 + assert tool.shoulder_length == 12.0 assert tool.description == "3.175*2*12mm Flat End" assert tool.product_id == "111011203812" assert tool.type_name == "Flat End" assert tool.taper_angle_deg is None + def test_parses_distinct_flute_shoulder_and_stick_lengths(self, parser): + lines = [ + ";@MKR|TOOL|number=1|id=111011203812|name=3.175*2*12mm Flat End|type=Flat End|" + "handlediameter=3.175|sticklength=12|shoulderlength=6|flutelength=6|diameter=2|" + "tipdiameter=2|cornerradius=0|angle=0|halfAngle=0\n" + ] + tool = parser.parse(lines)[1] + + assert tool.diameter == 2.0 + assert tool.shank_diameter == 3.175 + assert tool.flute_length == 6.0 + assert tool.shoulder_length == 6.0 + assert tool.length == 12.0 + + def test_parses_shoulder_equal_to_stick_without_shank_body(self, parser): + lines = [ + ";@MKR|TOOL|number=1|id=111011203812|name=3.175*2*12mm Flat End|type=Flat End|" + "handlediameter=3.175|sticklength=12|shoulderlength=12|flutelength=6|diameter=2|" + "tipdiameter=2|cornerradius=0|angle=0|halfAngle=0\n" + ] + tool = parser.parse(lines)[1] + + assert tool.flute_length == 6.0 + assert tool.shoulder_length == 12.0 + assert tool.length == 12.0 + def test_parses_engraving_half_angle_as_included_taper(self, parser): lines = [ ";@MKR|TOOL|number=2|id=abc|name=V-bit|type=Engraving|handlediameter=3.175|" @@ -194,6 +239,7 @@ def test_parses_engraving_half_angle_as_included_taper(self, parser): assert tool.tip_diameter == 0.1 assert tool.length == 20.0 assert tool.flute_length == 12.0 + assert tool.shoulder_length is None assert tool.shank_diameter == 3.175 def test_unknown_type_falls_back_to_unknown(self, parser): @@ -282,19 +328,14 @@ def test_includes_shank_length_and_flute_when_present(self): assert "Engraving" in tooltip -def _vertex_normal(vertices, index): - base = index * 8 - return (vertices[base + 3], vertices[base + 4], vertices[base + 5]) - - class TestMeshBuilder: def test_build_tool_mesh_uses_expected_vertex_layout(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0) vertices, indices, fmt = build_tool_mesh(tool_def) - vertex_count = len(vertices) // 8 + vertex_count = len(vertices) // FLOATS_PER_VERTEX assert fmt == VERTEX_FORMAT - assert len(vertices) % 8 == 0 + assert len(vertices) % FLOATS_PER_VERTEX == 0 assert len(indices) % 3 == 0 assert all(0 <= index < vertex_count for index in indices) assert len(indices) > vertex_count @@ -388,7 +429,7 @@ def test_build_tool_meshes_scales_geometry(self): def test_flat_end_mill_side_normals_are_radial(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0) vertices, indices, _fmt = build_tool_mesh(tool_def) - vertex_count = len(vertices) // 8 + vertex_count = len(vertices) // FLOATS_PER_VERTEX assert vertex_count < len(indices) @@ -404,7 +445,7 @@ def test_ball_end_mill_reuses_vertices_across_triangles(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL, diameter=6.0) vertices, indices, _fmt = build_tool_mesh(tool_def) - assert len(indices) > len(vertices) // 8 + assert len(indices) > len(vertices) // FLOATS_PER_VERTEX def test_pointed_tip_mesh_shares_single_apex_vertex(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.CHAMFER_MILL, diameter=6.0) @@ -584,7 +625,7 @@ def test_radius_mill_corner_arc_is_reversed_from_bull_nose(self): assert profile_bull_mid_r == pytest.approx(bull_mid_r, abs=0.05) assert profile_radius_mid_r < profile_bull_mid_r - def test_explicit_length_and_flute_produce_shank_step(self): + def test_explicit_length_and_flute_produce_shank_blend(self): profile = tool_profile( ToolDefinition( number=1, @@ -595,11 +636,215 @@ def test_explicit_length_and_flute_produce_shank_step(self): flute_length=12.0, ) ) + flute_r = 1.0 + shank_r = 3.175 / 2.0 + transition = abs(shank_r - flute_r) # ~45° blend + + assert profile[0] == (0.0, flute_r) + assert (12.0, flute_r) in profile + assert any(math.isclose(z, 12.0 + transition) and math.isclose(r, shank_r) for z, r in profile) + assert profile[-1] == (20.0, pytest.approx(shank_r)) + # No hard radial step at the flute tip. + assert not any(math.isclose(z, 12.0) and math.isclose(r, shank_r) for z, r in profile) + + def test_shoulder_keeps_cutting_diameter_before_shank_blend(self): + """Makera: flute < shoulder < stick → body at D, then blend to handle.""" + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + shank_diameter=3.175, + length=15.0, + flute_length=6.0, + shoulder_length=9.0, + ) + ) + flute_r = 1.0 + shank_r = 3.175 / 2.0 + transition = abs(shank_r - flute_r) + + assert (6.0, flute_r) in profile + assert (9.0, flute_r) in profile + # Cutting diameter continues through the shoulder body (flute → shoulder). + assert all(math.isclose(r, flute_r) for z, r in profile if z <= 9.0 + 1e-9) + assert any(math.isclose(z, 9.0 + transition) and math.isclose(r, shank_r) for z, r in profile) + assert profile[-1] == (15.0, pytest.approx(shank_r)) + assert not any(math.isclose(z, 9.0) and math.isclose(r, shank_r) for z, r in profile) + + def test_shoulder_equal_to_stick_has_no_handle_section(self): + """Makera: shoulder == stick → 2mm body to the top, no 3.175 shank.""" + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + shank_diameter=3.175, + length=12.0, + flute_length=6.0, + shoulder_length=12.0, + ) + ) + flute_r = 1.0 + shank_r = 3.175 / 2.0 - assert profile[0] == (0.0, 1.0) - assert (12.0, 1.0) in profile - assert profile[-1] == (20.0, pytest.approx(3.175 / 2.0)) - assert any(math.isclose(z, 12.0) and math.isclose(r, 3.175 / 2.0) for z, r in profile) + assert profile[0] == (0.0, flute_r) + assert (6.0, flute_r) in profile + assert profile[-1] == (12.0, pytest.approx(flute_r)) + assert all(r <= flute_r + 1e-9 for _z, r in profile) + assert not any(math.isclose(r, shank_r) for _z, r in profile) + + def test_mesh_uses_flute_color_without_flute_length(self): + tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0, length=18.0) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + for index in range(vertex_count): + assert _vertex_color(vertices, index) == pytest.approx(FLUTE_COLOR) + + def test_mesh_colors_flute_and_shank_when_flute_length_available(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + shank_diameter=3.175, + length=20.0, + flute_length=12.0, + ) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + colors = {_vertex_color(vertices, index) for index in range(vertex_count)} + assert FLUTE_COLOR in colors + assert SHANK_COLOR in colors + + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < 12.0 - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > 12.0 + 1e-6: + assert color == pytest.approx(SHANK_COLOR) + + def test_mesh_colors_flute_and_shoulder_when_no_handle_section(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=2.0, + shank_diameter=3.175, + length=12.0, + flute_length=6.0, + shoulder_length=12.0, + ) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + colors = {_vertex_color(vertices, index) for index in range(vertex_count)} + assert FLUTE_COLOR in colors + assert SHANK_COLOR in colors + + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < 6.0 - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > 6.0 + 1e-6: + assert color == pytest.approx(SHANK_COLOR) + + def test_infers_chamfer_flute_from_cone_when_metadata_missing(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.CHAMFER_MILL, + diameter=6.0, + taper_angle_deg=90.0, + ) + # 90° included → 45° half-angle → cone height == radius. + vertices, _indices, _fmt = build_tool_mesh(tool_def, length=18.0) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + colors = {_vertex_color(vertices, index) for index in range(vertex_count)} + assert FLUTE_COLOR in colors + assert SHANK_COLOR in colors + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < 3.0 - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > 3.0 + 1e-6: + assert color == pytest.approx(SHANK_COLOR) + + def test_inferred_flute_adds_short_shoulder_before_shank(self): + """Fusion-like tip cue only: short body at D before the handle blend.""" + profile = tool_profile( + ToolDefinition( + number=1, + tool_type=ToolType.CHAMFER_MILL, + diameter=6.0, + shank_diameter=8.0, + taper_angle_deg=90.0, + length=18.0, + ) + ) + flute_z = 3.0 + cutting_r = 3.0 + shank_r = 4.0 + shoulder_z = flute_z + 6.0 * INFERRED_SHOULDER_DIAMETER_FACTOR + transition = abs(shank_r - cutting_r) + + assert any(math.isclose(z, flute_z) and math.isclose(r, cutting_r) for z, r in profile) + assert (shoulder_z, cutting_r) in profile + # Shoulder body only — tip cone points below flute_z have r < cutting_r. + assert all( + math.isclose(r, cutting_r) + for z, r in profile + if flute_z - 1e-9 <= z <= shoulder_z + 1e-9 + ) + assert any( + math.isclose(z, shoulder_z + transition) and math.isclose(r, shank_r) for z, r in profile + ) + assert profile[-1] == (18.0, pytest.approx(shank_r)) + # Shank blend starts after the inferred shoulder, not at the tip. + assert not any(math.isclose(z, flute_z) and math.isclose(r, shank_r) for z, r in profile) + + def test_infers_lollipop_flute_at_ball_neck_join(self): + from carveracontroller.addons.tool_visualization.mesh_builder import _lollipop_ball_join_z + + diameter = 6.0 + ball_join = _lollipop_ball_join_z(diameter) + tool_def = ToolDefinition(number=1, tool_type=ToolType.LOLLIPOP_MILL, diameter=diameter) + vertices, _indices, _fmt = build_tool_mesh(tool_def, length=18.0) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + colors = {_vertex_color(vertices, index) for index in range(vertex_count)} + assert FLUTE_COLOR in colors + assert SHANK_COLOR in colors + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < ball_join - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > ball_join + 1e-6: + assert color == pytest.approx(SHANK_COLOR) + + def test_explicit_flute_length_not_overridden_by_inference(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.CHAMFER_MILL, + diameter=6.0, + taper_angle_deg=90.0, + length=20.0, + flute_length=12.0, + ) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < 12.0 - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > 12.0 + 1e-6: + assert color == pytest.approx(SHANK_COLOR) def test_missing_lengths_still_use_diameter_factor(self): profile = tool_profile( From 765ca7b6a710879e0bcb2c314510873484e31c3f Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:46:18 +0200 Subject: [PATCH 08/11] Change flute/shank color/opacity and improve missing values handling --- .../addons/tool_visualization/mesh_builder.py | 185 +++++++----------- carveracontroller/shaders/tool_pointer.glsl | 12 +- tests/unit/test_tool_visualization.py | 68 +++++-- 3 files changed, 123 insertions(+), 142 deletions(-) diff --git a/carveracontroller/addons/tool_visualization/mesh_builder.py b/carveracontroller/addons/tool_visualization/mesh_builder.py index d0ba3b7d..2f2bb9c1 100644 --- a/carveracontroller/addons/tool_visualization/mesh_builder.py +++ b/carveracontroller/addons/tool_visualization/mesh_builder.py @@ -6,23 +6,27 @@ from carveracontroller.addons.tool_visualization.tool_definition import ToolType -FLUTE_COLOR = (0.3, 0.3, 1.0) -SHANK_COLOR = (0.15, 0.55, 0.55) +FLUTE_COLOR = (0.85, 0.65, 0.15, 0.45) +SHANK_COLOR = (0.5, 0.5, 0.52, 0.3) VERTEX_FORMAT = [ (b"v_pos", 3, "float"), (b"v_normal", 3, "float"), - (b"v_color", 3, "float"), + (b"v_color", 4, "float"), (b"v_tc0", 2, "float"), ] -FLOATS_PER_VERTEX = 11 +FLOATS_PER_VERTEX = 12 RADIAL_SEGMENTS = 20 ROUND_SEGMENTS = 10 DEFAULT_TAPER_ANGLE_DEG = 30.0 -# Factor used to compute the shared tool height from the largest diameter in the table. -LENGTH_DIAMETER_FACTOR = 3.0 +# Factor used to compute overall stick-out when length metadata is missing. +LENGTH_DIAMETER_FACTOR = 6.0 + +# When flute length is missing, inferred/fallback flute height is capped to this +# multiple of diameter so long stick-outs are not painted entirely as cutting. +FALLBACK_FLUTE_DIAMETER_FACTOR = 4.0 # Flute -> shank blend: axial rise per unit radial change (~45°), capped as a # fraction of the available shank length so some cylinder remains above. @@ -124,18 +128,20 @@ def _build_cap_ring(positions, normals, colors, z, radius, nz_sign, segments, co def _pack_vertices(positions, normals, colors): vertices = [] for i in range(len(positions) // 3): - base = 3 * i + p = 3 * i + c = 4 * i vertices.extend( [ - positions[base], - positions[base + 1], - positions[base + 2], - normals[base], - normals[base + 1], - normals[base + 2], - colors[base], - colors[base + 1], - colors[base + 2], + positions[p], + positions[p + 1], + positions[p + 2], + normals[p], + normals[p + 1], + normals[p + 2], + colors[c], + colors[c + 1], + colors[c + 2], + colors[c + 3], 0.0, 0.0, ] @@ -257,19 +263,6 @@ def _effective_tool_diameter(tool_def, scale): return diameter -def _has_explicit_length(tool_def): - if not tool_def: - return False - length = getattr(tool_def, "length", None) - flute_length = getattr(tool_def, "flute_length", None) - shoulder_length = getattr(tool_def, "shoulder_length", None) - return ( - (length is not None and length > 0) - or (flute_length is not None and flute_length > 0) - or (shoulder_length is not None and shoulder_length > 0) - ) - - def _profile_length(tool_def, scale, diameter, shared_length=None): if tool_def: length = getattr(tool_def, "length", None) @@ -374,14 +367,17 @@ def _inferred_shoulder_length(tool_def, flute, overall): def _resolve_section_lengths(tool_def, fallback_overall): """Return `(flute_z, shoulder_z, overall_z)` in file units. - - flute_z: cutting flutes (blue) + - flute_z: cutting flutes (gold) - shoulder_z: end of cutting-diameter body; shank blend starts here - overall_z: total stick-out (sticklength) When flute length is missing, tip-defined tools (chamfer, lollipop, etc.) get a - geometry-based guess. When shoulder is also missing after a tip inference, - a short cutting-diameter shoulder is added so the shank does not start at - the tip. Explicit flute with no shoulder still steps at the flute length. + geometry-based guess, otherwise flute falls back to shoulder/overall and is + capped to FALLBACK_FLUTE_DIAMETER_FACTOR × diameter. When shoulder is also + missing after a tip inference, a short cutting-diameter shoulder is added so + the shank does not start at the tip. Explicit flute with no shoulder still + steps at the flute length. Missing stick-out uses + LENGTH_DIAMETER_FACTOR × diameter via `fallback_overall`. """ if not tool_def: return fallback_overall, fallback_overall, fallback_overall @@ -389,6 +385,7 @@ def _resolve_section_lengths(tool_def, fallback_overall): overall = getattr(tool_def, "length", None) flute = getattr(tool_def, "flute_length", None) shoulder = getattr(tool_def, "shoulder_length", None) + diameter = getattr(tool_def, "diameter", None) or 0.0 if overall is None or overall <= 0: overall = fallback_overall @@ -403,6 +400,8 @@ def _resolve_section_lengths(tool_def, fallback_overall): flute = shoulder else: flute = overall + if diameter > 0: + flute = min(flute, diameter * FALLBACK_FLUTE_DIAMETER_FACTOR) flute = min(flute, overall) @@ -644,14 +643,14 @@ def _lollipop_profile(diameter, length, **_kwargs): theta_join = math.acos(neck_radius / radius) points = [] - # Lower hemisphere: south pole → equator (guarantees full cutting diameter). + # Lower hemisphere: south pole -> equator (guarantees full cutting diameter). for i in range(ROUND_SEGMENTS + 1): theta = -math.pi / 2.0 + (math.pi / 2.0) * (i / ROUND_SEGMENTS) z = radius + radius * math.sin(theta) r = max(radius * math.cos(theta), 0.0) points.append((z, r)) - # Upper hemisphere: equator → neck join (skip duplicate equator point). + # Upper hemisphere: equator -> neck join (skip duplicate equator point). for i in range(1, ROUND_SEGMENTS + 1): theta = theta_join * (i / ROUND_SEGMENTS) z = radius + radius * math.sin(theta) @@ -702,41 +701,13 @@ def fallback_tool_profile(scale): return _chamfer_or_tapered_profile(diameter, length) -def _reference_length(tool_table, scale): - """Compute the shared fallback height for tools without explicit length metadata. - - Derived from the largest diameter among tools that lack length/flute_length, - so it scales with the document's unit system instead of a fixed absolute value. - """ - diameters = [ - _effective_tool_diameter(tool_def, scale) - for tool_def in tool_table.values() - if tool_def - and not _has_explicit_length(tool_def) - and getattr(tool_def, "diameter", None) - and tool_def.diameter > 0 - ] - if diameters: - return max(diameters) * LENGTH_DIAMETER_FACTOR - - # Every tool already has an explicit length (or none have a usable diameter). - diameters = [ - _effective_tool_diameter(tool_def, scale) - for tool_def in tool_table.values() - if tool_def and getattr(tool_def, "diameter", None) and tool_def.diameter > 0 - ] - if diameters: - return max(diameters) * LENGTH_DIAMETER_FACTOR - return fallback_tool_dimensions(scale)[1] - - def _tool_profile_with_shank(tool_def, length=None, scale=1.0): """Return `(profile, color_shank_start_index)` for a tool definition. Geometry sections (when metadata allows): - - tip → flute_z: cutting flutes at tool diameter (blue) - - flute_z → shoulder_z: same diameter body / shoulder (teal) - - shoulder_z → overall_z: blend + handle/shank diameter (teal) + - tip -> flute_z: cutting flutes at tool diameter (gold) + - flute_z -> shoulder_z: same diameter body / shoulder (gray) + - shoulder_z -> overall_z: blend + handle/shank diameter (gray) Falls back to a basic pointed (chamfer-like) profile when `tool_def` is None or its type is unknown/unsupported (see DEFAULT_PROFILE_BUILDER). @@ -781,7 +752,7 @@ def _tool_profile_with_shank(tool_def, length=None, scale=1.0): has_non_flute = overall_z > flute_tip_z + 1e-9 if has_non_flute: color_start = len(profile) - # Coincident ring → hard blue/teal edge at the end of the flutes. + # Coincident ring -> hard gold/gray edge at the end of the flutes. profile.append((flute_tip_z, last_r)) else: color_start = len(profile) @@ -805,10 +776,21 @@ def tool_profile(tool_def, length=None, scale=1.0): return profile -def _scale_profile(profile, scale, radius_boost): - """Scale the profile by the given scale and radius boost.""" - factor = scale * radius_boost - scaled_profile = [(z * factor, r * factor) for z, r in profile] +def _scale_profile(profile, scale): + """Scale profile into viewer units, with a per-tool radius visibility floor. + + If this tool's scaled radius would be below MIN_VISIBLE_RADIUS, enlarge only + that tool (uniformly in Z and R) so it stays visible. Other tools are + unaffected. + """ + if not scale or scale <= 0: + scale = 1.0 + scaled_profile = [(z * scale, r * scale) for z, r in profile] + + max_radius = max((r for _z, r in scaled_profile), default=0.0) + if 0.0 < max_radius < MIN_VISIBLE_RADIUS: + boost = MIN_VISIBLE_RADIUS / max_radius + scaled_profile = [(z * boost, r * boost) for z, r in scaled_profile] total_length = scaled_profile[-1][0] if scaled_profile else 0.0 if total_length < MIN_SHANK_LENGTH: @@ -818,37 +800,16 @@ def _scale_profile(profile, scale, radius_boost): return scaled_profile -def _compute_radius_boost(profiles, scale): - """Compute a single boost factor shared by every tool in `profiles`. - - Boosting each tool independently (to the same MIN_VISIBLE_RADIUS floor) - would make different-sized tools appear identical on screen whenever - they're all small enough to hit the floor. Instead we look at the - *smallest* tool of the batch and compute one factor that makes it meet - the visibility floor, then apply that same factor to every tool so their - relative sizes stay accurate to each other. - """ - radii = [max((r for _, r in profile), default=0.0) * scale for profile in profiles] - radii = [r for r in radii if r > 1e-9] - if not radii: - return 1.0 - - smallest_radius = min(radii) - if smallest_radius < MIN_VISIBLE_RADIUS: - return MIN_VISIBLE_RADIUS / smallest_radius - return 1.0 - - -def build_tool_mesh(tool_def, scale=1.0, radius_boost=1.0, length=None): +def build_tool_mesh(tool_def, scale=1.0, length=None): profile, shank_start = _tool_profile_with_shank(tool_def, length=length, scale=scale) - scaled_profile = _scale_profile(profile, scale, radius_boost) + scaled_profile = _scale_profile(profile, scale) return _build_revolve_mesh(scaled_profile, shank_start_index=shank_start) -def build_default_tool_mesh(scale=1.0, radius_boost=1.0): +def build_default_tool_mesh(scale=1.0): """Mesh used for tools with no metadata (fixed on-screen size).""" profile = fallback_tool_profile(scale) - scaled_profile = _scale_profile(profile, scale, radius_boost) + scaled_profile = _scale_profile(profile, scale) return _build_revolve_mesh(scaled_profile) @@ -856,13 +817,10 @@ def build_tool_meshes(tool_table, scale=1.0): """Build a mesh for every tool in `tool_table`, plus a default mesh for tools with no metadata. - Tools without explicit length/flute metadata share a fallback height derived - from the largest diameter among those tools (see `_reference_length`). - Tools that provide length or flute_length use their own heights. - - A single radius boost factor is derived from the smallest tool in the batch, - so tiny tools stay visible without making unrelated tools look like they - share the same diameter. + Tools without stick-out metadata use LENGTH_DIAMETER_FACTOR × their own + diameter. Tools that provide length / shoulder / flute use those heights. + Each tool is scaled independently; only tools below MIN_VISIBLE_RADIUS get + a per-tool visibility floor. The default (no-metadata) mesh keeps a fixed on-screen size, independent of file units. @@ -872,24 +830,15 @@ def build_tool_meshes(tool_table, scale=1.0): default_profile = fallback_tool_profile(scale) if tool_table: - shared_length = _reference_length(tool_table, scale) - profiles = {} - shank_starts = {} + tool_meshes = {} for number, tool_def in tool_table.items(): - length_hint = None if _has_explicit_length(tool_def) else shared_length - profile, shank_start = _tool_profile_with_shank(tool_def, length=length_hint, scale=scale) - profiles[number] = profile - shank_starts[number] = shank_start - radius_boost = _compute_radius_boost(list(profiles.values()), scale) - tool_meshes = { - number: _build_revolve_mesh( - _scale_profile(profile, scale, radius_boost), - shank_start_index=shank_starts[number], + profile, shank_start = _tool_profile_with_shank(tool_def, scale=scale) + tool_meshes[number] = _build_revolve_mesh( + _scale_profile(profile, scale), + shank_start_index=shank_start, ) - for number, profile in profiles.items() - } else: tool_meshes = {} - default_mesh = _build_revolve_mesh(_scale_profile(default_profile, scale, 1.0)) + default_mesh = _build_revolve_mesh(_scale_profile(default_profile, scale)) return tool_meshes, default_mesh diff --git a/carveracontroller/shaders/tool_pointer.glsl b/carveracontroller/shaders/tool_pointer.glsl index 9611ad51..9064ec4b 100644 --- a/carveracontroller/shaders/tool_pointer.glsl +++ b/carveracontroller/shaders/tool_pointer.glsl @@ -1,19 +1,19 @@ // Tool position pointer mesh with simple diffuse shading. // Drawn in two passes (back faces, then front faces) for correct translucency. -// Vertex colors distinguish flute (blue) from shank (teal) when available. +// Vertex colors distinguish flute (gold, more opaque) from shank (gray). ---vertex $HEADER$ attribute vec3 v_pos; attribute vec3 v_normal; -attribute vec3 v_color; +attribute vec4 v_color; uniform vec3 offset; uniform mat4 rotation; varying vec3 normal_vec; -varying vec3 tool_color; +varying vec4 tool_color; void main() { @@ -31,7 +31,7 @@ void main() $HEADER$ varying vec3 normal_vec; -varying vec3 tool_color; +varying vec4 tool_color; void main() { @@ -39,6 +39,6 @@ void main() // stays stable while orbiting the camera. vec3 n = normalize(normal_vec); float shade = 0.35 + 0.65 * abs(dot(n, normalize(vec3(0.35, 0.55, 1.0)))); - vec3 color = tool_color * shade; - gl_FragColor = vec4(color, 0.3) * texture2D(texture0, tex_coord0); + vec3 color = tool_color.rgb * shade; + gl_FragColor = vec4(color, tool_color.a) * texture2D(texture0, tex_coord0); } diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index 4a2c0599..ac13736a 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -12,6 +12,7 @@ get_tool_icon_path, ) from carveracontroller.addons.tool_visualization.mesh_builder import ( + FALLBACK_FLUTE_DIAMETER_FACTOR, FALLBACK_TOOL_DISPLAY_HEIGHT, FALLBACK_TOOL_DISPLAY_RADIUS, FLOATS_PER_VERTEX, @@ -21,7 +22,6 @@ MIN_VISIBLE_RADIUS, SHANK_COLOR, VERTEX_FORMAT, - _reference_length, build_tool_mesh, build_tool_meshes, tool_profile, @@ -71,7 +71,7 @@ def _vertex_normal(vertices, index): def _vertex_color(vertices, index): base = index * FLOATS_PER_VERTEX - return (vertices[base + 6], vertices[base + 7], vertices[base + 8]) + return (vertices[base + 6], vertices[base + 7], vertices[base + 8], vertices[base + 9]) def _vertex_z(vertices, index): @@ -340,33 +340,31 @@ def test_build_tool_mesh_uses_expected_vertex_layout(self): assert all(0 <= index < vertex_count for index in indices) assert len(indices) > vertex_count - def test_shared_reference_length_uses_largest_diameter(self): + def test_missing_stickout_uses_each_tools_own_diameter(self): tool_table = { 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0), 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=10.0), } - shared_length = _reference_length(tool_table, scale=1.0) + meshes, _ = build_tool_meshes(tool_table, scale=1.0) - assert shared_length == 10.0 * LENGTH_DIAMETER_FACTOR - profile_small = tool_profile(tool_table[1], length=shared_length, scale=1.0) - profile_large = tool_profile(tool_table[2], length=shared_length, scale=1.0) - assert profile_small[-1][0] == profile_large[-1][0] + assert _mesh_height(meshes[1][0]) == pytest.approx(3.0 * LENGTH_DIAMETER_FACTOR) + assert _mesh_height(meshes[2][0]) == pytest.approx(10.0 * LENGTH_DIAMETER_FACTOR) - def test_radius_boost_preserves_relative_sizes(self): + def test_tiny_tool_gets_per_tool_visibility_floor(self): + """Only the undersized tool is enlarged; a normal tool keeps true scale.""" tool_table = { 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=0.01), 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=1.0), } - meshes, _ = build_tool_meshes(tool_table, scale=0.01) + meshes, _ = build_tool_meshes(tool_table, scale=1.0) small_radius = _max_xy_radius(meshes[1][0]) large_radius = _max_xy_radius(meshes[2][0]) - assert small_radius >= MIN_VISIBLE_RADIUS - assert large_radius > small_radius - assert math.isclose(large_radius / small_radius, 100.0, rel_tol=1e-6) + assert small_radius == pytest.approx(MIN_VISIBLE_RADIUS) + assert large_radius == pytest.approx(0.5) - def test_default_mesh_unaffected_by_radius_boost(self): - """Default mesh keeps fixed on-screen size when known tools need boost.""" + def test_default_mesh_unaffected_by_tiny_tools(self): + """Default mesh keeps fixed on-screen size when known tools need a floor.""" tool_table = { 1: ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=0.01), 2: ToolDefinition(number=2, tool_type=ToolType.FLAT_END_MILL, diameter=1.0), @@ -509,6 +507,7 @@ def test_tapered_mill_is_bull_nose_tip_with_taper(self): corner_radius = 1.0 taper_angle_deg = 30.0 shared_length = diameter * LENGTH_DIAMETER_FACTOR + flute_length = diameter * FALLBACK_FLUTE_DIAMETER_FACTOR profile = tool_profile( ToolDefinition( number=12, @@ -524,7 +523,8 @@ def test_tapered_mill_is_bull_nose_tip_with_taper(self): flat_radius = diameter / 2.0 - corner_radius * math.cos(alpha) z_tan = corner_radius * (1.0 - math.sin(alpha)) r_tan = diameter / 2.0 - end_radius = r_tan + (shared_length - z_tan) * math.tan(alpha) + # Missing flute → taper only through the capped flute region; shank stays cylindrical. + end_radius = r_tan + (flute_length - z_tan) * math.tan(alpha) assert profile[0] == (0.0, pytest.approx(flat_radius)) assert any(math.isclose(z, z_tan, abs_tol=1e-6) and math.isclose(r, r_tan, abs_tol=1e-6) for z, r in profile) @@ -536,6 +536,7 @@ def test_tapered_mill_without_corner_radius_has_flat_tip(self): diameter = 6.0 taper_angle_deg = 30.0 shared_length = diameter * LENGTH_DIAMETER_FACTOR + flute_length = diameter * FALLBACK_FLUTE_DIAMETER_FACTOR profile = tool_profile( ToolDefinition( number=1, @@ -548,7 +549,7 @@ def test_tapered_mill_without_corner_radius_has_flat_tip(self): ) tip_radius = diameter / 2.0 - end_radius = tip_radius + shared_length * math.tan(math.radians(taper_angle_deg)) + end_radius = tip_radius + flute_length * math.tan(math.radians(taper_angle_deg)) assert profile[0] == (0.0, tip_radius) assert profile[-1][0] == pytest.approx(shared_length) assert profile[-1][1] == pytest.approx(end_radius) @@ -695,6 +696,7 @@ def test_shoulder_equal_to_stick_has_no_handle_section(self): assert not any(math.isclose(r, shank_r) for _z, r in profile) def test_mesh_uses_flute_color_without_flute_length(self): + # Stick-out under the 4×D fallback flute cap → entire mesh is flute-colored. tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0, length=18.0) vertices, _indices, _fmt = build_tool_mesh(tool_def) vertex_count = len(vertices) // FLOATS_PER_VERTEX @@ -702,6 +704,33 @@ def test_mesh_uses_flute_color_without_flute_length(self): for index in range(vertex_count): assert _vertex_color(vertices, index) == pytest.approx(FLUTE_COLOR) + def test_missing_flute_capped_to_diameter_factor(self): + diameter = 6.0 + length = 40.0 + flute_z = diameter * FALLBACK_FLUTE_DIAMETER_FACTOR + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=diameter, + length=length, + ) + vertices, _indices, _fmt = build_tool_mesh(tool_def) + vertex_count = len(vertices) // FLOATS_PER_VERTEX + + colors = {_vertex_color(vertices, index) for index in range(vertex_count)} + assert FLUTE_COLOR in colors + assert SHANK_COLOR in colors + for index in range(vertex_count): + z = _vertex_z(vertices, index) + color = _vertex_color(vertices, index) + if z < flute_z - 1e-6: + assert color == pytest.approx(FLUTE_COLOR) + elif z > flute_z + 1e-6: + assert color == pytest.approx(SHANK_COLOR) + + profile = tool_profile(tool_def) + assert profile[-1][0] == pytest.approx(length) + def test_mesh_colors_flute_and_shank_when_flute_length_available(self): tool_def = ToolDefinition( number=1, @@ -851,7 +880,10 @@ def test_missing_lengths_still_use_diameter_factor(self): ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=6.0), length=None, ) - assert profile[-1][0] == pytest.approx(6.0 * LENGTH_DIAMETER_FACTOR) + overall = 6.0 * LENGTH_DIAMETER_FACTOR + flute_z = 6.0 * FALLBACK_FLUTE_DIAMETER_FACTOR + assert profile[-1][0] == pytest.approx(overall) + assert any(math.isclose(z, flute_z) for z, _r in profile) def test_engraving_tip_diameter_zero_is_pointed(self): profile = tool_profile( From ac0c315182a4f2117bc89d0aad7f062f1aba5418 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Sat, 18 Jul 2026 16:56:59 +0200 Subject: [PATCH 09/11] Fix formatting issue --- tests/unit/test_tool_visualization.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index ac13736a..9d8cbd74 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -823,14 +823,8 @@ def test_inferred_flute_adds_short_shoulder_before_shank(self): assert any(math.isclose(z, flute_z) and math.isclose(r, cutting_r) for z, r in profile) assert (shoulder_z, cutting_r) in profile # Shoulder body only — tip cone points below flute_z have r < cutting_r. - assert all( - math.isclose(r, cutting_r) - for z, r in profile - if flute_z - 1e-9 <= z <= shoulder_z + 1e-9 - ) - assert any( - math.isclose(z, shoulder_z + transition) and math.isclose(r, shank_r) for z, r in profile - ) + assert all(math.isclose(r, cutting_r) for z, r in profile if flute_z - 1e-9 <= z <= shoulder_z + 1e-9) + assert any(math.isclose(z, shoulder_z + transition) and math.isclose(r, shank_r) for z, r in profile) assert profile[-1] == (18.0, pytest.approx(shank_r)) # Shank blend starts after the inferred shoulder, not at the tip. assert not any(math.isclose(z, flute_z) and math.isclose(r, shank_r) for z, r in profile) From 2840c8c85f7c6aac5c4532e221eec521016ee010 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Sun, 19 Jul 2026 04:00:53 +0200 Subject: [PATCH 10/11] Improve tool visualization tooltips --- .../tool_visualization/tooltip_builder.py | 121 +++++++---- carveracontroller/addons/tooltips/Tooltips.kv | 12 +- carveracontroller/addons/tooltips/Tooltips.py | 194 +++++++++++++----- carveracontroller/main.py | 15 +- tests/unit/test_tool_visualization.py | 82 +++++++- 5 files changed, 327 insertions(+), 97 deletions(-) diff --git a/carveracontroller/addons/tool_visualization/tooltip_builder.py b/carveracontroller/addons/tool_visualization/tooltip_builder.py index 6194743f..a22133e8 100644 --- a/carveracontroller/addons/tool_visualization/tooltip_builder.py +++ b/carveracontroller/addons/tool_visualization/tooltip_builder.py @@ -1,6 +1,7 @@ """Format tool definitions as toolbar tooltip text for the G-code viewer.""" from carveracontroller.addons.tool_visualization.tool_definition import ToolType +from carveracontroller.CNC import escape_gcode_markup from carveracontroller.translation import tr TOOL_TYPE_MSGIDS = { @@ -15,52 +16,100 @@ ToolType.THREAD_MILL: "Thread Mill", } +# Title size in px +_TITLE_SIZE = 17 + def _format_tool_type_label(tool_def): - if tool_def.type_name: - return tool_def.type_name + # Prefer our canonical labels when the type is known msgid = TOOL_TYPE_MSGIDS.get(tool_def.tool_type) - return tr._(msgid) if msgid else "" + if msgid: + return tr._(msgid) + # Unknown types: keep the raw CAM name as-is + return (tool_def.type_name or "").strip() + + +def _is_meaningful(value): + """Return True when a numeric field should be shown (present and non-zero).""" + return value is not None and value != 0 + + +def _format_dimension_lines(tool_def): + """Build one-label-per-line dimension rows, skipping redundant/noise fields.""" + lines = [] + + if tool_def.diameter is not None: + lines.append(tr._("Diameter: {value:g}").format(value=tool_def.diameter)) + + # Shank is noise when it matches the cutting diameter (common inferred default). + if _is_meaningful(tool_def.shank_diameter) and tool_def.shank_diameter != tool_def.diameter: + lines.append(tr._("Shank: {value:g}").format(value=tool_def.shank_diameter)) + + if _is_meaningful(tool_def.corner_radius): + lines.append(tr._("Corner radius: {value:g}").format(value=tool_def.corner_radius)) + + if _is_meaningful(tool_def.taper_angle_deg): + lines.append(tr._("Taper: {value:g}°").format(value=tool_def.taper_angle_deg)) + + if _is_meaningful(tool_def.length): + lines.append(tr._("Length: {value:g}").format(value=tool_def.length)) + + if _is_meaningful(tool_def.flute_length): + lines.append(tr._("Flute length: {value:g}").format(value=tool_def.flute_length)) + if _is_meaningful(tool_def.shoulder_length): + lines.append(tr._("Shoulder: {value:g}").format(value=tool_def.shoulder_length)) -def format_tool_tooltip(tool_def): - """Return multi-line tooltip text for a parsed tool, or an empty string.""" + if _is_meaningful(tool_def.thread_depth): + lines.append(tr._("Thread depth: {value:g}").format(value=tool_def.thread_depth)) + + if _is_meaningful(tool_def.thread_pitch): + lines.append(tr._("Pitch: {value:g}").format(value=tool_def.thread_pitch)) + + return lines + + +def _format_catalog_line(tool_def): + return tool_def.vendor or "" + + +def format_tool_tooltip(tool_def, *, markup=True): + """Return multi-line tooltip text for a parsed tool, or an empty string. + + When *markup* is True (default), the string includes Kivy Label markup for + hierarchy (larger title). Pass markup=False for plain text consumers such + as the tool-change confirm popup. + """ if tool_def is None: return "" title = f"T{tool_def.number}" type_label = _format_tool_type_label(tool_def) if type_label: - title = f"{title} - {type_label}" + title = f"{title} · {type_label}" - lines = [title] + description = tool_def.description or "" + catalog = _format_catalog_line(tool_def) - dimensions = [] - if tool_def.diameter is not None: - dimensions.append(tr._("D={value:g}").format(value=tool_def.diameter)) - if tool_def.shank_diameter is not None: - dimensions.append(tr._("SD={value:g}").format(value=tool_def.shank_diameter)) - if tool_def.corner_radius is not None: - dimensions.append(tr._("CR={value:g}").format(value=tool_def.corner_radius)) - if tool_def.taper_angle_deg is not None: - dimensions.append(tr._("TAPER={value:g}°").format(value=tool_def.taper_angle_deg)) - if tool_def.length is not None: - dimensions.append(tr._("L={value:g}").format(value=tool_def.length)) - if tool_def.flute_length is not None: - dimensions.append(tr._("FL={value:g}").format(value=tool_def.flute_length)) - if tool_def.shoulder_length is not None: - dimensions.append(tr._("SH={value:g}").format(value=tool_def.shoulder_length)) - if tool_def.thread_depth is not None: - dimensions.append(tr._("Thread depth={value:g}").format(value=tool_def.thread_depth)) - if tool_def.thread_pitch is not None: - dimensions.append(tr._("Pitch={value:g}").format(value=tool_def.thread_pitch)) - if dimensions: - lines.append(" ".join(dimensions)) - - if tool_def.description: - lines.append(tool_def.description) - - if tool_def.vendor: - lines.append(f" - {tool_def.vendor}") - - return "\n".join(lines) + if markup: + title = f"[size={_TITLE_SIZE}]{escape_gcode_markup(title)}[/size]" + if description: + description = escape_gcode_markup(description) + if catalog: + catalog = escape_gcode_markup(catalog) + + identity = [title] + if description: + identity.append(description) + if catalog: + identity.append(catalog) + + sections = ["\n".join(identity)] + + dimension_lines = _format_dimension_lines(tool_def) + if dimension_lines: + if markup: + dimension_lines = [escape_gcode_markup(line) for line in dimension_lines] + sections.append("\n".join(dimension_lines)) + + return "\n\n".join(sections) diff --git a/carveracontroller/addons/tooltips/Tooltips.kv b/carveracontroller/addons/tooltips/Tooltips.kv index 8fa35417..41d2b25b 100644 --- a/carveracontroller/addons/tooltips/Tooltips.kv +++ b/carveracontroller/addons/tooltips/Tooltips.kv @@ -27,8 +27,8 @@ : size_hint: None, None - width: max(tooltip_label.texture_size[0] + 20, tooltip_image.width + 20) - height: tooltip_label.texture_size[1] + tooltip_image.height + 20 + width: (tooltip_label.texture_size[0] + tooltip_image.width + self.spacing + 20) if self.orientation == 'horizontal' and tooltip_image.width else max(tooltip_label.texture_size[0] + 20, tooltip_image.width + 20, 220 if tooltip_label.text else 0) + height: (max(tooltip_label.texture_size[1], tooltip_image.height) + 20) if self.orientation == 'horizontal' and tooltip_image.width else tooltip_label.texture_size[1] + tooltip_image.height + 20 size: self.minimum_size orientation: 'vertical' padding: 10, 10 @@ -48,25 +48,23 @@ BoxLayout: size_hint: None, None size: tooltip_image.size - orientation: 'vertical' + pos_hint: {"center_y": 0.5} if root.orientation == 'horizontal' else {"center_x": 0.5} Image: id: tooltip_image size_hint: None, None fit_mode: 'scale-down' size: self.texture_size - pos_hint: {"center_x": 0.5} ToolTipContentLabel: id: tooltip_label size_hint: None, None - text_size: self.width, None size: self.texture_size halign: 'left' - valign: 'top' + valign: 'middle' + pos_hint: {"center_y": 0.5} if root.orientation == 'horizontal' else {} : id: tooltip_label - text_size: self.width, None size_hint: None, None height: self.texture_size[1] halign: 'left' diff --git a/carveracontroller/addons/tooltips/Tooltips.py b/carveracontroller/addons/tooltips/Tooltips.py index 91a9a916..7dc2bdae 100644 --- a/carveracontroller/addons/tooltips/Tooltips.py +++ b/carveracontroller/addons/tooltips/Tooltips.py @@ -16,21 +16,60 @@ from kivy.uix.switch import Switch from kivy.uix.textinput import TextInput +# Minimum tooltip box width for short labels (matches previous wrap floor). +TOOLTIP_MIN_WIDTH = 200 +# Wrap long tooltip text at this width so multi-line content stays readable. +TOOLTIP_MAX_WIDTH = 360 + + +def _compute_tooltip_box_size( + text_width, text_height, image_width, image_height, *, has_text, has_image, horizontal, spacing=15 +): + """Return (width, height) for a tooltip given content metrics and layout.""" + pad = 20 + if horizontal and has_image: + gap = spacing if has_text else 0 + width = text_width + image_width + pad + gap + if has_text: + width = max(width, TOOLTIP_MIN_WIDTH + pad) + height = max(text_height, image_height) + pad + return width, height + + width = max(text_width + pad, image_width + pad, TOOLTIP_MIN_WIDTH + pad if has_text else 0) + height = text_height + image_height + pad + return width, height + class Tooltip(BoxLayout): pass class ToolTipContentLabel(Label): - min_width = 200 + """Tooltip text label that sizes to content, wrapping only when needed.""" + + min_width = TOOLTIP_MIN_WIDTH + max_width = TOOLTIP_MAX_WIDTH def __init__(self, **kwargs): super().__init__(**kwargs) - self.text_size = (max(self.width, self.min_width), None) + self.text_size = (None, None) + + def on_text(self, *args): + self.refresh_text_size() + + def refresh_text_size(self): + """Size to the longest line, wrapping only when past max_width.""" + if not self.text: + self.text_size = (None, None) + return + + # Measure natural (unwrapped) width first. + self.text_size = (None, None) + self.texture_update() + natural_width = self.texture_size[0] - def on_size(self, *args): - self.text_size = (max(self.width, self.min_width), None) - if hasattr(self, "_label"): + if natural_width > self.max_width: + self.text_size = (self.max_width, None) self.texture_update() @@ -40,7 +79,7 @@ class ToolTipSwitch(Switch): tooltip_image = StringProperty("") tooltip_delay = NumericProperty(0.5) show_tooltips = BooleanProperty(False) - tooltip_image_size = ObjectProperty(None) + tooltip_image_size = ObjectProperty(None, allownone=True) def __init__(self, **kwargs): self._tooltip = None @@ -109,11 +148,17 @@ def _update_image(self, *largs): self._tooltip.ids.tooltip_image.size = (0, 0) self._tooltip.ids.tooltip_image.visible = False - def _update_image_size(self, instance, value): + def _update_image_size(self, *_args): + if not self._tooltip: + return + + tooltip_image = self._tooltip.ids.tooltip_image if self.tooltip_image_size: - self._tooltip.ids.tooltip_image.size = self.tooltip_image_size + tooltip_image.size = self.tooltip_image_size + elif self.tooltip_image: + tooltip_image.size = tooltip_image.texture_size else: - instance.size = instance.texture_size[0], instance.texture_size[1] + tooltip_image.size = (0, 0) def _update_tooltip_size(self): tooltip_label = self._tooltip.ids.tooltip_label @@ -123,7 +168,8 @@ def _update_tooltip_size(self): text_width, text_height = tooltip_label.texture_size image_width, image_height = tooltip_image.size - new_width = max(text_width + 20, image_width + 20) + # Keep a stable minimum width for short labels; long text can grow up to max wrap. + new_width = max(text_width + 20, image_width + 20, TOOLTIP_MIN_WIDTH + 20 if tooltip_label.text else 0) new_height = text_height + image_height + 20 # Update tooltip size @@ -165,7 +211,7 @@ def on_mouse_pos(self, *args): if self.tooltip_image: tooltip_padding = 40 - tooltip_width = max(text_width, image_width) + tooltip_width = max(text_width, image_width, TOOLTIP_MIN_WIDTH if self.tooltip_txt else 0) tooltip_height = tooltip_label.texture_size[1] + tooltip_image.height + tooltip_padding self._tooltip.size = (tooltip_width, tooltip_height) x = pos[0] @@ -197,7 +243,7 @@ class ToolTipTextInput(TextInput): tooltip_image = StringProperty("") tooltip_delay = NumericProperty(0.5) show_tooltips = BooleanProperty(False) - tooltip_image_size = ObjectProperty(None) + tooltip_image_size = ObjectProperty(None, allownone=True) def __init__(self, **kwargs): self._tooltip = None @@ -270,11 +316,17 @@ def _update_image(self, *largs): self._tooltip.ids.tooltip_image.size = (0, 0) self._tooltip.ids.tooltip_image.visible = False - def _update_image_size(self, instance, value): + def _update_image_size(self, *_args): + if not self._tooltip: + return + + tooltip_image = self._tooltip.ids.tooltip_image if self.tooltip_image_size: - self._tooltip.ids.tooltip_image.size = self.tooltip_image_size + tooltip_image.size = self.tooltip_image_size + elif self.tooltip_image: + tooltip_image.size = tooltip_image.texture_size else: - instance.size = instance.texture_size[0], instance.texture_size[1] + tooltip_image.size = (0, 0) def _update_tooltip_size(self): tooltip_label = self._tooltip.ids.tooltip_label @@ -284,7 +336,8 @@ def _update_tooltip_size(self): text_width, text_height = tooltip_label.texture_size image_width, image_height = tooltip_image.size - new_width = max(text_width + 20, image_width + 20) + # Keep a stable minimum width for short labels; long text can grow up to max wrap. + new_width = max(text_width + 20, image_width + 20, TOOLTIP_MIN_WIDTH + 20 if tooltip_label.text else 0) new_height = text_height + image_height + 20 # Update tooltip size @@ -326,7 +379,7 @@ def on_mouse_pos(self, *args): if self.tooltip_image: tooltip_padding = 40 - tooltip_width = max(text_width, image_width) + tooltip_width = max(text_width, image_width, TOOLTIP_MIN_WIDTH if self.tooltip_txt else 0) tooltip_height = tooltip_label.texture_size[1] + tooltip_image.height + tooltip_padding self._tooltip.size = (tooltip_width, tooltip_height) x = pos[0] @@ -358,8 +411,10 @@ class ToolTipButton(Button): tooltip_image = StringProperty("") tooltip_delay = NumericProperty(0.5) show_tooltips = BooleanProperty(False) - tooltip_image_size = ObjectProperty(None) + tooltip_image_size = ObjectProperty(None, allownone=True) tooltip_radius = NumericProperty(0.2) + tooltip_horizontal = BooleanProperty(False) + tooltip_markup = BooleanProperty(False) def __init__(self, **kwargs): self._tooltip = None @@ -372,6 +427,8 @@ def __init__(self, **kwargs): fbind("tooltip_txt", self._update_tooltip) fbind("tooltip_image", self._update_image) fbind("tooltip_image_size", self._update_image_size) + fbind("tooltip_horizontal", self._update_tooltip_layout) + fbind("tooltip_markup", self._update_tooltip_markup) Window.bind(mouse_pos=self.on_mouse_pos) self.bind(on_release=self.close_tooltip) self._build_tooltip() @@ -404,9 +461,23 @@ def _build_tooltip(self, *largs): image_widget = self._tooltip.ids.tooltip_image image_widget.bind(texture_size=self._update_image_size) + self._update_tooltip_layout() + self._update_tooltip_markup() self._update_image() self._update_tooltip() + def _update_tooltip_layout(self, *largs): + if not self._tooltip: + return + self._tooltip.orientation = "horizontal" if self.tooltip_horizontal else "vertical" + self._update_tooltip_size() + + def _update_tooltip_markup(self, *largs): + if not self._tooltip: + return + self._tooltip.ids.tooltip_label.markup = self.tooltip_markup + self._update_tooltip_size() + def _update_tooltip(self, *largs): txt = self.tooltip_txt if txt: @@ -428,24 +499,38 @@ def _update_image(self, *largs): self._tooltip.ids.tooltip_image.size = (0, 0) self._tooltip.ids.tooltip_image.visible = False - def _update_image_size(self, instance, value): + def _update_image_size(self, *_args): + if not self._tooltip: + return + + tooltip_image = self._tooltip.ids.tooltip_image if self.tooltip_image_size: - self._tooltip.ids.tooltip_image.size = self.tooltip_image_size + tooltip_image.size = self.tooltip_image_size + elif self.tooltip_image: + tooltip_image.size = tooltip_image.texture_size else: - instance.size = instance.texture_size[0], instance.texture_size[1] + tooltip_image.size = (0, 0) def _update_tooltip_size(self): + if not self._tooltip: + return tooltip_label = self._tooltip.ids.tooltip_label tooltip_image = self._tooltip.ids.tooltip_image - # Calculate new size based on text and image dimensions text_width, text_height = tooltip_label.texture_size image_width, image_height = tooltip_image.size - new_width = max(text_width + 20, image_width + 20) - new_height = text_height + image_height + 20 + new_width, new_height = _compute_tooltip_box_size( + text_width, + text_height, + image_width, + image_height, + has_text=bool(tooltip_label.text), + has_image=bool(self.tooltip_image), + horizontal=self.tooltip_horizontal, + spacing=self._tooltip.spacing, + ) - # Update tooltip size self._tooltip.size = (new_width, new_height) self._tooltip.canvas.ask_update() # Force UI refresh self._tooltip.ids.tooltip_label.texture_update() @@ -472,20 +557,23 @@ def on_mouse_pos(self, *args): return pos = args[1] - tooltip_width, tooltip_height = self._tooltip.size window_width, window_height = Window.size tooltip_label = self._tooltip.ids.tooltip_label tooltip_image = self._tooltip.ids.tooltip_image - text_width = tooltip_label.texture_size[0] - image_width = tooltip_image.width - - tooltip_padding = 10 - if self.tooltip_image: - tooltip_padding = 40 + text_width, text_height = tooltip_label.texture_size + image_width, image_height = tooltip_image.size - tooltip_width = max(text_width, image_width) - tooltip_height = tooltip_label.texture_size[1] + tooltip_image.height + tooltip_padding + tooltip_width, tooltip_height = _compute_tooltip_box_size( + text_width, + text_height, + image_width, + image_height, + has_text=bool(self.tooltip_txt), + has_image=bool(self.tooltip_image), + horizontal=self.tooltip_horizontal, + spacing=self._tooltip.spacing, + ) self._tooltip.size = (tooltip_width, tooltip_height) x = pos[0] y = pos[1] @@ -516,7 +604,7 @@ class ToolTipDropDown(DropDown): tooltip_image = StringProperty("") tooltip_delay = NumericProperty(0.5) show_tooltips = BooleanProperty(False) - tooltip_image_size = ObjectProperty(None) + tooltip_image_size = ObjectProperty(None, allownone=True) def __init__(self, **kwargs): self._tooltip = None @@ -585,11 +673,17 @@ def _update_image(self, *largs): self._tooltip.ids.tooltip_image.size = (0, 0) self._tooltip.ids.tooltip_image.visible = False - def _update_image_size(self, instance, value): + def _update_image_size(self, *_args): + if not self._tooltip: + return + + tooltip_image = self._tooltip.ids.tooltip_image if self.tooltip_image_size: - self._tooltip.ids.tooltip_image.size = self.tooltip_image_size + tooltip_image.size = self.tooltip_image_size + elif self.tooltip_image: + tooltip_image.size = tooltip_image.texture_size else: - instance.size = instance.texture_size[0], instance.texture_size[1] + tooltip_image.size = (0, 0) def _update_tooltip_size(self): tooltip_label = self._tooltip.ids.tooltip_label @@ -599,7 +693,8 @@ def _update_tooltip_size(self): text_width, text_height = tooltip_label.texture_size image_width, image_height = tooltip_image.size - new_width = max(text_width + 20, image_width + 20) + # Keep a stable minimum width for short labels; long text can grow up to max wrap. + new_width = max(text_width + 20, image_width + 20, TOOLTIP_MIN_WIDTH + 20 if tooltip_label.text else 0) new_height = text_height + image_height + 20 # Update tooltip size @@ -641,7 +736,7 @@ def on_mouse_pos(self, *args): if self.tooltip_image: tooltip_padding = 40 - tooltip_width = max(text_width, image_width) + tooltip_width = max(text_width, image_width, TOOLTIP_MIN_WIDTH if self.tooltip_txt else 0) tooltip_height = tooltip_label.texture_size[1] + tooltip_image.height + tooltip_padding self._tooltip.size = (tooltip_width, tooltip_height) x = pos[0] @@ -673,7 +768,7 @@ class ToolTipLabel(Label): tooltip_image = StringProperty("") tooltip_delay = NumericProperty(0.5) show_tooltips = BooleanProperty(False) - tooltip_image_size = ObjectProperty(None) + tooltip_image_size = ObjectProperty(None, allownone=True) def __init__(self, **kwargs): self._tooltip = None @@ -743,11 +838,17 @@ def _update_image(self, *largs): self._tooltip.ids.tooltip_image.size = (0, 0) self._tooltip.ids.tooltip_image.visible = False - def _update_image_size(self, instance, value): + def _update_image_size(self, *_args): + if not self._tooltip: + return + + tooltip_image = self._tooltip.ids.tooltip_image if self.tooltip_image_size: - self._tooltip.ids.tooltip_image.size = self.tooltip_image_size + tooltip_image.size = self.tooltip_image_size + elif self.tooltip_image: + tooltip_image.size = tooltip_image.texture_size else: - instance.size = instance.texture_size[0], instance.texture_size[1] + tooltip_image.size = (0, 0) def _update_tooltip_size(self): tooltip_label = self._tooltip.ids.tooltip_label @@ -757,7 +858,8 @@ def _update_tooltip_size(self): text_width, text_height = tooltip_label.texture_size image_width, image_height = tooltip_image.size - new_width = max(text_width + 20, image_width + 20) + # Keep a stable minimum width for short labels; long text can grow up to max wrap. + new_width = max(text_width + 20, image_width + 20, TOOLTIP_MIN_WIDTH + 20 if tooltip_label.text else 0) new_height = text_height + image_height + 20 # Update tooltip size @@ -799,7 +901,7 @@ def on_mouse_pos(self, *args): if self.tooltip_image: tooltip_padding = 40 - tooltip_width = max(text_width, image_width) + tooltip_width = max(text_width, image_width, TOOLTIP_MIN_WIDTH if self.tooltip_txt else 0) tooltip_height = tooltip_label.texture_size[1] + tooltip_image.height + tooltip_padding self._tooltip.size = (tooltip_width, tooltip_height) x = pos[0] diff --git a/carveracontroller/main.py b/carveracontroller/main.py index 9b15ba03..83c8eadd 100644 --- a/carveracontroller/main.py +++ b/carveracontroller/main.py @@ -4274,7 +4274,7 @@ def _format_target_tool_text(self): return "Custom Probe" tool_def = self.tool_table.get(tool_number) - tooltip = format_tool_tooltip(tool_def) if tool_def else "" + tooltip = format_tool_tooltip(tool_def, markup=False) if tool_def else "" return tooltip if tooltip else str(tool_number) # ----------------------------------------------------------------------- @@ -7289,7 +7289,18 @@ def _refresh_tool_filter_buttons(self, *_args): else: tool_button.icon = "" tool_def = self.tool_table.get(number) - tool_button.tooltip_txt = format_tool_tooltip(tool_def) if tool_def else "" + if tool_def: + tool_button.tooltip_markup = True + tool_button.tooltip_horizontal = True + tool_button.tooltip_image_size = (64, 64) + tool_button.tooltip_image = get_tool_icon_path(tool_def) + tool_button.tooltip_txt = format_tool_tooltip(tool_def) + else: + tool_button.tooltip_txt = "" + tool_button.tooltip_image = "" + tool_button.tooltip_image_size = None + tool_button.tooltip_horizontal = False + tool_button.tooltip_markup = False # ----------------------------------------------------------------------- def init_tool_filter(self): diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index 9d8cbd74..a233a337 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -304,13 +304,66 @@ def test_formats_full_tool_definition(self): ) tooltip = format_tool_tooltip(tool_def) - assert tooltip == ("T2 - Bull nose end mill\nD=6 CR=0.5 TAPER=5°\nRoughing endmill\n - Makera") + assert tooltip == ( + "[size=17]T2 · Bull Nose End Mill[/size]\n" + "Roughing endmill\n" + "Makera\n" + "\n" + "Diameter: 6\n" + "Corner radius: 0.5\n" + "Taper: 5°" + ) def test_uses_enum_label_when_type_name_missing(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.FLAT_END_MILL, diameter=3.0) - assert format_tool_tooltip(tool_def) == "T1 - Flat End Mill\nD=3" + assert format_tool_tooltip(tool_def) == "[size=17]T1 · Flat End Mill[/size]\n\nDiameter: 3" + + def test_prefers_enum_label_over_raw_type_name(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=6.0, + type_name="flat end mill", + ) + assert format_tool_tooltip(tool_def).startswith("[size=17]T1 · Flat End Mill[/size]") + + def test_falls_back_to_raw_type_name_for_unknown_type(self): + tool_def = ToolDefinition( + number=9, + tool_type=ToolType.UNKNOWN, + diameter=4.0, + type_name="CNC HSS Slot Drill", + ) + assert format_tool_tooltip(tool_def).startswith("[size=17]T9 · CNC HSS Slot Drill[/size]") + + def test_plain_text_without_markup(self): + tool_def = ToolDefinition( + number=2, + tool_type=ToolType.BULL_NOSE_END_MILL, + diameter=6.0, + description="Roughing endmill", + vendor="Makera", + type_name="Bull nose end mill", + ) + assert format_tool_tooltip(tool_def, markup=False) == ( + "T2 · Bull Nose End Mill\nRoughing endmill\nMakera\n\nDiameter: 6" + ) + + def test_escapes_markup_in_user_fields(self): + tool_def = ToolDefinition( + number=1, + tool_type=ToolType.FLAT_END_MILL, + diameter=3.0, + description="Bit [special] & co", + vendor="Acme [Tools]", + type_name="flat end mill", + ) + tooltip = format_tool_tooltip(tool_def) + assert "Bit &bl;special&br; & co" in tooltip + assert "Acme &bl;Tools&br;" in tooltip + assert "[special]" not in tooltip - def test_includes_shank_length_and_flute_when_present(self): + def test_includes_length_and_flute_when_present(self): tool_def = ToolDefinition( number=1, tool_type=ToolType.ENGRAVING, @@ -322,10 +375,27 @@ def test_includes_shank_length_and_flute_when_present(self): ) tooltip = format_tool_tooltip(tool_def) - assert "SD=3.175" in tooltip - assert "L=20" in tooltip - assert "FL=12" in tooltip + assert "Diameter: 3.175" in tooltip + assert "Length: 20" in tooltip + assert "Flute length: 12" in tooltip assert "Engraving" in tooltip + # Redundant shank matching diameter is omitted. + assert "Shank:" not in tooltip + + def test_hides_zero_corner_radius_and_shows_distinct_shank(self): + tool_def = ToolDefinition( + number=5, + tool_type=ToolType.RADIUS_MILL, + diameter=2.0, + shank_diameter=6.0, + corner_radius=0.0, + type_name="Radius mill", + ) + tooltip = format_tool_tooltip(tool_def) + + assert "Corner radius:" not in tooltip + assert "Shank: 6" in tooltip + assert tooltip.startswith("[size=17]T5 · Radius Mill[/size]") class TestMeshBuilder: From d825f4a77be6b8c9f480b8ff839e6bf340e60891 Mon Sep 17 00:00:00 2001 From: Lyrkan <850046+Lyrkan@users.noreply.github.com> Date: Sun, 19 Jul 2026 17:17:33 +0200 Subject: [PATCH 11/11] Better tool icons --- .../addons/tool_visualization/__init__.py | 11 ++++-- .../addons/tool_visualization/icon_builder.py | 28 +++++++++++++-- .../data/GcodeViewer/tools/ball_end_mill.png | Bin 1194 -> 29767 bytes .../GcodeViewer/tools/ball_end_mill_thumb.png | Bin 0 -> 45067 bytes .../GcodeViewer/tools/bull_nose_end_mill.png | Bin 1073 -> 38691 bytes .../tools/bull_nose_end_mill_thumb.png | Bin 0 -> 62410 bytes .../data/GcodeViewer/tools/flat_end_mill.png | Bin 963 -> 17487 bytes .../GcodeViewer/tools/flat_end_mill_thumb.png | Bin 0 -> 27312 bytes .../data/GcodeViewer/tools/lollipop_mill.png | Bin 1319 -> 36509 bytes .../GcodeViewer/tools/lollipop_mill_thumb.png | Bin 0 -> 74450 bytes .../data/GcodeViewer/tools/pointed_mill.png | Bin 1224 -> 36154 bytes .../GcodeViewer/tools/pointed_mill_thumb.png | Bin 0 -> 51057 bytes .../data/GcodeViewer/tools/radius_mill.png | Bin 1151 -> 18463 bytes .../GcodeViewer/tools/radius_mill_thumb.png | Bin 0 -> 30890 bytes .../data/GcodeViewer/tools/tapered_mill.png | Bin 1214 -> 24592 bytes .../GcodeViewer/tools/tapered_mill_thumb.png | Bin 0 -> 27619 bytes .../data/GcodeViewer/tools/thread_mill.png | Bin 1316 -> 20107 bytes .../GcodeViewer/tools/thread_mill_thumb.png | Bin 0 -> 24009 bytes carveracontroller/main.py | 11 ++++-- carveracontroller/makera.kv | 32 ++++++++++-------- tests/unit/test_tool_visualization.py | 15 +++++--- 21 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 carveracontroller/data/GcodeViewer/tools/ball_end_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/flat_end_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/lollipop_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/pointed_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/radius_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/tapered_mill_thumb.png create mode 100644 carveracontroller/data/GcodeViewer/tools/thread_mill_thumb.png diff --git a/carveracontroller/addons/tool_visualization/__init__.py b/carveracontroller/addons/tool_visualization/__init__.py index c5fa821e..f1c33c03 100644 --- a/carveracontroller/addons/tool_visualization/__init__.py +++ b/carveracontroller/addons/tool_visualization/__init__.py @@ -7,8 +7,15 @@ """ from carveracontroller.addons.tool_visualization.extractor import extract_tool_table -from carveracontroller.addons.tool_visualization.icon_builder import get_tool_icon_path +from carveracontroller.addons.tool_visualization.icon_builder import get_tool_icon_path, get_tool_tooltip_icon_path from carveracontroller.addons.tool_visualization.tool_definition import ToolDefinition, ToolType from carveracontroller.addons.tool_visualization.tooltip_builder import format_tool_tooltip -__all__ = ["extract_tool_table", "format_tool_tooltip", "get_tool_icon_path", "ToolDefinition", "ToolType"] +__all__ = [ + "extract_tool_table", + "format_tool_tooltip", + "get_tool_icon_path", + "get_tool_tooltip_icon_path", + "ToolDefinition", + "ToolType", +] diff --git a/carveracontroller/addons/tool_visualization/icon_builder.py b/carveracontroller/addons/tool_visualization/icon_builder.py index bdb40dee..c8914455 100644 --- a/carveracontroller/addons/tool_visualization/icon_builder.py +++ b/carveracontroller/addons/tool_visualization/icon_builder.py @@ -1,9 +1,12 @@ -"""Map tool definitions to toolbar icon paths for the G-code viewer.""" +"""Map tool definitions to toolbar / tooltip icon paths for the G-code viewer.""" from carveracontroller.addons.tool_visualization.tool_definition import ToolType TOOLS_ICON_DIR = "data/GcodeViewer/tools" DEFAULT_ICON = f"{TOOLS_ICON_DIR}/pointed_mill.png" +DEFAULT_THUMB_ICON = f"{TOOLS_ICON_DIR}/pointed_mill_thumb.png" + +# Full-body icons (used in tooltips) TOOL_TYPE_ICONS = { ToolType.FLAT_END_MILL: f"{TOOLS_ICON_DIR}/flat_end_mill.png", ToolType.BALL_END_MILL: f"{TOOLS_ICON_DIR}/ball_end_mill.png", @@ -17,9 +20,30 @@ ToolType.UNKNOWN: DEFAULT_ICON, } +# Zoomed thumbnails (used on the T1–T6 buttons) +TOOL_TYPE_THUMB_ICONS = { + ToolType.FLAT_END_MILL: f"{TOOLS_ICON_DIR}/flat_end_mill_thumb.png", + ToolType.BALL_END_MILL: f"{TOOLS_ICON_DIR}/ball_end_mill_thumb.png", + ToolType.BULL_NOSE_END_MILL: f"{TOOLS_ICON_DIR}/bull_nose_end_mill_thumb.png", + ToolType.RADIUS_MILL: f"{TOOLS_ICON_DIR}/radius_mill_thumb.png", + ToolType.CHAMFER_MILL: DEFAULT_THUMB_ICON, + ToolType.ENGRAVING: DEFAULT_THUMB_ICON, + ToolType.TAPERED_MILL: f"{TOOLS_ICON_DIR}/tapered_mill_thumb.png", + ToolType.LOLLIPOP_MILL: f"{TOOLS_ICON_DIR}/lollipop_mill_thumb.png", + ToolType.THREAD_MILL: f"{TOOLS_ICON_DIR}/thread_mill_thumb.png", + ToolType.UNKNOWN: DEFAULT_THUMB_ICON, +} + def get_tool_icon_path(tool_def): - """Return the toolbar icon path for a tool definition.""" + """Return the toolbar thumb icon path for a tool definition.""" + if tool_def is None: + return DEFAULT_THUMB_ICON + return TOOL_TYPE_THUMB_ICONS.get(tool_def.tool_type, DEFAULT_THUMB_ICON) + + +def get_tool_tooltip_icon_path(tool_def): + """Return the full-body tooltip icon path for a tool definition.""" if tool_def is None: return DEFAULT_ICON return TOOL_TYPE_ICONS.get(tool_def.tool_type, DEFAULT_ICON) diff --git a/carveracontroller/data/GcodeViewer/tools/ball_end_mill.png b/carveracontroller/data/GcodeViewer/tools/ball_end_mill.png index 1e7a917aa0f438333b7829b9a63d584f028111e0..089039632145f47ef111376d093f42bfed81b7f4 100644 GIT binary patch literal 29767 zcmZ^LcRbZ!{Qtez#kH@IY?thnJ+iJ#;zqbhx|A(@BvCfkzDBu3WM3r-+1X@f@0nF7 zS;=0%x6k+Y{r&gr(c^JFl-=VW8hoCYao!fBnb4|5(K)D3IbjA$oOKU0{j7)_3c|) zz$@_UNV6^ocp-nPtACUHH#s9MmmJBu

DmC8(>VVeC7-apsfCzxtdz>b%kLp5W8| zxg-*MGRDMR5EP8bg;Z7q-0aB>EqwR@D{5Nx^WpW0#`XM2pMyt!4OsPIuPkTX^`cU2 z_ZO2=-Dp0DE=Y^Zk}RxSW^P0&lS9OR@qFjrSfSUK$DlXHSp@}w3yZqmA3hYV1T-m} zKSJD$VG_pV>%8Rs|9-J^pEQ3)(Bs|W?!{VD=bzKh58Yp6$Y=}kEW~R*spa^!zD2@= zGbHA~78FSIqle>{vr9@0R(GE(9#MDO%UB{{5W2>#^hkms7!i&{K!j*=DPSN}B^k&8 z1p~p0;fdB6_2c|n?Q zFqF9zEIEmomIMEd7ZM_4Z25%kH(V70hS(Mwl^XB+_lxf73llIJrS+#V$I}x9bpf%P zLfdXx&2J;9?n|r=)bI7%jA1vx9j1@a8c3KO{%$`jSm(B=vjfr@6>U!trlCO#FER_- zi(Z>V3+Gml$wrxIPs_;;fkMbgWqBkoWKL)lz}eZPOFk>XJATEL5hes_ec^05n2ott zf9jOQUt6z>4L#Ui{dZLnmeB63*k0(6qvbcWpf^VOSCzpZ@3kdMDGAxCTETp4Zn}%j6hJVqj8ZOR09NO=y@@t%OaI9FPQbz_s26K{+HiYC8g9pvF3r0 zPyJJLQ+;qCoFom6SjopVY_T?8Vi+Ja(n_(PSe2K@n;w$Zw-()*U4D>_lx& zSLaHz{8H0N=LMr^iYWP8z0Jm!#g`w~<+fiw&TNlfK0t~Fhf@Z_AvVSA{MiJQg~j#8 zRlm&k!$~1f9+OGRYbj+PM!b~A3>c)7BPHX-IOaryV8RH4WKZKl$Jr=9cw;^gsh_?V zcUWfxu{CblOl<0^JU{ld_M}Bo@NQ`7++Ld*y=tXJ8TZ=aTp%qgi=0Ru1Ja^5)aM~0 zO6t!kgAQgN^w*ZZ!+cP=p{#Jx39Pq@7ud|GrN1|>pztEZh;po^GmS7m4nD|Ws1+sv z6=jepz7mQE#%Oz7k*&aN`!kYQ;#rjhpctXUMs6&KspA@=Y^q=^ReKq2#yCX_h1!?fGkt<~ul1Bh^KI1~l}cgXU|M)6v{(f9yD>k1LGlOteX znMhgJ_Eo=(Ae+t}<{y@N1SELGK4!@?5n7=DkET~mVBL?7O<*>D+=mZl4tC^Uj5uW) zqw<#(-YU=e2fp~0ck`k$kP*vCP{MnzU*A1`H;EsGOltpl@*uau9=(oR(tk1k(l8a2 zMXz?2gKJ{c&Q|wTzP8S{ldiMi?xU9^j!YkR*sv+un0fU3>$75CKK>tV8J;m)d>ATA zcB2pDc=L7fPj$35+YZ&=Y?O}RqR&^A9=H_w1LdKx1@#3c2 z&NTXWNlWK0E24FgHmbn2?7Ry)PdT*8eWwOH^E>4vaDCnhL9JAkc8tg|8;;pc+iE4} z*=W4j=-)7*d~bJD-6+V!-D9o0^Y-R%h|4vXP98i1rEWAmga$1nBt$Sle0k^q>O;0dTk^EZOJ-^D1-F+pArVx@l@}QAyZAQl3=M({PPQ!Gw>SYi*sJl0qop4S1siOtdi73&z6?AY# zOw2C zxtX6a$czYfuQn7M;5kxLX`eZj*aLkDxvT|uWqc%eh`S!mv5Wg=Qs%}JB zFEi)B%NoItl%SXVxylcN*W{-B@9=rLRbO>z=ynYmuc`byh<-`O8n3g%sp$lExfaEn z{WTSY!x*Bm^v^(MH-Aira}>n57m-(e22HPnu_@YhX&SFq0+uSrqvvmiw9TxXR5PE_ zl~*M7S0H0tfr781PwCTzJ!KoW!n;yE{rHztxMF;@x`>TW$Np$K_mGp=$+yT};V1CJ zOmC!eiPF1P@cPu~F*oF*L|f=8ON#g6*yQ2HBgjy@uWuB7(J4$*V7vE5{8*Fd%!I zUNBO7dy=?JEKHD(f|vF;uX7Y2>6aVT&( zzWoB4i8luJvBCsV6VT#UBp>7)bk=5B1iOe7E>Ac+?<;Hi+FdCYNmp*^-hK<-r1klU zRPu!z!n>}DUSRvG03@m5!lB_i`a_rNXoq;1%dw{0RnEL(#_j9m#g=v_x&=o~o0sDu z%0*st`fHQ8$b}XE)-#liX~=YFtawl3_Jz76%T@AIch5C<`i+eyPmR00w|87O)Y_}V zFV{sNbTAs2fQulu~w`#vA*S<~M9P>(ro zW?jA@muV*S@`tI@1gEFL*R0m{%IC&??o^#DGGAYIYnsuR-yabYXHgHL3UYpzJN=}0IT;oG2$>{^~VEA;(cpc~Tuin8G2#BJ^poS#kP5q3|TEFHS(n%8s__gr-2D$1H z8TW&kzGvdOgC>M?=8%^0cx92}R`u> z3CXtaUk(zOCO*fE*Wkvrjkh!FoQ%xtdQ$80WryznhJq84)LB%EIL`Q^142xu{=YoXv zdmD4_WZZEG{>?0C< z>gl5GS6SXqs5&Ua_^#-``*pr}w&%<3`D@ocF!ZUIrB9+ruhc-|hvhC#&8AE0Y4%7PlQ>K_Q$>Ksy)n zB!|L3CsQDTO(-+iat&kI&-7$1y{PbI^7C03=0JOn7ii&E{S6qW5up-y;(I~et6Zu= zM4iv1d@n2b2(OS`M({eRXeSg3=CG7Oz;q~}%ZhcxgI#f}M_6I;4<) z!^RNlAOv(zl6SJq_6Xg7QyM>$O}p}PxL%h2))(k7dEWSp?=d6fWl_$I0JL+tV_E>7 z_UtDj(GXqPpTrk9Q)rGU$`-vWN|Z1~aYc;D4IXH|EMX2$58^0unF-E@tyOjt}>!18sE7c0;acl?k zdi3WI(rB69`g~=`uS~;2iAyLU8w&cHviiUixYh^2qY6?XAtC|8#)cI(O$m?gruZ{e zM{cvc?BT+WXFYGItdvu^Xx*&|JiAfTuAZH~xjze`*EbyH9DH^E^UZsfk7tTb?ETR6 zU2BPKZoO0YA}{_|8oQ#;rfSWn*eA6i3g2IF+Av-#brszwf^jSIt)m&j5P`BQ#Tr5( z<2|Xr(x(%Z$q52Z@r?fAJ5U=f{a}HcgUb3qEhDXD2_ zY;2!0`R)H{XLqlUCldLg8o|4(^PR(gr6VFD5JV^iNm$3MNp^O2FU!;F3Z|$#uz**I zZ8dPSF&IFRc(gLoK)u-pGgU(lvL0Uh0^j|%RO@&9m1~~w3ZUB=Ks16$8WtAZFJ8Qm zl$Vbv+wqkA76GTkpcT`o^CcZo-#&wo49R~X?h2Pn%q9ebVvGtLb%r?4mm|k1F(NSG zX2s4QKbX}1zI?aS=iV5amd0vc_l(Bk{O{{BXD7R*NNgy# zFdbTVsj^IhC9iBDOWBXv;^KH>r-R+y(#i^~0mp$GO;oI(J!7slr^QR@-MO=L*zG4N zuLka6@gImZmUbKxLgXFEv@^ihEF4D&2qBp1I1CwbgPhK_wJh z9062L{b6gY?_o~l_KzfkH)r&aepbss?~_7Q^Y|#Ld*61LO@Yf5-Nwt;uT(+SpQ#$V znia%VQhzGFva*68YN=&)mf3VlO5X?_TBM(>io?|69fKK5VSM#9)LL9E^&;J`=}hi>z+zSa*wx$8BuCK5IfEA zg7HWxDTNOW8GZcpabdc0-S=!yVY^}eL=}P4aIV1M%$Sb9-c(ArKl$}_VbI~kEW@WE zUi~mky}7qnHWUE@sqB1ZJp3W39$mNjg(@H*V7nDdInhGUFHkQG(9r3@TilVAzJf0lG1@@Vi!pfLSO*C9duT5CKoJy zdXyE!iiXwu?Th`b_4idFMMb^h`+sE!O~g{b#qVkTyah9zTqueAQ*mWLh=>$!nVb}Q z;rC+5VYIBYG??nD#KPK8o@WyX7BVi*|LS9}bL?qeLr9b~6)1$eM%)Lw!tvkvJlmhi zc?H>QI8gK7^vY_>(Ts#2s^Q?#o9fB$|6Ut}dKQ*5LGV)kf0MGbh?usCNB;B}v~iD} zA)1F6I*h%0$+_4ac?RWMe|J0T8zZBb(M2_i+HDp49mLQ1S2(WWkmzuKwS=7=3e#DQ zVw28v_eR!tBt%(awd+@|nuqF*8u>2yF2WrBN-6_w&Ls`;_bmdh^w~4w;HL|8=ZN$3 z`HPdu^2c;<`s~wlqX$KFH!YPz%S8Uxsx)4lG;uRBG8*>Ss^k+2JYXQ*ND?>Y%kEJs zV@$;#K)i>fXik0bmi1>8<&t7`bL|y_zhl_Q=f3fm1%j7CGS1dW#kIG$%lou2o%#Ec zA}w=I3B!ulfCjexyQpO8&r~@aW$EHVoptu-@lKxl@dMlP2czqIzU^Da5Z(Te;={<_ zdp86G1wD`d{Ze%8PK|yJSH#FT3dCD$a45{rraSUs}4`$kXGTWcORViY#eU znXAjqAz>_RY@u5xrWOjqRb2<#p|+z7n)oYJ-eDNZ_>F9g@N(^HW?QB61cKPy7;v&Z zqJB1V_*GC1OymniM2)2AF3z7e3p8pvaEcaPPDoW%)g4Ei1m5HgQR08lVbs7yb&!E$ zZp>&de+Mf}N<%)0{8lO(0dD1C7`_#kCHAsgak42$9h7ZSY~}V$?Og3I|1_zQ#(cpS zd8eiBpHEC5J?iipP)!IACx!8NoE}n~wq8GlaQSa*0E$kQ=I6?ZKbr0_Bo)K48~Dzl z_3z&w{h4Z*`D2jIMiOg=5>5Hv2@m68VP$)84{h-pOTK*6DHN%KGVXC>w;!k39d7jtJob-PXPL>5Yb~m^V-P)arQT3nis$2pe7#1c299xI#`_pG1*Li z>Le1f!&2r!xG!D9LhosaE~}}DYC4Qn?>z3fLBRMPE=KP7oc9OC0!1#H-l1CN%8pIn zbs*9tb)q|HS%7OKZLqjB~yYOKQxh%x?%GXnp{F3HGPEzJIXSbVqI~ z5v6fAPIThBO`b8xPK-A7rj7_0Ei51)07Cqr5)$k^`Qf2au~w%OoAT|mBJ*qJ?Vs0! zSi|EWV&7U9+ah;<83eJBkdVBeShqrZdLgz@F( z#e8D~j?E1;aQ(LM>a&fxR#xUamf*B~?LLnag=9ihM$*>@xUtH6_1mEjj*>Bo9t$9~vtI@_Po7AB ze~qF1wEq3ZT%?Jofp4xAe{TFbW$rYT$ix%ukAv?hp@nBKLDfAc*PhYoh>EkK zoa3gZlz_jj!3d$ZR}}gA;n$fFrB)tGf@A3G!hLsoRuW*oZ z7UtEfrSX`^B@Yc?vlE#>$qvvo`sm~VI z>109xvyF|-dy^vI$#~|(!y%1Z?hNPRC)5lwkX*00-k{=;C$%v}_e;WizS>eigpCS~ zn}y_dAlmXml~fnoS1)w2_6?cD8(ov~ACg5$-7}Zw&F72mB4U|Ntj*gD)Hucjs7A`LBVw2c9+N3_! zmk4)9QlU9}8Z9*9!8JG$di~)S{EG&zbA2d+sjnasct-t-gv1yJG1`9zOv6W@nFM3- zQwkg$9_#XtZog?|jJ=XtF|{By%L3W(9d!FEgm*;!g{@4Q;=;xcGoRH#NBM5md3dtfB%3 z^lZZ(>vqcr%soFp>&l>7_D;X7KbIljx?%WhU$vI;rAV;E(rEWJ@6M$yGSs8pGo(z9 z;p8NeIQ%MHh?l!~rIEY&83!op{zbmz8wi4w$mcTCIy}tKc+}^Pf`yn%L~fllZnYKO zeYbS4wj8e@ysg`^<=-Ssn+URD`m_#Ut8Zn>%`B0L3}`e{YAandZ1E`8J&XDq>Y7 zUeM5~hAO5VQem=f2kJBA#Y@Zv{hg|Sy{Ec7usfp(s$t6poEGKcC+T|;)eg7}%fLW2 zvAUaPwCcaB56%!86RyJ{ypqqoh4sr43DWj|d2kCqx|4kWlyzF)RcBjlNDjVLaAAVt zI=Jdk+3usQE0^x(aGW0W2td_Vlc6dTH;b{PIZ*v3itF1~kIBh^!Sz}#i40U13={&r zUl%MM&;3_u^(sZq#A$Qb#-yo*#jWxwm)r07AA^m1ex|-}tJpX zaTumB%03V5Bn|4*&hxZ8$eb&hYrN_sf*~EWJ3YOA&N(-sP*3Q7e4T9geoFhob1oB; zl$l}IVp!eRG@t&j%)zcRrHbzC69Gqm?ab?a0SNfxiIV>x8*WVl13I=iZM`jG%VcTCh^xnqNQMl?3%gG=Oh*C^Q}Q zO>PDLczH`wNr_@Y?q1bPXL>1k<-4=#yTRRJNWW%7%?P@?RUeoB{sb75v51|dHci=k zRve)B2}20q_=R#2#-N<1-JdtsvwVMNR*+}k2Bt7=^G=dxpPqnUdv1RyHIw3FQ!}&J zyZ%EgW!U1F`HQppwxuQB4`U)Ooh_LSel4vzoP7letC@aaXXkZLaNezirOmo6H__i< z_|+eL+&e$Mi;IQyJ2Z7O3#C5iih9fdqqhtQpvjz|CeILo=eDpQ-)j>ws6un7BBBzb z(bl9SE2(%=ebKUd_oC^4*7NdY^KPyA79__-K%~b}mJR5Gp3K2g5tl5hr2a2pm;sa4 zK<$W+mRk*vfF*V-`YwjAdT!1t2@xf4+=#iw9l(@g=i0Mc&9&j!+@JmEZ|w+Va2ikN zJVx#?x*k_kmxv(~HWNl_v&OVD_**nvbA+rO(M&YROW&v%-dGP31Q?MrDC;c8z~&-E z)fw~QwgzIIe$1!VJi_k5LWWIXAlLlqil|UB`u&*GB{~h^K6=R=V#mt+(&1S)hH}b< zS%xNNETn$V#;a$mP34tDXtchhkX=WbLb@9Z+(k~P-L7Q}s}n$Gh)T!rd~0BA z8*{U`P-X={2T#`zM}24WL`<=+BgEnM?c0OcJWSz2Z<-8nR3cZO`>v!t-oC58cem7) zy>TmV$YEjN{LjErZ!<8{%Y3#T0SM77@!4TQ`b`l)kPVD|G-raf0!l?{Iq9z>}(|Y$)u=dS0zKq zOCY0J^pgB7JPz7_{Ic5?I4>?U9j}{C?aXUD09nD((h}4e&q)HCj(y&m(L^~FcJEek z(Cr0x@xvi`UXFFnF(Kd}JgLPyRZh3C>R2xgY3Idbi|v_k5iX-|M$S}K6}mU3S?-<^ zFE<|=baLyWkc)*4J2F^=y|&q{9(1k(=miTWYWtgWu~|oHSuNY!9xBNP0GsvwnS4K+ z0$i!M>9-C3@xpK6Sd9tnFANu=$YFx;)9Zk9@}E0gVczri;K**UHEkCSvXx35wGg#r zp%IHFXcQVp7()mU3|X$iyk7`I-QdQ0;JeF3z{1+XuJC*n$>s+!#oo+N_MrtR8bCM> zcepR40GcG2S+M*?;<7h?{PZaocnUz1oUC-dpYc03_uP!ayFT|@fAaah8_JpeYf5n1 zT}x>?qdo|a_=SaTxOEw{P!>tyZ!t-8Z{{uL8jD4e>R`!HCAKnC>_O}9XK@whP2Vm%Kqvt_lk(FU zsU2EU*#SUVF26rgw$iLHo@S+6#U^d98~^bWzS-GIKTtXQHv)8{^cyFy?4M&&LrS|G zMkMLK&byB7y!Pj|1CLKkRR0mc6Oeiq{o+x`we$0kn=@q!jsJ+(-yK~@{I{to?ZP~O zw81cT&WQ4uc<5sV$SHuLl+@i^``fWj)GjfyjZuar#jjVocG!ZxMXXze+p?z7q8 zX7N{<3pi6oiRQv-Noc7~PXrDLXihC*osivVab?&Ns>#k#opm#3^aLqNM*0yLj6I78;uf^#IYg3N%L zQm&O!3x$SdUkP@I;Es-jY1}GQW(YvFendJqzk5Z=_iy)__M*vV*4KP~tTO=(6#vh} zoQz;YFUgs*=e1bnh39>bK#to&gh8f9W zi)RW}QV8#k*2TxgYiNc^X;;4T!!ccZ+o@mH@ZY>19$T-PdC&bSuymlzRfw24uqq`d zM=Hz@kh-JYRnK3;{55Wjd3kw?Pk!jk7ICZkSQnwP=_t4P56TOv6-5{zgATIRuU`I0 zgrgm28#%_v0gk&psG+y{CRFysc1rJ=Pw`O3@u~W;|FL^%tj_gw+UBB?fb!0zKQ(<* ziXp$svNAHhHa8=1i9k7C9#@fM5ted~-=o3+KyoOihvvG7bZuQv zQCVF8-KH%--(m-`%RN6?nPIgv-g9SS)SqZ*X{?-_MDF~0Snn%kPkzJuw{b5CoRn&r zLe(sFr`zV{K()-Sa@lj~(w&Qk6LBO#-8VwJc!iiK%S0umq`;k?iQj(eeHgZ-R1D|Z zBT=8&IPthd7Z1NazE~Mp=;(F26E@#2{y4^ia>9A3`TPv%u9m%qE*1?ht^}v8)Va?$ zDo${f{e|)9^`0}A?=A6UQt-_@ONvvak2M&E==4()FuB;`_MeT|bzgan3jMqxWR77l zhBCv8L(v0-byj4hn*9tiM0&Y-I`?{?HM-45UP6pD-oW3FgE-=v*Y9Jqx>i275sWxaQCP_F|jsy=O*b&3fblt}QjN{N-I+OUdI#uf2)p0WG`|Jc`+y8o0Z?(Mzyw|7n4XR2E zhv$|fu3QzIkrbrVGzr!KbO4oBRYgoqJ%I55+ZF=I2_2%|(ih*AIR1qt8Z&gC2K;*z zc@m3LX1kGF5z1}Csy(AUf71|c?|DZ|eNaLXWccw}!N}wOQg98xHiUIc%uOX*mG=?FuPj z2&HWBhHbaypYt{a6jfNID`)GuHc=Q?nFPwjO`4L7Ib9)Q07fg>;juQDQ^S~O2>E6W zG6IdkF^Zp7_p+2^-kvM}VHl>GzgfQ>)VL{Y?w+-5Y6E4%dje+~NZeU@dtdSL^2#Py z+uA};_BW_T0yWG)gWeBELT)wg-IOf^O^XF(p@{9A$}*79yZ8u>{rWFs8-AYefNaACl8D6sK`X7sn+bMqnW$4-b3Ld&gbC=a&_6mdt*Dfw^?33loIvp>d@{6V@^oM?yoC6Z{YKMFoY(J>}}0Y(nXA~-K@ z-V4;_6FpHG2%}VnH*+<|ybv@BCC`yl zB;sYpugU2bf$MOWvdf6V%15WlFX>+Ld_*#&lq}%cRmK495RQ^mRGic%;WBb%L|M*o zpwo@!@k8RfXGTBH!V>@di=8KNWd%)mYXsLkthpj9>!wp?3Un3#j5ahhC_Y_-v)FWm zW;0b{X_C>T@f%-b@KQal=?C|3x9e4Jb-s2 zv{+>VWvyV&yCrCeE4<<(1uG{V(v z4caF;CEAU`m%r~qy_?6U9CACXOAhi_XlQ9*{mLrKVKn?HYyx97Zu6W~HFjroes zbHk|ow~ISLuVAPTJGR}WI)f2ZJf#&COrl|$k+fFU{tyi~;EkKkqH+w8Wu~FalK_?i zKjsiYKM;|GY_tE>u6F;%8C?M>qB_h9`pKP$tyCj)uaXO`2J;TaSi0KKeA?oD{SDA@ zMQD4x`iHO~a-XNDL7d0)MoJQMxm)ut14xi=>yt;MZ39=6;nn->wQSvYnh=?C$hJlh zC0Zz|pp=tpch^hE&869z`m)SkOwfCvc%nU3^Ak-UnF9`FLz^lK7Yj5G3T6AsC+Pr( zrKG>T$i@~h1yNi|TctI|M2!VHA)++i(}BnX0Z+K1+VGHXfatm}FlTQY=0(=&Y0WeD z0av}JjBAmH6!+!z-GI%JpkT7bGpj}v9>y?RHD@`H#$CYb84w)A+8k^?yaeeuxMxB3 zkb|YS9nhJm>1cSe20~v+wq^6dz&VKgNr$H=RkJTImoT`^$)+=k%@2J^@qa& zbBG-fgWRt=(abzc?6x&5nOMG4&nHYCtj}a2;QPMXF?vPs0W3=d-z!Cm<41Gd;-{x;_d zfbGQMBTGw5t8Eb>tOr45R}MS*PmB~^%#-FbBd;RXB}kseOZ6~;*v3~eC`tJn%vT5a z(w-*kybu88o=5c zt(tVIOa)YOAkyNH@NgwSKbw^A93AC*@#61xIP8Q?2qw#77YdKkuAK4t*{|gUehLmm z)Q(GwCR^j!EM^Y^JUXOgWk*+L1h1Xo25Y1}c4G$Qi~n+;O40{_Kq1kaj11NL0yDUz zP0hTi=D&ZRsF3}M7R+pJZU#~fOZI-@X=#o?#2$EFDk@MnPdH=*{*?s=7UBmlkFsa{ z*?(9o1MrQ9!3+}1i1?c<#5c{!Tr7gAY#g22gK!*^YjLg7Kh>n}*3TbJh4L&P*4!7e z<2@&X;@L4<(NdviV3WSx%9m()Jw@^bpd}pUL+=mXutB zK>^X<Rw@=B5&{NHHBA^r?2M&kpI#&HWiOQeMoSpVtF02fITw=gl0gxf5 zUY0O8Cc%W6ShPlINH!z9-#$7Yw{ZMgB@7%!hnH8 zvCh6eh_>?gr@qu06_-7eFj`b<3JT=HaxYGHC+mE!gYqovn}ul6EXb%q?CZ!#@;SHp zB;_lYR+LyQ93_;v*7i6fr>Uu_y_w{z#up*gRmD5(SA+OGHm(GBTW77w+--R*LfQ8? zqr5aPAz}-NUcg3PyxqhZNuq`I2J|$eKpG3n-GW(P&(HkYLV1?0730Icy}q7jDwdYL z0ss(gZOt5o7W5*O1C6AUE{}II{kJW^<+yw4asU44G(-YfvkgxzP(o6pD#x!}i@ZyZddYU^1u9n~Dm{$<|_WG`Nze|Y~1ufe|zJ#uZz<{!Twq(eYhDR74p zga=@!ONW}qzD#4+0Ox!8*c*t8H6M6hoE^?Bkfs4J+-8*0vs&{GZ7X0h00qC4_Bc~RK0WSAyz2}M z5^{7z>f+)OjEMonZ-M@)Q~f=x^~cm3ze$kK&&4{g z;Z8jFevj2CEDYV^ZV5P;C*cWzQzD(c9)HXHF>_Z{q_#$e{Cw|CeftlE=Kr@_O@#$S)%RPoO$iU6k#NjmM_{DtP95> zY`3Dt!n7WEuq-D@BO8nqPHabwp%MIFGrRx{Zsqu#0t3S*#4jePZnKNg-xsvz;CGSRt4ZXaoY5tEvx6uW+VLJ=}*RR>(O;xUq#YK0&4~{F83l-6f#ezW{4Rhv81Fzo(?h{5%b;B0HYWCU_JVJQB-mfUGS11;g8JZR zmnJMk><*#5_{&vU5=omUY|<2M+wH<84A@AhBkK zuUbBTuJK)zmU#FDiV8VDf260c-@IF&SZW;cDJp^+#$=+9%?3%a9Sj`owciN$e?+_& z{7?(vFQAw1YkD1pPQ?MuHRo|J+EV+XThofmyk}gr&XVzrTB3oUsZ%kO-#!D^uG1KqK=4(iof7LOjbN&EUO%u>x=C3hh$EbY%Dg4&;RmCr|Hes z!SB&O>0gvj2XJP=qY&i8@3_kE-@pINI_>7xcLsgA)Zf7UA)YtIAMxV8452o^NI>XQ zyKAd&`uQV{qCS!{R6zx(JYKaU2^hef27a5SaGJsJQo#65OJjGCWe2DU5OXn5Ka>4D zC6*8OOnl`Pzq>lH40twxbmQOv0~8mBSPj0g1b{?_V<_G*z=V^zqpr+68&^N-ZhBep zpCk1Y+_Zntn9Z5~n#f>RESpV{pST?mbhpev@J1~Jn;;}J7(>EG64`wS0s(Cq8NPYb zmUA-YGROqzNs{(&aKJtU&ic#;cz*L7O#IzM8u>%omL+w`18c%w%ed6GL za)|@bgn1ekE@A^NR%Y)vH5KAL!^254+d3nrey`>u|W5KDYp6`((tmI3mIUB>xx1_0f9 zdwWxJG6&awbuSmb%cK-N;={o#&6r`qv9BdAqlJL_1oUSEl^rerKV83dzHnAz`x2u> zNO|~wS9Yk_JYBhFki|ULNau3{=uiCr_M{Y?S5w{#s0l*Z*k}ewg`)jHRWalh_UDzN zqznbLU>gdW9L4+--Ah!4T=t${faS2L_OJQL1^l63uLf)AA5(3b&0hX;PU=s!_tyASAIUc2^x zsuL0tmUlY20i7YGeP)UFwZy~LlP!zjakjg6@77$LpY%0`n%q#2QPLWT2A)Hk{WV(k z#6A~^lSlpiE`K;P*Y;g&mM_8FqC(*Afw9_av%QAwd{oRwAZ{c5%k9(gZA_3WY3ROH z7X1Lo5<2YJtI~ogWRf|?@(?FyXF0|v#+L*T&R;4+j04|0w#RuwJ|+~y-Lt+O=-AXg<;w|4X>#4wjd zCc{5-wc5zX`_9GOi^nT3ZJ`3u^K6t-(U?LU@C>M&D~<>H`#Xv*q8SA}{{9f|@@!j9v{_p&GZPwO)yFm!h{H|2pOjkXc{k-M(N-6?4LqPX@GrYmawIK&` zIMG{Ap-MCaFP783J4@B^A8jT9g`?=HsCIeG=-S)p)bWLdg{cq@NxXWB-QwPaMO$Uj zePC+sZ>dLhatEnM$k2u&KB8Qb*>5qo|NAG4lZ*{$m@?lcs(Ag)tot_CxGzi%eEypr zqU-ivQ&aZk60COc5UmCi_itMy-3YFwgQ0`&NJ7u{A^&L*3U8Q#wj+Gg-UMzU6DY4r z)YCyA^w3E;x$sCXUl<;v!`~LKL6xS*45W;Fcbu=kIfUluh0W}`1 zvCvTtJxYHsF{oL*8Nv@xOjKf;vXkJr)p`S$zXUJQJ-Ab!=>`?{1s| zkZk~rDYc_+gWT$B1qt9kGtiek3^OA8_E|%?ea~58;R_cCB0TzK^>}qtEiij@V?8q$ zxE=YFo=*KZHJ5ol8xQP(T&0kF4Eqiup^HEU$ATs?hv15P^Ea78F&*B(?GXE!t}@a4 z5&)M2a%GvBTq@^>%N`tpnIx7q=e<(>S?UQ>wMxJw?d0;K24+|F&aXVgwN~qElJHg( zX)8i27%2A;X#~t)hq&UR?6pW2bTRKY*SIN+y_BJLX74u@DE+h(OnN|>52|KysuZzB zfs!Z@A87w%98+Z%U#OwmZx*(Xjg8gt`#yipN<|f$h(V#F{WfdK0rVV4^_+L{9pUl{ zMr$|~5SqCZemd39J@XuvE_nF|8T=ud234Ow1J^$)CBuat&hHLz0S)C%A|c%E^1mN= z`1McRP1`@_W1gQCNa%F{o<4u8(ER(?jmJ1M*Ix{vV*h}D(?6D2fxAwv(dx)bYj2h9u$cVZO!vYa#C~5)VU@hloCpPCAULF-<;GW*E7A&nVfBj;W zO^@qJ7Cy=hTG`I&j&rlvW!kvhg0ja0ZEIWH#YU(S-%l1~Oav3tM_8xygR3;#__Y>! zuhVK@lDuQT4%6B2t5ExeRUqYeSsblz6M{~c*S5A2oFTjuVP5fjd*1cHg#jRh1bjes z;37@}psc3yC=SI#;cNvwZNHleB7d>Vc#3K0JTG_m_%XY6+P_6yxuCs_>PB6xHl4Eq zx1ho@nP1%bKZU(@P?Y~0{=2{eOD~9Yhjfaxu!MkX0IMHFM7oqNrMuIhMF9a75D<|P zX=x-3Kxq&`3F(GC_xhc4&YVAfb7q{;aoFYAXWw<-*Xz2TOARj~!i?BTN=hn}a{7vd zgz%GoY9Vo(n}+k;g^XZ4xlwLL%8S%MPd6T}5^M?6he6|LWQL4o>9)JUYZa;WK zrot;KWPG04iyjn&ocSS4#E{A>>p){X4yYpE@URi|kY@bM02yj(^uIfjNcYE4ui}`n zqtgrPdvq8%yOiD)Y+<>OXROWt8kK-PedI-UQ2mD`A*KEEXR8nI&B0*QZUwwsLbCpJ zMJE?kW~i;{t5Y|b6kI1ig2D`w03_J8=5RV#F{*}n26?o#E^JfGu(%g8zQfhJAG4_r zL>e%#*-UgRx+c+X6_Q}?@xVN_J=&N$ykLCKZlZeSW~l&2uTFy*@FgS*s`7{Y8Y|f+ zR2J7xCE4DTSxQb}h}0wk_f4`t;#t7P#f0SK&M@wZ-MghThg@dC$KJ4kLoWmlxz+&z zsy2r*GN>M7hkZwf(%d|Zg?O?@Vc3&OPo2Hkv?`tBqtU(5@9O)N>X+k#3D@z4L|RtP zl(*S?YI{5;-W59hc7KTaiX|grzuq@Oobg}d$2S^`N^_jxW{>ta2TioFv5$rHXZP0U z+`Kc+GSMZyZ0PuHoDA#_< z&DX_HI9tI5>aeUp6$qMKz zb~VBS-V5^&uw$s^R1X&OVNAx8gohL{gKX&TP7i7x5&_l>4)q`oKD6CEOTIRq$Rc6^ z=~aYa2itmSVAa0+nKY)2wHf?BAVfH8nmpmp;@Ep7AilyH*g zLVq5v2y6q;CeCzGABapjBRy($Ame?4#Y)@#I=RSeAe!oS{KMNoljpzOCyBq5daEac z7g{6VZQqXu(NG0}UrZ0axx2F~;ofh5%!3dlNJ>jfOENc_+=*;BrY|uaIh0=UGD8U$ z!aErVGrG<9oc{7hOpt&kFXks_rC9M;DZ9;CWi(H1FOB3?wF18cEBesJz7}&^c6f-) zQK~yB0wcE97!T!nO8f=49&~Nc*(IBSp9kbdbirF*HB#@v+c_!&k$9Y6Ip)?G}Dne3uvRY?;$n4INsSk-N8mj60VfiS(=wbWC#AK;ND zn7?u{A7iWmYx+IZ$v6ClRJhZbU@fr*YL*fU5V7Yyl**Rli?{i{sESUBe=>CGJ#;I<8d82|o90V6 zChWE_lMM|qvG5m)F2&Ayv2^$S9$SzE8Hj_vJUJDrxVx55ckX@Q?Q7!%dQ5|blTF0G zOo0=r!OwRBchhNen_n~8h;jf)6p4NXs1GoRvmR3bF3du=&RIo=v9D5`YQ)vFv$d7D zfN`|ORVs;7g-MK@*JP!wVy*K>NSGm%R(sE)32w+xxt88$It$MwkH(j~2kM6}@mhCJ z{<5_YX)_#!!B}Xq zV!1_V(SdDqP>1(SVT2Kz$r&ZGzBPu@KK><}ig&dMHIr&2MWL9BdzuKw-taap1-yCF zf$MyYrv%Q44lbf?@XKR!@=@Eu8TuZyUTjs>X+8RgP|TgtU@cOMG1^Jrh1-BEK5p2Z(VLn85;cjhMLsafrh|38k?FC z&v9rvB5|1Tl*5CAo;zFkdJ-6KmR$=s^J{7r9;H0jc}JGQyS}9=^=y`kr)+j?bhH`V zY0T+sS1(_l&Wq-XE7{@0(O$zYL+h=?*u*5v_9mgjlfm2NO2AZ z_p9N%xhYkKVV6YK!67(vu+9G9vmE{Ty+JJiOYSTQymMyH_5@6SuIHN=H2Dp^P8c}tPXlt@ZV%)SfzsN`C^VsbHN**tG*)l zBq3ep9t(>1$4q~ATJ5U>hHTI4J^wi|QVvQ-un+l^*VXxc*!kfIZ9g8w&hljV<4*mE z2|uK=I7{5CmZ@NTU`m|ePfsP)jWvG4eRq?2%f#1@=)ZN2jQ)ae0ZY~=vPrc~Xkm^d zs^s43qPR+9c7mT&*X8hlp>o`!uOFde@n< zeBe8APMHOHYcjh%^Q>z)10}2Q)-Ej~H#a5RKo-Ngn$_sWJGHWu@xQqj^F@FB@Amf2 zZAZB*L3&ha%EyBavOkH+h-=hxa2{5e3gDOgp%iq41ltlP`H65|Dbdq*KCo6(@gl+C z3}ttB?X-|6ZxYwjD>}GhVS`HMN6cH&thfmKMPZ^WjQg^PZMa6bsd=>Lu-9=p16M0z~{YIRu_xUsv(HwP( zjC8MN9j@h4`3Ev{hP~F#K?^$C)u$f~T)AZ3W^8015Jv~z;5ce!J~?+NFR2yhOc)M4 zje9T6hd6ektnFQ~MU1u_?N&rpcTa;fY3s}C+OU0wg?|t`JI5V7j68WqoX03DzHOU5 z*Re&@M&6~QqoeD#H7c|C>VweG0-g4GQi?1YVTV$S?@TGf)8noCyHe92mAqM2l_T0& zex})B#lp=MHq4OVu9&%;GN&kn-wZy{uX8c)WvqdA;60wndbiVk)nau4F3P9?(xT~e zx4{$^;+a%4=|=^}=0@)6!8|RW1AhHB_iROZL`F;y>`4B98<@#y^q;B5&dkiXW#2!H zm{~kGSS(!-p&^2yBz1^uPWM?Y8Q@>LlIanQN9c5POp_8tb?UURL`ntNcwEg%IU%8< z5^KA7u)(N8M;N1f-*fQD4k7ZTgi0~KwKx-$Ls3PAS@Y-5vXj2M6N-Yn%asFGQ;p|k zEMEDX`!{ifuLkM z5f?pPX4bsv2y5#=5{Mm8Fen{Hqe9_u_|LoJ$jr zXNwcFSRfoD84vGo3!^Lggqeg9oo@mAYW`L-f8ixR&g;g%I=9p%1!tw}6yHV@2KUhD_x*Ev9`tn~s?6KR?gq1l(%bVr!S~ zoP6;@$K3<*$kRX$=U33_z9 z_Uvv>_F1sZNt!ppj_4=$OjcD%Eor7jqfM%dg{1~T`qRTVAt@>An4~~qsio?!-M{~1@7r?i4BWvIF{%0Fn*uBOQQ!eHTGdx@|w;V7f& zxI4h2GM8%>QLr{eJLK?|VCnhSmZk#r0@~JcA4sA&5Fv&v2?l^z@jUL;3~zqRsVlM_ zvM?<4S+V(F`6N6Uw6tVgQZ|2#NpK(I%S8rFLm!tV=indvn%L*fpl;%}6b zupN9|^8UH$OX&YsP&A!Z7NWWkBaZA>0tpSOxJ>CTJsAK_!K7;Z`{Q9)tOUS4mKM2m zp<8)GlT+zU_JOu5ACvJv^^GSQUx*Omhg2BTrOLi|)K$MU5ak+)2)RjZBBpw{T&d_a z+P75M%4Ftp6T0kBoi!gEuqiGm1|2EFM3N^xdL-t)5VJ1uoVs~`^RKm~B|Qj99bn)X zdLZ!e^^qJ02g9*iPOp`d7fZrfVTl$e$9I!XYI5rJlOrpRSyqG$6Owhu;DcLxbLB@j z%YOUP8TKci>Yv`fLQO|En?DeM{GLGKK+}rQBywRj3jt0b932O_64{FG&z%z#LnQd| z-7JW~x0K?&K#{h?f)s66Nr4q1_-SHeDUcc^cVe24`1z3Q$UMl0*`nFfq^D`sE31*h zFCLAzHoBOPFg_ui3}dX%M|XXSR}ktg-1zMzsoo{Qj=QLO)J1UiO9viEGv3Bt`ugYG zhog;N2>J1Z-6q+}%IbOPqJ7CizlFu&qI(<&GoTfAdRan6LeYKkN)v(?^*t07Lne&U zM(4h)ArI$o8$`OjrTt`+onPWuvKxHxCCBr9p!2nN|Mn;X6+T(^U++tC9qwP_&#w%$ zcP)ZLMuqL(`o$PGvs`BtpSeT@cPJJ28ZRC`RdgrDVU5$OME*AY$BB{ELDO&)eY>j| zd=j7;(Aj|9WrQ8|1+NYREIfOboTO??wb}eoOysA;auWc=VnjsWH&{b-t1sEc- zbz@N{Z_VqB>k1!Q!0n0R8&~xxG9619a;zasX5px@*z}V5AsJgDnRxsh&|3scf)L*2 z^v_F;)fuF08%KAXe*~xEfUM|*rWb~l#F9EXnS-cC9F5H*a=3yyM>ND6$@0ZO&gsmf z=EZ3g* IgDbjbo_Z~&*P36{MLA8iiiU_wAoasbN2fNMwgbv=-i&DF4=JCUW{#= zG~;MkLa|t{9V4*CF@faejR(pvTrYAgI+BBYs=NpUr_nz`8RdOHizN|yljcH zM9r}5TlWN|Y6b_Z!+4#&+9n)^Y4tYOrF%YSXvJhb+TdTKq^~9XUjI(uRQYj;_M`#}p$2y!yNATA0b|4pn@_?;ErLJ*+mDFtEem%~mmD5dB{brcwe@26 zJm#HFM}@9z()L;;Rk}`nVB)oR;H2b?2;NXXzNGB$dE(Yl%~ezPlqw97aF#>K582QV zXh6xUkdsNiHtE0MzCL?_zrcSNHpM{aQ{gpNR|HLhFJ2-Nh>s*3od!0+7^JU8AWU1{ zUS?DOj-~c0U>FjW#bI0AIbi*ZT1Q=FE!_3FvO5YYL2w2`o^tjhyKai7%XOY#<&bfS zFc0%g0=ZJ`Mp=j_E%>_52n~&ljC4@3RL}@L9ItT~q5d|yw^u7-c_zeqvn{Fpna}2Y zx_^CO=`|L(fN0p-GoL8z8erA1ArBn{)$c8{L`6r@BMq?w5fiRZhuoi3A{p^sAJn3o z>w3tao6@>_T%D?}w47fl*&M(U=<*CK+z}pi)VxTJu?`?h9(=N!^GsmW+6wy8s6~o? zil3h5fpaBKq;|i%he;f{JY{4oeyi2o>+sP_!tspyWJdkyZza293Ein_frV^jC`K~9 z4N`qTiyVAtu5VcKZH+m2o%xlKBdie}put$)H0nb!W^N5R<~HEfiFuLY%d$VS`BB8+ z+M#It3;#$+NU{P>UBg%(-A)lwdW1*ECbfatvv;1s1rh#vLlQhI>L;r?1uo6Bglj;& z8-{49&lxZNh}b=zxaZKpt>nQ73_^_NPQo<9AN&ahQRvt6Wm z9mLgEh&Zxvp!qj{U4gUQ$4w+1hhhi>dmt^Dc`U@^Udd12n}{&%1LOy$P#d2%Dm%cg zoUtX)^}~+e>fe)NkcI9f_VV(J2Gy+Zncr-&d&XA4w^t*6IdS3g^5 zp$kyOA8oqbrfX<8Rt!9l^YimZM-=c}oKlM|Wea|E@_v|-S?acS<#*%)2keRdyQ|LZ zrzUS|+t4xwkKN1eA{{izd-;;QA+W&!%a=Z&TsEc3ic<1g@le+IF!rylSO2#morZX~ z;L$A40tZfHd9r~W7C1|`fx$o$rZkA2Q#A$JMETdEjCJBPZM<^I^(rtc&1#y*EmRCInbk7WYa zkjYBWV%{N~MF=Lp+Z|)BA41RCPqGT8Or{Skkl)FuZvxBk>_gL(tPkgjT9(S2LKC-% z;m!~`6VTr@PMcs_9;3W_MHz$C~}birX^<}m2PBa)a(D&_3+=x2-wP9~yA zx_7VRUojDkgZGT{r4^-Xn}!^o`Rq>g-m59cKZX2EFM1P4)1p4Nn%|smPbS@k9`h17 zE?O)2L=}k4SQXmhDmKa6AE>dc9i3+guGV*?2QHEQSPWv_386{BwoT?TnH?*JhaioA zn7kZY;YnY`k2;c8&g%2JopFDt4h|28#>U7y#Ag*V%|>?h`#xQHd0FGOPS3aD3rCew zN9DC{C&yfQU(crug{K(!Xj%CF7JuM&AM^u{8i6c{GDuYej1QwtEC4{5ns71 z8i@W?-J2#^JAankz&m4??8!OJmx7qs3Tco*2A#4zW*ZyTVDP9g?KlJ*25Q*v^1ShG zHpH^#+|ZWH8kk31!BD(Rv;AAHa9ork`nsN=xyUF4KlXc8Q}X@QgtMp4#0vlq=`XKL zl9G}Z38MHdm;eO&=x52vMp?hR()uj0J~t-9fY{`YK@X;gf<@=}05MCe9s(!qkPuHQ z1W_KN+4M|LRmmC&w}}|6sE9gK`RvnO=p?qNPpr8DHq%-q_riuyhI>*53=wCA9i+#I zSt9u`jS6%*-pY-MkTOeeAsVtbA>=gcw{ZKe?4McQE1n>>s+iGfoA33WO<+;fu2 zKSnj)=B~`0)8ltvAQ+lrmq>GA*(UF}a-8gZE7PvBqTI~<(nZaG91Z;^%&(HF9{1jg zLkhu<_rxz>PUxg;{z@{srYa>l=*~gjnVf^--xM${4As`;GGvpqTj4ciYR*{IiAmH~ z2lK+fCM?@~dy2q(&b|s3GJG|xe3hK-rqKF~S2m+`em4L2P(PtNYvT+K|Fr zp@8yCTJ#DZK_K7t^@Lf_<`q5PPNC1hGS zl)6th6WPex2^OYAoCNzXK?n`z=|l*EU>;IXU>;cphyns3B!tLFBuL%rn?!;VKYb^; zcHM@N$vVZhvfrk{nCs6@L+#^#pad9h(lc)CzVI-z!--*u^I-ZWBs@+$UKajjB+LjU zm*N8SV$F?Bt^1q`yB@IfgCf3X#G%6kq-~dt?2J96vx_|lT8%6}axq~TC%8W@@mwEs`SR4j z0 z&wms9-P9(@+psnf7PUgYDqWc&2;g*V=IauZUuOv_CQaE=7%uMQBuKiWt=Ys;MYG6q zjwU>$)FRhcTTD53jx7}8;b0;m;FtlZ`-g5P{m=1&zGTlCdEe9>N*^Sm`K~HJYQFq! z@V0)kyHytUnMrPgSxWLHp0++>tMxtwj#4rr=P}Np@Uni;na81&`O68JE!l=!+z0~m zT}_jDzwNFDVmjLyhlt4d%FWA`a#vU|uWJ9er$;vHlQIJAIA|>`t#!)DZe9#3whqDH z&PanKeIsIqUg5u^q5UN?Dmwa91+g@Zjbjz=;P0DDdQt)DJc2Q2vaqZftbQqB7xp)$ zr^-@*ij0kPfp^0d@73#d@kut9!h;dH$zNE3}acMXLlv^4A}jBY>n zC^1ST2IEIVL)4{fl&nvF8`fCJy%qbu_E=jW<=5z$%G{JN+wUyw?D3s36LA|Vs4#7e z{*$~2y%%g_bHq_C#-X?sIgh?S-lhu^-k$6nr4yzvndKX z#G|C;Qq$tj(n_SRKWw)V^tP3o8v+6b z*3Jv_<`$+6eq`tR{ZMb{bb%x$eL933+shF1D4SRm?ck>taot%=ikA_`_UP)hqkM2~ z(-UF=-ENP(e#IjbtGg9rw9UgIz?QiVoR{tl{j@2uZBoGRaC%K^yO@3 zs!CdHl|!@qe?(!qW~I4iCC$I6>tCK}VGSR99o_|x8yLh;ytw1+@J|1j`SwS~DR}^+ zFXbW|t#6fROp`}AphOHrnb4_3x_$K;)BLEu(Z9lxMx{m-jg3k0gbb>43rrlH1f9#( zRSFK}(z3E)P;fwICIP4f2K$Y3TkGj<2JQTh&#zmiY{c^vCQ#_+PqoK|R8$wY#I#Z) zAifXU-!r~kV1$Oe6iW3qgQ8T3$!Miue5Xqxa(;W=o^VM7M}?(NOl*LB4X*sgA6$=R z2kP!NC4y7;&lL>XJ@l&0uWLQctg(R*J6vmDG*_nQsI09u^5;#_AwZ<_}e< z3#9CH?-T7eQ44zX;H=36QS)0x@Ss72(`2B(VOa_h562JsL`Fw%DxK5e54{JwkGVk$%av}PC$DEo7_zY-_QYpCguUs80fW5*W___c3ut! zYq6z<vggW9!Mi&^(EfQL*CGguccvH>Y?(O0sdNDD&<=+B1(3t%2~8Y82N979rl;`iX>YpHQ&PmqCVT#JEc z=fP~oL`6aA!6x>s0MA{={!mtLSX?_U@4BefKgTtgTDajYF+S8pSPCZQbc1qv1VR&) z?zwcgEa%(%K<@ut5)13o;w0+C4`L)YL;2p{yf35B1Sb92+#l<6oo!qpX=}EXXS|sy z6bq@1UU586RcAQR6VV=q48u?yC4AlsYB?k*s7E*|$u5LV;t(rsIy5HR#6!Lk5)zhy zft(P>0*R*tkP<#m+lpcs#=>Rij14+OIM>j%Y-j7|r2llwwNL-A=Y5ttpr?{E$WX5R z5cMvN2*3myIks&@8v8NYcV}j>e?w%*Iw@|2O7y-y8J8V@8tWU_{b<^TR{bvNB$xmp zj|5fl07kB{aYizUuOa&Fcc*uTp%+E8=09iA12i@~JPa^wD5T;-?Fj7YaYj~FTq$M0 z62w?QKq*2vgc4Og(=;{)2C}K6C+7Mj|AW0z4H$qs>oZrn8*rr~PZDIsB_u5&Bm~jQ z7Oe7Y_*Cg?%8<_m`@Ww)A1?Nf#W4zqbQx05@N@f8Ldt^ycBUs)tk&0)3}LmyHL$7a z$Wy%HdXpCtOGQr;Vss6Jo4s#C|6&$MRD%E2+LrMfJp@`2rNZRGd~!5;>a>$O`RtjO zq6HyCL~_>fR@pFFAGO?dGuIQ`)ZqI#4j z%Igi2>h`kzfWr8}rLw;{eRh@o0J_@Q*|~u~h)9~)q1aPI@2eI23#vK8+Z3M%u4*T0 z8OFLVRkeoGsiAn0CqMO12o4UoU(m=?_NaUIMtd}6TPIDc@^`EEZDHF@K_cnMr=%CdkwL?Rj9FbH@{N;n^&|EA!2Q2IZ(M_!MH+8I1NPFN#zXGn{~QwyF*#lwV%JK( z<)yR&yEUyS59^X*a@6m;ioE{i>)ot!j2JJ~r$Vs~=j65dB$66qf=us3LIDWX5G8*b z|5_k-$|J=u7RvPG(rRj<{JN{HL;1RdG*WOkhw!kGya4?G@i8rG!FO+#xhV#qIkcuh zxq@BF8NAC#S$BExc8U2$ec;5k0;cAqmdA7x^>5$Q?!0u#-$3N%c)w*m__5?_HL`ks z?_;Mr+06bMVUj}WBfn5Oc3K1_C2=at*CBdh?XTtt=NEJjA6(`5>b9+Q$D!~+uZ`PQ z7yaccS0M!Bxl#EOKcrCjW%>93$z(_yZ}lU>WfZqy$R7NlMsBxm6%O0!Esiv;(_EhV z02zgUs{ATv4$Qrmmv2l3Y|j5M5_lm}%?*+JT5H?s=AZS0{|aGCE|v5#&vJF_BT#Lh zXZdzke?%6o%eYaZpEoO#&QK@Z40&#+M}GYgnKZ|^hE?i=?D70m`TUP^A=*6#F^DP? z&ax$lRedg$u0;p|_xGPsl!suxxJY7n@((p5h7m>1XlU@6n#%HHA9uiEAM1ysPw9CS zJO#MayT=m!E9SumMbQI62Vc~)4^C8&Ahu}Kx~(SQAsg9sShaIAUc|jT8PSM9JSX-H{!|5oBK*z zDDnnwG=H_RpSDrpKOgNwiNZVQnFuJ8kMx~7Qx{u0VV;>bx-38mabeh4>V;a5b-u=v zS*llQVs8{9(HeO}4kxQ!Yil`;fxil|HRbMc_h2B=wgvCuj~}W99(chIyiOO5JpP_g zIri2`S)nOJvm&A`nlA695M7~wj{^k)LHgZ8+~Tw7D3(YYvH%RrN33NZ=#47K%Y%(# z>^16&oZPuSZJg*UOt@jvZvWFZPxE8SxI(^+_IJ#CsoUGLuF2Gia1=SlpLBeh+WR!M zxHErc2srU&Ou)t|{dmluRFizevj2*sYuh_13cc=lQ$Qqmd^kC+g+~B!C^ydO*LzA_r_-MW_vZxfr|#P|7?%FG zbf`3E-S^8YFz|HxWK)RgnfRjEiN)?+t&5l*1h#whE4e%s-Uy4pTvlT{$K(4fIx#WP zN8qNMfdHSNVFV(j?K!Q{jp6myc&XWM3TBZn1JGpGOTOXquJ6;$Sz9-q=%1{szhCoI z$KS{Gl>gHp4FY}#A1lw_UHI> zOR3`d%BE_G?#iGfhP)=W?IsQz@=jXJ@xSrEgr@M3=11+<_wGx7wpqSUbn?Ue&Mg?i*Uf|R0)^S3390z^=mUcF9D~(<_#^L4>tC1n8I zTN)4S&By-}9ce5db~Rq};Fk^yhHklOod+p6{MYXp3~C-cH!10l!5rHQJ;u}J=eOBU zscqiP9~%*Aj|Og{v3D&}>gZI!c4Uob348mgcHB&~lTJ`>jgWtY@S~S0hGTCNFX~f3 zYK;5VsNuNxo+Mc1AS#DQx~PgPT;E!=w|pHain zH`16_%NeN#er=qG2RH=kIi8zVtft9m;nYNi$hs5y|8N@q_>(U|22F{g|M(>gYF_Yw zK$Yig|L~IyhBXq6^Dny*-hnH`ozGA8b8)cwxs|M{) z$BT>INQ-*$av|ABv^{!be>pt6vOe-by~qAIY9Zm2^YfEu3z1KQqVxpNYN$KyzlC|< zIH_<+ozY17OX^)(p%b#SZL%p*+`aU;UTBg%XYuyYx9-P?PKoMrAMM`xqHqqhOYc^woP%ggiG55;XGGKZ&Qq|j*1 zyCb_~9XYPt@NVIPX7u(&O_tN zg9?g2%E40x;*U$}fK#SPi)*JRR_<0BE3KN$f0z9gyW=3@Oz{bU!opJu9dRWWcz%6OX8d~Kb&a_(qCKui?4IR`-(KS!BjDKKkC763{*54+07@uZ>W9q z@aa>?B`2+BoW>%r<9J!};}9o%d)mN#_i%EuQbAOq<$fLhK({{d;Q!~*lmB}vrJBGA z9&_qdm=-P9I6OsD(CdP+myM;Dt+KU;E&PR$m6ny4kXDe8QMxW8r+ijg`P^ACX=!C? z=`Ww-Km31Q;OuI1$Ikcv{DSAnXW{1&!vD{2@Vet{>*;0b?Dl_t&2|>U6yZe|FI?3w J)3gZtzW`d_bA12+ literal 1194 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NS2ic{vM085o!=JzX3_DsH{K;hh)kDBy6>Ea^XY8WXdyA)}LB z|Mjci=deaBU3J^<$?@%5H@+|D|KKSHB+}#G$u(4SD)=!JGIa<$%wc%MBB0)2!FXg; zi2fn5?)#4FhW$6K8`g%Gx9w$qPy~sRb=!XaH{8v>;peYsw{02p)EajDWuEcZJ>mDu z@B9tkoDaNi@Bc5!$P@86Mwsb=lQGkbpRxu?uOt}@W@<9_RQL+3&l6%0pDBD`g1Bk! zElWlpqi26MGf8Z@W~s(%pxP)I{Le(YfzxeneH_E#YrFSnGQOF2;NIoG$M!Ik#eLd0 z`R~Oe3}vxj<^}IfN@K9rtKQ%F@8lJRvgjXim-igJ!%!CW%Wm?Xn@@|Cv5}RDnYMv}m4SidThSyG4Y~O#nQ4`1 z8Vt;>j7%UJY*sE5JR)z4*}Q$iB} Dn+}lu diff --git a/carveracontroller/data/GcodeViewer/tools/ball_end_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/ball_end_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..82895760b6e42366f7dbc80f1c27feff29f7af28 GIT binary patch literal 45067 zcma&NWmr`07xq2$&_hUxbPWw63?ZE(IdG#QDIH384c$FRH-jPqQX-v#bScuE(u~sa zZ2!mmKA#^xFvM_h?Y-Bv*13M`ykc~<)kujLh(I6^sfM~T0tCVWzQh87@qrg(w+}YJ z3yY;XLJI`);{t(@;ULfz@FV072;?aY0{u1zfuu4)AX=B)W<43;7x=HAsVM`mz{jOh zOEB<4;GvE#38s z=haJ&3{#7RkhISaAm-8wVs6pGs&BKze@Du9(-m7Q&15PN4b;luzMWM@zEQyaf*qnj zXF>2t5&Op*pT7>@KMoJJN*o0oWko&x)D`@xZF=^4!M(2b^yzoMqx|Z%A8qF(*Zb~n z)y{#-N7sQJ#1iZ$-wgX*3f=hm1Bt9UW3#Tp*8d3*>2yYflB zAqWJAmZFYj$oKa4>>7-C(%~QwloN%ZOX{afP)$ZOV?_HuOJJCgw12c=cs0@XEpi%!#tk3e52OxHJ~W1+K_E1>m>7>mA*x7@u5jvrEir8$Q@dbW5VW=H zpLG-t2^G_F_3#Kk3Ow>xPov8fiSMThw}>VnKU{wweD(fBU+%9y9ocnsF&F{o(1<^= z3SV{EY0uz^J>D3wyeSF(lO)2V)!9S<<@ECMI=;JJR;>6LdPK0bjD>5Ib+j>%#(fcd zTiFp&QNiaELcppY&%JIp&djK%c<<+Ezk7eV(iL`e_wR0e!9pg#YGjl*J11-vB*rF# zAAEy{>@%A=9t33|kh-C6)Sc=2g0|J7ernrua#@jr1ve71gXT|7O9$q!WcW-E` zUe<4U*ZDwsI3wo&ZnOHwhl=Xpf*&^1^j!tLtTYV65! z1aCm~G?Y?teAmOp*Ea?h!x}E1U8bH&H)4Zx)NwESrLnP75^tLkh2TN6{QN=hHmU$t zXj$z0_Kh=@!!yY@KgyvY5{OS za}e42v@*z7zQB<+YGVHJwprlU@d>K&D84h z*X9&~|L{u!T}{GMZKQ=4mTn&lTA5l!eTt*8g8iAC6{}Irb_EK1n^6(0$wl?Y&m>+| z$-N35LK$jP7t_{evd|IC{MYXhBKAg3jkSB+h+TuSe*TSz|5K`RYi$R6d-_U4;&`nN zGbm^Mq&bRh1g$9L4vI(UDyADoE2s~HX+_f;rLey?K#>pxm7-Yv^ktk`4y^MfUAUci zjvzLu>WCV1dUo@=o_1&79gAA=KHx&m|GxFrT@%LZ?gq0j*}C(T#L#^76>r4A%*vxn z_X1m+6UTE|J?hodQ_40|a*b4&jJ#vQzb#bRxTIX7N3cCCN%rs#XNvkYrPla?mk48G zGFNvVjwQ*%hdD1^z6?Rxy!X~Kcz0E*$f7~XvnkV}kpNB^k1p~UrbCQbHqK!!%z;_v zEgG<Y?4aw` z*1DP^%qOMH#no*|vOYR1FKq-A_$T><_n7L&f^R`&4>>`dc4FO^-^p-%-Zwhxx zAGIblF8L9+A2p4Ar^B(vg==Kki1Z0FCAfNdCE8IoonvIk8;nSSE&bu=@6noMe(oYv zsBS2SHbh15jP8kj9@ls_k6kZ=R56MRl@fvTHK7dE=96xsz!msw_BAX1$yp$I`%#XJ z{zq&?fthh#9Dl+5meO@VzVySh?Sl%INwY7V&VE{0pGv7wnG0s6_@5tB=(u)KT|dQ& z_~yK<3XkbBM^^CR+}VRPQswy)j4C4=mxCT&UtfNSXK<0D?y?4|Msj?P`+H!OOkH$!YyuVl6aA5{s1pd^$*>chU~+eS#QElSU4scB!!QF~lo-Xmaz+qegNVBiXH&|Ik+Q`Bui z*L9?EC{TYJhd(?{LfDb=guT|T?+Zud`N6!Sd_a2d5Ksm8gowb zY#o-vzw)zo(7CIHza;;5v*d<*Do&m-CLOWYA1S@$^gBfdXMgWBF4(JUyTF#rT*iXQ zLMIhhBbU1UlZ>UZk`iA|yJiKmMrz@&Jquwv7-%%|kN4sJ>iqJh_`7%S+zJ#djY5RW zk^Oc1?R;nN&(~ zJtG~kg+1h*vnQ^L<0GUxnk$@0F@`0Z=glu6v@X2@7YPn($oit497HdoVlp2R7w6L4 zDKl0|ekodTyEy$d1R9zzH|i8r5S;&%21E;=|26hZdLLu^EDluoxWlG|E(NZf22T6F z-#iY&!us~d7q=HiR$2H!KJ)U^`U#zyTK|rR)LYtjh+?D4wbh5@CwCIdO680!4@ADI zX>k;dkdcBAb{9dQPzvqDF_)mA7!HcrwR2s;=i_!_dest(9sNHBv=!tlHUF|`TdH#w z)qCjSb8GqyKYaE<-I4bz?b7I#nN8y;)>jn;6c;Y#I5xxN5A5MYE63lt{$-Im^o0V? zMpZ{JipQ^+Mr)J(XyS7kug!+)wr5&XE$%Msr0?T$<*_6_H~3qq%U#aNvD#dwkt~)n z=>A}Ghr{7h)L~s9+Kg>FvMBu33?ej3@2&s&aoAN`{momchUWwrQ`Ge~xvTzNLGatV z?LRe=+sgb{-2sNIcw7^`!Yn3mtG83sF;c&&htM$miapO)zMTB$k9*)dc zZ*nvO+*hVOJo#=)EMjo*#FepR@$LG~4qeFv*n$olBs12twZ)Y^Qg(fZxu^Mptq6|5 zhp12#^I(U>e4%@91T9BXha#l5a{JnaHp3(as}C4%q-HAPKyJ(?eBVkDkgcl;F0&uF zaC_Zi1xcI{p4JFRFxdx*Jz^V*J6e&EDlGS{2Thh*%ah{)i|kX_sv%h!-q>|VPoCya zEU4TtuTtTFXRewsS0*Lsu>i53enB&w*WxHw_He=;*W ztD34wac%#Rtw^jB7PjrX<0TD~l2UD)S4rhKz6G@(m6%prT3X^X7#(Ee3|oScP)k+U za1BPRUKlSZSjBPGzsJ_NrURz%<^NHG#29iL%98j34glgnW$|@+&WaIZcYfXo=#5^K#E^0rj#z zJm$nFUi*DmP&GMRlS~j1vbkw370n$15xL~MIz>XW@9Z4HJ->M3w&A8N|th2XdA>+>JZH-GQ*eg#6? z4O<#0Ku%(s?hDGLaVR&THIHxUrV$vDH18c z){OGGSdN!tDLT%lW`wMLSP81^#wI4Lv81nbh_LJu{Mr(ogD^Qh+j-uiueDP*Z@V{k z8Su%EVe-^#Jbjm!c!Gk0B6K8>NDKT@w@+17udS`|K%xW@*k7}~?GSKf*Ki&UmQq~T zQG^4lH3xcMUzNauP8m?J?d_F+gB=^Ev0VD(p;IW4@_HIj{TJfpttQ{4phPThDunZ4 z?XwE??^)ywG}1T+%bh5MQ=a18C5VW6F@ST``VsPpie}U@M|S47bgW=`!y}>anQ!i2 zJnsPopw8MU+0UV&%bWhWr6mlI4OH{<^JO0kCqG&0Hh&+i$9fE5b9MC!;nra)S!@r5 zuqoY1Iy5i<^+LCDTC`J_n$YMAAt7U-?(OoI&|To(Jl<9(#{-TyEj`}my>mZ_BrBeFZzYuN1y zGj>~xU${4i{q5K0E0-xT73u_5WuifnJw2UUIwTv|!TtViV;m6t6LwZ?wAeh*n)dep z-TxP6X5Il&yXT^wk(a84b(qHi7pqY_fBjZ+mEbXObZBLzzz>H8MV$zHOuA%$ITnwL zb`h!<&`?&QA&}jAH-#8OqkhE!3RXITkc^+08nhSmLj5(0uK zIx;m7QtSaB7iZ??+(MbBjw-&}W(Ijv+h-Tc?XV|u;}5ZZw$>z#r5m?YRHu#%xhOBV ziuvVn5*WBYtqN*qwi|u=jgA&oL;XWIOw8$nGm`h2{gamKzY)2Ov$gYa@||mYrkW3e zvSg9IL`o7WM2D?l1x9W<9j;$Kf49hCoz)OG;*bfu@S&k+@oMZYswrHmGNq=~>q~9^ z|AHMTp=D2TdN*ziZ`B-?##0b$Yp0ak+q85fkIzu>oN>-&t^lkfPuWan_+m{!bv%#16&}(-w zrjkI7@ASboJ&kh>-g1u-8~@Nu}}9-R90 zTn69YIMET+%3z7oEi4?LJpM`e{fSjD+)0GE%Zt)Tp!4!6&YUEUq7zk0 zw(Qn-agZf$e74LS_?70oDg9%TW)?8f?_QLsk11#j)76yW`Gi3YKn|QwB6}!QdnhJh zA_2j=82VD&+D8m?!nj4lyJ(GAh3X{J>YSLsWX*SR#XlV~-z^^q*l}W2c1nhAy9)PV zjj-Thb*`R(!tNkr`rqU_KN{7C zAcCgj7P(jpr<6g;L8uC18g*gcI*Uqy*%2HNX1}d`lRf0-O}4J?uqBA53IDR-+aSo@ zTH;z7O;VmrN2(Uhp61^3jzR=)4qQ}a+%Kt?U2136FtO`Jp;C6}+$(`+XlQtRysET+ zw5(ETI`kq~+_v#2DgKna)#&QR26YlsVC38PIRoBM+>j*IlEn0MYZM=+I+Rh?;?cq1 zg=GgYSUF7-tjy~&D6dcy{)0`!QgNJEspH63Ebx5szw{@*OAaj!WFQZ4va)YJt@|kV zXDDc2J5IAtirAvAs{!fUQ<);QcZbex42MU7H#}Q; zLfz4WH{GqnfcO1vP`pv)onLiVbqMf8gv%qP{x%geB|%H5K;2vIXRoOgS+po6z#C!y5;a!KTy7J*k3Yabmqg2 zSBnWx`O0;>mWXKbO5S%wCbZ!Q4RV8LQYEvTWy{$l@^H)M}pXYxxHM~Hv0twJm|eg0s6Z&H||87 z3dVo{c^I&jg4}mphlx8iIc;yo({>Kd{!uA~Hs_Je<%z$Zx5)VW*FQfhJ^jHyq|(yT zV#7UFK{$fUix-JkWtR!MfeqcNRaGya2mVtVZ{Cd9gXWs>Fzs=z?7Hxxt5|rR(DRt!H~%v0tMl!pV^e4f0F62;N1GWq3+clXlV=X@5-+Lu@9vXv0{;@Z{lm| zQZG;LjoBmXJ*U75&=3c$_&q%Gc%K8k9eFwPMeL02(xviA-?~WOddH`Q8}ogA zU4QGD);XhU?%FTbi2wLK_0Dx`ivK4t_B^-a->yjwi!xPO?wwx)n<%SJ#6Coq2+oer z`jqsKknLeLx9{L#{n{KN;>jnM9b zMz-s!4+6TaEAFGOBX_qC#{}Yi%`LLa0H6%iSYbuJo} zMh^JAW~3Im_d@X5g%W}f?8Za-duGm^8%bU)0js@e>$qTkZ5e3do`lBD1Vj4~19V97 z#~bl>Xlf`TMP6Mmx%-ayOtgAn`wTM^UdP}5GW*EME;o2t<^#Qo-ZT$;XRR9}h^IV$ zQV9G)T##Rb5>V0qw2pl$wOwnjyOWdC%Hd+m%+iu7U8L&VGia2~MjpiwLxAk%29=E8 zpYQfp6pFf)hW`W~aDliAE8$A}0Ua+#dRt*1Z(B7|&4uaADOIY1J{DHG=eQg;5Lzqs zb)z7`t02*Ti4a6aR^X^=N0c0c@cZz9t+Iiu7vfxxP=EaK69l?-uq5Ot1jnj!zt!83 zA3nM}la;bnYaNy55hv!1f!=Q7JxTaP>#85(bg&%ikdcwGmoaz2Fm1A;KS3Y7VrucqJq&1Qw0znCP1fxBu`_l}{GA!tFQ5CBz3H}02 zt@Y8MPm2x&$JIA{_fLi4`XEcim(1abC%kfi&4L^z#?Z zG6%{J8B*K2%MF*MQ{Ca*@2N*iB;#xzJcp39bkJRSAyT_7!}d zR17u?IKh*>+Oh0)-N&y4*jW@ikW_$`KbNg9=%-BG`g{NCAql=+SWH*Os&l7ZM@@)58@rPf%otdw%y^9*UIT*rfAFK=0W8t{xk7^T3$;k9})!BY+ zZgxXBx-zaONGx?qbX;oj3kYC=YzEX-sXgb;TrpfR{Wp9`e$R0O)Oj*q zyyyZR2ngJcseG!%qt&!cPFTcV*&urGRX_34N)*sP>;#+N6o}Mv)^TH#f>qd7hvkzW z%Hd_5_012oU+PLFTGEbY3|RvyZ=+6`ci2ZTbG&2mZOQTxyOzFBK0$sBRyxA&i_yQX z>~sA>XfjkLi4}aaXA(UtX3B~yC@6Gt($BmO+-24q6r$cpz{%MeXb`5LcQax`M1e-7 z%S_Af@G$PwY9)Gx_sq5rNDk|nz?^!JD{ck4{Kq4zPdeINK##pD9)T=LmV<)T-1}5k zu9Z{=bfM|I9Fy%#mKBWYhnPZMrp)xAtjG*Jh(tr$boshO)- zV>rUbgajXlv4GK1nC|O0Tl=;IRUChR|C!}wwMwHW4Ob-c^>M$vc4yt2o1444y08+H zbcC}sJ0;Z^`@uaBa%S1yrKNnTo8gS}x2ZCX%Y2~ccXf{m0gTA{oiRc+wbVYf%w+UZ zuZh|eUp7u6LxN`DJ|4(L;|>kFrgx8cA~^MkdML2y)k_{#zp-0r0u#ubi_v5of&@>Bd77`FYHZ7X&lxTN^dSyIOh7#s9SVtE z%rjYN@g@g4t>b{;kEb})V1(BR9O~-h6D`#46T9kyn>S*FLKM$Bt+kym^-NFGzzVu` zCEn}&VkRha$BpVKx^Bb*71hU1c`&LBNTUCIFs!V9Rf)Jdx^cccP`PyO0|Mt_w*Z)! zbk5C1l7vpmLl<@QC20_Zm2Q?z=q@b&LF0|`Wk%B0Se#6Trpu#;iCMP&o9_336v%y< zUo|8d#!RQ&KDE2@`!`WZ&2CxUMA9_FrW@h^6xjLsqU$LeNBdFFd0?8Tl~vIRtb4s* z=XihiF>N}J^<1=sxcG5`a{vy|IO8p<44IfW)wAC}Hk)M$2h!Wh&CSB`eWmV)NnQA! z!S|qCuJ=e;#~*ubfUFkW2;Q2h^a6DpG~SAXBA2prbQm}xl7;Hl*Rr)xYc z(Zb`z>@5lHv76Y6y|RXLE&C4>sw@H_OZZVMke3_0xTXJ zTKM@hMv?0blQ|!djt0~c05z2L40fb-jT}k;)KA-nuYH{0Njh5eciDRn8mW7A04lpZ zN!iN%29K#hz19R-q`QKjY}WH6*4_CIbK;H&R_)Pso(G>i$nDHMAH{5=QHgBQOi5VA z&#x)UJFO@s2ajA}+3)5=I~r=5Vj7qIh=Cv}G)#D|)$jl6^F(W7I5iOfOD_IQ>A3p( z?$X?GNJn`u2huus+st`$4Q-{$9zl1o$$1j6VrQ1Dy+xu1Vo05 z9sZkPc!rM3lP7Zr;@Ubo?s3ubL?wUf8X6)N7fpa3sJXUikPGy(As=c80z)T`&RqlC z;={tioI)P*7tcDZ0s>AO#v!*UVV0Ho>xY88c?~wP=Vtr2s zFIe4_%lf+t_N8bxXFni$n^f~}6m#B5uzN_Gc(k-FeAZjL!Yupk2>=3^T3!u`p5l*Q z2WwD(cwW#97mFp=wk`n?FIqJA5DY;29rCN$-bYFc6XPEYDu5|U*X{NBgp+t3et|KS zb{|A+r=9+|2qlUzTfP-cOiVORtVXGpO!VGflOIpNaxO9!q&13L-0#$EmeG1+B~MH? z5TrWVl=E!n!0Y|KT%TsS_yZ;APj~1~y>cUm=Q*2y#%}+Oj@M~}Psm#jpB*^b#(_Z~ zPA2e4_;wWgGWi^0&^5JpP8F2vS_C!_lQUSb7UWn3Lmz45L)R7Ae*KSD=7OP&*U0rGml<_$R0j8kiKxSMQ z534#PeZaDZAUsRzlZBKES{>^hqPeSd8VXUYhbZ!)@pEh0k+~;`@q%cBr9aN~pH*-{ zpz*mWBfm-V+ms&z-*_n5D{%pK307y(PY|PtUWXA&W6i^#feYO5ZPZ0B2NcRIcDAa- z9p6oGM<|@qTd(93493G#5QE{X@_1vn&3R5)iQk7 zQAi{!(?Uzqt+cm-7)vVdxQ%ABRul@qeq2`;3(Yv*iP=`W*q^Z7Ig`p%wp14oiQ#_n z(xk63cpqn>sV;|9wpKq$3|yy;2f{_cJ2N9sNGGFFbeE$f1S=55?4XDtGGMR|I|nI3 z-VP`;MQD$2XnP?A#MOt%A&HA+-5N3E>-$(BI^tS)q1GNC=PoGx<_c zrJt4?Pp)j|T`RTNkvE5C0n0i5L{9x?vSU$~ZG~TZYTdI2gS5(PzO^oU{DK-A8{1sS zXQ$tYO>!vE;m^!1^yala{lqV%WRsYvN0fe@%k_v=7oo(*p6zzL57KG(c|8|a1b{@| zbWyK!uah%rXA5g<&N#MxYOlwkBLNZ&NL-f3w(=kz`T43o=y(zLuw*uPM{1H9&Qd8j?zMBs;p!J4QIpESF z)=~|eVje-3={hQ(*fNovwXs(hm}Eat)eoCz{^HwsEAoRfj$>Q>X#-X^l*zlBN$Yg) z-@gaOz=tz%C}6WOsCc3_Iq=MV_A-p-8K|tX#WlBZ`DlIR7}Ve2j~8=tdmH$_R&QZJ zxyjgTxj%sYvBWSW+^$bJw{Yt4wak~Djz?DAlN{Rf6CAQ+ibqzyXz}r6grx!~AVq); z1nRi^bD)I=Ckp9uK@M20MY=AblI9=1+M^df;vA8p z8^bIt`@YA~OghL6L;zFQlKBJRGp#`|N;FnJPn%%z?XM@>Gb*O#2A}Kd5`b>5#IVAI zUHHL#{QE1cNM(-ECm6HBB#i z1R3Rl{JRE>BG*s8LPRdwlK=v-(Bw`F*s@k~X|o;6*4xUI89Vt0hlbn({!FNS{rc5~ zQ*u=DALCu=!U5C@HZtp2x}PF-77iaJoGGx$FU(T@u}imxNbQ}*a%9D&P~-?7f2_De zSn_H9gBT_M{+Y2e=8sa6va=Kl@`v<z`W_| z=NGFjzBDftJ2IlxdcNcj_%KyWgAd&uC9t{<&)jY3x5{XUS%n!AYY+QEq{$)JDY3Aa zsW02U1Py+-^$kDb??&X#`f1zlg)E2(k{?rWrrJ{yD2$&6cD%2r(N2%lM`n`Mzw}z< zw|ryDKJFBIY&~jj8fA8ORBlA(nYye;{on`kQy7Cy>Oxr8XBKMS@Xo)B6pV?bM@t*sqTq-V%fX~R)`dwbjc8S>ao;9-klp;VgFud!eWE~4-KB(AwD zzdwcr1p`CCLktB(03j01bwcre-~5g50HhGPXk>m)DGncXs<-Uf6T{d&0MP+sOB7|V26i9alJEBaM0JDFh(?mh zFO^L3C-$!&b$c*owaprIVPw=<0h>*tX=6r-ojzzBUT&IN+HX{mhPG+wr%&TBcDXm} zqakCljgQFI6(S6EOL9L#z#nKp(+zEmk{2bp)1X6d#YsVBaSM^N@7k}~M06Z|wdHiF znFoZFF^p6u%6c0fCm3Qaa0q}q0Y&XZ(&*M{4Z)pRSm<4B@vdoV$~yR6PIXW(cW^!X z0Vxu>>JnX7_t@Cf)TXj;3j_Eh|AA2e*X6rYUmo=Y%6*q^TNpW|chd{0#O>7xt$VCw z!u125No7|_4YtSesVWl8=KDDzbRX8y@!__k6u8x0@2Eoxa23Xj!gFH`{)9sm?RN!@ zIMZ{KEk9J1C5sN>Wu6{QH4S%U6qSvBxfs2B<9!J%;%(zA^ZQvmA2+wqw6wH+*&gob z;_m{}fIz)yFBpiRH<8O>%FKHQOJ~ZVVPs}r2lydiZ35mCewR-4&!W4P(&_ZuD9><`N$qPHg5E~EjTIvJh z!=#{N5se}1%QrJE>K`R;{rdHLJp~D5_gZ!-@cdE0-m7J7OOo}I85OmB+cNBDoQrF} z#uKS@Z}52vV=5rR4qG(9{HXCd$2SxUH62}ICCZpsz^!prKVg^a#9ytMFLOt5@vY!? z_E#Y5?f6VL*2ccj-DWUx+JL&=AUpQ-HtL*yNBP+sjjnM&DJj0h^=|C3q_O;WAc2o2 z^?R`jze=zl9?pv{J89^`Ljce)VTWrTD><`pe{nIRb&3aK1O;=H_GHaJuxHJ z&31Vk#QYB#HZNAq=RHFsu%3NRETj8oh1MnF;WU1n=9P#K`mpN?%Ed3FH!E}Xbxn+m zbC-8?=?nSv3}OGo(CBFf{HajX>VFLe+Ce8>IxD~0@9*~7Q9*Wq5VP4AxI}A?=m*_zC)4*X%mZBmsj002}~Q zZCF>Qu*1A;#h<4p1wz}`^fao&eD^SkqI*-x-FEy34*=uD*nKhGDL)E`CNo4>4ZP0$2Q4+%)cdqe@`H<#QHJ7r=aPJC?t?wuTK_K#nE+B?a6Z1TRcXJQ=af=Z4JXN)SXG*Zkri z%~7EgsSQSSlA@`3#Pt?JWRdJZIx1d13UkFTe~>CRff$TNc$rpCx0}c3N3q6uH8K#N zjym9AF@h#WhH60yEz!OkczdR~}eWv~n0nL2+P8p6I*4S!iezmlJ<_8RI#mwolaM|E% zUex_j7SMn%_4Pky7wlpSu5UZeJk4a~Jb-NTm`j-u)h+-fnaz2_)I9(zC7i7-fLz*-ENyKG zypNW;uCAJK?rdHq6DpAX5F7o+p7!?{|M?*S_vbcuxVg7CEl|7^>SjSBlku%M-!lYb zs37UccQ3UXiAba)(Z6KYvUPIk2|DP3a%TtB~qVU2S zm)INKIGNNtHnwr6$0>n%dF_w!FvFcmLBUcK&!L+Rchh<^*>{tZlXaOI)ga zk82HhLqraHB?St7y}TlIWG`VkG$iNrVJw}1=z5otk-||feYl_Ktj~_Q98u(EFb@yi zc+YHGhi{6VNN{mdTGs+n5KjaDb!bsDT`OtX)ha*Zu&%X2OuZw#S5$6455IsMqtvnsrP zmNUHwpfjhh{hyPg0OIx><1Ci#j+9M}<4+c_S}Sc#N=gDi=T0-uK`RnyhQ)HUB#x)* zIqPzs#k}NIt}|vf3b7*<-F^&*rf?BT9gvNVj=$fW)OSn0m7K4yb5KIl1e$wMUFKYy!- zH8p8`SCb*q@@#%oS~~ZK;L3?lZj2wD!{O9>9l&ts2FeG{&;aA{e{i{ORvChOSks!F zyog5U!lP95;?vTofKAdg8%m>V{OVQD-Ceu>vo9XDEf*ns@@1)%Mntq%eCZ=N96u!S z)L?MDtEcQ@Zl0d$1JVBDpfy-b-}(T(?al7*!NCdt<$z#*o3_1f(>WS4^S+=V=SzW^ z^B_4f7D7&T_{$vE`&c{5-A^*#c-+Z4Yo|_eBuEG)t%rPG8nOu;RW zbEo)KCp9TzOQcR_B-jkwhb5rb3V@vZi0~$dH(2m3t+waOMDA^-$ z{JN-Kzm;egfN%lmBTPq#Dy zXtWp}CvZS!GEAng^3=LSZKa1}{PKo zl2N`x4I{9re?Yt>E*eXOdy3;#-Vk0`E1Uf5MX$;r7by-#uCltA8nFmkBC2 zP9WcuWl8Xv=Rf{_Z;DI#zQ~WUpDe(saULeu(di@OHQ0rupK54min%^NEHbKWj%kN$ z*yR}N8u~ErnFDr=L|~)(`Tg$pRYU@2)xUo|fqGVAEcgH(h@#Y0G|9PlvRak8HCK^I zwg3%&#zwiVj}wH+RtXAD9Q`FZR_6hOOOr)o(kQ64htQJ>O~!|B1Giu89^PI9>M{^e zISb|$6z^~X6J$YRj zbM)pFSz;}L4Y+!VVF%iMyGq~?63-K-P9T%)?;pN?V~LZ0lrwJ3kgS8#RI~jp+FX== z9q7LStO3vu$^R@u4-Ve!9~=}JR%BT)e%DXe%47CxzIfBCU#Q_odg!WVl{zVdl^=0N z2F^=I12sLFCc5`0lB_%FgeMKt?dV$~i#`L=sDJGz)^{AUkK>w_N^h>`UIrnbC_b*y z92DJp81jR`KG&S`8y!g$Oj5dkV3vMOOr%AwM4c_fs3g&Q`5OOle>sBrqKey0Da;i| zyKHj!3MXPhdYHzpWwC3$KWXCNj08A4r#q-y{sX`xaex16LAqJeBS$^S6&>x$g-NkR zlasVL2NXEL`sP1yz<3iR%Kpd=d_oSUaO^~#F&CGBaAkG7zCvSzqIDn20)2QAFM80o z#5C#dJoqAME%-exR_D1TF@a0iZH?U7Hb8i`&+qOAtgqL2X?CHOe-QSI2>7+luUf=U zU{V)`JKo%)cA!HaHpvjQ zV(IyYlziC-2k15+2(|~<2tMw5EJc=d5V*5EtDm6qao;kOjGWwLzVheAE3@U!t1B*t z2B~oB@kt(viG>x4$|uqJA1^3Ue_lK(WCaz2Y>HVGVRV}ySbZ@|xB}Fik`va^+WT$u z0hlMVzlc8M9fQ#xA$4N90e2Cz$1@A4=km{P(^(p5XGW%)PqF@@MR=a5;+P6Aq9x~{ zhw(p)h#12I+$WgL>Hu{aKK3B0N11v(SI?%z9*)|VUHyy4f1TI)HE?_r*yd!(#%5;y z0L8AUtzENg{erTa4ShG>L+?F0SbV6arbeG{(JMn|`Qp{%FvXmaGFJzLwdA!Y))Z|H z#XS{5foRGo!AbYyq(1+*_?y^a1DnIF8Y_f?<5RNk<8ksZDr`w(lS=;aduAk%zcOBw zP{J#Jd_NC$A8jRuCg6Ntt+w9Gs%jlDsAABMm=ExE%J1x#!7nnP>QG@Hqv~H{jbDD1-1q4m z3cUXRmN_%;Y-j+fh4E)pecd)uFQ-HUM`PwFUliMg0>`_6zHEoA{^{RHFh^Cy{iPji zFf&Nq0^&b3z)TkPZ`yUTKU)`1-~R|~&wa9gbY$u1I3&r~g4zCi^G3SrDQ!iAEjRvU z`;lE6fYyKlAzwG^@j|s|cb8Kls1s4_X?RxB^c$J=)x#?&aZL7}1W+m!b|548cY_ah zjHKM_JH42&o}Ygc&X{k)I#>#x9<(1mTUYC*q3g_;S!}BfIzCnqjg{Rcxo*S2;8BXg zm8g*S`-;p7s(_^eu$uux<}(o`zqBg8als2;#LCwDP<*UylJCV)z|8O;NDI251HjjD z;PSyKz(au|=5xO2T~kwo1^8(CYvMqkluiSeDZKZ6dC)EZjRKz0>)djpm)rkU{QTd^ z9(#L2J?bWW*1nNFH`M#?bCpk9%ki@>6zKOU;$2-1Ss!3OKi~rZz$%dITp3x9vHMAN z6?s!)wX@6mQEQ(jK9C3R_qSIDjZ|Nb?zM{raX0}^yqH^w;BDsqmZKo0X@{S(tY6^? z2$$51t=dbkmPN1PN4`0El@dZ5jbn91HCecCy$*rtr%d1#_4f95bnyq_N15)4|A5)w z=~o|q?M1LMok{wNqy{W^1BHKJfKXdUJK3g}sqzWn{}-2#sA+3U0E}Zh?Oy$=tlI@Y zuRF@8QbH;5iwWzwsu;6ksmJo4K7lK(PZ$^|;~4SUK_75#gd&+JLMx^boJOEvIoK;0 zGUM}59N&M0eC(Cu8dLS`;dFfH`nDHu)N+4rHHu6Bu=H}>8lecUT~?9W+-83CXmv_Q zPKB}m?N-4^zXY%Zpi=?T|9b{hb;tHl!Zg-wz}?zfw|bPd*z3Jgz`^kucmo`buygf# z&EgIt6<=(+>jK5m=yuCPal}|e3q`V(FE-YJLHBXi#P#;DMx+K5I0b`i>S6?aPX2V% zzr{OyxBA*s?y^}ZhME3<>rGqNe{>b3h-^n(5p|AJPbTyUu;RMrer-qI*j3%I4Obj) zcw0HvjVP8wfKvy6_p7tcc8tiW$AB)OLt-fa2k1{iw*3!bzHm3$qeij__e7wH#+Ah+ zr4L!}A1neMQ*lt5;zmx+q*%o8M%&w3Y%%qH+o2BxSybbozLyS|ojNs`q~r*GkPF6d z9oJecra3${%&79LRj)cp_F^>gX4IRexIm8Qf2-XdBY$$Pt_Y6It$hanE)Oklc=tKB zQ881**h@@8co~a2(t30}^gu@y82I&A$@Hah12yg&pyRC`iJJB= zWYFQmH+awXPn;ffs<1Oemw+>9Y5!fHm1sH{aSsI0dVodDBOrL*(5b68fa8R%MbI&l zgdB_KiFP4y2n;w%?&Eh%l4sfvlZD4CXHG-d61dWKjQKog9DeFFe)&>Tvi*1((~MG16liCJ zEaDXiLg0bR58uHz^(#H4V~Y*IMQ@;Er+*2;6vTz9c@ip7t<)iTHYd%Sk<&;-pJcI)mpe-l6C2G;dgmfk2x`OvQlema- zR_pz6UAI+Vs~-o(g5Txj%>TuX@G`l}_GmLnsEYw_ge{wv5LcRAt~Urp3AW$Di|=Cx zlrqZ(m%Xs#6u47tP{#KZw;=G09&kS;JCbkZmKgr;fXG+x`*sTOh)a~Ok}AKY9=PWP zz}j5&y>33~MT@ACeWMt&WH#?GI zpt18jtIRHg*8*rdTnm@q1VI_;FZTbVsqB!m`(L0JT*MS~>fHX2_VcxuBgDW#@;VKJZ| zJ6VhtfU3OD=bB2pzPge#dOR_0m?g7dH|_v~<%Z+3j25${u1*$rOjc)ah;Z8wDr9(^ zWW`HFx%-|lyuoDW&#Wn^6KNBMkH3vjU=4@ec@?1d*>Dh^+?!)a_OpT#46ql}20=r> zv7vkMPCg`P&EgEl*!+n`p!{FhJR-~-mSF6tfK@0IsekZB*318%da^?2KgchY`00UZ z*C`hwE6W(5Y}{lnb+csJ*Vc+n(Y0SInwvKWrA}YY%H#`LU{`;sd7d{iVsKxOHQY_? z8gv3kIEw!8a>Kn!x=;l=@mw^JP|&`O?0C~qZ)$01`*`>7FdLY%v1s5?3U2x$v5P77 zg7aeHI}ybO#fF@RCXbT)P%5}PIJFTtC&YJqD(5rExc+kFZ-m-Ey!((1spQ10ft$yr zMA@ZdH4!=bxzf(oEmDJxbnhCtOfNcvPHq9a>3(Q06!O2OG$$t#5KxB@*M~mB!Jh98 z%J2k=*2G`y_U~L#5C|}%`mUD)szdg_?PX`95*a23potjtq8n0;`@b4?NkPv?3T|Ul zQ>UEF9?Jorswxfsj!fH7J_Mo!*c|FyidwMSihrHXh<|lL*<r?HFPixT#N zw<5*_w)jPE1SDGV8kv7iECtcKySKAs{9+a?!_g%DIYYdM%*aqES-IGIM5QQ|Spkep zd2T45`Ut1yzmGZc;eD8PZ!$tUZnE;HBiF-{oB$;v7D`-Jr>T3fs-Gt43BwSPcz+un zGNU&VUKY-QwgSX9HX!n)KPK!&{~JecYy=~sxT4J1^jgoMA46Y`YutFTLE_vnT^_AijYvCF3%DGm{^_9PS zRYSls!Gcv{!K!;k3M&8J70Yp0^5mVaAECk~h|v*#BVe|nw4)^JrfnB!ixY>5)?@hUr=&f-kLPQbGO z`i@i;t)iyu?(WDW!RV!5d^?j3ulKKNT^)==UU5sMJ(A_+v~q{|o9iQ8)ptv*6-`@wy|Mz0M(%>LB6cFmq-er<0%!2{ zr;3G!q6NB;3FP?)G5Wv9;hLST`8naN8U|iXvN1i@YPiDav~XxKNj$AJ@P>oSyE|Vk zyGhRsh6iJZTMc8pN9 zpdq_S5sr74?7or%GF&~SI#HWS1!ddNTyGwPu02t*Xs3()z#JaaAy|JPGi!u^=bI9c zK?{n%SxS7fmx)w2_;WA#UakwCtW+jBqwK326<(+4%(lTR-@J$Z)*QO~3}0r;hVC>~ zFA}MTn2edU-@2nr#YmnW-pfhYjU=I?*qlCHgA8qJ!&&Qa$`sh#DIZH#O*CZ9eQ~kEe=aMJT2<@ z83*v12DesdSQw5M7>cFCQE09%pmJ}`wZ$8iKKk3yH*vCGv&&4#{F9P^fFQL|XG1Rt zvtI!o-OS8Pr2+XbI0{cMTe&!~b0Co4o|QR8NDB8v=D0g=i2fKv1Hz5(4k=U6-tEQb zq0BooXv#1R-drOWv{_s?mLg6@C8B}yv#{!erpsAGljkxP+TxTa2-IEJ|J7YzEVr+X z4Zf7|a@07McXBnU8wkNi40Y^q=oI5YcD~*1ui;CqdWt6u>1$2d0eeJ^GjaZAghbe( zHO`gdbY%G%Nre-f_^C^4(@uD=0!2ovKpf&6^!XqQ*4>SNqYqx%3Q;RxI&jI4@$^e$ z=NR7|HTo;6>8)i~a2jLO{0B^hbhBmqzH7UW?>zq)-pXVd=z;?b3zCJs5A}1}CHFfJ zL*N|?()iXA8!1P)ic$QpX)Q#gzl!_~*532P1PNY)v<&kuK(6!vp(Z8gB#=Do&Sin3uBDT0xI88*L9f~w>SQUaq6^f=Jm&Z*V z-O|2E_#RQ}w)uvZmXZ`WkSdA(6jd#zw6wFkbG!wDAD%c!eFGIp|6Aws+-h0_9WHlS zLM1pblmpKbG;9H?k%o;+*a6`w<@wd*NpPqt>(58JD7W9RCw8@wMLL?!&5$nI1@*62 zYnOF=>GkZT3)EAGS5qIqlSS_8j{!q=hB7y~HcdD}T_uKj-d?Q4eyq=ajN9H2ZaI{| zie(Ksmg)F}Ngm=6zMT$FJlkCxx<*-?$%Dwwyc#ez%u{Xd?5GQ4=y9r*3ENobt;=DA z3pq#}q~%9RNa-gMnhbv##)VzG?1jIlEDzHZc!*#Kby!7hZD`$`-yM4TbwW)Jy>3$3 z4;0jN>0P?*!pY{vl=z)kSxom94mKze8um15mDSBL<(n>LWuMXefrJi)*tg+dRh*nZ zWLqlq1vpy%+ka8;V62FJJ0ryN*EnuJ&axYa|fP2%yfr_^1&i=$3{bjK#Sgi*HhXH$mm@mS^QP#+V5WqdU*Du|WWwbA=>CNj&4T-`k6o&(4 z1xVaCgM?Mg)aL2{SN(!P=lB|I8Dc-a4a%j5X>h2X+lnG_gj&2@Pf>ON@q4;id4>0d z-M2+e`3%>^1PAY#>lZ)L=T0FtXYE(_#M5pL_Mf)X)Ti7ed(%0#D?tVlPD@=i=QtHz zDJM}Y1cr4VG=JV|e$RA5ZBklG`794PYC`*gQTS^gaNqg@J_Gjsq9Wg;gW~jBYfXP( z`#Bk}YmJch_ot?4m{I2`oW{5>;C_)vpt}}hb7(oWbo5Btza27@B7NP}OZ?q%;AbZ+ZQ67ryqvEYG0Tdb~I2T0l zRIWE!n0u@QOSWnu7ateJg7OLzs!c6$*IXM-zmy?4{|97oB%PEk%cdyR3K|<(`6^%mgr1`6raM^Ne z!F%ENeUCP1K@0%$)Fl}@zF+>%P7&yQ(ek|9(I8aQq#=X&>;h;3oL z75_EmO$jo5)fKe+VBvny-kieZEeh44WP}+vpY+4^@F$bJj%hx?xeNx1J2&R|33>@y zca&JD;5R@)3j@x-Tge`iZWl9u?jbC%pS);6Qh=%zJgshxI4^_2YASyLWK}b~dAd59aj63@~^umH?z_$Nfr=?*3pH}0QAxe{S&JQ0l^MdTGrF>~sZ7k@};_|^7(4eoY07vISZ%XOb z{CTyPFckOMCzh%395NIFdxYf6*J3n4K;)kG%{ura`e@{Cte|YS4@`-%+MaVZ2e-~r4}&0UEfz4U>Gw>oVvBdI8ZTn6vqVueE`q=fUU zf%JvN26DdLKt|~h^b$MslfHUfxws=c=wwP}H z6-bQoE>7E{;pHae&&wB0*Qx5A(bosp(mLkH-aDO+plv%B-MmkS`_-@{Ms|y=+UVU3 zi`^q{EO4Fyy27>jn1A-wI@ze>BR#mV5LxHpW4J9gQ{h2(!{o58uI|%;xyT6w{IO~o z7(F};mn?C*vLzje+9#E;a--Idb}PY@LX34icn@!3{b)8fv65OcFZ9D@Irg^S~z@*XVPabs6_z4Wws|7gnC!qn4G z-lqSZqn;88%Ly3VEH86_3tfnToaFMqgeCZuYfQYCyCxH}Wd}i$>-!5%yxaE)#OY#h zF3^P}T{(AH+^Qeo;IE z1ppNi=&!9nDywvQ`1PYQ3i0ER?Rl(nA-6=&f#EczLW3b7*a|;In&>DhE7h;=j-gkZ z92i_Pn6k&OHnPu04z5qAuQ%3P8UC|%wdzVc)e8M#lgo(V)<_h`q7dvx%LvfF;b0cl zsBo+ay#Zov2QED|EVbGH2vvnk%X5;_+N;3|DC?V>y%HB3(pclH0dMy|x57q_`4?$n zJ;qPzb^g?90W%wBE*)A8Sb-hmH zcOc1dT1`zp+z?GpehDUEoRkpI_d5cp5$E z7R|D3RW$N+>+pQN7|Njy>6XmRP`sn?9f&ft;N9E_oZJV+^M516f z4Acp{zrn$9_x657bI|~racQ3|KsKiG*z=QqeHE~|U4=rYzzFWfYqry<0aJn+Qy>Ub zZbB4UaKjVqMbm)8QMuUAqlz42c21N+`v-vwv4Z9df6Aqdv_vY|y+`7|r9P3{KiTu8 zn7K!;R+>5Z>0nI_Lp`zoxVnq_DCz@RYa*G!Onp=}e|N=A=C?)!S8DMjZnzCx4sPXF z9C18*j(@bZ0m5MIq*P+Kv?JGY(I7%%K0N5=*!{|i;+xb{ zD)N|knTnWh-=O-=EGcrNY>Y#3jYuUQ(*UgH5I3dUQvyRS7i&hI$Z@G zMIG(?q{_Sk0@mP(EjQ|W_p+5V`&tFo{#b}a{OFY|Q2!(eY%uM|fuoLM;1U9HVcTW+ z`%Ii^eqGB5w5J<0%g8xl$f~<&I+U3)8&qgiD8C%AwxFxT56aX5rzW8R~ zt_^q!ub0~nx7jEky}URm5dVAVLzwF$iNFdfz9d;J`de5Jr#)P9ZF!gua zB;UaDmt^5TOx@Fq|6VptQd%Za0HiQTw-5m4$$SP|lotE5Cq7kV3P(QYzqH#ht=+$6 zirP;_r79cRWC_Z};3x{9xdPP~iW{z&=C3zl|pj^s-%;+?=ppqr7c&_8G5C6tryq7;{6o_Y{15=&H)wBCpwCC^UU5uAS4*X`oDMT22C_@n z!a}a{6jqfWXbf-EDAoLh6%ym|8Rxh181ofL0c^a@Q)9kR;ERJ8ya+~8fRO_bI)UB8 zplA^Rku|_$W`5XIY1_^5ksyL{=wUvh6r@BuNCLi18VlVa!;@R`auH3N-aLNgQ=r9k z8D=5(_o7$+%J`X;fK4({v8q>zAu3x^s&O&;`x_5KggxhX@MIsDKsG3i^ zm4RcAO`D>?f!I-bKGh==NumEd(q8WBLI@PJ#7+CXy~F@t0aEK`Tibr-A?HC!fs@wz z6`|=KK`e-y06h~^6Bhf(k9J(3z=CfH_z@nFaHV?|H*iBLM@GIjy`vA|M1}W|ZRr;q zp=HVO@Hz4&}QYk_g66h$ur$?By&qz zS{lSKfX@<7u9d8%e8!N>_fe=`))fil@(Oa3TJw_P$F5wZjbs5LK3!~NG(2NoZ6OB_ zE#DL!{3ioFDhl|&`Q~agk$MIVf}YOs50XVbTqyd-n>vSKL8o>63}{V|xor+Tl#T~O zWdf_!k`~3B5fB#CHZsEI?H*J^x?kfazZ~JmUOuq4MH0rO2(_sYz zz9x8jn|{t!-?xNI4|-k``{bPj#}+)~lm`araCi-|eXK-W0=p0)3p;72YK!^Q3ggt) ztwv3!bN}ekBaWL(q+PXT+fQG#*rImIU!P)bAG@_*Vz=f4^H2idI%`#oIxlQx2A-G` zmP6tRa)8rGfhP>l(Z=x~ocq8ZN9J-7#u#{(O2292`43n%07fGhFo$2RH+%hZu9tH< z6`YNQ<%T#edm6d#?r2C3ZW3$HKvOVS1pe-K@ns2vGlmexPk=-`=*b@6WJU5{oEU_bg%c@m~OIk zl`51w6tz1@i}u%NML~?W7@gn8%UylSh_Vk9rj>slvysyKIzmt3$G4rcDj1qav+vi; zELJ`P>!bO89IQUaMP5@1RcSYwsGWmo92vh0;6b6zK{gD%_V%W_v2Zt-0q7{^c-i!v z8zl=bHa#&h<>nuV%Xe_xlB9)Wx_eX#r8VkmP=u1TpCARr|>QWZlBA2Y8X zc^=C19HcH^j7UDT-KG8>`t2DGU54OJMT|*Jlp`uCM0n{t6{O>n8m(#6((a7t?I~&u zx%|v00d2_Jlq=R3#eA&6Uo7Dcdkb&koA;}#Q0(uvh2rXH@B2usf(uxQmZR`_PX(9` z*NihT6Mi}c$0 z=015u}m08-@P#wOKwVu@O65R_ttrDl-vcNg{nrXC_xAZ;QYh}CW#)&--9zx)n z!qZZKMF2z4zpGP>%!GO_v2pmh^N))8+h1q#A!AYRDQ^YLO=qhpFs?G%IfwZ>3uq+O zi~!s4^`^k3f4$V{@5uh(s6bvcXc#(#Q{xoL*@N*8=Yg+Rds#EXmP6(4Tb}3 zrfS2UNe=SVT%vmSq$sI002{+<=3>nHc*n(X&UTo|+G(oFw~2!`OD zZS3=*?c=9j)ZIiLU(~I$e~*9$kAL2p1FwvDg{%6zpZc>qqx&Bb*;2&_D<%k%>KB6| znRWklS|qB1;pFO-Xx23C(VOyH@=|+ORc+_G)Ryx%*=zF-xr-go3(PfjoBEf}zn5Qs zY11HTSoaG^7ctLE4RuXiJ_bT37@OIPn-X52*H%_dy~@e6^hx7x7zH=p$l_IJ(@-=%$5Xzdbm#^ zPV>$8sBAO#O_EXDRGS)M3wA7pbChgWicPlnr^1uER>reR?w!=AQ7&eF#A^udc&-u&;! zdKD40@E}34%>w@OxmXnEt(-%UI?YwN+8Ct7#kz6TfeMwZ3i38f=jV^(O#}Gwi@N`y zJ-`MC{DSu;xG!%^{zF4~mwp5Zn95b6;K8lWr!(@pii6VRWSfTmE@L+~PSDqb&=rd5 zNaQhq<^%Kvm(95IHxUe0GneC!Y}eUbV*(&ffWuIjKll{}M-$4eHkYs4_zQj|!lxg@%Z1?Y40e7zuK;gy zz_uSUF$qObIHW1rIJTXdvx#Ziu!^oF&A!w)i+0SsFOZ+rTmA1`Ez zrakwEmF4ijoD2K|HBZYMD0WO@juGD%|BTstN9WQ2iM`i%eX4fwBgyW|IpXYw(Gl zyY~9^@?6ljZ230dnUtRsKfyE!udqfnD97*1#FxYK7TNcOwe#;0*r-RKhll?oSAyi7J|)hRVmAy=C{P&WHFpdT-_GOm2u=qdr_h^=DQJ-S4*~fR5QC4<=wH+6uVUi) z4~jc~F85PZOrIp*GF%DPz?(d6Wb!~@P^#Sr(7PuBB?I}uE&f8#e^})XEg?&aT4(#E zMAVjhw~_#fBr0RP*R=dDkki_4U`~;L^GVCc_v=XvXsv0;BTss+PujYBn1W&ev-f7Y z*zxZl9e5@yYHIM5V4O)BxrJFw`^l?+S2aOPaAZS;r%KC}J7SG9-~Z{1QzKNTXz63n zsptR1N?}WME(Zs(SPJw>yS?nP@vzEg zzTxAp;5d&XjZ~-@%iC#G5(@z#tz&HLk>cj#^)j)#VKi`TmyDIrZlp>UHVf-Bvi(rw zw!nLzt?j=@18f*TI{+tNCu;hD5(<}eIm4Pmz+ZTO{+!l!(RZDFv{coGoVB>#Zrjpa zcd`M(9KI%nHu){xmX}2nF-gzkJv>tUo`<=w2+3tu_B5ohTsskVCQfaV>Y6LBYf&ep zl79paZeRpqU`oGjQft==mMYNC`BFrvc^!jQyIit zx$p)g7ji9jm0h2{^(vZM7s$@GcolS-(t6$~Q2HekXty!iKCtYgS4kBUOl8`f!?N;( zKWvt9p6R;;MjSL16RE#3B*mXg9luOaY*3-e~z3YR0UU* zo4fl0jkma3A#xFH#p#yb4!{Z511=mK){>y^#t+ZW{6f|~xk|?X%R|T5l?$UT%-cIi zdRg7SN&`0y>6(|Bh#pWoapY(L2pB6uc=6bEzW_aeqk4-OGhP+< zZ{uQmdGfBG0C=C9nu=VW#IQtJ==j)uqA;BL}(K#x5=ZaEo8cY(%rp86rS)x z(FN$Qlg^<+$HL7biX->=a^5p*_zQlg#hoV za{Rz`CfoM{^d_NK-9|{B&d@>ls(va+`vd}vBob~Tg3wO4cJFTXXqYArb@P;YCw_Km zb?S5ZSw7g}40V0()Y#bi8dR|&N98_k%6V`7+>zpEGgsoGlix$0X$F z@n-GGUY%o(Cr$#2V91oO%Vagg)Um|4D4_)GvtWGqw8!E#FHP>3TICthy}qn-UOhV> zCm6?bBaCa^myGE;Z`%*PRgI1RMnhgu+)u@Wc-Jy#k|s#!I@x8@-}br``Li2!aSj#E zR5k21{#Y2&Ta@g9S~-b#SBRRs##pKY4hAS>kTk9;dw$Vzvab&o#haiesmu}lxO-3@PEc7FpxfF2E`N&I>=<@gHRPsh>R*44LrS`wI_ zN(A@cWwso=n$A8YdEU`9yR1@&s-9hBoXSIr60wXDPo{Qf3xjHvguCVCae9<7O?eOt z?w|nw(2KgK{F{D^KnJ{uhX8&I!1tsDGPoR3DV9*z{92*D^F!6m!KFLt$w1rcn>Qb0 zdhq^zUiAZZ33s|T6Lg6l+u7H0w#mVJ7(Yq7M*-z{9IJ=)zbH|L+;%11MiC!F?MC#S^%+ulmiHjRuio7`d0(f38_cjR|8FFzr^xDywDEhy)>&)ail2FekgD@Q79tdE zm;!wWuA-ZZg4%29>P)v3>J(64LguRve1MA-&_ZHI`B!Sfe?ESCJs~$D!-$rtT9)rT zf1uMVH^F`9L3-h+kr#XY-M!VWhkG98TX-Vk7>5D>3zeVGUV3;y!y_Y#iK>P7-w@?; z#P4#z*E}fik2$u~&f`1>50WHLGAv9-6U0PiHGbY3Y*vNh_8%8Ti;^mjI(dV4!5#9j z`b>EXq6)vg=fbLObD(t<Z|n+WTTSyh)g@rcFVZ{ApSb`U!^ zx821tH98Eum0{YB7ppX_A!ejvOtmIaA``s*1q*&TEjgfav}0D`OJBWS`_| zv`52c;=me#%R)NlNH&1FOE-W|V+VC?G$!I;9^JVj5{qdB6~lu4TZy=sukk&4PKK2& zRT1NeI|vQ7fy{hrC;K|RLKfHE4M?W?9XAS^dcydWWkfU!On z|Dew8u3~`#=kDF-p!O)I7!QC4v&X%MMze2#fKDAV{?~WGcqhLz3v>OY6j>0G!BYa6Q@vFj1LRHf}}sg|MeY_ z%&-r?ltngMDTBp(*jFSG+&)^}G@OX}gA2-($0=_|Xt3}g`xk)he|RVsZUrfSlq;=k zdw6lNXeTqm50>{4bHVzJGD=@et81lII&&ppJ;D+cSXcX=hYE1aL55=jeM4@^??CSh zA(0R~2|Ll9=6}x<%VORvp~8wVVQp8}uVdQI9$$}41g^EbG?jort`~xKwiOH6UJb`} z8vZDZG#@spf%t|apePmv!xB^@78N6BNliNdv&M(hF1V*UdM?B5d~+lq|CY$k+k@e{JLvv1(8C6Q!P>)!b~ z8-C_k;XFvl{>NZxflaOv_U%f+>tTu9TzBwW_$RdeR zOGR1B+~w{oN)@1F0pl|snf%nT>!YB(n(GVy6%5PvTSK{OOkmdfANJ$7{>?*HZ`a9{ zF!rRz`y$1H-5+m17!w?Z+8J^`(H*HK%ImCJvc4*9JF{r+F5OxO2q_3N6{&mgJJ#4A7Yaa09I4{QbRgrFZ9gdy~003`j#>5Tqca9?tA7^TAu1tDnDGYe*q^O7^t= z)9X?aX|~E(5l_FpdMoNj5j|y9l_l~SVDzR8!UQZD6m>%&+X#wpYpKDiNqcmr;){^G zFC9$Ds-N8_Z)V?Wy;wTEW{~9ak430j>+@`8k$j{mNf!0oCc?8JhpfEa4YOTPI@tW?PLxEJi0P@;*H#LHSdplkXBG;fv~ zv2GgRcS|e3`|q%E${~6>qLO>o4hIjGR& zbIct(;x8|zeDsfS{C%E*|Smh{6Nh&|H4M9To(*@C^C!Lb!)8Y_fn%JF`2El<_0>g{H~ap zqbt+UL~Ug-A}Jm7n0{rNmjO^wJ-tnm*vxopIfsXbY6k;OiI(QoLM;}sWkDL%SOt6X z9rmmqO)Hww8r48yjgIAI6qxkP+~4u8ux-&nQHCUzaH1R)lM)c*!Ae|sEU3wr^nsX$ z#}B{QbqN672Ji#0#EQ^oK%NIy>LIZQWM4#-qCIh|CT#VY1h1=h$|Onl3eUl! zCa@e0giVX1#_1HHIY78GDQ6`Nb%M)3*t|HM`@(l6Nxo4i9{eOL_);>PL*lZeATa^1 zvk&I6FNh9h%=d82Q{dunI`!9FuLjyGfoJU;*SrWA65DnkT!F!mHR3HXo(n>o?%@a| zO^KU~g-VnVzD(>`lZJD;lKLZ?14uRi82tAv1*xskXvx>oaS|1 z=e-VI^CJeQ^Wc@ihdhUe6gr3Z39)_R@G`@u-Cr!OU_uM_CD0b#-_jrd&NyzZ!Y(?6 z$83HsKtczfplM2pSpI>m@kRXgQkxRLfa?SL9V6*r`NN_scB99VaoJ3-h9ycoJ51#E z{~?7xD<%*Vp|G~jKN<3HrD#jYn3DI!Z|aQT0)-1O;{L6m5R;-;;q5hYuafe0eAKJ_ zFXz)jY)67+bignT+Ea-mfOEkA8{E}WbHB;@_Y_?rSO#%ipQ{VyN+@+fqzrb&E84bFa zAtQ8)a8Zm>`ivRQq|6z2M+K5)XdFvR-@i!#@N|7;_+$2j1I~njL}Pr9CJga7lfK6eV;62#t2Q>`3-GWE zNvc zl*pe?to6X!ix^&P!A>(+E}~e$v7MGFp>%&ro1k^5m7?SQt>qj z0vY5AWmcex+zG@~K3a)wq)-CYSmR#y)4!<1Cl_Omc&!hTuX-_~>0hs-mKt4qS63@{ zY~M*vn0R<%(zQ5Kx1}0}Fn(@O(b91?-F@<^XwIUtuGX?Ew*&R%%m4N8rY&A%4ot1tiDB(y`s%ccG@?Yca}32}-$8@*l4=!k3~>w%%58FL_NqCnXWp3~ z+nkte8c9QxxRC5xVYrC5X+InLCGvArCoBryjidqII-Qi-cmw}y7L*$-xaC9^vr)3_ zAxTdy-r|cw;+3H@lAfI0CGgc3%lXA9Gtg8N{VkyTN#!8Bkis%BY6qusT>t8lUpKQ| zzus4J_YVqzApOnk?t2^92i=MAosDU4uBzGw(AIFM!K$dMiIC`+3Bl0L63xMe4EVCq z<=qg{90KCM3g4@>Xo+Z#2?zFq`eN%AnQZOEp1oS>P!1tPvV#TG{91iNXF(h%SIBc$ zSVN)MaA9N?6&LoyRV@W8zMHa5+|2$2yT#H1P=+j#$p@~%IgnP^cD4- zk8R9JzxB8+y;oHHTtCytt8_}At8~`%fVuF@RwO$SQWTQ2ecrYGXzJ+MK+bK2PF;!t zsmvdMvtpj4XChpVy01ckJ*~#6US93hq=7<2tnNw<$g8Y<`SEO??wH9Bt2nLN(zf*UwEzfZY~z5wm>ip_Pgt0Zp}B#p&rX2Wd_}h&I(WR za@B=0oC+QOpmcB2Qz83(x0uK6cy`NOE0QWGBv{r~J})vShBvvN*MEqwN46P;9x?gK zMc1+wy;JiWoJly03-)e23RW(Y$Nm@|`mbyaxAxr|yBV7&@zPqaQ`=6KB)Y){kwlt3 z-Pd)zK*PU8gZBORmNSQCZEL1{(rnh>lKErv^;2bdX*i5rvQ zT`CX(R_OtrzRB~wM`0IsUqj`pkU4%mjX!KF$?2_74kl;@8f(JNAr%R3Clc{(f)X(q zGT-25O4BbQ<^j^37f07YTU1ovgaU?_8wDw-51YJpW^|%=hIm?WYW!=w-ir%?<{Q!D zDw5Nx#g%nLaXqj~FkGgK`&>r=a&7Ojsq-+kSWYfp#Jp#&Ot+LrHtoHxjTJTLRnEez z#)83eY>7uayGj06ebB6pW9!W2G91v_koznkrS+ja-||MiHfSJuxsv@gx;2S6>!BT? zdN6Dh*YNK$H!^KxqMivI{*w>!t9VjncPbV>&-~zne7rwq3>|t1;lzU?q-NwSUruC$ zRSkZhYf?CH218^0nUocqlx+MhC0LHii=t7KICT6LQpa`6DF0r-{n$2Rek#Zpy0AIq=jPPA8k#`$3|bbDXVzg$cI*{)*3gl2uf z$Y1{Y4Wk55F0LqO&pRC9^+Tx+=Kj0aNW0t|1z@TeA;!G60Bcmo2=y(s9H4k84uxvl zj8Hx7(&w5)5g1APTGPAxQx3oARluU$%4oteLt|(-mRTXuP=sZ% zLb*qd_JD9Ey>o*6{5=#j;JcY47+}p9<|f`)AwGpA5f6K-#P#~=(Zv~A!%`=sCk4;dv?7U66*DaID8*E08hCvnS?yqIzfKD)(y0xn!_2((0$8OD(a%?l2QZ%Y-+ zE`%YG%u;U}sJYO#C7)UHw3IKH3HA6>z$zeX2=+*Z`1Ob+Ui6=l^*`y*f__qz5yG)>xMM`h1 zj%kFUL$|{UI?ae})bAXH@FdI|9plV79v5-tNDiktDsmy9e94J90mL0Jm{6(~X`?O? z&BD-6_0V)fk6yhbL~481E4XT9Xd1e@&_(i}AJK~@w*sWzo>aYUQ0qoqc2K4_yAq+A z;n!RN7A~mW3g4_BdrrE#%mWk|-Kq1GV^VI#ur5`*dOKVHS8SUj*Jnc1EVvS@_BI|) z;ZQDzaI+1&vEGNCCQjvI?4seTx1SXI0ydIqEHv1&P_%kz=v^c{_El@~zJXFsvegMu zu_aWhiN@~i6zpEh;K#-6gW{yxDDK|dj2u*A;ZIA+4JEj}&97Isi3u-9eD{aZG7o1n zMzq#EB8yxl&tBS9^HqTb>gI1~m*>_M0^g5{Xexi$YlLqf_=)7?@bu3e#4lypH&%T; z9>1{#rD;KXIG6K~%%lOp`DfT`vme+;i6|IC=(q~H-5O@cW2VV3F+BSJFIMuL4jeob zBKLW}0)Q|O4@|e>C)VPDvMA;#6nr2R{V+ttV(8)e9(&qk zB#PD2rZ`!LtBY{x4o5^}&%J>M0|ixyqSndFaL1LHf!Y#uU|(#+gBY5a_e&nunmGtTG#U3~ZYj<;iL%@pnzUXu^)K3% zyyUmx?7{0_H_s?0{1uRe9#F`@GtM0P7n84<2v%#eXj8D$CNwlQIu?w}3Y5-r6=;Nt zR_2uDKH|yEMIj)p*z7T|C*`{lIQ8X)V$d@&Jm!^*TZF^bum}V^)bmyhaEF1o!255N zxwDR&5UHx9m7;B~i3L0Acgt9SD9#m?P>Ai2C?OXl_naTOnSt2hB~&+4V}<=0bBmt! zpl}xG$F_#yL@(yx6WJz zF7W5VFo_2|R<`#(B8WBU*rKfWx0Q*wiu9Be9QX*oe^gLIayK;I1OJ(A6x2#ds@%f`?=%TT-m~44_FkS;gbUb71vR8uT^F`pTw}l zpP3T4jpPm9iP|H-zb&{AamaE2&cFgBnBM8Qw(n7wfP76XK0sOD6;dZme)g>IYl9&^ zgpeatUuqP4i5(XGX6{6T>_Qrh`2$?QYNFs(2bp?mu5JywlXm8~WrbeR8fwNR(qL6e z?S!a5bkc+T-4{yp(`LU;1E#n7b^eBFd0*RR28*Sw<5j2%$8At*WuM9(KggvtfyLav zvlI{xdE4Flk9d510{Hr9mUaRFi|D2PB<5q$Ez@*7Mwdn_>3gfYcq{Js=HJA=FVP+a zY;3vO3BzIfrDGt_840Kmt?3)a@1QhlcOGgyhdv}z=cozg3{OOQ%H@P>9Uadlw5|DE zeZE;UY}7PH4xTtGVSU0-1$HI!B+-97A?md6%%ANKNyHH^yl#Ck6Fw}OuDKm1G(v4j zjVnm?PY`oICnjV-P|$YRe`~iNOI!I;>E7!VIsZ1<2XG=Z4fb;Tz80}w`J;qFqNAgi z@4wydP7>nU_3({+iBj-yh0pMcyr3?@qq2C2=p~6V;eBTG&xyN?b*4cNK9kV}$ipaP zv@!S+fZDImot#iu?0(mTP5X{ko=_gUc$^-00c!*Tf%B?ER&J;F^?``|zUkN)aHtbo ze7V{EmLz|gbdoxEy??UVw%^7V{_}Fd?bmz6Ek%1^PKSx92U5m@HK-#Pufx=Y*<)F^ z!LNl(^2)zszv=*NLvL?XI)^>=hqaTwx}A=Q)}zomNAVnk1ZVR;w=37!vNA&Yh>tz7 zwb?cp6k#aj@DLNuesrH^w??S4{l{G&iubj76m`*5!lB?5J z(T-c|NyGnZ?5u;LeB*Y%^nysa(v85ByfbI!{PE758D`+0XO`Kg?)&;)*XQ~x{7>>B*b+@`;wQQQZs~R0am=+r z@y5ah`G~c622E5|{MYBO&R4LCZukyixKhaZR^a;FQHeWI-IR7)F77m!1oFAWBTlPc z{I8a;DnE(In4)|9qB&_Dwcq@ja?;Vao&N&bFE+F37*N7xvO7oPQ); zbNl92ey6S6CCw1-3HmE>8M5gsh`sKw_LNb9J!Iwqb>3%Z_l8GCrapJc3kAx90y+jJ zeo@eKj4|X-SorP4TusWc_3OAh+_JuY;52QtBpLF|?)FkFR+E1bxFuSs#LLB}7zs81 z0|gQVgKO+iE#u29Wv!+6xb*0kVN_ONKm|(46@j2OI3&IECf-$?cpy{QxrYw^kx*hi z#&r7mbmj3<$7YaaOS1^H_uWA4mKFy)77p>RWQB^#k4MqJ@W#~eFTxfB|~vqBC|C>W6%nK-xevl%;bzJ^7HC>2K(&SD&x3E%xO zAm`QlTLgk<0a(W1gSqaqbDE&7>jywJTK@N>qnNELB4gw?X(bgu~zWiuT^L)-w? z)8@oCarbtWl$;+GAt=TKqlT!!<84_Ey`@d@?fqnDP-3uSPVmmdo(k=R1l!T%0-0&NGDP7hg4rW30-pS;?H`$J z42$Dkb^#^V9uz)-8Z)n<4Fh$BCMVb6>zGB|WzV#nIc*XB=HZs6E#Xu2Oz`2S_nOIe znhKILc#MnBA3td>4LNR{xdbL5eSYhZ5LRFm2T%Dg^aLD;)|va|Mp?TAy~($k>?#vJ z-+XdplFSGb|Mux=`^&YBr7X})RyDDO>2xA11;!fQM>*fd$4yM?{*Fi*Ix^l=ADvP9 z>)P|pN>wA?2&&BIGFB4|jR}{&zrdU0NAp%Vc)QM{)mD`i0*Oo4jIFmWGI}azmkCeR3~Y#r(9%l`h+2Yhq>thBVtZ`PFLN^T|j@0~SkL%z7V{Ok2-`Cdo-QfPc? zzll^m|A&FX`K4>D^3FH%2M->k=jJ|YrDQLu$~2cQ#+O$}vLn1oUdIs}A01WZ>K|2C zbYs||AdCzExB9dNr0he^w|RB4u8m9lsXrCW2;W!(Mrzdr%Rz&=xkw%@J02^Vl~^wq za&tgnyDnMoY}O;#s3G3qJd?p60@*F~4J`{;nK>i2uq?Xi8oQ-dFzYT!PO0(P=7I4S zE9Gxwmsi&%r1TWAp3Eee3WJH6=Y&bbQ|Y!lJTs5n0}^!vLn^8MFhXqEqh1V@scT=d zL_fXfKHNt~PYDGL&sZ!LgRre2xbLqhBcl~_&(SxDB9(DcCc1eY9pSud6+&s>?-x!mE|iX0RkUJe#ek1f0s*X z{4vc0K)qS{)Uf_Hu-KP;0fo%UweFij5W(x6kIwqCm+=rakcxuBtlRQF^{_DfccNWK zN9MhKeYR*cHRKOjgYox;cWIhCFLYYBvp38=UgzeTvup0-yy>orz46H_`2HPunT>P; z^C=Ltsfah|$z%BDmS?TlN;klV=ID?(bUv!2_-;I}d*lxh&xr32(aw}Ky)WwAqE_$= zTAW_`V{(%Df5J}*CM8mOiRr_JpwbmYU1a2C{yK&d#i?|JM;s8*nQDF9Le)?5(>{>5 zykPVvhO|*VV@8n+^|;^boKM?oU@}Xvri$iIu(kI&@0ub$IzH~+zx<&*C78VVP%-<{ zha16Kr@rF$(t@q!K|>o)7Tz2>t!VM{#jBcNDkjLB{J6`c=_zIoE<+>bArR5~A{42U z0bti8+X}ap7&5(j zDz5J(CrO${uM%pj&8dJ6Yx=IBkz$NT+RvrS>Op~!lC)c4MjqYrFGccL@8; zf@Lhed4!+dSt|Plc*&>>D@K5PAFSF$XzF3`j5^5l^y^%wML|@DZ$?RgH_dG&L$T%Q zvHc-spUZz_p_1y*);0`Qqy0RW=r zM@21)Q^WN3tR$U@_3HFWF_sx6168<%&=c9K97xG&m`UiXcavVezbA* zaP|hQM9I01$Ml9MQS0aA>CQyDIT`nRjx%e|U*q$Fu@qP&AuGqe{dw)~fv*v*`fyLY zm|E20q<&4g0jE^BQ;W@ zC{z?bnX<(u?m-mnU3p;6phJZ3(2J3`DobWeINLL5oapPl{Y#ibOy za!Qn(HiF&A7UQ4hCh=9{)6|m^!$Z5NUh;%aPWnn3YN|laW?q%!!@~^A8!txFSdTa` z+EbIuAM>h|=7P;CQMLjl<#BNlV$uw3dfWClX`Jxh)YsQz8eGZHkk|A1M+(1;kuSH~ z9MCR~IiiPZyKk(sKpHvd#UDLqeGN&SZ=jVx#%q}z1nmdwuUw_AO~URl5rSANaH4yj zAGv`AJtRz3NEh+qLT`pL^3djYU<0be{78OdTds9&ZWR~wuYRGWlNG+m&<6W7M6AMxTviADT&iktgF+4GDCg?ozpRc9gUKuSwS1Z+XTwQu9&LyJZ6ZEZ0%<2HLk z({9Q<6kdORug+(S5nMOj&dApYPvL^}9YW=UXTJqn&B_KOOPG{ifWGq|=5POp+246L;lB zmT-?g3C$E+JB9FeJiLbJ0H6i1djnL>A7OI3EE2uZRIRBym}WcE;jWCq;;H7T(mP9R za@!Ld;rCe~??rW9ap{%#U!K;3ZVc-aI*_uo7Vb=VP{ME9E6(RxJoN2wV?e!y5%O5uA@B^*@b)?#78%PY&-rQ7~M~US6Cz4}AEas}ZfHtsb-bOO&;H zX)>_uN;vjkCj$W7w$6Kl7JTa*QR$=QSmyoH%ETF?=PtE5Cik2S1Zf9zT8g$aBUr;o z-&^|Z{xoZ}HwFyp>%;u_c_OULemyXWzWQ}s3%3>N>l?BxHPDKs6S0Vkn2la&sbKkoZ@-d7 z97+=^D@EFu8a=?2Q*=|J;6=I=TPZP6OVNaTAoCcm(b6K{&zLe6#BjsPd z#9hCII+1wt%U|dtRr%t?+J+{S3V%sAP#N;v%1dw{3%s`oYP!eg&+jEqwie$f@K zz=?>gs6kA;nph%~osi_=IzHGST(4gSYS9>zJ!PI0#Kt`U(!}WR_RQTO zusu1l10tdTV6EPf=;DN&%#!R^;`G2Rwqez>-jzwzSlQI@ym`=7=%_I})^*}vLeAYD zET{uma}s_V-rvm&gOQ;$J%3nhQhcJv)D*|M)w4qi zXVondNpB76wFw@e-NF&1M9LTnxQgQ54J&`Ldq6pYgoX=T1W z2vC@;L$i!{m~~HY3uDTyxm2R9zeTdk!^{-b`OXi%A}^zFtPC)RTr7n4?o8JEOxFG) zcmb|civHA?lM4X?V?KjZD^VCm>_MDg%)VbVY8}-@k0nf6FR%5fB!$Q8e|VH{B)FQE z+L;IOl+9tuOTyFa8Ti@zO#q8v7!o(sj|~GERSUOuk26P$jTvLTn;9+Bqw`5#cpL|^ zK>@Qrnqp*senV&d39gL!sB!Nm63s$bqUk}1h5V>i4Mu-i9qYNv@x9;nd1!70rd-iqsPYtW4I|&z`Q7F&}U3w{cNI$|9AnEJI^_ zaczO&GHJ^4RAGx;p>|&FE|}N%@^{1Tl&qL##(ks4y#CnNYlXJPLpiHv8LaUZtd&*c zs^*0Y3>qo|?7WRP=W6F9dFPZi=-4+TmMSZD zDum69EcSt7F}q7zrz;hemwWPS^cd<#hjy@G<&~g-kX;6ulIC{=iYyF4Nvj@>DjFbm-QMFA3lIFI@n-gT}3)?^J(kU1nZ8o)!XmJ1C zY$aw`NI3iQ8zq6Oo5w=sTVZADSr!jm00?v|fBGh*p#{%@Es_U{{%(Bov`EfLpZ-i9z2}Bd+lWhU9{owqvYUpi^bgFil<|p)wC0|=P zi&1aHEV33?7v<9UMToecsHV1N_u|HYt)nlAHGLR9=?#58tZ7^z`p#9B-cj#`*`;c? z4<(k$j4zz|I947qNz!}sLIgKdcAu}4@@h@wZfr;Up-=7O1y26ti~J{^H+an_j?({B z?jSXro}EkCaOlD@d(|Gn0){$*_xZ!&_g2X&y=3xE^}~| z+H(8$#6D3kMPE-WH&>hysr3vLUK-COZ;Ih*W~Y4h^UmBRP-jLXsAXz$kefb@pai0= z+GXTRb2BNZScW2m9F{LSon)L(l>OqxHZtCs`t2>Q$7e^^kIhnE4XP)f`}p7IpoCZw z4yOsU_c^1FCo?2O+;?2*OtOc`3#$Z8?rFlyS$a4zqE&(BNu@K09|A5udA9jxd>p?o z{%i@qdQOU9pa14TRVK!H!RS{)gmW&t+gB~kRpY=&*%q~9X}Eb`D?X$(H=)3eA;?&R z?@fXdo;A5P-PtY0sAW~7B)q7+i5=^Oeq!O)U3|tDjk^SvY_T7=3!!}Tq6wyvSG)c* zluFeBHcOR2HyJ(2XS=wX+reG20d;3D1}tw{5O;_~4>RbdZ_CtFPBA@aAziyk5yzh@9vA4lbe1AuM+dvXCt`Cyi=yWM;Vjmt5FjC zc)lNcS0t>!v$a#Ha`xf4d%AzjVnJdcgUeRZb0aFkqIUzM>YlG_Jtlli*dT*$KV+7} z4E{@GzsuXc-(=vlv_4d9)ap-g9(WGzK)6uIP$0rYlYg<1ACpA>w%1z2Wfu=9Hda;D zl{Zz%T*T*IoOcJiG;zEl2@}DOqPkd3X)?`H3bYYTxOiBr>nWvHU;~Tp6ot-w6)J~g zt6V2|FsOsrU~>1Hznp8Wj0sivvW!g!rOaVeX80=jNeG&Uvv{wLDCeJg43Z8<7u2-992@r8K!hseFSL0#}3~a3P z-=H1#m~I1sJe&6R*GHcW@Wtq^x1=xBu2u+?`~pHkwktvMdbIEOA~JV9`1m;JiNzj{ z^OY}Ni-uX<2^^L;j{Jr!%I`30gTHAGDP!zzGJ(U)kkH4v-}vf4`fp;(D%6*<*`4HY z>>mFT8FM!gH#v-)RzkQQwR4r>A2M5Ae7U@LZhm2$E*t#jj458&e3j|Lg#)9f=&yA} z+r$GjYYhYnV(N|L{ z*PrKE7{YT~og)_ZC;8n+EhwK+uMIwu?h=D!2D;>#%;qu;$E9jNR^bFk@8fFej zC55zI4iRiS?y(IKOCqz?M!6clXo`P-Idr%mtTc7{ftTWDwy(*rNC6@aP$c^0Bhe3T zA73Bz;rd;(`e#G{ib+qz1?9whPY{M`FqdIYW^7?=LBP*dux6+GAo96+roZD?aXv?h zEB#J~v!tk(IeQCLI>^bbqS%&P5Aoeyou1wv@eP=2ox9zvPS*ML-JP%H^xPDc`Gh1X zHVA(Ci(egn-4nTACt9{Ovn&Fkoe?D6LJ`K~$g`LHIlAYvKZ&4zZvO`KW-?)99JBH| z)u#(a$1B~23nmm(S*L-`7F|IGiFvC@L?)5Bj7;JRXbl8=s>+?)bq4GS?BtwPl%{p) z%NWI-ot^t|iVv#@IEAq6okCPrEN7DG<@9R33~b5z5vR!V!95jlN8vpj@q0 zx^1(U*}-9X_VxpI!A!iD@z$AZ=T{#E=MIwzc*0cl2xlm1eu_L=KEFBf==h}1KU9*D zBjKIO!Y^%c9_A1t1h=wgMm-_q*RXT)5+osS%5|=*dgEl$Q7INER<@$d;XKJ2$n|$0 zUXoeUC;m#2E(lX{kvI<>7Xv_btNg<8+VV)V|F~qLc2Oie!aE;bvi&%lmAQ5 z+@t@Mhb(Sc;eE75Z=iRB!sZq$*ozT>vK=Q$pX!fr+b=9kWHe$aZA2-y91YYdJO9#^ zQs{AIh9&a2QLYtt+&>YV4X((yNkQZ!nDmt+#1h#nTxNAS>~=dwnebyswV{iInq0>f z0?OJ5`{W?@lU%>whPIrA1jSd?$TAtQMCnB=C_V{74h|roK&|1xaus-;)04MM0fJ4jpiWHYd`*~@X*K|v9dI8_lDX{>80h%a!xtCC9P%CSy|1D~QaiUDJ4+~1mg)(`{zuR!k;gz#muI5(vA5)VC z(>o=td)scStzBGgCx;o`gW2X!O>*_b#KkQjDC+@>vRJi(@J8Pq8_+}2XUGHudFxr1 zP-OS-Y!cS+Zn3X$<|ykXWoU4`$)@bjQ7kgwbK`IPEs~k5k{QN}O_7Vrpi*2ti zVK3bB^l8w)pUE5QHV*sC*|C9JM-%fh0gd+M-ObPZQ^kt4py(-NxKT~E4y+4JPE7)T zn;_%=4<>BU6nBG8_*y~*1hx2i9S-hsNcw1JB{AdsV8^p_2W6&*_*?{1r6j9btw5?- zX5&LcjrUUad$O&Z>eReS9{_@PZDQRlyHHqOk+gjpGS&0xIT5(kFuV& z3zX>WY@~Ox3eest{^meI&!MFWhZ@l;j}=GgB>+?z04d6Yl*fVQeLxB=ud0i>h9C)vScBPxgoMOLObXulK%E9K|L3C^;7{W`p+XondDE{8+T97dE3~-*W#W?qWqr?#)D zc5gEKZgiYZW~%Vw)4fm)EaH}`MK^l3fygi3>cfHzkm!KK0fa$YJ;k+2xnUOiz*BU; z{{Ev|@QSH0b|_UedR#$cB8*`wLQsz{*;bbEEK(+c0!w8YRqg`u&qzE`!O>p0D6}_Y0)5 z`b>QlxBbkI-7Pdob~B~0O|p9^Yk-njGYs9+H=`q;}d+Pkf9B-ey$Vcqw; zOV)WBG7~C87J2vQYJ9|out`#%7H5JU3|t6eiN-1a_~H4FrMeUYsn0HzoqLP?FE!{I zF(zjEDHor(;_n-uq4RYi9I!OENYs0S*YR+^{5TYfkJ^j%q#*Au<7p$I-Js2|Tdi*0 zT59u6wclR^H`>sXEf{(E(U}2Fh3+Kz14VXSt+@{~=f#G$zRiG4AQ0Ht7j4nnNTb^R z$=AMrGpV+Bi>}MPnGikR`8WR8fSRlb(l1MAc7poOfe46tNy}lE(tY7hua>FxQK-9OXP9oq$3_}Z-q?|7t%WmblD=YBK`O(sg}PeL__+G*m6GQjU|r|P?<~mgKEH)r{c>u} z`QG|IsF^U!$leH@X$)l#n%~HsZ9RC<8W$NE3`=BHJStCNIquFO@Q3(W?X5i$2wJ_b zbYCu;MIgb(QItNQu~BXbp5Oq@_lo*ukNi%GD1ma&60Ugj=@RI^kHSE?RJAn2^-y^j z84N(^?o%&xzG4{X;AdFZT&9po;bc8W#=V+-_7SrwfITBCd_>PA-W8B!{7`L-6*l%5 zwM9_zbV8@m2!7-;lwnmQ#dP^gx>dhvBiJ9kqYUf=)7NKLI&}ZZn4{u;#l+UxwAJjB z*vQ}7Wiy#K@LT(B6^jYiF@G4koL-2VU@-=Ks;N{MC^r#89Ii@gV56du*LjxofvONc z3L`#`BpvG{SI~Oj$ zDRH}j`<0hWgy6d&0OvC$^dfYYi|rKpU!SmbF9)TN|NNli}R_|kmf4R8bTL)NyOvB=#%1gb~1dTd9dODM-5HWHB5*iAG5K$*Y zGyl$G6cs6lGCSXpV=xlVi&3fBB3wd^`7%pax$z#zi+mb!`OUTRq_Z(()}!Z!$E8DR z?auVccU(lMYJSx|?vi^a>`1OSzPML%(BlGzrXtb`2#$2ad;_D6aFOOsxKiB2={YUqvv+k z&+YHoKC=hEAmXCpQbMBALSnK8Vv_eH?%umAB_Jw#PgK;g!^86bIl#@s?x_Qq)BkS= r(B_ORfCJ$F_YiqP7|U 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 diff --git a/carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/bull_nose_end_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..76b369257146576f1c1063338689be13a86acc88 GIT binary patch literal 62410 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 F{|8#`FmwO_ literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/flat_end_mill.png b/carveracontroller/data/GcodeViewer/tools/flat_end_mill.png index 8f42e331778da993ff959a590738e2a675fe05c3..e6113f8897a9bcd3057bf8992d5d1fe8eac360e4 100644 GIT binary patch literal 17487 zcmZsCXHZk$7i|&NO7HyW3Wz}Hy^DaN z^d^WD6_EDwe>3mfo5{@0{cz9hyJz3C*IIj>cmsV6DhLY%002;FX{s6l06@ZDAb^aR zaQXYv?kC{_a?sIG1pum(c_ayUq|dbU)JT7j(oqXTe|&$z4FIUvYN;xj1bq3~>00Y- z{$l0q>!t45cmEand3nYWq4axc|4F|-@O)QVc}G^C@*PY=-(iRhAs~(l(*_XTK$$M! zyk<%GEHJYftWT3t#b+%2!@P%~!`&rBo?~NzQ`()z7;`W7!)Gy_{t5@rCp+sGrE%5j z_ul-q1T(C>^sl`9YxDBwovVegp00zj|IhF0lKW}>ef;$ZPdz-&`&zA^&_c8?BuPsDq4{ERm3ipa z=>3M5okC|kcTBPKdq?IOx3euY)qxxNM*2l~!L9s6nIB&!Wn!I;owZ#nyhjCFRWt<4 zGL7{Gy_-7p!~5)g68b!sWiuJ5n1z6&u8I4;D(!f|Xt3n-F-nyG!EMl*|KifVX*)+% z83@DvhW({esN@bsuub;mCWm0osv8QBl~1$8Uo8LgZkv)OXGe7=5_`4c5MHp(srC-l z$7*!3;GO72w>E77mkZ8#eh~kkfam)&`qiTNz7%>oiIfNjr&A^SVJ#mx#uoyCmw}j2 zBwkgf@7k+_I*BADDYxGajqbQfLg3WVYR2dO6sLjT775|pCxo-CIP|{A$#{8~LAl*D zv;(dEUdPn3uKLLb>t8<_zI#=Ee{y~{4MGNbUWAdlnAHBUsUN-85}{wc90iL$V}e6; zj#S=CEsJ-Xe)xCz9baKWbg44$@cY|g$ScRz*?GgKRR9Tn!JiLmS&jktf|0d{3odAr zDTG3I3wxj5S-Aa$XvweY%}b8=BOjW;e=;Aj)G1r}+d0iGKBqrW*e|$ z?!}wL6Kk~Rf^&%mn^tE%fW{D|Uov)@M=SXwE0E^9SBpOp5x#Jmhjo`IOug%D$f88z zKza|7+-q1Ezxjp&cg3??q*VRplMzrBSu5lXck1}~(urv7^w(4{HVyA_7IN?3n_hco z8HcNH7M|5-+}z5(lwg)*K5iai+n+yv5EC98^oG!j;{in6G1(188rdR}Ab5yTlDt?U zbbs|h_kSqGJrD`yZWEXnev%Wm5Qn8M+>1b3q+->pc+Gwa;Ot5PYKCaz5IwbW|i?itei{o~Vg~lp7Hn?9>RF;3WH3l#C z2$e6D<5^zA=*DrBKkoMY~(RP%TNtUQ>cNU37G03({aAvC;S6!un?NoU&hUgg|1;h&9@P4;2j3BBaYK<82QaRRwkI|>(5b2bX;u$8^f#NI=NG0IY{43smr$E& zzI|4&NSP*fA_s7(5rArq(X+|n;Ta=Yp=uKo>tEPMLW&8-p8ZKQr^h#?+5T7FiLqJ^ z-4izzYjuwlFLt3|NfXL~yT326_M>gj1lj7|=N1wk37*^(c((S9y2bL@s^9#orxb|;fluE2C!Y|cEke(!Q8lx;T%cw8=2sDziNPcG4&JxV z`VY%3oyg3!IBA=lBL;46tz>pnSI=so1I8AfT=*A!Ix#|K$ama*)~3-Rg6;k0csO=4 zb6Df(-|2I%Pu)SNYGVY%s(rpA5r0#&_U4f4>@cW{wS7$k$fl1iJ^=FulGL1REQ=TAJrkY`q;w186Le#vm* zw{?XgGnJL1ejv?C+Jj2ldu4Ty!ryfu=)sFmpF~N$1I%e8dhahk&1O<=yZacaGR8qd z^Pd;g!WisgGEm6Tm0WW6+a;?I#dz%kgK_-sn z#}}8<7}$G9tT*!5^c~uHwG_BmK-hoMh)^irER~Ist$I60+W#!gf{6e4$Mx{a$~~N2 z=9*mqkV4F7dS$rula%tCDvdDnV+IXl<&N8}(ci-V+lwA>KRokoc7R8hhIPh^iK`Mj z0MX@NW}Ez7{DT5^=_!fE4ZDjDIHzx=kA^~p&Wm)mo(DqXhHmdT^{FT;LtOuom4$hu z-^rPT&zLoRgNW-gSG~0H_wp#}GO`6%dU^af-7O*zVzdZ01EgAekNEFh0^7Liq^?jhA@UnBFG7|vCGTt;SNS$V2#~jh8 zy<|e^*RR!90P{nr}^m7*C#>nRxfK1I_q79i=vtyy9SMkLI3tCIB9hf`lY& zhn16}Vq}RfEF2v%;T=cax;wpf$LxZIMFS;1^Ud(4k`99sczJC9IEp{}Q-&j+fQ~d< zxTFiS2(NIoy*$HN-q%4Xjt09IlJaTx*5d;5bKuFZI+i*-ZqmL6t7bbx^k=bY z&A*({T=EAJC-oJhd{0^6!FWse!V$7CvJH#t(sBqCqeERgr&bi0`F;~Lb`@-p*0+f$ zp5S}GxW@nF7=rsH`!3Hu%|hxKXzYX1h~i&Zm^O_X9$22Eehd^m5Qt!}Q(Yeg9~4R; z?6Y)}{0*PqX8uv6LKO#6^^xcx`2R!l9YzOGwMV~*P2>U+-DEN%vCK8a>;7_z1z~_zYRRf7n{vJdnYH1_UV?%;9W)se^(dnI z*U3E+IAZk_!QX3-96czk6XvbWf=rw9v0E66-!p1!XB4X}MZ0_F+W}RwO(9E*--f&F zc~@HzoV=M|*3SZgI>SDp5ez0>>RUPo|7&pu`UUrkPUok7eY^6NdX<0JtcsCFMoG8~ z(?~zM_i274wR*CbA~-fbqD20lgG?x*w7ffd-psPlF8!})|BB~_xFSgmr2L`cOwCo4 zA;Zkc1>b8dTRU&oh2uYql;daf=|(o}uRft^2t~eY-!k82>0hV4lvI3vpB%9eMT~M_ znr3`KBeDy;=ODtZ41yCH`iI~|db@;*IN>lQb8Q~i!VqvkK)OSVF+2Nr{_KM9U%wc7 zRt*%Bk7&8jt?lAyOX z3AhhN#lBFjpQUvW&cK_am7p8{))(2fOQX(+>i*99qlb}LijT2;t5R4o#^?xY_IGsL z@9Pv4Md|@W`b*aSM{&VTviFlHQD7((mV^$c&hCYfn~bxpI5VH4DNJ)Q4i+eu$23+Tc5--pm76m-Q6NkPj}DZYUtTNTDWxXKh8+m={k$*^tlEYi6TF zu5w3}2?4bH9Y0;^k$w25dbxnmqWFiclDKQ~rP{LRz0T==eWWLLF=K+x?udZM_n9R2 zyE>4?cvuMrFY$?Ne$&NGi)?clocHW>^Gn*~sEycI$p0{QrE$9uyjpuWQ_`K0BfZC! z5-35t5ZLKJ>tAZR_JoYg4+%j_;QUe;s_+kDcGna?B*B@@84Qc{~6 zfjh~-r_})QPUhta>qOvEUBSxN&p+$KGtD3JDW5)MAEGVx`K?v9>!?P*%JaRraL6%O zeNYEOe*3~Pj&*sJg*^9X7xQgm#jnFZLCf6)q?zK$xZqyLG+mNUv3nV=UIEDD{l#ce z9KLQWuZP;pPqG=f{3RBSvkWfCj3By_F{HfJS1Ak>1pi8>`*8TP=f2$Ww%2Dg#jbf} zmgJnU=o4X<0ogn#kB4PwQ^BvBXh?P@NBD<=b{!>YwOxlZjhtt2sM?qc%# zSLu-zj{HG@YQO2{>EF#acTw>7OK%c(zw4$Sg$X(AGx^ z$4nlf((FQggBBsTk??>OyH_}@n53GlGO?{>M8}WnT|Z_GJGt!iFooOW+s=i=V@1MR z=dp+V^H&oNxan6qh5i3nDZ|H)CEQO$1!ZC{BpZpJ$50FM3FLGWQ+oME=HyTLBxTw; zZD{OJ1g)$)9o?H=NJ?K;NCI1~5|%Wa%Hj*=yk0$Z4~pNV3}izaOp&I*f=U4bqvZ zYiBo;T%ReqIUc_33AqJ@sh7To98KkPOcX3qHK5WorJiuIsQ|ft`6NPz=JGjTQL!}$ zDp|*=WE8fK@*%)_3VoTpk+G+7wJoo+C+*bnT(Fj>=+?K^wu}4E0}QJE1L4gto5h}F zQ`A^El8U&qDL^SL)?|U;2Pc9fCxRsI24o>toLcK0AGJuL^0%YLsZOql$}aAnylMq9 z6H!a(&@k$T`dnAtHf~E74szVm1hjO2#L2(mWd>$&4zOwTl4J{Fjf10`Ztpt27L~}t z;-YXkDjNr8y-CW7T+VtB>IIq3gvDSgydnam>S zV~-w)a<0WiDts`V;_0+mF4mrplPFJhvn96=Ry`Ph*xWjF7R1J``t(1*^mo@=!(UVz zAhW$VpB3Er$_@tH4}jO&Z*69?->`m+?Gabch*Bvv?Q3Oe1o9n{K_FjrR|P9lVQEEQ ze?Bo!x%q1&)<>i{LBE=P@ab~qZV;=4+;Y$5g}KjW{#LxuJ*S5}eX-BeFk!!rrGe0C zeup#?6B)I$cpbdBonk*mf+2c~i5whGtuK1-Mf>1eljQrdcn)8YOK&+jW_j2i^<2_1 z`#v6hf8t}n?*uC8vcr{3O8m=U4s4DVOgV*iO*rh45ILV=ZFU3@NTHjqqsiPjZVhu6 zKgTVIJ~{hyd`qc0A%b1kx;%(IJo|9>4)|{Spd>kY!IQ3aqJ!yI`L-D(j_AOGY|Rle zCZ1xua0X419`Q|5ktJm|Z~}9AT!Rw^f*JxOvL{Y`d-HAod0SXjI|yG7{X1xDQlG>9 z_?27KX8xLSfNxGtgokh8NR)T9%~r=VY?K5HE+OUnBlhu1>YD~5lToJW$Kg<&0);$m z(!)n^bmVTD+|bPhA$cJ>Kj{HCz|`-b#r`Z134$M-f?+@(W?48o_i>&N_h4J!=>fEG zOQCffhcnmWxE)e*ra;NHU^G>U-Ax;nUNfUo9A@(WnYAp`cz2&T76QcQ3vM`VM#;TZ zuZSrmc`7;i`0UdK2VKP{sX_~=;M$dCh=h>@CA;(3G~jPR5e8ST~9K!5TpoGUfn9H@z|F=%kkbjEP94++(Bl+=QH?HL;B^6ra{ke74 zjNOPPMfI9Ob#OOxrpf0 zPJuZo5sCaH@L$CGn4#`82u|*HC8~o&Z0On_@n-1d!8t>3y!VNe7@xWN;w(gf6!BMs`^gwdHuP|%$3PTT2zG8 zI3#bVkhwxI{u_Ju6e*HYWScBX*QUsoZd5q9g@)|k&~%S?ln*ojQ#v1@-Tf?vpIYrx z%42D_JfoU+(3Q^TjmeDdia|?3@&}_HZ#P_~VKKK6JMF4uyt*X~sz}Pb9BGq^uW{>& z;r5BZ#POnNi_dqHw`N_;X7ySO6y+IEnlnW&jQqgoBzMbC#ah|@;Q3AwNeCTvRTXK` zosN$}ksDWg6+ejFrx8WTt#Au@(uV~inw7saFudx@A#6C1hGSBYf76OGP)=~vgrR!p~#K4-HgE6Xsr zrWvmaerJoxaSlyYfaFy02`*Ru_>=0Alo?78Rv|{7Qmd%b{w7Sje3k>Tt}JhYifppW z<|X9lXe%0X{p{o!0W=w26iiCH*5bc#TzX=Y#}aMWS_3=kJ7uGiaR z9b33P#isCR_l7dNTs~@_D4g%3RVZwIpF$hF>`R`Br%Hj6V-Mf8X|1}HKp{5bWcM~m{<$O6;*htA2kq3U&<7xBne zH@nQ+`@xt@{YIN0; zwh^6_RqmmwA}D|9nNEu-|}hIJ~(68EOqydz4KmEW|Et$S{d{(o-%2ZG@{yVktS)k z!LW(+srB5e+P$F|j@=H8^i!Wcxj>ot-$XR$qIVmS<$T6oH3uumB1HN>>vic6-xoO> zyukLt&^Ij+nKMe^+;IA%w~-EdnvW}gjyJFf1GIJ;|Bh%f>e4!p&y*s+uXD5XVK!!` zw~#{`nasfg2z%jWdsdACkGy=oV$Q6`4U*F0=lrll?y7vnRHhI72gQXyM(M2=UQ@74 z9Jr%P49AT%g9Nrgw-i8Qph?)INi??f@w8e)@hf%!5}jTz0l}kh{E^VvHV(cJ%#^Dj8vaEX)EY5Hf%Eca^yvSLZ z&At!$Nl7NNctK|I@jvIkXQ+yj0I?H4yFl`~fp6w>j|`XyI}|AN@exg1N>7s}k@=m( ze}$r%X~1p3J3UIZ(vcp_9PQq%0j9x5l?q7+ zDjzn9(t{}s7708%$M-Ihns^SFrS&l~`xwHe413JCItK1y_Rdi;;Ciq9WLlz7C-Srf zSvp!j;2sOh}Ez!{&*QmbW@n`7NqK=M}cpCVZNE%?QWT}1teBJJ~3i?0;p z>~>^SG;O>5EgG2x?{QByDRPr>6`UXQubADIE&c!n97(UnUlJw-2g&zIVlQXsjci**>Meei2e zk;n*5?lZ4Y?qlW1%CteoY&Y%N<^^OgUv@!nvlj7lbK!lW8J9O?T|b4(-{Py%r5 zeL2Kn%;d;FGr`@xRNgO|3QngxR+1Ni?Q7XOB-LPy?(y2kMyRDwutf=k=`iE8-*{o% zT7-?2dEy08Twgz?s{3U!=_Dv+c)Wh)v_cvX;7i9w7Y)n4q{=-a3%Q8q&!L;@ih7KRR)+^9 z#T%f?MwybYz$^$Itpy(Ot=9fve`drHOcc4npwlMvGLtY36a0^k zQC9gyn~LHvI?d#!C4eZrC7f$sp45G|Y=WFck+a7pH8V+}9iVY-0@c$lNXqd+(b8sN z6PE|3*E8|TR3V6K`A(nUm-P#qp=DVRoG`uMe`FRFfV^?Dy?llYQ=4uCc+a>)?)MBz zT!ojdS7B}LNd`Majgy=sxSvO{qB~$b#hSwQ%gyF-9vLuy~uI zYcjV0$zvBfSaDn~=OE0O`ehSR*2&3zHD^6%^LOoP$ouv_hH&Wc(-Hbo%7&KQ6MOa) z1+N(;i78h}d&!Qh&lO-1f_bkDRF9ZPa=VAD6ZIC zoC4>se;(eiskscne~pOY?oxOOk%b75s1Khm1PCD!n>|Dh{G*@zA;ZE^K~zoi}UBC?xN{RqAuQ{2(( zzyw<0ZHc5>4+WWBrw9%{%= z(vJptzv#{9jDRu2em?M9`rAI}q4g6bsgC9EGxCl!y~3Rvc{sSzbw&ldzEZoY7g}wDXP8ujk zFi$jl4>}92)X?N@TaRFctDucl?Ig%b|9U&_2-`r zl8#$`GlSu?@*k9=c&y(9?|c9EgmhsRgj)A~Bh2;uG}+b}&M{g~@16D<3HqW;lG~)4 zZ4k$ytOXx(F?zoUyF1;0x4$|_qgYm?JBADF7D-TQ#*;1DvuULHf0uo+=Ku5&>2D)r zib6>v+Zr(~*6XUXl>xNH4hwUh4-3FTde1DOxNQBG=F;P2c3Q5O2>!$<7f{^^5EyeB zoRV)~0hC``mXuS~|1&Y>sPnRug@&Inrgh}4`WcvCQ2uN?I5owej5HX}pTMvYLFesm zx~*^cB^laBZEY9}7~m!h7&-jH5kur}(&FLIfwmL&QvnQ3Wl12h}&;-IafTuNpYP)ZL5i*^S;h(uLNj~Z+^+r*~iQIi; z{DLx>I_7UQ7b#jsHPXYzIUa|5a&8jMGYO{8gwAY9a*h63F%!Ge_;z*{#KmqwNH|@z zr72sqgT`bS*W;^u(#Or9V8OfDFFaLVzxWem9-Uk!hneEFw%HKXTXlWgrzIRetu*%W z_>P&TX6x_MRGS;QclU4KnPMNj_U8NI>+-^>BxLHBr1>=3sfIpY{F3?cIoy%w0ML8D zwNbX6>xlolJUG20e_u;cnNCMBhNoC7+!0U8YmseDSr8UnGby=jZ7))n2N3ga+VEfR_i&Ia;V}$4Gm6-U=Wniw72j{ru#2tv{Uhuf~X(tSYW)c8Jg)fR{y>`5=`aqp<)h~PahqTT1 zB76MXk4{@kxJ(T%s##65A6*u2uIro0Pj;d6s69*{(|d=U!;e039nsy3zSnYoog#YA zo~{8;y3GAIdb4r0qW<2W*Y8lJVMc@sonEG15e~|WaE2T@h>yc`PR!~2^2qTT*Wkbb zcy$>$$}Ypw1*CseARfuxlSahMX2i_+AGyUEjCs&_>ac7pChs`he-u&v(&o1clwGLka0Nm6R$mgWEPu^3(-`!pq6 zlP)ewp%fx5p_;#zjo}or14H_#EuADS$7zp%^|bafgS0Pp9Zmh3eg%02du;U*ii1ce zSp*PO^V7V!uHa0faKZ{qY3-zrE!q-WN_&>(#hA?0K!Qv;-H|~GawYH3{J=@(^EZvV zSxA=4khbJ-4#C2Dg8w+|Z*|&4kY+s+#@n*!c1pBmeN`L}vs8Ys^_WfR6v33K2C7NZVoh z#H6Ma3)!i4Vx5DC&&h!)abq9jdz*&2lwrZPiWxb&e9hYx9kI8EHex-Ib*naESW>#L zyA!I9=%l8YxTx~z$NR`LdGK26q8c;Ku@Shw;8*05FgSDQvrqhi^H)`d%iHwID2WP} zqTy&sX*)_CTHRp#)2anGS@EV!Lef@d|9Za=oz3!LAd3@PU+`7UBn>G)up2Raw%9}H z&|*y%O8p2KYqLG&`Ns@ReTkC7M`*ees|P4oSLlX`n?#7G^NV`(wVu+?kR$cwkYXS1 z={&)5!+xVR)`Y1uueqVZ-6pM+EnZvaJl)wI$Pl&LZ*nJWZ~>03Yl;QZN6SFW!~ikP zBx1qpJTBcJ(6Un0#nS z-RA~is};o5(@r0Is2tz~n)FVMuQ~q8p9-z7Q4usH`rzP?tbE)j3!nmCwK}= zU+!`{AY|C2mv9#fQo(Pft&3v(dttk+t#~cEJ;;4%#K;D(=@!68Sm$@ztER?0ih`>E z_xgqPn=--x#e6AuN9)^*egrmw4ao@`ETmLZilsWl73XXVJ}UKHP{{`NjTDFfhSr^O z3(}_Wm_C+p!00M4>a1azR6cnI|MbJ59E6zae{h59CS&7Pu!V9D}){zF?!kim6-gGKBU^9R=xU&^E0 zY5<~p_Z?`2&=hDTalj*#Vg$ch^Qf8;Tts049{H3kGj)r{hb|<$kY|S~%Vi^nF$H&G zt%GzGy@_P?khUh9w9@$-bnnodurH!NN!&Y}9$$ap#rrI^NEN_kZR1Fxk})Mdgav5C z@C*!d1|$v`*v)JbJa-_pM~bN`>}_bdD&0={y(6u1fS!{49iPLe9x6R~LRd%Fh>hfO z9y?+N?1{gw-z6LbsTrNl?Y%jUsZ+2~QvEJmkrdH^g;DAB z5n@LJ+W-|rbw*9|b2Spe3{td7f{uOqk;F(8R81BF%3CLk`8X2G1Y%!{;`ODF53|cq z-vj@nMtYstJR$sTQOD_1{$e{4 zkxd+MBF%8-*D*gcFcs3?oTlUroNEE1 zM^8tYamU{4t;@^cuaz9!Pn@?49CEXlO2gLyr|AzU`%91-niu>hN$g3bks&BMvcW&$ zyx;fl5R9u;AgDmIJ)LrSG`}o&v69kjwi~LuKI13MkJiuJj(-cpm*%1wcMhq=n)M?b z->NMgS!8M_?myvs*uop9!vMdA^eQ83NH`f(ypBNM48qAK?DxWb%A|GDxP zW-;IiqD;*zhuRM{Az%2{=xsO!Hs^HXb2X|jGSJT0{Iu;~R5n}ERCW<1Xx{Ayal99D z&knAg*4QfTc5Xs+{)juiFCQ+w98mil2dnd2kQT*CqR`1Zya>eiQ3O{L zhFQDD(7+O0xkZ1JB?Ma_GfaxFV8_`7ymfPNcv~pA#l}&tmPD)lzYl*>@U>)6mlOTizz#q>zRDGDpwoFB&fOTVJ_F~si(V)FsG~IQh~TV| z42DXI^7<&e+V}oA07m6KoviB8n*7=joQ59)3YU1x z@^zr2%Z41fLI@#)J3pIh%Rs+dJgXP&<7c8;#6ONmf~nqeG7PIL#qp#S*Vk`4M+M`- zzA*k=UV+Ez>gunC3yfm26%|JZ>mExzVBRn_SToRH$doK682^f%7lUk1{@iKbw*sIZ z_+rE1zV6^}zx}$6(Gm**uNAmFwr7wGn%?u9!290cQ}RPn$#-Yz4cgLL3=-7lP~=ER z$9;txt^{u1FIrRvjeTzJ#@;x;-XllB(iYaWXyMf6H3H*K*kX$OyX!_xju-Nfp zh3$pSTE}R=$`*PeM3!J46P#c8=_m_9Zy_^biV3ItZHtfnsDa&>LkscLsos;s8KpcX ze5r*l&757=QQ`?KN!|%%=_nS5L^zwY8a;HffpUs7lx%}p&G@OT{QE3J?4V#7_fjSB zmw|zI439(Cyrx?mog~u$Nqu8HH;f&q(aTGg7@*mMr4HGSt0}lh=z*!JN&i&A17%Xc z{Jdqgl9t941ltvv0mDwI>dQB&1bWRIkM9~iwf(-&qE^7zuABv1Z@^Vc)m|0coRzbo1l8j zH%`Jo%OV7If{9x&db*-9UkXNjFI6b(y<>3^k-DS50UC)+V+{V9@x&Xi>1LoGmHfivz!kVW+;7_yUR*gc&pXD5Wr90+qFjcAUZUsa6{wM`R)(}8R z4g*;wA2;s?WP!KDRyJZ|zKj+&y(VoyP(_32hlfXUpHL_As5$0;k+n7kSC)ZYz6LAS z87!C4sOFdUC{_n-<-|gNRfP@n;l+pK6BL&*yG?qcbNEqIA|6E1_SRtm)SpAvY>i{!tUz=AYGG+l|*G@li~YEoKsAu?_ODz zBmy09Nsg1$B$z><{Cx02_tFRJ>x=)n@lKG{H7{z3-8@ntC1R!&q!y2^uwVO;DLw!l zWLGEMazXl!(AR;ZjZz-U#}uB8+!hZBJgx}(!vC~WA*@4f z$!97q32-cPhTIo&D;|Qij_b3jt_!cuvSneex+^KU0LYCE)mMdJ1#5(0r7iw3LSm z++&MIj9V5#KIAW8lhgq(9^ZobyBQ8xoe9>7x_AoqQZnk&x_MYa-K=kPL> zfebTR@z4%$o%D&`vW3jTG2XWh%Y&ztC`{}-d00N;6X4}Ym8jxXDQ8<>MPXqHW)dsr z>)aw^(i{-2csjpH@{1OzfzcQJ$sTS62#1c`>&?)$tLcG)6BxL_3tD`zY00Oe&J=2s z5A`MR_HpFiwHbCI=KP)^9`%fyU1jBvBbS+vbaiqdGc9mIhEDgS^nE)3%A37_PPdT> zh?7BcrTWE0fd*g<8tP>Im^#h!?(s`jWoe00#J1}QJrd0&M;Ryh;oBMG!WjYY*%Cy9 zsrGo&j&vEC)5#HG!hZO5nXhU zbopF7xI|Uj8G9n}y??Js>uyM2b~4d$zB2`6->I*pQW<_O+mA#5>ziZBM;w#ZM&4LQ z)5PWMATpGpq;J)NHG%IYK8x~tD`x8<1O?7f)RA1TZhCMv&kT3j&i+{?-@~#9E9Osy z7f#gQR~D^Hjgh56!N1O8O>kyWn=nx7#F|BR~j+xHir*N3^k*N z$(W#8l+!!>3{O6A=yrz+ecOK*03{fyu53MjnC*0Ozk@IHa~G}Nk)))P=T@^SsQWYU zT}6Hr{k|F);hYh=v_xb8>}E^Id`=l7eSZQ4<|5i-Ho44o;Ny;A zL69J+8#haoVygc0+w8deB23EnabJ$|q;X^U|cdWrGmt z*Q(TnyNUALThff}dU0D)Et`yflE6*QAy*g$3<+liSk9x@40`1_Rv1y_vF8u`QgpXT z1C?E;g#OXW@rtg*-C#aiF9_KQ5&~N(Zk!DYnWiE?$F};w5j$<0|KMB_KnetoVb9!q&cmw*j|a zi=*D{%a_|gCKjU`m9~AD{zC%i>R=`gw2^h!kzAxn(8W4`o*};C zow92nE;W@S!}2{zq#@U|elZieb2Zr0dGjZX`2QMR48^|u-pcpWg=|liT+1IwWmzeX zP#*e4?$2uMPTY6#Y*2~YW`0YztjMvO4oh1r)jr}UVsZD_UXlH+Z*U5j*7>g1&a{0jE@bNB3D_H7!$YKCtu`5hdrU=WirZr}e~BjSo8>eN=tE&Ffh)#kG;v$N0k z@um)_f*nR@g+f|t&IeG&^tsY8aJ%$+SxM{dOlr?H&7D?2N=-AX?b9j7>XE9a7FOK; zVHUs+?JhBaoo)eDubb|US~|Oc^nwaC@(TnR_adaDZ6oA8nGdlO1qb5dPaek`BZ9Rr zOk!7|x`0Z#52UfxpN+b;LDW@~m>t}>Yq@F0IVL-EuOe zYuqqqVj(v@z9dvK&P!Y>3hD5^T{AX`L60OUwKddpBR9;-IP~b7kt6v0>u<){isxg~ z>%8O%Is98#4aVMdl^>zD_G8c#Ea$Dhj=ZL`$4a4QVS0PdVt z-kknITo8I~1V=bQ-!c3BCHMGLDMw;TqLw(civn3ui2LbJe^y_ALB#|}p;zcF#*EcV z@>s348w?S~sadeF)bE3Bb|TJKbl6DeCl%lyBAB}lQ zQ;3sUGn4;Erb07-JzMJWPO{xXF$lMJb=k$_H-v-ne4@~~ZLRGnc7<&y5;eHk?=L7*Wr%~gZ{Yd zU>2B>pW}z%;T?n-HsBH9aL+K;4GP=;1oeUi3H`O!HRUzAN)Mv2 z9myXfjL+mgDrHBw-blS=v4?Ag$3C#pkS};j!HJ=Ywg*&6W zyBBl_rsuE0pWlq^M!Cr-k6ne)ou&hvmD_p$ywc7t5{Ll|BzE3HXHd>Tjk34tZa)mnJ+M7!B=5 zR_$_GgcVGA9l`2>S&>$2R3i-MGh&aUP?HN(3yUP%fe9pqe0rN3(SqAc{AR~#^E=XA z8p)O_1Z=YK=Wl+V(Wtoa8--BGhC0kWZ9b%M6z&MNlD2wCVqW@elNo%^0S^F%>Nk{x zJ0?s?s&oA+2JKjO4Ge2^5p=$d>Pz|NJ$8b_&p4}dMu9O_akkXghjNPkGC+*##X?ab=pUr@? zIOaikO3d=2b4NvS{@KQZXW?bxj)^N3!no8SZ&k@(0;N!!9yu$!_^zYqLBtN)4>?%M zvRlm(nMzCDNWJ^;dNbNfJ5`H{0OuOmss+D+G*rkOMg@Vx);5G$9W+Gjh>N7p?@DsR zqK70<(<0kHATf1M^RCis$Na}BiaA3O3D5IKN6?6kd#DkMjb?M2wl7Ul^CrLuWX`8X ze%`9()>(*)dVM%H2Pgb7smC{^pe&k;E-N*YUi1XQx*5SNKU|Vutb~-utGpBH7R@F4 zI^LjO8EO2r;&z9oQc#g_=BnXMlySIO|9VT0OQbnDP7b1>@?t$lUkd>YN4c)B1!IML0OuyM@40hE!@Msk`yr#+YZqOEUxEaBxK7!Xs@e{mU?9T@vu znZJ|+vrb&lYcLIcKa>7Qy@c;gt-2jwsP`t^kfjV7sp({7dipXK|W{Qfp@&$K4STBB(%7H!WrF*J%&$X$vlosH$gKJAjKSebX*p zo7pgh=|#YV%gg=ePnn~)Ql*7aCbx*GXLIF@+a(+J{1sd8zyH>rlAOQ!V(xQ--rxII z{XWlj|4-M?M?aol#VUT=f@kZk#Au(|oADwO4USnDGV(epEu3ATqPtzd?TU~Tu!|gU z!%18**X)OyrevE_UZ(D4XHmnhJ0h9-rhgaAUbn=2m-*YbPhR~w`tkPv-1Uk7P2*V$ zlE3Z0uNC*d*E_m?!>1p&WV|LV_$aHT3?8~;J-UdJ6i6}+3+`A(V1&}*2&zR@%CSs z+4}?AOaFiSpet)@_h)(dzw;@pBYkqt=AW4@X})y%;+w}}Y9?r2y=1sCk7ezKl~ek8 zj8+=8MJ&JYm51roN(O`dWzW~Hou6^m%Deu8aqZ<|+pR};Me2s#_1Y#_COtPLJx~2k z=9lP~Ip3Z>THn$C@BcsRdtdi&`0{e|xvll9{+YyZmoHK>T-)23vq?gKmaF!hKJmwv zrmxkmx?H=Kyeo6Ii{RegM`;0=~>(1IeuA8#|Rzv*?{Z~&n%)XJbd*dywTV*a$h!Wes=wBXZt_Sy4d<9iwgv9EZETd&)mm%dQtqhR4nM<-iiPD zxwDm@`iq>{2t0j5wZt`|BqgyV)hf9t6-Y4{85o)A8kp-ET80>!SeY1G8JcMu7+4t? z9ACqdh@v4kKP5A*61RqJANSk^YS4h&P?DLOT3nKtTYy{7!zXi@fO;4_UHx3vIVCg! E0GE^3zW@LL literal 963 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D1k^Oi)5S5Q;?~JWCA!|;ejKz&qb7>2|hGusE( zX32f1m7{ND?-0InocZtM8&-zE1gl!&8c~vxSdwa$T$Bo=7>o>z%ybRRbq!5IjEt>} zjjT+}v<(cb3=ACKiYB3G$jwj5OshoGU|?otXavz9Bj$Jss6hj6LrG?CYH>+oZULGe aV-uk95Iwz$$J>B<7(8A5T-G@yGywqbbqa(4 diff --git a/carveracontroller/data/GcodeViewer/tools/flat_end_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/flat_end_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..e1a76f5be0fdd4dd54dbfff8d01c1c0a2658d6a1 GIT binary patch literal 27312 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

s)t==f?qQREcHLkUYgnqT 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 diff --git a/carveracontroller/data/GcodeViewer/tools/lollipop_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/lollipop_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..736fe975dbfbe288fadac1c0e371613560e302bf GIT binary patch literal 74450 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 literal 1224 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 NJYD@<);T3K0RW94on-(3 literal 1151 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NUO?)A!jXGcYjwdAc};RNQ)d$2w2iQH1s4vWI{5Z*o>#Je8vOZ3~>w}m>R?x_AoqP zWzc7+7!{&-NPMq;&s=l!<)io8_wtuK-Wk8+I$OcbpUt(Q9PCp6?rdb3bKCAkcv8WE zm)rX|6JDE2$dvtBtIT}EYVBVEnVLUa)fghO%a5;It;!a9Q@h>2OC7#SFu=^B{p8k&R{8Cw~fS(%z?8yHv_7__X}+J>SbH$Npa ztrAUxfrXW^0Yt;~)O1sz1`W6kC7HRY#U+Wk1!#JV&8L7(8A5T-G@y GGywnxZheIS diff --git a/carveracontroller/data/GcodeViewer/tools/radius_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/radius_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..e7eab6a9c1ccffcb18686267a3e320ce9bfef134 GIT binary patch literal 30890 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 FzX0PRflPLtIhYs{ znGOiwII+)zLBR)#_MO{3`88P8_RXDp9S{;g6>*Olj$UPHn9cd2n}y*J0zD|@3ykq* z*fI43p8|t`8UiI-coeEKHW)BIa5G!yh|rKA^FC;uGDzK>W6Mk@FgVOWpq{4=M?-;@ zaJ)$XxetyE<~fUA7hvEJX2?t2JPXNT&pyOGB(SsF5e)TiyC6p78Qjo zj1O3vc66dx{^s$Aqh(-E=9w+*MRKtI`}l1_pin8>#F&c|^gu8Cwrtth%dnyQgDg^L z0iAR1fxC740N_dH?yQSCxbTUokWD?z%=l{ zhA&k|nPH7m4m;QtK!<=)gR$j|jV&NAY-s9z7Jw391$ynq%Y+%ygf}G~uR3p2bJ zW_TXpQ%8xd=fxh$QXuCfh|NCDim?9y-@VH|iXf$D5|Vdtc=o diff --git a/carveracontroller/data/GcodeViewer/tools/tapered_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/tapered_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..560f80ee82b3c8cf638ecb44243a850656bd0ff4 GIT binary patch literal 27619 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

dK~sRw-g9Zm@9I=NJ6j4CQ zx(7>_#}nTPv>um-y&>@kyg8y{k)~=9DZUT)NTE69m}}lPKlxXMl7X~k z^n`a3ilAylh=U?=q{eIV;HHILfem1B>fM;0EVJi~v&b&cjarN!nr7*5=h8BP3m~R= zo4kZe=NZ2=R!McenToU5UZ%_YUSDgh`||s+zt22Qe+Q9pr$7oHpmpC%%P4f(R>S7I zQb+O^IB5z-KL!)R($Wxdk4b29e{62kG7?d%2Rq@RhaF~+YH?eewPo1)mD5jfadASU z)cRQdj$e0vNK>T^?A!cgS4#opNFhYj;v>OsSi(hhF{^MQQ-$;UJne^cC9$_z<7>VN zBNmUgS@E&!^Y!T9w#la_ocvC7XSNZ4I)DrVeE1&-si!-2i&Qh*;qatD9@MN^2cwnDR#v^UVvW(TBA7qHRaA-VPen6~(2?!~Yos`8$v>51dOk z_6zRb-RyQ-$4NQT3HksGS7D^LM4`%+NrSY62gsH-B; z;a|I!t&>>#hy~;cm^=7A^f83YJS0(_^d4#83^^!F?2+MJLvC^FNCCy5>BjB24j6!) z;LI?$pSR+)lE2eT;&BCyL;~UIYOX*8geVR=cjy%a(qsQ+tTO|gVq*~_L4J+JwMz}- z+Rh88vlzeMQRCN@ZNF{Z3t-I=^?Vr^BN}%69Ph}VSAy%owOVzy{H$yoOY7^9R83Nh zHBD-Ilk+3#L5t|RBg4mI1F*mA#hj9y%FCPoCB1(^C4AFlH(EpY+_@^| zv<@i#PC>#9h_n?GtFlBE8FPl?GNCNte|l1xkh*9JctjXI_(5#}XwD*mcn~o$v9y9hr?(6d za$MfS8C}NVw`-0Z#5#Lsl~<^W(~6hbHLOH#I4sos!!Z67XPy_-`@a{?&D|a`0V+lunR=xvy&mGEGgn*zY}6=MWc{ z9MeG9bKgOGtT^3m0C3Ra0jFK(mEXJsR=D${LH!IxuBlKM4-U|cMu*1DVQHu_!jphE zISmzjKU1dX=i6^l#uVnKw-95c*x0@xgWlW#O73yMN}=-^=%K$(GYsx+SNB4f*4h(e zsrAG%d0*O~Nag2pirx^RO6sMmhJ=I;Gs$6mUjW?Y+uU=#1_P3>_HJE?J>{I4AFU+&x--2lZI zkg{tQCKyKV}QM z-4a>ckh0_XK3R^i;ZEw{>;HCw2M%cKJ=A6tCfBcxe_3~e^Q+W=dyIgLiCf7e*X@&1 ztkwy!(S)TZw)H#aJi3mN)t6i@q;}-)$@4gP!mIQ#(#?h*Jl2kXViihH&5?(ZO@@G) z?^y>_VfOI{L`Aif8(G%r@WIPCQuEqXWCHN$7EkJ{gJo=-uKptu8KJV=k+r4Rurt36 zVB7Kk*rw`K-`3%8$Bz4WVKGyB-SP zCWeBDw4HDBKX@6XhX~`psTStY9W;$x+nouAt~e}I{ufZ%oazM;;{j9-OSidPVolp~ zB2K{tS5)naUuK^Hxm%R0br?XbdW~*6ZulZp-=%z%~~4 zMtL+?p=)UgU!6^h#6D2<^tOG*n932hD08TG;*P0mRx*LWL`+^uC6%i;QD`viIUt$T zNNldg=;d6sm-)*%NVTO&UizS9s$PMW@aPUSJdl5}&G^Yp>jer)Hvi5%-8?Q6Oqv z_NCQTsBKDzIKmj7tL+&aocPB!yx%^eMu6tkmuI|GG7*|OCN&>TzS9BdnZ8o`oI?TrvsPNz)l1J6DAtKaUrH56wSk2Jced4{X`XGa0*m zwmT5E15zGg7!MZ|DDA2)y2U6cFzv$v5bH)ZlS|7h_PNxCAI%V|TKAzv8NPT1C-&QC z@pciv8#$U5OunH?Fn5!V(7!nkZ@u8}KnTTa6s)5qy@wnYDsGYC)0j3|rYkqni59z3 zj5cyCQ$ZO>V*TwQw1ltLc@YvitMI07Ai}Ilo~djNL~%!QRRr+tPFQNIxZljHcY<&J z>II78sT7DLB~86$cc7t-xs;Pi6q+wwZ%r(7*u%pgi3bL(vfTojYy$Yy4R?4jVkste z+?OTy`m&tIkJ;WbeuAVDe@c^2bhnZZ0O{geod}&(H5~mWF3Vge>pY+Oe{; z?G9h1&jd3&pt0|-;Hy`4j!yS?^?*kN+K6=Z1TiwgH$#D}gn>E#z(7P1W@tr}8T~d> z1}#}S^CKDnSikP(;3EJI#Bkw6lp`h1FpDL>hvR?SMK-k02H|c^B=3N zK8v&9(M#1xM+Y#z2!RR$^IvW9x9m;F9Oo-O<(M)W+pDp%2j50IMUn6~g`Iwa6Zj|o zTUI%!s-hz# zvcBG!P9M;h$`*4T7&#I6s&eb#oE?u7qeZJMgvD~TF{%(K;5srXMU;$Asom;qN*U*Cwt-=^O=-!Ngv3*2p?KXQtFP3R8K!fnUYQ& zFkSEM0i=@L3xo%{H(AVrWZ9MSH?iz}(ZfjKx~wHZvaSs8taS%W0v>maW|i-Py;Fkz!s+*F6c?f^?%RCU8pTt!1`(of zfLu+bqxl%)J8?-c%;v*_C=s3~hi+z03kJqMB(HUJmOaCt>bf29W9{E8wA552V>8m8(>)(G) zbF#_kUkQX5`mRiy#?U%(k^`|DIP9H|Rsu#6nvvCBVh?u^DhIs!u;C}SplNUF9(_Z4Xn_u701dxSpzPkDb3eNdg$SL{D%BBDQlAXkG_P_Fz z`hAPWZ?io}CQN?hsnJP%6ls^3J{3bq;V2`!gDI67!ZEf;0BVcDgYhb}&p&td2>VCw zOPe^VFMuktw!hU_m{P!RUw=usAUOBhHqV2;rzlPUS|&oYly3X5lejplj?>K>&-3U~ zM_fF*p0(_Qw)6jsl9m&*&@2d#uk5Rz>k z*L#)x4j^7*!%lgYzWRk5ZdKu??G#WFKVKti4S!r~h^K%6wUH?9C_ue}9g{RkDK{I%Tdx;d7E!~$ z>zv*Rep~6rw*lg?VNMA5F8T{l;K|{ILfejOC-^FC_5JovO~CuBo~*wc+t}1mr^%8+ z*0sV4X<6AWmwNWRXX#N2rDIGlem6(=+k?0xPAMi(m2S|LYim6r&`bC8>;+;Cap09c zM4USPZwnW|zEvd^rt(h699!t@9C?5yK0X|p=2CiQ1GU^-o|GU8q2Aopvz_IC!p6@&ydnhD?pHG5t>4YjQqEJQQe}5!M*yD=LZYkYB}_g)m(Y<) zxl^7XuT5B=qI?*PgE-+7F_KgBl@S%|l28OVeS%7sE7sLsbK$4Th)lhB9< z1=1&uA>hiLwA(IVRvOp4{3G6WxZ(3q--}bE;{{oPsxeVc-iuKQsL;2K0Ak0*voi>O zd?PSGYVnK1$XJ@6Zr%Y%t&}nq1T7&|*#;+IC=RHyn#kNprhZ9oHitV4A!K|#z9V>z ztA8OYga-nf1y(q&Gs3!G1i!@7A^&ZVi(elty=Jy%q0{}7Jd}5vLOD=bH>+SEjYGVw zyO3mxkuaes>QwFLP68C~dQoCk2Nlho8yif+x+5_!5Hjrqsr`hF?hCygFEiJu{0^1? zBIE47u}Q5qt8%#Zu;EEzz>E)DGeqn%N!F}3rI7EP+tR?!n4cA@F|Rpp0f!5{ta1NA z8(qD6fi{r7D@luOdiC8LG}D2V)%n>eQN6EBf@ToObloMTeUckh3928o$G+H9IjO`h7%4L^Cc zi*|u!UXTD|B&t#+PJYUTthc|PewkoNMd*C+SwKq~OALGs<9WPAU(p=lq{^(QLGIgR zv5fCo=fzW|QMi`ii&J9hK#OZdC4cU*?+v7~+%^0@d2i8@~AZ-hU^ z`ycJRxl;{PfwDm365>L{@-2qW8uL&tfwa}#j1S*qYBV$Uaju*)}n^y?b z5dvU)T_63Pvv7Fdz8Iva`wxh&sD~{luOwe4-=v8oG3F{Y8rYST-a)xan^VgmVKbgt zI+8|y&7qoz@tRC^cpYHkfIAUL&92bhN=*H;ii(ffGY#1p#LC86v`3^(pEOqHE(2br z1}%mtEC<1D^9yoxIm^ML(Z~wt(FV3hAw}QZ`n7?&BTvMlKavP{b9fBH_6zOsbQzQ4 z-fSp&+aWIO9YZuVfZ5PUtWNep2zwdV!vuxe>p&o6*igDcV=iP{L$L@!hbP5|p)0FD z1aK+LKh78LRgMcJ{7m4fyNUBl`IV{7L^ z9!dzJ8?hS0b`PwEia)m{h4#$4|L$?Af7mdWRI3zgtMGJj(K@b1J3&{iAW}DjvPIUR zNpvwH@f0UV3N{qu>E@hzAtd2Lu6&mzdMSd+<_$NG;MeD050wVB>hM`Z1c*mtgRtQ* zwjh-*ReD+%W8+!zq3u{FiGj#$pf=So->ZYHvUV%s&_9Udy|dur$^)v; z)yK6>9hQ1U79Fftffh8{I)fiQhd*JyZcv8D!FnmeIpev}$|NvG977Fa z!IW0)eP{W+^2u+P+c8W@k^m>M85HcF_T{QIbp!!Vx7n6@b?PY6F&aH(`nvqMd*0{= z@z1Zy#!@Dqens{Kpt#r!z7khQ8jy(@6qT*}F3*`RS?*lD*1dHIC-_2`$b{i56nk{{ zdC1bQZT}DHpA@7iCtxH$C=5~q=G#VkG4+h$5t!jFdZH|m#g2Z``9PcqdtRRMorGAV zSnd$M5rF6Gc2r4d5E9+0uj-~6B>RIiMO=Hz;_em$3ew&Br#l7<$s=|edL7M`?kZ`j z{%E13^-AZxm0-{ea~Mb(zBOhVf;$)eKJ={ZyvDtsHVzK3pvlX9lb*QFI;rYpWE|-D zdy!D?3*r0UlSYNp9;qm<4SJ6@OmU8F?ey|a<3h*zIT+6C=!OCj;3-CugdXljh=Vl; ztwH+5`~+z5O`^Z3+-6O!epnud1nKLtZ=3}$%*J&hA|nieodW1Q(CNn2xNd*KFT5!&HZi#6T=$~xhZ4ROE}VMZgsJkh`ddBiwTAki z$%?_S$o{Uxy}b^euO}BQQ?3pAI>HJ(1p?%(tn9Wj*`-_sAFtG>1kaB|*js(3a7~KS zE?@Ik;gL=<%H6Q)-!FbhP#RIHlBu(ACw%mdXG=)2u9!i6V^B3;vpl`CaFuHZTzrEc zj%7p<9|@AsKl)M>K7B7{s;q+F=kq+FM8Mwhbx`C7_s0~Q0RYD+yrIqA+ao6z{AqP2 zfrAi9I)}KPm*MBO;V&OiQ7MFIw%r2UFRJ@8;p=OgDJL-%a%`L5x>v?*t6jvgHE)a( z97u%57k$g@%HxEn7?-?)zW^F>(}>`#h))}=WXavj z_*h`t%7&#}_W`?eH#d*q)KHcfL7LZ zi&?bwl59Q{$5!WtG<~${kWUwyOhugv{pRuFy-mkyLUwIwn9IHGRn4-=i(B(sD`S`) z_bj~Z2JEI`*UlLsN|xpjS0sSYmi@cP>0I{8WiD&l*G&5Xc$DwoE@CqFs@D{6sddy> zxEhx{o)9oKN=Dw=1)>Aq!YQ(LyjiG4CN#w%<<^y zkKKR|L*8~pL$)0?nZK?6Temc zIo)3A;>}fT8p&Faj_0hUr3Z%*>24zjs_#%V`cNBkWoeV)KG5QSc0kpR(b_E|qGCuT zkttG>xtC8+k?v1FlM$-yexRKXIc2vBTcLElmtEJg_WJ3XJQbcptf7h-r`*C zb&qq0I4Ll4q-}K4kHrXweEq3wmMZ(0-}qXs)=R8QHa4=0XOJ;r+nP5r+?fnwt8Emp zCM0GXAVvkWog;aLH?4WqV2LfWD78J3UPLPY}n!pE7Z7Nl8**r=I9z% z#=}cmHNPtEOwg;uQgymY&ShI~wzT`Z6SjNk}=!L42kVHW(eJyq8UBO9x1V5viFjub;sVExgLMnBVYq*rV+r zTt&UI3uu{FfnIobMB&pX_mpgk%3V^ficHAhg}B$}i&Un75I%OomsD<(ORGOf+4JPO zU0NURwx-VoWh4-#9}>xlTbvw;8|yDDZ>fjH0`t?@#JpbOlzx&xUP}zt%l&{Q12Ra6 zqs0wISic@p0+l3-UIAV{z3cH~xtyYO2Uh$iL6D5vfl{8&z3fxtsM9H{^Y{ytGHvolR8azm16_wFqA`zZRnP zNeUoW(Kn|3@i9B&ZP>VVFN6 zmbKpxjiqSph*ux8{*-o4gu*o*uk{EO%5{M5A%?k(H1d#ZRWo=c}!A9JJ5WjH25dN4LSVX);YLV;Hv!nNKuREm)JTmbm&7lag_t6mB zbU64{wcHlPhBzl#{JEIy^n!?HoMh{mdA8zVq`VsZ=x?hY5Se*MxTNcP2?Cq8Uvikz zqu4qEr2KI`u-NV8%S*Y}uZ)(a9iY&jAr`6qIq?zOd$}OTxO#z*AWwB++Yx}uyIx%# zvk^L7yf&f+Aj*W#+p58{ry;kK@??Jf`JtpfY^-F<#@FCd$_X}jGqD?qMB`}vHs9<1cLb>Xv)UW7>pwR= z3sqgSjodlzMH*~s5fy@owUwcFfpHZiMeEAl4K5JnD7*ZG%b1sUJM3kKepzq8XGAam z7%K{gZsKlaIgo?LLo%U6Ifp2CQH79^F%f;ZAJrhjAdrv0YhScpAS8SNBLCSW?N5fs+H|tY5>b*FT2lWxv00nLw7Yl|db?pu zxG7f-NXs)yVIsnSS0w;^;}sdLu~!L}6l9s#v$JpL1B(4>HUAdTtYA1@H^GM+bop0v z@An7A_3R$$(%6s)-bTR@c5~CO%9Ye?N?-T8K$s8du)o`7!APxM7(j%c90Hx;$7>(O z$HiPG3exM3bZA+swzw;rm5e7Nfg0{iz1toh9>{+C8rh(B#@4dEyxEaqpa4%x$X!|e z($g3Bo`0OYt@`>SH-$g{TvG`7!d~>q%HMss#6#vg!^fc4=rh8k*!zH#aM=b^ZsIq zp+8Qq(h}H!Ght`)VO+i>T(+(A*0s}r8=k(r@w8Z6?1d`q?=$Xa>V=UN?s%N6OBg27 zm)6`yaF^V;Xv&S>C+jq-b~fkiedCHRSxk0dkGOTymwCpdGiXx>#H-@I*M9z5Oo;W- zIy}!ZM6P(}C03sQ58)qskgtf|amb<`4x@guEfbqa0GMg$!bd(n_U=-7vcpq@6b`3H z7QOOsgc%afJ$jSj+`Z^oWPp>#!GduR{qnGEqk}J-XL*6=O_OV)-y)gyT^qiJ;Wx%6 zZ%8sMdTvEPAu=G#JR|hU|O7lLYyAnyYw__ufIjTvvM4yKp2ht zywy~s1Q3WX=5{T002OYUMwVzfa8pEzz&Ngf=-C3tkEZJSHVp63nUeFkPlsx^zPos2 zgly#d;}ahlQjTeg`~C|+g#@87x4-i4A%PNMN}kp1^V7A>8`mtuosTSYdUR$#k8Xh^ zzKiY7K0p4z2iHG(*wHOUWV@~J);RS-O8=ELe;FZO$%G()|5CV^ORrt0^+$ z6&@r2>C7;hshzl91U>od?E7Zw`Tt&96wqzpv$}`tio8pvCsDXCWuTC zlhpV5%h@Req^rkaQ#+55C6s)#nrx$WSdv>{|n6Oc&nrM?kqg4yq7%e>iy1-!= zxZr6>{=f+C)ibY_t35<$2ilBmU9^!#D9 zdn1l4-e|Ag(hUjN&J6jf3#dDVu^s_n+heHxz}5$|zHyow$Zq7ceZ)xc-?6jRTM9|< zx(KBE^y46LD4N0|&fzs!m0Tj2jf0+#ACy*1BD{ZjII>)ue@*v-m96MG3yKiJ z#A-+efKyz9LT(l0TMS0=8BUZ{+@Y0fTNTJxkPLg~P1NH0&-E9}8K2gjP4neS=M~6KfsVh={AVn`SVVs9)kw@zZbmT4qQW2BS|lr5C?; z-kr5B;Ig;@0MjUaz!km8LpBe=rOClw|PEo*XOjK0m=V zlLH^x_IH6PgDMvi`6rDxOYH*hFEvdyYO6>LXb88OQMHF&5B5Z&9}`i3So>@0rcdeGx7)77VV&8=`Am%MWFDH}rSlubq>gCHt}!oBt5x<-tR zqhL1j?VQ;;j^U|b)p{nWLZ4}>ZM%$+>Hm|JP#)M%QWPl~1u+zN2J!m&;~lT)1;83B z88-F!9x%({%g@u}2oep^J78WQb-y}l_3+u$V|x4?aNH+S#QT1Vz>9^i;qGUbj2^g? zPpZ755)`VYAd8p$RX4I|AzO-bERL1n@tVa>&WDaUaCoV;y665xqWidz3)b+4|Uzd9Wmh&eOOz|y9g!H zjyd;^Sj!J#$iLctR+TdXodHLAZ&wN5vu%yFxsFqHmN6(QkdoTi=;{7AkBf)JrV69`5IEQ2X3&vcB(iv87UwQpqkdV%(hVr@y0w3faHn5OFvFgc-i zZ9yJRkZm11>H|Q~yr5mC;L8<`ESVzY(B~SR(iDv##a3a|_}mhSQvm zVCDp)pcE85F=iEmQkLEL3HVOK0~9pVp5p0UtFx&?|K0OvVuJD{WIvCh=bSy7-ohj~ z1hs8cQQYe_9;j#3o95Ku{b8x-(>sE^zkdI7u3jDteYg<70banDOqTd7G4a(RiZfjf zhlV+97z7gE1!jhyzQ4FQoh1ixM(|J@sOSTsc7{IwXX_L?D9$y*pi!pM1ey`K8;KXc z6=F1rqe0AL5?mCEbMknx^8<-!Cqmg+UC_*EDFC6s#DRjwm7lhWur?+cH9Whu0>v8| zUvUUk!B10=bq>mEhy-~S_wN)OMQIVI?4eltvx3$eW_u-6%(bE*PgLc&V3n`qK-6FgF7?YGrk+td9Zxfzfm2whgLTX4Gp+Gb#aY?dm)92|wf%%5vr*Li98(5~sWZvkQ7N&Z$g&8u zd15?Woe^cJqkdgdxe(c8nYeRn;{UZNVYHuZ-u*O(YDp7%USHcl&zIB`Yr&f!>&B(i zoNFtn2P56Vb5bXj*ki|6$Bxk=-d$frzj=6jqaq^-(i}45gM&5#-jEF#Mq>~UY2I>) zr=T?-G_X7r1GrSU%)oy%c(>Wy?rB=VCrl{*IpdMah-!K9K3+9bBeK~j7_)Ib`3FAp zaOh#uTK1aYB!Q0P6FNAnpf+Xq zhBS@cOPWpdl&-1ja`Z!WgfWAfSMZ8plR>cKKWD)Qi;xr9SN*U#n40&zl)e#j{bTVB zzf<-N``?NO3Nw0vY5scGw}$|(lPo#;xwq=sABwc4zKrOKBoJmKr<-51;bDqEJRM~5 z2455u;T1<40O5V_w*3+M($wo8m$Cks%(cJ3QTi{%Zob&l<3o zK4+!Jep9cq`>OZUD0?1HxDYH~pDXNqHNE-Fc<>cM5coRTLU`~+r{;=#LgiLWicN)y z$X{s%89XcSb7q%K6Rf!3s;hbV6 z(^?`WDeS@vfo4iIBh{u^y6^Y?SOO+dQ`1liJOf{CT@du_Sp|$w37_9YL+;*xJ?aC5 zlOfwoGLI8)8ewxjPQ2P=C&XyLm#4x9;6DLcrpW$a;tYfwfjl44@;=v>=Ns z9#O}*JjZf0J%$qp2*o#7R-3wyj{7i=_tRh22;h~oQPbX848fn5`h#Y|zx|qT&5?ct zc=R@$X^NU58p0`r6;+3j!ijji4TRecerEJhERxySgRG!OW6sh4poLLdUR?HiA9PFJknd1O00U38m%^BYC3s_Q1RFs&ajfjexL0a0R zKse;_c|Gr8^r}3j6&NR^&Fe=rSDBunPJZIXiAK8@RTRVAJ?06-x;d?Nl?#oHxlU*n5b2xT_<1_M zBdaslipnhVrmA|{#+%k1;kI|Bh5caKFc(wt=(Ck-R2GT3_-4eLB;Lgj(Rh!9r)0i1 z6@K_M+_|LUm4?v@H(TGGlDTHTd2ouFlGs$FA6G$THu?6~A_1}Np(?a!&1hd`V}5*O zSX-?Lt?%w(ssb92@8S? zzA5vZTvuEN#ita-i0}vOS!Kd7VibhRJJW7#0{Y0G_>zm)lX&!q33kUTFMFFAwJnap zx`cYCKw@jGtX?&%@o~h97Bs|fz^z3{JVs;AMV01!e4tYp9` zPImGuta5XW2eB!@OS+FH(7_TfjIg%IqQVtefQa_-3T4F7KSf5zQYzd3G?S~$?VLcg8&({A9JiYGPa-sD4g-KKKBRv;UE z^YKX{bascq$C9TP{i2fDF;&pY|N1_DgsLo=8Y(S*6_dshw06_FycqO7B0V9c^|N)h zI5L#KAWZjwAWhe}LA5Tr$=bWvpttx?$Od1OD6Y64ZGc|8v5sYW)or}(ASvH_=0ak5 z@MlXB)GUH$L5hEIkZ333RRZ{iAeu3+53eYfAOnvWz|g7d0>aZF$FiaAXJfT5DLH59 z6NGqg1AVv(+*B^uX-GBR+$$(^c~)W0J;N{-Q1^$?EdY1^Kk-Jw4T>UQ`uq^fK|h?I zoyl2y4v5fDoox`)xo6=R)9hCD={5lN=&GwrMegco%zv}|y;%MTXV#eCR-7Wm8jO+u zCNys39t`R7hAe@L!mfjJJ3{5I!20+{N4?`d1)S^U3HHVcr*hMYZQdS`wWYRG@Ksw% z1002$huX9T%b^GB9T%FUeYVp}($P2p;5T>TWD@SPR zGfwFu#aldXF2f8$SGfb(kvr$W3XM>`RY4_$@q~45=C5w2BzLv}j%$u90b~o{dfnma zJih9JJ=ChvsJoixfsOn{uexDF<2662{!^>Pg#p}V3!b+WZZ3SdP&ghp^j|t((`O*k z=KB#uJb@|R5EY6%90~2mMnJw5P>)g*l}vHH@eTfNhssiq*3o$_N5x{eRiRUi+zWn-G-+V^-?29NE_hvT7fWaNk3n<%_&xM=Q?*KO7uUN{7EZ671{k>!+A(DZ^*%e4CUf6nvv1sH zq4#=Ae2TmSyMvH^b$&9XfnL!38P|3dl=?_aw2&9hL?s5*o7El3Enqg%ZGD*jmH|M& zG0JlBqyB0QU|X$=!Ta~l+%D(h)9d%+e+I2iacC0zh1HtigST|Y$$f2K)NKsL(3?R< zSbEUQrbo`k#;swGyfW4X2!TBQD<4_qVJNX=w$2g4`w{CD_>jDjhXMsC1OS&+#T+07 zk%eTLDZH0aRu^Dk(P69xiNYyf@Jf8m^GEJZoFIPJjp>46I|VraM{20-p;3NDWMH5t z#+rn3b>6t)mASQ*kyhqnvJajYON$!Jjuqwx0i>F4s0Az2<4qE$1+6W+spb9XlmxvH z#=&sv!PJyn?hX~&@5;v>Z$^+K#z2+Q#+%KL*Xw=y-BlY|F*cuU$??6W<8rd*=uCJ& zGpJ=~h*5pNHC_>5MW(Yg3}|7!)jZ%(h*mFl@@(8YJ~^|{z?3nA(jrYz8UwS(Io0Z| zYV#NvRJJwLiYDVMm<#31t#dUv&OlXsK;DT#WU{Up(CD>TTC+L#T8N%Uc#?a#G}4zK zjsPbCX6f91ufJnPGYx*sX}2;1&l7fYK29;}zuLwmC06>rR6#{E-}O4fnUs56A0n)nfx(Ho*xgO0c0R}MjpI>D?gxp3vxH#b zJRyd>iAYxg;{L`o5bG)#18MW`mkV0dzG`UXyLOUK$Uu6oIo#T96Z4})rkA5|7_&iH z?yR~P%w{N!)+(J5-D*bA#xE{Zf)2`x83?_Y?T+z>2nyxSa7#A-Im~#LLmh~$?CSU1 zPt|W`b>*}045%G&<%J)w;kozH0CF0C!ZtR>j? zQDYgO{mmi=SLnS*F!U{Zj=J?T<;f_)nl^y^qIFR-^w~MRx@H}0Dn--&X(eobcF(?R zx&NKCFTNMI<`Cta7smG0W7gm}k_o)Z2mf<@;l;i$NtPzGbmr6S|(cE}L_`->Jzm>`sHX zS&!F!!CZBumPT6h3AKhK0~zyTQU0Q5xw@X}wF=0?>zw-(9WoI47M})>{H8y+b397P z_u?95zZK_&Psov5qL};y%5{uNR>u4#p8zXHzIR4h64$k4$A4Mf#QFu8X6!bko3=_-DlBf66`3f^9` zU=s%QD@R1Z<&ycY*ICA#9GG|oH+9sx4f&Ok|IBfQ$TqT(VfYU zB2H#}ma}pub6SXe6R*(EP!+V>%?)(}eO_9f1^95Qs5VTPAJ&i7N}|Lo1#X$8lWRs- z#+&-Ugmdz%wuwtD&d%bp?w4W!Y&~H9;eAu8r%xSNeh${`Y_ueDZU>zDXq3#InVb$f z+VwN?qJS>-8H_P2_=(e1yvnnFJ-ON@$d>m|zf#9j`F3xF$wssK#+I6n&z6QCIAtUP zl?yR-+EF5ChB@ZLarBn6i+khENda4Gn(X9D53XvKgxj+*Y*%u;O!H5@CZWCD{(Y53&rR`jYzn_aX0w{4255aD zjw*qRCpT}QA^_jgHf%0yt5C}Df!`Ixx5hk$G@ut;)WmUP`6(;~IGlm92c%AJBppAx%xFkJ)q6MJ1ZjY&KEq+mGN*b** zP+wk$32z(&Fc1MwF>4k}rC*>~z*dlQgG~Q{8BpJpu^2-$StAuX+l*jBj`P=@)gHo8 z*pDU_xpnP7a}1A%QijOhWx+td~3DoK83b*fo6fto5%ea{w9hTOgo*EnUqTQat zE^vKDCsi5_j-=&A&8sB?wG)6##z9RP%4XtGKPAeIbA8rB-3UqsEOz~A!M7TuYEP;U zUZEp*u5hjfg!NcrBgHI?O^x5XG@!oXgV+P+e!SS(Q(gn{akIwN;C$uV0QfSl6Ey!WHY23W#ycu`u zYoIz{LiA3D`8cb`LPkW>97r8UPGl#jT-c3C2{`pLZ6IX!+j4M2jwQ zTx9eMeC{$M=EL*H7QDrVebV5045ohTgmC41-opE_ANO!=EyUy)*{}6$YzxuYUB;7A(e% zZ$Cqd{?k-l;PT%s$7Qyac3;xv`@UHFG2M@1xzhRg>%Vy z|GKNEqHE`(pFv#Qrvnu%C?F^RE~x8Vm{nL?PgH)Kpu>(dDUKNbht`rL2Vv*qN9G~| zy`yftfA2Caa%T6^GCap8qu=S?wKrnj_F^LY=in<7e2p|(at3XhmVx7e)uDfg!$6n& zpYul1#lqb9sDz7dB-X}MrmOS3rHKY;A*?w~W#dELn4m@tk&u)^v0uF!%nbf^wyPJ; z3OQB%=EwprA&YtH5s^Mt90Lfn-cdT;GlMjh^WNr%v+LSO>LuY2-VKyBqHFLwt4x&4`&KkD0io2i$sp;qRE`SS@$eBVXSEVT1%s-N=9CO^5;#au5S` z>vI;(u@7|p17l?=ow6yB6EN!5-jS|pt)}}Djnle$XR*rxD$rshW)&lz1vfY< zVu82eMLsu?r7+`)4A;Q^V{l>LFuA2 zG3+f!PRlx95wNFMRIz(>e-y1+pIIQL3aBDp_mBg4ggtNAi^2o=NQ;B)C6J)mJGS{L zr8%|G0GSe!71zZX0b28E5GWpTz1p&U3?(wT_0H$85|-h=1W$c%STLMF?869_ah$Ba z(g53@Z_xpokYAZ|L2uoPke@Ps6IWpXnaC*)roz`qsTVuHetqOpW}b~9A42C+(U?i7 z%hU$2WKz7CM?Pf?Xz5~%n5iCQ+tcV7p{`1Efl(GO;sq%A-x_PCKcMAWZ_vaM^{B`S z%iRFY-i={@blH1Xj=#43gnKK`=9*@)Nwuee)M8o!4TD;8*=PY*uyS%7oK3bDTWmogfG#T`W#LRjotrKie2E2T&MUJ0~c< zQ_TO$RB~f2#gy{fle=W>ZP5f=je;|?V|%en$jPzk5C*e$|N9FIZOl*QS-ZU<)#yl= z4!~6aR+>O>8yO35vA9w{*Jq(72t)I-k)_r6$MCBLAmy#IF(nT(%>+Lnv2pOP7b& zSbEy+;XCBg_hR0~MP!MsQ{9NQRQ$}{{^`SQyN}ca&g-lSSHX5cK>3pc#bPr%TojSpb0ai`hsjG7U{`dSmXs4YE z?_3ellM2?=DKNFfQ0U(J{97FZ8kGN>C}SffvRp0}Pd}`!)D0w|#s4&*x_HckUA+6` z(6=&+lB;zJ3`pHoZQa?=lmak0+!8*rj;{Wszp*~#z!p$U2dUX~aFB7iu>Ah_?T+mFkS(6_l0N7Ck;Z)E_xF0)#lpas zC@%X4M`5voreMn0n=INlWs$d8_#rsmtIXC)gu8ejg_mE925tA>ac=hj$mBRkVWu$1 zOYDc8%#dqB1ETm^W+<$Pa;j3Nw;d}F)s?HxE^vcvswuW)1N8RM;Oqwx-UD+=FWN(a z4L+5Cv3Yb68851~vw-dx+y#HT0pOr?twl~EpsU!s{X>6ND%v)E><&}I20V|GdYXI% z!!IC1j`@IyHqV;kWmV(bc8EYn?fY;)T>l8I7E}xB1Qphv^@ou^P-^d*r1t#2C%>7m zs?9F&U5ZHqg#zjZfK#qHP-`1(>6tGl1qVw7$C_~@(Yd=Y+Rq#SY)1>-d!O1?#)iK( zL~KZ%YV38A`XaV#q-HU8fTu@2#o^d{^<=4Vf@g~N9eLgF^Te{(~DkGiEevRvNm_^m4E_$xO+H}JK6BldHW zCWp!(fg@THRX0_aT7$k1u&eY>uLIdiuBDl@byhX68r9-JTfhObtT-^}gRn4WVt_gjmE^~9S5OnZO1H~dcHTbA@vZ%}k!#FRt zMp1G%g4mzW{8VQ?DTOQ26~M28fRmDi{GgsrYq2_79j@j#loyd4ZO|#NGUj zG2tHW?!B}h{}SYD1b|3SAm-Q+DrUK~UlkKO^257@ugeeK9eDKveC^9{>MoztByR2T z0%F4CQ$P=vR3rg#!eym)TN`mFR%ipL_W-ZH%QU?+LEIOCW#wUFjb751Ky(cH|BVfJ zA0s}770L+l2ZHPZ(G@AE0reT|IZnQEd%|CCIsBFft+ieN%7PC@gXFQy^YGaA$5F1< z_TMs!h)}*-uw{XP*HRj_(#BXN23W7phyKuq#lX>{ge@&SpiU9(O*{C)0n} zI&ATL6Tqt~1N=WxpC|*3<_(_PVMEPuMHv>-9=e9ixosdfZ0K z_M?+Fz+U8M^N!W|x}#ksBS{jN-kv~G*|<#l7~gtT$`6V7yH0grQgy#tQ&W7Ffn0vb z(CT}=1<*V=DuK;7jvS3`!0TKR14kkG5G)|OtScXk0m=0Y_;vYFj{T+7N7PWS zAZO017=aRR1hXFE3Ft^FI%txwRW_h~4H{Ahy{!!qSrwWM2LaPSL2PxV7-(hVA&h zit*BE3VUkrYt~URIDcN#7icK;{}Yl7q^7y&o7m}iDOKhl zKAhJ9)!nF}Zkio$iaYjTy|tIt(RvXe^#f9qu3mGdwgGQWel?Sp9RH&|C-j~_8KSSU z)zu+mQrHtD0%yh{aSxRI34Bwj?}OK3sgd?^LgGw=j}AouYtv}KF*ii zR(v)xKJHFMDtk$}>L}qMdIB7HP&Z!O5EEtAeJQl{?nhQNogI_lR7p$SRFP};!p()8 zOCb#1IDTm@ur4E6^)q}flh1Ozfcn`?{F|^c{Zs0TfI+i^Kny$|^?tf3PBEF2FS@Xo z?5C(gEDA+33`Ooa6`FLaTVoFFi}Y277$D{UWvJg)MmrIkG|kdifBftUf+=CL{Iq&e ze%6QP15J6ae6}m=*JwkGxx=%Sf_b18N@ zS#{<1wcL{msm*ue7Ji94J3gOnRVb4HGD$Ci1_x)f7omK2ON$!e?{tq*KyglP=|1P?i5xDH=vQsruYR<_AB27b8DD}3LS zj^jr_;z2k~QE6MZ$t%+Nx;l_zGo+-mjlsylBSF(G5ehjSO7Li%_ON^koS(n7wr$}b zD88LZ&rC=XE1`GoN`@}uWa%F&_VW=ouETt$zj++*P*oSdZ!~x?_P0b%kd0vbJLiLi zWSofO{96V->D!H@w>bq8w^{VS{;&L*7;(eCdbbEmULGk zyD`|DF&P=^tp!_eawlWMW*DRhH_}h0B_#4|z$vlLT~qq7^*517X`;3#n{nCF7G2v2 zW8MR6B1^kI+Lx@14Gl+)Q%3x=I}DIIq5khJXdkNhaM&-*jH!GT&>3{W@NfL8B=S*c zs{HmER%OskXl19gjn>sO3yg+W&sGk}vi^k1Y|Y1BERfkB27>#80P>3_RK1L(Y0imI zCOq+P^6r=0bCQfWHjiNc>Y)}k`NjoT1p|W~TbyJhS!RGn)|4Q&q-KLt#n_Ctm( zU9ng2KNlA8x91nZ-R8S5+dXOC+HVEwxA;QQ`+#Hnwmr|PWJ|44peKKx63EdSkWAYr z07Q$@I#v*0hb}C5JBEFGeRx2#n9qrZ_*N~WmRbO2?$Ao{{3?_VkwiQH_d-h~6MD=U zo*TB~dB|fe;Y7z=WmEwfWPD~1**(+z^7&8?RJ(LYhQ>tITFpDvUjB&7pp0>rSdj@` zk74&B?7K%->Wurxsz1E~!Wl|YnEh4N@J>j~g4PaEtSj5IK)*R1`j9%CDM80=%||Lz zH!}@5iUN@v-^0E0@E^P+T8%Klg9FjBfx_r7fU#1d3?5!OD#@t1G z7qA8E2FlS{GqhEo)y#0g?t4-p9 z%Em?t_(4Dgf0dugKLPduh2?-Pn{G7VpR&lDe+mU0$Ux>Jeu954acqwGl&EDqn@|sJack^1&Vs7r!qejztk?TXDh{>kIE>Db! z+DRGkGf*I{?r-CkU4qbA0x7V z?{D0%-x+aFPh;ZGdDJ*tL<4@!isGk6jKY48S(x;#?-Bzal1$ELN$)-z#gm33j>n}= z$`cM*0pwzwMW*Zk~^`01v1n<8u0_4Pl0( z_dd+GdV75jBWcRVzvd@1TnB$C!gh9rpCADcm z{H!2z7)-#1ap7fFh5cv$^)oxWi)Kulk3ye_ujt)Y<|GroC2fzAbq1|b7L)*dg}-~$ zMzh+ZrojvY32ntXGfh66@ykpoe!#-20uZFfYNoTkcw9qeMR=;?ByL}k_*?PJC-I_n zpx*1Gei+l*X@sh@)a_-=n1JhM(o?>~z{qr=erf&@jFCI^j@I^fSQJ&2alY4qd;nvf zsx&IsG|HXA^o!C*UcrrECzyt9kdisPKty&-kk^+~cXcM#)9RUhr23pHCds0|1ejXt z(ZrB^N}0L5ER)wR;<9lB@4CZ6yM;^53R4k z`l`3Jghr-vQ44b&UU}_7@m@H~GTwhSN=^x^1!tnP75rr}OC5JITob6v!>z8yNrM`P zU%a(LaneCE=6=AYuH9=+cy8uIM-jOtY9ccC?+bvFiVd#SpM5(U@vIu_{Y`g4jZ21$ zk{-Zvi|rdHi>B^Qk_|?7X|bjtZJ+v)zk5;Z?d>1>Ti?0aLmha`3BbvI{GE6-5HD5o z>Po+*1FLYI0AybYqzN|ogB|rp!<7w1ZwZ73RY&tv#a26uv6zv&yL`e|ewy?E8nhyz zYY(d1SLkm_li6>8qowFH9p-Ys%+GiG`52_RXLXqZhT{2o+wO!}!*BAH=76>!!!mGi41`OqS2D`^s4LuI!E zzk1a*`1y<(QF8#N`eF-(*zEP3sE|&45#JsxpZ$HhuJ5eRsrHT~m>C-9qPz-b(Tl8+ zSjfkOI`(}QmXZ#!Md|DL|SSM-!kLbw3`^P^o`*0a9CKNGi;ZbrOZeRPd6jHC+7V01r(HcwP{Ht5 z7bUa9^W?0Vf%MDnd~R}kBiqQj{!+;{cZRxbZOWLO=xt9+pr=bqyP+7iONkFLd|> zbA$Tx=<-ZAv=rC+d^Rh8@=-!-ebC=_dSp*$;Q070 z_WtnYDi3@H?%X-K9)Iyz^qWBgQhbl5$6Y*+?S`GuY z{Iu@unn*=&;yPGR*677vLu;@tzkVNmYrl4i(R6epe&|Dw-gbZAd$v)AvwlzbC6u}V z@Y^>)Nvr@yKF8~UR}P=IJt`*;wv6G?jnS>nlxj&+DmNysh9+Kf5J$+RTz_ksqcMg2 zQaR`!1*1b`#cJ!VnqdOlUJZ|X;J^9(>83RzO^g=Lp0`3+im zav46%GMZ`gW}Nm64nDP8DUL>v9byWeaQ3d4t2O!gkOl7^Pdc5AR;CU3X>GB@T%#dl ziH4B_lRZoS0uf1NsWT0I`c*DV9^1&I1&(caWsDd5e$u^Qzy0Ums+YN8p^;oFN!`Hf z%^6t#bZWluhGh63-tSSohnt?CO7K7be7s7hD6|NeGN=%^I59}1_Ajs(4?lod$n_5} zpH!KDX`oweAYRKn+r^#aH~56^h!3dlogQl(4v-4-{NJ2qCmntP!c^Vw`x>XnC9UqIe`Z=Q!|4Ho`U zemYHW$qq|EE@`b7Q*F8?*oliS5AgDEdSd7Zw?_t>a&yQ!l4dD1@JGa@bE~ahF_pB@gOf``&&rF#uf=p z{B^uk6Y+(S7XrY5g4D<9dS4~16g+vG@1}3|7~TIdAtp$+OJ2ionR&f_AfQwbvo6X+&;TilP3<&M5=4Vf$53Tgvi z4duPhH5LJ$Ua~a)JcdL)@S5Q5TdkU(-u|TbFbLjsM{eQcnqfLMrRqp2VyKFl=+m?O zkMOz&eaSoop_pa2UnRY$0|;u>TMvgL)<`i%ITPFFQu6wncwc!^oYZ@bVc)=7s?Ut# zI_zT6{l+;%1GSSHSGk&%ugsLxn#)A@oU`hO{sb1$ypKZv(9A^v+tYs(=exW|ecNMB zKRR^6-qCGKKR=``6@OBhw>bq9>Zp<^S&j(vtv>92)3hOzj1ON6Km0(-Zw{K|jley| zDvs?%V|$4jhum{=CsX2{O@UkI#aqvJ<~BpOW9wX>B>tlTsD682)z8Y3!;Y%Xok?FW z=?)~mB8fr)yU=KCK}J7A)<9Sr`xet#YlL52B~KlHIH2&Bjgi88JqVY)>wDa7MH;I= z%;y8%7Zo^-40JM0I*PD3TW%&2@TY%zs;Y{|s(830eh)1qvg(BkN&SGU@5IbSO!E2x zpLgOF>7^wd=bxcZ1taFC<4MFS67ToSPm}fA$^U=ffBN6whAJBE_>++J)3X%vV3xuq)jGVHZg1EG_vb1!|XNSN4&js$D x4z5l?|MLaaYcp2B1!Di_4!*ALjy}GR+`aziYY3-j7~mSvEj?r1N^NA+{{jnRo4)`6 literal 0 HcmV?d00001 diff --git a/carveracontroller/data/GcodeViewer/tools/thread_mill.png b/carveracontroller/data/GcodeViewer/tools/thread_mill.png index 34cc00cafa69573fd809992925da5c79963d8d85..79c7890a9b20f25db06ea3aebf36e1e6f1241770 100644 GIT binary patch literal 20107 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 literal 1316 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?IlE*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1C76=D-CY>|xA&jf59DzcctjR6Fz_7)VaDV6 zD^h@h>?NMQuI#Va`NWkNrt6>D#K6G(+0(@_q~g}wJKjOkjsgw`Cm#N8zrnoX;Gu{7 z5-q!SJL!LBxqLOBOGj|u-yLk#mVX)ei>&`L@bJn5sQF&g9YOe zP6fYFAsUB-xn;xj%lrWrC%<3j|Il_&dG~Ld?U(sK>KmIM*c|)+LGanz49ds99N5fz zoB6WY0ps}pCxrcOF&uW={AEt^w*zx{19tvPTt0UrE;f9f5pqrJ+zbe!KZr59qfL&4A=iJcNVtX$Qbi)zwAxs-{uXk>(76C z`Q|Qz-v9q*?;GbzANX2-<(TK&TR?&0ZEqWGfdcoFPhYu~&oI4yKW}xySGIz`@mnjJ zw9Ok%*Y_-~PPhvc=--kvE87exu*bDJ;V4jGwa$z;E%qD_7l_(3lkf-~9CH&Cm1& zwjU~It8IH<%)nW5=a_ifb9TpX2ae~=z4XqXN%h0NxB4gl^*6n3+%7xg%*^*pDj&8x z>mOUG-~6WWzU=H{C-a$AKfHQzy5QUEgz5)BvJ3vbXFSEpQ^9zS-5`ml{haNA7KU}% zCk(dDD?ib>oW&qRCHkDzu{l7oD+yxr3a@CUvl`^taGx_jvjr&jV1iuPx<>Wc5(h2> z*8cQSKFjl9*D<~~H~or#*>}~Pzp>DE@=oanT{>nUd&ZY4=4MHfnTfy>LAAs+q9i4; zB-JXpC>2OC7#SFu=^B{p8k&R{8Cw|}S(%t?8yHv_7(AaPcMU~DZhlH;S|yqW14}Cd xBZvmY?NSGU8Z_WGlw{_n7MCRE7NF@dHUSzB(bKDVybY*_!PC{xWt~$(69DC;-7f$D diff --git a/carveracontroller/data/GcodeViewer/tools/thread_mill_thumb.png b/carveracontroller/data/GcodeViewer/tools/thread_mill_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..a5e8be9bce358468a2a259544da918c68dcc7b6c GIT binary patch literal 24009 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 vbG=#}*Vz9D*JtIC literal 0 HcmV?d00001 diff --git a/carveracontroller/main.py b/carveracontroller/main.py index 83c8eadd..18956916 100644 --- a/carveracontroller/main.py +++ b/carveracontroller/main.py @@ -195,7 +195,12 @@ def ios_webbrowser_open(url, new=None): from . import Utils, custom_widgets from .__version__ import __version__ from .addons.probing.ProbingControls import ProbeButton -from .addons.tool_visualization import extract_tool_table, format_tool_tooltip, get_tool_icon_path +from .addons.tool_visualization import ( + extract_tool_table, + format_tool_tooltip, + get_tool_icon_path, + get_tool_tooltip_icon_path, +) from .addons.tooltips.Tooltips import Tooltip, ToolTipButton, ToolTipDropDown from .CNC import ( CNC, @@ -7261,7 +7266,7 @@ def load_gcode_file(self, filepath): # ----------------------------------------------------------------------- def _update_tool_button_icon_visibility(self, *_args): tool_bar = self.float_layout.tool_bar - tool_bar_icons_required_width = dp(438 + 6 * 58) + tool_bar_icons_required_width = dp(438 + 6 * 66) if tool_bar.width <= 0: return has_parsed_tools = bool(self.tool_table) @@ -7293,7 +7298,7 @@ def _refresh_tool_filter_buttons(self, *_args): tool_button.tooltip_markup = True tool_button.tooltip_horizontal = True tool_button.tooltip_image_size = (64, 64) - tool_button.tooltip_image = get_tool_icon_path(tool_def) + tool_button.tooltip_image = get_tool_tooltip_icon_path(tool_def) tool_button.tooltip_txt = format_tool_tooltip(tool_def) else: tool_button.tooltip_txt = "" diff --git a/carveracontroller/makera.kv b/carveracontroller/makera.kv index cd50a94b..f29ae44c 100644 --- a/carveracontroller/makera.kv +++ b/carveracontroller/makera.kv @@ -107,20 +107,22 @@ text: root.text if root.text else '' halign: 'right' if root.icon_align == 'left' and root.icon else 'center' valign: 'middle' if root.icon_align == 'left' else ('top' if root.min_icon else 'middle') - text_size: (self.width - dp(root.icon_size + 8), self.height - dp(root.min_icon_size + 8) if root.min_icon else self.height) if root.icon_align == 'left' and root.icon else (self.width, self.height - dp(root.min_icon_size + 12) if root.min_icon else None) + # Reserve a bit more bottom space when an eye icon is present so text/tool icons sit higher. + text_size: (self.width - dp(root.icon_size + 8), self.height - dp(root.min_icon_size + 12) if root.min_icon else self.height) if root.icon_align == 'left' and root.icon else (self.width, self.height - dp(root.min_icon_size + 12) if root.min_icon else None) color: tuple(app.active_color) if (root.active and not root.disabled) else ((110/255, 110/255, 110/255, 1) if root.disabled else (250/255, 250/255, 250/255, 1)) canvas.before: Color: rgba: tuple(app.active_color) if (root.active and not root.disabled) else ((110/255, 110/255, 110/255, 1) if root.disabled else (250/255, 250/255, 250/255, 1)) Rectangle: source: root.icon - pos: (self.x + dp(4), self.center_y - dp(root.icon_size / 2)) if root.icon_align == 'left' else (self.center_x - dp(root.icon_size / 2), self.center_y - dp(root.icon_size / 2)) + # Nudge tool icons up slightly when an eye is shown, to keep a gap above it. + pos: (self.x + dp(4), self.center_y - dp(root.icon_size / 2) + (dp(4) if root.min_icon else 0)) if root.icon_align == 'left' else (self.center_x - dp(root.icon_size / 2), self.center_y - dp(root.icon_size / 2)) size: dp(root.icon_size) if root.icon else 0, dp(root.icon_size) if root.icon else 0 Color: rgba: (250/255, 250/255, 250/255, 1) if root.min_active else (60/255, 60/255, 60/255, 1) Rectangle: source: root.min_icon if root.min_icon and not root.disabled else '' - pos: self.center_x - dp(root.min_icon_size / 2), self.y + dp(4) + pos: self.center_x - dp(root.min_icon_size / 2), self.y + dp(1) size: dp(root.min_icon_size) if root.min_icon and not root.disabled else 0, dp(root.min_icon_size) if root.min_icon and not root.disabled else 0 : @@ -4266,12 +4268,12 @@ # tools GcodeViewerToolBarButton: id: t1 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T1' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 1 disabled: 1 not in root.used_tools min_icon: 'data/eye.png' @@ -4280,12 +4282,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t2 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T2' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 2 disabled: 2 not in root.used_tools min_icon: 'data/eye.png' @@ -4294,12 +4296,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t3 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T3' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 3 disabled: 3 not in root.used_tools min_icon: 'data/eye.png' @@ -4308,12 +4310,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t4 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T4' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 4 disabled: 4 not in root.used_tools min_icon: 'data/eye.png' @@ -4322,12 +4324,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t5 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T5' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 5 disabled: 5 not in root.used_tools min_icon: 'data/eye.png' @@ -4336,12 +4338,12 @@ app.root.filter_tool() GcodeViewerToolBarButton: id: t6 - width: '58dp' if root.show_tool_button_icons else '44dp' + width: '66dp' if root.show_tool_button_icons else '44dp' valign: 'middle' text: 'T6' icon: '' icon_align: 'left' - icon_size: 20 + icon_size: 28 active: app.tool == 6 disabled: 6 not in root.used_tools min_icon: 'data/eye.png' diff --git a/tests/unit/test_tool_visualization.py b/tests/unit/test_tool_visualization.py index a233a337..5f05ee34 100644 --- a/tests/unit/test_tool_visualization.py +++ b/tests/unit/test_tool_visualization.py @@ -271,19 +271,26 @@ def test_infer_shank_diameter(self): class TestIconBuilder: def test_default_icon_for_missing_tool(self): - assert get_tool_icon_path(None) == "data/GcodeViewer/tools/pointed_mill.png" + assert get_tool_icon_path(None) == "data/GcodeViewer/tools/pointed_mill_thumb.png" def test_maps_known_tool_types(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL) - assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/ball_end_mill.png" + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/ball_end_mill_thumb.png" def test_maps_tapered_mill_icon(self): tool_def = ToolDefinition(number=12, tool_type=ToolType.TAPERED_MILL) - assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/tapered_mill.png" + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/tapered_mill_thumb.png" def test_maps_engraving_to_default_pointed_icon(self): tool_def = ToolDefinition(number=1, tool_type=ToolType.ENGRAVING) - assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/pointed_mill.png" + assert get_tool_icon_path(tool_def) == "data/GcodeViewer/tools/pointed_mill_thumb.png" + + def test_tooltip_icons_use_full_body_assets(self): + from carveracontroller.addons.tool_visualization.icon_builder import get_tool_tooltip_icon_path + + assert get_tool_tooltip_icon_path(None) == "data/GcodeViewer/tools/pointed_mill.png" + tool_def = ToolDefinition(number=1, tool_type=ToolType.BALL_END_MILL) + assert get_tool_tooltip_icon_path(tool_def) == "data/GcodeViewer/tools/ball_end_mill.png" class TestTooltipBuilder: