예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
 def handleMCode(self, code: float, args: List[str]):
     spindleSpeed = GcodePreprocessorUtils.parseCoord(args, 'S')
     if not qIsNaN(spindleSpeed):
         self.m_lastSpindleSpeed = spindleSpeed
예제 #9
0
 def _(self, command: str) -> PointSegment:
     stripped = GcodePreprocessorUtils.removeComment(command)
     args = GcodePreprocessorUtils.splitCommand(stripped)
     return self.addCommand(args)
예제 #10
0
    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())
예제 #11
0
    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)
예제 #12
0
    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