mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 10:42:09 +10:00
Gerber export writes drill files in Excellon format, picked by a constant in GerberExporter, through gerber-writer 1.2.0; a Drill Hole no longer adds its outline and crosshair to the drill file
This commit is contained in:
@@ -97,10 +97,10 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
<artifactId>gerber-writer-api-1.1.0</artifactId>
|
<artifactId>gerber-writer-api-1.2.0</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.1.0.jar</systemPath>
|
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.2.0.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.stream.Collectors;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.bancika.gerberwriter.DataLayer;
|
import com.bancika.gerberwriter.DataLayer;
|
||||||
|
import com.bancika.gerberwriter.DrillFormat;
|
||||||
|
|
||||||
import org.diylc.common.PCBLayer;
|
import org.diylc.common.PCBLayer;
|
||||||
import org.diylc.core.ComponentState;
|
import org.diylc.core.ComponentState;
|
||||||
@@ -32,6 +33,9 @@ public class GerberExporter {
|
|||||||
public static final double OUTLINE_THICKNESS = new Size(0.3d, SizeUnit.mm).convertToPixels();
|
public static final double OUTLINE_THICKNESS = new Size(0.3d, SizeUnit.mm).convertToPixels();
|
||||||
private static final Logger LOG = Logger.getLogger(GerberExporter.class);
|
private static final Logger LOG = Logger.getLogger(GerberExporter.class);
|
||||||
|
|
||||||
|
// Excellon is the drill format every fab accepts; Gerber drill files are not read by all of them
|
||||||
|
private static final DrillFormat DRILL_FORMAT = DrillFormat.EXCELLON;
|
||||||
|
|
||||||
public static void exportGerber(String fileNameBase, Project currentProject, IView view,
|
public static void exportGerber(String fileNameBase, Project currentProject, IView view,
|
||||||
Graphics2D graphics2d, String diylcVersion) {
|
Graphics2D graphics2d, String diylcVersion) {
|
||||||
|
|
||||||
@@ -137,6 +141,23 @@ public class GerberExporter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
g2d.getDrillLayerMap().forEach((layer, drillLayer) -> {
|
||||||
|
try {
|
||||||
|
String fileName = layer.formatFileName(fileNameBase, boardComponent.getName(),
|
||||||
|
DRILL_FORMAT == DrillFormat.EXCELLON ? "drl" : "gbr");
|
||||||
|
LOG.info("Exporting layer: " + layer + " for board " + boardComponent.getName()
|
||||||
|
+ " to file: " + fileName);
|
||||||
|
drillLayer.dumpToFile(fileName, DRILL_FORMAT);
|
||||||
|
generatedFiles.add(fileName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Error writing drill file: " + e.getMessage());
|
||||||
|
view.showMessage(
|
||||||
|
LangUtil.translate(
|
||||||
|
"Failed to export the project to gerber. Please check the log for details"),
|
||||||
|
LangUtil.translate("Gerber Export"), IView.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
view.showMessage(
|
view.showMessage(
|
||||||
String.format(
|
String.format(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.awt.font.GlyphVector;
|
|||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Line2D;
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.BufferedImageOp;
|
import java.awt.image.BufferedImageOp;
|
||||||
@@ -32,6 +33,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.bancika.gerberwriter.DataLayer;
|
import com.bancika.gerberwriter.DataLayer;
|
||||||
|
import com.bancika.gerberwriter.DrillLayer;
|
||||||
import com.bancika.gerberwriter.Point;
|
import com.bancika.gerberwriter.Point;
|
||||||
import com.bancika.gerberwriter.padmasters.Circle;
|
import com.bancika.gerberwriter.padmasters.Circle;
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
private static final double CURVE_APPROXIMATION_TOLERANCE = 1d;
|
private static final double CURVE_APPROXIMATION_TOLERANCE = 1d;
|
||||||
|
|
||||||
private Map<GerberLayer, DataLayer> layerMap;
|
private Map<GerberLayer, DataLayer> layerMap;
|
||||||
|
private Map<GerberLayer, DrillLayer> drillLayerMap;
|
||||||
private boolean trackingGerber = false;
|
private boolean trackingGerber = false;
|
||||||
private Map<GerberLayer, GerberProperties> currentLayers =
|
private Map<GerberLayer, GerberProperties> currentLayers =
|
||||||
new HashMap<GerberLayer, GerberProperties>();
|
new HashMap<GerberLayer, GerberProperties>();
|
||||||
@@ -65,6 +68,7 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
this.graphics2d = graphics2d;
|
this.graphics2d = graphics2d;
|
||||||
this.boardRect = boardRect;
|
this.boardRect = boardRect;
|
||||||
this.layerMap = new HashMap<GerberLayer, DataLayer>();
|
this.layerMap = new HashMap<GerberLayer, DataLayer>();
|
||||||
|
this.drillLayerMap = new HashMap<GerberLayer, DrillLayer>();
|
||||||
this.diylcVersion = diylcVersion;
|
this.diylcVersion = diylcVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +119,11 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startGerberOutput(GerberLayer layer, String function, boolean negative) {
|
public void startGerberOutput(GerberLayer layer, String function, boolean negative) {
|
||||||
layerMap.computeIfAbsent(layer, k -> layer.buildLayer(diylcVersion));
|
if (layer.isDrill()) {
|
||||||
|
drillLayerMap.computeIfAbsent(layer, k -> layer.buildDrillLayer(diylcVersion));
|
||||||
|
} else {
|
||||||
|
layerMap.computeIfAbsent(layer, k -> layer.buildLayer(diylcVersion));
|
||||||
|
}
|
||||||
currentLayers.put(layer, new GerberProperties(function, negative));
|
currentLayers.put(layer, new GerberProperties(function, negative));
|
||||||
trackingGerber = true;
|
trackingGerber = true;
|
||||||
}
|
}
|
||||||
@@ -155,6 +163,10 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
return layerMap;
|
return layerMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<GerberLayer, DrillLayer> getDrillLayerMap() {
|
||||||
|
return drillLayerMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether text is written mirrored, each string about its own centre. The output is in top
|
* Sets whether text is written mirrored, each string about its own centre. The output is in top
|
||||||
* view, so text on the bottom side has to be mirrored to read correctly once the board is turned
|
* view, so text on the bottom side has to be mirrored to read correctly once the board is turned
|
||||||
@@ -168,6 +180,11 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
public void draw(Shape s) {
|
public void draw(Shape s) {
|
||||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||||
currentLayers.entrySet().forEach(entry -> {
|
currentLayers.entrySet().forEach(entry -> {
|
||||||
|
// only round fills are holes; outlines, such as a drill hole marker's border and
|
||||||
|
// crosshair, are not drilled
|
||||||
|
if (entry.getKey().isDrill()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
double width = 1;
|
double width = 1;
|
||||||
if (stroke != null && stroke instanceof BasicStroke) {
|
if (stroke != null && stroke instanceof BasicStroke) {
|
||||||
width = ((BasicStroke) stroke).getLineWidth();
|
width = ((BasicStroke) stroke).getLineWidth();
|
||||||
@@ -222,6 +239,10 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
public void fillShape(Shape s) {
|
public void fillShape(Shape s) {
|
||||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||||
currentLayers.entrySet().forEach(entry -> {
|
currentLayers.entrySet().forEach(entry -> {
|
||||||
|
// only round fills are holes
|
||||||
|
if (entry.getKey().isDrill()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
DataLayer dataLayer = layerMap.get(entry.getKey());
|
DataLayer dataLayer = layerMap.get(entry.getKey());
|
||||||
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
||||||
GerberPathRenderer.outputPathArea(s.getPathIterator(finalTx), dataLayer,
|
GerberPathRenderer.outputPathArea(s.getPathIterator(finalTx), dataLayer,
|
||||||
@@ -234,6 +255,10 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
private void fillFlash(Ellipse2D c) {
|
private void fillFlash(Ellipse2D c) {
|
||||||
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
if (trackingGerber && !getColor().equals(Constants.TRANSPARENT_COLOR)) {
|
||||||
currentLayers.entrySet().forEach(entry -> {
|
currentLayers.entrySet().forEach(entry -> {
|
||||||
|
if (entry.getKey().isDrill()) {
|
||||||
|
addHole(c, entry.getKey(), entry.getValue().function);
|
||||||
|
return;
|
||||||
|
}
|
||||||
DataLayer dataLayer = layerMap.get(entry.getKey());
|
DataLayer dataLayer = layerMap.get(entry.getKey());
|
||||||
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
AffineTransform finalTx = getFinalTx(entry.getKey().isMirrored());
|
||||||
if (Math.abs(c.getWidth() - c.getHeight()) < 0.1 && finalTx.getShearX() == 0
|
if (Math.abs(c.getWidth() - c.getHeight()) < 0.1 && finalTx.getShearX() == 0
|
||||||
@@ -255,6 +280,17 @@ public class GerberG2DWrapper extends Graphics2D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addHole(Ellipse2D c, GerberLayer layer, String function) {
|
||||||
|
AffineTransform finalTx = getFinalTx(layer.isMirrored());
|
||||||
|
Point2D center = finalTx.transform(new Point2D.Double(c.getCenterX(), c.getCenterY()), null);
|
||||||
|
double factor = SizeUnit.px.getFactor();
|
||||||
|
// the drawing transform scales evenly, so the circle stays a circle, scaled by the square root
|
||||||
|
// of the determinant whether or not it is also rotated
|
||||||
|
double diameter = c.getWidth() * Math.sqrt(Math.abs(finalTx.getDeterminant())) * factor;
|
||||||
|
drillLayerMap.get(layer).addHole(new Point(center.getX() * factor, center.getY() * factor),
|
||||||
|
diameter, function);
|
||||||
|
}
|
||||||
|
|
||||||
private AffineTransform getFinalTx(boolean isMirrored) {
|
private AffineTransform getFinalTx(boolean isMirrored) {
|
||||||
AffineTransform finalTx = new AffineTransform();
|
AffineTransform finalTx = new AffineTransform();
|
||||||
if (isMirrored) {
|
if (isMirrored) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.diylc.core.gerber;
|
package org.diylc.core.gerber;
|
||||||
|
|
||||||
import com.bancika.gerberwriter.DataLayer;
|
import com.bancika.gerberwriter.DataLayer;
|
||||||
|
import com.bancika.gerberwriter.DrillLayer;
|
||||||
import com.bancika.gerberwriter.GenerationSoftware;
|
import com.bancika.gerberwriter.GenerationSoftware;
|
||||||
|
|
||||||
public enum GerberLayer {
|
public enum GerberLayer {
|
||||||
@@ -30,9 +31,18 @@ public enum GerberLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DataLayer buildLayer(String diylcVersion) {
|
public DataLayer buildLayer(String diylcVersion) {
|
||||||
GenerationSoftware genSoftware =
|
return new DataLayer(function, negative, createGenerationSoftware(diylcVersion));
|
||||||
new GenerationSoftware("bancika", "DIY Layout Creator", diylcVersion);
|
}
|
||||||
return new DataLayer(function, negative, genSoftware);
|
|
||||||
|
public DrillLayer buildDrillLayer(String diylcVersion) {
|
||||||
|
return new DrillLayer(this == DrillPlated, createGenerationSoftware(diylcVersion));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true for the drill layers, which hold holes rather than drawn copper or graphics
|
||||||
|
*/
|
||||||
|
public boolean isDrill() {
|
||||||
|
return this == DrillPlated || this == DrillNonPlated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExtension() {
|
public String getExtension() {
|
||||||
@@ -56,7 +66,15 @@ public enum GerberLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String formatFileName(String fileNameBase, String boardName) {
|
public String formatFileName(String fileNameBase, String boardName) {
|
||||||
|
return formatFileName(fileNameBase, boardName, getExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatFileName(String fileNameBase, String boardName, String extension) {
|
||||||
return fileNameBase + (fileNameBase.endsWith(".") ? "" : ".")
|
return fileNameBase + (fileNameBase.endsWith(".") ? "" : ".")
|
||||||
+ boardName + "-" + getSuffix() + "." + getExtension();
|
+ boardName + "-" + getSuffix() + "." + extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GenerationSoftware createGenerationSoftware(String diylcVersion) {
|
||||||
|
return new GenerationSoftware("bancika", "DIY Layout Creator", diylcVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -673,6 +673,10 @@
|
|||||||
<changeType>IMPROVEMENT</changeType>
|
<changeType>IMPROVEMENT</changeType>
|
||||||
<description>Gerber export no longer cuts the holes of solder pads and vias out of the copper layers; the holes are defined by the drill files alone, as the Gerber specification recommends</description>
|
<description>Gerber export no longer cuts the holes of solder pads and vias out of the copper layers; the holes are defined by the drill files alone, as the Gerber specification recommends</description>
|
||||||
</org.diylc.appframework.update.Change>
|
</org.diylc.appframework.update.Change>
|
||||||
|
<org.diylc.appframework.update.Change>
|
||||||
|
<changeType>IMPROVEMENT</changeType>
|
||||||
|
<description>Gerber export writes the drill files in Excellon format, the drill format every PCB fab accepts, instead of Gerber format; a 'Drill Hole' no longer adds its outline and crosshair to the drill file</description>
|
||||||
|
</org.diylc.appframework.update.Change>
|
||||||
<org.diylc.appframework.update.Change>
|
<org.diylc.appframework.update.Change>
|
||||||
<changeType>BUG_FIX</changeType>
|
<changeType>BUG_FIX</changeType>
|
||||||
<description>Rotated labels in pasted components and building blocks were drawn in the wrong place and at the wrong angle while following the mouse, until the components were placed</description>
|
<description>Rotated labels in pasted components and building blocks were drawn in the wrong place and at the wrong angle while following the mouse, until the components were placed</description>
|
||||||
|
|||||||
@@ -73,10 +73,10 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
<artifactId>gerber-writer-api-1.1.0</artifactId>
|
<artifactId>gerber-writer-api-1.2.0</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.1.0.jar</systemPath>
|
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.2.0.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ public class Via extends AbstractTransparentComponent<Void>
|
|||||||
public static Size HOLE_SIZE = new Size(0.4d, SizeUnit.mm);
|
public static Size HOLE_SIZE = new Size(0.4d, SizeUnit.mm);
|
||||||
public static Color COLOR = Color.black;
|
public static Color COLOR = Color.black;
|
||||||
|
|
||||||
// gerber-writer has no constant for it
|
|
||||||
private static final String VIA_DRILL = "ViaDrill";
|
|
||||||
|
|
||||||
private Size size = SIZE;
|
private Size size = SIZE;
|
||||||
private Size holeSize = HOLE_SIZE;
|
private Size holeSize = HOLE_SIZE;
|
||||||
private Color color = COLOR;
|
private Color color = COLOR;
|
||||||
@@ -112,7 +109,8 @@ public class Via extends AbstractTransparentComponent<Void>
|
|||||||
if (gerberDrawingObserver != null) {
|
if (gerberDrawingObserver != null) {
|
||||||
gerberDrawingObserver.stopGerberOutput(GerberLayer.CopperTop);
|
gerberDrawingObserver.stopGerberOutput(GerberLayer.CopperTop);
|
||||||
gerberDrawingObserver.stopGerberOutput(GerberLayer.CopperBot);
|
gerberDrawingObserver.stopGerberOutput(GerberLayer.CopperBot);
|
||||||
gerberDrawingObserver.startGerberOutput(GerberLayer.DrillPlated, VIA_DRILL, false);
|
gerberDrawingObserver.startGerberOutput(GerberLayer.DrillPlated, GerberFunctions.VIA_DRILL,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
g2d.setColor(Constants.CANVAS_COLOR);
|
g2d.setColor(Constants.CANVAS_COLOR);
|
||||||
g2d.fill(new Ellipse2D.Double(point.getX() - holeDiameter / 2,
|
g2d.fill(new Ellipse2D.Double(point.getX() - holeDiameter / 2,
|
||||||
|
|||||||
+38
-8
@@ -21,18 +21,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.diylc.components.connectivity;
|
package org.diylc.components.connectivity;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.Map;
|
import java.util.EnumSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.bancika.gerberwriter.DataLayer;
|
import com.bancika.gerberwriter.DrillFormat;
|
||||||
|
|
||||||
import org.diylc.common.PCBLayer;
|
import org.diylc.common.PCBLayer;
|
||||||
|
import org.diylc.components.electromechanical.DrillHole;
|
||||||
import org.diylc.core.ComponentState;
|
import org.diylc.core.ComponentState;
|
||||||
import org.diylc.core.Project;
|
import org.diylc.core.Project;
|
||||||
import org.diylc.core.gerber.GerberG2DWrapper;
|
import org.diylc.core.gerber.GerberG2DWrapper;
|
||||||
@@ -79,7 +81,7 @@ public class SolderPadGerberTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testViaIsOnBothLayersAndTented() {
|
public void testViaIsOnBothLayersAndTented() {
|
||||||
Via via = new Via();
|
Via via = new Via();
|
||||||
Set<GerberLayer> layers = drawGerber(via).keySet();
|
Set<GerberLayer> layers = layersOf(drawGerber(via));
|
||||||
assertTrue(layers.contains(GerberLayer.CopperTop));
|
assertTrue(layers.contains(GerberLayer.CopperTop));
|
||||||
assertTrue(layers.contains(GerberLayer.CopperBot));
|
assertTrue(layers.contains(GerberLayer.CopperBot));
|
||||||
assertTrue(layers.contains(GerberLayer.DrillPlated));
|
assertTrue(layers.contains(GerberLayer.DrillPlated));
|
||||||
@@ -95,11 +97,32 @@ public class SolderPadGerberTest {
|
|||||||
assertNoCutOut(drawGerber(new Via()));
|
assertNoCutOut(drawGerber(new Via()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testViaIsDrilledOnceAsViaDrill() {
|
||||||
|
String excellon = drawGerber(new Via()).getDrillLayerMap().get(GerberLayer.DrillPlated)
|
||||||
|
.dumpToString(DrillFormat.EXCELLON);
|
||||||
|
assertTrue(excellon.contains("; #@! TA.AperFunction,Plated,PTH,ViaDrill\nT1C0.4\n"));
|
||||||
|
assertEquals(1, countHoles(excellon));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDrillHoleMarkerIsDrilledOnce() {
|
||||||
|
// the marker's border and crosshair are drawn too, but they are not holes
|
||||||
|
String excellon = drawGerber(new DrillHole()).getDrillLayerMap()
|
||||||
|
.get(GerberLayer.DrillNonPlated).dumpToString(DrillFormat.EXCELLON);
|
||||||
|
assertTrue(excellon.contains("T1C3.0\n"));
|
||||||
|
assertEquals(1, countHoles(excellon));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long countHoles(String excellon) {
|
||||||
|
return excellon.lines().filter(line -> line.startsWith("X")).count();
|
||||||
|
}
|
||||||
|
|
||||||
// a cut-out is drawn with clear polarity, %LPC*%
|
// a cut-out is drawn with clear polarity, %LPC*%
|
||||||
private static void assertNoCutOut(Map<GerberLayer, DataLayer> layers) {
|
private static void assertNoCutOut(GerberG2DWrapper g2d) {
|
||||||
for (GerberLayer copperLayer : new GerberLayer[] {GerberLayer.CopperTop,
|
for (GerberLayer copperLayer : new GerberLayer[] {GerberLayer.CopperTop,
|
||||||
GerberLayer.CopperBot}) {
|
GerberLayer.CopperBot}) {
|
||||||
String gerber = layers.get(copperLayer).dumpGerberToString();
|
String gerber = g2d.getLayerMap().get(copperLayer).dumpGerberToString();
|
||||||
assertTrue(gerber.contains("D03*"));
|
assertTrue(gerber.contains("D03*"));
|
||||||
assertFalse(gerber.contains("%LPC*%"));
|
assertFalse(gerber.contains("%LPC*%"));
|
||||||
}
|
}
|
||||||
@@ -113,10 +136,17 @@ public class SolderPadGerberTest {
|
|||||||
SolderPad pad = new SolderPad();
|
SolderPad pad = new SolderPad();
|
||||||
pad.setLayer(layer);
|
pad.setLayer(layer);
|
||||||
pad.setHoleType(holeType);
|
pad.setHoleType(holeType);
|
||||||
return drawGerber(pad).keySet();
|
return layersOf(drawGerber(pad));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<GerberLayer, DataLayer> drawGerber(IGerberComponentCustom component) {
|
private static Set<GerberLayer> layersOf(GerberG2DWrapper g2d) {
|
||||||
|
Set<GerberLayer> layers = EnumSet.noneOf(GerberLayer.class);
|
||||||
|
layers.addAll(g2d.getLayerMap().keySet());
|
||||||
|
layers.addAll(g2d.getDrillLayerMap().keySet());
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GerberG2DWrapper drawGerber(IGerberComponentCustom component) {
|
||||||
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
|
||||||
Graphics2D graphics = img.createGraphics();
|
Graphics2D graphics = img.createGraphics();
|
||||||
GerberG2DWrapper g2d =
|
GerberG2DWrapper g2d =
|
||||||
@@ -124,6 +154,6 @@ public class SolderPadGerberTest {
|
|||||||
g2d.startedDrawingComponent();
|
g2d.startedDrawingComponent();
|
||||||
component.draw(g2d, ComponentState.NORMAL, false, new Project(), g2d, g2d);
|
component.draw(g2d, ComponentState.NORMAL, false, new Project(), g2d, g2d);
|
||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
return g2d.getLayerMap();
|
return g2d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,10 +140,10 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
<artifactId>gerber-writer-api-1.1.0</artifactId>
|
<artifactId>gerber-writer-api-1.2.0</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.1.0.jar</systemPath>
|
<systemPath>${project.basedir}/../lib/gerber-writer-api-1.2.0.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.diylc.local</groupId>
|
<groupId>org.diylc.local</groupId>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user