def processCommand(self, args: List[str]) -> PointSegment: gCodes = [] ps = None # Handle F code speed = GcodePreprocessorUtils.parseCoord(args, 'F') if not qIsNaN(speed): if self.m_isMetric: self.m_lastSpeed = speed else: self.m_lastSpeed = speed * 25.4 # Handle S code spindleSpeed = GcodePreprocessorUtils.parseCoord(args, 'S') if not qIsNaN(spindleSpeed): self.m_lastSpindleSpeed = spindleSpeed # Handle P code dwell = GcodePreprocessorUtils.parseCoord(args, 'P') if not qIsNaN(dwell): self.m_points[-1].setDwell(dwell) # handle G codes. gCodes = GcodePreprocessorUtils.parseCodes(args, 'G') # If there was no command, add the implicit one to the party. if len(gCodes) == 0 and self.m_lastGcodeCommand != -1: gCodes.append(self.m_lastGcodeCommand) for code in gCodes: ps = self.handleGCode(code, args) return ps
def loadData(self, data: List[str]): time = QElapsedTimer() time.start() # Reset parsers self.m_viewParser.reset() # Prepare parser gp = GcodeParser() ####gp.setTraverseSpeed(self.m_settings.rapidSpeed()) gp.setTraverseSpeed(100) print("Prepared to load: %s" % time.elapsed()) time.start() # Block parser updates on table changes self.m_programLoading = True while len(data) > 0: command = data.pop(0) # Trim command trimmed = command.strip() if len(trimmed) > 0: # Split command stripped = GcodePreprocessorUtils.removeComment(command) args = GcodePreprocessorUtils.splitCommand(stripped) gp.addCommand(args) item = GCodeItem() item.command = trimmed item.state = GCodeItem.States.InQueue item.line = gp.getCommandNumber() item.args = args self.m_programModel.m_data.append(item) self.m_programModel.insertRow(self.m_programModel.rowCount()) print("model filled: %s ms." % time.elapsed()) time.start() arcPrecision = 0.0 # TODO self.m_settings.arcPrecision() arcDegreeMode = False # TODO self.m_settings.arcDegreeMode() all_lines = self.m_viewParser.getLinesFromParser( gp, arcPrecision, arcDegreeMode) #self.updateProgramEstimatedTime(all_lines) print("view parser filled: %s ms" % time.elapsed()) self.m_programLoading = False
def expandArc(self) -> List[PointSegment]: startSegment = self.m_points[-2] lastSegment = self.m_points[-1] empty = [] # Can only expand arcs. if not lastSegment.isArc(): return empty # Get precalculated stuff. start = startSegment.point() end = lastSegment.point() center = lastSegment.center() radius = lastSegment.getRadius() clockwise = lastSegment.isClockwise() plane = startSegment.plane() # # Start expansion. # expandedPoints = GcodePreprocessorUtils.generatePointsAlongArcBDring(plane, start, end, center, clockwise, radius, self.m_smallArcThreshold, self.m_smallArcSegmentLength, False) # Validate output of expansion. if len(expandedPoints) == 0: return empty # Remove the last point now that we're about to expand it. self.m_points.pop(-1) self.m_commandNumber = self.m_commandNumber - 1 # Initialize return value psl = [] # Create line segments from points. # skip first element. for k in range(1, len(expandedPoints)-1): temp = PointSegment.PointSegment_FromQVector3D(expandedPoints[k+1], self.m_commandNumber) self.m_commandNumber += 1 temp.setIsMetric(lastSegment.isMetric()) self.m_points.append(temp) psl.append(temp) # Update the new endpoint. self.m_currentPoint.setX(self.m_points[-1].point().x()) self.m_currentPoint.setY(self.m_points[-1].point().y()) self.m_currentPoint.setZ(self.m_points[-1].point().z()) return psl
def preprocessCommand(self, command: str) -> List[str]: result = [] hasComment = False # Remove comments from command. newCommand = GcodePreprocessorUtils.removeComment(command) rawCommand = newCommand hasComment = (len(newCommand) != len(command)) if self.m_removeAllWhitespace: newCommand = GcodePreprocessorUtils.removeAllWhitespace(newCommand) if len(newCommand) > 0: # Override feed speed if self.m_speedOverride > 0: newCommand = GcodePreprocessorUtils.overrideSpeed(newCommand, self.m_speedOverride) if self.m_truncateDecimalLength > 0: newCommand = GcodePreprocessorUtils.truncateDecimals(self.m_truncateDecimalLength, newCommand) # If this is enabled we need to parse the gcode as we go along. if self.m_convertArcsToLines: # || this.expandCannedCycles) { arcLines = self.convertArcsToLines(newCommand) if len(arcLines) > 0: result.append(arcLines) else: result.append(newCommand) elif hasComment: # Maintain line level comment. result.append(command.replace(rawCommand, newCommand)) else: result.append(newCommand) elif hasComment: # Reinsert comment-only lines. result.append(command) return result
def addArcPointSegment(self, nextPoint: QVector3D, clockwise: bool, args: List[str]) -> PointSegment: ps = PointSegment.PointSegment_FromQVector3D(nextPoint, self.m_commandNumber) self.m_commandNumber += 1 center = GcodePreprocessorUtils.updateCenterWithCommand(args, self.m_currentPoint, nextPoint, self.m_inAbsoluteIJKMode, clockwise) radius = GcodePreprocessorUtils.parseCoord(args, 'R') # Calculate radius if necessary. if qIsNaN(radius): m = QMatrix4x4() m.setToIdentity() if self.m_currentPlane == PointSegment.Plane.XY: pass elif self.m_currentPlane == PointSegment.Plane.ZX: m.rotate(90, 1.0, 0.0, 0.0) elif self.m_currentPlane == PointSegment.Plane.YZ: m.rotate(-90, 0.0, 1.0, 0.0) radius = math.sqrt( \ math.pow(((m * self.m_currentPoint).x() - (m * center).x()), 2.0) + \ math.pow(((m * self.m_currentPoint).y() - (m * center).y()), 2.0)) ps.setIsMetric(self.m_isMetric) ps.setArcCenter(center) ps.setIsArc(True) ps.setRadius(radius) ps.setIsClockwise(clockwise) ps.setIsAbsolute(self.m_inAbsoluteMode) ps.setSpeed(self.m_lastSpeed) ps.setSpindleSpeed(self.m_lastSpindleSpeed) ps.setPlane(self.m_currentPlane) self.m_points.append(ps) # Save off the endpoint. self.m_currentPoint = nextPoint return ps
def handleGCode(self, code: float, args: List[str]) -> PointSegment: ps = None nextPoint = GcodePreprocessorUtils.updatePointWithCommand(args, self.m_currentPoint, self.m_inAbsoluteMode) if code == 0.0: ps = self.addLinearPointSegment(nextPoint, True) elif code == 1.0: ps = self.addLinearPointSegment(nextPoint, False) elif code == 38.2: ps = self.addLinearPointSegment(nextPoint, False) elif code == 2.0: ps = self.addArcPointSegment(nextPoint, True, args) elif code == 3.0: ps = self.addArcPointSegment(nextPoint, False, args) elif code == 17.0: self.m_currentPlane = PointSegment.Plane.XY elif code == 18.0: self.m_currentPlane = PointSegment.Plane.ZX elif code == 19.0: self.m_currentPlane = PointSegment.Plane.YZ elif code == 20.0: self.m_isMetric = False elif code == 21.0: self.m_isMetric = True elif code == 90.0: self.m_inAbsoluteMode = True elif code == 90.1: self.m_inAbsoluteIJKMode = True elif code == 91.0: self.m_inAbsoluteMode = False elif code == 91.1: self.m_inAbsoluteIJKMode = False if code == 0.0 or code == 1.0 or code == 2.0 or code == 3.0 or code == 38.2: self.m_lastGcodeCommand = code return ps
def convertArcsToLines(self, command: str) -> List[str]: result = [] start = self.m_currentPoint ps = self.addCommand(command) if ps == None or not ps.isArc(): return result psl = self.expandArc() if len(psl) == 0: return result # Create an array of new commands out of the of the segments in psl. # Don't add them to the gcode parser since it is who expanded them. for segment in psl: end = segment.point() result.append(GcodePreprocessorUtils.generateG1FromPoints(start, end, self.m_inAbsoluteMode, self.m_truncateDecimalLength)) start = segment.point() return result
def handleMCode(self, code: float, args: List[str]): spindleSpeed = GcodePreprocessorUtils.parseCoord(args, 'S') if not qIsNaN(spindleSpeed): self.m_lastSpindleSpeed = spindleSpeed
def _(self, command: str) -> PointSegment: stripped = GcodePreprocessorUtils.removeComment(command) args = GcodePreprocessorUtils.splitCommand(stripped) return self.addCommand(args)
def updateParser(self): time = QElapsedTimer() print("updating parser:") time.start() parser = self.m_currentDrawer.viewParser() gp = GcodeParser() #gp.setTraverseSpeed(m_settings.rapidSpeed()) gp.setTraverseSpeed(100) if self.m_codeDrawer.getIgnoreZ(): gp.reset(QVector3D(qQNaN(), qQNaN(), 0)) self.ui.tblProgram.setUpdatesEnabled(False) progress = QProgressDialog("Updating...", "Abort", 0, self.m_currentModel.rowCount() - 2, self) progress.setWindowModality(QtCore.Qt.WindowModal) progress.setFixedSize(progress.sizeHint()) if self.m_currentModel.rowCount() > PROGRESSMINLINES: progress.show() progress.setStyleSheet( "QProgressBar {text-align: center qproperty-format: \"\"}") for i in range(self.m_currentModel.rowCount()): # Get stored args args = self.m_currentModel.m_data[i].args # Store args if none if len(args) == 0: stripped = GcodePreprocessorUtils.removeComment( self.m_currentModel.m_data[i].command) args = GcodePreprocessorUtils.splitCommand(stripped) self.m_currentModel.m_data[i].args = args # Add command to parser gp.addCommand(args) # Update table model self.m_currentModel.m_data[i].state = GCodeItem.States.InQueue self.m_currentModel.m_data[i].response = "" self.m_currentModel.m_data[i].line = gp.getCommandNumber() if progress.isVisible() and (i % PROGRESSSTEP == 0): progress.setValue(i) QApplication.instance().processEvents() if progress.wasCanceled(): break progress.close() self.ui.tblProgram.setUpdatesEnabled(True) parser.reset() arcPrecision = 0.0 # TODO self.m_settings.arcPrecision() arcDegreeMode = False # TODO self.m_settings.arcDegreeMode() all_lines = parser.getLinesFromParser(gp, arcPrecision(), arcDegreeMode()) #self.updateProgramEstimatedTime(all_lines) self.m_currentDrawer.update() self.ui.glwVisualizer.updateExtremes(self.m_currentDrawer) #self.updateControlsState() if self.m_currentModel == self.m_programModel: self.m_fileChanged = True print("Update parser time: %s" % time.elapsed())
def loadData(self, data: List[str]): time = QElapsedTimer() time.start() # Reset tables self.clearTable() #self.m_probeModel.clear() #self.m_programHeightmapModel.clear() self.m_currentModel = self.m_programModel # Reset parsers self.m_viewParser.reset() #self.m_probeParser.reset() # Reset code drawer self.m_currentDrawer = self.m_codeDrawer self.m_codeDrawer.update() self.ui.glwVisualizer.fitDrawable(self.m_codeDrawer) self.updateProgramEstimatedTime([]) # Update interface #self.ui.chkHeightMapUse.setChecked(False) #self.ui.grpHeightMap.setProperty("overrided", False) #self.style().unpolish(self.ui.grpHeightMap) #self.ui.grpHeightMap.ensurePolished() # Reset tableview headerState = self.ui.tblProgram.horizontalHeader().saveState() self.ui.tblProgram.setModel(None) # Prepare parser gp = GcodeParser() ####gp.setTraverseSpeed(self.m_settings.rapidSpeed()) gp.setTraverseSpeed(100) if self.m_codeDrawer.getIgnoreZ(): gp.reset(QVector3D(qQNaN(), qQNaN(), 0)) print("Prepared to load: %s" % time.elapsed()) time.start() # Block parser updates on table changes self.m_programLoading = True # Prepare model self.m_programModel.m_data.clear() self.m_programModel.m_data = [] progress = QProgressDialog("Opening file...", "Abort", 0, len(data), self) progress.setWindowModality(Qt.WindowModal) progress.setFixedSize(progress.sizeHint()) if len(data) > PROGRESSMINLINES: progress.show() progress.setStyleSheet( "QProgressBar {text-align: center qproperty-format: \"\"}") while len(data) > 0: command = data.pop(0) # Trim command trimmed = command.strip() if len(trimmed) > 0: # Split command stripped = GcodePreprocessorUtils.removeComment(command) args = GcodePreprocessorUtils.splitCommand(stripped) gp.addCommand(args) item = GCodeItem() item.command = trimmed item.state = GCodeItem.States.InQueue item.line = gp.getCommandNumber() item.args = args self.m_programModel.m_data.append(item) if progress.isVisible() and (len(data) % PROGRESSSTEP == 0): progress.setValue(progress.maximum() - len(data)) QApplication.instance().processEvents() if progress.wasCanceled(): break progress.close() self.m_programModel.insertRow(self.m_programModel.rowCount()) print("model filled: %s ms." % time.elapsed()) time.start() arcPrecision = 0.0 # TODO self.m_settings.arcPrecision() arcDegreeMode = False # TODO self.m_settings.arcDegreeMode() all_lines = self.m_viewParser.getLinesFromParser( gp, arcPrecision, arcDegreeMode) #self.updateProgramEstimatedTime(all_lines) print("view parser filled: %s ms" % time.elapsed()) self.m_programLoading = False # Set table model self.ui.tblProgram.setModel(self.m_programModel) self.ui.tblProgram.horizontalHeader().restoreState(headerState) # connect this model self.ui.tblProgram.selectionModel().currentChanged.connect( self.onTableCurrentChanged) # Update tableview self.ui.tblProgram.selectRow(0) # Update code drawer self.m_codeDrawer.update() self.ui.glwVisualizer.fitDrawable(self.m_codeDrawer)
def getLinesFromParser(self, gp: GcodeParser, arcPrecision: float, arcDegreeMode: bool) -> List[LineSegment]: psl = gp.getPointSegmentList() # For a line segment list ALL arcs must be converted to lines. minArcLength = 0.1 start = None end = None # Prepare segments indexes self.m_lineIndexes = [[] for _ in range(len(psl))] lineIndex = 0 for segment in psl: ps = segment isMetric = ps.isMetric() ps.convertToMetric() end = ps.point() # start is null for the first iteration. if start != None: # Expand arc for graphics. if ps.isArc(): points = GcodePreprocessorUtils.generatePointsAlongArcBDring( ps.plane(), start, end, ps.center(), ps.isClockwise(), ps.getRadius(), minArcLength, arcPrecision, arcDegreeMode) # Create line segments from points. if len(points) > 0: startPoint = start for nextPoint in points: if nextPoint == startPoint: continue ls = LineSegment() #ls.setIsArc(ps.isArc()) #ls.setIsClockwise(ps.isClockwise()) #ls.setPlane(ps.plane()) #ls.setIsFastTraverse(ps.isFastTraverse()) #ls.setIsZMovement(ps.isZMovement()) #ls.setIsMetric(isMetric) #ls.setIsAbsolute(ps.isAbsolute()) #ls.setSpeed(ps.getSpeed()) #ls.setSpindleSpeed(ps.getSpindleSpeed()) #ls.setDwell(ps.getDwell()) #self.testExtremes(nextPoint) ls.m_isArc = ps.m_isArc ls.m_isClockwise = ps.isClockwise() ls.m_plane = ps.m_plane ls.m_isFastTraverse = ps.m_isFastTraverse ls.m_isZMovement = ps.m_isZMovement ls.m_isMetric = isMetric ls.m_isAbsolute = ps.m_isAbsolute ls.m_speed = ps.m_speed ls.m_spindleSpeed = ps.m_spindleSpeed ls.m_dwell = ps.m_dwell ls.m_first = startPoint ls.m_second = nextPoint ls.m_lineNumber = lineIndex self.testExtremes(nextPoint) self.m_lines.append(ls) self.m_lineIndexes[ps.getLineNumber()].append( len(self.m_lines) - 1) startPoint = nextPoint lineIndex += 1 # Line else: ls = LineSegment() ls.m_first = start ls.m_second = end ls.m_lineNumber = lineIndex lineIndex += 1 #ls.setIsArc(ps.isArc()) #ls.setIsFastTraverse(ps.isFastTraverse()) #ls.setIsZMovement(ps.isZMovement()) #ls.setIsMetric(isMetric) #ls.setIsAbsolute(ps.isAbsolute()) #ls.setSpeed(ps.getSpeed()) #ls.setSpindleSpeed(ps.getSpindleSpeed()) #ls.setDwell(ps.getDwell()) ls.m_isArc = ps.m_isArc ls.m_isFastTraverse = ps.m_isFastTraverse ls.m_isZMovement = ps.m_isZMovement ls.m_isMetric = ps.m_isMetric ls.m_isAbsolute = ps.m_isAbsolute ls.m_speed = ps.m_speed ls.m_spindleSpeed = ps.m_spindleSpeed ls.m_dwell = ps.m_dwell self.testExtremes(end) self.testLength(start, end) self.m_lines.append(ls) self.m_lineIndexes[ps.getLineNumber()].append( len(self.m_lines) - 1) start = end return self.m_lines