def tooltableFromAttrs(self, stringattrs):
        if stringattrs.get('Version') and 1 == int(stringattrs['Version']):
            
            tt = Path.Tooltable()
            tt.Version = 1
            tt.Name = self.getNextToolTableName()

            if stringattrs.get('Version'):
                tt.Version = stringattrs.get('Version')

            if stringattrs.get('TableName'):
                tt.Name = stringattrs.get('TableName')
                if any(table.Name == tt.Name for table in self.toolTables):
                    tt.Name = self.getNextToolTableName(tt.Name)
            
            for key, attrs in PathUtil.keyValueIter(stringattrs['Tools']):
                    tool = Path.Tool() 
                    tool.Name = str(attrs["name"])
                    tool.ToolType = str(attrs["tooltype"])
                    tool.Material = str(attrs["material"])
                    tool.Diameter = float(attrs["diameter"])
                    tool.LengthOffset = float(attrs["lengthOffset"])
                    tool.FlatRadius = float(attrs["flatRadius"])
                    tool.CornerRadius = float(attrs["cornerRadius"])
                    tool.CuttingEdgeAngle = float(attrs["cuttingEdgeAngle"])
                    tool.CuttingEdgeHeight = float(attrs["cuttingEdgeHeight"])
                    tt.setTool(int(key), tool)

            return tt
        else:
            PathLog.error(translate('PathToolLibraryManager', "Unsupported Path tooltable template version %s") % stringattrs.get('Version'))
        return None
    def getTools(self, tablename):
        '''returns the tool data for a given table'''
        tooldata = []
        tableExists =  any(table.Name == tablename for table in self.toolTables)
        if tableExists:
            self.currentTableName = tablename
        else:
            return None

        tt = self.getTableFromName(tablename)
        headers = ["","Tool Num.","Name","Tool Type","Diameter"]
        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(headers)

        def unitconv(ivalue):
            val = FreeCAD.Units.Quantity(ivalue, FreeCAD.Units.Length)
            displayed_val = val.UserString      #just the displayed value-not the internal one
            return displayed_val

        if tt:
            if len(tt.Tools) == 0:
                tooldata.append([])
            for number, t in PathUtil.keyValueIter(tt.Tools):

                itemcheck = QtGui.QStandardItem()
                itemcheck.setCheckable(True)
                itemNumber =  QtGui.QStandardItem(str(number))
                itemName =  QtGui.QStandardItem(t.Name)
                itemToolType =  QtGui.QStandardItem(t.ToolType)
                itemDiameter =  QtGui.QStandardItem(unitconv(t.Diameter))

                row = [itemcheck, itemNumber, itemName, itemToolType, itemDiameter]
                model.appendRow(row)

        return model
    def getTools(self, tablename):
        '''returns the tool data for a given table'''
        tooldata = []
        tt = self._findList(tablename)
        headers = ["","Tool Num.","Name","Tool Type","Material","Diameter","Length Offset","Flat Radius","Corner Radius","Cutting Edge Angle","Cutting Edge Height"]
        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(headers)

        def unitconv(ivalue):
            val = FreeCAD.Units.Quantity(ivalue, FreeCAD.Units.Length)
            displayed_val = val.UserString      #just the displayed value-not the internal one
            return displayed_val

        if tt:
            if len(tt.Tools) == 0:
                tooldata.append([])
            for number, t in PathUtil.keyValueIter(tt.Tools):

                itemcheck = QtGui.QStandardItem()
                itemcheck.setCheckable(True)
                itemNumber =  QtGui.QStandardItem(str(number))
                itemName =  QtGui.QStandardItem(t.Name)
                itemToolType =  QtGui.QStandardItem(t.ToolType)
                itemMaterial =  QtGui.QStandardItem(t.Material)
                itemDiameter =  QtGui.QStandardItem(unitconv(t.Diameter))
                itemLengthOffset =  QtGui.QStandardItem(unitconv(t.LengthOffset))
                itemFlatRadius =  QtGui.QStandardItem(unitconv(t.FlatRadius))
                itmCornerRadius =  QtGui.QStandardItem(unitconv(t.CornerRadius))
                itemCuttingEdgeAngle =  QtGui.QStandardItem(str(t.CuttingEdgeAngle))
                itemCuttingEdgeHeight =  QtGui.QStandardItem(unitconv(t.CuttingEdgeHeight))

                row = [itemcheck, itemNumber, itemName, itemToolType, itemMaterial, itemDiameter, itemLengthOffset, itemFlatRadius, itmCornerRadius, itemCuttingEdgeAngle, itemCuttingEdgeHeight]
                model.appendRow(row)

        return model
