diff --git a/klippy/extras/bed_mesh.py b/klippy/extras/bed_mesh.py index 8a4f56da..24d190b4 100644 --- a/klippy/extras/bed_mesh.py +++ b/klippy/extras/bed_mesh.py @@ -36,28 +36,53 @@ def lerp(t, v0, v1): return (1. - t) * v0 + t * v1 # retreive commma separated pair from config -def parse_pair(config, param, check=True, cast=float, - minval=None, maxval=None): - val = config.get(*param).strip().split(',', 1) - pair = tuple(cast(p.strip()) for p in val) - if check and len(pair) != 2: - raise config.error( - "bed_mesh: malformed '%s' value: %s" - % (param[0], config.get(*param))) - elif len(pair) == 1: +def parse_config_pair(config, option, default, minval=None, maxval=None): + pair = config.getintlist(option, (default, default)) + if len(pair) != 2: + if len(pair) != 1: + raise config.error("bed_mesh: malformed '%s' value: %s" + % (option, config.get(option))) pair = (pair[0], pair[0]) if minval is not None: if pair[0] < minval or pair[1] < minval: raise config.error( "Option '%s' in section bed_mesh must have a minimum of %s" - % (param[0], str(minval))) + % (option, str(minval))) if maxval is not None: if pair[0] > maxval or pair[1] > maxval: raise config.error( "Option '%s' in section bed_mesh must have a maximum of %s" - % (param[0], str(maxval))) + % (option, str(maxval))) return pair +# retreive commma separated pair from a g-code command +def parse_gcmd_pair(gcmd, name, minval=None, maxval=None): + try: + pair = [int(v.strip()) for v in gcmd.get(name).split(',')] + except: + raise gcmd.error("Unable to parse parameter '%s'" % (name,)) + if len(pair) != 2: + if len(pair) != 1: + raise gcmd.error("Unable to parse parameter '%s'" % (name,)) + pair = (pair[0], pair[0]) + if minval is not None: + if pair[0] < minval or pair[1] < minval: + raise gcmd.error("Parameter '%s' must have a minimum of %d" + % (name, minval)) + if maxval is not None: + if pair[0] > maxval or pair[1] > maxval: + raise gcmd.error("Parameter '%s' must have a maximum of %d" + % (name, maxval)) + return pair + +# retreive commma separated coordinate from a g-code command +def parse_gcmd_coord(gcmd, name): + try: + v1, v2 = [float(v.strip()) for v in gcmd.get(name).split(',')] + except: + raise gcmd.error("Unable to parse parameter '%s'" % (name,)) + return v1, v2 + class BedMesh: FADE_DISABLE = 0x7FFFFFFF @@ -385,7 +410,7 @@ class BedMeshCalibrate: orig_cfg = self.orig_config self.radius = config.getfloat('mesh_radius', None, above=0.) if self.radius is not None: - self.origin = parse_pair(config, ('mesh_origin', "0, 0")) + self.origin = config.getfloatlist('mesh_origin', (0., 0.), count=2) x_cnt = y_cnt = config.getint('round_probe_count', 5, minval=3) # round beds must have an odd number of points along each axis if not x_cnt & 1: @@ -399,10 +424,9 @@ class BedMeshCalibrate: max_x = max_y = self.radius else: # rectangular - x_cnt, y_cnt = parse_pair( - config, ('probe_count', '3'), check=False, cast=int, minval=3) - min_x, min_y = parse_pair(config, ('mesh_min',)) - max_x, max_y = parse_pair(config, ('mesh_max',)) + x_cnt, y_cnt = parse_config_pair(config, 'probe_count', 3, minval=3) + min_x, min_y = config.getfloatlist('mesh_min', count=2) + max_x, max_y = config.getfloatlist('mesh_max', count=2) if max_x <= min_x or max_y <= min_y: raise config.error('bed_mesh: invalid min/max points') orig_cfg['x_count'] = mesh_cfg['x_count'] = x_cnt @@ -410,8 +434,7 @@ class BedMeshCalibrate: orig_cfg['mesh_min'] = self.mesh_min = (min_x, min_y) orig_cfg['mesh_max'] = self.mesh_max = (max_x, max_y) - pps = parse_pair(config, ('mesh_pps', '2'), check=False, - cast=int, minval=0) + pps = parse_config_pair(config, 'mesh_pps', 2, minval=0) orig_cfg['mesh_x_pps'] = mesh_cfg['mesh_x_pps'] = pps[0] orig_cfg['mesh_y_pps'] = mesh_cfg['mesh_y_pps'] = pps[1] orig_cfg['algo'] = mesh_cfg['algo'] = \ @@ -419,12 +442,11 @@ class BedMeshCalibrate: orig_cfg['tension'] = mesh_cfg['tension'] = config.getfloat( 'bicubic_tension', .2, minval=0., maxval=2.) for i in list(range(1, 100, 1)): - min_opt = "faulty_region_%d_min" % (i,) - max_opt = "faulty_region_%d_max" % (i,) - if config.get(min_opt, None) is None: + start = config.getfloatlist("faulty_region_%d_min" % (i,), None, + count=2) + if start is None: break - start = parse_pair(config, (min_opt,)) - end = parse_pair(config, (max_opt,)) + end = config.getfloatlist("faulty_region_%d_max" % (i,), count=2) # Validate the corners. If necessary reorganize them. # c1 = min point, c3 = max point # c4 ---- c3 @@ -518,7 +540,7 @@ class BedMeshCalibrate: self.mesh_max = (self.radius, self.radius) need_cfg_update = True if "MESH_ORIGIN" in params: - self.origin = parse_pair(gcmd, ('MESH_ORIGIN',)) + self.origin = parse_gcmd_coord(gcmd, 'MESH_ORIGIN') need_cfg_update = True if "ROUND_PROBE_COUNT" in params: cnt = gcmd.get_int('ROUND_PROBE_COUNT', minval=3) @@ -527,14 +549,13 @@ class BedMeshCalibrate: need_cfg_update = True else: if "MESH_MIN" in params: - self.mesh_min = parse_pair(gcmd, ('MESH_MIN',)) + self.mesh_min = parse_gcmd_coord(gcmd, 'MESH_MIN') need_cfg_update = True if "MESH_MAX" in params: - self.mesh_max = parse_pair(gcmd, ('MESH_MAX',)) + self.mesh_max = parse_gcmd_coord(gcmd, 'MESH_MAX') need_cfg_update = True if "PROBE_COUNT" in params: - x_cnt, y_cnt = parse_pair( - gcmd, ('PROBE_COUNT',), check=False, cast=int, minval=3) + x_cnt, y_cnt = parse_gcmd_pair(gcmd, 'PROBE_COUNT', minval=3) self.mesh_config['x_count'] = x_cnt self.mesh_config['y_count'] = y_cnt need_cfg_update = True @@ -1094,10 +1115,8 @@ class ProfileManager: self.incompatible_profiles.append(name) continue self.profiles[name] = {} - z_values = profile.get('points').split('\n') - self.profiles[name]['points'] = \ - [[float(pt.strip()) for pt in line.split(',')] - for line in z_values if line.strip()] + zvals = profile.getlists('points', seps=(',', '\n'), parser=float) + self.profiles[name]['points'] = zvals self.profiles[name]['mesh_params'] = params = \ collections.OrderedDict() for key, t in PROFILE_OPTIONS.items():