jpcgt/flatcam/Beta слито с Beta
This commit is contained in:
commit
5569c68670
315
FlatCAMApp.py
315
FlatCAMApp.py
|
@ -124,6 +124,10 @@ class App(QtCore.QObject):
|
|||
# Manual URL
|
||||
manual_url = "http://flatcam.org/manual/index.html"
|
||||
video_url = "https://www.youtube.com/playlist?list=PLVvP2SYRpx-AQgNlfoxw93tXUXon7G94_"
|
||||
gerber_spec_url ="https://www.ucamco.com/files/downloads/file/81/The_Gerber_File_Format_specification." \
|
||||
"pdf?7ac957791daba2cdf4c2c913f67a43da"
|
||||
excellon_spec_url = "https://www.ucamco.com/files/downloads/file/305/the_xnc_file_format_specification.pdf"
|
||||
bug_report_url = "https://bitbucket.org/jpcgt/flatcam/issues?status=new&status=open"
|
||||
|
||||
# this variable will hold the project status
|
||||
# if True it will mean that the project was modified and not saved
|
||||
|
@ -401,20 +405,15 @@ class App(QtCore.QObject):
|
|||
"global_portable": self.ui.general_defaults_form.general_app_group.portability_cb,
|
||||
"global_language": self.ui.general_defaults_form.general_app_group.language_cb,
|
||||
|
||||
"global_shell_at_startup": self.ui.general_defaults_form.general_app_group.shell_startup_cb,
|
||||
"global_version_check": self.ui.general_defaults_form.general_app_group.version_check_cb,
|
||||
"global_send_stats": self.ui.general_defaults_form.general_app_group.send_stats_cb,
|
||||
"global_pan_button": self.ui.general_defaults_form.general_app_group.pan_button_radio,
|
||||
"global_mselect_key": self.ui.general_defaults_form.general_app_group.mselect_radio,
|
||||
|
||||
"global_project_at_startup": self.ui.general_defaults_form.general_app_group.project_startup_cb,
|
||||
"global_project_autohide": self.ui.general_defaults_form.general_app_group.project_autohide_cb,
|
||||
"global_toggle_tooltips": self.ui.general_defaults_form.general_app_group.toggle_tooltips_cb,
|
||||
"global_worker_number": self.ui.general_defaults_form.general_app_group.worker_number_sb,
|
||||
"global_tolerance": self.ui.general_defaults_form.general_app_group.tol_entry,
|
||||
|
||||
"global_open_style": self.ui.general_defaults_form.general_app_group.open_style_cb,
|
||||
"global_delete_confirmation": self.ui.general_defaults_form.general_app_group.delete_conf_cb,
|
||||
|
||||
"global_compression_level": self.ui.general_defaults_form.general_app_group.compress_combo,
|
||||
"global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb,
|
||||
|
@ -442,15 +441,17 @@ class App(QtCore.QObject):
|
|||
"global_layout": self.ui.general_defaults_form.general_gui_set_group.layout_combo,
|
||||
"global_hover": self.ui.general_defaults_form.general_gui_set_group.hover_cb,
|
||||
"global_selection_shape": self.ui.general_defaults_form.general_gui_set_group.selection_cb,
|
||||
"global_shell_at_startup": self.ui.general_defaults_form.general_gui_set_group.shell_startup_cb,
|
||||
"global_project_at_startup": self.ui.general_defaults_form.general_gui_set_group.project_startup_cb,
|
||||
"global_project_autohide": self.ui.general_defaults_form.general_gui_set_group.project_autohide_cb,
|
||||
"global_toggle_tooltips": self.ui.general_defaults_form.general_gui_set_group.toggle_tooltips_cb,
|
||||
"global_delete_confirmation": self.ui.general_defaults_form.general_gui_set_group.delete_conf_cb,
|
||||
|
||||
# Gerber General
|
||||
"gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
|
||||
"gerber_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
|
||||
"gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb,
|
||||
"gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
|
||||
"gerber_buffering": self.ui.gerber_defaults_form.gerber_gen_group.buffering_radio,
|
||||
"gerber_simplification": self.ui.gerber_defaults_form.gerber_gen_group.simplify_cb,
|
||||
"gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_gen_group.simplification_tol_spinner,
|
||||
|
||||
# Gerber Options
|
||||
"gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
|
||||
|
@ -468,6 +469,9 @@ class App(QtCore.QObject):
|
|||
# "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
|
||||
# "gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
|
||||
"gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
|
||||
"gerber_buffering": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffering_radio,
|
||||
"gerber_simplification": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplify_cb,
|
||||
"gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplification_tol_spinner,
|
||||
|
||||
# Gerber Export
|
||||
"gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
|
||||
|
@ -513,9 +517,9 @@ class App(QtCore.QObject):
|
|||
# Excellon Options
|
||||
"excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry,
|
||||
"excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry,
|
||||
"excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.eendz_entry,
|
||||
"excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_entry,
|
||||
"excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry,
|
||||
"excellon_spindledir": self.ui.excellon_defaults_form.excellon_opt_group.spindledir_radio,
|
||||
"excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb,
|
||||
"excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry,
|
||||
"excellon_toolchange": self.ui.excellon_defaults_form.excellon_opt_group.toolchange_cb,
|
||||
|
@ -529,10 +533,10 @@ class App(QtCore.QObject):
|
|||
"excellon_offset": self.ui.excellon_defaults_form.excellon_adv_opt_group.offset_entry,
|
||||
"excellon_toolchangexy": self.ui.excellon_defaults_form.excellon_adv_opt_group.toolchangexy_entry,
|
||||
"excellon_startz": self.ui.excellon_defaults_form.excellon_adv_opt_group.estartz_entry,
|
||||
"excellon_endz": self.ui.excellon_defaults_form.excellon_adv_opt_group.eendz_entry,
|
||||
"excellon_feedrate_rapid": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_rapid_entry,
|
||||
"excellon_z_pdepth": self.ui.excellon_defaults_form.excellon_adv_opt_group.pdepth_entry,
|
||||
"excellon_feedrate_probe": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_probe_entry,
|
||||
"excellon_spindledir": self.ui.excellon_defaults_form.excellon_adv_opt_group.spindledir_radio,
|
||||
"excellon_f_plunge": self.ui.excellon_defaults_form.excellon_adv_opt_group.fplunge_cb,
|
||||
"excellon_f_retract": self.ui.excellon_defaults_form.excellon_adv_opt_group.fretract_cb,
|
||||
|
||||
|
@ -585,23 +589,23 @@ class App(QtCore.QObject):
|
|||
"geometry_feedrate": self.ui.geometry_defaults_form.geometry_opt_group.cncfeedrate_entry,
|
||||
"geometry_feedrate_z": self.ui.geometry_defaults_form.geometry_opt_group.cncplunge_entry,
|
||||
"geometry_spindlespeed": self.ui.geometry_defaults_form.geometry_opt_group.cncspindlespeed_entry,
|
||||
"geometry_spindledir": self.ui.geometry_defaults_form.geometry_opt_group.spindledir_radio,
|
||||
"geometry_dwell": self.ui.geometry_defaults_form.geometry_opt_group.dwell_cb,
|
||||
"geometry_dwelltime": self.ui.geometry_defaults_form.geometry_opt_group.dwelltime_entry,
|
||||
"geometry_ppname_g": self.ui.geometry_defaults_form.geometry_opt_group.pp_geometry_name_cb,
|
||||
"geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb,
|
||||
"geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry,
|
||||
"geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.gendz_entry,
|
||||
"geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry,
|
||||
"geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb,
|
||||
|
||||
# Geometry Advanced Options
|
||||
"geometry_toolchangexy": self.ui.geometry_defaults_form.geometry_adv_opt_group.toolchangexy_entry,
|
||||
"geometry_startz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gstartz_entry,
|
||||
"geometry_endz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gendz_entry,
|
||||
"geometry_feedrate_rapid": self.ui.geometry_defaults_form.geometry_adv_opt_group.cncfeedrate_rapid_entry,
|
||||
"geometry_extracut": self.ui.geometry_defaults_form.geometry_adv_opt_group.extracut_cb,
|
||||
"geometry_z_pdepth": self.ui.geometry_defaults_form.geometry_adv_opt_group.pdepth_entry,
|
||||
"geometry_feedrate_probe": self.ui.geometry_defaults_form.geometry_adv_opt_group.feedrate_probe_entry,
|
||||
"geometry_spindledir": self.ui.geometry_defaults_form.geometry_adv_opt_group.spindledir_radio,
|
||||
"geometry_f_plunge": self.ui.geometry_defaults_form.geometry_adv_opt_group.fplunge_cb,
|
||||
"geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
|
||||
"geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
|
||||
|
@ -613,8 +617,6 @@ class App(QtCore.QObject):
|
|||
"cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
|
||||
"cncjob_plot_kind": self.ui.cncjob_defaults_form.cncjob_gen_group.cncplot_method_radio,
|
||||
"cncjob_annotation": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_cb,
|
||||
"cncjob_annotation_fontsize": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontsize_sp,
|
||||
"cncjob_annotation_fontcolor": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry,
|
||||
|
||||
"cncjob_tooldia": self.ui.cncjob_defaults_form.cncjob_gen_group.tooldia_entry,
|
||||
"cncjob_coords_type": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_type_radio,
|
||||
|
@ -629,6 +631,8 @@ class App(QtCore.QObject):
|
|||
# CNC Job Advanced Options
|
||||
"cncjob_toolchange_macro": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_text,
|
||||
"cncjob_toolchange_macro_enable": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_cb,
|
||||
"cncjob_annotation_fontsize": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontsize_sp,
|
||||
"cncjob_annotation_fontcolor": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry,
|
||||
|
||||
# NCC Tool
|
||||
"tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
|
||||
|
@ -677,6 +681,7 @@ class App(QtCore.QObject):
|
|||
"tools_film_type": self.ui.tools_defaults_form.tools_film_group.film_type_radio,
|
||||
"tools_film_boundary": self.ui.tools_defaults_form.tools_film_group.film_boundary_entry,
|
||||
"tools_film_scale": self.ui.tools_defaults_form.tools_film_group.film_scale_entry,
|
||||
"tools_film_color": self.ui.tools_defaults_form.tools_film_group.film_color_entry,
|
||||
|
||||
# Panelize Tool
|
||||
"tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns,
|
||||
|
@ -846,6 +851,22 @@ class App(QtCore.QObject):
|
|||
"global_point_clipboard_format": "(%.4f, %.4f)",
|
||||
"global_zdownrate": None,
|
||||
|
||||
# autocomplete keywords
|
||||
"global_autocomplete_keywords":
|
||||
['all', 'angle_x', 'angle_y', 'axis', 'axisoffset', 'box', 'center_x', 'center_y',
|
||||
'columns', 'combine', 'connect', 'contour', 'depthperpass', 'dia', 'diatol', 'dist',
|
||||
'drilled_dias', 'drillz', 'pp',
|
||||
'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'margin', 'method',
|
||||
'milled_dias',
|
||||
'minoffset', 'multidepth', 'name', 'offset', 'opt_type', 'order', 'outname',
|
||||
'overlap', 'passes', 'postamble', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref',
|
||||
'rest', 'rows', 'scale_factor', 'spacing_columns', 'spacing_rows', 'spindlespeed',
|
||||
'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move',
|
||||
'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin',
|
||||
'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual',
|
||||
'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy', 'iso_type',
|
||||
'Desktop', 'FlatPrj', 'FlatConfig', 'Users', 'Documents', 'My Documents', 'Marius'
|
||||
],
|
||||
# General GUI Settings
|
||||
"global_hover": False,
|
||||
"global_selection_shape": True,
|
||||
|
@ -857,9 +878,6 @@ class App(QtCore.QObject):
|
|||
"gerber_multicolored": False,
|
||||
"gerber_circle_steps": 128,
|
||||
"gerber_use_buffer_for_union": True,
|
||||
"gerber_buffering": "full",
|
||||
"gerber_simplification": False,
|
||||
"gerber_simp_tolerance": 0.0005,
|
||||
|
||||
# Gerber Options
|
||||
"gerber_isotooldia": 0.00787402,
|
||||
|
@ -877,6 +895,9 @@ class App(QtCore.QObject):
|
|||
"gerber_aperture_scale_factor": 1.0,
|
||||
"gerber_aperture_buffer_factor": 0.0,
|
||||
"gerber_follow": False,
|
||||
"gerber_buffering": "full",
|
||||
"gerber_simplification": False,
|
||||
"gerber_simp_tolerance": 0.0005,
|
||||
|
||||
# Gerber Export
|
||||
"gerber_exp_units": 'IN',
|
||||
|
@ -917,9 +938,9 @@ class App(QtCore.QObject):
|
|||
# Excellon Options
|
||||
"excellon_drillz": -0.0590551,
|
||||
"excellon_travelz": 0.0787402,
|
||||
"excellon_endz": 0.5,
|
||||
"excellon_feedrate": 3.14961,
|
||||
"excellon_spindlespeed": None,
|
||||
"excellon_spindledir": 'CW',
|
||||
"excellon_dwell": False,
|
||||
"excellon_dwelltime": 1,
|
||||
"excellon_toolchange": False,
|
||||
|
@ -933,10 +954,10 @@ class App(QtCore.QObject):
|
|||
"excellon_offset": 0.0,
|
||||
"excellon_toolchangexy": "0.0, 0.0",
|
||||
"excellon_startz": None,
|
||||
"excellon_endz": 0.5,
|
||||
"excellon_feedrate_rapid": 31.4961,
|
||||
"excellon_z_pdepth": -0.02,
|
||||
"excellon_feedrate_probe": 3.14961,
|
||||
"excellon_spindledir": 'CW',
|
||||
"excellon_f_plunge": False,
|
||||
"excellon_f_retract": False,
|
||||
|
||||
|
@ -983,10 +1004,10 @@ class App(QtCore.QObject):
|
|||
"geometry_travelz": 0.0787402,
|
||||
"geometry_toolchange": False,
|
||||
"geometry_toolchangez": 0.5,
|
||||
"geometry_endz": 0.5,
|
||||
"geometry_feedrate": 3.14961,
|
||||
"geometry_feedrate_z": 3.14961,
|
||||
"geometry_spindlespeed": None,
|
||||
"geometry_spindledir": 'CW',
|
||||
"geometry_dwell": False,
|
||||
"geometry_dwelltime": 1,
|
||||
"geometry_ppname_g": 'default',
|
||||
|
@ -994,11 +1015,11 @@ class App(QtCore.QObject):
|
|||
# Geometry Advanced Options
|
||||
"geometry_toolchangexy": "0.0, 0.0",
|
||||
"geometry_startz": None,
|
||||
"geometry_endz": 0.5,
|
||||
"geometry_feedrate_rapid": 3.14961,
|
||||
"geometry_extracut": False,
|
||||
"geometry_z_pdepth": -0.02,
|
||||
"geometry_f_plunge": False,
|
||||
"geometry_spindledir": 'CW',
|
||||
"geometry_feedrate_probe": 3.14961,
|
||||
"geometry_segx": 0.0,
|
||||
"geometry_segy": 0.0,
|
||||
|
@ -1010,8 +1031,6 @@ class App(QtCore.QObject):
|
|||
"cncjob_plot": True,
|
||||
"cncjob_plot_kind": 'all',
|
||||
"cncjob_annotation": True,
|
||||
"cncjob_annotation_fontsize": 9,
|
||||
"cncjob_annotation_fontcolor": '#990000',
|
||||
"cncjob_tooldia": 0.0393701,
|
||||
"cncjob_coords_type": "G90",
|
||||
"cncjob_coords_decimals": 4,
|
||||
|
@ -1025,7 +1044,10 @@ class App(QtCore.QObject):
|
|||
# CNC Job Advanced Options
|
||||
"cncjob_toolchange_macro": "",
|
||||
"cncjob_toolchange_macro_enable": False,
|
||||
"cncjob_annotation_fontsize": 9,
|
||||
"cncjob_annotation_fontcolor": '#990000',
|
||||
|
||||
# NCC Tool
|
||||
"tools_ncctools": "0.0393701, 0.019685",
|
||||
"tools_nccorder": 'rev',
|
||||
"tools_nccoverlap": 0.015748,
|
||||
|
@ -1044,6 +1066,7 @@ class App(QtCore.QObject):
|
|||
"tools_ncctipdia": 0.00393701,
|
||||
"tools_ncctipangle": 30,
|
||||
|
||||
# Cutout Tool
|
||||
"tools_cutouttooldia": 0.0944882,
|
||||
"tools_cutoutkind": "single",
|
||||
"tools_cutoutmargin": 0.00393701,
|
||||
|
@ -1051,6 +1074,7 @@ class App(QtCore.QObject):
|
|||
"tools_gaps_ff": "4",
|
||||
"tools_cutout_convexshape": False,
|
||||
|
||||
# Paint Tool
|
||||
"tools_painttooldia": 0.023622,
|
||||
"tools_paintorder": 'rev',
|
||||
"tools_paintoverlap": 0.015748,
|
||||
|
@ -1061,14 +1085,18 @@ class App(QtCore.QObject):
|
|||
"tools_paintcontour": True,
|
||||
"tools_paint_plotting": 'normal',
|
||||
|
||||
# 2-Sided Tool
|
||||
"tools_2sided_mirror_axis": "X",
|
||||
"tools_2sided_axis_loc": "point",
|
||||
"tools_2sided_drilldia": 0.0393701,
|
||||
|
||||
# Film Tool
|
||||
"tools_film_type": 'neg',
|
||||
"tools_film_boundary": 0.0393701,
|
||||
"tools_film_scale": 0,
|
||||
"tools_film_color": '#000000',
|
||||
|
||||
# Panel Tool
|
||||
"tools_panelize_spacing_columns": 0,
|
||||
"tools_panelize_spacing_rows": 0,
|
||||
"tools_panelize_columns": 1,
|
||||
|
@ -1078,6 +1106,7 @@ class App(QtCore.QObject):
|
|||
"tools_panelize_constrainy": 0.0,
|
||||
"tools_panelize_panel_type": 'gerber',
|
||||
|
||||
# Calculators Tool
|
||||
"tools_calc_vshape_tip_dia": 0.007874,
|
||||
"tools_calc_vshape_tip_angle": 30,
|
||||
"tools_calc_vshape_cut_z": 0.000787,
|
||||
|
@ -1086,6 +1115,7 @@ class App(QtCore.QObject):
|
|||
"tools_calc_electro_cdensity": 13.0,
|
||||
"tools_calc_electro_growth": 10.0,
|
||||
|
||||
# Transform Tool
|
||||
"tools_transform_rotate": 90,
|
||||
"tools_transform_skew_x": 0.0,
|
||||
"tools_transform_skew_y": 0.0,
|
||||
|
@ -1098,6 +1128,7 @@ class App(QtCore.QObject):
|
|||
"tools_transform_mirror_reference": False,
|
||||
"tools_transform_mirror_point": (0, 0),
|
||||
|
||||
# SolderPaste Tool
|
||||
"tools_solderpaste_tools": "0.0393701, 0.011811",
|
||||
"tools_solderpaste_new": 0.011811,
|
||||
"tools_solderpaste_z_start": 0.00019685039,
|
||||
|
@ -1115,6 +1146,7 @@ class App(QtCore.QObject):
|
|||
"tools_solderpaste_dwellrev": 1,
|
||||
"tools_solderpaste_pp": 'Paste_1',
|
||||
|
||||
# Subtract Tool
|
||||
"tools_sub_close_paths": True,
|
||||
|
||||
# file associations
|
||||
|
@ -1204,9 +1236,9 @@ class App(QtCore.QObject):
|
|||
|
||||
"excellon_drillz": self.ui.excellon_options_form.excellon_opt_group.cutz_entry,
|
||||
"excellon_travelz": self.ui.excellon_options_form.excellon_opt_group.travelz_entry,
|
||||
"excellon_endz": self.ui.excellon_options_form.excellon_opt_group.eendz_entry,
|
||||
"excellon_feedrate": self.ui.excellon_options_form.excellon_opt_group.feedrate_entry,
|
||||
"excellon_spindlespeed": self.ui.excellon_options_form.excellon_opt_group.spindlespeed_entry,
|
||||
"excellon_spindledir": self.ui.excellon_options_form.excellon_opt_group.spindledir_radio,
|
||||
"excellon_dwell": self.ui.excellon_options_form.excellon_opt_group.dwell_cb,
|
||||
"excellon_dwelltime": self.ui.excellon_options_form.excellon_opt_group.dwelltime_entry,
|
||||
"excellon_toolchange": self.ui.excellon_options_form.excellon_opt_group.toolchange_cb,
|
||||
|
@ -1218,7 +1250,7 @@ class App(QtCore.QObject):
|
|||
"excellon_toolchangexy": self.ui.excellon_options_form.excellon_adv_opt_group.toolchangexy_entry,
|
||||
"excellon_f_plunge": self.ui.excellon_options_form.excellon_adv_opt_group.fplunge_cb,
|
||||
"excellon_startz": self.ui.excellon_options_form.excellon_adv_opt_group.estartz_entry,
|
||||
"excellon_endz": self.ui.excellon_options_form.excellon_adv_opt_group.eendz_entry,
|
||||
"excellon_spindledir": self.ui.excellon_options_form.excellon_adv_opt_group.spindledir_radio,
|
||||
|
||||
"geometry_plot": self.ui.geometry_options_form.geometry_gen_group.plot_cb,
|
||||
"geometry_cnctooldia": self.ui.geometry_options_form.geometry_gen_group.cnctooldia_entry,
|
||||
|
@ -1228,12 +1260,12 @@ class App(QtCore.QObject):
|
|||
"geometry_feedrate": self.ui.geometry_options_form.geometry_opt_group.cncfeedrate_entry,
|
||||
"geometry_feedrate_z": self.ui.geometry_options_form.geometry_opt_group.cncplunge_entry,
|
||||
"geometry_spindlespeed": self.ui.geometry_options_form.geometry_opt_group.cncspindlespeed_entry,
|
||||
"geometry_spindledir": self.ui.geometry_options_form.geometry_opt_group.spindledir_radio,
|
||||
"geometry_dwell": self.ui.geometry_options_form.geometry_opt_group.dwell_cb,
|
||||
"geometry_dwelltime": self.ui.geometry_options_form.geometry_opt_group.dwelltime_entry,
|
||||
"geometry_ppname_g": self.ui.geometry_options_form.geometry_opt_group.pp_geometry_name_cb,
|
||||
"geometry_toolchange": self.ui.geometry_options_form.geometry_opt_group.toolchange_cb,
|
||||
"geometry_toolchangez": self.ui.geometry_options_form.geometry_opt_group.toolchangez_entry,
|
||||
"geometry_endz": self.ui.geometry_options_form.geometry_opt_group.gendz_entry,
|
||||
"geometry_depthperpass": self.ui.geometry_options_form.geometry_opt_group.depthperpass_entry,
|
||||
"geometry_multidepth": self.ui.geometry_options_form.geometry_opt_group.multidepth_cb,
|
||||
|
||||
|
@ -1241,9 +1273,9 @@ class App(QtCore.QObject):
|
|||
"geometry_segy": self.ui.geometry_options_form.geometry_adv_opt_group.segy_entry,
|
||||
"geometry_feedrate_rapid": self.ui.geometry_options_form.geometry_adv_opt_group.cncfeedrate_rapid_entry,
|
||||
"geometry_f_plunge": self.ui.geometry_options_form.geometry_adv_opt_group.fplunge_cb,
|
||||
"geometry_spindledir": self.ui.geometry_options_form.geometry_adv_opt_group.spindledir_radio,
|
||||
"geometry_toolchangexy": self.ui.geometry_options_form.geometry_adv_opt_group.toolchangexy_entry,
|
||||
"geometry_startz": self.ui.geometry_options_form.geometry_adv_opt_group.gstartz_entry,
|
||||
"geometry_endz": self.ui.geometry_options_form.geometry_adv_opt_group.gendz_entry,
|
||||
"geometry_extracut": self.ui.geometry_options_form.geometry_adv_opt_group.extracut_cb,
|
||||
|
||||
"cncjob_plot": self.ui.cncjob_options_form.cncjob_gen_group.plot_cb,
|
||||
|
@ -1487,10 +1519,17 @@ class App(QtCore.QObject):
|
|||
"background-color:%s" % str(self.defaults['global_proj_item_dis_color'])[:7])
|
||||
|
||||
# Init the Annotation CNC Job color
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.set_value(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.set_value(
|
||||
self.defaults['cncjob_annotation_fontcolor'])
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
|
||||
"background-color:%s" % str(self.defaults['cncjob_annotation_fontcolor'])[:7])
|
||||
|
||||
# Init the Tool Film color
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_entry.set_value(
|
||||
self.defaults['tools_film_color'])
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
|
||||
"background-color:%s" % str(self.defaults['tools_film_color'])[:7])
|
||||
|
||||
# ### End of Data ####
|
||||
|
||||
# ###############################################
|
||||
|
@ -1671,6 +1710,9 @@ class App(QtCore.QObject):
|
|||
self.ui.menuhelp_about.triggered.connect(self.on_about)
|
||||
self.ui.menuhelp_home.triggered.connect(lambda: webbrowser.open(self.app_url))
|
||||
self.ui.menuhelp_manual.triggered.connect(lambda: webbrowser.open(self.manual_url))
|
||||
self.ui.menuhelp_report_bug.triggered.connect(lambda: webbrowser.open(self.bug_report_url))
|
||||
self.ui.menuhelp_exc_spec.triggered.connect(lambda: webbrowser.open(self.excellon_spec_url))
|
||||
self.ui.menuhelp_gerber_spec.triggered.connect(lambda: webbrowser.open(self.gerber_spec_url))
|
||||
self.ui.menuhelp_videohelp.triggered.connect(lambda: webbrowser.open(self.video_url))
|
||||
self.ui.menuhelp_shortcut_list.triggered.connect(self.on_shortcut_list)
|
||||
|
||||
|
@ -1809,11 +1851,17 @@ class App(QtCore.QObject):
|
|||
# ########## CNC Job related signals #############
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.tc_variable_combo.currentIndexChanged[str].connect(
|
||||
self.on_cnc_custom_parameters)
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.editingFinished.connect(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.editingFinished.connect(
|
||||
self.on_annotation_fontcolor_entry)
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.clicked.connect(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.clicked.connect(
|
||||
self.on_annotation_fontcolor_button)
|
||||
|
||||
# ########## Tools related signals #############
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_entry.editingFinished.connect(
|
||||
self.on_film_color_entry)
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_button.clicked.connect(
|
||||
self.on_film_color_button)
|
||||
|
||||
# ########## Modify G-CODE Plot Area TAB ###########
|
||||
self.ui.code_editor.textChanged.connect(self.handleTextChanged)
|
||||
self.ui.buttonOpen.clicked.connect(self.handleOpen)
|
||||
|
@ -1830,7 +1878,7 @@ class App(QtCore.QObject):
|
|||
self.collection.view.activated.connect(self.on_row_activated)
|
||||
|
||||
# Monitor the checkbox from the Application Defaults Tab and show the TCL shell or not depending on it's value
|
||||
self.ui.general_defaults_form.general_app_group.shell_startup_cb.clicked.connect(self.on_toggle_shell)
|
||||
self.ui.general_defaults_form.general_gui_set_group.shell_startup_cb.clicked.connect(self.on_toggle_shell)
|
||||
|
||||
# Make sure that when the Excellon loading parameters are changed, the change is reflected in the
|
||||
# Export Excellon parameters.
|
||||
|
@ -1900,27 +1948,13 @@ class App(QtCore.QObject):
|
|||
'mirror', 'ncc',
|
||||
'ncc_clear', 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset',
|
||||
'open_excellon', 'open_gcode', 'open_gerber', 'open_project', 'options', 'paint',
|
||||
'pan', 'panel', 'panelize', 'plot', 'save', 'save_project', 'save_sys', 'scale',
|
||||
'pan', 'panel', 'panelize', 'plot_all', 'plot_objects', 'save', 'save_project',
|
||||
'save_sys', 'scale',
|
||||
'set_active', 'set_sys', 'setsys', 'skew', 'subtract_poly', 'subtract_rectangle',
|
||||
'version', 'write_gcode'
|
||||
]
|
||||
|
||||
self.ordinary_keywords = ['all', 'angle_x', 'angle_y', 'axis', 'axisoffset', 'box', 'center_x', 'center_y',
|
||||
'columns', 'combine', 'connect', 'contour', 'depthperpass', 'dia', 'diatol', 'dist',
|
||||
'drilled_dias', 'drillz', 'pp',
|
||||
'endz', 'extracut', 'factor', 'False', 'false', 'feedrate', 'feedrate_rapid',
|
||||
'filename', 'follow', 'gaps', 'gapsize', 'grid', 'gridoffset', 'gridoffsetx',
|
||||
'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'margin', 'method',
|
||||
'milled_dias',
|
||||
'minoffset', 'multidepth', 'name', 'offset', 'opt_type', 'order', 'outname',
|
||||
'overlap', 'passes', 'postamble', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref',
|
||||
'rest', 'rows', 'scale_factor', 'spacing_columns', 'spacing_rows', 'spindlespeed',
|
||||
'toolchange', 'toolchangez', 'tooldia', 'tools', 'travelz', 'True', 'true', 'type',
|
||||
'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move',
|
||||
'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin',
|
||||
'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual',
|
||||
'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy'
|
||||
]
|
||||
self.ordinary_keywords = self.defaults["global_autocomplete_keywords"]
|
||||
|
||||
self.tcl_keywords = [
|
||||
'after', 'append', 'apply', 'argc', 'argv', 'argv0', 'array', 'attemptckalloc', 'attemptckrealloc',
|
||||
|
@ -2255,6 +2289,10 @@ class App(QtCore.QObject):
|
|||
# Variable to store the GCODE that was edited
|
||||
self.gcode_edited = ""
|
||||
|
||||
# reference for the self.ui.code_editor
|
||||
self.reference_code_editor = None
|
||||
self.script_code = ''
|
||||
|
||||
# if Preferences are changed in the Edit -> Preferences tab the value will be set to True
|
||||
self.preferences_changed_flag = False
|
||||
|
||||
|
@ -3064,8 +3102,8 @@ class App(QtCore.QObject):
|
|||
result = self.exec_command_test(text, False)
|
||||
|
||||
# MS: added this method call so the geometry is updated once the TCL command is executed
|
||||
if no_plot is None:
|
||||
self.plot_all()
|
||||
# if no_plot is None:
|
||||
# self.plot_all()
|
||||
|
||||
return result
|
||||
|
||||
|
@ -5554,8 +5592,8 @@ class App(QtCore.QObject):
|
|||
|
||||
def on_annotation_fontcolor_entry(self):
|
||||
self.defaults['cncjob_annotation_fontcolor'] = \
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.get_value()
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.get_value()
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
|
||||
"background-color:%s" % str(self.defaults['cncjob_annotation_fontcolor']))
|
||||
|
||||
def on_annotation_fontcolor_button(self):
|
||||
|
@ -5567,12 +5605,38 @@ class App(QtCore.QObject):
|
|||
if annotation_color.isValid() is False:
|
||||
return
|
||||
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
|
||||
"background-color:%s" % str(annotation_color.name()))
|
||||
|
||||
new_val_sel = str(annotation_color.name())
|
||||
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.set_value(new_val_sel)
|
||||
self.defaults['global_proj_item_dis_color'] = new_val_sel
|
||||
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.set_value(new_val_sel)
|
||||
self.defaults['cncjob_annotation_fontcolor'] = new_val_sel
|
||||
|
||||
def on_film_color_entry(self):
|
||||
self.defaults['tools_film_color'] = \
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_entry.get_value()
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
|
||||
"background-color:%s" % str(self.defaults['tools_film_color']))
|
||||
|
||||
def on_film_color_button(self):
|
||||
current_color = QtGui.QColor(self.defaults['tools_film_color'])
|
||||
|
||||
c_dialog = QtWidgets.QColorDialog()
|
||||
film_color = c_dialog.getColor(initial=current_color)
|
||||
|
||||
if film_color.isValid() is False:
|
||||
return
|
||||
|
||||
# if new color is different then mark that the Preferences are changed
|
||||
if film_color != current_color:
|
||||
self.on_preferences_edited()
|
||||
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
|
||||
"background-color:%s" % str(film_color.name()))
|
||||
|
||||
new_val_sel = str(film_color.name())
|
||||
self.ui.tools_defaults_form.tools_film_group.film_color_entry.set_value(new_val_sel)
|
||||
self.defaults['tools_film_color'] = new_val_sel
|
||||
|
||||
def on_splash_changed(self, state):
|
||||
settings = QSettings("Open Source", "FlatCAM")
|
||||
|
@ -5915,11 +5979,11 @@ class App(QtCore.QObject):
|
|||
if self.ui.shell_dock.isHidden():
|
||||
self.ui.shell_dock.show()
|
||||
|
||||
script_code = self.ui.code_editor.toPlainText()
|
||||
self.script_code = deepcopy(self.ui.code_editor.toPlainText())
|
||||
# self.shell._sysShell.exec_command(script_code)
|
||||
|
||||
old_line = ''
|
||||
for tcl_command_line in script_code.splitlines():
|
||||
for tcl_command_line in self.script_code.splitlines():
|
||||
# do not process lines starting with '#' = comment and empty lines
|
||||
if not tcl_command_line.startswith('#') and tcl_command_line != '':
|
||||
# id FlatCAM is run in Windows then replace all the slashes with
|
||||
|
@ -5942,17 +6006,16 @@ class App(QtCore.QObject):
|
|||
self.shell.append_output(result + '\n')
|
||||
|
||||
old_line = ''
|
||||
except tk.TclError as e:
|
||||
except tk.TclError:
|
||||
old_line = old_line + tcl_command_line + '\n'
|
||||
except Exception as e:
|
||||
log.debug("App.handleRunCode() --> %s" % str(e))
|
||||
|
||||
if old_line != '':
|
||||
# it means that the script finished with an error
|
||||
result = self.tcl.eval("set errorInfo")
|
||||
self.log.error("Exec command Exception: %s" % (result + '\n'))
|
||||
self.shell.append_error('ERROR: ' + result + '\n')
|
||||
else:
|
||||
# success! plot all objects
|
||||
self.plot_all()
|
||||
|
||||
self.shell.close_proccessing()
|
||||
|
||||
|
@ -7522,7 +7585,7 @@ class App(QtCore.QObject):
|
|||
self.inform.emit('[success] %s...' %
|
||||
_("New Project created"))
|
||||
|
||||
def on_file_new(self):
|
||||
def on_file_new(self, cli=None):
|
||||
"""
|
||||
Callback for menu item File->New. Returns the application to its
|
||||
startup state. This method is thread-safe.
|
||||
|
@ -7582,15 +7645,16 @@ class App(QtCore.QObject):
|
|||
# Init Tools
|
||||
self.init_tools()
|
||||
|
||||
# Close any Tabs opened in the Plot Tab Area section
|
||||
for index in range(self.ui.plot_tab_area.count()):
|
||||
self.ui.plot_tab_area.closeTab(index)
|
||||
# for whatever reason previous command does not close the last tab so I do it manually
|
||||
self.ui.plot_tab_area.closeTab(0)
|
||||
if cli is None:
|
||||
# Close any Tabs opened in the Plot Tab Area section
|
||||
for index in range(self.ui.plot_tab_area.count()):
|
||||
self.ui.plot_tab_area.closeTab(index)
|
||||
# for whatever reason previous command does not close the last tab so I do it manually
|
||||
self.ui.plot_tab_area.closeTab(0)
|
||||
|
||||
# # And then add again the Plot Area
|
||||
self.ui.plot_tab_area.addTab(self.ui.plot_tab, "Plot Area")
|
||||
self.ui.plot_tab_area.protectTab(0)
|
||||
# # And then add again the Plot Area
|
||||
self.ui.plot_tab_area.addTab(self.ui.plot_tab, "Plot Area")
|
||||
self.ui.plot_tab_area.protectTab(0)
|
||||
|
||||
# take the focus of the Notebook on Project Tab.
|
||||
self.ui.notebook.setCurrentWidget(self.ui.project_tab)
|
||||
|
@ -8201,6 +8265,9 @@ class App(QtCore.QObject):
|
|||
self.ui.code_editor.completer_enable = False
|
||||
self.ui.buttonRun.hide()
|
||||
|
||||
# make sure to keep a reference to the code editor
|
||||
self.reference_code_editor = self.ui.code_editor
|
||||
|
||||
# Switch plot_area to CNCJob tab
|
||||
self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab)
|
||||
|
||||
|
@ -8219,20 +8286,37 @@ class App(QtCore.QObject):
|
|||
|
||||
if obj.kind == 'gerber':
|
||||
flt = "Gerber Files (*.GBR);;All Files (*.*)"
|
||||
else:
|
||||
elif obj.kind == 'excellon':
|
||||
flt = "Excellon Files (*.DRL);;All Files (*.*)"
|
||||
elif obj.kind == 'cncjob':
|
||||
"GCode Files (*.NC);;All Files (*.*)"
|
||||
else:
|
||||
flt = "All Files (*.*)"
|
||||
|
||||
self.init_code_editor(name=_("Source Editor"))
|
||||
self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt))
|
||||
self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt))
|
||||
|
||||
# then append the text from GCode to the text editor
|
||||
try:
|
||||
file = StringIO(obj.source_file)
|
||||
except AttributeError:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("There is no selected object for which to see it's source file code."))
|
||||
return 'fail'
|
||||
if obj.kind == 'cncjob':
|
||||
try:
|
||||
file = obj.export_gcode(
|
||||
preamble=self.defaults["cncjob_prepend"],
|
||||
postamble=self.defaults["cncjob_append"],
|
||||
to_file=True)
|
||||
if file == 'fail':
|
||||
return 'fail'
|
||||
except AttributeError:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("There is no selected object for which to see it's source file code."))
|
||||
return 'fail'
|
||||
else:
|
||||
try:
|
||||
file = StringIO(obj.source_file)
|
||||
except AttributeError:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("There is no selected object for which to see it's source file code."))
|
||||
return 'fail'
|
||||
|
||||
self.ui.cncjob_frame.hide()
|
||||
try:
|
||||
|
@ -8289,6 +8373,10 @@ class App(QtCore.QObject):
|
|||
self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt))
|
||||
self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt))
|
||||
self.ui.buttonRun.show()
|
||||
try:
|
||||
self.ui.buttonRun.clicked.disconnect(self.handleRunCode)
|
||||
except TypeError:
|
||||
pass
|
||||
self.ui.buttonRun.clicked.connect(self.handleRunCode)
|
||||
|
||||
self.handleTextChanged()
|
||||
|
@ -8556,8 +8644,6 @@ class App(QtCore.QObject):
|
|||
def make_negative_film():
|
||||
exported_svg = obj.export_svg(scale_factor=scale_factor)
|
||||
|
||||
self.progress.emit(40)
|
||||
|
||||
# Determine bounding area for svg export
|
||||
bounds = box.bounds()
|
||||
size = box.size()
|
||||
|
@ -8583,8 +8669,6 @@ class App(QtCore.QObject):
|
|||
svg_header += '<g transform="scale(1,-1)">'
|
||||
svg_footer = '</g> </svg>'
|
||||
|
||||
self.progress.emit(60)
|
||||
|
||||
# Change the attributes of the exported SVG
|
||||
# We don't need stroke-width - wrong, we do when we have lines with certain width
|
||||
# We set opacity to maximum
|
||||
|
@ -8613,7 +8697,6 @@ class App(QtCore.QObject):
|
|||
exported_svg = ET.tostring(root)
|
||||
|
||||
svg_elem = svg_header + str(exported_svg) + svg_footer
|
||||
self.progress.emit(80)
|
||||
|
||||
# Parse the xml through a xml parser just to add line feeds
|
||||
# and to make it look more pretty for the output
|
||||
|
@ -8627,7 +8710,6 @@ class App(QtCore.QObject):
|
|||
"Most likely another app is holding the file open and not accessible."))
|
||||
return 'fail'
|
||||
|
||||
self.progress.emit(100)
|
||||
if self.defaults["global_open_style"] is False:
|
||||
self.file_opened.emit("SVG", filename)
|
||||
self.file_saved.emit("SVG", filename)
|
||||
|
@ -8649,7 +8731,7 @@ class App(QtCore.QObject):
|
|||
else:
|
||||
make_negative_film()
|
||||
|
||||
def export_svg_black(self, obj_name, box_name, filename, scale_factor=0.00, use_thread=True):
|
||||
def export_svg_positive(self, obj_name, box_name, filename, scale_factor=0.00, use_thread=True):
|
||||
"""
|
||||
Exports a Geometry Object to an SVG file in positive black.
|
||||
|
||||
|
@ -8660,7 +8742,7 @@ class App(QtCore.QObject):
|
|||
:param use_thread: if to be run in a separate thread; boolean
|
||||
:return:
|
||||
"""
|
||||
self.report_usage("export_svg_black()")
|
||||
self.report_usage("export_svg_positive()")
|
||||
|
||||
if filename is None:
|
||||
filename = self.defaults["global_last_save_folder"]
|
||||
|
@ -8684,7 +8766,7 @@ class App(QtCore.QObject):
|
|||
(_("No object Box. Using instead"), obj))
|
||||
box = obj
|
||||
|
||||
def make_black_film():
|
||||
def make_positive_film():
|
||||
exported_svg = obj.export_svg(scale_factor=scale_factor)
|
||||
|
||||
self.progress.emit(40)
|
||||
|
@ -8695,9 +8777,9 @@ class App(QtCore.QObject):
|
|||
# We set the colour to WHITE
|
||||
root = ET.fromstring(exported_svg)
|
||||
for child in root:
|
||||
child.set('fill', '#000000')
|
||||
child.set('fill', str(self.defaults['tools_film_color']))
|
||||
child.set('opacity', '1.0')
|
||||
child.set('stroke', '#000000')
|
||||
child.set('stroke', str(self.defaults['tools_film_color']))
|
||||
|
||||
exported_svg = ET.tostring(root)
|
||||
|
||||
|
@ -8765,7 +8847,7 @@ class App(QtCore.QObject):
|
|||
|
||||
def job_thread_film(app_obj):
|
||||
try:
|
||||
make_black_film()
|
||||
make_positive_film()
|
||||
except Exception as e:
|
||||
proc.done()
|
||||
return
|
||||
|
@ -8773,7 +8855,7 @@ class App(QtCore.QObject):
|
|||
|
||||
self.worker_task.emit({'fcn': job_thread_film, 'params': [self]})
|
||||
else:
|
||||
make_black_film()
|
||||
make_positive_film()
|
||||
|
||||
def save_source_file(self, obj_name, filename, use_thread=True):
|
||||
"""
|
||||
|
@ -9375,7 +9457,7 @@ class App(QtCore.QObject):
|
|||
self.inform.emit('[success] %s: %s' %
|
||||
(_("Opened"), filename))
|
||||
|
||||
def open_excellon(self, filename, outname=None):
|
||||
def open_excellon(self, filename, outname=None, plot=True):
|
||||
"""
|
||||
Opens an Excellon file, parses it and creates a new object for
|
||||
it in the program. Thread-safe.
|
||||
|
@ -9429,7 +9511,7 @@ class App(QtCore.QObject):
|
|||
|
||||
# Object name
|
||||
name = outname or filename.split('/')[-1].split('\\')[-1]
|
||||
ret_val = self.new_object("excellon", name, obj_init, autoselected=False)
|
||||
ret_val = self.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
|
||||
if ret_val == 'fail':
|
||||
self.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_('Open Excellon file failed. Probable not an Excellon file.'))
|
||||
|
@ -9442,7 +9524,7 @@ class App(QtCore.QObject):
|
|||
self.inform.emit('[success] %s: %s' %
|
||||
(_("Opened"), filename))
|
||||
|
||||
def open_gcode(self, filename, outname=None):
|
||||
def open_gcode(self, filename, outname=None, plot=True):
|
||||
"""
|
||||
Opens a G-gcode file, parses it and creates a new object for
|
||||
it in the program. Thread-safe.
|
||||
|
@ -9494,7 +9576,7 @@ class App(QtCore.QObject):
|
|||
name = outname or filename.split('/')[-1].split('\\')[-1]
|
||||
|
||||
# New object creation and file processing
|
||||
ret = self.new_object("cncjob", name, obj_init, autoselected=False)
|
||||
ret = self.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
|
||||
if ret == 'fail':
|
||||
self.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Failed to create CNCJob Object. Probable not a GCode file.\n "
|
||||
|
@ -9542,7 +9624,7 @@ class App(QtCore.QObject):
|
|||
(_("Failed to open config file"), filename))
|
||||
return
|
||||
|
||||
def open_project(self, filename, run_from_arg=None):
|
||||
def open_project(self, filename, run_from_arg=None, plot=True, cli=None):
|
||||
"""
|
||||
Loads a project from the specified file.
|
||||
|
||||
|
@ -9551,16 +9633,21 @@ class App(QtCore.QObject):
|
|||
3) Calls on_file_new()
|
||||
4) Updates options
|
||||
5) Calls new_object() with the object's from_dict() as init method.
|
||||
6) Calls plot_all()
|
||||
6) Calls plot_all() if plot=True
|
||||
|
||||
:param filename: Name of the file from which to load.
|
||||
:type filename: str
|
||||
:param run_from_arg: True if run for arguments
|
||||
:param plot: If True plot all objects in the project
|
||||
:param cli: run from command line
|
||||
:return: None
|
||||
"""
|
||||
App.log.debug("Opening project: " + filename)
|
||||
|
||||
self.set_ui_title(name=_("Loading Project ... Please Wait ..."))
|
||||
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
|
||||
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
|
||||
if cli is None:
|
||||
self.set_ui_title(name=_("Loading Project ... Please Wait ..."))
|
||||
|
||||
# Open and parse an uncompressed Project file
|
||||
try:
|
||||
|
@ -9583,7 +9670,6 @@ class App(QtCore.QObject):
|
|||
with lzma.open(filename) as f:
|
||||
file_content = f.read().decode('utf-8')
|
||||
d = json.loads(file_content, object_hook=dict2obj)
|
||||
|
||||
except Exception as e:
|
||||
App.log.error("Failed to open project file: %s with error: %s" % (filename, str(e)))
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s' %
|
||||
|
@ -9594,13 +9680,19 @@ class App(QtCore.QObject):
|
|||
# # NOT THREAD SAFE # ##
|
||||
if run_from_arg is True:
|
||||
pass
|
||||
elif cli is True:
|
||||
self.delete_selection_shape()
|
||||
else:
|
||||
self.on_file_new()
|
||||
|
||||
# Project options
|
||||
self.options.update(d['options'])
|
||||
self.project_filename = filename
|
||||
self.set_screen_units(self.options["units"])
|
||||
|
||||
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
|
||||
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
|
||||
if cli is None:
|
||||
self.set_screen_units(self.options["units"])
|
||||
|
||||
# Re create objects
|
||||
App.log.debug(" **************** Started PROEJCT loading... **************** ")
|
||||
|
@ -9608,24 +9700,31 @@ class App(QtCore.QObject):
|
|||
for obj in d['objs']:
|
||||
def obj_init(obj_inst, app_inst):
|
||||
obj_inst.from_dict(obj)
|
||||
|
||||
App.log.debug("Recreating from opened project an %s object: %s" %
|
||||
(obj['kind'].capitalize(), obj['options']['name']))
|
||||
|
||||
self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"),
|
||||
obj['kind'].upper(),
|
||||
obj['options']['name']
|
||||
)
|
||||
)
|
||||
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
|
||||
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
|
||||
if cli is None:
|
||||
self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"),
|
||||
obj['kind'].upper(),
|
||||
obj['options']['name']
|
||||
)
|
||||
)
|
||||
|
||||
self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=True)
|
||||
self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=plot)
|
||||
|
||||
# self.plot_all()
|
||||
self.inform.emit('[success] %s: %s' %
|
||||
(_("Project loaded from"), filename))
|
||||
|
||||
self.should_we_save = False
|
||||
self.file_opened.emit("project", filename)
|
||||
self.set_ui_title(name=self.project_filename)
|
||||
|
||||
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
|
||||
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
|
||||
if cli is None:
|
||||
self.set_ui_title(name=self.project_filename)
|
||||
|
||||
App.log.debug(" **************** Finished PROJECT loading... **************** ")
|
||||
|
||||
|
|
116
FlatCAMObj.py
116
FlatCAMObj.py
|
@ -600,7 +600,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# Show/Hide Advanced Options
|
||||
if self.app.defaults["global_app_level"] == 'b':
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:green;"><b>Basic</b></span>'
|
||||
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
|
||||
))
|
||||
self.ui.apertures_table_label.hide()
|
||||
self.ui.aperture_table_visibility_cb.hide()
|
||||
|
@ -613,7 +613,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
self.ui.except_cb.hide()
|
||||
else:
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:red;"><b>Advanced</b></span>'
|
||||
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
|
||||
))
|
||||
|
||||
if self.app.defaults["gerber_buffering"] == 'no':
|
||||
|
@ -923,8 +923,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
||||
def isolate(self, iso_type=None, dia=None, passes=None, overlap=None,
|
||||
outname=None, combine=None, milling_type=None, follow=None):
|
||||
def isolate(self, iso_type=None, dia=None, passes=None, overlap=None, outname=None, combine=None,
|
||||
milling_type=None, follow=None, plot=True):
|
||||
"""
|
||||
Creates an isolation routing geometry object in the project.
|
||||
|
||||
|
@ -947,13 +947,13 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
combine = bool(combine)
|
||||
if milling_type is None:
|
||||
milling_type = self.options["milling_type"]
|
||||
|
||||
if iso_type is None:
|
||||
self.iso_type = 2
|
||||
else:
|
||||
self.iso_type = iso_type
|
||||
|
||||
base_name = self.options["name"] + "_iso"
|
||||
base_name = outname or base_name
|
||||
base_name = self.options["name"]
|
||||
|
||||
def generate_envelope(offset, invert, envelope_iso_type=2, follow=None, passes=0):
|
||||
# isolation_geometry produces an envelope that is going on the left of the geometry
|
||||
|
@ -1061,12 +1061,15 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
return new_geometry
|
||||
|
||||
if combine:
|
||||
if self.iso_type == 0:
|
||||
iso_name = self.options["name"] + "_ext_iso"
|
||||
elif self.iso_type == 1:
|
||||
iso_name = self.options["name"] + "_int_iso"
|
||||
if outname is None:
|
||||
if self.iso_type == 0:
|
||||
iso_name = base_name + "_ext_iso"
|
||||
elif self.iso_type == 1:
|
||||
iso_name = base_name + "_int_iso"
|
||||
else:
|
||||
iso_name = base_name + "_iso"
|
||||
else:
|
||||
iso_name = base_name
|
||||
iso_name = outname
|
||||
|
||||
# TODO: This is ugly. Create way to pass data into init function.
|
||||
def iso_init(geo_obj, app_obj):
|
||||
|
@ -1161,25 +1164,31 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
self.app.new_object("geometry", iso_name, iso_init)
|
||||
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
|
||||
else:
|
||||
for i in range(passes):
|
||||
|
||||
offset = dia * ((2 * i + 1) / 2.0) - (i * overlap * dia)
|
||||
if passes > 1:
|
||||
if self.iso_type == 0:
|
||||
iso_name = self.options["name"] + "_ext_iso" + str(i + 1)
|
||||
elif self.iso_type == 1:
|
||||
iso_name = self.options["name"] + "_int_iso" + str(i + 1)
|
||||
if outname is None:
|
||||
if self.iso_type == 0:
|
||||
iso_name = base_name + "_ext_iso" + str(i + 1)
|
||||
elif self.iso_type == 1:
|
||||
iso_name = base_name + "_int_iso" + str(i + 1)
|
||||
else:
|
||||
iso_name = base_name + "_iso" + str(i + 1)
|
||||
else:
|
||||
iso_name = base_name + str(i + 1)
|
||||
iso_name = outname
|
||||
else:
|
||||
if self.iso_type == 0:
|
||||
iso_name = self.options["name"] + "_ext_iso"
|
||||
elif self.iso_type == 1:
|
||||
iso_name = self.options["name"] + "_int_iso"
|
||||
if outname is None:
|
||||
if self.iso_type == 0:
|
||||
iso_name = base_name + "_ext_iso"
|
||||
elif self.iso_type == 1:
|
||||
iso_name = base_name + "_int_iso"
|
||||
else:
|
||||
iso_name = base_name + "_iso"
|
||||
else:
|
||||
iso_name = base_name
|
||||
iso_name = outname
|
||||
|
||||
# TODO: This is ugly. Create way to pass data into init function.
|
||||
def iso_init(geo_obj, app_obj):
|
||||
|
@ -1230,7 +1239,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
self.app.new_object("geometry", iso_name, iso_init)
|
||||
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
|
||||
|
||||
def on_plot_cb_click(self, *args):
|
||||
if self.muted_ui:
|
||||
|
@ -2316,14 +2325,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
# Show/Hide Advanced Options
|
||||
if self.app.defaults["global_app_level"] == 'b':
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:green;"><b>Basic</b></span>'
|
||||
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
|
||||
))
|
||||
|
||||
self.ui.tools_table.setColumnHidden(4, True)
|
||||
self.ui.estartz_label.hide()
|
||||
self.ui.estartz_entry.hide()
|
||||
self.ui.eendz_label.hide()
|
||||
self.ui.eendz_entry.hide()
|
||||
self.ui.feedrate_rapid_label.hide()
|
||||
self.ui.feedrate_rapid_entry.hide()
|
||||
self.ui.pdepth_label.hide()
|
||||
|
@ -2332,7 +2339,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
self.ui.feedrate_probe_entry.hide()
|
||||
else:
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:red;"><b>Advanced</b></span>'
|
||||
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
|
||||
))
|
||||
|
||||
assert isinstance(self.ui, ExcellonObjectUI), \
|
||||
|
@ -2595,7 +2602,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
|
||||
return has_slots, excellon_code
|
||||
|
||||
def generate_milling_drills(self, tools=None, outname=None, tooldia=None, use_thread=False):
|
||||
def generate_milling_drills(self, tools=None, outname=None, tooldia=None, plot=False, use_thread=False):
|
||||
"""
|
||||
Note: This method is a good template for generic operations as
|
||||
it takes it's options from parameters or otherwise from the
|
||||
|
@ -2674,7 +2681,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
Point(hole['point']).buffer(buffer_value).exterior)
|
||||
if use_thread:
|
||||
def geo_thread(app_obj):
|
||||
app_obj.new_object("geometry", outname, geo_init)
|
||||
app_obj.new_object("geometry", outname, geo_init, plot=plot)
|
||||
app_obj.progress.emit(100)
|
||||
|
||||
# Create a promise with the new name
|
||||
|
@ -2683,11 +2690,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
# Send to worker
|
||||
self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
|
||||
else:
|
||||
self.app.new_object("geometry", outname, geo_init)
|
||||
self.app.new_object("geometry", outname, geo_init, plot=plot)
|
||||
|
||||
return True, ""
|
||||
|
||||
def generate_milling_slots(self, tools=None, outname=None, tooldia=None, use_thread=False):
|
||||
def generate_milling_slots(self, tools=None, outname=None, tooldia=None, plot=True, use_thread=False):
|
||||
"""
|
||||
Note: This method is a good template for generic operations as
|
||||
it takes it's options from parameters or otherwise from the
|
||||
|
@ -2781,7 +2788,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
|
||||
if use_thread:
|
||||
def geo_thread(app_obj):
|
||||
app_obj.new_object("geometry", outname + '_slot', geo_init)
|
||||
app_obj.new_object("geometry", outname + '_slot', geo_init, plot=plot)
|
||||
app_obj.progress.emit(100)
|
||||
|
||||
# Create a promise with the new name
|
||||
|
@ -2790,7 +2797,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
# Send to worker
|
||||
self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
|
||||
else:
|
||||
self.app.new_object("geometry", outname + '_slot', geo_init)
|
||||
self.app.new_object("geometry", outname + '_slot', geo_init, plot=plot)
|
||||
|
||||
return True, ""
|
||||
|
||||
|
@ -3596,7 +3603,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# Show/Hide Advanced Options
|
||||
if self.app.defaults["global_app_level"] == 'b':
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:green;"><b>Basic</b></span>'
|
||||
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
|
||||
))
|
||||
|
||||
self.ui.geo_tools_table.setColumnHidden(2, True)
|
||||
|
@ -3607,8 +3614,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.addtool_btn.hide()
|
||||
self.ui.copytool_btn.hide()
|
||||
self.ui.deltool_btn.hide()
|
||||
self.ui.endzlabel.hide()
|
||||
self.ui.gendz_entry.hide()
|
||||
# self.ui.endzlabel.hide()
|
||||
# self.ui.gendz_entry.hide()
|
||||
self.ui.fr_rapidlabel.hide()
|
||||
self.ui.cncfeedrate_rapid_entry.hide()
|
||||
self.ui.extracut_cb.hide()
|
||||
|
@ -3618,7 +3625,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.feedrate_probe_entry.hide()
|
||||
else:
|
||||
self.ui.level.setText(_(
|
||||
'<span style="color:red;"><b>Advanced</b></span>'
|
||||
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
|
||||
))
|
||||
self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
|
||||
self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
|
||||
|
@ -4518,7 +4525,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Failed. No tool selected in the tool table ..."))
|
||||
|
||||
def mtool_gen_cncjob(self, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None, use_thread=True):
|
||||
def mtool_gen_cncjob(self, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None,
|
||||
plot=True, use_thread=True):
|
||||
"""
|
||||
Creates a multi-tool CNCJob out of this Geometry object.
|
||||
The actual work is done by the target FlatCAMCNCjob object's
|
||||
|
@ -4875,7 +4883,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
def job_thread(app_obj):
|
||||
if self.solid_geometry:
|
||||
with self.app.proc_container.new(_("Generating CNC Code")):
|
||||
if app_obj.new_object("cncjob", outname, job_init_single_geometry) != 'fail':
|
||||
if app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
|
||||
app_obj.inform.emit('[success] %s: %s' %
|
||||
(_("CNCjob created")), outname)
|
||||
app_obj.progress.emit(100)
|
||||
|
@ -4892,22 +4900,23 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
else:
|
||||
if self.solid_geometry:
|
||||
self.app.new_object("cncjob", outname, job_init_single_geometry)
|
||||
self.app.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
|
||||
else:
|
||||
self.app.new_object("cncjob", outname, job_init_multi_geometry)
|
||||
self.app.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
|
||||
|
||||
def generatecncjob(
|
||||
self, outname=None,
|
||||
tooldia=None, offset=None,
|
||||
dia=None, offset=None,
|
||||
z_cut=None, z_move=None,
|
||||
feedrate=None, feedrate_z=None, feedrate_rapid=None,
|
||||
spindlespeed=None, dwell=None, dwelltime=None,
|
||||
multidepth=None, depthperpass=None,
|
||||
toolchange=None, toolchangez=None, toolchangexy=None,
|
||||
extracut=None, startz=None, endz=None,
|
||||
ppname_g=None,
|
||||
pp=None,
|
||||
segx=None, segy=None,
|
||||
use_thread=True):
|
||||
use_thread=True,
|
||||
plot=True):
|
||||
"""
|
||||
Only used for TCL Command.
|
||||
Creates a CNCJob out of this Geometry object. The actual
|
||||
|
@ -4919,14 +4928,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
:param feedrate: Feed rate while cutting on X - Y plane
|
||||
:param feedrate_z: Feed rate while cutting on Z plane
|
||||
:param feedrate_rapid: Feed rate while moving with rapids
|
||||
:param tooldia: Tool diameter
|
||||
:param dia: Tool diameter
|
||||
:param outname: Name of the new object
|
||||
:param spindlespeed: Spindle speed (RPM)
|
||||
:param ppname_g Name of the postprocessor
|
||||
:param pp Name of the postprocessor
|
||||
:return: None
|
||||
"""
|
||||
|
||||
tooldia = tooldia if tooldia else float(self.options["cnctooldia"])
|
||||
tooldia = dia if dia else float(self.options["cnctooldia"])
|
||||
outname = outname if outname is not None else self.options["name"]
|
||||
|
||||
z_cut = z_cut if z_cut is not None else float(self.options["cutz"])
|
||||
|
@ -4957,7 +4966,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
dwell = dwell if dwell else self.options["dwell"]
|
||||
dwelltime = dwelltime if dwelltime else float(self.options["dwelltime"])
|
||||
|
||||
ppname_g = ppname_g if ppname_g else self.options["ppname_g"]
|
||||
ppname_g = pp if pp else self.options["ppname_g"]
|
||||
|
||||
# Object initialization function for app.new_object()
|
||||
# RUNNING ON SEPARATE THREAD!
|
||||
|
@ -5034,7 +5043,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# To be run in separate thread
|
||||
def job_thread(app_obj):
|
||||
with self.app.proc_container.new(_("Generating CNC Code")):
|
||||
app_obj.new_object("cncjob", outname, job_init)
|
||||
app_obj.new_object("cncjob", outname, job_init, plot=plot)
|
||||
app_obj.inform.emit('[success] %s: %s' %
|
||||
(_("CNCjob created")), outname)
|
||||
app_obj.progress.emit(100)
|
||||
|
@ -5044,7 +5053,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# Send to worker
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
else:
|
||||
self.app.new_object("cncjob", outname, job_init)
|
||||
self.app.new_object("cncjob", outname, job_init, plot=plot)
|
||||
|
||||
# def on_plot_cb_click(self, *args): # TODO: args not needed
|
||||
# if self.muted_ui:
|
||||
|
@ -5833,11 +5842,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
|
||||
preamble = str(self.ui.prepend_text.get_value())
|
||||
postamble = str(self.ui.append_text.get_value())
|
||||
gc = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
|
||||
if gc == 'fail':
|
||||
|
||||
gco = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
|
||||
if gco == 'fail':
|
||||
return
|
||||
else:
|
||||
self.app.gcode_edited = gc
|
||||
self.app.gcode_edited = gco
|
||||
|
||||
self.app.init_code_editor(name=_("Code Editor"))
|
||||
self.app.ui.buttonOpen.clicked.connect(self.app.handleOpen)
|
||||
|
|
|
@ -320,7 +320,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
self.app.ui.menuprojectgeneratecnc.setVisible(False)
|
||||
if type(obj) != FlatCAMGeometry and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMGerber:
|
||||
self.app.ui.menuprojectedit.setVisible(False)
|
||||
if type(obj) != FlatCAMGerber and type(obj) != FlatCAMExcellon:
|
||||
if type(obj) != FlatCAMGerber and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMCNCjob:
|
||||
self.app.ui.menuprojectviewsource.setVisible(False)
|
||||
else:
|
||||
self.app.ui.menuprojectgeneratecnc.setVisible(False)
|
||||
|
|
24
README.md
24
README.md
|
@ -9,6 +9,18 @@ CAD program, and create G-Code for Isolation routing.
|
|||
|
||||
=================================================
|
||||
|
||||
16.09.2019
|
||||
|
||||
- modified the TclCommand New so it will no longer close all tabs when called (it closed the Code Editor tab which may have been holding the code that run)
|
||||
- fixed the App.on_view_source() method for CNCJob objects: the Gcode will now contain the Prepend and Append code from the Edit -> Preferences -> CNCJob -> CNCJob Options
|
||||
- added a new parameter named 'muted' for the TclCommands: cncjob, drillcncjob and write_gcode. Setting it as -muted 1 will disable the error reporting in TCL Shell
|
||||
- some GUI optimizations
|
||||
- more GUI optimizations related to being part of the Advanced category or not
|
||||
- added possibility to change the positive SVG exported file color in Tool Film
|
||||
- fixed some issues recently introduced in the TclCommands CNCJob, DrillCNCJob and write_gcode; changed some parameters names
|
||||
- fixed issue in the Laser postprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start
|
||||
- added new links in Menu -> Help (Excellon, Gerber specifications and a Report Bug)
|
||||
|
||||
15.09.2019
|
||||
|
||||
- refactored FlatCAMGeometry.mtool_gen_cncjob() method
|
||||
|
@ -19,6 +31,18 @@ CAD program, and create G-Code for Isolation routing.
|
|||
- finished updating the TclCommand cncjob to work for multi-geo Geometry objects with the parameters from the args
|
||||
- fixed the TclCommand cncjob to use the -outname parameter
|
||||
- added some more keywords in the data_model for auto-completer
|
||||
- fixed isolate TclCommand to use correctly the -outname parameter
|
||||
- added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source
|
||||
- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects
|
||||
- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects
|
||||
- modified the TclCommands so that open files do not plot the opened files automatically
|
||||
- made all TclCommands not to be plotted automatically
|
||||
- made sure that all TclCommands are not threaded
|
||||
- added new TclCommands: NewExcellon, NewGerber
|
||||
- fixed the TclCommand open_project
|
||||
- added the outname parameter (and established an default name when outname not used) for the AlignDrillGrid and AlignDrill TclCommands
|
||||
- fixed Scripts repeating multiple time when the Code Editor is used. This repetition was correlated with multiple openings of the Code Editor window (especially after an error)
|
||||
- added the autocomplete keywords that can be changed to the defaults dictionary
|
||||
|
||||
14.09.2019
|
||||
|
||||
|
|
54
camlib.py
54
camlib.py
|
@ -5685,10 +5685,11 @@ class CNCjob(Geometry):
|
|||
must_visit.remove(nearest)
|
||||
return path
|
||||
|
||||
def generate_from_excellon_by_tool(self, exobj, tools="all", drillz = 3.0,
|
||||
toolchange=False, toolchangez=0.1, toolchangexy='',
|
||||
endz=2.0, startz=None,
|
||||
excellon_optimization_type='B'):
|
||||
def generate_from_excellon_by_tool(
|
||||
self, exobj, tools="all", drillz = 3.0,
|
||||
toolchange=False, toolchangez=0.1, toolchangexy='',
|
||||
endz=2.0, startz=None,
|
||||
excellon_optimization_type='B'):
|
||||
"""
|
||||
Creates gcode for this object from an Excellon object
|
||||
for the specified tools.
|
||||
|
@ -6482,11 +6483,18 @@ class CNCjob(Geometry):
|
|||
# self.gcode += self.doformat(p.toolchange_code)
|
||||
self.gcode += self.doformat(p.toolchange_code)
|
||||
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
if 'laser' not in self.pp_geometry_name:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
else:
|
||||
# for laser this will disable the laser
|
||||
self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height
|
||||
|
||||
if self.dwell is True:
|
||||
self.gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
else:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
if 'laser' not in self.pp_geometry_name:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
|
||||
if self.dwell is True:
|
||||
self.gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
|
@ -6589,15 +6597,16 @@ class CNCjob(Geometry):
|
|||
)
|
||||
return self.gcode
|
||||
|
||||
def generate_from_geometry_2(self, geometry, append=True,
|
||||
tooldia=None, offset=0.0, tolerance=0,
|
||||
z_cut=1.0, z_move=2.0,
|
||||
feedrate=2.0, feedrate_z=2.0, feedrate_rapid=30,
|
||||
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0,
|
||||
multidepth=False, depthpercut=None,
|
||||
toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0",
|
||||
extracut=False, startz=None, endz=2.0,
|
||||
pp_geometry_name=None, tool_no=1):
|
||||
def generate_from_geometry_2(
|
||||
self, geometry, append=True,
|
||||
tooldia=None, offset=0.0, tolerance=0,
|
||||
z_cut=1.0, z_move=2.0,
|
||||
feedrate=2.0, feedrate_z=2.0, feedrate_rapid=30,
|
||||
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0,
|
||||
multidepth=False, depthpercut=None,
|
||||
toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0",
|
||||
extracut=False, startz=None, endz=2.0,
|
||||
pp_geometry_name=None, tool_no=1):
|
||||
"""
|
||||
Second algorithm to generate from Geometry.
|
||||
|
||||
|
@ -6825,13 +6834,18 @@ class CNCjob(Geometry):
|
|||
# self.gcode += self.doformat(p.toolchange_code)
|
||||
self.gcode += self.doformat(p.toolchange_code)
|
||||
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
if 'laser' not in self.pp_geometry_name:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
else:
|
||||
# for laser this will disable the laser
|
||||
self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height
|
||||
|
||||
if self.dwell is True:
|
||||
self.gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
else:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
if 'laser' not in self.pp_geometry_name:
|
||||
self.gcode += self.doformat(p.spindle_code) # Spindle start
|
||||
|
||||
if self.dwell is True:
|
||||
self.gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
|
@ -7247,7 +7261,7 @@ class CNCjob(Geometry):
|
|||
|
||||
match_lsr_pos = re.search(r"^(M0[3|5])", gline)
|
||||
if match_lsr_pos:
|
||||
if match_lsr_pos.group(1) == 'M05':
|
||||
if 'M05' in match_lsr_pos.group(1):
|
||||
# the value does not matter, only that it is positive so the gcode_parse() know it is > 0,
|
||||
# therefore the move is of kind T (travel)
|
||||
command['Z'] = 1
|
||||
|
@ -7316,7 +7330,7 @@ class CNCjob(Geometry):
|
|||
pass
|
||||
elif 'hpgl' in self.pp_excellon_name or 'hpgl' in self.pp_geometry_name:
|
||||
pass
|
||||
elif 'grbl_laser' in self.pp_excellon_name or 'grbl_laser' in self.pp_geometry_name:
|
||||
elif 'laser' in self.pp_excellon_name or 'laser' in self.pp_geometry_name:
|
||||
pass
|
||||
elif ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
|
||||
if self.pp_geometry_name == 'line_xyz' or self.pp_excellon_name == 'line_xyz':
|
||||
|
|
|
@ -400,6 +400,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share/globe16.png'), _('Online Help\tF1'))
|
||||
self.menuhelp_home = self.menuhelp.addAction(QtGui.QIcon('share/home16.png'), _('FlatCAM.org'))
|
||||
self.menuhelp.addSeparator()
|
||||
self.menuhelp_report_bug = self.menuhelp.addAction(QtGui.QIcon('share/bug16.png'), _('Report a bug'))
|
||||
self.menuhelp.addSeparator()
|
||||
self.menuhelp_exc_spec = self.menuhelp.addAction(QtGui.QIcon('share/pdf_link16.png'),
|
||||
_('Excellon Specification'))
|
||||
self.menuhelp_gerber_spec = self.menuhelp.addAction(QtGui.QIcon('share/pdf_link16.png'),
|
||||
_('Gerber Specification'))
|
||||
|
||||
self.menuhelp.addSeparator()
|
||||
|
||||
self.menuhelp_shortcut_list = self.menuhelp.addAction(QtGui.QIcon('share/shortcuts24.png'),
|
||||
_('Shortcuts List\tF3'))
|
||||
self.menuhelp_videohelp = self.menuhelp.addAction(QtGui.QIcon('share/youtube32.png'), _('YouTube Channel\tF4')
|
||||
|
@ -2044,7 +2053,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
|
||||
def eventFilter(self, obj, event):
|
||||
# filter the ToolTips display based on a Preferences setting
|
||||
if self.general_defaults_form.general_app_group.toggle_tooltips_cb.get_value() is False:
|
||||
if self.general_defaults_form.general_gui_set_group.toggle_tooltips_cb.get_value() is False:
|
||||
if event.type() == QtCore.QEvent.ToolTip:
|
||||
return True
|
||||
else:
|
||||
|
@ -4026,6 +4035,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
|
|||
)
|
||||
self.selection_cb = FCCheckBox()
|
||||
|
||||
# Notebook Font Size
|
||||
self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
|
||||
self.notebook_font_size_label.setToolTip(
|
||||
_("This sets the font size for the elements found in the Notebook.\n"
|
||||
|
@ -4074,6 +4084,56 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
|
|||
else:
|
||||
self.splash_cb.set_value(False)
|
||||
|
||||
# Shell StartUp CB
|
||||
self.shell_startup_label = QtWidgets.QLabel('%s:' % _('Shell at StartUp'))
|
||||
self.shell_startup_label.setToolTip(
|
||||
_("Check this box if you want the shell to\n"
|
||||
"start automatically at startup.")
|
||||
)
|
||||
self.shell_startup_cb = FCCheckBox(label='')
|
||||
self.shell_startup_cb.setToolTip(
|
||||
_("Check this box if you want the shell to\n"
|
||||
"start automatically at startup.")
|
||||
)
|
||||
|
||||
# Project at StartUp CB
|
||||
self.project_startup_label = QtWidgets.QLabel('%s:' % _('Project at StartUp'))
|
||||
self.project_startup_label.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"to be shown automatically at startup.")
|
||||
)
|
||||
self.project_startup_cb = FCCheckBox(label='')
|
||||
self.project_startup_cb.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"to be shown automatically at startup.")
|
||||
)
|
||||
|
||||
# Project autohide CB
|
||||
self.project_autohide_label = QtWidgets.QLabel('%s:' % _('Project AutoHide'))
|
||||
self.project_autohide_label.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"hide automatically when there are no objects loaded and\n"
|
||||
"to show whenever a new object is created.")
|
||||
)
|
||||
self.project_autohide_cb = FCCheckBox(label='')
|
||||
self.project_autohide_cb.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"hide automatically when there are no objects loaded and\n"
|
||||
"to show whenever a new object is created.")
|
||||
)
|
||||
|
||||
# Enable/Disable ToolTips globally
|
||||
self.toggle_tooltips_label = QtWidgets.QLabel('<b>%s:</b>' % _('Enable ToolTips'))
|
||||
self.toggle_tooltips_label.setToolTip(
|
||||
_("Check this box if you want to have toolTips displayed\n"
|
||||
"when hovering with mouse over items throughout the App.")
|
||||
)
|
||||
self.toggle_tooltips_cb = FCCheckBox(label='')
|
||||
self.toggle_tooltips_cb.setToolTip(
|
||||
_("Check this box if you want to have toolTips displayed\n"
|
||||
"when hovering with mouse over items throughout the App.")
|
||||
)
|
||||
|
||||
# Add (label - input field) pair to the QFormLayout
|
||||
self.form_box.addRow(self.spacelabel, self.spacelabel)
|
||||
|
||||
|
@ -4088,11 +4148,27 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
|
|||
self.form_box.addRow(self.axis_font_size_label, self.axis_font_size_spinner)
|
||||
self.form_box.addRow(QtWidgets.QLabel(''))
|
||||
self.form_box.addRow(self.splash_label, self.splash_cb)
|
||||
self.form_box.addRow(self.shell_startup_label, self.shell_startup_cb)
|
||||
self.form_box.addRow(self.project_startup_label, self.project_startup_cb)
|
||||
self.form_box.addRow(self.project_autohide_label, self.project_autohide_cb)
|
||||
self.form_box.addRow(QtWidgets.QLabel(''))
|
||||
self.form_box.addRow(self.toggle_tooltips_label, self.toggle_tooltips_cb)
|
||||
|
||||
# Add the QFormLayout that holds the Application general defaults
|
||||
# to the main layout of this TAB
|
||||
self.layout.addLayout(self.form_box)
|
||||
|
||||
# Delete confirmation
|
||||
self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
|
||||
self.delete_conf_cb.setToolTip(
|
||||
_("When checked the application will ask for user confirmation\n"
|
||||
"whenever the Delete object(s) event is triggered, either by\n"
|
||||
"menu shortcut or key shortcut.")
|
||||
)
|
||||
self.layout.addWidget(self.delete_conf_cb)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
def handle_style(self, style):
|
||||
# set current style
|
||||
settings = QSettings("Open Source", "FlatCAM")
|
||||
|
@ -4141,7 +4217,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
|
|||
self.form_box = QtWidgets.QFormLayout()
|
||||
|
||||
# Units for FlatCAM
|
||||
self.unitslabel = QtWidgets.QLabel('<b>%s:</b>' % _('Units'))
|
||||
self.unitslabel = QtWidgets.QLabel('<span style="color:red;"><b>%s:</b></span>' % _('Units'))
|
||||
self.unitslabel.setToolTip(_("The default value for FlatCAM units.\n"
|
||||
"Whatever is selected here is set every time\n"
|
||||
"FLatCAM is started."))
|
||||
|
@ -4180,18 +4256,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
|
|||
"security features. In this case the language will be\n"
|
||||
"applied at the next app start."))
|
||||
|
||||
# Shell StartUp CB
|
||||
self.shell_startup_label = QtWidgets.QLabel('%s:' % _('Shell at StartUp'))
|
||||
self.shell_startup_label.setToolTip(
|
||||
_("Check this box if you want the shell to\n"
|
||||
"start automatically at startup.")
|
||||
)
|
||||
self.shell_startup_cb = FCCheckBox(label='')
|
||||
self.shell_startup_cb.setToolTip(
|
||||
_("Check this box if you want the shell to\n"
|
||||
"start automatically at startup.")
|
||||
)
|
||||
|
||||
# Version Check CB
|
||||
self.version_check_label = QtWidgets.QLabel('%s:' % _('Version Check'))
|
||||
self.version_check_label.setToolTip(
|
||||
|
@ -4232,43 +4296,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
|
|||
self.mselect_radio = RadioSet([{'label': _('CTRL'), 'value': 'Control'},
|
||||
{'label': _('SHIFT'), 'value': 'Shift'}])
|
||||
|
||||
# Project at StartUp CB
|
||||
self.project_startup_label = QtWidgets.QLabel('%s:' % _('Project at StartUp'))
|
||||
self.project_startup_label.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"to be shown automatically at startup.")
|
||||
)
|
||||
self.project_startup_cb = FCCheckBox(label='')
|
||||
self.project_startup_cb.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"to be shown automatically at startup.")
|
||||
)
|
||||
|
||||
# Project autohide CB
|
||||
self.project_autohide_label = QtWidgets.QLabel('%s:' % _('Project AutoHide'))
|
||||
self.project_autohide_label.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"hide automatically when there are no objects loaded and\n"
|
||||
"to show whenever a new object is created.")
|
||||
)
|
||||
self.project_autohide_cb = FCCheckBox(label='')
|
||||
self.project_autohide_cb.setToolTip(
|
||||
_("Check this box if you want the project/selected/tool tab area to\n"
|
||||
"hide automatically when there are no objects loaded and\n"
|
||||
"to show whenever a new object is created.")
|
||||
)
|
||||
|
||||
# Enable/Disable ToolTips globally
|
||||
self.toggle_tooltips_label = QtWidgets.QLabel('<b>%s:</b>' % _('Enable ToolTips'))
|
||||
self.toggle_tooltips_label.setToolTip(
|
||||
_("Check this box if you want to have toolTips displayed\n"
|
||||
"when hovering with mouse over items throughout the App.")
|
||||
)
|
||||
self.toggle_tooltips_cb = FCCheckBox(label='')
|
||||
self.toggle_tooltips_cb.setToolTip(
|
||||
_("Check this box if you want to have toolTips displayed\n"
|
||||
"when hovering with mouse over items throughout the App.")
|
||||
)
|
||||
# Worker Numbers
|
||||
self.worker_number_label = QtWidgets.QLabel('%s:' % _('Workers number'))
|
||||
self.worker_number_label.setToolTip(
|
||||
_("The number of Qthreads made available to the App.\n"
|
||||
|
@ -4321,15 +4349,11 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
|
|||
self.form_box.addRow(self.languagespace, self.language_apply_btn)
|
||||
|
||||
self.form_box.addRow(self.spacelabel, self.spacelabel)
|
||||
self.form_box.addRow(self.shell_startup_label, self.shell_startup_cb)
|
||||
self.form_box.addRow(self.version_check_label, self.version_check_cb)
|
||||
self.form_box.addRow(self.send_stats_label, self.send_stats_cb)
|
||||
|
||||
self.form_box.addRow(self.panbuttonlabel, self.pan_button_radio)
|
||||
self.form_box.addRow(self.mselectlabel, self.mselect_radio)
|
||||
self.form_box.addRow(self.project_startup_label, self.project_startup_cb)
|
||||
self.form_box.addRow(self.project_autohide_label, self.project_autohide_cb)
|
||||
self.form_box.addRow(self.toggle_tooltips_label, self.toggle_tooltips_cb)
|
||||
self.form_box.addRow(self.worker_number_label, self.worker_number_sb)
|
||||
self.form_box.addRow(tol_label, self.tol_entry)
|
||||
|
||||
|
@ -4350,15 +4374,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
|
|||
# self.advanced_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
|
||||
self.layout.addWidget(self.open_style_cb)
|
||||
|
||||
# Delete confirmation
|
||||
self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
|
||||
self.delete_conf_cb.setToolTip(
|
||||
_("When checked the application will ask for user confirmation\n"
|
||||
"whenever the Delete object(s) event is triggered, either by\n"
|
||||
"menu shortcut or key shortcut.")
|
||||
)
|
||||
self.layout.addWidget(self.delete_conf_cb)
|
||||
|
||||
# Save compressed project CB
|
||||
self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
|
||||
self.save_type_cb.setToolTip(
|
||||
|
@ -4442,40 +4457,6 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.circle_steps_label, 1, 0)
|
||||
grid0.addWidget(self.circle_steps_entry, 1, 1)
|
||||
|
||||
# Milling Type
|
||||
buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
|
||||
buffering_label.setToolTip(
|
||||
_("Buffering type:\n"
|
||||
"- None --> best performance, fast file loading but no so good display\n"
|
||||
"- Full --> slow file loading but good visuals. This is the default.\n"
|
||||
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
|
||||
)
|
||||
self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
|
||||
{'label': _('Full'), 'value': 'full'}])
|
||||
grid0.addWidget(buffering_label, 2, 0)
|
||||
grid0.addWidget(self.buffering_radio, 2, 1)
|
||||
|
||||
# Simplification
|
||||
self.simplify_cb = FCCheckBox(label=_('Simplify'))
|
||||
self.simplify_cb.setToolTip(_("When checked all the Gerber polygons will be\n"
|
||||
"loaded with simplification having a set tolerance."))
|
||||
grid0.addWidget(self.simplify_cb, 3, 0)
|
||||
|
||||
# Simplification tolerance
|
||||
self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
|
||||
self.simplification_tol_label.setToolTip(_("Tolerance for poligon simplification."))
|
||||
|
||||
self.simplification_tol_spinner = FCDoubleSpinner()
|
||||
self.simplification_tol_spinner.set_precision(5)
|
||||
self.simplification_tol_spinner.setWrapping(True)
|
||||
self.simplification_tol_spinner.setRange(0.00000, 0.01000)
|
||||
self.simplification_tol_spinner.setSingleStep(0.0001)
|
||||
|
||||
grid0.addWidget(self.simplification_tol_label, 4, 0)
|
||||
grid0.addWidget(self.simplification_tol_spinner, 4, 1)
|
||||
self.ois_simplif = OptionalInputSection(self.simplify_cb,
|
||||
[self.simplification_tol_label, self.simplification_tol_spinner],
|
||||
logic=True)
|
||||
self.layout.addStretch()
|
||||
|
||||
|
||||
|
@ -4525,7 +4506,11 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
"A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
|
||||
)
|
||||
grid0.addWidget(overlabel, 2, 0)
|
||||
self.iso_overlap_entry = FloatEntry()
|
||||
self.iso_overlap_entry = FCDoubleSpinner()
|
||||
self.iso_overlap_entry.set_precision(3)
|
||||
self.iso_overlap_entry.setWrapping(True)
|
||||
self.iso_overlap_entry.setRange(0.000, 0.999)
|
||||
self.iso_overlap_entry.setSingleStep(0.1)
|
||||
grid0.addWidget(self.iso_overlap_entry, 2, 1)
|
||||
|
||||
# Milling Type
|
||||
|
@ -4615,7 +4600,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.setTitle(str(_("Gerber Adv. Options")))
|
||||
|
||||
# ## Advanced Gerber Parameters
|
||||
self.adv_param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Advanced Param."))
|
||||
self.adv_param_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.adv_param_label.setToolTip(
|
||||
_("A list of Gerber advanced parameters.\n"
|
||||
"Those parameters are available only for\n"
|
||||
|
@ -4633,7 +4618,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"This means that it will cut through\n"
|
||||
"the middle of the trace.")
|
||||
)
|
||||
grid0.addWidget(self.follow_cb, 0, 0)
|
||||
grid0.addWidget(self.follow_cb, 0, 0, 1, 2)
|
||||
|
||||
# Aperture Table Visibility CB
|
||||
self.aperture_table_visibility_cb = FCCheckBox(label=_('Table Show/Hide'))
|
||||
|
@ -4643,7 +4628,42 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"that are drawn on canvas.")
|
||||
|
||||
)
|
||||
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0)
|
||||
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0, 1, 2)
|
||||
|
||||
# Buffering Type
|
||||
buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
|
||||
buffering_label.setToolTip(
|
||||
_("Buffering type:\n"
|
||||
"- None --> best performance, fast file loading but no so good display\n"
|
||||
"- Full --> slow file loading but good visuals. This is the default.\n"
|
||||
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
|
||||
)
|
||||
self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
|
||||
{'label': _('Full'), 'value': 'full'}])
|
||||
grid0.addWidget(buffering_label, 2, 0)
|
||||
grid0.addWidget(self.buffering_radio, 2, 1)
|
||||
|
||||
# Simplification
|
||||
self.simplify_cb = FCCheckBox(label=_('Simplify'))
|
||||
self.simplify_cb.setToolTip(_("When checked all the Gerber polygons will be\n"
|
||||
"loaded with simplification having a set tolerance."))
|
||||
grid0.addWidget(self.simplify_cb, 3, 0, 1, 2)
|
||||
|
||||
# Simplification tolerance
|
||||
self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
|
||||
self.simplification_tol_label.setToolTip(_("Tolerance for poligon simplification."))
|
||||
|
||||
self.simplification_tol_spinner = FCDoubleSpinner()
|
||||
self.simplification_tol_spinner.set_precision(5)
|
||||
self.simplification_tol_spinner.setWrapping(True)
|
||||
self.simplification_tol_spinner.setRange(0.00000, 0.01000)
|
||||
self.simplification_tol_spinner.setSingleStep(0.0001)
|
||||
|
||||
grid0.addWidget(self.simplification_tol_label, 4, 0)
|
||||
grid0.addWidget(self.simplification_tol_spinner, 4, 1)
|
||||
self.ois_simplif = OptionalInputSection(self.simplify_cb,
|
||||
[self.simplification_tol_label, self.simplification_tol_spinner],
|
||||
logic=True)
|
||||
|
||||
# Scale Aperture Factor
|
||||
# self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
|
||||
|
@ -5141,7 +5161,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
self.update_excellon_cb.setToolTip(
|
||||
"If checked, the Excellon Export settings will be updated with the ones above."
|
||||
)
|
||||
grid2.addWidget(self.update_excellon_cb, 2, 0)
|
||||
grid2.addWidget(self.update_excellon_cb, 2, 0, 1, 2)
|
||||
|
||||
grid2.addWidget(QtWidgets.QLabel(""), 3, 0)
|
||||
|
||||
|
@ -5161,8 +5181,10 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
grid2.addWidget(self.excellon_optimization_label, 5, 0)
|
||||
|
||||
self.excellon_optimization_radio = RadioSet([{'label': _('MH'), 'value': 'M'},
|
||||
{'label': _('Basic'), 'value': 'B'}])
|
||||
self.excellon_optimization_radio = RadioSet([{'label': _('MetaHeuristic'), 'value': 'M'},
|
||||
{'label': _('Basic'), 'value': 'B'},
|
||||
{'label': _('TSA'), 'value': 'T'}],
|
||||
orientation='vertical', stretch=False)
|
||||
self.excellon_optimization_radio.setToolTip(
|
||||
_("This sets the optimization type for the Excellon drill path.\n"
|
||||
"If MH is checked then Google OR-Tools algorithm with MetaHeuristic\n"
|
||||
|
@ -5234,6 +5256,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
grid2 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid2)
|
||||
|
||||
# Cut Z
|
||||
cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
|
||||
cutzlabel.setToolTip(
|
||||
_("Drill depth (negative)\n"
|
||||
|
@ -5243,6 +5266,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.cutz_entry = LengthEntry()
|
||||
grid2.addWidget(self.cutz_entry, 0, 1)
|
||||
|
||||
# Travel Z
|
||||
travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
|
||||
travelzlabel.setToolTip(
|
||||
_("Tool height when travelling\n"
|
||||
|
@ -5271,15 +5295,27 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.toolchangez_entry = LengthEntry()
|
||||
grid2.addWidget(self.toolchangez_entry, 3, 1)
|
||||
|
||||
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate (Plunge)'))
|
||||
# End Move Z
|
||||
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
|
||||
endzlabel.setToolTip(
|
||||
_("Height of the tool after\n"
|
||||
"the last move at the end of the job.")
|
||||
)
|
||||
grid2.addWidget(endzlabel, 4, 0)
|
||||
self.eendz_entry = LengthEntry()
|
||||
grid2.addWidget(self.eendz_entry, 4, 1)
|
||||
|
||||
# Feedrate Z
|
||||
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
|
||||
frlabel.setToolTip(
|
||||
_("Tool speed while drilling\n"
|
||||
"(in units per minute).\n"
|
||||
"So called 'Plunge' feedrate.\n"
|
||||
"This is for linear move G01.")
|
||||
)
|
||||
grid2.addWidget(frlabel, 4, 0)
|
||||
grid2.addWidget(frlabel, 5, 0)
|
||||
self.feedrate_entry = LengthEntry()
|
||||
grid2.addWidget(self.feedrate_entry, 4, 1)
|
||||
grid2.addWidget(self.feedrate_entry, 5, 1)
|
||||
|
||||
# Spindle speed
|
||||
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed'))
|
||||
|
@ -5287,23 +5323,9 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
_("Speed of the spindle\n"
|
||||
"in RPM (optional)")
|
||||
)
|
||||
grid2.addWidget(spdlabel, 5, 0)
|
||||
grid2.addWidget(spdlabel, 6, 0)
|
||||
self.spindlespeed_entry = IntEntry(allow_empty=True)
|
||||
grid2.addWidget(self.spindlespeed_entry, 5, 1)
|
||||
|
||||
# Spindle direction
|
||||
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
|
||||
spindle_dir_label.setToolTip(
|
||||
_("This sets the direction that the spindle is rotating.\n"
|
||||
"It can be either:\n"
|
||||
"- CW = clockwise or\n"
|
||||
"- CCW = counter clockwise")
|
||||
)
|
||||
|
||||
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
|
||||
{'label': _('CCW'), 'value': 'CCW'}])
|
||||
grid2.addWidget(spindle_dir_label, 6, 0)
|
||||
grid2.addWidget(self.spindledir_radio, 6, 1)
|
||||
grid2.addWidget(self.spindlespeed_entry, 6, 1)
|
||||
|
||||
# Dwell
|
||||
dwelllabel = QtWidgets.QLabel('%s:' % _('Dwell'))
|
||||
|
@ -5317,6 +5339,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
self.dwell_cb = FCCheckBox()
|
||||
self.dwelltime_entry = FCEntry()
|
||||
|
||||
grid2.addWidget(dwelllabel, 7, 0)
|
||||
grid2.addWidget(self.dwell_cb, 7, 1)
|
||||
grid2.addWidget(dwelltime, 8, 0)
|
||||
|
@ -5358,7 +5381,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.mill_hole_label.setToolTip(
|
||||
_("Create Geometry for milling holes.")
|
||||
)
|
||||
grid2.addWidget(excellon_gcode_type_label, 11, 0, 1, 2)
|
||||
grid2.addWidget(self.mill_hole_label, 11, 0, 1, 2)
|
||||
|
||||
tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia'))
|
||||
tdlabel.setToolTip(
|
||||
|
@ -5400,12 +5423,13 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
# ## ADVANCED OPTIONS ###
|
||||
# #######################
|
||||
|
||||
self.cncjob_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.cncjob_label.setToolTip(
|
||||
_("Parameters used to create a CNC Job object\n"
|
||||
"for this drill object that are shown when App Level is Advanced.")
|
||||
self.exc_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.exc_label.setToolTip(
|
||||
_("A list of Excellon advanced parameters.\n"
|
||||
"Those parameters are available only for\n"
|
||||
"Advanced App. Level.")
|
||||
)
|
||||
self.layout.addWidget(self.cncjob_label)
|
||||
self.layout.addWidget(self.exc_label)
|
||||
|
||||
grid1 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid1)
|
||||
|
@ -5436,15 +5460,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.estartz_entry = FloatEntry()
|
||||
grid1.addWidget(self.estartz_entry, 2, 1)
|
||||
|
||||
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
|
||||
endzlabel.setToolTip(
|
||||
_("Height of the tool after\n"
|
||||
"the last move at the end of the job.")
|
||||
)
|
||||
grid1.addWidget(endzlabel, 3, 0)
|
||||
self.eendz_entry = LengthEntry()
|
||||
grid1.addWidget(self.eendz_entry, 3, 1)
|
||||
|
||||
# Feedrate Rapids
|
||||
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
|
||||
fr_rapid_label.setToolTip(
|
||||
_("Tool speed while drilling\n"
|
||||
|
@ -5453,9 +5469,9 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"It is useful only for Marlin,\n"
|
||||
"ignore for any other cases.")
|
||||
)
|
||||
grid1.addWidget(fr_rapid_label, 4, 0)
|
||||
grid1.addWidget(fr_rapid_label, 3, 0)
|
||||
self.feedrate_rapid_entry = LengthEntry()
|
||||
grid1.addWidget(self.feedrate_rapid_entry, 4, 1)
|
||||
grid1.addWidget(self.feedrate_rapid_entry, 3, 1)
|
||||
|
||||
# Probe depth
|
||||
self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
|
||||
|
@ -5463,18 +5479,32 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
_("The maximum depth that the probe is allowed\n"
|
||||
"to probe. Negative value, in current units.")
|
||||
)
|
||||
grid1.addWidget(self.pdepth_label, 5, 0)
|
||||
grid1.addWidget(self.pdepth_label, 4, 0)
|
||||
self.pdepth_entry = FCEntry()
|
||||
grid1.addWidget(self.pdepth_entry, 5, 1)
|
||||
grid1.addWidget(self.pdepth_entry, 4, 1)
|
||||
|
||||
# Probe feedrate
|
||||
self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
|
||||
self.feedrate_probe_label.setToolTip(
|
||||
_("The feedrate used while the probe is probing.")
|
||||
)
|
||||
grid1.addWidget(self.feedrate_probe_label, 6, 0)
|
||||
grid1.addWidget(self.feedrate_probe_label, 5, 0)
|
||||
self.feedrate_probe_entry = FCEntry()
|
||||
grid1.addWidget(self.feedrate_probe_entry, 6, 1)
|
||||
grid1.addWidget(self.feedrate_probe_entry, 5, 1)
|
||||
|
||||
# Spindle direction
|
||||
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
|
||||
spindle_dir_label.setToolTip(
|
||||
_("This sets the direction that the spindle is rotating.\n"
|
||||
"It can be either:\n"
|
||||
"- CW = clockwise or\n"
|
||||
"- CCW = counter clockwise")
|
||||
)
|
||||
|
||||
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
|
||||
{'label': _('CCW'), 'value': 'CCW'}])
|
||||
grid1.addWidget(spindle_dir_label, 6, 0)
|
||||
grid1.addWidget(self.spindledir_radio, 6, 1)
|
||||
|
||||
fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
|
||||
fplungelabel.setToolTip(
|
||||
|
@ -6048,15 +6078,25 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
|
|||
self.toolchangez_entry = LengthEntry()
|
||||
grid1.addWidget(self.toolchangez_entry, 5, 1)
|
||||
|
||||
# End move Z
|
||||
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
|
||||
endzlabel.setToolTip(
|
||||
_("Height of the tool after\n"
|
||||
"the last move at the end of the job.")
|
||||
)
|
||||
grid1.addWidget(endzlabel, 6, 0)
|
||||
self.gendz_entry = LengthEntry()
|
||||
grid1.addWidget(self.gendz_entry, 6, 1)
|
||||
|
||||
# Feedrate X-Y
|
||||
frlabel = QtWidgets.QLabel('%s:' % _('Feed Rate X-Y'))
|
||||
frlabel.setToolTip(
|
||||
_("Cutting speed in the XY\n"
|
||||
"plane in units per minute")
|
||||
)
|
||||
grid1.addWidget(frlabel, 6, 0)
|
||||
grid1.addWidget(frlabel, 7, 0)
|
||||
self.cncfeedrate_entry = LengthEntry()
|
||||
grid1.addWidget(self.cncfeedrate_entry, 6, 1)
|
||||
grid1.addWidget(self.cncfeedrate_entry, 7, 1)
|
||||
|
||||
# Feedrate Z (Plunge)
|
||||
frz_label = QtWidgets.QLabel('%s:' % _('Feed Rate Z'))
|
||||
|
@ -6065,9 +6105,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
|
|||
"plane in units per minute.\n"
|
||||
"It is called also Plunge.")
|
||||
)
|
||||
grid1.addWidget(frz_label, 7, 0)
|
||||
grid1.addWidget(frz_label, 8, 0)
|
||||
self.cncplunge_entry = LengthEntry()
|
||||
grid1.addWidget(self.cncplunge_entry, 7, 1)
|
||||
grid1.addWidget(self.cncplunge_entry, 8, 1)
|
||||
|
||||
# Spindle Speed
|
||||
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
|
||||
|
@ -6078,23 +6118,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
|
|||
"this value is the power of laser."
|
||||
)
|
||||
)
|
||||
grid1.addWidget(spdlabel, 8, 0)
|
||||
grid1.addWidget(spdlabel, 9, 0)
|
||||
self.cncspindlespeed_entry = IntEntry(allow_empty=True)
|
||||
grid1.addWidget(self.cncspindlespeed_entry, 8, 1)
|
||||
|
||||
# Spindle direction
|
||||
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
|
||||
spindle_dir_label.setToolTip(
|
||||
_("This sets the direction that the spindle is rotating.\n"
|
||||
"It can be either:\n"
|
||||
"- CW = clockwise or\n"
|
||||
"- CCW = counter clockwise")
|
||||
)
|
||||
|
||||
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
|
||||
{'label': _('CCW'), 'value': 'CCW'}])
|
||||
grid1.addWidget(spindle_dir_label, 9, 0)
|
||||
grid1.addWidget(self.spindledir_radio, 9, 1)
|
||||
grid1.addWidget(self.cncspindlespeed_entry, 9, 1)
|
||||
|
||||
# Dwell
|
||||
self.dwell_cb = FCCheckBox(label='%s:' % _('Dwell'))
|
||||
|
@ -6137,12 +6163,13 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
# ------------------------------
|
||||
# ## Advanced Options
|
||||
# ------------------------------
|
||||
self.cncjob_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.cncjob_label.setToolTip(
|
||||
_("Parameters to create a CNC Job object\n"
|
||||
"tracing the contours of a Geometry object.")
|
||||
self.geo_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.geo_label.setToolTip(
|
||||
_("A list of Geometry advanced parameters.\n"
|
||||
"Those parameters are available only for\n"
|
||||
"Advanced App. Level.")
|
||||
)
|
||||
self.layout.addWidget(self.cncjob_label)
|
||||
self.layout.addWidget(self.geo_label)
|
||||
|
||||
grid1 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid1)
|
||||
|
@ -6166,16 +6193,6 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.gstartz_entry = FloatEntry()
|
||||
grid1.addWidget(self.gstartz_entry, 2, 1)
|
||||
|
||||
# End move Z
|
||||
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
|
||||
endzlabel.setToolTip(
|
||||
_("Height of the tool after\n"
|
||||
"the last move at the end of the job.")
|
||||
)
|
||||
grid1.addWidget(endzlabel, 3, 0)
|
||||
self.gendz_entry = LengthEntry()
|
||||
grid1.addWidget(self.gendz_entry, 3, 1)
|
||||
|
||||
# Feedrate rapids
|
||||
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feed Rate Rapids'))
|
||||
fr_rapid_label.setToolTip(
|
||||
|
@ -6218,6 +6235,20 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.feedrate_probe_entry = FCEntry()
|
||||
grid1.addWidget(self.feedrate_probe_entry, 7, 1)
|
||||
|
||||
# Spindle direction
|
||||
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
|
||||
spindle_dir_label.setToolTip(
|
||||
_("This sets the direction that the spindle is rotating.\n"
|
||||
"It can be either:\n"
|
||||
"- CW = clockwise or\n"
|
||||
"- CCW = counter clockwise")
|
||||
)
|
||||
|
||||
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
|
||||
{'label': _('CCW'), 'value': 'CCW'}])
|
||||
grid1.addWidget(spindle_dir_label, 8, 0)
|
||||
grid1.addWidget(self.spindledir_radio, 8, 1)
|
||||
|
||||
# Fast Move from Z Toolchange
|
||||
fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
|
||||
fplungelabel.setToolTip(
|
||||
|
@ -6227,8 +6258,8 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"WARNING: the move is done at Toolchange X,Y coords.")
|
||||
)
|
||||
self.fplunge_cb = FCCheckBox()
|
||||
grid1.addWidget(fplungelabel, 8, 0)
|
||||
grid1.addWidget(self.fplunge_cb, 8, 1)
|
||||
grid1.addWidget(fplungelabel, 9, 0)
|
||||
grid1.addWidget(self.fplunge_cb, 9, 1)
|
||||
|
||||
# Size of trace segment on X axis
|
||||
segx_label = QtWidgets.QLabel('%s:' % _("Seg. X size"))
|
||||
|
@ -6237,9 +6268,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"Useful for auto-leveling.\n"
|
||||
"A value of 0 means no segmentation on the X axis.")
|
||||
)
|
||||
grid1.addWidget(segx_label, 9, 0)
|
||||
grid1.addWidget(segx_label, 10, 0)
|
||||
self.segx_entry = FCEntry()
|
||||
grid1.addWidget(self.segx_entry, 9, 1)
|
||||
grid1.addWidget(self.segx_entry, 10, 1)
|
||||
|
||||
# Size of trace segment on Y axis
|
||||
segy_label = QtWidgets.QLabel('%s:' % _("Seg. Y size"))
|
||||
|
@ -6248,9 +6279,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"Useful for auto-leveling.\n"
|
||||
"A value of 0 means no segmentation on the Y axis.")
|
||||
)
|
||||
grid1.addWidget(segy_label, 10, 0)
|
||||
grid1.addWidget(segy_label, 11, 0)
|
||||
self.segy_entry = FCEntry()
|
||||
grid1.addWidget(self.segy_entry, 10, 1)
|
||||
grid1.addWidget(self.segy_entry, 11, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
@ -6344,37 +6375,6 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.annotation_cb, 2, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
|
||||
|
||||
# Annotation Font Size
|
||||
self.annotation_fontsize_label = QtWidgets.QLabel('%s:' % _("Annotation Size"))
|
||||
self.annotation_fontsize_label.setToolTip(
|
||||
_("The font size of the annotation text. In pixels.")
|
||||
)
|
||||
grid0.addWidget(self.annotation_fontsize_label, 3, 0)
|
||||
self.annotation_fontsize_sp = FCSpinner()
|
||||
grid0.addWidget(self.annotation_fontsize_sp, 3, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
|
||||
|
||||
# Annotation Font Color
|
||||
self.annotation_color_label = QtWidgets.QLabel('%s:' % _('Annotation Color'))
|
||||
self.annotation_color_label.setToolTip(
|
||||
_("Set the font color for the annotation texts.")
|
||||
)
|
||||
self.annotation_fontcolor_entry = FCEntry()
|
||||
self.annotation_fontcolor_button = QtWidgets.QPushButton()
|
||||
self.annotation_fontcolor_button.setFixedSize(15, 15)
|
||||
|
||||
self.form_box_child = QtWidgets.QHBoxLayout()
|
||||
self.form_box_child.setContentsMargins(0, 0, 0, 0)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_entry)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
|
||||
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
|
||||
color_widget = QtWidgets.QWidget()
|
||||
color_widget.setLayout(self.form_box_child)
|
||||
grid0.addWidget(self.annotation_color_label, 4, 0)
|
||||
grid0.addWidget(color_widget, 4, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 4, 2)
|
||||
|
||||
# ###################################################################
|
||||
# Number of circle steps for circular aperture linear approximation #
|
||||
# ###################################################################
|
||||
|
@ -6383,9 +6383,9 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
_("The number of circle steps for <b>GCode</b> \n"
|
||||
"circle and arc shapes linear approximation.")
|
||||
)
|
||||
grid0.addWidget(self.steps_per_circle_label, 5, 0)
|
||||
grid0.addWidget(self.steps_per_circle_label, 3, 0)
|
||||
self.steps_per_circle_entry = IntEntry()
|
||||
grid0.addWidget(self.steps_per_circle_entry, 5, 1)
|
||||
grid0.addWidget(self.steps_per_circle_entry, 3, 1)
|
||||
|
||||
# Tool dia for plot
|
||||
tdlabel = QtWidgets.QLabel('%s:' % _('Travel dia'))
|
||||
|
@ -6394,11 +6394,11 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
"rendered in the plot.")
|
||||
)
|
||||
self.tooldia_entry = LengthEntry()
|
||||
grid0.addWidget(tdlabel, 6, 0)
|
||||
grid0.addWidget(self.tooldia_entry, 6, 1)
|
||||
grid0.addWidget(tdlabel, 4, 0)
|
||||
grid0.addWidget(self.tooldia_entry, 4, 1)
|
||||
|
||||
# add a space
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 7, 0)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 5, 0)
|
||||
|
||||
# Number of decimals to use in GCODE coordinates
|
||||
cdeclabel = QtWidgets.QLabel('%s:' % _('Coordinates decimals'))
|
||||
|
@ -6407,8 +6407,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
"the X, Y, Z coordinates in CNC code (GCODE, etc.)")
|
||||
)
|
||||
self.coords_dec_entry = IntEntry()
|
||||
grid0.addWidget(cdeclabel, 8, 0)
|
||||
grid0.addWidget(self.coords_dec_entry, 8, 1)
|
||||
grid0.addWidget(cdeclabel, 6, 0)
|
||||
grid0.addWidget(self.coords_dec_entry, 6, 1)
|
||||
|
||||
# Number of decimals to use in GCODE feedrate
|
||||
frdeclabel = QtWidgets.QLabel('%s:' % _('Feedrate decimals'))
|
||||
|
@ -6417,8 +6417,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
"the Feedrate parameter in CNC code (GCODE, etc.)")
|
||||
)
|
||||
self.fr_dec_entry = IntEntry()
|
||||
grid0.addWidget(frdeclabel, 9, 0)
|
||||
grid0.addWidget(self.fr_dec_entry, 9, 1)
|
||||
grid0.addWidget(frdeclabel, 7, 0)
|
||||
grid0.addWidget(self.fr_dec_entry, 7, 1)
|
||||
|
||||
# The type of coordinates used in the Gcode: Absolute or Incremental
|
||||
coords_type_label = QtWidgets.QLabel('%s:' % _('Coordinates type'))
|
||||
|
@ -6432,8 +6432,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
|
|||
{"label": _("Absolute G90"), "value": "G90"},
|
||||
{"label": _("Incremental G91"), "value": "G91"}
|
||||
], orientation='vertical', stretch=False)
|
||||
grid0.addWidget(coords_type_label, 10, 0)
|
||||
grid0.addWidget(self.coords_type_radio, 10, 1)
|
||||
grid0.addWidget(coords_type_label, 8, 0)
|
||||
grid0.addWidget(self.coords_type_radio, 8, 1)
|
||||
|
||||
# hidden for the time being, until implemented
|
||||
coords_type_label.hide()
|
||||
|
@ -6570,6 +6570,42 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
# )
|
||||
# hlay1.addWidget(self.tc_insert_buton)
|
||||
|
||||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 2)
|
||||
|
||||
# Annotation Font Size
|
||||
self.annotation_fontsize_label = QtWidgets.QLabel('%s:' % _("Annotation Size"))
|
||||
self.annotation_fontsize_label.setToolTip(
|
||||
_("The font size of the annotation text. In pixels.")
|
||||
)
|
||||
grid0.addWidget(self.annotation_fontsize_label, 2, 0)
|
||||
self.annotation_fontsize_sp = FCSpinner()
|
||||
grid0.addWidget(self.annotation_fontsize_sp, 2, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
|
||||
|
||||
# Annotation Font Color
|
||||
self.annotation_color_label = QtWidgets.QLabel('%s:' % _('Annotation Color'))
|
||||
self.annotation_color_label.setToolTip(
|
||||
_("Set the font color for the annotation texts.")
|
||||
)
|
||||
self.annotation_fontcolor_entry = FCEntry()
|
||||
self.annotation_fontcolor_button = QtWidgets.QPushButton()
|
||||
self.annotation_fontcolor_button.setFixedSize(15, 15)
|
||||
|
||||
self.form_box_child = QtWidgets.QHBoxLayout()
|
||||
self.form_box_child.setContentsMargins(0, 0, 0, 0)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_entry)
|
||||
self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
|
||||
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
|
||||
color_widget = QtWidgets.QWidget()
|
||||
color_widget.setLayout(self.form_box_child)
|
||||
grid0.addWidget(self.annotation_color_label, 3, 0)
|
||||
grid0.addWidget(color_widget, 3, 1)
|
||||
grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
||||
|
@ -6705,8 +6741,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
|
|||
"Higher values = slow processing and slow execution on CNC\n"
|
||||
"due of too many paths.")
|
||||
)
|
||||
self.ncc_overlap_entry = FCDoubleSpinner()
|
||||
self.ncc_overlap_entry.set_precision(3)
|
||||
self.ncc_overlap_entry.setWrapping(True)
|
||||
self.ncc_overlap_entry.setRange(0.000, 0.999)
|
||||
self.ncc_overlap_entry.setSingleStep(0.1)
|
||||
grid0.addWidget(nccoverlabel, 7, 0)
|
||||
self.ncc_overlap_entry = FloatEntry()
|
||||
grid0.addWidget(self.ncc_overlap_entry, 7, 1)
|
||||
|
||||
# Margin entry
|
||||
|
@ -7050,8 +7090,12 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI):
|
|||
"Higher values = slow processing and slow execution on CNC\n"
|
||||
"due of too many paths.")
|
||||
)
|
||||
self.paintoverlap_entry = FCDoubleSpinner()
|
||||
self.paintoverlap_entry.set_precision(3)
|
||||
self.paintoverlap_entry.setWrapping(True)
|
||||
self.paintoverlap_entry.setRange(0.000, 0.999)
|
||||
self.paintoverlap_entry.setSingleStep(0.1)
|
||||
grid0.addWidget(ovlabel, 2, 0)
|
||||
self.paintoverlap_entry = LengthEntry()
|
||||
grid0.addWidget(self.paintoverlap_entry, 2, 1)
|
||||
|
||||
# Margin
|
||||
|
@ -7167,6 +7211,26 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(ftypelbl, 0, 0)
|
||||
grid0.addWidget(self.film_type_radio, 0, 1)
|
||||
|
||||
# Film Color
|
||||
self.film_color_label = QtWidgets.QLabel('%s:' % _('Film Color'))
|
||||
self.film_color_label.setToolTip(
|
||||
_("Set the film color when positive film is selected.")
|
||||
)
|
||||
self.film_color_entry = FCEntry()
|
||||
self.film_color_button = QtWidgets.QPushButton()
|
||||
self.film_color_button.setFixedSize(15, 15)
|
||||
|
||||
self.form_box_child = QtWidgets.QHBoxLayout()
|
||||
self.form_box_child.setContentsMargins(0, 0, 0, 0)
|
||||
self.form_box_child.addWidget(self.film_color_entry)
|
||||
self.form_box_child.addWidget(self.film_color_button, alignment=Qt.AlignRight)
|
||||
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
|
||||
film_color_widget = QtWidgets.QWidget()
|
||||
film_color_widget.setLayout(self.form_box_child)
|
||||
grid0.addWidget(self.film_color_label, 1, 0)
|
||||
grid0.addWidget(film_color_widget, 1, 1)
|
||||
|
||||
self.film_boundary_entry = FCEntry()
|
||||
self.film_boundary_label = QtWidgets.QLabel('%s:' % _("Border"))
|
||||
self.film_boundary_label.setToolTip(
|
||||
|
@ -7179,8 +7243,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
|
|||
"white color like the rest and which may confound with the\n"
|
||||
"surroundings if not for this border.")
|
||||
)
|
||||
grid0.addWidget(self.film_boundary_label, 1, 0)
|
||||
grid0.addWidget(self.film_boundary_entry, 1, 1)
|
||||
grid0.addWidget(self.film_boundary_label, 2, 0)
|
||||
grid0.addWidget(self.film_boundary_entry, 2, 1)
|
||||
|
||||
self.film_scale_entry = FCEntry()
|
||||
self.film_scale_label = QtWidgets.QLabel('%s:' % _("Scale Stroke"))
|
||||
|
@ -7189,8 +7253,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
|
|||
"It means that the line that envelope each SVG feature will be thicker or thinner,\n"
|
||||
"therefore the fine features may be more affected by this parameter.")
|
||||
)
|
||||
grid0.addWidget(self.film_scale_label, 2, 0)
|
||||
grid0.addWidget(self.film_scale_entry, 2, 1)
|
||||
grid0.addWidget(self.film_scale_label, 3, 0)
|
||||
grid0.addWidget(self.film_scale_entry, 3, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
@ -7737,7 +7801,7 @@ class FAExcPrefGroupUI(OptionsGroupUI):
|
|||
self.layout.addWidget(self.exc_list_label)
|
||||
|
||||
self.exc_list_text = FCTextArea()
|
||||
self.exc_list_text.sizeHint(custom_sizehint=150)
|
||||
# self.exc_list_text.sizeHint(custom_sizehint=150)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.exc_list_text.setFont(font)
|
||||
|
@ -7770,7 +7834,7 @@ class FAGcoPrefGroupUI(OptionsGroupUI):
|
|||
self.layout.addWidget(self.gco_list_label)
|
||||
|
||||
self.gco_list_text = FCTextArea()
|
||||
self.gco_list_text.sizeHint(custom_sizehint=150)
|
||||
# self.gco_list_text.sizeHint(custom_sizehint=150)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.gco_list_text.setFont(font)
|
||||
|
@ -7803,7 +7867,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
|
|||
self.layout.addWidget(self.grb_list_label)
|
||||
|
||||
self.grb_list_text = FCTextArea()
|
||||
self.grb_list_text.sizeHint(custom_sizehint=150)
|
||||
# self.grb_list_text.sizeHint(custom_sizehint=150)
|
||||
self.layout.addWidget(self.grb_list_text)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
|
@ -7814,6 +7878,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
|
|||
"FlatCAM and the files with above extensions.\n"
|
||||
"They will be active after next logon.\n"
|
||||
"This work only in Windows."))
|
||||
|
||||
self.layout.addWidget(self.grb_list_btn)
|
||||
|
||||
# self.layout.addStretch()
|
||||
|
|
|
@ -292,7 +292,11 @@ class GerberObjectUI(ObjectUI):
|
|||
"A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
|
||||
)
|
||||
overlabel.setMinimumWidth(90)
|
||||
self.iso_overlap_entry = FloatEntry()
|
||||
self.iso_overlap_entry = FCDoubleSpinner()
|
||||
self.iso_overlap_entry.set_precision(3)
|
||||
self.iso_overlap_entry.setWrapping(True)
|
||||
self.iso_overlap_entry.setRange(0.000, 0.999)
|
||||
self.iso_overlap_entry.setSingleStep(0.1)
|
||||
grid1.addWidget(overlabel, 2, 0)
|
||||
grid1.addWidget(self.iso_overlap_entry, 2, 1, 1, 2)
|
||||
|
||||
|
@ -709,11 +713,12 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.eendz_entry = LengthEntry()
|
||||
grid1.addWidget(self.eendz_entry, 5, 1)
|
||||
|
||||
# Excellon Feedrate
|
||||
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate (Plunge)'))
|
||||
# Excellon Feedrate Z
|
||||
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
|
||||
frlabel.setToolTip(
|
||||
_("Tool speed while drilling\n"
|
||||
"(in units per minute).\n"
|
||||
"So called 'Plunge' feedrate.\n"
|
||||
"This is for linear move G01.")
|
||||
)
|
||||
grid1.addWidget(frlabel, 6, 0)
|
||||
|
|
|
@ -274,7 +274,7 @@ class Film(FlatCAMTool):
|
|||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export SVG positive cancelled."))
|
||||
return
|
||||
else:
|
||||
self.app.export_svg_black(name, boxname, filename, scale_factor=scale_stroke_width)
|
||||
self.app.export_svg_positive(name, boxname, filename, scale_factor=scale_stroke_width)
|
||||
else:
|
||||
try:
|
||||
filename, _f = QtWidgets.QFileDialog.getSaveFileName(
|
||||
|
|
|
@ -292,7 +292,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
"Higher values = slow processing and slow execution on CNC\n"
|
||||
"due of too many paths.")
|
||||
)
|
||||
self.ncc_overlap_entry = FCEntry()
|
||||
self.ncc_overlap_entry = FCDoubleSpinner()
|
||||
self.ncc_overlap_entry.set_precision(3)
|
||||
self.ncc_overlap_entry.setWrapping(True)
|
||||
self.ncc_overlap_entry.setRange(0.000, 0.999)
|
||||
self.ncc_overlap_entry.setSingleStep(0.1)
|
||||
grid3.addWidget(nccoverlabel, 2, 0)
|
||||
grid3.addWidget(self.ncc_overlap_entry, 2, 1)
|
||||
|
||||
|
@ -1292,6 +1296,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
method=None,
|
||||
rest=None,
|
||||
tools_storage=None,
|
||||
plot=True,
|
||||
run_threaded=True):
|
||||
"""
|
||||
Clear the excess copper from the entire object.
|
||||
|
@ -2189,9 +2194,9 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
def job_thread(app_obj):
|
||||
try:
|
||||
if rest_machining_choice is True:
|
||||
app_obj.new_object("geometry", name, gen_clear_area_rest)
|
||||
app_obj.new_object("geometry", name, gen_clear_area_rest, plot=plot)
|
||||
else:
|
||||
app_obj.new_object("geometry", name, gen_clear_area)
|
||||
app_obj.new_object("geometry", name, gen_clear_area, plot=plot)
|
||||
except FlatCAMApp.GracefulException:
|
||||
proc.done()
|
||||
return
|
||||
|
|
|
@ -214,8 +214,12 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
"Higher values = slow processing and slow execution on CNC\n"
|
||||
"due of too many paths.")
|
||||
)
|
||||
self.paintoverlap_entry = FCDoubleSpinner()
|
||||
self.paintoverlap_entry.set_precision(3)
|
||||
self.paintoverlap_entry.setWrapping(True)
|
||||
self.paintoverlap_entry.setRange(0.000, 0.999)
|
||||
self.paintoverlap_entry.setSingleStep(0.1)
|
||||
grid3.addWidget(ovlabel, 1, 0)
|
||||
self.paintoverlap_entry = FCEntry()
|
||||
grid3.addWidget(self.paintoverlap_entry, 1, 1)
|
||||
|
||||
# Margin
|
||||
|
@ -1168,7 +1172,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
outname=None,
|
||||
connect=None,
|
||||
contour=None,
|
||||
tools_storage=None):
|
||||
tools_storage=None,
|
||||
plot=True,
|
||||
run_threaded=True):
|
||||
"""
|
||||
Paints a polygon selected by clicking on its interior or by having a point coordinates given
|
||||
|
||||
|
@ -1432,7 +1438,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
|
||||
def job_thread(app_obj):
|
||||
try:
|
||||
app_obj.new_object("geometry", name, gen_paintarea)
|
||||
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
|
||||
except FlatCAMApp.GracefulException:
|
||||
proc.done()
|
||||
return
|
||||
|
@ -1451,8 +1457,11 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
# Promise object with the new name
|
||||
self.app.collection.promise(name)
|
||||
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
if run_threaded:
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
else:
|
||||
job_thread(app_obj=self.app)
|
||||
|
||||
def paint_poly_all(self, obj,
|
||||
tooldia=None,
|
||||
|
@ -1463,7 +1472,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
outname=None,
|
||||
connect=None,
|
||||
contour=None,
|
||||
tools_storage=None):
|
||||
tools_storage=None,
|
||||
plot=True,
|
||||
run_threaded=True):
|
||||
"""
|
||||
Paints all polygons in this object.
|
||||
|
||||
|
@ -1901,9 +1912,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
def job_thread(app_obj):
|
||||
try:
|
||||
if self.rest_cb.isChecked():
|
||||
app_obj.new_object("geometry", name, gen_paintarea_rest_machining)
|
||||
app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
|
||||
else:
|
||||
app_obj.new_object("geometry", name, gen_paintarea)
|
||||
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
|
||||
except FlatCAMApp.GracefulException:
|
||||
proc.done()
|
||||
return
|
||||
|
@ -1920,8 +1931,11 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
# Promise object with the new name
|
||||
self.app.collection.promise(name)
|
||||
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
if run_threaded:
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
else:
|
||||
job_thread(app_obj=self.app)
|
||||
|
||||
def paint_poly_area(self, obj, sel_obj,
|
||||
tooldia=None,
|
||||
|
@ -1932,7 +1946,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
outname=None,
|
||||
connect=None,
|
||||
contour=None,
|
||||
tools_storage=None):
|
||||
tools_storage=None,
|
||||
plot=True,
|
||||
run_threaded=True):
|
||||
"""
|
||||
Paints all polygons in this object that are within the sel_obj object
|
||||
|
||||
|
@ -2366,9 +2382,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
def job_thread(app_obj):
|
||||
try:
|
||||
if self.rest_cb.isChecked():
|
||||
app_obj.new_object("geometry", name, gen_paintarea_rest_machining)
|
||||
app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
|
||||
else:
|
||||
app_obj.new_object("geometry", name, gen_paintarea)
|
||||
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
|
||||
except FlatCAMApp.GracefulException:
|
||||
proc.done()
|
||||
return
|
||||
|
@ -2385,8 +2401,11 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
# Promise object with the new name
|
||||
self.app.collection.promise(name)
|
||||
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
if run_threaded:
|
||||
# Background
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
else:
|
||||
job_thread(app_obj=self.app)
|
||||
|
||||
def paint_poly_ref(self, obj, sel_obj,
|
||||
tooldia=None,
|
||||
|
@ -2397,7 +2416,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
outname=None,
|
||||
connect=None,
|
||||
contour=None,
|
||||
tools_storage=None):
|
||||
tools_storage=None,
|
||||
plot=True,
|
||||
run_threaded=True):
|
||||
"""
|
||||
Paints all polygons in this object that are within the sel_obj object
|
||||
|
||||
|
@ -2441,7 +2462,9 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
outname=outname,
|
||||
connect=connect,
|
||||
contour=contour,
|
||||
tools_storage=tools_storage)
|
||||
tools_storage=tools_storage,
|
||||
plot=plot,
|
||||
run_threaded=run_threaded)
|
||||
|
||||
@staticmethod
|
||||
def paint_bounds(geometry):
|
||||
|
|
BIN
share/bug16.png
BIN
share/bug16.png
Binary file not shown.
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 303 B |
Binary file not shown.
After Width: | Height: | Size: 686 B |
Binary file not shown.
After Width: | Height: | Size: 230 B |
|
@ -78,8 +78,7 @@ class TclCommand(object):
|
|||
|
||||
:return: current command
|
||||
"""
|
||||
|
||||
command_string = []
|
||||
command_string = list()
|
||||
command_string.append(self.aliases[0])
|
||||
|
||||
if self.original_args is not None:
|
||||
|
@ -117,7 +116,7 @@ class TclCommand(object):
|
|||
if help_key in self.arg_names:
|
||||
arg_type = self.arg_names[help_key]
|
||||
type_name = str(arg_type.__name__)
|
||||
#in_command_name = help_key + "<" + type_name + ">"
|
||||
# in_command_name = help_key + "<" + type_name + ">"
|
||||
in_command_name = help_key
|
||||
|
||||
elif help_key in self.option_types:
|
||||
|
@ -163,35 +162,36 @@ class TclCommand(object):
|
|||
|
||||
@staticmethod
|
||||
def parse_arguments(args):
|
||||
"""
|
||||
Pre-processes arguments to detect '-keyword value' pairs into dictionary
|
||||
and standalone parameters into list.
|
||||
"""
|
||||
Pre-processes arguments to detect '-keyword value' pairs into dictionary
|
||||
and standalone parameters into list.
|
||||
|
||||
This is copy from FlatCAMApp.setup_shell().h() just for accessibility,
|
||||
original should be removed after all commands will be converted
|
||||
This is copy from FlatCAMApp.setup_shell().h() just for accessibility,
|
||||
original should be removed after all commands will be converted
|
||||
|
||||
:param args: arguments from tcl to parse
|
||||
:return: arguments, options
|
||||
"""
|
||||
:param args: arguments from tcl to parse
|
||||
:return: arguments, options
|
||||
"""
|
||||
|
||||
options = {}
|
||||
arguments = []
|
||||
n = len(args)
|
||||
name = None
|
||||
for i in range(n):
|
||||
match = re.search(r'^-([a-zA-Z].*)', args[i])
|
||||
if match:
|
||||
assert name is None
|
||||
name = match.group(1)
|
||||
continue
|
||||
options = {}
|
||||
arguments = []
|
||||
n = len(args)
|
||||
|
||||
if name is None:
|
||||
arguments.append(args[i])
|
||||
else:
|
||||
options[name] = args[i]
|
||||
name = None
|
||||
name = None
|
||||
for i in range(n):
|
||||
match = re.search(r'^-([a-zA-Z].*)', args[i])
|
||||
if match:
|
||||
assert name is None
|
||||
name = match.group(1)
|
||||
continue
|
||||
|
||||
return arguments, options
|
||||
if name is None:
|
||||
arguments.append(args[i])
|
||||
else:
|
||||
options[name] = args[i]
|
||||
name = None
|
||||
|
||||
return arguments, options
|
||||
|
||||
def check_args(self, args):
|
||||
"""
|
||||
|
@ -274,7 +274,6 @@ class TclCommand(object):
|
|||
"""
|
||||
|
||||
# self.worker_task.emit({'fcn': self.exec_command_test, 'params': [text, False]})
|
||||
|
||||
try:
|
||||
self.log.debug("TCL command '%s' executed." % str(self.__class__))
|
||||
self.original_args = args
|
||||
|
@ -416,7 +415,6 @@ class TclCommandSignaled(TclCommand):
|
|||
# when operation will be really long is good to set it higher then defqault 30s
|
||||
self.app.worker_task.emit({'fcn': self.execute_call, 'params': [args, unnamed_args]})
|
||||
|
||||
|
||||
return self.output
|
||||
|
||||
except Exception as unknown:
|
||||
|
|
|
@ -29,6 +29,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
|
|||
('axisoffset', float),
|
||||
('dia', float),
|
||||
('dist', float),
|
||||
('outname', str),
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
|
@ -47,9 +48,11 @@ class TclCommandAlignDrill(TclCommandSignaled):
|
|||
('minoffset', 'min and max distance between align hole and pcb.'),
|
||||
('axisoffset', 'Offset on second axis before aligment holes'),
|
||||
('axis', 'Mirror axis parallel to the X or Y axis.'),
|
||||
('dist', 'Distance of the mirror axis to the X or Y axis.')
|
||||
('dist', 'Distance of the mirror axis to the X or Y axis.'),
|
||||
('outname', 'Name of the resulting Excellon object.'),
|
||||
]),
|
||||
'examples': []
|
||||
'examples': ['aligndrill my_object -axis X -box my_object -dia 3.125 -grid 1 '
|
||||
'-gridoffset 0 -minoffset 2 -axisoffset 2']
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
|
@ -64,6 +67,11 @@ class TclCommandAlignDrill(TclCommandSignaled):
|
|||
|
||||
name = args['name']
|
||||
|
||||
if 'outname' in args:
|
||||
outname = args['outname']
|
||||
else:
|
||||
outname = name + "_aligndrill"
|
||||
|
||||
# Get source object.
|
||||
try:
|
||||
obj = self.app.collection.get_by_name(str(name))
|
||||
|
@ -176,9 +184,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
|
|||
px = 0.5 * (xmin + xmax)
|
||||
py = 0.5 * (ymin + ymax)
|
||||
|
||||
obj.app.new_object("excellon",
|
||||
name + "_aligndrill",
|
||||
alligndrill_init_me)
|
||||
obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
|
||||
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
@ -194,8 +200,8 @@ class TclCommandAlignDrill(TclCommandSignaled):
|
|||
try:
|
||||
px = dist
|
||||
py = dist
|
||||
obj.app.new_object("excellon", name + "_alligndrill", alligndrill_init_me)
|
||||
obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
||||
return 'Ok'
|
||||
return 'Ok. Align Drills Excellon object created'
|
||||
|
|
|
@ -17,7 +17,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
|
|||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
# For positional arguments
|
||||
arg_names = collections.OrderedDict([
|
||||
('outname', str)
|
||||
|
||||
])
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
|
@ -29,11 +29,12 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
|
|||
('gridy', float),
|
||||
('gridoffsety', float),
|
||||
('columns', int),
|
||||
('rows', int)
|
||||
('rows', int),
|
||||
('outname', str)
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
required = ['outname', 'gridx', 'gridy', 'columns', 'rows']
|
||||
required = ['gridx', 'gridy', 'columns', 'rows']
|
||||
|
||||
# structured help for current command, args needs to be ordered
|
||||
help = {
|
||||
|
@ -48,7 +49,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
|
|||
('colums', 'Number of grid holes on X axis.'),
|
||||
('rows', 'Number of grid holes on Y axis.'),
|
||||
]),
|
||||
'examples': []
|
||||
'examples': ['aligndrillgrid -rows 2 -columns 2 -gridoffsetx 10 -gridoffsety 10 -gridx 2.54 -gridy 5.08']
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
|
@ -61,6 +62,11 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
|
|||
:return: None or exception
|
||||
"""
|
||||
|
||||
if 'outname' in args:
|
||||
outname = args['outname']
|
||||
else:
|
||||
outname = "new_aligndrill_grid"
|
||||
|
||||
if 'gridoffsetx' not in args:
|
||||
gridoffsetx = 0
|
||||
else:
|
||||
|
@ -102,4 +108,4 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
|
|||
init_obj.create_geometry()
|
||||
|
||||
# Create the new object
|
||||
self.app.new_object("excellon", args['outname'], aligndrillgrid_init_me)
|
||||
self.app.new_object("excellon", outname, aligndrillgrid_init_me, plot=False)
|
||||
|
|
|
@ -90,6 +90,6 @@ class TclCommandBbox(TclCommand):
|
|||
bounding_box = bounding_box.envelope
|
||||
geo_obj.solid_geometry = bounding_box
|
||||
|
||||
self.app.new_object("geometry", args['outname'], geo_init)
|
||||
self.app.new_object("geometry", args['outname'], geo_init, plot=False)
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
|
|
@ -24,7 +24,7 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
|
||||
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
('tooldia', float),
|
||||
('dia', float),
|
||||
('z_cut', float),
|
||||
('z_move', float),
|
||||
('feedrate', float),
|
||||
|
@ -42,6 +42,7 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
('dwell', bool),
|
||||
('dwelltime', float),
|
||||
('pp', str),
|
||||
('muted', int),
|
||||
('outname', str)
|
||||
])
|
||||
|
||||
|
@ -53,7 +54,7 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
'main': "Generates a CNC Job from a Geometry Object.",
|
||||
'args': collections.OrderedDict([
|
||||
('name', 'Name of the source object.'),
|
||||
('tooldia', 'Tool diameter to show on screen.'),
|
||||
('dia', 'Tool diameter to show on screen.'),
|
||||
('z_cut', 'Z-axis cutting position.'),
|
||||
('z_move', 'Z-axis moving position.'),
|
||||
('feedrate', 'Moving speed on X-Y plane when cutting.'),
|
||||
|
@ -71,7 +72,8 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
('dwell', 'True or False; use (or not) the dwell'),
|
||||
('dwelltime', 'Time to pause to allow the spindle to reach the full speed'),
|
||||
('outname', 'Name of the resulting Geometry object.'),
|
||||
('pp', 'Name of the Geometry postprocessor. No quotes, case sensitive')
|
||||
('pp', 'Name of the Geometry postprocessor. No quotes, case sensitive'),
|
||||
('muted', 'It will not put errors in the Shell.')
|
||||
]),
|
||||
'examples': ['cncjob geo_name -tooldia 0.5 -z_cut -1.7 -z_move 2 -feedrate 120 -ppname_g default']
|
||||
}
|
||||
|
@ -91,15 +93,26 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
if 'outname' not in args:
|
||||
args['outname'] = str(name) + "_cnc"
|
||||
|
||||
if 'muted' in args:
|
||||
muted = args['muted']
|
||||
else:
|
||||
muted = 0
|
||||
|
||||
obj = self.app.collection.get_by_name(str(name), isCaseSensitive=False)
|
||||
|
||||
if obj is None:
|
||||
self.raise_tcl_error("Object not found: %s" % str(name))
|
||||
if not muted:
|
||||
self.raise_tcl_error("Object not found: %s" % str(name))
|
||||
else:
|
||||
return
|
||||
|
||||
if not isinstance(obj, FlatCAMGeometry):
|
||||
self.raise_tcl_error('Expected FlatCAMGeometry, got %s %s.' % (str(name), type(obj)))
|
||||
if not muted:
|
||||
self.raise_tcl_error('Expected FlatCAMGeometry, got %s %s.' % (str(name), type(obj)))
|
||||
else:
|
||||
return
|
||||
|
||||
args["tooldia"] = args["tooldia"] if "tooldia" in args else obj.options["cnctooldia"]
|
||||
args["dia"] = args["dia"] if "dia" in args else obj.options["cnctooldia"]
|
||||
|
||||
args["z_cut"] = args["z_cut"] if "z_cut" in args else obj.options["cutz"]
|
||||
args["z_move"] = args["z_move"] if "z_move" in args else obj.options["travelz"]
|
||||
|
@ -130,20 +143,24 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
del args['name']
|
||||
|
||||
for arg in args:
|
||||
if arg == "toolchange_xy" or arg == "spindlespeed":
|
||||
if arg == "toolchange_xy" or arg == "spindlespeed" or arg == "startz":
|
||||
continue
|
||||
else:
|
||||
if args[arg] is None:
|
||||
self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
|
||||
'The parameter that is None is in the default values found in the list \n'
|
||||
'generated by the TclCommand "list_sys geom". or in the arguments.')
|
||||
print(arg, args[arg])
|
||||
if not muted:
|
||||
self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
|
||||
'The parameter that is None is in the default values found in the list \n'
|
||||
'generated by the TclCommand "list_sys geom". or in the arguments.')
|
||||
else:
|
||||
return
|
||||
|
||||
# HACK !!! Should be solved elsewhere!!!
|
||||
# default option for multidepth is False
|
||||
obj.options['multidepth'] = False
|
||||
|
||||
if not obj.multigeo:
|
||||
obj.generatecncjob(use_thread=False, **args)
|
||||
obj.generatecncjob(use_thread=False, plot=False, **args)
|
||||
else:
|
||||
# Update the local_tools_dict values with the args value
|
||||
local_tools_dict = deepcopy(obj.tools)
|
||||
|
@ -171,5 +188,6 @@ class TclCommandCncjob(TclCommandSignaled):
|
|||
outname=args['outname'],
|
||||
tools_dict=local_tools_dict,
|
||||
tools_in_use=[],
|
||||
use_thread=False)
|
||||
use_thread=False,
|
||||
plot=False)
|
||||
# self.raise_tcl_error('The object is a multi-geo geometry which is not supported in cncjob Tcl Command')
|
||||
|
|
|
@ -226,6 +226,7 @@ class TclCommandCopperClear(TclCommand):
|
|||
contour=contour,
|
||||
rest=rest,
|
||||
tools_storage=ncc_tools,
|
||||
plot=False,
|
||||
run_threaded=False)
|
||||
return
|
||||
|
||||
|
@ -259,6 +260,7 @@ class TclCommandCopperClear(TclCommand):
|
|||
contour=contour,
|
||||
rest=rest,
|
||||
tools_storage=ncc_tools,
|
||||
plot=False,
|
||||
run_threaded=False)
|
||||
return
|
||||
else:
|
||||
|
|
|
@ -123,7 +123,7 @@ class TclCommandCutout(TclCommand):
|
|||
geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
|
||||
|
||||
try:
|
||||
self.app.new_object("geometry", name + "_cutout", geo_init_me)
|
||||
self.app.new_object("geometry", name + "_cutout", geo_init_me, plot=False)
|
||||
self.app.inform.emit("[success] Rectangular-form Cutout operation finished.")
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
|
|
@ -17,7 +17,6 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
|
||||
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
('tools', str),
|
||||
('drilled_dias', str),
|
||||
('drillz', float),
|
||||
('travelz', float),
|
||||
|
@ -31,7 +30,8 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
('pp', str),
|
||||
('outname', str),
|
||||
('opt_type', str),
|
||||
('diatol', float)
|
||||
('diatol', float),
|
||||
('muted', int)
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
|
@ -62,7 +62,8 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
'the same as the ones in the tools from the Excellon object. E.g: if in drill_dias we have a '
|
||||
'diameter with value 1.0, in the Excellon we have a tool with dia = 1.05 and we set a tolerance '
|
||||
'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) '
|
||||
'in Excellon will be processed. Float number.')
|
||||
'in Excellon will be processed. Float number.'),
|
||||
('muted', 'It will not put errors in the Shell or status bar.')
|
||||
]),
|
||||
'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate 222 -feedrate_rapid 456 -spindlespeed 777'
|
||||
' -toolchange True -toolchangez 33 -endz 22 -pp default\n'
|
||||
|
@ -84,12 +85,20 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
if 'outname' not in args:
|
||||
args['outname'] = name + "_cnc"
|
||||
|
||||
if 'muted' in args:
|
||||
muted = args['muted']
|
||||
else:
|
||||
muted = 0
|
||||
|
||||
obj = self.app.collection.get_by_name(name)
|
||||
if obj is None:
|
||||
self.raise_tcl_error("Object not found: %s" % name)
|
||||
|
||||
if not isinstance(obj, FlatCAMExcellon):
|
||||
self.raise_tcl_error('Expected FlatCAMExcellon, got %s %s.' % (name, type(obj)))
|
||||
if not muted:
|
||||
self.raise_tcl_error('Expected FlatCAMExcellon, got %s %s.' % (name, type(obj)))
|
||||
else:
|
||||
return
|
||||
|
||||
xmin = obj.options['xmin']
|
||||
ymin = obj.options['ymin']
|
||||
|
@ -127,8 +136,11 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
nr_diameters -= 1
|
||||
|
||||
if nr_diameters > 0:
|
||||
self.raise_tcl_error("One or more tool diameters of the drills to be drilled passed to the "
|
||||
"TclCommand are not actual tool diameters in the Excellon object.")
|
||||
if not muted:
|
||||
self.raise_tcl_error("One or more tool diameters of the drills to be drilled passed to the "
|
||||
"TclCommand are not actual tool diameters in the Excellon object.")
|
||||
else:
|
||||
return
|
||||
|
||||
# make a string of diameters separated by comma; this is what generate_from_excellon_by_tool() is
|
||||
# expecting as tools parameter
|
||||
|
@ -181,4 +193,4 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
job_obj.gcode_parse()
|
||||
job_obj.create_geometry()
|
||||
|
||||
self.app.new_object("cncjob", args['outname'], job_init)
|
||||
self.app.new_object("cncjob", args['outname'], job_init, plot=False)
|
||||
|
|
|
@ -61,4 +61,4 @@ class TclCommandExteriors(TclCommandSignaled):
|
|||
geo_obj.solid_geometry = obj_exteriors
|
||||
|
||||
obj_exteriors = obj.get_exteriors()
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
self.app.new_object('geometry', outname, geo_init, plot=False)
|
||||
|
|
|
@ -279,7 +279,7 @@ class TclCommandGeoCutout(TclCommandSignaled):
|
|||
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
self.app.new_object('geometry', outname, geo_init, plot=False)
|
||||
|
||||
# cutout_obj.plot()
|
||||
# self.app.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
|
@ -338,7 +338,7 @@ class TclCommandGeoCutout(TclCommandSignaled):
|
|||
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.new_object('geometry', outname, geo_init)
|
||||
self.app.new_object('geometry', outname, geo_init, plot=False)
|
||||
|
||||
cutout_obj = self.app.collection.get_by_name(outname)
|
||||
else:
|
||||
|
|
|
@ -71,7 +71,7 @@ class TclCommandImportSvg(TclCommandSignaled):
|
|||
with self.app.proc_container.new("Import SVG"):
|
||||
|
||||
# Object creation
|
||||
self.app.new_object(obj_type, outname, obj_init)
|
||||
self.app.new_object(obj_type, outname, obj_init, plot=False)
|
||||
|
||||
# Register recent file
|
||||
self.app.file_opened.emit("svg", filename)
|
||||
|
|
|
@ -85,4 +85,4 @@ class TclCommandIsolate(TclCommandSignaled):
|
|||
self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (name, type(obj)))
|
||||
|
||||
del args['name']
|
||||
obj.isolate(**args)
|
||||
obj.isolate(plot=False, **args)
|
||||
|
|
|
@ -61,4 +61,4 @@ class TclCommandJoinExcellon(TclCommand):
|
|||
FlatCAMExcellon.merge(objs, obj_)
|
||||
|
||||
if objs is not None:
|
||||
self.app.new_object("excellon", outname, initialize)
|
||||
self.app.new_object("excellon", outname, initialize, plot=False)
|
||||
|
|
|
@ -61,4 +61,4 @@ class TclCommandJoinGeometry(TclCommand):
|
|||
FlatCAMGeometry.merge(objs, obj_)
|
||||
|
||||
if objs is not None:
|
||||
self.app.new_object("geometry", outname, initialize)
|
||||
self.app.new_object("geometry", outname, initialize, plot=False)
|
||||
|
|
|
@ -128,7 +128,7 @@ class TclCommandMillDrills(TclCommandSignaled):
|
|||
del args['name']
|
||||
|
||||
# This runs in the background... Is blocking handled?
|
||||
success, msg = obj.generate_milling_drills(**args)
|
||||
success, msg = obj.generate_milling_drills(plot=False, **args)
|
||||
except Exception as e:
|
||||
success = None
|
||||
msg = None
|
||||
|
|
|
@ -127,7 +127,7 @@ class TclCommandMillSlots(TclCommandSignaled):
|
|||
del args['name']
|
||||
|
||||
# This runs in the background... Is blocking handled?
|
||||
success, msg = obj.generate_milling_slots(**args)
|
||||
success, msg = obj.generate_milling_slots(plot=False, **args)
|
||||
|
||||
except Exception as e:
|
||||
success = None
|
||||
|
|
|
@ -103,6 +103,5 @@ class TclCommandMirror(TclCommandSignaled):
|
|||
|
||||
try:
|
||||
obj.mirror(axis, [dist, dist])
|
||||
obj.plot()
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
|
|
@ -36,4 +36,4 @@ class TclCommandNew(TclCommand):
|
|||
:return: None or exception
|
||||
"""
|
||||
|
||||
self.app.on_file_new()
|
||||
self.app.on_file_new(cli=True)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
from ObjectCollection import *
|
||||
from tclCommands.TclCommand import TclCommandSignaled
|
||||
|
||||
|
||||
class TclCommandNewExcellon(TclCommandSignaled):
|
||||
"""
|
||||
Tcl shell command to subtract polygon from the given Geometry object.
|
||||
"""
|
||||
|
||||
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||
aliases = ['new_excellon']
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
# For positional arguments
|
||||
arg_names = collections.OrderedDict([
|
||||
('name', str)
|
||||
])
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
# For options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
required = []
|
||||
|
||||
# structured help for current command, args needs to be ordered
|
||||
help = {
|
||||
'main': "Creates a new empty Excellon object.",
|
||||
'args': collections.OrderedDict([
|
||||
('name', 'New object name.'),
|
||||
]),
|
||||
'examples': []
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
"""
|
||||
execute current TCL shell command
|
||||
|
||||
:param args: array of known named arguments and options
|
||||
:param unnamed_args: array of other values which were passed into command
|
||||
without -somename and we do not have them in known arg_names
|
||||
:return: None or exception
|
||||
"""
|
||||
|
||||
if 'name' in args:
|
||||
name = args['name']
|
||||
else:
|
||||
name = 'new_exc'
|
||||
self.app.new_object('excellon', name, lambda x, y: None, plot=False)
|
|
@ -23,7 +23,7 @@ class TclCommandNewGeometry(TclCommandSignaled):
|
|||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
required = ['name']
|
||||
required = []
|
||||
|
||||
# structured help for current command, args needs to be ordered
|
||||
help = {
|
||||
|
@ -43,7 +43,9 @@ class TclCommandNewGeometry(TclCommandSignaled):
|
|||
without -somename and we do not have them in known arg_names
|
||||
:return: None or exception
|
||||
"""
|
||||
if 'name' in args:
|
||||
name = args['name']
|
||||
else:
|
||||
name = 'new_geo'
|
||||
|
||||
name = args['name']
|
||||
|
||||
self.app.new_object('geometry', str(name), lambda x, y: None)
|
||||
self.app.new_object('geometry', str(name), lambda x, y: None, plot=False)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
from ObjectCollection import *
|
||||
from tclCommands.TclCommand import TclCommandSignaled
|
||||
|
||||
|
||||
class TclCommandNewGerber(TclCommandSignaled):
|
||||
"""
|
||||
Tcl shell command to subtract polygon from the given Geometry object.
|
||||
"""
|
||||
|
||||
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||
aliases = ['new_gerber']
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
# For positional arguments
|
||||
arg_names = collections.OrderedDict([
|
||||
('name', str)
|
||||
])
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered.
|
||||
# For options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
required = []
|
||||
|
||||
# structured help for current command, args needs to be ordered
|
||||
help = {
|
||||
'main': "Creates a new empty Gerber object.",
|
||||
'args': collections.OrderedDict([
|
||||
('name', 'New object name.'),
|
||||
]),
|
||||
'examples': []
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
"""
|
||||
execute current TCL shell command
|
||||
|
||||
:param args: array of known named arguments and options
|
||||
:param unnamed_args: array of other values which were passed into command
|
||||
without -somename and we do not have them in known arg_names
|
||||
:return: None or exception
|
||||
"""
|
||||
|
||||
if 'name' in args:
|
||||
name = args['name']
|
||||
else:
|
||||
name = 'new_grb'
|
||||
|
||||
def initialize(grb_obj, self):
|
||||
grb_obj.multitool = False
|
||||
grb_obj.source_file = []
|
||||
grb_obj.multigeo = False
|
||||
grb_obj.follow = False
|
||||
grb_obj.apertures = {}
|
||||
grb_obj.solid_geometry = []
|
||||
|
||||
try:
|
||||
grb_obj.options['xmin'] = 0
|
||||
grb_obj.options['ymin'] = 0
|
||||
grb_obj.options['xmax'] = 0
|
||||
grb_obj.options['ymax'] = 0
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.app.new_object('gerber', name, initialize, plot=False)
|
|
@ -89,7 +89,7 @@ class TclCommandNregions(TclCommand):
|
|||
non_copper = bounding_box.difference(geo)
|
||||
geo_obj.solid_geometry = non_copper
|
||||
|
||||
self.app.new_object("geometry", args['outname'], geo_init)
|
||||
self.app.new_object("geometry", args['outname'], geo_init, plot=False)
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
|
||||
|
|
|
@ -46,5 +46,7 @@ class TclCommandOpenExcellon(TclCommandSignaled):
|
|||
"""
|
||||
|
||||
filename = args.pop('filename')
|
||||
filename = filename.replace(' ', '')
|
||||
|
||||
args['plot'] = False
|
||||
self.app.open_excellon(filename, **args)
|
||||
|
|
|
@ -45,5 +45,8 @@ class TclCommandOpenGCode(TclCommandSignaled):
|
|||
without -somename and we do not have them in known arg_names
|
||||
:return: None or exception
|
||||
"""
|
||||
args['plot'] = False
|
||||
filename = args["filename"]
|
||||
filename = filename.replace(' ', '')
|
||||
|
||||
self.app.open_gcode(args['filename'], **args)
|
||||
self.app.open_gcode(filename, **args)
|
||||
|
|
|
@ -30,7 +30,7 @@ class TclCommandOpenGerber(TclCommandSignaled):
|
|||
('filename', 'Path to file to open.'),
|
||||
('outname', 'Name of the resulting Gerber object.')
|
||||
]),
|
||||
'examples': []
|
||||
'examples': ["open_gerber gerber_object_path -outname bla"]
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
|
@ -50,25 +50,19 @@ class TclCommandOpenGerber(TclCommandSignaled):
|
|||
self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (outname, type(gerber_obj)))
|
||||
|
||||
# Opening the file happens here
|
||||
self.app.progress.emit(30)
|
||||
try:
|
||||
gerber_obj.parse_file(filename)
|
||||
|
||||
except IOError:
|
||||
app_obj.inform.emit("[ERROR_NOTCL] Failed to open file: %s " % filename)
|
||||
app_obj.progress.emit(0)
|
||||
self.raise_tcl_error('Failed to open file: %s' % filename)
|
||||
|
||||
except ParseError as e:
|
||||
app_obj.inform.emit("[ERROR_NOTCL] Failed to parse file: %s, %s " % (filename, str(e)))
|
||||
app_obj.progress.emit(0)
|
||||
self.log.error(str(e))
|
||||
return
|
||||
|
||||
# Further parsing
|
||||
app_obj.progress.emit(70)
|
||||
|
||||
filename = args['filename']
|
||||
filename = filename.replace(' ', '')
|
||||
|
||||
if 'outname' in args:
|
||||
outname = args['outname']
|
||||
|
@ -76,17 +70,16 @@ class TclCommandOpenGerber(TclCommandSignaled):
|
|||
outname = filename.split('/')[-1].split('\\')[-1]
|
||||
|
||||
if 'follow' in args:
|
||||
self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' parameter for the Tcl Command isolate()")
|
||||
self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' "
|
||||
"parameter for the Tcl Command isolate()")
|
||||
|
||||
with self.app.proc_container.new("Opening Gerber"):
|
||||
|
||||
# Object creation
|
||||
self.app.new_object("gerber", outname, obj_init)
|
||||
self.app.new_object("gerber", outname, obj_init, plot=False)
|
||||
|
||||
# Register recent file
|
||||
self.app.file_opened.emit("gerber", filename)
|
||||
|
||||
self.app.progress.emit(100)
|
||||
|
||||
# GUI feedback
|
||||
self.app.inform.emit("[success] Opened: " + filename)
|
||||
|
|
|
@ -43,5 +43,7 @@ class TclCommandOpenProject(TclCommandSignaled):
|
|||
without -somename and we do not have them in known arg_names
|
||||
:return: None or exception
|
||||
"""
|
||||
filename = args['filename']
|
||||
filename = filename.replace(' ', '')
|
||||
|
||||
self.app.open_project(args['filename'])
|
||||
self.app.open_project(filename, cli=True, plot=False)
|
||||
|
|
|
@ -201,7 +201,9 @@ class TclCommandPaint(TclCommand):
|
|||
outname=outname,
|
||||
connect=connect,
|
||||
contour=contour,
|
||||
tools_storage=paint_tools)
|
||||
tools_storage=paint_tools,
|
||||
plot=False,
|
||||
run_threaded=False)
|
||||
return
|
||||
|
||||
# Paint single polygon in the painted object
|
||||
|
@ -222,7 +224,9 @@ class TclCommandPaint(TclCommand):
|
|||
outname=outname,
|
||||
connect=connect,
|
||||
contour=contour,
|
||||
tools_storage=paint_tools)
|
||||
tools_storage=paint_tools,
|
||||
plot=False,
|
||||
run_threaded=False)
|
||||
return
|
||||
|
||||
# Paint all polygons found within the box object from the the painted object
|
||||
|
@ -250,7 +254,9 @@ class TclCommandPaint(TclCommand):
|
|||
outname=outname,
|
||||
connect=connect,
|
||||
contour=contour,
|
||||
tools_storage=paint_tools)
|
||||
tools_storage=paint_tools,
|
||||
plot=False,
|
||||
run_threaded=False)
|
||||
return
|
||||
|
||||
else:
|
||||
|
|
|
@ -90,7 +90,7 @@ class TclCommandPanelize(TclCommand):
|
|||
if 'threaded' in args:
|
||||
threaded = args['threaded']
|
||||
else:
|
||||
threaded = 1
|
||||
threaded = 0
|
||||
|
||||
if 'spacing_columns' in args:
|
||||
spacing_columns = args['spacing_columns']
|
||||
|
@ -265,10 +265,10 @@ class TclCommandPanelize(TclCommand):
|
|||
|
||||
if isinstance(obj, FlatCAMExcellon):
|
||||
self.app.progress.emit(50)
|
||||
self.app.new_object("excellon", outname, job_init_excellon, plot=True, autoselected=True)
|
||||
self.app.new_object("excellon", outname, job_init_excellon, plot=False, autoselected=True)
|
||||
else:
|
||||
self.app.progress.emit(50)
|
||||
self.app.new_object("geometry", outname, job_init_geometry, plot=True, autoselected=True)
|
||||
self.app.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True)
|
||||
|
||||
if threaded == 1:
|
||||
proc = self.app.proc_container.new("Generating panel ... Please wait.")
|
||||
|
|
|
@ -2,7 +2,7 @@ from ObjectCollection import *
|
|||
from tclCommands.TclCommand import TclCommand
|
||||
|
||||
|
||||
class TclCommandPlot(TclCommand):
|
||||
class TclCommandPlotAll(TclCommand):
|
||||
"""
|
||||
Tcl shell command to update the plot on the user interface.
|
||||
|
||||
|
@ -11,7 +11,7 @@ class TclCommandPlot(TclCommand):
|
|||
"""
|
||||
|
||||
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||
aliases = ['plot']
|
||||
aliases = ['plot_all']
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered
|
||||
arg_names = collections.OrderedDict([
|
|
@ -0,0 +1,51 @@
|
|||
from ObjectCollection import *
|
||||
from tclCommands.TclCommand import TclCommand
|
||||
|
||||
|
||||
class TclCommandPlotObjects(TclCommand):
|
||||
"""
|
||||
Tcl shell command to update the plot on the user interface.
|
||||
|
||||
example:
|
||||
plot
|
||||
"""
|
||||
|
||||
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||
aliases = ['plot_objects']
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered
|
||||
arg_names = collections.OrderedDict([
|
||||
('names', str)
|
||||
])
|
||||
|
||||
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
required = []
|
||||
|
||||
# structured help for current command, args needs to be ordered
|
||||
help = {
|
||||
'main': "Plot a list of objects.",
|
||||
'args': collections.OrderedDict([
|
||||
('names', "UA list of object names to be plotted.")
|
||||
]),
|
||||
'examples': ["plot_objects"]
|
||||
}
|
||||
|
||||
def execute(self, args, unnamed_args):
|
||||
"""
|
||||
|
||||
:param args:
|
||||
:param unnamed_args:
|
||||
:return:
|
||||
"""
|
||||
names = [x.strip() for x in args['names'].split(",")]
|
||||
objs = []
|
||||
for name in names:
|
||||
objs.append(self.app.collection.get_by_name(name))
|
||||
|
||||
for obj in objs:
|
||||
obj.plot()
|
|
@ -22,7 +22,8 @@ class TclCommandWriteGCode(TclCommandSignaled):
|
|||
# For options like -optionname value
|
||||
option_types = collections.OrderedDict([
|
||||
('preamble', str),
|
||||
('postamble', str)
|
||||
('postamble', str),
|
||||
('muted', int)
|
||||
])
|
||||
|
||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||
|
@ -35,7 +36,9 @@ class TclCommandWriteGCode(TclCommandSignaled):
|
|||
('name', 'Source CNC Job object.'),
|
||||
('filename', 'Output filename.'),
|
||||
('preamble', 'Text to append at the beginning.'),
|
||||
('postamble', 'Text to append at the end.')
|
||||
('postamble', 'Text to append at the end.'),
|
||||
('muted', 'It will not put errors in the Shell or status bar.')
|
||||
|
||||
]),
|
||||
'examples': ["write_gcode name c:\\\\gcode_repo"]
|
||||
}
|
||||
|
@ -62,6 +65,11 @@ class TclCommandWriteGCode(TclCommandSignaled):
|
|||
preamble = args['preamble'] if 'preamble' in args else ''
|
||||
postamble = args['postamble'] if 'postamble' in args else ''
|
||||
|
||||
if 'muted' in args:
|
||||
muted = args['muted']
|
||||
else:
|
||||
muted = 0
|
||||
|
||||
# TODO: This is not needed any more? All targets should be present.
|
||||
# If there are promised objects, wait until all promises have been fulfilled.
|
||||
# if self.collection.has_promises():
|
||||
|
@ -82,9 +90,15 @@ class TclCommandWriteGCode(TclCommandSignaled):
|
|||
try:
|
||||
obj = self.app.collection.get_by_name(str(obj_name))
|
||||
except:
|
||||
return "Could not retrieve object: %s" % obj_name
|
||||
if not muted:
|
||||
return "Could not retrieve object: %s" % obj_name
|
||||
else:
|
||||
return
|
||||
|
||||
try:
|
||||
obj.export_gcode(str(filename), str(preamble), str(postamble))
|
||||
except Exception as e:
|
||||
return "Operation failed: %s" % str(e)
|
||||
if not muted:
|
||||
return "Operation failed: %s" % str(e)
|
||||
else:
|
||||
return
|
||||
|
|
|
@ -35,7 +35,9 @@ import tclCommands.TclCommandMillSlots
|
|||
import tclCommands.TclCommandMirror
|
||||
import tclCommands.TclCommandNew
|
||||
import tclCommands.TclCommandNregions
|
||||
import tclCommands.TclCommandNewExcellon
|
||||
import tclCommands.TclCommandNewGeometry
|
||||
import tclCommands.TclCommandNewGerber
|
||||
import tclCommands.TclCommandOffset
|
||||
import tclCommands.TclCommandOpenExcellon
|
||||
import tclCommands.TclCommandOpenGCode
|
||||
|
@ -44,7 +46,8 @@ import tclCommands.TclCommandOpenProject
|
|||
import tclCommands.TclCommandOptions
|
||||
import tclCommands.TclCommandPaint
|
||||
import tclCommands.TclCommandPanelize
|
||||
import tclCommands.TclCommandPlot
|
||||
import tclCommands.TclCommandPlotAll
|
||||
import tclCommands.TclCommandPlotObjects
|
||||
import tclCommands.TclCommandSaveProject
|
||||
import tclCommands.TclCommandSaveSys
|
||||
import tclCommands.TclCommandScale
|
||||
|
|
Loading…
Reference in New Issue