Beispiel #4
0
 def operationsWithSettings(self):
     """operationsWithSettings() ... returns a list of operations which currently have some settings defined."""
     ops = []
     for name, value in PathUtil.keyValueIter(_RegisteredOps):
         for prop in value.registeredPropertyNames(name):
             if hasattr(self.obj, prop):
                 ops.append(name)
                 break
     return list(sorted(ops))
 def tooltableFromAttrs(self, stringattrs):
     if stringattrs.get('Version') and 1 == int(stringattrs['Version']):
         attrs = {}
         for key, val in PathUtil.keyValueIter(stringattrs['Tools']):
             attrs[int(key)] = val
         return Path.Tooltable(attrs)
     else:
         PathLog.error(translate('PathToolLibraryManager', "Unsupported Path tooltable template version %s") % stringattrs.get('Version'))
     return None
 def operationsWithSettings(self):
     '''operationsWithSettings() ... returns a list of operations which currently have some settings defined.'''
     ops = []
     for name,value in PathUtil.keyValueIter(_RegisteredOps):
         for prop in value.registeredPropertyNames(name):
             if hasattr(self.obj, prop):
                 ops.append(name)
                 break
     return list(sorted(ops))
def Attach(vobj, name):
    '''Attach(vobj, name) ... attach the appropriate view provider to the view object.
    If no view provider was registered for the given name a default IconViewProvider is created.'''

    PathLog.track(vobj.Object.Label, name)
    global _factory
    for key,value in PathUtil.keyValueIter(_factory):
        if key == name:
            return value(vobj, name)
    PathLog.track(vobj.Object.Label, name, 'PathIconViewProvider')
    return ViewProvider(vobj, name)
Beispiel #8
0
def Attach(vobj, name):
    """Attach(vobj, name) ... attach the appropriate view provider to the view object.
    If no view provider was registered for the given name a default IconViewProvider is created."""

    PathLog.track(vobj.Object.Label, name)
    global _factory  # pylint: disable=global-statement
    for key, value in PathUtil.keyValueIter(_factory):
        if key == name:
            return value(vobj, name)
    PathLog.track(vobj.Object.Label, name, "PathIconViewProvider")
    return ViewProvider(vobj, name)
def Attach(vobj, name):
    '''Attach(vobj, name) ... attach the appropriate view provider to the view object.
    If no view provider was registered for the given name a default IconViewProvider is created.'''

    PathLog.track(vobj.Object.Label, name)
    global _factory
    for key,value in PathUtil.keyValueIter(_factory):
        if key == name:
            return value(vobj, name)
    PathLog.track(vobj.Object.Label, name, 'PathIconViewProvider')
    return ViewProvider(vobj, name)
 def tooltableFromAttrs(self, stringattrs):
     if stringattrs.get('Version') and 1 == int(stringattrs['Version']):
         attrs = {}
         for key, val in PathUtil.keyValueIter(stringattrs['Tools']):
             attrs[int(key)] = val
         return Path.Tooltable(attrs)
     else:
         PathLog.error(
             translate('PathToolLibraryManager',
                       "Unsupported Path tooltable template version %s") %
             stringattrs.get('Version'))
     return None
Beispiel #11
0
 def __init__(self, obj, form):
     self.form = form
     self.obj = obj
     self.ops = sorted([OpTaskPanel(self.obj, name, op) for name, op in PathUtil.keyValueIter(PathSetupSheet._RegisteredOps)], key = lambda op: op.name)
     if form:
         parent = form.tabOpDefaults
         for op in self.ops:
             form.opDefaultOp.addItem(op.form.windowTitle(), op)
             op.form.setParent(parent)
             parent.layout().addWidget(op.form)
             op.form.hide()
     self.currentOp = None
def _traverseTemplateAttributes(attrs, codec):
    coded = {}
    for key,value in PathUtil.keyValueIter(attrs):
        if type(value) == dict:
            PathLog.debug("%s is a dict" % key)
            coded[key] = _traverseTemplateAttributes(value, codec)
        elif type(value) == list:
            PathLog.debug("%s is a list" % key)
            coded[key] = [_traverseTemplateAttributes(attr, codec) for attr in value]
        elif PathUtil.isString(value):
            PathLog.debug("%s is a string" % key)
            coded[key] = codec(value)
        else:
            PathLog.debug("%s is %s" % (key, type(value)))
            coded[key] = value
    return coded
