Skip to content

Commit

Permalink
add amf source code files by upload
Browse files Browse the repository at this point in the history
  • Loading branch information
SYSUeric66 authored Aug 11, 2023
1 parent e3db981 commit 8c7bf56
Show file tree
Hide file tree
Showing 12 changed files with 2,024 additions and 0 deletions.
Binary file added Huaqiu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2023.08.11
8 changes: 8 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .plugin import Plugin

try:
Plugin().register()
except Exception as e:
import logging
logger = logging.getLogger()
logger.debug(repr(e))
43 changes: 43 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"ui_param": { },
"rule": {
"silkscreen":{
"Green":["White"],
"Red":["White"],
"Yellow":["White"],
"Blue":["White"],
"White":["Black"],
"Matte Black":["White"],
"Black":["White"]
},
"tg":{
"showNoTG":["1","2"],
"showTG":["4","6","8","10","12","14","16","18","20"],
"1":["None"],
"2":["None"],
"4":["TG130","TG150"],
"6":["TG150","TG170"],
"8":["TG150","TG170"],
"10":["TG170"],
"12":["TG170"],
"14":["TG170"],
"16":["TG170"],
"18":["TG170"],
"20":["TG170"]
},
"thickness":{
"default":[14, "1.6", "2.0"],
"1":["0.6","0.8","1.0","1.2","1.6"],
"2":["0.6","0.8","1.0","1.2","1.6"],
"4":["0.6","0.8","1.0","1.2","1.6","2.0","2.5"],
"6":["1.0","1.2","1.6","2.0","2.5"],
"8":["1.2","1.6","2.0","2.5"],
"10":["1.2","1.6","2.0","2.5"],
"12":["1.6","2.0","2.5"],
"14":["1.6","2.0","2.5","3.0"],
"16":["2.0","2.5","3.0"],
"18":["2.0","2.5","3.0","3.2"],
"20":["2.0","2.5","3.0","3.2"]
}
}
}
674 changes: 674 additions & 0 deletions dialog_amf.py

Large diffs are not rendered by default.

659 changes: 659 additions & 0 deletions dialog_amf_base.py

Large diffs are not rendered by default.

258 changes: 258 additions & 0 deletions fabrication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
import csv
import logging
import os
import re
from pathlib import Path
from zipfile import ZipFile

from pcbnew import (
EXCELLON_WRITER,
PCB_PLOT_PARAMS,
PLOT_CONTROLLER,
PLOT_FORMAT_GERBER,
ZONE_FILLER,
B_Cu,
B_Mask,
B_Paste,
B_SilkS,
Cmts_User,
Edge_Cuts,
F_Cu,
F_Mask,
F_Paste,
F_SilkS,
GetBoard,
GetBuildVersion,
In1_Cu,
In2_Cu,
In3_Cu,
In4_Cu,
Refresh,
ToMM,
)

from .helpers import get_exclude_from_pos, get_footprint_by_ref, get_smd, is_nightly


class Fabrication:
def __init__(self, parent):
self.logger = logging.getLogger(__name__)
self.parent = parent
self.board = GetBoard()
self.corrections = []
self.path, self.filename = os.path.split(self.board.GetFileName())
self.create_folders()

def create_folders(self):
"""Create output folders if they not already exist."""
self.outputdir = os.path.join(self.path, "nextpcb_amf", "output_files")
Path(self.outputdir).mkdir(parents=True, exist_ok=True)
self.gerberdir = os.path.join(self.path, "nextpcb_amf", "gerber")
Path(self.gerberdir).mkdir(parents=True, exist_ok=True)

def fill_zones(self):
"""Refill copper zones following user prompt."""
#if self.parent.settings.get("gerber", {}).get("fill_zones", True):
filler = ZONE_FILLER(self.board)
zones = self.board.Zones()
filler.Fill(zones)
Refresh()

