diff --git a/README.md b/README.md index ec86228..221a0d5 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The code for this plugin is licensed under the MIT license. Please see `LICENSE` `panelizer.py` is based heavily on [Simon John (@sej7278)](https://github.com/sej7278/kicad-panelizer)'s version of [Willem Hillier (@willemcvu)'s kicad-panelizer](https://github.com/willemcvu/kicad-panelizer). -The [wxFormBuilder](https://github.com/wxFormBuilder/wxFormBuilder/releases) `text_dialog.fbp` and associated code is based on [Greg Davill @gregdavill](https://github.com/gregdavill)'s [KiBuzzard](https://github.com/gregdavill/KiBuzzard). +The [wxFormBuilder](https://github.com/wxFormBuilder/wxFormBuilder/releases) `text_dialog.fbp` and associated code is based on [Greg Davill (@gregdavill)](https://github.com/gregdavill)'s [KiBuzzard](https://github.com/gregdavill/KiBuzzard). ## How It Works diff --git a/SparkFunKiCadPanelizer/panelizer/panelizer.py b/SparkFunKiCadPanelizer/panelizer/panelizer.py index 24e1632..2bdbf52 100644 --- a/SparkFunKiCadPanelizer/panelizer/panelizer.py +++ b/SparkFunKiCadPanelizer/panelizer/panelizer.py @@ -118,10 +118,20 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): # Minimum spacer for exposed edge panels MINIMUM_SPACER = 6.35 # mm + INVALID_WIDTH = 999999999 + # 'Extra' ordering instructions # Any PCB_TEXT containing any of these keywords will be copied into the ordering instructions possibleExtras = ['clean', 'Clean', 'CLEAN'] + # Permutations for Ordering Instructions + possibleOrderingInstructions = [ + "Ordering_Instructions", + "ORDERING_INSTRUCTIONS", + "Ordering Instructions", + "ORDERING INSTRUCTIONS" + ] + sysExit = -1 # -1 indicates sysExit has not (yet) been set. The code below will set this to 0, 1, 2. report = "\nSTART: " + datetime.now().isoformat() + "\n" @@ -390,8 +400,8 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): # Array of tracks # Note: Duplicate uses the same net name for the duplicated track. # This creates DRC unconnected net errors. (KiKit does this properly...) - minTrackWidth = 999999999 - minViaDrill = 999999999 + minTrackWidth = INVALID_WIDTH + minViaDrill = INVALID_WIDTH tracks = board.GetTracks() newTracks = [] for sourceTrack in tracks: # iterate through each track to be copied @@ -431,8 +441,9 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): newModules = [] prodIDs = [] for sourceModule in modules: - if "Ordering_Instructions" in sourceModule.GetFPIDAsString(): - orderingInstructionsSeen = True + for instruction in possibleOrderingInstructions: + if instruction in sourceModule.GetFPIDAsString(): + orderingInstructionsSeen = True if "SparkFun_Logo" in sourceModule.GetFPIDAsString(): sparkfunLogoSeen = True if "SparkX_Logo" in sourceModule.GetFPIDAsString(): @@ -518,26 +529,28 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): for sourceDrawing in drawings: if isinstance(sourceDrawing, pcbnew.PCB_TEXT): txt = sourceDrawing.GetShownText() - if "mask" in txt or "Mask" in txt or "MASK" in txt: - solderMask = txt - if "layers" in txt or "Layers" in txt or "LAYERS" in txt: - if numLayers is None: # Should we trust the instructions or the tracks?! - numLayers = txt - if "impedance" in txt or "Impedance" in txt or "IMPEDANCE" in txt: - controlledImpedance = txt - if "finish" in txt or "Finish" in txt or "FINISH" in txt: - finish = txt - if "thickness" in txt or "Thickness" in txt or "THICKNESS" in txt: - thickness = txt - if "material" in txt or "Material" in txt or "MATERIAL" in txt: - material = txt - if "weight" in txt or "Weight" in txt or "WEIGHT" in txt or "oz" in txt or "Oz" in txt or "OZ" in txt: - copperWeight = txt - for extra in possibleExtras: - if extra in txt: - if orderingExtras is None: - orderingExtras = "" - orderingExtras += txt + "\n" + lines = txt.splitlines() + for line in lines: + if "mask" in line or "Mask" in line or "MASK" in line: + solderMask = line + if "layers" in line or "Layers" in line or "LAYERS" in line: + if numLayers is None: # Should we trust the instructions or the tracks?! + numLayers = line + if "impedance" in line or "Impedance" in line or "IMPEDANCE" in line: + controlledImpedance = line + if "finish" in line or "Finish" in line or "FINISH" in line: + finish = line + if "thickness" in line or "Thickness" in line or "THICKNESS" in line: + thickness = line + if "material" in line or "Material" in line or "MATERIAL" in line: + material = line + if "weight" in line or "Weight" in line or "WEIGHT" in line or "oz" in line or "Oz" in line or "OZ" in line: + copperWeight = line + for extra in possibleExtras: + if extra in line: + if orderingExtras is None: + orderingExtras = "" + orderingExtras += line + "\n" pos = sourceDrawing.GetPosition() # Check if drawing is outside the bounding box if pos.x >= boardLeftEdge and pos.x <= boardRightEdge and \ pos.y >= boardTopEdge and pos.y <= boardBottomEdge: @@ -1070,27 +1083,29 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): if material is not None: report += material + "\n" if solderMask is None: - solderMask = "Solder Mask: Red" + solderMask = "Solder Mask: Red (Default)" report += solderMask + "\n" if silkscreen is None: - silkscreen = "Silkscreen: White" + silkscreen = "Silkscreen: White (Default)" report += silkscreen + "\n" if numLayers is None: - numLayers = "Layers: 2" + numLayers = "Layers: 2 (Default)" report += numLayers + "\n" if finish is None: - finish = "Finish: HASL Lead-free" + finish = "Finish: HASL Lead-free (Default)" report += finish + "\n" if thickness is None: - thickness = "Thickness: 1.6mm" + thickness = "Thickness: 1.6mm (Default)" report += thickness + "\n" if copperWeight is None: - copperWeight = "Copper weight: 1oz" + copperWeight = "Copper weight: 1oz (Default)" report += copperWeight + "\n" - report += "Minimum track width: {:.2f}mm ({:.2f}mil)\n".format( - float(minTrackWidth) / SCALE, float(minTrackWidth) * 1000 / (SCALE * 25.4)) - report += "Minimum via drill: {:.2f}mm ({:.2f}mil)\n".format( - float(minViaDrill) / SCALE, float(minViaDrill) * 1000 / (SCALE * 25.4)) + if minTrackWidth < INVALID_WIDTH: + report += "Minimum track width: {:.2f}mm ({:.2f}mil)\n".format( + float(minTrackWidth) / SCALE, float(minTrackWidth) * 1000 / (SCALE * 25.4)) + if minViaDrill < INVALID_WIDTH: + report += "Minimum via drill: {:.2f}mm ({:.2f}mil)\n".format( + float(minViaDrill) / SCALE, float(minViaDrill) * 1000 / (SCALE * 25.4)) if orderingExtras is not None: report += orderingExtras else: @@ -1110,49 +1125,51 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("Solder mask color not found!", 'Warning', wx.OK | wx.ICON_WARNING) - solderMask = "Solder Mask: Red" + solderMask = "Solder Mask: Red (Default)" oi.write(solderMask + "\n") if silkscreen is None: if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("Silkscreen color not found!", 'Warning', wx.OK | wx.ICON_WARNING) - silkscreen = "Silkscreen: White" + silkscreen = "Silkscreen: White (Default)" oi.write(silkscreen + "\n") if numLayers is None: if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("Number of layers not found!", 'Warning', wx.OK | wx.ICON_WARNING) - numLayers = "Layers: 2" + numLayers = "Layers: 2 (Default)" oi.write(numLayers + "\n") if finish is None: if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("PCB finish not found!", 'Warning', wx.OK | wx.ICON_WARNING) - finish = "Finish: HASL Lead-free" + finish = "Finish: HASL Lead-free (Default)" oi.write(finish + "\n") if thickness is None: if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("PCB thickness not found!", 'Warning', wx.OK | wx.ICON_WARNING) - thickness = "Thickness: 1.6mm" + thickness = "Thickness: 1.6mm (Default)" oi.write(thickness + "\n") if copperWeight is None: if wx.GetApp() is not None and orderingInstructionsSeen: resp = wx.MessageBox("Copper weight not found!", 'Warning', wx.OK | wx.ICON_WARNING) - copperWeight = "Copper weight: 1oz" + copperWeight = "Copper weight: 1oz (Default)" oi.write(copperWeight + "\n") - oi.write("Minimum track width: {:.2f}mm ({:.2f}mil)\n".format( - float(minTrackWidth) / SCALE, float(minTrackWidth) * 1000 / (SCALE * 25.4))) - oi.write("Minimum via drill: {:.2f}mm ({:.2f}mil)\n".format( - float(minViaDrill) / SCALE, float(minViaDrill) * 1000 / (SCALE * 25.4))) + if minTrackWidth < INVALID_WIDTH: + oi.write("Minimum track width: {:.2f}mm ({:.2f}mil)\n".format( + float(minTrackWidth) / SCALE, float(minTrackWidth) * 1000 / (SCALE * 25.4))) + if minViaDrill < INVALID_WIDTH: + oi.write("Minimum via drill: {:.2f}mm ({:.2f}mil)\n".format( + float(minViaDrill) / SCALE, float(minViaDrill) * 1000 / (SCALE * 25.4))) if orderingExtras is not None: oi.write(orderingExtras) except Exception as e: # Don't throw exception if we can't save ordering instructions pass - if (prodIDs is not None): + if len(prodIDs) > 0: emptyProdIDs = {} for prodID in prodIDs: if (prodID[0] == '') or (prodID[0] == ' '): @@ -1160,16 +1177,17 @@ def startPanelizer(self, args, board=None, ordering=None, logger=None): emptyProdIDs[prodID[1]] = 1 else: emptyProdIDs[prodID[1]] = emptyProdIDs[prodID[1]] + 1 - if wx.GetApp() is not None and orderingInstructionsSeen and emptyProdIDs: + if len(emptyProdIDs) > 0: refs = "" - for keys, value in emptyProdIDs.items(): + for ref, num in emptyProdIDs.items(): if refs == "": - refs += keys + refs += ref else: - refs += "," + keys - resp = wx.MessageBox("Empty (undefined) PROD_IDs found!\n" + refs, - 'Warning', wx.OK | wx.ICON_WARNING) - report += "Empty (undefined) PROD_IDs found!" + refs + "\n" + refs += "," + ref + if wx.GetApp() is not None and orderingInstructionsSeen: + resp = wx.MessageBox("Empty (undefined) PROD_IDs found!\n" + refs, + 'Warning', wx.OK | wx.ICON_WARNING) + report += "Empty (undefined) PROD_IDs found: " + refs + "\n" sysExit = 1 if sysExit < 0: diff --git a/SparkFunKiCadPanelizer/resource/_version.py b/SparkFunKiCadPanelizer/resource/_version.py index d538f87..0058b93 100644 --- a/SparkFunKiCadPanelizer/resource/_version.py +++ b/SparkFunKiCadPanelizer/resource/_version.py @@ -1 +1 @@ -__version__ = "1.0.0" \ No newline at end of file +__version__ = "1.0.1" \ No newline at end of file