Beispiel #13
0
def _traverseTemplateAttributes(attrs, codec):
    coded = {}
    for key, value in PathUtil.keyValueIter(attrs):
        if type(value) == dict:
            PathLog.debug("%s is a dict" % key)
            coded[key] = _traverseTemplateAttributes(value, codec)
        elif type(value) == list:
            PathLog.debug("%s is a list" % key)
            coded[key] = [_traverseTemplateAttributes(attr, codec) for attr in value]
        elif PathUtil.isString(value):
            PathLog.debug("%s is a string" % key)
            coded[key] = codec(value)
        else:
            PathLog.debug("%s is %s" % (key, type(value)))
            coded[key] = value
    return coded
    def getTools(self, tablename):
        '''returns the tool data for a given table'''
        tooldata = []
        tt = self._findList(tablename)
        headers = [
            "", "Tool Num.", "Name", "Tool Type", "Material", "Diameter",
            "Length Offset", "Flat Radius", "Corner Radius",
            "Cutting Edge Angle", "Cutting Edge Height"
        ]
        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(headers)

        def unitconv(ivalue):
            val = FreeCAD.Units.Quantity(ivalue, FreeCAD.Units.Length)
            displayed_val = val.UserString  #just the displayed value-not the internal one
            return displayed_val

        if tt:
            if len(tt.Tools) == 0:
                tooldata.append([])
            for number, t in PathUtil.keyValueIter(tt.Tools):

                itemcheck = QtGui.QStandardItem()
                itemcheck.setCheckable(True)
                itemNumber = QtGui.QStandardItem(str(number))
                itemName = QtGui.QStandardItem(t.Name)
                itemToolType = QtGui.QStandardItem(t.ToolType)
                itemMaterial = QtGui.QStandardItem(t.Material)
                itemDiameter = QtGui.QStandardItem(unitconv(t.Diameter))
                itemLengthOffset = QtGui.QStandardItem(unitconv(
                    t.LengthOffset))
                itemFlatRadius = QtGui.QStandardItem(unitconv(t.FlatRadius))
                itmCornerRadius = QtGui.QStandardItem(unitconv(t.CornerRadius))
                itemCuttingEdgeAngle = QtGui.QStandardItem(
                    str(t.CuttingEdgeAngle))
                itemCuttingEdgeHeight = QtGui.QStandardItem(
                    unitconv(t.CuttingEdgeHeight))

                row = [
                    itemcheck, itemNumber, itemName, itemToolType,
                    itemMaterial, itemDiameter, itemLengthOffset,
                    itemFlatRadius, itmCornerRadius, itemCuttingEdgeAngle,
                    itemCuttingEdgeHeight
                ]
                model.appendRow(row)

        return model
    def setFromTemplate(self, attrs):
        '''setFromTemplate(attrs) ... sets the default values from the given dictionary.'''
        for name in Template.All:
            if attrs.get(name) is not None:
                setattr(self.obj, name, attrs[name])

        for opName,op in PathUtil.keyValueIter(_RegisteredOps):
            opSetting = attrs.get(opName)
            if opSetting is not None:
                prototype = op.prototype(opName)
                for propName in op.properties():
                    value = opSetting.get(propName)
                    if not value is None:
                        prop = prototype.getProperty(propName)
                        propertyName = OpPropertyName(opName, propName)
                        propertyGroup = OpPropertyGroup(opName)
                        prop.setupProperty(self.obj, propertyName, propertyGroup, prop.valueFromString(value))
Beispiel #16
0
    def __baseObjectData(self, obj):
        data = {"baseimage": "", "bases": ""}
        try:
            bases = {}
            for name, count in PathUtil.keyValueIter(
                Counter([obj.Proxy.baseObject(obj, o).Label for o in obj.Model.Group])
            ):
                bases[name] = str(count)

            data["baseimage"] = self.__makePicture(obj.Model, "baseimage")
            data["bases"] = bases

        except Exception as e:
            data["errors"] = e
            self.squawk("PathSanity(__baseObjectData)", e, squawkType="CAUTION")

        return data
