From 509f4087e1c555d676c4ba53a8f10ab290d053b2 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Sep 2021 03:01:06 +0300 Subject: [PATCH] - in Milling Plugin added a property that allows to segment the resulting GCode threfore allowing autolevelling - in Levelling Plugin added a check that allow levelling only for CNC Job objects resulted from Geometry - some minor changes --- CHANGELOG.md | 4 +- .../geometry/GeometryAdvOptPrefGroupUI.py | 2 + appPlugins/ToolLevelling.py | 18 ++--- appPlugins/ToolMilling.py | 66 +++++++++++++++++-- camlib.py | 6 +- 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc253458..0190bed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,9 @@ CHANGELOG for FlatCAM beta - Fiducials Plugin: replaced a Radio button with a Combobox2 and optimized the UI - The Combobox2 GUI element no longer issue an exception if it is tried to set a string value, it will set automatically the index 0 - some changes in the Preferences UI for Film and Fiducial Plugins - +- in Milling Plugin added a property that allows to segment the resulting GCode threfore allowing autolevelling +- in Levelling Plugin added a check that allow levelling only for CNC Job objects resulted from Geometry +- some minor changes 8.09.2021 diff --git a/appGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py b/appGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py index 5823e255..38bb2d31 100644 --- a/appGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py +++ b/appGUI/preferences/geometry/GeometryAdvOptPrefGroupUI.py @@ -34,6 +34,8 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI): self.layout.addWidget(self.geo_label) grid1 = FCGridLayout(v_spacing=5, h_spacing=3) + grid1.setColumnStretch(0, 0) + grid1.setColumnStretch(1, 1) self.layout.addLayout(grid1) # Size of trace segment on X axis diff --git a/appPlugins/ToolLevelling.py b/appPlugins/ToolLevelling.py index b4a6dbc8..e199a925 100644 --- a/appPlugins/ToolLevelling.py +++ b/appPlugins/ToolLevelling.py @@ -310,14 +310,13 @@ class ToolLevelling(AppTool, CNCjob): self.ui.al_method_radio.setDisabled(True) self.ui.al_method_radio.set_value('v') - target_obj = self.app.collection.get_by_name(self.ui.object_combo.get_value()) - if target_obj and target_obj.is_segmented_gcode is True: + if loaded_obj and loaded_obj.is_segmented_gcode is True and loaded_obj.options["type"] == 'Geometry': self.ui.al_frame.setDisabled(False) - self.ui.al_mode_radio.set_value(target_obj.options['tools_al_mode']) + self.ui.al_mode_radio.set_value(loaded_obj.options['tools_al_mode']) self.on_controller_change() - self.on_mode_radio(val=target_obj.options['tools_al_mode']) - self.on_method_radio(val=target_obj.options['tools_al_method']) + self.on_mode_radio(val=loaded_obj.options['tools_al_mode']) + self.on_method_radio(val=loaded_obj.options['tools_al_method']) else: self.ui.al_frame.setDisabled(True) @@ -345,9 +344,9 @@ class ToolLevelling(AppTool, CNCjob): self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(obj_name))) return - if target_obj is None or target_obj.is_segmented_gcode is False: - self.ui.al_frame.setDisabled(True) - else: + if target_obj is not None and target_obj.is_segmented_gcode is True and \ + target_obj.options["type"] == 'Geometry': + self.ui.al_frame.setDisabled(False) # Shapes container for the Voronoi cells in Autolevelling @@ -355,6 +354,9 @@ class ToolLevelling(AppTool, CNCjob): self.probing_shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, layers=1) else: self.probing_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=obj_name + "_probing_shapes") + return + + self.ui.al_frame.setDisabled(True) def on_object_selection_changed(self, current, previous): try: diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index f1179b5b..f4b8501a 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -490,6 +490,8 @@ class ToolMilling(AppTool, Excellon): "tools_mill_z_pdepth": self.ui.pdepth_entry, "tools_mill_feedrate_probe": self.ui.feedrate_probe_entry, "tools_mill_ppname_g": self.ui.pp_geo_name_cb, + "segx": self.ui.segx_entry, + "segy": self.ui.segy_entry, # "gcode_type": self.ui.excellon_gcode_type_radio, "tools_mill_area_exclusion": self.ui.exclusion_cb, @@ -542,6 +544,8 @@ class ToolMilling(AppTool, Excellon): "mill_depth_probe": "tools_mill_z_pdepth", "mill_fr_probe": "tools_mill_feedrate_probe", "mill_ppname_g": "tools_mill_ppname_g", + "mill_segx": "segx", + "mill_segy": "segy", "mill_exclusion": "tools_mill_area_exclusion", "mill_area_shape": "tools_mill_area_shape", @@ -2729,8 +2733,16 @@ class ToolMilling(AppTool, Excellon): outname = "%s_%s" % (self.target_obj.options["name"], 'cnc') if outname is None else outname tools_dict = self.sel_tools if tools_dict is None else tools_dict - segx = segx if segx is not None else float(self.target_obj.options['segx']) - segy = segy if segy is not None else float(self.target_obj.options['segy']) + if not self.target_obj.tools: + segx = segx if segx is not None else float(self.target_obj.options['segx']) + segy = segy if segy is not None else float(self.target_obj.options['segy']) + else: + tools_list = list(self.target_obj.tools.keys()) + # the segx and segy values are the same for all tools os we just take the values from the first tool + sel_tool = tools_list[0] + data_dict = self.target_obj.tools[sel_tool]['data'] + segx = data_dict['segx'] + segy = data_dict['segy'] try: xmin = self.target_obj.options['xmin'] @@ -4443,6 +4455,52 @@ class MillingUI: grid3.addWidget(pp_geo_label, 12, 0) grid3.addWidget(self.pp_geo_name_cb, 12, 1) + # Allow Levelling + self.allow_level_cb = FCCheckBox('%s' % _("Allow levelling")) + self.allow_level_cb.setToolTip( + _("Allow levelling by having segments size more than zero.") + ) + self.allow_level_cb.setObjectName("mill_allow_level") + + grid3.addWidget(self.allow_level_cb, 14, 0, 1, 2) + + # Size of trace segment on X axis + segx_label = FCLabel('%s:' % _("Segment X size")) + segx_label.setToolTip( + _("The size of the trace segment on the X axis.\n" + "Useful for auto-leveling.\n" + "A value of 0 means no segmentation on the X axis.") + ) + self.segx_entry = FCDoubleSpinner() + self.segx_entry.set_range(0, 99999) + self.segx_entry.set_precision(self.decimals) + self.segx_entry.setSingleStep(0.1) + self.segx_entry.setWrapping(True) + self.segx_entry.setObjectName("mill_segx") + + grid3.addWidget(segx_label, 16, 0) + grid3.addWidget(self.segx_entry, 16, 1) + + # Size of trace segment on Y axis + segy_label = FCLabel('%s:' % _("Segment Y size")) + segy_label.setToolTip( + _("The size of the trace segment on the Y axis.\n" + "Useful for auto-leveling.\n" + "A value of 0 means no segmentation on the Y axis.") + ) + self.segy_entry = FCDoubleSpinner() + self.segy_entry.set_range(0, 99999) + self.segy_entry.set_precision(self.decimals) + self.segy_entry.setSingleStep(0.1) + self.segy_entry.setWrapping(True) + self.segy_entry.setObjectName("mill_segy") + + grid3.addWidget(segy_label, 18, 0) + grid3.addWidget(self.segy_entry, 18, 1) + + self.oih = OptionalHideInputSection(self.allow_level_cb, + [segx_label, self.segx_entry, segy_label, self.segy_entry]) + # ------------------------------------------------------------------------------------------------------------ # ------------------------- EXCLUSION AREAS ------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------ @@ -4458,11 +4516,11 @@ class MillingUI: ) self.exclusion_cb.setObjectName("mill_exclusion") - grid3.addWidget(self.exclusion_cb, 14, 0, 1, 2) + grid3.addWidget(self.exclusion_cb, 20, 0, 1, 2) self.exclusion_frame = QtWidgets.QFrame() self.exclusion_frame.setContentsMargins(0, 0, 0, 0) - grid3.addWidget(self.exclusion_frame, 16, 0, 1, 2) + grid3.addWidget(self.exclusion_frame, 22, 0, 1, 2) self.exclusion_box = QtWidgets.QVBoxLayout() self.exclusion_box.setContentsMargins(0, 0, 0, 0) diff --git a/camlib.py b/camlib.py index 6921c354..021eb92b 100644 --- a/camlib.py +++ b/camlib.py @@ -2785,8 +2785,11 @@ class CNCjob(Geometry): self.dwell = dwell self.dwelltime = dwelltime + # For Autolevelling self.segx = float(segx) if segx is not None else 0.0 self.segy = float(segy) if segy is not None else 0.0 + # tells if the generated Gcode is segmented for autolevelling + self.is_segmented_gcode = False self.input_geometry_bounds = None @@ -2814,9 +2817,6 @@ class CNCjob(Geometry): # search for toolchange code: M6 self.re_toolchange = re.compile(r'^\s*(M6)$') - # tells if the generated Gcode is segmented for autolevelling - self.is_segmented_gcode = False - # Attributes to be included in serialization # Always append to it because it carries contents # from Geometry.