def get_position(self, footprint):
"""Calculate position based on center of bounding box"""
if get_smd(footprint):
return footprint.GetPosition()
bbox = footprint.GetBoundingBox(False, False)
return bbox.GetCenter()

def generate_geber(self, layer_count=None):
"""Generating Gerber files"""
# inspired by https://github.com/KiCad/kicad-source-mirror/blob/master/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py
pctl = PLOT_CONTROLLER(self.board)
popt = pctl.GetPlotOptions()

# https://github.com/KiCad/kicad-source-mirror/blob/master/pcbnew/pcb_plot_params.h
popt.SetOutputDirectory(self.gerberdir)

# Plot format to Gerber
# https://github.com/KiCad/kicad-source-mirror/blob/master/include/plotter.h#L67-L78
popt.SetFormat(1)

# General Options
popt.SetPlotValue(True)
popt.SetPlotReference(True)
popt.SetPlotInvisibleText(False)

popt.SetSketchPadsOnFabLayers(False)

# Gerber Options
popt.SetUseGerberProtelExtensions(False)

popt.SetCreateGerberJobFile(False)

popt.SetSubtractMaskFromSilk(True)

popt.SetPlotViaOnMaskLayer(False) # Set this to True if you need untented vias

popt.SetUseAuxOrigin(True)

# Tented vias or not, selcted by user in settings
popt.SetPlotViaOnMaskLayer(True)

popt.SetUseGerberX2format(True)

popt.SetIncludeGerberNetlistInfo(True)

popt.SetDisableGerberMacros(False)

if is_nightly(GetBuildVersion()):
from pcbnew import DRILL_MARKS_NO_DRILL_SHAPE

popt.SetDrillMarksType(DRILL_MARKS_NO_DRILL_SHAPE)
else:
popt.SetDrillMarksType(PCB_PLOT_PARAMS.NO_DRILL_SHAPE)

popt.SetPlotFrameRef(False)

# delete all existing files in the output directory first
for f in os.listdir(self.gerberdir):
os.remove(os.path.join(self.gerberdir, f))

# if no layer_count is given, get the layer count from the board
if not layer_count:
layer_count = self.board.GetCopperLayerCount()

if layer_count == 1:
plot_plan = [
("CuTop", F_Cu, "Top layer"),
("SilkTop", F_SilkS, "Silk top"),
("MaskTop", F_Mask, "Mask top"),
("PasteTop", F_Paste, "Paste top"),
("EdgeCuts", Edge_Cuts, "Edges"),
("VScore", Cmts_User, "V score cut"),
]
elif layer_count == 2:
plot_plan = [
("CuTop", F_Cu, "Top layer"),
("SilkTop", F_SilkS, "Silk top"),
("MaskTop", F_Mask, "Mask top"),
("PasteTop", F_Paste, "Paste top"),
("CuBottom", B_Cu, "Bottom layer"),
("SilkBottom", B_SilkS, "Silk top"),
("MaskBottom", B_Mask, "Mask bottom"),
("PasteBottom", B_Paste, "Paste bottom"),
("EdgeCuts", Edge_Cuts, "Edges"),
("VScore", Cmts_User, "V score cut"),
]
elif layer_count == 4:
plot_plan = [
("CuTop", F_Cu, "Top layer"),
("SilkTop", F_SilkS, "Silk top"),
("MaskTop", F_Mask, "Mask top"),
("PasteTop", F_Paste, "Paste top"),
("CuIn1", In1_Cu, "Inner layer 1"),
("CuIn2", In2_Cu, "Inner layer 2"),
("CuBottom", B_Cu, "Bottom layer"),
("SilkBottom", B_SilkS, "Silk top"),
("MaskBottom", B_Mask, "Mask bottom"),
("PasteBottom", B_Paste, "Paste bottom"),
("EdgeCuts", Edge_Cuts, "Edges"),
("VScore", Cmts_User, "V score cut"),
]
elif layer_count == 6:
plot_plan = [
("CuTop", F_Cu, "Top layer"),
("SilkTop", F_SilkS, "Silk top"),
("MaskTop", F_Mask, "Mask top"),
("PasteTop", F_Paste, "Paste top"),
("CuIn1", In1_Cu, "Inner layer 1"),
("CuIn2", In2_Cu, "Inner layer 2"),
("CuIn3", In3_Cu, "Inner layer 3"),
("CuIn4", In4_Cu, "Inner layer 4"),
("CuBottom", B_Cu, "Bottom layer"),
("SilkBottom", B_SilkS, "Silk top"),
("MaskBottom", B_Mask, "Mask bottom"),
("PasteBottom", B_Paste, "Paste bottom"),
("EdgeCuts", Edge_Cuts, "Edges"),
("VScore", Cmts_User, "V score cut"),
]