Beispiel #17
0
    def setFromTemplate(self, attrs):
        '''setFromTemplate(attrs) ... sets the default values from the given dictionary.'''
        for name in Template.All:
            if attrs.get(name) is not None:
                setattr(self.obj, name, attrs[name])

        for opName, op in PathUtil.keyValueIter(_RegisteredOps):
            opSetting = attrs.get(opName)
            if opSetting is not None:
                prototype = op.prototype(opName)
                for propName in op.properties():
                    value = opSetting.get(propName)
                    if value is not None:
                        prop = prototype.getProperty(propName)
                        propertyName = OpPropertyName(opName, propName)
                        propertyGroup = OpPropertyGroup(opName)
                        prop.setupProperty(self.obj, propertyName, propertyGroup, prop.valueFromString(value))
 def updateBoneList(self):
     itemList = []
     for loc, (enabled, inaccessible, ids) in PathUtil.keyValueIter(self.obj.Proxy.boneStateList(self.obj)):
         lbl = '(%.2f, %.2f): %s' % (loc[0], loc[1], ','.join(str(id) for id in ids))
         item = QtGui.QListWidgetItem(lbl)
         if enabled:
             item.setCheckState(QtCore.Qt.CheckState.Checked)
         else:
             item.setCheckState(QtCore.Qt.CheckState.Unchecked)
         flags = QtCore.Qt.ItemFlag.ItemIsSelectable
         if not inaccessible:
             flags |= QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsUserCheckable
         item.setFlags(flags)
         item.setData(self.DataIds, ids)
         item.setData(self.DataKey, ids[0])
         itemList.append(item)
     self.form.bones.clear()
     for item in sorted(itemList, key=lambda item: item.data(self.DataKey)):
         self.form.bones.addItem(item)
Beispiel #19
0
 def updateBoneList(self):
     itemList = []
     for loc, (enabled, inaccessible, ids) in PathUtil.keyValueIter(self.obj.Proxy.boneStateList(self.obj)):
         lbl = '(%.2f, %.2f): %s' % (loc[0], loc[1], ','.join(str(id) for id in ids))
         item = QtGui.QListWidgetItem(lbl)
         if enabled:
             item.setCheckState(QtCore.Qt.CheckState.Checked)
         else:
             item.setCheckState(QtCore.Qt.CheckState.Unchecked)
         flags = QtCore.Qt.ItemFlag.ItemIsSelectable
         if not inaccessible:
             flags |= QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsUserCheckable
         item.setFlags(flags)
         item.setData(self.DataIds, ids)
         item.setData(self.DataKey, ids[0])
         itemList.append(item)
     self.form.bones.clear()
     for item in sorted(itemList, key=lambda item: item.data(self.DataKey)):
         self.form.bones.addItem(item)
    def generateTags(self, obj, count, width=None, height=None, angle=None, radius=None, spacing=None):
        PathLog.track(count, width, height, angle, spacing)
        # for e in self.baseWire.Edges:
        #    debugMarker(e.Vertexes[0].Point, 'base', (0.0, 1.0, 1.0), 0.2)

        if spacing:
            tagDistance = spacing
        else:
            tagDistance = self.baseWire.Length / (count if count else 4)

        W = width if width else self.defaultTagWidth()
        H = height if height else self.defaultTagHeight()
        A = angle if angle else self.defaultTagAngle()
        R = radius if radius else self.defaultTagRadius()

        # start assigning tags on the longest segment
        (shortestEdge, longestEdge) = self.shortestAndLongestPathEdge()
        startIndex = 0
        for i in range(0, len(self.baseWire.Edges)):
            edge = self.baseWire.Edges[i]
            PathLog.debug('  %d: %.2f' % (i, edge.Length))
            if PathGeom.isRoughly(edge.Length, longestEdge.Length):
                startIndex = i
                break

        startEdge = self.baseWire.Edges[startIndex]
        startCount = int(startEdge.Length / tagDistance)
        if (longestEdge.Length - shortestEdge.Length) > shortestEdge.Length:
            startCount = int(startEdge.Length / tagDistance) + 1

        lastTagLength = (startEdge.Length + (startCount - 1) * tagDistance) / 2
        currentLength = startEdge.Length

        minLength = min(2. * W, longestEdge.Length)

        PathLog.debug("length=%.2f shortestEdge=%.2f(%.2f) longestEdge=%.2f(%.2f) minLength=%.2f" % (self.baseWire.Length, shortestEdge.Length, shortestEdge.Length/self.baseWire.Length, longestEdge.Length, longestEdge.Length / self.baseWire.Length, minLength))
        PathLog.debug("   start: index=%-2d count=%d (length=%.2f, distance=%.2f)" % (startIndex, startCount, startEdge.Length, tagDistance))
        PathLog.debug("               -> lastTagLength=%.2f)" % lastTagLength)
        PathLog.debug("               -> currentLength=%.2f)" % currentLength)

        edgeDict = {startIndex: startCount}

        for i in range(startIndex + 1, len(self.baseWire.Edges)):
            edge = self.baseWire.Edges[i]
            (currentLength, lastTagLength) = self.processEdge(i, edge, currentLength, lastTagLength, tagDistance, minLength, edgeDict)
        for i in range(0, startIndex):
            edge = self.baseWire.Edges[i]
            (currentLength, lastTagLength) = self.processEdge(i, edge, currentLength, lastTagLength, tagDistance, minLength, edgeDict)

        tags = []

        for (i, count) in PathUtil.keyValueIter(edgeDict):
            edge = self.baseWire.Edges[i]
            PathLog.debug(" %d: %d" % (i, count))
            # debugMarker(edge.Vertexes[0].Point, 'base', (1.0, 0.0, 0.0), 0.2)
            # debugMarker(edge.Vertexes[1].Point, 'base', (0.0, 1.0, 0.0), 0.2)
            if 0 != count:
                distance = (edge.LastParameter - edge.FirstParameter) / count
                for j in range(0, count):
                    tag = edge.Curve.value((j+0.5) * distance)
                    tags.append(Tag(j, tag.x, tag.y, W, H, A, R, True))

        return tags
