def conv_new_pressed(P, W, button): if button and (W.conv_save.isEnabled() or W.conv_send.isEnabled() or P.convPreviewActive): head = _translate('HandlerClass', 'Unsaved Shape') btn1 = _translate('HandlerClass', 'CONTINUE') btn2 = _translate('HandlerClass', 'CANCEL') msg0 = _translate( 'HandlerClass', 'You have an unsaved, unsent, or active previewed shape') msg1 = _translate('HandlerClass', 'If you continue it will be deleted') if not P.dialog_show_yesno( QMessageBox.Warning, '{}'.format(head), '{}\n\n{}\n'.format( msg0, msg1), '{}'.format(btn1), '{}'.format(btn2)): return if P.oldConvButton == 'conv_line': if P.lAlias == 'LP2P': CONVLINE.set_line_point_to_point(P, W, False) elif P.lAlias == 'LBLA': CONVLINE.set_line_by_angle(P, W, False) elif P.lAlias == 'A3Pt': CONVLINE.set_arc_3_points(P, W, False) elif P.lAlias == 'A2PR': CONVLINE.set_arc_2_points_radius(P, W, False) elif P.lAlias == 'ALAR': CONVLINE.set_arc_by_angle_radius(P, W, False) with open(P.fNgc, 'w') as outNgc: outNgc.write('(new conversational file)\nM2\n') COPY(P.fNgc, P.fTmp) COPY(P.fNgc, P.fNgcBkp) W.conv_preview.load(P.fNgc) W.conv_save.setEnabled(False) W.conv_send.setEnabled(False) P.validShape = False conv_preview_button(P, W, False) conv_enable_tabs(P, W)
def accept(P, W): COPY(P.fNgc, P.fNgcBkp) W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(False) W.undo.setEnabled(False) W.conv_send.setEnabled(True)
def conv_save_pressed(P, W): head = _translate('HandlerClass', 'Save Error') with open(P.fNgc, 'r') as inFile: for line in inFile: if '(new conversational file)' in line: msg0 = _translate('HandlerClass', 'An empty file cannot be saved') P.dialog_show_ok(QMessageBox.Warning, '{}'.format(head), '{}\n'.format(msg0)) return P.vkb_show() dlg = QFileDialog(W) dlg.setOptions(QFileDialog.DontUseNativeDialog) dlg.setAcceptMode(QFileDialog.AcceptSave) dlg.setNameFilters(['G-Code Files (*.ngc *.nc *.tap)', 'All Files (*)']) dlg.setDefaultSuffix('ngc') dlg.setDirectory(P.programPrefix) name = '' if dlg.exec_(): name = dlg.selectedFiles()[0] if name: COPY(P.fNgc, name) W.conv_save.setEnabled(False) conv_enable_tabs(P, W) P.vkb_show(True)
def conv_send_pressed(P, W): COPY(P.fNgcBkp, P.fNgcSent) W.conv_send.setEnabled(False) W.conv_save.setEnabled(False) conv_enable_tabs(P, W) P.vkb_hide() ACTION.OPEN_PROGRAM(P.fNgcSent)
def write_prefs_file(self): inPrefs = [] BYPASS = ['[PLASMA_PARAMETERS]', '[ENABLE_OPTIONS]', \ '[DEFAULT MATERIAL]', '[SINGLE CUT]', \ '[CONVERSATIONAL]', '[STATISTICS]'] bypass = False prefsFile = os.path.join(self.toFilePath, 'qtplasmac.prefs') prefsCopy = '{}_{}_{}'.format(prefsFile, self.date, self.time) COPY(prefsFile, prefsCopy) with open(prefsFile, 'w') as outFile: with open(prefsCopy, 'r') as inFile: for line in inFile: if line.startswith('[') and not line.strip() in BYPASS: bypass = False elif line.startswith('[') and line.strip() in BYPASS: bypass = True if not bypass: inPrefs.append(line) outFile.write('{}'.format(line)) for item in self.prefParms: outFile.write('{}\n'.format(item)) msg = 'Conversion appears successful.\n' msg += '\nAny time stamped backup of an original qtplasmac.prefs ' msg += 'file or an original material.cfg file may be deleted from ' msg += 'the configuration folder when the result of the conversion ' msg += 'has been confirmed.\n' self.dialog_ok('SUCCESS', msg) sys.exit()
def conv_setup(P, W): P.convSettingsChanged = False P.validShape = False P.savedSettings = {'origin': None, 'intext': None, 'in': None, 'out': None} P.invalidLeads = 0 W.preview = QPushButton(_translate('Conversational', 'PREVIEW')) W.undo = QPushButton(_translate('Conversational', 'RELOAD')) if not ACTION.prefilter_path: W.undo.setEnabled(False) conv_preview_button(P, W, False) P.convButtonState = {} P.convCommonButtons = ['new', 'save', 'send', 'settings'] for w in P.convCommonButtons: P.convButtonState[w] = False if P.unitsPerMm == 1: P.unitCode = ['21', '0.25', 32] else: P.unitCode = ['20', '0.004', 1.26] P.ambles = 'G{} G64P{} G40 G49 G80 G90 G92.1 G94 G97'.format( P.unitCode[0], P.unitCode[1]) CONVSET.load(P, W) # grid size is in inches W.conv_preview.grid_size = P.gridSize / P.unitsPerMm / 25.4 W.conv_preview.set_current_view() W.conv_new.setEnabled(True) W.conv_save.setEnabled(False) W.conv_send.setEnabled(False) W.conv_settings.setEnabled(True) if ACTION.prefilter_path and P.fileOpened: COPY(P.filteredBkp, P.fNgc) COPY(P.filteredBkp, P.fNgcBkp) W.conv_preview.load(P.filteredBkp) W.conv_preview.set_current_view() conv_enable_tabs(P, W) else: conv_new_pressed(P, W, None) P.xOrigin = STATUS.get_position()[0][0] P.yOrigin = STATUS.get_position()[0][1] P.xSaved = '0.000' P.ySaved = '0.000' P.convBlock = [False, False] if not P.convWidgetsLoaded or P.developmentPin.get(): conv_widgets(P, W) if not P.oldConvButton: conv_shape_request(P, W, 'conv_line', True) else: conv_shape_request(P, W, P.oldConvButton, True)
def conv_undo_shape(P, W): # setup for a reload if required if not P.convPreviewActive: head = _translate('HandlerClass', 'Reload Request') btn1 = _translate('HandlerClass', 'CONTINUE') btn2 = _translate('HandlerClass', 'CANCEL') if ACTION.prefilter_path: name = os.path.basename(ACTION.prefilter_path) msg0 = _translate('HandlerClass', 'The original file will be loaded') msg1 = _translate('HandlerClass', 'If you continue all changes will be deleted') if not P.dialog_show_yesno( QMessageBox.Warning, '{}'.format(head), '{}:\n\n{}\n\n{}\n'.format(msg0, name, msg1), '{}'.format(btn1), '{}'.format(btn2)): return (True) else: msg0 = _translate('HandlerClass', 'An empty file will be loaded') msg1 = _translate('HandlerClass', 'If you continue all changes will be deleted') if not P.dialog_show_yesno(QMessageBox.Warning, '{}'.format(head), '{}\n\n{}\n'.format(msg0, msg1), '{}'.format(btn1), '{}'.format(btn2)): return (True) if ACTION.prefilter_path: COPY(ACTION.prefilter_path, P.fNgcBkp) else: with open(P.fNgcBkp, 'w') as outNgc: outNgc.write('(new conversational file)\nM2\n') P.validShape = False W.preview.setEnabled(True) W.undo.setEnabled(False) W.conv_save.setEnabled(False) W.conv_send.setEnabled(False) # undo the shape if os.path.exists(P.fNgcBkp): COPY(P.fNgcBkp, P.fNgc) W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(False) if not P.validShape: W.undo.setEnabled(False) if not P.convBlock[1]: P.convBlock[0] = False conv_preview_button(P, W, False) conv_enable_tabs(P, W)
def conv_accept(P, W): P.validShape = True conv_preview_button(P, W, False) COPY(P.fNgc, P.fNgcBkp) W.conv_preview.load(P.fNgc) W.add.setEnabled(False) W.conv_save.setEnabled(True) W.conv_send.setEnabled(True) conv_enable_tabs(P, W)
def do_ini_file(P, W, iniPath, xOffset, yOffset, param, comment): written = False COPY(iniPath, '{}~'.format(iniPath)) inFile = open('{}~'.format(iniPath), 'r') outFile = open(iniPath, 'w') while 1: line = inFile.readline() if not line: break elif line.startswith('[QTPLASMAC]'): outFile.write(line) break else: outFile.write(line) while 1: line = inFile.readline() if not line: if not written: outFile.write('{}\n'.format(comment)) if xOffset or yOffset: outFile.write('{} = X{:0.3f} Y{:0.3f}\n'.format( param, xOffset, yOffset)) else: outFile.write('#{} = X0.000 Y0.000\n'.format(param)) break elif line.startswith('['): if not written: outFile.write('{}\n'.format(comment)) if xOffset or yOffset: outFile.write('{} = X{:0.3f} Y{:0.3f}\n'.format( param, xOffset, yOffset)) else: outFile.write('#{} = X0.000 Y0.000\n'.format(param)) outFile.write(line) break elif line.startswith('{}'.format(param)) or line.startswith( '#{}'.format(param)): if xOffset or yOffset: outFile.write('{} = X{:0.3f} Y{:0.3f}\n'.format( param, xOffset, yOffset)) else: outFile.write('#{} = X0.000 Y0.000\n'.format(param)) written = True break else: outFile.write(line) while 1: line = inFile.readline() if not line: break else: outFile.write(line) inFile.close() outFile.close() os.remove('{}~'.format(iniPath))
def read_mat_file(self, matFile, newDir, newName): newFile = '{}/{}_material.cfg'.format(newDir, newName) if os.path.isfile(newFile): matCopy = '{}_{}_{}'.format(newFile, self.date, self.time) COPY(newFile, matCopy) with open(newFile, 'w') as outFile: with open(matFile) as inFile: for line in inFile: if line.startswith('THC') or line.startswith('#THC'): continue outFile.write(line)
def next_segment(fTmp, fNgc): with open(fTmp, 'w') as outTmp: with open(fNgc, 'r') as inNgc: while (1): line = inNgc.readline() if not line or 'M5 $0' in line: break else: outTmp.write(line) COPY(fTmp, fNgc) outNgc = open(fNgc, 'w')
def do_tool_file(P, W, toolFile, xOffset, yOffset): written = False COPY(toolFile, '{}~'.format(toolFile)) inFile = open('{}~'.format(toolFile), 'r') outFile = open(toolFile, 'w') for line in inFile: if line.startswith('T1'): outFile.write('T1 P1 X{:0.3f} Y{:0.3f} ;scribe\n'.format( xOffset, yOffset)) written = True else: outFile.write(line) if not written: outFile.write('T1 P1 X{:0.3f} Y{:0.3f} ;scribe\n'.format( xOffset, yOffset)) inFile.close() outFile.close() os.remove('{}~'.format(toolFile))
def conv_add_shape_to_file(P, W): COPY(P.fNgc, P.fNgcBkp) try: if W.xsEntry.text(): P.xSaved = W.xsEntry.text() except: pass try: if W.ysEntry.text(): P.ySaved = W.ysEntry.text() except: pass try: P.oSaved = W.center.isChecked() except: pass P.validShape = True W.add.setEnabled(False) W.conv_save.setEnabled(True) W.conv_send.setEnabled(True) conv_preview_button(P, W, False) conv_enable_tabs(P, W)
def preview(P, W): if P.dialogError: return if P.conv_add_segment == 0: try: if not W.entry1.text(): W.entry1.setText('{:0.3f}'.format(P.xOrigin)) W.xS = float(W.entry1.text()) except: msg = 'Invalid X ORIGIN entry detected.\n' error_set(P, msg) return try: if not W.entry2.text(): W.entry2.setText('{:0.3f}'.format(P.yOrigin)) W.yS = float(W.entry2.text()) except: msg = 'Invalid Y ORIGIN entry detected.\n' error_set(P, msg) return outTmp = open(P.fTmp, 'w') outNgc = open(P.fNgc, 'w') inWiz = open(P.fNgcBkp, 'r') for line in inWiz: if '(new conversational file)' in line: outNgc.write('\n{} (preamble)\n'.format(P.preAmble)) break elif '(postamble)' in line: break elif 'm2' in line.lower() or 'm30' in line.lower(): break outNgc.write(line) outTmp.write('\n(conversational line)\n') outTmp.write('M190 P{}\n'.format( int(W.conv_material.currentText().split(':')[0]))) outTmp.write('M66 P3 L3 Q1\n') outTmp.write('f#<_hal[plasmac.cut-feed-rate]>\n') outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(W.xS, W.yS)) outTmp.write('m3 $0 s1\n') try: if W.lType.currentText() == 'LINE POINT ~ POINT': if P.landscape: W.conv_savedX = W.entry4.text() W.conv_savedY = W.entry5.text() do_line_point_to_point(P, W, float(W.entry4.text()), float(W.entry5.text())) else: W.conv_savedX = W.entry3.text() W.conv_savedY = W.entry4.text() do_line_point_to_point(P, W, float(W.entry3.text()), float(W.entry4.text())) elif W.lType.currentText() == 'LINE BY ANGLE': if not float(W.entry4.text()): raise Exception('Length cannot be zero.\n') if P.landscape: do_line_by_angle(P, W, float(W.entry4.text()), float(W.entry5.text())) else: do_line_by_angle(P, W, float(W.entry3.text()), float(W.entry5.text())) elif W.lType.currentText() == 'ARC 3P': if P.landscape: W.conv_savedX = W.entry7.text() W.conv_savedY = W.entry8.text() do_arc_3_points(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text()), float(W.entry8.text())) else: W.conv_savedX = W.entry5.text() W.conv_savedY = W.entry6.text() do_arc_3_points(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text()), float(W.entry6.text())) elif W.lType.currentText() == 'ARC 2P +RADIUS': if P.landscape: W.conv_savedX = W.entry4.text() W.conv_savedY = W.entry5.text() if float(W.entry7.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_2_points_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text())) else: W.conv_savedX = W.entry3.text() W.conv_savedY = W.entry4.text() if float(W.entry5.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_2_points_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text())) elif W.lType.currentText() == 'ARC ANGLE +RADIUS': if P.landscape: if float(W.entry7.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_by_angle_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text())) else: if float(W.entry5.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_by_angle_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text())) except: msg = 'Invalid entry detected.\n' error_set(P, msg) outNgc.close() outTmp.close() return elif P.conv_add_segment >= 1: inTmp = open(P.fNgc, 'r') outTmp = open(P.fTmp, 'w') while (1): line = inTmp.readline() if not line or line == P.conv_gcodeLine: break else: outTmp.write(line) if P.conv_add_segment == 1: outTmp.write(line) while (1): line = inTmp.readline() if 'M5 $0' in line: break else: outTmp.write(line) inTmp.close() COPY(P.fTmp, P.fNgc) outNgc = open(P.fNgc, 'w') try: if W.lType.currentText() == 'LINE POINT ~ POINT': W.conv_savedX = W.entry1.text() W.conv_savedY = W.entry2.text() do_line_point_to_point(P, W, float(W.entry1.text()), float(W.entry2.text())) elif W.lType.currentText() == 'LINE BY ANGLE': if not float(W.entry1.text()): raise Exception('Length cannot be 0') do_line_by_angle(P, W, float(W.entry1.text()), float(W.entry2.text())) elif W.lType.currentText() == 'ARC 3P': if P.landscape: W.conv_savedX = W.entry4.text() W.conv_savedY = W.entry5.text() do_arc_3_points(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry4.text()), float(W.entry5.text())) else: W.conv_savedX = W.entry3.text() W.conv_savedY = W.entry4.text() do_arc_3_points(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text()), float(W.entry4.text())) elif W.lType.currentText() == 'ARC 2P +RADIUS': W.conv_savedX = W.entry1.text() W.conv_savedY = W.entry2.text() if P.landscape: if float(W.entry4.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_2_points_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry4.text())) else: if float(W.entry3.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_2_points_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text())) elif W.lType.currentText() == 'ARC ANGLE +RADIUS': if float(W.entry3.text()) == 0: msg = 'Radius must be greater than zero.\n' error_set(P, msg) return else: do_arc_by_angle_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text())) except: msg = 'Invalid entry detected.\n' error_set(P, msg) outNgc.close() outTmp.close() return outTmp.write(P.conv_gcodeLine) outTmp.write('M5 $0\n') outTmp.close() outTmp = open(P.fTmp, 'r') for line in outTmp: outNgc.write(line) outTmp.close() outNgc.write('\n{} (postamble)\n'.format(P.postAmble)) outNgc.write('m2\n') outNgc.close() W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) W.undo.setEnabled(True) if P.conv_add_segment == 1: P.conv_add_segment = 2
def convert_pressed(self): # CHECK IF INI FILE NAME EXISTS if not self.iniIn: return # CHECK IF FULL PATH EXISTS if not os.path.dirname(self.iniIn): msg = 'Missing path to a PlasmaC configuration\n' self.dialog_ok('PATH ERROR', msg) self.fromFile.setFocus() return # CHECK IF VALID PLASMAC CONFIG if not os.path.exists('{}/plasmac'.format(os.path.dirname( self.iniIn))): msg = '{}\n'.format(self.iniIn) msg += '\n is not a PlasmaC configuration\n' self.dialog_ok('CONFIG ERROR', msg) self.fromFile.setFocus() return # CHECK IF SIM CONFIG simConfig = False with open(self.iniIn, 'r') as inFile: for line in inFile: if 'plasmac_test.py' in line and not line.startswith('#'): simConfig = True break # SET FILENAMES AND PATHS fName = os.path.basename(self.iniIn) newDir = os.path.dirname(self.iniIn) oldDir = '{}_{}_{}'.format(os.path.dirname(self.iniIn), 'plasmac', str(time.time()).split('.')[0]) newIniFile = os.path.join(newDir, fName) oldIniFile = os.path.join(oldDir, fName) # CREATE NEW DIRECTORY AND BACKUPS DIRECTORY try: os.rename(newDir, oldDir) os.makedirs('{}/backups'.format(newDir)) except: msg = 'Could not create directory\n'.format(newDir) self.dialog_ok('DIRECTORY ERROR', msg) return # GET THE MACHINE NAME with open(oldIniFile) as inFile: while (1): line = inFile.readline() if not line: print('cannot find [EMC] section in ini file') return if line.startswith('[EMC]'): break while (1): line = inFile.readline() if not line: print('cannot find MACHINE variable in ini file') return if line.startswith('MACHINE'): machineName = line.split('=')[1].strip().lower() break # COPY ORIGINAL BASE MACHINE FILES IF EXISTING try: for filename in os.listdir('{}/backups'.format(oldDir)): if filename.startswith('_original'): COPY('{}/backups/{}'.format(oldDir, filename), '{}/backups/{}'.format(newDir, filename)) except: pass # CREATE LINK TO QTPLASMAC COMMON FILES try: os.symlink(self.commonPath, '{}/qtplasmac'.format(newDir)) except: msg = 'Could not link to Common directory: ' msg += '{}\n'.format(self.commonPath) msg += '\nConversion cannot continue' self.dialog_ok('LINK ERROR', msg) self.fromFile.setFocus() return # COPY HAL FILES halFiles = [] oldPostguiFile = None newPostguiFile = None newConnectionsFile = None with open(oldIniFile, 'r') as inFile: while (1): line = inFile.readline() if line.startswith('[HAL]'): break if not line: msg = 'Could not get [HAL] section of ini file\n' msg += '\nConversion cannot continue' self.dialog_ok('INI FILE ERROR', msg) self.fromFile.setFocus() return while (1): line = inFile.readline() if line.startswith('POSTGUI_HALFILE'): oldPostguiFile = line.split('=')[1].strip() newPostguiFile = 'custom_postgui.hal' halFiles.append(oldPostguiFile) COPY('{}/{}'.format(oldDir, oldPostguiFile), '{}/{}'.format(newDir, newPostguiFile)) elif 'connections.hal' in line: oldConnectionsFile = line.split('=')[1].strip() newConnectionsFile = 'custom.hal' halFiles.append(newConnectionsFile) COPY('{}/{}'.format(oldDir, oldConnectionsFile), '{}/{}'.format(newDir, newConnectionsFile)) with open('{}/{}'.format(newDir, newConnectionsFile), 'w') as outConFile: with open('{}/{}'.format(oldDir, oldConnectionsFile), 'r') as inConFile: for line in inConFile: if 'plasmac:torch-on' in line: outConFile.write(line) outConFile.write( '\n#***** LASER ALIGNMENT CONNECTION *****\n' ) if self.laserOnPin.text(): outConFile.write( 'net plasmac:laser-on => {}\n'. format(self.laserOnPin.text())) else: outConFile.write( '# net plasmac:laser-on => {YOUR_LASER_ON_OUTPUT}\n\n' ) else: outConFile.write(line) elif line.startswith('HALFILE'): if 'plasmac.tcl' in line: halFiles.append('plasmac.tcl') else: hFile = line.split('=')[1].strip() with open('{}/{}'.format(oldDir, hFile), 'r') as inHal: if simConfig and 'motor-pos-cmd' in inHal.read(): halFiles.append('machine.tcl') COPY('{}/machine.tcl'.format(self.simPath), '{}/machine.tcl'.format(newDir)) else: halFiles.append(hFile) COPY('{}/{}'.format(oldDir, hFile), '{}/{}'.format(newDir, hFile)) if not line or line.startswith('['): break # COPY TOOL TABLE if os.path.exists('{}/tool.tbl'.format(oldDir)): COPY('{}/tool.tbl'.format(oldDir), '{}/tool.tbl'.format(newDir)) # PARSE ORIGINAL INI FILE TO FIND BUTTONS self.buttons = {} for n in range(1, 20): self.buttons[n] = None numButton = 1 n0, n1, name, code = '', '', '', '' with open(oldIniFile, 'r') as inFile: while (1): line = inFile.readline() if line.startswith('[PLASMAC]'): break while (1): line = inFile.readline() if line.startswith('['): break if line.startswith('BUTTON_') and '_NAME' in line: n0 = line.split('=')[0].strip().replace('BUTTON_', '').replace( '_NAME', '') name = line.split('=')[1].strip() if line.startswith('BUTTON_') and '_CODE' in line: n1 = line.split('=')[0].strip().replace('BUTTON_', '').replace( '_CODE', '') code = line.split('=')[1].strip() if n0 == n1 and name and code: self.buttons[numButton] = [name, code] n0, n1, name, code = '', '', '', '' numButton += 1 # MAKE NEW INI FILE section = '' with open(newIniFile, 'w') as outFile: with open(oldIniFile, 'r') as inFile: for line in inFile: # SET SECTION NAMES if line.startswith('['): section = '' if line.startswith('[APPLICATIONS]'): section = 'APPLICATIONS' if line.startswith('[PLASMAC]'): section = 'PLASMAC' line = '[QTPLASMAC]\n' if line.startswith('[FILTER]'): section = 'FILTER' if line.startswith('[RS274NGC]'): section = 'RS274NGC' if line.startswith('[HAL]'): section = 'HAL' if line.startswith('[DISPLAY]'): section = 'DISPLAY' if line.startswith('[EMC]'): section = 'EMC' # CONVERT SECTION PARAMETERS if section == 'APPLICATIONS': continue if section == 'PLASMAC': omissions = [ 'LAST', 'CONF', 'FONT', 'MAXI', 'WIND', 'THEM', 'AXIS', 'CONE', 'BUTT', 'PAUS', 'TORC' ] if line.startswith('#') or line.startswith('PM_PR'): continue if line[:4] in omissions: continue if line.startswith('['): outFile.write('\n') if line.strip(): if line.startswith('MODE'): outFile.write(line) outFile.write(self.estop) outFile.write( '#LASER_TOUCHOFF = X0.0 Y0.0\n') outFile.write( '#CAMERA_TOUCHOFF = X0.0 Y0.0\n') for n in range(1, 20): if self.buttons[n]: outFile.write( 'BUTTON_{}_NAME = {}\n'. format(n, self.buttons[n][0])) outFile.write( 'BUTTON_{}_CODE = {}\n'. format(n, self.buttons[n][1])) else: outFile.write(line) continue elif section == 'FILTER': if line.startswith('[FILTER]'): outFile.write('\n{}'.format(line)) outFile.write( 'PROGRAM_EXTENSION = .ngc,.nc,.tap GCode File (*.ngc, *.nc, *.tap)\n' ) outFile.write( 'ngc = ./qtplasmac/qtplasmac_gcode.py\n' ) outFile.write( 'nc = ./qtplasmac/qtplasmac_gcode.py\n' ) outFile.write( 'tap = ./qtplasmac/qtplasmac_gcode.py\n' ) continue elif section == 'RS274NGC': if line.startswith('SUBROUTINE') or line.startswith( 'USER_M_PATH'): if 'plasmac' in line: line = line.replace('plasmac', 'qtplasmac') else: line = '{}:./qtplasmac\n'.format(line.strip()) if line.startswith('#') or line.replace( ' ', '').strip() == 'FEATURES=12': continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue elif section == 'HAL': if line.startswith('[HAL]'): outFile.write('\n{}'.format(line)) outFile.write('TWOPASS = ON\n') outFile.write('HALUI = halui\n') for file in halFiles: if '_connections' in file: outFile.write( 'HALFILE = custom.hal\n' ) elif 'postgui' in file: outFile.write( 'POSTGUI_HALFILE = custom_postgui.hal\n' ) else: outFile.write( 'HALFILE = {}\n'. format(file)) if simConfig: outFile.write( 'POSTGUI_HALFILE = sim_postgui.tcl\n' ) continue elif section == 'DISPLAY': if line.startswith('DISPLAY'): line = self.display omissions = [ 'OPEN_F', 'EDITOR', 'TOOL_E', 'USER_C', 'EMBED_', 'GLADEV', 'CONE_B' ] if line.startswith('#'): continue if line[:6] in omissions: continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue elif section == 'EMC': if 'enable the axis_tweaks' in line: continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue # NO CONVERSION REQUIRED else: if line.strip(): if line.startswith('['): outFile.write('\n') if 'marry this config' in line or 'sim testing panel' in line: continue outFile.write(line) self.prefParms = [] if os.path.isfile(os.path.join(oldDir, machineName + '_config.cfg')): self.read_con_file( os.path.join(oldDir, machineName + '_config.cfg')) else: print('file not found, config parameters can not be converted.') if os.path.isfile(os.path.join(oldDir, machineName + '_run.cfg')): self.read_run_file(os.path.join(oldDir, machineName + '_run.cfg')) else: print('file not found, run parameters can not be converted.') if os.path.isfile(os.path.join(oldDir, machineName + '_wizards.cfg')): self.read_wiz_file( os.path.join(oldDir, machineName + '_wizards.cfg')) else: print('file not found, wizard parameters can not be converted.') if os.path.isfile(os.path.join(oldDir, 'plasmac_stats.var')): self.read_sta_file(os.path.join(oldDir, 'plasmac_stats.var')) else: print('file not found, statistics can not be converted.') if os.path.isfile(os.path.join(oldDir, machineName + '_material.cfg')): self.read_mat_file( os.path.join(oldDir, machineName + '_material.cfg'), newDir, machineName) else: print('file not found, materials can not be converted.') self.write_prefs_file(newDir, machineName) # ADD A SIM POSTGUI IF A SIM CONFIG if simConfig: with open('{}/{}'.format(newDir, 'sim_postgui.tcl'), 'a') as outFile: outFile.write(self.sim_postgui()) # WE GOT THIS FAR SO IT MAY HAVE WORKED msg = 'Conversion appears successful.\n' if self.mode == 'automatic': msg += '\nRestart LinuxCNC using the following ini file:\n' else: msg += '\nStart LinuxCNC using the following ini file:\n' msg += '\n{}/{}.ini\n'.format(newDir, machineName) self.dialog_ok('SUCCESS', msg) print(msg) sys.exit(0)
def preview(P, W, Conv): if P.dialogError or not W.preview.isEnabled(): return msg = [] try: columns = int(W.cnEntry.text()) except: msg.append(_translate('Conversational', 'COLUMNS NUMBER')) try: rows = int(W.rnEntry.text()) except: msg.append(_translate('Conversational', 'ROWS NUMBER')) try: xOffset = float(W.coEntry.text()) except: msg.append(_translate('Conversational', 'COLUMNS OFFSET')) try: yOffset = float(W.roEntry.text()) except: msg.append(_translate('Conversational', 'ROWS OFFSET')) try: xOrgOffset = float(W.xsEntry.text()) except: msg.append(_translate('Conversational', 'X OFFSET ORIGIN')) try: yOrgOffset = float(W.ysEntry.text()) except: msg.append(_translate('Conversational', 'Y OFFSET ORIGIN')) try: angle = float(W.aEntry.text()) except: msg.append(_translate('Conversational', 'ANGLE')) try: scale = float(W.scEntry.text()) if scale == 0: scale = 1 W.scEntry.setText('1') except: msg.append(_translate('Conversational', 'SCALE')) try: rotation = float(W.rtEntry.text()) except: msg.append(_translate('Conversational', 'ROTATION')) if msg: msg0 = _translate('Conversational', 'Invalid entry detected in') msg1 = '' for m in msg: msg1 += '{}\n'.format(m) error_set(P, W, '{}:\n\n{}'.format(msg0, msg1)) return # if columns > 0 and rows > 0 and (columns == 1 or (columns > 1 and xOffset != 0)) and (rows == 1 or (rows > 1 and yOffset != 0)): if 1: COPY(P.fNgc, P.fTmp) inCode = open(P.fTmp, 'r') outNgc = open(P.fNgc, 'w') # edit existing parameters if P.convBlock[0]: indent = False for line in inCode: if line.startswith('#<array_x_offset>'): line = '#<array_x_offset> = {}\n'.format(xOffset) elif line.startswith('#<array_y_offset>'): line = '#<array_y_offset> = {}\n'.format(yOffset) elif line.startswith('#<array_columns>'): line = '#<array_columns> = {}\n'.format(columns) elif line.startswith('#<array_rows>'): line = '#<array_rows> = {}\n'.format(rows) elif line.startswith('#<origin_x_offset>'): line = '#<origin_x_offset> = {}\n'.format(xOrgOffset) elif line.startswith('#<origin_y_offset>'): line = '#<origin_y_offset> = {}\n'.format(yOrgOffset) elif line.startswith('#<array_angle>'): line = '#<array_angle> = {}\n'.format(angle) elif line.startswith('#<blk_scale>'): line = '#<blk_scale> = {}\n'.format(scale) elif line.startswith('#<shape_angle>'): line = '#<shape_angle> = {}\n'.format(rotation) elif line.startswith('#<shape_mirror>'): line = '#<shape_mirror> = {}\n'.format(P.convMirror) elif line.startswith('#<shape_flip>'): line = '#<shape_flip> = {}\n'.format(P.convFlip) elif '#<shape_mirror>' in line and (P.convMirrorToggle or P.convFlipToggle): if 'g2' in line: line = line.replace('g2', 'g3') elif 'g3' in line: line = line.replace('g3', 'g2') outNgc.write('{}'.format(line)) # create new array else: xIndex = [5221, 5241, 5261, 5281, 5301, 5321, 5341, 5361, 5381][0] outNgc.write(';conversational block\n\n') # inputs outNgc.write(';inputs\n') outNgc.write('#<ucs_x_offset> = #{}\n'.format(xIndex)) outNgc.write('#<ucs_y_offset> = #{}\n'.format(xIndex + 1)) outNgc.write('#<ucs_r_offset> = #{}\n'.format(xIndex + 9)) outNgc.write('#<array_x_offset> = {}\n'.format(xOffset)) outNgc.write('#<array_y_offset> = {}\n'.format(yOffset)) outNgc.write('#<array_columns> = {}\n'.format(columns)) outNgc.write('#<array_rows> = {}\n'.format(rows)) outNgc.write('#<origin_x_offset> = {}\n'.format(xOrgOffset)) outNgc.write('#<origin_y_offset> = {}\n'.format(yOrgOffset)) outNgc.write('#<array_angle> = {}\n'.format(angle)) outNgc.write('#<blk_scale> = {}\n'.format(scale)) outNgc.write('#<shape_angle> = {}\n'.format(rotation)) outNgc.write('#<shape_mirror> = {}\n'.format(P.convMirror)) outNgc.write('#<shape_flip> = {}\n\n'.format(P.convFlip)) # calculations outNgc.write(';calculations\n') outNgc.write('#<this_col> = 0\n') outNgc.write('#<this_row> = 0\n') outNgc.write( '#<blk_x_offset> = [#<origin_x_offset> + [#<ucs_x_offset> * {}]]\n' .format(P.convUnits[0])) outNgc.write( '#<blk_y_offset> = [#<origin_y_offset> + [#<ucs_y_offset> * {}]]\n' .format(P.convUnits[0])) outNgc.write( '#<x_sin> = [[#<array_x_offset> * #<blk_scale>] * SIN[#<array_angle>]]\n' ) outNgc.write( '#<x_cos> = [[#<array_x_offset> * #<blk_scale>] * COS[#<array_angle>]]\n' ) outNgc.write( '#<y_sin> = [[#<array_y_offset> * #<blk_scale>] * SIN[#<array_angle>]]\n' ) outNgc.write( '#<y_cos> = [[#<array_y_offset> * #<blk_scale>] * COS[#<array_angle>]]\n\n' ) # main loop outNgc.write(';main loop\n') outNgc.write('o<loop> while [#<this_row> LT #<array_rows>]\n') outNgc.write( ' #<shape_x_start> = [[#<this_col> * #<x_cos>] - [#<this_row> * #<y_sin>] + #<blk_x_offset>]\n' ) outNgc.write( ' #<shape_y_start> = [[#<this_row> * #<y_cos>] + [#<this_col> * #<x_sin>] + #<blk_y_offset>]\n' ) outNgc.write( ' #<blk_angle> = [#<shape_angle> + #<array_angle> + #<ucs_r_offset>]\n' ) if P.convUnits[1]: outNgc.write(' {}\n'.format(P.convUnits[1])) outNgc.write( ' G10 L2 P0 X#<shape_x_start> Y#<shape_y_start> R#<blk_angle>\n\n' ) # the shape started, ended = False, False for line in inCode: line = line.strip().lower() # remove line numbers if line.startswith('n'): line = line[1:] while line[0].isdigit() or line[0] == '.': line = line[1:].lstrip() if not line: break # remove leading 0's from G & M codes elif (line.lower().startswith('g') or \ line.lower().startswith('m')) and \ len(line) > 2: while line[1] == '0' and len(line) > 2: if line[2].isdigit(): line = line[:1] + line[2:] else: break # scale the shape if len(line) and line[0] in 'gxyz': started = True rLine = scale_shape(P, W, line) if rLine is not None: outNgc.write(' {}\n'.format(rLine)) else: return # loop counter elif not ended and ('m2' in line or 'm30' in line or (line.startswith('%') and started)): ended = True outNgc.write('\n #<this_col> = [#<this_col> + 1]\n') outNgc.write( ' o<count> if [#<this_col> EQ #<array_columns>]\n') outNgc.write(' #<this_col> = 0\n') outNgc.write(' #<this_row> = [#<this_row> + 1]\n') outNgc.write(' o<count> endif\n') outNgc.write('o<loop> endwhile\n') elif not line: outNgc.write('\n') elif ended and ('m2' in line or 'm30' in line or line.startswith('%')): pass else: outNgc.write(' {}\n'.format(line)) # reset offsets to original outNgc.write( '\nG10 L2 P0 X[#<ucs_x_offset> * {0}] Y[#<ucs_y_offset> * {0}] R#<ucs_r_offset>\n' .format(P.convUnits[0])) outNgc.write('\nM2\n') inCode.close() outNgc.close() W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) W.undo.setEnabled(True) Conv.conv_preview_button(P, W, True) else: msg = [] if columns <= 0: msg.append( _translate('Conversational', 'COLUMNS entries are required')) if rows <= 0: msg.append( _translate('Conversational', 'ROWS entries are required')) if xOffset == 0 and columns > 1: msg.append( _translate('Conversational', 'COLUMNS OFFSET is required')) if yOffset == 0 and rows > 1: msg.append(_translate('Conversational', 'ROWS OFFSET is required')) msg0 = '' for m in msg: msg0 += '{}.\n\n'.format(m) error_set(P, W, msg0) return W.add.setEnabled(True) P.convBlock[0] = True P.convMirrorToggle = False P.convFlipToggle = False
def cancel(P, W, widget): COPY(P.fNgcBkp, P.fNgc) if widget: P.conv_preview.load(P.fNgc)
def accept(P, W): COPY(P.fNgc, P.fNgcBkp) P.conv_preview.load(P.fNgc)
def cancel(P, W): COPY(P.fNgcBkp, P.fNgc) W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(False) W.undo.setEnabled(False)
def preview(P, W): invalidLine = False # check all entries are valid # try: if 1: try: if not W.entry1.text(): W.entry1.setText('{:0.3f}'.format(P.xLineStart)) P.xLineStart = float(W.entry1.text()) W.entry1.setText('{:0.3f}'.format(float(W.entry1.text()))) except: msg0 = _translate('Conversational', 'Invalid X ORIGIN entry detected') error_set(P, '{}.\n'.format(msg0)) invalidLine = True try: if not W.entry2.text(): W.entry2.setText('{:0.3f}'.format(P.yLineStart)) P.yLineStart = float(W.entry2.text()) W.entry2.setText('{:0.3f}'.format(float(W.entry2.text()))) except: msg0 = _translate('Conversational', 'Invalid Y ORIGIN entry detected') error_set(P, '{}.\n'.format(msg0)) invalidLine = True if P.lAlias == 'LP2P': if P.landscape: entry_check(P, W, W.entry4, 'x') entry_check(P, W, W.entry5, 'x') entry = [W.entry4, W.entry5] else: entry_check(P, W, W.entry3, 'x') entry_check(P, W, W.entry4, 'y') entry = [W.entry3, W.entry4] if float(entry[0].text()) == float(W.entry1.text()) and \ float(entry[1].text()) == float(W.entry2.text()): msg0 = _translate('Conversational', 'Line length would be zero') error_set(P, '{}.\n'.format(msg0)) invalidLine = True else: invalidLine = do_line_point_to_point(P, W, float(entry[0].text()), \ float(entry[1].text())) elif P.lAlias == 'LBLA': if P.landscape: entry_check(P, W, W.entry4, None) entry_check(P, W, W.entry5, None) entry = [W.entry4, W.entry5] else: entry_check(P, W, W.entry3, None) entry_check(P, W, W.entry5, None) entry = [W.entry3, W.entry5] if float(entry[0].text()) <= 0: msg0 = _translate('Conversational', 'Length must be greater than zero') error_set(P, '{}.\n'.format(msg0)) invalidLine = True else: invalidLine = do_line_by_angle(P, W, float(entry[0].text()), \ float(entry[1].text())) elif P.lAlias == 'A3Pt': if P.landscape: entry_check(P, W, W.entry4, 'x') entry_check(P, W, W.entry5, 'y') entry_check(P, W, W.entry7, 'x') entry_check(P, W, W.entry8, 'y') entry = [W.entry4, W.entry5, W.entry7, W.entry8] else: entry_check(P, W, W.entry3, 'x') entry_check(P, W, W.entry4, 'y') entry_check(P, W, W.entry5, 'x') entry_check(P, W, W.entry6, 'y') entry = [W.entry3, W.entry4, W.entry5, W.entry6] invalidLine = do_arc_3_points(P, W, float(entry[0].text()), \ float(entry[1].text()), float(entry[2].text()), float(entry[3].text())) elif P.lAlias == 'A2PR': if P.landscape: entry_check(P, W, W.entry4, 'x') entry_check(P, W, W.entry5, 'y') entry_check(P, W, W.entry7, None) entry = [W.entry4, W.entry5, W.entry7] else: entry_check(P, W, W.entry3, 'x') entry_check(P, W, W.entry4, 'y') entry_check(P, W, W.entry5, None) entry = [W.entry3, W.entry4, W.entry5] if float(entry[2].text()) == 0: msg0 = _translate('Conversational', 'Radius must be greater than zero') error_set(P, '{}.\n'.format(msg0)) invalidLine = True else: invalidLine = do_arc_2_points_radius(P, W, float(entry[0].text()), \ float(entry[1].text()), float(entry[2].text())) elif P.lAlias == 'ALAR': if P.landscape: entry_check(P, W, W.entry4, None) entry_check(P, W, W.entry5, None) entry_check(P, W, W.entry7, None) entry = [W.entry4, W.entry5, W.entry7] radius = float(W.entry7.text()) else: entry_check(P, W, W.entry3, None) entry_check(P, W, W.entry4, None) entry_check(P, W, W.entry5, None) entry = [W.entry3, W.entry4, W.entry5] radius = float(W.entry5.text()) if float(entry[2].text()) == 0: msg0 = _translate('Conversational', 'Radius must be greater than zero') error_set(P, '{}.\n'.format(msg0)) invalidLine = True else: invalidLine = do_arc_by_angle_radius(P, W, float(entry[0].text()), \ float(entry[1].text()), float(entry[2].text())) # except: else: msg0 = _translate('Conversational', 'Invalid entry detected') error_set(P, '{}.\n'.format(msg0)) return if invalidLine: return #do next segment if P.conv_add_segment == 1: inTmp = open(P.fNgc, 'r') outTmp = open(P.fTmp, 'w') while (1): line = inTmp.readline() if not line or 'M5 $0' in line: break else: outTmp.write(line) inTmp.close() COPY(P.fTmp, P.fNgc) outNgc = open(P.fNgc, 'w') # do first segment else: outTmp = open(P.fTmp, 'w') outNgc = open(P.fNgc, 'w') inWiz = open(P.fNgcBkp, 'r') for line in inWiz: if '(new conversational file)' in line: outNgc.write('\n{} (preamble)\n'.format(P.preAmble)) break elif '(postamble)' in line: break elif 'm2' in line.lower() or 'm30' in line.lower(): break outNgc.write(line) outTmp.write('\n(conversational {})\n'.format(W.lType.currentText())) outTmp.write('M190 P{}\n'.format( int(W.conv_material.currentText().split(':')[0]))) outTmp.write('M66 P3 L3 Q1\n') outTmp.write('f#<_hal[plasmac.cut-feed-rate]>\n') outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(P.xLineStart, P.yLineStart)) outTmp.write('m3 $0 s1\n') # write the gcode outTmp.write(P.conv_gcodeLine) outTmp.write('M5 $0\n') outTmp.close() outTmp = open(P.fTmp, 'r') for line in outTmp: outNgc.write(line) outTmp.close() outNgc.write('\n{} (postamble)\n'.format(P.postAmble)) outNgc.write('m2\n') outNgc.close() P.conv_preview_button(True) W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) W.undo.setEnabled(True) if P.conv_add_segment == 1: P.conv_add_segment = 2 P.previewActive = True
def preview(P, W): if P.dialogError: return try: columns = int(W.cnEntry.text()) except: columns = 1 try: rows = int(W.rnEntry.text()) except: rows = 1 try: xOffset = float(W.coEntry.text()) except: xOffset = 0 try: yOffset = float(W.roEntry.text()) except: yOffset = 0 try: xOrgOffset = float(W.oxEntry.text()) except: xOrgOffset = 0 try: yOrgOffset = float(W.oyEntry.text()) except: yOrgOffset = 0 if columns > 0 and rows > 0 and (columns == 1 or (columns > 1 and xOffset != 0)) and (rows == 1 or (rows > 1 and yOffset != 0)): cancel(P, W, None) if P.arrayMode == 'conversational': fPre = [] fPst = [] outCod = open(P.fTmp, 'w') inWiz = open(P.fNgc, 'r') while(1): d = inWiz.readline() if d.startswith('(conversational'): outCod.write(d) break fPre.append(d) while(1): d = inWiz.readline() if '(postamble' in d: fPst.append(d) break outCod.write(d) while(1): d = inWiz.readline() if not d: break fPst.append(d) outCod.close() inWiz.close() outNgc = open(P.fNgc, 'w') for line in fPre: outNgc.write(line) for row in range(rows): for column in range(columns): outNgc.write('\n(row:{} column:{})\n'.format(row + 1, column + 1)) inCod = open(P.fTmp, 'r') for line in inCod: raw = line.strip().lower() if (raw.startswith('g0') or raw.startswith('g1') or raw.startswith('g2') or raw.startswith('g3')) and \ not raw.replace(' ','').startswith('g0z[#<_ini[axis_z]max_limit>-'): a, b = raw.split('x') c, d = b.split('y') if ('i') in d: e, f = d.split('i') f = 'i' + f else: e = d f = '' outNgc.write('{}x{} y{} {}\n'.format \ (a, (float(c) + column * xOffset) + xOrgOffset, (float(e) + row * yOffset) + yOrgOffset, f)) else: outNgc.write(line) inCod.close() for line in fPst: outNgc.write(line) outNgc.close() W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) W.undo.setEnabled(True) else: COPY(P.fNgc, P.fTmp) inCod = open(P.fTmp, 'r') units = 1 for line in inCod: if 'G21' in line.upper().replace(' ', '') and P.unitsPerMm != 1: units = 25.4 break if 'G20' in line.upper().replace(' ', '') and P.unitsPerMm == 1: units = 0.03937 break outNgc = open(P.fNgc, 'w') xIndex = [5221,5241,5261,5281,5301,5321,5341,5361,5381][0] outNgc.write('#<ucs_x_offset> = #{}\n'.format(xIndex)) outNgc.write('#<ucs_y_offset> = #{}\n'.format(xIndex + 1)) for row in range(rows): for column in range(columns): outNgc.write('\n(row:{} column:{})\n'.format(row + 1, column + 1)) if P.arrayMode == 'external': outNgc.write('G10 L2 P0 X[{} + #<ucs_x_offset>] Y[{} + #<ucs_y_offset>]\n'.format\ ((column * xOffset * units) + xOrgOffset, (row * yOffset * units) + yOrgOffset)) else: # check this down the track for arraying external arrays multiple times outNgc.write('G10 L2 P0 X{} Y{} ($$$$$$)\n'.format\ ((column * xOffset * units) + xOrgOffset, (row * yOffset * units) + yOrgOffset)) inCod = open(P.fTmp, 'r') for line in inCod: a = b = c = '' a = line.upper().replace(' ', '') if 'M2' in a or 'M30' in a: b = a.replace('M2', '') c = b.replace('M30', '') outNgc.write(c) elif '(postamble)' in line: pass else: outNgc.write(line) inCod.close() outNgc.write('G10 L2 P0 X#<ucs_x_offset> Y#<ucs_y_offset>\n') outNgc.write('M2\n') outNgc.close() W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) W.undo.setEnabled(True) else: msg = '' if columns <= 0: msg += 'Columns are required\n\n' if rows <= 0: msg += 'Rows are required\n\n' if xOffset == 0 and columns > 1: msg += 'Column Offset is required\n\n' if yOffset == 0 and rows > 1: msg += 'Row Offset is required' P.dialogError = True P.dialog_error('ARRAY', msg) return W.add.setEnabled(True)
def preview(P, W): if P.dialogError: return if W.add_segment == 0: try: if not W.entry1.text(): W.entry1.setText('{:0.3f}'.format(P.xOrigin)) W.xS = float(W.entry1.text()) if not W.entry2.text(): W.entry2.setText('{:0.3f}'.format(P.yOrigin)) W.yS = float(W.entry2.text()) except: msg = 'Invalid entry detected\n' P.dialogError = True P.dialog_error('LINE', msg) return outTmp = open(P.fTmp, 'w') outNgc = open(P.fNgc, 'w') inWiz = open(P.fNgcBkp, 'r') for line in inWiz: if '(new conversational file)' in line: outNgc.write('\n{} (preamble)\n'.format(P.preAmble)) break elif '(postamble)' in line: break elif 'm2' in line.lower() or 'm30' in line.lower(): break outNgc.write(line) outTmp.write('\n(conversational line)\n') outTmp.write('M190 P{}\n'.format( int(W.conv_material.currentText().split(':')[0]))) outTmp.write('M66 P3 L3 Q1\n') outTmp.write('f#<_hal[plasmac.cut-feed-rate]>\n') outTmp.write('g0 x{:.6f} y{:.6f}\n'.format(W.xS, W.yS)) outTmp.write('m3 $0 s1\n') try: # if W.lType.currentText() == 'line point to point': # if P.landscape: # W.savedX = W.entry4.text() # W.savedY = W.entry5.text() # do_line_point_to_point(P, W, float(W.entry4.text()), float(W.entry5.text())) # else: # W.savedX = W.entry3.text() # W.savedY = W.entry4.text() # do_line_point_to_point(P, W, float(W.entry3.text()), float(W.entry4.text())) # elif W.lType.currentText() == 'line by angle': # if not float(W.entry4.text()): # raise Exception('length cannot be 0') # if P.landscape: # do_line_by_angle(P, W, float(W.entry4.text()), float(W.entry5.text())) # else: # do_line_by_angle(P, W, float(W.entry3.text()), float(W.entry5.text())) # elif W.lType.currentText() == 'arc 3p': # if P.landscape: # W.savedX = W.entry7.text() # W.savedY = W.entry8.text() # do_arc_3_points(P, W, float(W.entry4.text()), float(W.entry5.text()), \ # float(W.entry7.text()), float(W.entry8.text())) # else: # W.savedX = W.entry5.text() # W.savedY = W.entry6.text() # do_arc_3_points(P, W, float(W.entry3.text()), float(W.entry4.text()), \ # float(W.entry5.text()), float(W.entry6.text())) # elif W.lType.currentText() == 'arc 2p & radius': # if P.landscape: # W.savedX = W.entry4.text() # W.savedY = W.entry5.text() # do_arc_2_points_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ # float(W.entry7.text())) # else: # W.savedX = W.entry3.text() # W.savedY = W.entry4.text() # do_arc_2_points_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ # float(W.entry5.text())) # elif W.lType.currentText() == 'arc angle & radius': # if P.landscape: # do_arc_by_angle_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ # float(W.entry7.text())) # else: # do_arc_by_angle_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ # float(W.entry5.text())) if W.lType.currentText() == 'line point to point': if P.landscape: W.savedX = W.entry4.text() W.savedY = W.entry5.text() do_line_point_to_point(P, W, float(W.entry4.text()), float(W.entry5.text())) else: W.savedX = W.entry3.text() W.savedY = W.entry4.text() do_line_point_to_point(P, W, float(W.entry3.text()), float(W.entry4.text())) elif W.lType.currentText() == 'line by angle': if not float(W.entry4.text()): raise Exception('length cannot be 0') if P.landscape: do_line_by_angle(P, W, float(W.entry4.text()), float(W.entry5.text())) else: do_line_by_angle(P, W, float(W.entry3.text()), float(W.entry5.text())) elif W.lType.currentText() == 'arc 3p': if P.landscape: W.savedX = W.entry7.text() W.savedY = W.entry8.text() do_arc_3_points(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text()), float(W.entry8.text())) else: W.savedX = W.entry5.text() W.savedY = W.entry6.text() do_arc_3_points(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text()), float(W.entry6.text())) elif W.lType.currentText() == 'arc 2p & radius': if P.landscape: W.savedX = W.entry4.text() W.savedY = W.entry5.text() do_arc_2_points_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text())) else: W.savedX = W.entry3.text() W.savedY = W.entry4.text() do_arc_2_points_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text())) elif W.lType.currentText() == 'arc angle & radius': if P.landscape: do_arc_by_angle_radius(P, W, float(W.entry4.text()), float(W.entry5.text()), \ float(W.entry7.text())) else: do_arc_by_angle_radius(P, W, float(W.entry3.text()), float(W.entry4.text()), \ float(W.entry5.text())) except Exception as e: msg = 'Last entry is not valid\n\n' msg += str(e) P.dialogError = True P.dialog_error('LINE', msg) outNgc.close() outTmp.close() return elif W.add_segment >= 1: print('ADD ANOTHER SEGMENT') inTmp = open(P.fNgc, 'r') outTmp = open(P.fTmp, 'w') while (1): line = inTmp.readline() if not line or line == W.gcodeLine: break else: outTmp.write(line) if W.add_segment == 1: outTmp.write(line) while (1): line = inTmp.readline() if 'M5 $0' in line: break else: outTmp.write(line) inTmp.close() COPY(P.fTmp, P.fNgc) outNgc = open(P.fNgc, 'w') try: if W.lType.currentText() == 'line point to point': W.savedX = W.entry1.text() W.savedY = W.entry2.text() do_line_point_to_point(P, W, float(W.entry1.text()), float(W.entry2.text())) elif W.lType.currentText() == 'line by angle': if not float(W.entry1.text()): raise Exception('Length cannot be 0') do_line_by_angle(P, W, float(W.entry1.text()), float(W.entry2.text())) elif W.lType.currentText() == 'arc 3p': if P.landscape: W.savedX = W.entry4.text() W.savedY = W.entry5.text() do_arc_3_points(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry4.text()), float(W.entry5.text())) else: W.savedX = W.entry3.text() W.savedY = W.entry4.text() do_arc_3_points(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text()), float(W.entry4.text())) elif W.lType.currentText() == 'arc 2p & radius': W.savedX = W.entry1.text() W.savedY = W.entry2.text() if P.landscape: do_arc_2_points_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry4.text())) else: do_arc_2_points_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text())) elif W.lType.currentText() == 'arc angle & radius': print('arc by angle radius', W.entry1.text(), W.entry2.text(), W.entry3.text()) do_arc_by_angle_radius(P, W, float(W.entry1.text()), float(W.entry2.text()), \ float(W.entry3.text())) except Exception as e: msg = 'Last entry is not Invalid\n\n' msg += str(e) P.dialogError = True P.dialog_error('LINE', msg) outNgc.close() outTmp.close() return outTmp.write(W.gcodeLine) outTmp.write('M5 $0\n') outTmp.close() outTmp = open(P.fTmp, 'r') for line in outTmp: outNgc.write(line) outTmp.close() outNgc.write('\n{} (postamble)\n'.format(P.postAmble)) outNgc.write('m2\n') outNgc.close() W.conv_preview.load(P.fNgc) W.conv_preview.set_current_view() W.add.setEnabled(True) # W.continu.setEnabled(True) if W.add_segment == 1: W.add_segment = 2
def convert_pressed(self): # CHECK IF PLASMAC CONFIG SELECTED simConfig = False if not self.fromFilePath: msg = 'Missing path to PlasmaC configuration\n' self.dialog_ok('PATH ERROR', msg) self.fromFile.setFocus() return else: # CHECK IF SIM CONFIG with open(self.fromFileName, 'r') as inFile: for line in inFile: if 'plasmac_test.py' in line and not line.startswith('#'): simConfig = True break # CHECK IF NEW NAME ENTERED if not self.newName.text(): msg = 'Missing name for QtPlasmaC configuration\n' self.dialog_ok('NAME ERROR', msg) self.newName.setFocus() return # CREATE NAMES newName = self.newName.text() newDir = '{}/{}'.format(self.DIR, newName) oldDir = os.path.dirname(self.fromFileName) # check if directory already exists if os.path.exists(newDir): msg = '{} already exists\n'.format(newDir) self.dialog_ok('DUPLICATE ERROR', msg) self.newName.setFocus() return # CHECK IF VALID PLASMAC CONFIG if not os.path.exists('{}/plasmac'.format(oldDir)): msg = '{}\n'.format(self.fromFileName) msg += '\n is not a PlasmaC configurtion\n' self.dialog_ok('CONFIG ERROR', msg) self.fromFile.setFocus() return # CREATE NEW DIRECTORY AND BACKUPS DIRECTORY try: os.makedirs('{}/backups'.format(newDir)) except: msg = 'Could not create directory\n'.format(newDir) self.dialog_ok('DIRECTORY ERROR', msg) self.newName.setFocus() return # COPY ORIGINAL BASE MACHINE FILES IF EXISTING try: for filename in os.listdir('{}/backups'.format(oldDir)): if filename.startswith('_original'): COPY('{}/backups/{}'.format(oldDir, filename), '{}/backups/{}'.format(newDir, filename)) except: pass # CREATE LINK TO QTPLASMAC COMMON FILES try: os.symlink(self.commonPath , '{}/qtplasmac'.format(newDir)) except: msg = 'Could not link to Common directory: ' msg += '{}\n'.format(self.commonPath) msg += '\nConversion cannot continue' self.dialog_ok('LINK ERROR', msg) self.fromFile.setFocus() return # COPY HAL FILES halFiles = [] oldPostguiFile = None newPostguiFile = None newConnectionsFile = None with open(self.fromFileName, 'r') as inFile: while(1): line = inFile.readline() if line.startswith('[HAL]'): break if not line: msg = 'Could not get [HAL] section of ini file\n' msg += '\nConversion cannot continue' self.dialog_ok('INI FILE ERROR', msg) self.fromFile.setFocus() return while(1): line = inFile.readline() if line.startswith('POSTGUI_HALFILE'): oldPostguiFile = line.split('=')[1].strip() newPostguiFile = oldPostguiFile.replace('.hal', '.tcl') halFiles.append(oldPostguiFile) COPY('{}/{}'.format(oldDir, oldPostguiFile), '{}/{}'.format(newDir, newPostguiFile)) elif 'connections.hal' in line: oldConnectionsFile = line.split('=')[1].strip() newConnectionsFile = '{}_connections.hal'.format(newName) halFiles.append(newConnectionsFile) COPY('{}/{}'.format(oldDir, oldConnectionsFile), '{}/{}'.format(newDir, newConnectionsFile)) elif line.startswith('HALFILE'): if 'plasmac.tcl' in line: halFiles.append('plasmac.tcl') else: hFile = line.split('=')[1].strip() with open('{}/{}'.format(oldDir, hFile), 'r') as inHal: if simConfig and 'motor-pos-cmd' in inHal.read(): halFiles.append('machine.tcl') COPY('{}/machine.tcl'.format(self.simPath), '{}/machine.tcl'.format(newDir)) else: halFiles.append(hFile) COPY('{}/{}'.format(oldDir, hFile), '{}/{}'.format(newDir, hFile)) if not line or line.startswith('['): break # COPY TOOL TABLE if os.path.exists('{}/tool.tbl'.format(oldDir)): COPY('{}/tool.tbl'.format(oldDir), '{}/tool.tbl'.format(newDir)) # PARSE ORIGINAL INI FILE TO FIND BUTTONS self.buttons = {} for n in range(1, 20): self.buttons[n] = None numButton = 1 n0,n1,name,code = '','','','' with open(self.fromFileName, 'r') as inFile: while(1): line = inFile.readline() if line.startswith('[PLASMAC]'): break while(1): line = inFile.readline() if line.startswith('['): break if line.startswith('BUTTON_') and '_NAME' in line: n0 = line.split('=')[0].strip().replace('BUTTON_','').replace('_NAME','') name = line.split('=')[1].strip() if line.startswith('BUTTON_') and '_CODE' in line: n1 = line.split('=')[0].strip().replace('BUTTON_','').replace('_CODE','') code = line.split('=')[1].strip() if n0 == n1 and name and code: self.buttons[numButton] = [name, code] n0,n1,name,code = '','','','' numButton += 1 # MAKE NEW INI FILE section = '' with open('{}/{}.ini'.format(newDir, newName), 'w') as outFile: with open(self.fromFileName, 'r') as inFile: for line in inFile: # SET SECTION NAMES if line.startswith('['): section = '' if line.startswith('[APPLICATIONS]'): section = 'APPLICATIONS' if line.startswith('[PLASMAC]'): section = 'PLASMAC' line = '[QTPLASMAC]\n' xtraButtons = [] if line.startswith('[FILTER]'): section = 'FILTER' if line.startswith('[RS274NGC]'): section = 'RS274NGC' if line.startswith('[HAL]'): section = 'HAL' if line.startswith('[DISPLAY]'): section = 'DISPLAY' if line.startswith('[EMC]'): section = 'EMC' # CONVERT SECTION PARAMETERS if section == 'APPLICATIONS': continue if section == 'PLASMAC': omissions = ['LAST','CONF','FONT','MAXI','WIND','THEM','AXIS','CONE','BUTT','PAUS','TORC'] if line.startswith('#') or line.startswith('PM_PR'): continue if line[:4] in omissions: continue if line.startswith('['): outFile.write('\n') if line.strip(): if line.startswith('MODE'): outFile.write(line) outFile.write(self.estop) if self.laserX.text(): try: self.laserXOffset = float(self.laserX.text()) except: self.dialog_ok('ERROR','Laser X Offset is invalid and will be set to 0.0') self.laserXOffset = 0.0 if self.laserY.text(): try: self.laserYOffset = float(self.laserY.text()) except: self.dialog_ok('ERROR','Laser Y Offset is invalid and will be set to 0.0') self.laserYOffset = 0.0 if self.laserXOffset or self.laserYOffset: outFile.write('LASER_TOUCHOFF = X{:0.4f} Y{:0.4f}\n' \ .format(self.laserXOffset, self.laserYOffset)) else: outFile.write('#LASER_TOUCHOFF = X0.0 Y0.0\n') if self.cameraX.text(): try: self.cameraXOffset = float(self.cameraX.text()) except: self.dialog_ok('ERROR','Camera X Offset is invalid and will be set to 0.0') self.cameraXOffset = 0.0 if self.cameraY.text(): try: self.cameraYOffset = float(self.cameraY.text()) except: self.dialog_ok('ERROR','Camera Y Offset is invalid and will be set to 0.0') self.cameraYOffset = 0.0 if self.cameraXOffset or self.cameraYOffset: outFile.write('CAMERA_TOUCHOFF = X{:0.4f} Y{:0.4f}\n' \ .format(self.cameraXOffset, self.cameraYOffset)) else: outFile.write('#CAMERA_TOUCHOFF = X0.0 Y0.0\n') for n in range(1, 9): if self.buttons[n]: outFile.write('BUTTON_{}_NAME = {}\n'.format(n, self.buttons[n][0])) outFile.write('BUTTON_{}_CODE = {}\n'.format(n, self.buttons[n][1])) for n in range(9, 20): if self.buttons[n]: b = [] b.append(self.buttons[n][0]) b.append(self.buttons[n][1]) xtraButtons.append(b) if xtraButtons: print('\n**********') print('The maximum number of user buttons is eight') print('The following have not been allocated to a user button:\n') for b in xtraButtons: print('NAME:{} CODE:{}\n'.format(b[0], b[1])) print('**********\n') else: outFile.write(line) continue elif section == 'FILTER': if line.startswith('[FILTER]'): outFile.write('\n{}'.format(line)) outFile.write('PROGRAM_EXTENSION = .ngc,.nc,.tap GCode File (*.ngc, *.nc, *.tap)\n') outFile.write('ngc = ./qtplasmac/qtplasmac_gcode.py\n') outFile.write('nc = ./qtplasmac/qtplasmac_gcode.py\n') outFile.write('tap = ./qtplasmac/qtplasmac_gcode.py\n') continue elif section == 'RS274NGC': if line.startswith('SUBROUTINE') or line.startswith('USER_M_PATH'): if 'plasmac' in line: line = line.replace('plasmac', 'qtplasmac') else: line = '{}:./qtplasmac\n'.format(line.strip()) if line.startswith('#') or line.replace(' ', '').strip() == 'FEATURES=12': continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue elif section == 'HAL': if line.startswith('[HAL]'): outFile.write('\n{}'.format(line)) outFile.write('TWOPASS = ON\n') for file in halFiles: if 'postgui' in file: outFile.write('POSTGUI_HALFILE = {}\n'.format(file.replace('.hal', '.tcl'))) else: outFile.write('HALFILE = {}\n'.format(file)) outFile.write('HALUI = halui\n') continue elif section == 'DISPLAY': if line.startswith('DISPLAY'): line = self.display omissions = ['OPEN_F','EDITOR','TOOL_E','USER_C','EMBED_','GLADEV','CONE_B'] if line.startswith('#'): continue if line[:6] in omissions: continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue elif section == 'EMC': if line.startswith('MACHINE'): line = 'MACHINE = {}\n'.format(newName) if 'enable the axis_tweaks' in line: continue if line.startswith('['): outFile.write('\n') if line.strip(): outFile.write(line) continue # NO CONVERSION REQUIRED else: if line.strip(): if line.startswith('['): outFile.write('\n') if 'marry this config' in line or 'sim testing panel' in line: continue outFile.write(line) # GET THE ORIGINAL MACHINE NAME with open(self.fromFileName) as inFile: while(1): line = inFile.readline() if not line: print('cannot find [EMC] section in ini file') return if line.startswith('[EMC]'): break while(1): line = inFile.readline() if not line: print('cannot find MACHINE variable in ini file') return if line.startswith('MACHINE'): self.fromMachine = line.split('=')[1].strip().lower() break self.prefParms = [] if os.path.isfile(os.path.join(self.fromFilePath, self.fromMachine + '_config.cfg')): self.read_con_file(os.path.join(self.fromFilePath, self.fromMachine + '_config.cfg')) else: print('file not found, config parameters can not be converted.') if os.path.isfile(os.path.join(self.fromFilePath, self.fromMachine + '_run.cfg')): self.read_run_file(os.path.join(self.fromFilePath, self.fromMachine + '_run.cfg')) else: print('file not found, run parameters can not be converted.') if os.path.isfile(os.path.join(self.fromFilePath, self.fromMachine + '_wizards.cfg')): self.read_wiz_file(os.path.join(self.fromFilePath, self.fromMachine + '_wizards.cfg')) else: print('file not found, wizard parameters can not be converted.') if os.path.isfile(os.path.join(self.fromFilePath, 'plasmac_stats.var')): self.read_sta_file(os.path.join(self.fromFilePath, 'plasmac_stats.var')) else: print('file not found, statistics can not be converted.') if os.path.isfile(os.path.join(self.fromFilePath, self.fromMachine + '_material.cfg')): self.read_mat_file(os.path.join(self.fromFilePath, self.fromMachine + '_material.cfg'), newDir, newName) else: print('file not found, materials can not be converted.') self.write_prefs_file(newDir, newName) # APPEND TO POSTGUI IF A SIM CONFIG if simConfig: if newPostguiFile: with open('{}/{}'.format(newDir, newPostguiFile), 'a') as outFile: outFile.write(self.sim_postgui()) # WE GOT THIS FAR SO IT MAY HAVE WORKED msg = 'Conversion appears successful.\n' msg += '\nStart LnixCNC using the following ini file:\n' msg += '\n{}/{}.ini\n'.format(newDir, newName) self.dialog_ok('SUCCESS', msg) sys.exit()
def add_component_hal_file(path, inifile, halfiles): written = False tmpFile = '{}~'.format(inifile) COPY(inifile, tmpFile) with open(tmpFile, 'r') as inFile: with open(inifile, 'w') as outFile: while 1: line = inFile.readline() if not line: break elif line.startswith('[HAL]'): outFile.write(line) break else: outFile.write(line) while 1: line = inFile.readline() if not line: if not written: outFile.write('HALFILE = qtplasmac_comp.hal\n') break elif line.startswith('['): if not written: outFile.write('HALFILE = qtplasmac_comp.hal\n') outFile.write(line) break elif 'custom.hal' in line.lower(): outFile.write('HALFILE = qtplasmac_comp.hal\n') outFile.write(line) written = True break else: outFile.write(line) while 1: line = inFile.readline() if not line: break else: outFile.write(line) if os.path.isfile(tmpFile): os.remove(tmpFile) #'plasmac.axis-z-position', pinsToCheck = [ 'PLASMAC COMPONENT INPUTS', 'plasmac.arc-ok-in', 'plasmac.axis-x-position', 'plasmac.axis-y-position', 'plasmac.breakaway', 'plasmac.current-velocity', 'plasmac.cutting-start', 'plasmac.cutting-stop', 'plasmac.feed-override', 'plasmac.feed-reduction', 'plasmac.float-switch', 'plasmac.feed-upm', 'plasmac.ignore-arc-ok-0', 'plasmac.machine-is-on', 'plasmac.motion-type', 'plasmac.offsets-active', 'plasmac.ohmic-probe', 'plasmac.program-is-idle', 'plasmac.program-is-paused', 'plasmac.program-is-running', 'plasmac.scribe-start', 'plasmac.spotting-start', 'plasmac.thc-disable', 'plasmac.torch-off', 'plasmac.units-per-mm', 'plasmac.x-offset-current', 'plasmac.y-offset-current', 'plasmac.z-offset-current', 'PLASMAC COMPONENT OUTPUTS', 'plasmac.adaptive-feed', 'plasmac.feed-hold', 'plasmac.offset-scale', 'plasmac.program-pause', 'plasmac.program-resume', 'plasmac.program-run', 'plasmac.program-stop', 'plasmac.torch-on', 'plasmac.x-offset-counts', 'plasmac.y-offset-counts', 'plasmac.xy-offset-enable', 'plasmac.z-offset-counts', 'plasmac.z-offset-enable', 'plasmac.requested-velocity' ] for f in halfiles: f = os.path.expanduser(f) if not 'custom' in f: halfile = os.path.join(path, f) with open(halfile, 'r') as inFile: if 'plasmac.cutting-start' in inFile.read(): inFile.seek(0) tmpFile = '{}~'.format(halfile) COPY(halfile, tmpFile) with open(tmpFile, 'r') as inFile: with open(f, 'w') as outFile: for line in inFile: if any(pin in line for pin in pinsToCheck): continue outFile.write(line) if os.path.isfile(tmpFile): os.remove(tmpFile) print('QtPlasmaC updated to V1.221.154')
def cancel(P, W, widget): COPY(P.fNgcBkp, P.fNgc) if widget: W.conv_preview.load(P.fNgc) W.add.setEnabled(False) W.undo.setEnabled(False)
def preview(Conv, fNgc, fTmp, columns, rows, cOffset, \ rOffset, xOffset, yOffset, angle, \ scale, rotation, convBlock, convMirror, convFlip, \ convMirrorToggle, convFlipToggle, g5xIndex, convUnits): error = '' msg1 = _('entry is invalid') valid, columns = Conv.conv_is_float(columns) if not valid: msg0 = _('COLUMNS NUMBER') error += '{} {}\n\n'.format(msg0, msg1) valid, cOffset = Conv.conv_is_float(cOffset) if not valid and cOffset: msg0 = _('COLUMNS OFFSET') error += '{} {}\n\n'.format(msg0, msg1) valid, rows = Conv.conv_is_float(rows) if not valid: msg0 = _('ROWS NUMBER') error += '{} {}\n\n'.format(msg0, msg1) valid, rOffset = Conv.conv_is_float(rOffset) if not valid and rOffset: msg0 = _('ROWS OFFSET') error += '{} {}\n\n'.format(msg0, msg1) valid, xOffset = Conv.conv_is_float(xOffset) if not valid and xOffset: msg0 = _('X OFFSET') error += '{} {}\n\n'.format(msg0, msg1) valid, yOffset = Conv.conv_is_float(yOffset) if not valid and yOffset: msg0 = _('Y OFFSET') error += '{} {}\n\n'.format(msg0, msg1) valid, angle = Conv.conv_is_float(angle) if not valid and angle: msg0 = _('PATTERN ANGLE') error += '{} {}\n\n'.format(msg0, msg1) valid, scale = Conv.conv_is_float(scale) if not valid: msg0 = _('SHAPE SCALE') error += '{} {}\n\n'.format(msg0, msg1) valid, rotation = Conv.conv_is_float(rotation) if not valid and rotation: msg0 = _('SHAPE ROTATION') error += '{} {}\n\n'.format(msg0, msg1) if error: return error if columns <= 0: msg = _('COLUMNS NUMBER cannot be zero') error += '{}\n\n'.format(msg) if rows <= 0: msg = _('ROWS NUMBER cannot be zero') error += '{}\n\n'.format(msg) # if columns == 1 and rows == 1: # msg = _('Either COLUMNS NUMBER or ROWS NUMBER must be greater then one') # error += '{}\n\n'.format(msg) if columns > 1 and not cOffset: msg = _('COLUMNS OFFSET is required') error += '{}\n\n'.format(msg) if rows > 1 and not rOffset: msg = _('ROWS OFFSET is required') error += '{}\n\n'.format(msg) if scale <= 0: msg = _('SCALE cannot be zero') error += '{}\n\n'.format(msg) if error: return error COPY(fNgc, fTmp) inCode = open(fTmp, 'r') outNgc = open(fNgc, 'w') # edit existing parameters if convBlock[0]: indent = False for line in inCode: if line.startswith('#<array_x_offset>'): line = '#<array_x_offset> = {}\n'.format(cOffset) elif line.startswith('#<array_y_offset>'): line = '#<array_y_offset> = {}\n'.format(rOffset) elif line.startswith('#<array_columns>'): line = '#<array_columns> = {}\n'.format(columns) elif line.startswith('#<array_rows>'): line = '#<array_rows> = {}\n'.format(rows) elif line.startswith('#<origin_x_offset>'): line = '#<origin_x_offset> = {}\n'.format(xOffset) elif line.startswith('#<origin_y_offset>'): line = '#<origin_y_offset> = {}\n'.format(yOffset) elif line.startswith('#<array_angle>'): line = '#<array_angle> = {}\n'.format(angle) elif line.startswith('#<blk_scale>'): line = '#<blk_scale> = {}\n'.format(scale) elif line.startswith('#<shape_angle>'): line = '#<shape_angle> = {}\n'.format(rotation) elif line.startswith('#<shape_mirror>'): line = '#<shape_mirror> = {}\n'.format(convMirror) elif line.startswith('#<shape_flip>'): line = '#<shape_flip> = {}\n'.format(convFlip) elif '#<shape_mirror>' in line and (convMirrorToggle or convFlipToggle): if 'g2' in line: line = line.replace('g2', 'g3') elif 'g3' in line: line = line.replace('g3', 'g2') outNgc.write('{}'.format(line)) # create new array else: xIndex = [5221, 5241, 5261, 5281, 5301, 5321, 5341, 5361, 5381][(g5xIndex - 1)] outNgc.write(';conversational block\n\n') # inputs outNgc.write(';inputs\n') outNgc.write('#<ucs_x_offset> = #{}\n'.format(xIndex)) outNgc.write('#<ucs_y_offset> = #{}\n'.format(xIndex + 1)) outNgc.write('#<ucs_r_offset> = #{}\n'.format(xIndex + 9)) outNgc.write('#<array_x_offset> = {}\n'.format(cOffset)) outNgc.write('#<array_y_offset> = {}\n'.format(rOffset)) outNgc.write('#<array_columns> = {}\n'.format(columns)) outNgc.write('#<array_rows> = {}\n'.format(rows)) outNgc.write('#<origin_x_offset> = {}\n'.format(xOffset)) outNgc.write('#<origin_y_offset> = {}\n'.format(yOffset)) outNgc.write('#<array_angle> = {}\n'.format(angle)) outNgc.write('#<blk_scale> = {}\n'.format(scale)) outNgc.write('#<shape_angle> = {}\n'.format(rotation)) outNgc.write('#<shape_mirror> = {}\n'.format(convMirror)) outNgc.write('#<shape_flip> = {}\n\n'.format(convFlip)) # calculations outNgc.write(';calculations\n') outNgc.write('#<this_col> = 0\n') outNgc.write('#<this_row> = 0\n') outNgc.write( '#<blk_x_offset> = [#<origin_x_offset> + [#<ucs_x_offset> * {}]]\n' .format(convUnits[0])) outNgc.write( '#<blk_y_offset> = [#<origin_y_offset> + [#<ucs_y_offset> * {}]]\n' .format(convUnits[0])) outNgc.write( '#<x_sin> = [[#<array_x_offset> * #<blk_scale>] * SIN[#<array_angle>]]\n' ) outNgc.write( '#<x_cos> = [[#<array_x_offset> * #<blk_scale>] * COS[#<array_angle>]]\n' ) outNgc.write( '#<y_sin> = [[#<array_y_offset> * #<blk_scale>] * SIN[#<array_angle>]]\n' ) outNgc.write( '#<y_cos> = [[#<array_y_offset> * #<blk_scale>] * COS[#<array_angle>]]\n\n' ) # main loop outNgc.write(';main loop\n') outNgc.write('o<loop> while [#<this_row> LT #<array_rows>]\n') outNgc.write( ' #<shape_x_start> = [[#<this_col> * #<x_cos>] - [#<this_row> * #<y_sin>] + #<blk_x_offset>]\n' ) outNgc.write( ' #<shape_y_start> = [[#<this_row> * #<y_cos>] + [#<this_col> * #<x_sin>] + #<blk_y_offset>]\n' ) outNgc.write( ' #<blk_angle> = [#<shape_angle> + #<array_angle> + #<ucs_r_offset>]\n' ) if convUnits[1]: outNgc.write(' {}\n'.format(convUnits[1])) outNgc.write( ' G10 L2 P0 X#<shape_x_start> Y#<shape_y_start> R#<blk_angle>\n\n' ) # the shape started, ended = False, False for line in inCode: line = line.strip().lower() # remove line numbers if line.startswith('n'): line = line[1:] while line[0].isdigit() or line[0] == '.': line = line[1:].lstrip() if not line: break # remove leading 0's from G & M codes elif (line.lower().startswith('g') or \ line.lower().startswith('m')) and \ len(line) > 2: while line[1] == '0' and len(line) > 2: if line[2].isdigit(): line = line[:1] + line[2:] else: break # scale the shape if len(line) and line[0] in 'gxyz': started = True rLine = scale_shape(line, convMirrorToggle, convFlipToggle) if rLine is not None: outNgc.write(' {}\n'.format(rLine)) else: return # loop counter elif not ended and ('m2' in line or 'm30' in line or (line.startswith('%') and started)): ended = True outNgc.write('\n #<this_col> = [#<this_col> + 1]\n') outNgc.write( ' o<count> if [#<this_col> EQ #<array_columns>]\n') outNgc.write(' #<this_col> = 0\n') outNgc.write(' #<this_row> = [#<this_row> + 1]\n') outNgc.write(' o<count> endif\n') outNgc.write('o<loop> endwhile\n') elif not line: outNgc.write('\n') elif ended and ('m2' in line or 'm30' in line or line.startswith('%')): pass else: outNgc.write(' {}\n'.format(line)) # reset offsets to original outNgc.write( '\nG10 L2 P0 X[#<ucs_x_offset> * {0}] Y[#<ucs_y_offset> * {0}] R#<ucs_r_offset>\n' .format(convUnits[0])) outNgc.write('\nM2\n') inCode.close() outNgc.close() return False