for layer_info in plot_plan:
if layer_info[1] <= B_Cu:
popt.SetSkipPlotNPTH_Pads(True)
else:
popt.SetSkipPlotNPTH_Pads(False)
pctl.SetLayer(layer_info[1])
pctl.OpenPlotfile(layer_info[0], PLOT_FORMAT_GERBER, layer_info[2])
if pctl.PlotLayer() is False:
self.logger.error(f"Error plotting {layer_info[2]}")
self.logger.info(f"Successfully plotted {layer_info[2]}")
pctl.ClosePlot()

def generate_excellon(self):
"""Generate Excellon files."""
drlwriter = EXCELLON_WRITER(self.board)
mirror = False
minimalHeader = False
offset = self.board.GetDesignSettings().GetAuxOrigin()
mergeNPTH = False
drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)
drlwriter.SetFormat(False)
genDrl = True
genMap = True
drlwriter.CreateDrillandMapFilesSet(self.gerberdir, genDrl, genMap)
self.logger.info("Finished generating Excellon files")

def zip_gerber_excellon(self):
"""Zip Gerber and Excellon files, ready for upload."""
zipname = f"GERBER-{self.filename.split('.')[0]}.zip"
with ZipFile(os.path.join(self.outputdir, zipname), "w") as zipfile:
for folderName, subfolders, filenames in os.walk(self.gerberdir):
for filename in filenames:
if not filename.endswith(("gbr", "drl", "pdf")):
continue
filePath = os.path.join(folderName, filename)
zipfile.write(filePath, os.path.basename(filePath))
self.logger.info("Finished generating ZIP file")

def generate_cpl(self):
"""Generate placement file (CPL)."""
cplname = f"CPL-{self.filename.split('.')[0]}.csv"
#self.corrections = self.parent.library.get_all_correction_data()
aux_orgin = self.board.GetDesignSettings().GetAuxOrigin()
with open(
os.path.join(self.outputdir, cplname), "w", newline="", encoding="utf-8"
) as csvfile:
writer = csv.writer(csvfile, delimiter=",")
writer.writerow(
["Designator", "Val", "Package", "Mid X", "Mid Y", "Rotation", "Layer"]
)
for part in self.parent.store.read_pos_parts():
for fp in get_footprint_by_ref(self.board, part[0]):
if get_exclude_from_pos(fp):
continue
position = self.get_position(fp) - aux_orgin
writer.writerow(
[
part[0],
part[1],
part[2],
ToMM(position.x),
ToMM(position.y) * -1,
'',
"top" if fp.GetLayer() == 0 else "bottom",
]
)
self.logger.info("Finished generating CPL file")

def generate_bom(self):
"""Generate BOM file."""
bomname = f"BOM-{self.filename.split('.')[0]}.csv"
with open(
os.path.join(self.outputdir, bomname), "w", newline="", encoding="utf-8"
) as csvfile:
writer = csv.writer(csvfile, delimiter=",")
writer.writerow(["Value", "Designator", "Footprint", "MPN"])
for part in self.parent.store.read_bom_parts():
writer.writerow(part)
self.logger.info("Finished generating BOM file")
Loading

0 comments on commit 8c7bf56

Please sign in to comment.