def parse(inputstring):
    "parse(inputstring): returns a list of parsed output string"
    print("preprocessing...")
    # split the input by line
    lines = inputstring.split("\n")
    return_output = []
    output = ""
    last = {'X':None,'Y':None,'Z':None,'A':None,'B':None}
    lastrapidspeed = {'XY':"50", 'Z':"50", 'A':"50", 'B':"50" }  #set default rapid speeds
    lastfeedspeed = {'XY':"50", 'Z':"50", 'A':"50", 'B':"50" } #set default feed speed
    movecommand = ['G1', 'G0', 'G02', 'G03']

    for l in lines:
        # remove any leftover trailing and preceding spaces
        l = l.strip()
        if not l:
            # discard empty lines
            continue
        if l[0] in ["'","&"]:
            # discard comment and other non strictly gcode lines
            if l[0:9] == "'New Path":
                # starting new path
                if any (x in output for x in movecommand): #make sure the path has at least one move command.
                    return_output.append(output)
                    output = ""
            continue

        words = [a.strip() for a in l.split(",")]
        words[0] = words[0].upper()
        if words[0] in ["J2","J3","J4","J5","M2","M3","M4","M5"]: #multi-axis jogs and moves
            if words[0][0] == 'J': #jog move
                s = "G0 "
            else:   #feed move
                s = "G1 "
            speed = lastfeedspeed["XY"]

            for i  in range (1, len(words)):
                if words [i] == '':
                    if last[AXIS[i-1]] == None:
                        continue
                    else:
                        s += AXIS[i-1] + last[AXIS[i-1]]
                else:
                    s += AXIS[i-1] + words[i]
                    last[AXIS[i-1]] = words[i]
            output += s +" F" + speed + '\n'

        if words[0] in ["JA","JB","JX","JY","JZ","MA","MB","MX","MY","MZ"]: #single axis jogs and moves
            if words[0][0] == 'J': #jog move
                s = "G0 "
                if words[0][1] in ['X','Y']:
                    speed = lastrapidspeed["XY"]
                else:
                    speed = lastrapidspeed[words[0][1]]

            else:   #feed move
                s = "G1 "
                if words[0][1] in ['X','Y']:
                    speed = lastfeedspeed["XY"]
                else:
                    speed = lastfeedspeed[words[0][1]]


            last[words[0][1]] = words[1]
            output += s
            for key, val in PathUtil.keyValueIter(last):
                if val is not None:
                    output += key + str(val) + " F" + speed + "\n"

        if words[0] in ["JS"]: #set jog speed
            for i  in range (1, len(words)):
                if words [i] == '':
                    continue
                else:
                    lastrapidspeed[SPEEDS[i-1]] = words[i]

        if words[0] in ["MD"]: #move distance with distance and angle.
            #unsupported at this time
            continue
        if words[0] in ["MH"]: #move home
            #unsupported at this time
            continue
        if words[0] in ["MS"]: #set move speed
            for i  in range (1, len(words)):
                if words [i] == '':
                    continue
                else:
                    lastfeedspeed[SPEEDS[i-1]] = words[i]
        if words[0] in ["MO"]: #motors off
            #unsupported at this time
            continue

        if words[0] in ["TR"]: #Setting spindle speed
            if  float(words[1]) < 0:
                s = "M4 S"
            else:
                s = "M3 S"
            s += str(abs(float(words[1])))
            output += s + '\n'

        if words[0] in ["CG"]: #Gcode circle/arc
            if words[1] != "": # diameter mode
                print("diameter mode not supported")
                continue

            else:
                if words[7] == "1": #CW
                    s = "G2"
                else: #CCW
                    s = "G3"


                s += " X" + words[2] + " Y" + words[3] + " I" + words[4] + " J" + words[5] + " F" + str(lastfeedspeed["XY"])
                output  += s + '\n'

                last["X"] = words[2]
                last["Y"] = words[3]

    #Make sure all appended paths have at least one move command.
    if any (x in output for x in movecommand):
        return_output.append(output)
        print("done preprocessing.")

    return return_output
    def generateTags(self, obj, count, width=None, height=None, angle=None, radius=None, spacing=None):
        PathLog.track(count, width, height, angle, spacing)
        # for e in self.baseWire.Edges:
        #    debugMarker(e.Vertexes[0].Point, 'base', (0.0, 1.0, 1.0), 0.2)

        if spacing:
            tagDistance = spacing
        else:
            tagDistance = self.baseWire.Length / (count if count else 4)

        W = width if width else self.defaultTagWidth()
        H = height if height else self.defaultTagHeight()
        A = angle if angle else self.defaultTagAngle()
        R = radius if radius else self.defaultTagRadius()

        # start assigning tags on the longest segment
        (shortestEdge, longestEdge) = self.shortestAndLongestPathEdge()
        startIndex = 0
        for i in range(0, len(self.baseWire.Edges)):
            edge = self.baseWire.Edges[i]
            PathLog.debug('  %d: %.2f' % (i, edge.Length))
            if PathGeom.isRoughly(edge.Length, longestEdge.Length):
                startIndex = i
                break

        startEdge = self.baseWire.Edges[startIndex]
        startCount = int(startEdge.Length / tagDistance)
        if (longestEdge.Length - shortestEdge.Length) > shortestEdge.Length:
            startCount = int(startEdge.Length / tagDistance) + 1

        lastTagLength = (startEdge.Length + (startCount - 1) * tagDistance) / 2
        currentLength = startEdge.Length

        minLength = min(2. * W, longestEdge.Length)

        PathLog.debug("length=%.2f shortestEdge=%.2f(%.2f) longestEdge=%.2f(%.2f) minLength=%.2f" % (self.baseWire.Length, shortestEdge.Length, shortestEdge.Length/self.baseWire.Length, longestEdge.Length, longestEdge.Length / self.baseWire.Length, minLength))
        PathLog.debug("   start: index=%-2d count=%d (length=%.2f, distance=%.2f)" % (startIndex, startCount, startEdge.Length, tagDistance))
        PathLog.debug("               -> lastTagLength=%.2f)" % lastTagLength)
        PathLog.debug("               -> currentLength=%.2f)" % currentLength)

        edgeDict = {startIndex: startCount}

        for i in range(startIndex + 1, len(self.baseWire.Edges)):
            edge = self.baseWire.Edges[i]
            (currentLength, lastTagLength) = self.processEdge(i, edge, currentLength, lastTagLength, tagDistance, minLength, edgeDict)
        for i in range(0, startIndex):
            edge = self.baseWire.Edges[i]
            (currentLength, lastTagLength) = self.processEdge(i, edge, currentLength, lastTagLength, tagDistance, minLength, edgeDict)

        tags = []

        for (i, count) in PathUtil.keyValueIter(edgeDict):
            edge = self.baseWire.Edges[i]
            PathLog.debug(" %d: %d" % (i, count))
            # debugMarker(edge.Vertexes[0].Point, 'base', (1.0, 0.0, 0.0), 0.2)
            # debugMarker(edge.Vertexes[1].Point, 'base', (0.0, 1.0, 0.0), 0.2)
            if 0 != count:
                distance = (edge.LastParameter - edge.FirstParameter) / count
                for j in range(0, count):
                    tag = edge.Curve.value((j+0.5) * distance)
                    tags.append(Tag(j, tag.x, tag.y, W, H, A, R, True))

        return tags
Beispiel #23
0
def parse(inputstring):
    "parse(inputstring): returns a list of parsed output string"
    print("preprocessing...")
    # split the input by line
    lines = inputstring.split("\n")
    return_output = []
    output = ""
    last = {'X': None, 'Y': None, 'Z': None, 'A': None, 'B': None}
    lastrapidspeed = {
        'XY': "50",
        'Z': "50",
        'A': "50",
        'B': "50"
    }  # set default rapid speeds
    lastfeedspeed = {
        'XY': "50",
        'Z': "50",
        'A': "50",
        'B': "50"
    }  # set default feed speed
    movecommand = ['G1', 'G0', 'G02', 'G03']

    for line in lines:
        # remove any leftover trailing and preceding spaces
        line = line.strip()
        if not line:
            # discard empty lines
            continue
        if line[0] in ["'", "&"]:
            # discard comment and other non strictly gcode lines
            if line[0:9] == "'New Path":
                # starting new path
                if any(x in output for x in movecommand
                       ):  # make sure the path has at least one move command.
                    return_output.append(output)
                    output = ""
            continue

        words = [a.strip() for a in line.split(",")]
        words[0] = words[0].upper()
        if words[0] in ["J2", "J3", "J4", "J5", "M2", "M3", "M4",
                        "M5"]:  # multi-axis jogs and moves
            if words[0][0] == 'J':  # jog move
                s = "G0 "
            else:  # feed move
                s = "G1 "
            speed = lastfeedspeed["XY"]

            for i in range(1, len(words)):
                if words[i] == '':
                    if last[AXIS[i - 1]] is None:
                        continue
                    else:
                        s += AXIS[i - 1] + last[AXIS[i - 1]]
                else:
                    s += AXIS[i - 1] + words[i]
                    last[AXIS[i - 1]] = words[i]
            output += s + " F" + speed + '\n'

        if words[0] in [
                "JA", "JB", "JX", "JY", "JZ", "MA", "MB", "MX", "MY", "MZ"
        ]:  # single axis jogs and moves
            if words[0][0] == 'J':  # jog move
                s = "G0 "
                if words[0][1] in ['X', 'Y']:
                    speed = lastrapidspeed["XY"]
                else:
                    speed = lastrapidspeed[words[0][1]]

            else:  # feed move
                s = "G1 "
                if words[0][1] in ['X', 'Y']:
                    speed = lastfeedspeed["XY"]
                else:
                    speed = lastfeedspeed[words[0][1]]

            last[words[0][1]] = words[1]
            output += s
            for key, val in PathUtil.keyValueIter(last):
                if val is not None:
                    output += key + str(val) + " F" + speed + "\n"

        if words[0] in ["JS"]:  # set jog speed
            for i in range(1, len(words)):
                if words[i] == '':
                    continue
                else:
                    lastrapidspeed[SPEEDS[i - 1]] = words[i]

        if words[0] in ["MD"]:  # move distance with distance and angle.
            # unsupported at this time
            continue
        if words[0] in ["MH"]:  # move home
            # unsupported at this time
            continue
        if words[0] in ["MS"]:  # set move speed
            for i in range(1, len(words)):
                if words[i] == '':
                    continue
                else:
                    lastfeedspeed[SPEEDS[i - 1]] = words[i]
        if words[0] in ["MO"]:  # motors off
            # unsupported at this time
            continue

        if words[0] in ["TR"]:  # Setting spindle speed
            if float(words[1]) < 0:
                s = "M4 S"
            else:
                s = "M3 S"
            s += str(abs(float(words[1])))
            output += s + '\n'

        if words[0] in ["CG"]:  # Gcode circle/arc
            if words[1] != "":  # diameter mode
                print("diameter mode not supported")
                continue

            else:
                if words[7] == "1":  # CW
                    s = "G2"
                else:  # CCW
                    s = "G3"

                s += " X" + words[2] + " Y" + words[3] + " I" + words[
                    4] + " J" + words[5] + " F" + str(lastfeedspeed["XY"])
                output += s + '\n'

                last["X"] = words[2]
                last["Y"] = words[3]

    # Make sure all appended paths have at least one move command.
    if any(x in output for x in movecommand):
        return_output.append(output)
        print("done preprocessing.")

    return return_output