progress
This commit is contained in:
parent
057897461c
commit
85819042bc
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# see https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to Unix line endings on checkout.
|
||||
*.xml text eol=lf
|
||||
*.java text eol=lf
|
||||
*.bat text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.iml text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.ini text eol=lf
|
||||
*.rules text eol=lf
|
||||
|
||||
# KiCad files
|
||||
*.dsn text eol=lf
|
||||
*.kicad_pcb text eol=lf
|
||||
*.net text eol=lf
|
||||
*.pro text eol=lf
|
||||
*.sch text eol=lf
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
import com.rusefi.util.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static com.rusefi.pcb.PcbMergeTool.log;
|
||||
|
||||
/**
|
||||
* 1/19/14
|
||||
* (c) Andrey Belomutskiy
|
||||
*/
|
||||
public class ChangesModel {
|
||||
private static final ChangesModel instance = new ChangesModel();
|
||||
private static final String REMOVE = "remove";
|
||||
private static final String ADD = "add";
|
||||
private static final String MOVE = "move_module";
|
||||
private static final String OPTIMIZE = "optimize";
|
||||
private static final String COPY = "copy";
|
||||
private static final String MERGE_NET = "merge_net";
|
||||
|
||||
public final Set<String> DEL_REQUESTS = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
||||
public final List<NameAndOffset> ADD_REQUESTS = new ArrayList<NameAndOffset>();
|
||||
public final List<NameAndOffset> MOVE_REQUESTS = new ArrayList<NameAndOffset>();
|
||||
|
||||
public final List<TwoFileRequest> OPTIMIZE_REQUESTS = new ArrayList<TwoFileRequest>();
|
||||
public final List<TwoFileRequest> COPY_REQUESTS = new ArrayList<TwoFileRequest>();
|
||||
/**
|
||||
* Old net name > New net name
|
||||
*/
|
||||
public final Map<String, String> NET_MERGE_REQUESTS = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
public static ChangesModel getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void readConfiguration(String fileName) throws IOException {
|
||||
if (!new File(fileName).isFile()) {
|
||||
log("No such file: " + fileName);
|
||||
return;
|
||||
}
|
||||
log("Reading commands from " + fileName);
|
||||
List<String> a = FileUtils.readFileToList(fileName);
|
||||
|
||||
getInstance().read(a);
|
||||
}
|
||||
|
||||
public void read(List<String> lines) {
|
||||
int lineIndex = 0;
|
||||
for (String line : lines) {
|
||||
lineIndex++;
|
||||
line = line.trim();
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
if (line.startsWith("#"))
|
||||
continue; // this line is a comment
|
||||
|
||||
if (line.toLowerCase().startsWith(REMOVE)) {
|
||||
DEL_REQUESTS.add(line.substring(REMOVE.length()).trim());
|
||||
continue;
|
||||
} else if (line.toLowerCase().startsWith(ADD)) {
|
||||
addAddRequest(line.substring(ADD.length()).trim());
|
||||
continue;
|
||||
} else if (line.toLowerCase().startsWith(MOVE)) {
|
||||
addMoveRequest(line.substring(MOVE.length()).trim());
|
||||
continue;
|
||||
} else if (line.toLowerCase().startsWith(OPTIMIZE)) {
|
||||
OPTIMIZE_REQUESTS.add(TwoFileRequest.parseTwoFile(line.substring(OPTIMIZE.length()).trim(), lineIndex));
|
||||
continue;
|
||||
} else if (line.toLowerCase().startsWith(COPY)) {
|
||||
COPY_REQUESTS.add(TwoFileRequest.parseTwoFile(line.substring(COPY.length()).trim(), lineIndex));
|
||||
continue;
|
||||
} else if (line.toLowerCase().startsWith(MERGE_NET)) {
|
||||
TwoFileRequest req = TwoFileRequest.parseTwoFile(line.substring(MERGE_NET.length()).trim(), lineIndex);
|
||||
NET_MERGE_REQUESTS.put(req.input, req.output);
|
||||
log("Net " + req.input + " to be merged into " + req.output);
|
||||
continue;
|
||||
}
|
||||
|
||||
System.err.println("ChangesModel: Ignoring invalid line: " + line);
|
||||
|
||||
}
|
||||
log("Got " + DEL_REQUESTS.size() + " remove request(s)");
|
||||
log("Got " + ADD_REQUESTS.size() + " add request(s)");
|
||||
log("Got " + OPTIMIZE_REQUESTS.size() + " optimize request(s)");
|
||||
log("Got " + NET_MERGE_REQUESTS.size() + " merge net request(s)");
|
||||
}
|
||||
|
||||
private void addMoveRequest(String request) {
|
||||
MOVE_REQUESTS.add(NameAndOffset.parseNameAndOffset(request));
|
||||
}
|
||||
|
||||
private void addAddRequest(String request) {
|
||||
ADD_REQUESTS.add(NameAndOffset.parseNameAndOffset(request));
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
DEL_REQUESTS.clear();
|
||||
ADD_REQUESTS.clear();
|
||||
OPTIMIZE_REQUESTS.clear();
|
||||
MOVE_REQUESTS.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/24/14
|
||||
*/
|
||||
public class NameAndOffset {
|
||||
private final String name;
|
||||
public final double x;
|
||||
public final double y;
|
||||
|
||||
public NameAndOffset(String name, double x, double y) {
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public static NameAndOffset parseNameAndOffset(String request) {
|
||||
String[] tokens = request.split(" ");
|
||||
NameAndOffset result;
|
||||
if (tokens.length == 1) {
|
||||
result = new NameAndOffset(tokens[0], 0, 0);
|
||||
} else if (tokens.length == 3) {
|
||||
double x = Double.parseDouble(tokens[1]);
|
||||
double y = Double.parseDouble(tokens[2]);
|
||||
result = new NameAndOffset(tokens[0], x, y);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid: " + request);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/24/14
|
||||
*/
|
||||
public class PcbCopyTool {
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 2) {
|
||||
System.out.println("Two parameters expected: SOURCE DESTINATION");
|
||||
return;
|
||||
}
|
||||
|
||||
ChangesModel.readConfiguration("pcb_merge_changes.txt");
|
||||
|
||||
String input = args[0];
|
||||
String output = args[1];
|
||||
|
||||
PcbNode.copy(input, output);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
import com.rusefi.pcb.nodes.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 12/16/13.
|
||||
*/
|
||||
public class PcbMergeTool {
|
||||
private static Networks networks = new Networks();
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 3) {
|
||||
System.out.println("Three parameters expected: SOURCE_PCB_FILENAME DESTINATION_PCB_FILENAME CHANGES_LIST_FILENAME");
|
||||
return;
|
||||
}
|
||||
String sourcePcb = args[0];
|
||||
String destination = args[1];
|
||||
String changes = args[2];
|
||||
|
||||
ChangesModel.readConfiguration(changes);
|
||||
|
||||
log("Running COPY commands");
|
||||
for (TwoFileRequest or : ChangesModel.getInstance().COPY_REQUESTS)
|
||||
PcbNode.copy(or.input, or.output);
|
||||
|
||||
log("Running OPTIMIZE commands");
|
||||
for (TwoFileRequest or : ChangesModel.getInstance().OPTIMIZE_REQUESTS)
|
||||
RemoveUnneededTraces.optimize(or.input, or.output);
|
||||
|
||||
PcbNode destNode = PcbNode.readFromFile(sourcePcb);
|
||||
|
||||
|
||||
for (PcbNode net : destNode.iterate("net")) {
|
||||
String netName = net.getChild(1); // todo: nicer method?
|
||||
if (!Networks.isLocalNetwork(netName))
|
||||
networks.registerNetworkIfPcbSpecific(netName);
|
||||
}
|
||||
|
||||
log("Running ADD commands");
|
||||
for (NameAndOffset addRequest : ChangesModel.getInstance().ADD_REQUESTS) {
|
||||
PcbNode node = PcbMoveTool.readAndMove(addRequest.getName(), addRequest.x, addRequest.y);
|
||||
|
||||
mergePcb(destNode, node);
|
||||
}
|
||||
|
||||
log("Running MOVE commands");
|
||||
for (NameAndOffset moveRequest : ChangesModel.getInstance().MOVE_REQUESTS) {
|
||||
String moduleName = moveRequest.getName();
|
||||
ModuleNode module = findModuleByName(destNode, moduleName);
|
||||
if (module == null) {
|
||||
log("Module not found: " + moduleName);
|
||||
continue;
|
||||
}
|
||||
|
||||
PointNode at = module.at;
|
||||
at.setLocation(at.x + moveRequest.x, at.y + moveRequest.y);
|
||||
}
|
||||
|
||||
removeNodes(destNode);
|
||||
|
||||
destNode.write(destination);
|
||||
|
||||
RemoveUnneededTraces.optimize(destination, destination);
|
||||
}
|
||||
|
||||
private static ModuleNode findModuleByName(PcbNode destNode, String moduleName) {
|
||||
for (PcbNode node : destNode.iterate("module")) {
|
||||
ModuleNode mn = (ModuleNode) node;
|
||||
if (moduleName.toLowerCase().equals(mn.getReference().toLowerCase()))
|
||||
return mn;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void mergePcb(PcbNode destNode, PcbNode source) throws IOException {
|
||||
/**
|
||||
* original local net name > new net name in combined PCB
|
||||
*/
|
||||
Map<String, String> netNameMapping = new HashMap<>();
|
||||
/**
|
||||
* original local net ID (as string) > new net ID
|
||||
*/
|
||||
Map<String, Integer> netIdMapping = new HashMap<>();
|
||||
|
||||
for (PcbNode net : source.iterate("net")) {
|
||||
String netId = net.getChild(0);
|
||||
String netName = net.getChild(1); // todo: nicer method?
|
||||
String newName = networks.registerNetworkIfPcbSpecific(netName);
|
||||
netNameMapping.put(netName, newName);
|
||||
netIdMapping.put(netId, networks.getId(newName));
|
||||
}
|
||||
|
||||
List<PcbNode> zones = source.iterate("zone");
|
||||
log("Processing " + zones.size() + " zone(s)");
|
||||
for (PcbNode z : zones) {
|
||||
ZoneNode zone = (ZoneNode) z;
|
||||
if (zone.getLayerNode().isSilkcreenLayer())
|
||||
destNode.addChild(zone);
|
||||
}
|
||||
|
||||
List<PcbNode> arcs = source.iterate("gr_arc");
|
||||
log("Processing " + arcs.size() + " arc(s)");
|
||||
for (PcbNode arc : arcs)
|
||||
destNode.addChild(arc);
|
||||
|
||||
|
||||
List<PcbNode> lines = source.iterate("gr_line");
|
||||
log("Processing " + lines.size() + " line(s)");
|
||||
for (PcbNode l : lines) {
|
||||
GrLineNode line = (GrLineNode) l;
|
||||
if (line.layerNode.isSilkcreenLayer())
|
||||
destNode.addChild(line);
|
||||
}
|
||||
|
||||
|
||||
List<PcbNode> labels = source.iterate("gr_text");
|
||||
log("Processing " + labels.size() + " label(s)");
|
||||
for (PcbNode label : labels) {
|
||||
destNode.addChild(label);
|
||||
}
|
||||
|
||||
List<PcbNode> modules = source.iterate("module");
|
||||
log("Processing " + modules.size() + " module(s)");
|
||||
for (PcbNode module : modules) {
|
||||
for (PcbNode pad : module.iterate("pad")) {
|
||||
if (!pad.hasChild("net"))
|
||||
continue;
|
||||
fixNetId(netIdMapping, netNameMapping, pad);
|
||||
// PcbNode net = pad.find("net");
|
||||
// String localName = netNameMapping.get(net.getChild(1));
|
||||
// net.setString(1, localName);
|
||||
// net.setInt(0, networks.getId(localName));
|
||||
}
|
||||
destNode.addChild(module);
|
||||
}
|
||||
|
||||
List<PcbNode> segments = source.iterate("segment");
|
||||
log("Processing " + segments.size() + " segments");
|
||||
for (PcbNode segment : segments) {
|
||||
// if (!segment.hasChild("net"))
|
||||
// continue;
|
||||
fixNetId(netIdMapping, netNameMapping, segment);
|
||||
|
||||
destNode.addChild(segment);
|
||||
}
|
||||
|
||||
List<PcbNode> vias = source.iterate("via");
|
||||
log("Processing " + vias.size() + " vias");
|
||||
for (PcbNode via : vias) {
|
||||
fixNetId(netIdMapping, netNameMapping, via);
|
||||
|
||||
destNode.addChild(via);
|
||||
}
|
||||
|
||||
// for (PcbNode zone : source.iterate("zone")) {
|
||||
// fixNetId(netIdMapping, zone);
|
||||
// destNode.addChild(zone);
|
||||
// }
|
||||
}
|
||||
|
||||
public static void removeNodes(PcbNode source) {
|
||||
for (PcbNode module : source.iterate("module")) {
|
||||
if (shouldRemove((ModuleNode) module))
|
||||
source.removeChild(module);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRemove(ModuleNode module) {
|
||||
for (PcbNode fp_text : module.iterate("fp_text")) {
|
||||
if ("reference".equals(fp_text.getChild(0))) {
|
||||
String name = fp_text.getChild(1);
|
||||
if (ChangesModel.getInstance().DEL_REQUESTS.contains(name))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void fixNetId(Map<String, Integer> netIdMapping, Map<String, String> netNameMapping, PcbNode node) {
|
||||
NetNode net = (NetNode) node.find("net");
|
||||
String originalId = net.id;
|
||||
Integer currentNetId = netIdMapping.get(originalId);
|
||||
String globalName = networks.nameById.get(currentNetId);
|
||||
// String newName = netNameMapping.get(originalName);
|
||||
// if (newName == null)
|
||||
// throw new NullPointerException("?");
|
||||
|
||||
if (ChangesModel.getInstance().NET_MERGE_REQUESTS.containsKey(globalName)) {
|
||||
String newName = ChangesModel.getInstance().NET_MERGE_REQUESTS.get(globalName);
|
||||
log("Will merge " + globalName + " into " + newName + ". ID was " + currentNetId);
|
||||
currentNetId = networks.networks.get(newName);
|
||||
if (currentNetId == null)
|
||||
throw new NullPointerException("Cannot find net: " + newName);
|
||||
log("New ID: " + currentNetId);
|
||||
globalName = newName;
|
||||
}
|
||||
net.setInt(0, currentNetId);
|
||||
if (net.getName() != null)
|
||||
net.setString(1, globalName);
|
||||
}
|
||||
|
||||
private static class Networks {
|
||||
/**
|
||||
* Net name > Net Id
|
||||
*/
|
||||
private Map<String, Integer> networks = new HashMap<>();
|
||||
private Map<Integer, String> nameById = new HashMap<>();
|
||||
|
||||
public String registerNetworkIfPcbSpecific(String name) {
|
||||
if (isLocalNetwork(name)) {
|
||||
String newName = "F-0000" + networks.size();
|
||||
log("Board-specific net: " + name + " would be " + newName);
|
||||
|
||||
registerNet(newName);
|
||||
int newId = networks.get(newName);
|
||||
log(newName + " is " + newId);
|
||||
return newName;
|
||||
} else {
|
||||
if (networks.containsKey(name)) {
|
||||
log("Existing global net: " + name);
|
||||
return name;
|
||||
}
|
||||
|
||||
log("New global net: " + name);
|
||||
registerNet(name);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLocalNetwork(String name) {
|
||||
return name.startsWith("N-00");
|
||||
}
|
||||
|
||||
private void registerNet(String name) {
|
||||
networks.put(name, networks.size());
|
||||
nameById.put(networks.get(name), name);
|
||||
}
|
||||
|
||||
public int getId(String localName) {
|
||||
Integer value = networks.get(localName);
|
||||
if (value == null)
|
||||
throw new NullPointerException("No id for " + localName);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void log(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 12/8/13
|
||||
*/
|
||||
public class PcbMoveTool {
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 4) {
|
||||
System.out.println("Four parameters expected: SRC_FILENAME DST_FILENAME X Y");
|
||||
return;
|
||||
}
|
||||
String srcFileName = args[0];
|
||||
String dstFileName = args[1];
|
||||
double x = Double.parseDouble(args[2]);
|
||||
double y = Double.parseDouble(args[3]);
|
||||
|
||||
PcbNode node = readAndMove(srcFileName, x, y);
|
||||
node.write(dstFileName);
|
||||
}
|
||||
|
||||
public static PcbNode readAndMove(String fileName, double x, double y) throws IOException {
|
||||
PcbNode node = PcbNode.readFromFile(fileName);
|
||||
|
||||
move(node, x, y);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static void move(PcbNode pcbNode, double dx, double dy) {
|
||||
System.out.println("Moving " + pcbNode + ": dx=" +dx + " dy=" + dy);
|
||||
|
||||
List<PcbNode> dimensions = pcbNode.iterate("dimension");
|
||||
System.out.println("Moving " + dimensions.size() + " dimension");
|
||||
for (PcbNode dimension : dimensions) {
|
||||
moveAt(dx, dy, dimension.find("gr_text"));
|
||||
movePts(dx, dy, dimension.find("feature1"));
|
||||
movePts(dx, dy, dimension.find("feature2"));
|
||||
movePts(dx, dy, dimension.find("crossbar"));
|
||||
movePts(dx, dy, dimension.find("arrow1a"));
|
||||
movePts(dx, dy, dimension.find("arrow1b"));
|
||||
movePts(dx, dy, dimension.find("arrow2a"));
|
||||
movePts(dx, dy, dimension.find("arrow2b"));
|
||||
}
|
||||
|
||||
List<PcbNode> gr_lines = pcbNode.iterate("gr_line");
|
||||
System.out.println("Moving " + gr_lines.size() + " gr_lines");
|
||||
for (PcbNode gr_line : gr_lines)
|
||||
moveStartEnd(dx, dy, gr_line);
|
||||
|
||||
List<PcbNode> gr_arcs = pcbNode.iterate("gr_arc");
|
||||
System.out.println("Moving " + gr_arcs.size() + " gr_arcs");
|
||||
for (PcbNode gr_arc : gr_arcs) {
|
||||
PcbNode start = gr_arc.find("start");
|
||||
moveCoordinatesInFirstChildren(dx, dy, start);
|
||||
|
||||
PcbNode end = gr_arc.find("end");
|
||||
moveCoordinatesInFirstChildren(dx, dy, end);
|
||||
}
|
||||
|
||||
List<PcbNode> gr_circles = pcbNode.iterate("gr_circle");
|
||||
System.out.println("Moving " + gr_circles.size() + " gr_circles");
|
||||
for (PcbNode gr_circle : gr_circles) {
|
||||
PcbNode start = gr_circle.find("center");
|
||||
moveCoordinatesInFirstChildren(dx, dy, start);
|
||||
|
||||
PcbNode end = gr_circle.find("end");
|
||||
moveCoordinatesInFirstChildren(dx, dy, end);
|
||||
}
|
||||
|
||||
List<PcbNode> gr_texts = pcbNode.iterate("gr_text");
|
||||
System.out.println("Moving " + gr_texts.size() + " gr_texts");
|
||||
for (PcbNode gr_text : gr_texts)
|
||||
moveAt(dx, dy, gr_text);
|
||||
|
||||
List<PcbNode> zones = pcbNode.iterate("zone");
|
||||
System.out.println("Moving " + zones.size() + " zones");
|
||||
for (PcbNode zone : zones) {
|
||||
List<PcbNode> filledPolygons = zone.iterate("filled_polygon");
|
||||
for (PcbNode filledPolygon : filledPolygons)
|
||||
movePts(dx, dy, filledPolygon);
|
||||
List<PcbNode> polygons = zone.iterate("polygon");
|
||||
for (PcbNode polygon : polygons)
|
||||
movePts(dx, dy, polygon);
|
||||
}
|
||||
|
||||
|
||||
List<PcbNode> segments = pcbNode.iterate("segment");
|
||||
System.out.println("Moving " + segments.size() + " segments");
|
||||
for (PcbNode segment : segments)
|
||||
moveStartEnd(dx, dy, segment);
|
||||
|
||||
List<PcbNode> vias = pcbNode.iterate("via");
|
||||
System.out.println("Moving " + vias.size() + " vias");
|
||||
for (PcbNode via : vias)
|
||||
moveAt(dx, dy, via);
|
||||
|
||||
|
||||
List<PcbNode> modules = pcbNode.iterate("module");
|
||||
System.out.println("Moving " + modules.size() + " modules");
|
||||
for (PcbNode module : modules)
|
||||
moveAt(dx, dy, module);
|
||||
}
|
||||
|
||||
public static void movePts(double dx, double dy, PcbNode polygon) {
|
||||
PcbNode pts = polygon.find("pts");
|
||||
|
||||
for (PcbNode point : pts.nodes())
|
||||
moveCoordinatesInFirstChildren(dx, dy, point);
|
||||
}
|
||||
|
||||
public static void moveStartEnd(double dx, double dy, PcbNode segment) {
|
||||
PcbNode start = segment.find("start");
|
||||
moveCoordinatesInFirstChildren(dx, dy, start);
|
||||
|
||||
PcbNode end = segment.find("end");
|
||||
moveCoordinatesInFirstChildren(dx, dy, end);
|
||||
}
|
||||
|
||||
public static void moveAt(double dx, double dy, PcbNode module) {
|
||||
PcbNode at = module.find("at");
|
||||
moveCoordinatesInFirstChildren(dx, dy, at);
|
||||
}
|
||||
|
||||
public static void moveCoordinatesInFirstChildren(double dx, double dy, PcbNode at) {
|
||||
moveCoordinates(dx, dy, at, 0);
|
||||
}
|
||||
|
||||
private static void moveCoordinates(double dx, double dy, PcbNode at, int index) {
|
||||
double x = at.asDouble(index);
|
||||
double y = at.asDouble(index + 1);
|
||||
at.setDouble(index, x + dx);
|
||||
at.setDouble(index + 1, y + dy);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
import com.rusefi.pcb.nodes.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class RemoveUnneededTraces {
|
||||
private final static Set<String> alreadyRemoved = new HashSet<String>();
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 2) {
|
||||
System.out.println("two parameters expected: INPUT_FILE OUTPUT_FILE");
|
||||
return;
|
||||
}
|
||||
String input = args[0];
|
||||
String output = args[1];
|
||||
|
||||
optimize(input, output);
|
||||
}
|
||||
|
||||
public static void optimize(String input, String output) throws IOException {
|
||||
PcbNode destNode = PcbNode.readFromFile(input);
|
||||
|
||||
|
||||
while (removeUnusedSegments(destNode) || removeUnusedVias(destNode)) {
|
||||
System.out.println("Still removing...");
|
||||
}
|
||||
|
||||
destNode.write(output);
|
||||
}
|
||||
|
||||
private static boolean removeUnusedVias(PcbNode destNode) {
|
||||
List<ViaNode> unused = findUnusedVias(destNode);
|
||||
for (ViaNode via : unused) {
|
||||
System.out.println("Removing via: " + via);
|
||||
boolean removed = destNode.removeChild(via);
|
||||
if (!removed)
|
||||
throw new IllegalStateException("not removed: " + removed);
|
||||
|
||||
}
|
||||
return !unused.isEmpty();
|
||||
}
|
||||
|
||||
private static List<ViaNode> findUnusedVias(PcbNode destNode) {
|
||||
List<ViaNode> result = new ArrayList<ViaNode>();
|
||||
|
||||
List<PcbNode> stuff = destNode.iterate("segment");
|
||||
// stuff.addAll(destNode.iterate("segment"));
|
||||
|
||||
for (PcbNode n : destNode.iterate("via")) {
|
||||
ViaNode via = (ViaNode) n;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (PcbNode segment : stuff)
|
||||
if (segment.isConnected(via.location))
|
||||
count++;
|
||||
|
||||
if (via.netId == NetNode.GND_NET_ID) {
|
||||
if (count == 0)
|
||||
result.add(via);
|
||||
} else {
|
||||
if (count < 2)
|
||||
result.add(via);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean removeUnusedSegments(PcbNode destNode) {
|
||||
List<PcbNode> stuff = new ArrayList<PcbNode>(destNode.iterate("module"));
|
||||
stuff.addAll(destNode.iterate("via"));
|
||||
|
||||
|
||||
Object o = destNode.iterate("segment");
|
||||
List<SegmentNode> segments = (List<SegmentNode>) o;
|
||||
System.out.println(segments.size() + " segment(s)");
|
||||
|
||||
List<SegmentNode> unused = findUnusedSegments(segments, stuff);
|
||||
for (SegmentNode segment : unused) {
|
||||
boolean removed = destNode.removeChild(segment);
|
||||
if (!removed)
|
||||
throw new IllegalStateException();
|
||||
String netName = segment.net.id;
|
||||
if (!alreadyRemoved.contains(netName)) {
|
||||
alreadyRemoved.add(netName);
|
||||
System.out.println("Unused segment in network " + netName + ": " + segment);
|
||||
}
|
||||
}
|
||||
return !unused.isEmpty();
|
||||
}
|
||||
|
||||
private static List<SegmentNode> findUnusedSegments(List<SegmentNode> segments, List<PcbNode> modules) {
|
||||
List<SegmentNode> unused = new ArrayList<SegmentNode>();
|
||||
for (SegmentNode segment : segments) {
|
||||
if (isUnused(segments, segment, modules)) {
|
||||
// System.out.println("Unused on " + segment.net.id + ": " + segment);
|
||||
unused.add(segment);
|
||||
}
|
||||
}
|
||||
return unused;
|
||||
}
|
||||
|
||||
public static boolean isUnused(List<SegmentNode> segments, SegmentNode segment, List<PcbNode> modules) {
|
||||
PointNode start = segment.start;
|
||||
PointNode end = segment.end;
|
||||
if (isConnected(start, segments, segment) == null && isConnected(start, modules, null) == null) {
|
||||
System.out.println("Not connected start: " + segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
PcbNode endModule = isConnected(end, modules, null);
|
||||
if (isConnected(end, segments, segment) == null && endModule == null) {
|
||||
System.out.println("Not connected end: " + segment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PcbNode isConnected(PointNode point, List<? extends PcbNode> elements, SegmentNode parent) {
|
||||
for (PcbNode segmentNode : elements) {
|
||||
if (segmentNode == parent)
|
||||
continue;
|
||||
|
||||
if (segmentNode.isConnected(point))
|
||||
return segmentNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.rusefi.pcb;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/24/14
|
||||
*/
|
||||
public class TwoFileRequest {
|
||||
public final String input;
|
||||
public final String output;
|
||||
|
||||
public TwoFileRequest(String input, String output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
static TwoFileRequest parseTwoFile(String request, int lineIndex) {
|
||||
String[] tokens = request.split(" ");
|
||||
if (tokens.length != 2)
|
||||
throw new IllegalArgumentException("Unexpected token count in [" + request + "] @" + lineIndex);
|
||||
|
||||
return new TwoFileRequest(tokens[0], tokens[1]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 5/30/2014
|
||||
*/
|
||||
public class AddNetNode extends PcbNode {
|
||||
public AddNetNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PadNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 1/21/14.
|
||||
*/
|
||||
public class CirclePadNode extends PadNode {
|
||||
public CirclePadNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CirclePadNode{" +
|
||||
"at=" + at +
|
||||
", size=" + size +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 2/7/14.
|
||||
*/
|
||||
public class GrLineNode extends PcbNode {
|
||||
public final LayerNode layerNode;
|
||||
public GrLineNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
layerNode = (LayerNode) find("layer");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 2/7/14.
|
||||
*/
|
||||
public class LayerNode extends PcbNode {
|
||||
public final String name;
|
||||
|
||||
public LayerNode(String nodeName, int closingIndex, List<Object> children) {
|
||||
super(nodeName, closingIndex, children);
|
||||
name = (String) children.get(0);
|
||||
}
|
||||
|
||||
public boolean isSilkcreenLayer() {
|
||||
return name.equals("B.SilkS") || name.equals("F.SilkS");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class ModuleNode extends PcbNode {
|
||||
final List<PadNode> pads;
|
||||
public final PointNode at;
|
||||
private final String reference;
|
||||
|
||||
public ModuleNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
Object o = iterate("pad");
|
||||
pads = (List<PadNode>) o;
|
||||
at = (PointNode) find("at");
|
||||
|
||||
reference = iterate("fp_text").get(0).getChild(1);
|
||||
}
|
||||
|
||||
public String getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModuleNode{" +
|
||||
"reference=" + reference +
|
||||
", pads.size=" + pads.size() +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected(PointNode point) {
|
||||
PointNode offsetPoint = at.translate(point);
|
||||
|
||||
for (PadNode pad : pads) {
|
||||
if (pad.isConnected(offsetPoint))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class NetNode extends PcbNode {
|
||||
public final String id;
|
||||
final String name;
|
||||
public static int GND_NET_ID;
|
||||
|
||||
public NetNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
id = getChild(0);
|
||||
name = children.size() > 1 ? getChild(1) : null;
|
||||
if (name != null)
|
||||
System.out.println("NetNode(" + name + " network: " + id + ")");
|
||||
|
||||
if ("GND".equalsIgnoreCase(name))
|
||||
GND_NET_ID = Integer.parseInt(id);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NetNode{" +
|
||||
"id='" + id + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 1/21/14.
|
||||
*/
|
||||
public abstract class PadNode extends PcbNode {
|
||||
protected final PointNode at;
|
||||
protected final SizeNode size;
|
||||
protected final String name;
|
||||
|
||||
public PadNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
name = (String) children.get(0);
|
||||
at = (PointNode) find("at");
|
||||
size = (SizeNode) find("size");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected(PointNode point) {
|
||||
return point.isConnected(at, size);
|
||||
}
|
||||
|
||||
public static PcbNode parse(String nodeName, int i, List<Object> children) {
|
||||
Object shape = children.get(2);
|
||||
if ("rect".equals(shape))
|
||||
return new RectPadNode(nodeName, i, children);
|
||||
if ("circle".equals(shape))
|
||||
return new CirclePadNode(nodeName, i, children);
|
||||
if ("oval".equals(shape))
|
||||
return new CirclePadNode(nodeName, i, children); // yes, let's treat oval as circle. good enough
|
||||
throw new IllegalStateException("Unknown pad shape: " + shape.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PadNode{" +
|
||||
"at=" + at +
|
||||
", size=" + size +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.*;
|
||||
import com.rusefi.util.FileUtils;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 12/8/13
|
||||
*/
|
||||
public class PcbNode {
|
||||
public final String nodeName;
|
||||
public final int closingIndex;
|
||||
public final List<Object> children;
|
||||
|
||||
public PcbNode(String nodeName, int closingIndex, List<Object> children) {
|
||||
this.nodeName = nodeName;
|
||||
this.closingIndex = closingIndex;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #write
|
||||
*/
|
||||
public static PcbNode readFromFile(String fileName) throws IOException {
|
||||
String content = FileUtils.readFile(fileName);
|
||||
PcbNode node = parse(content);
|
||||
System.out.println("GND network: " + NetNode.GND_NET_ID);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static void copy(String inputFileName, String outputFileName) throws IOException {
|
||||
System.out.println("From " + inputFileName + " to " + outputFileName);
|
||||
PcbNode node = readFromFile(inputFileName);
|
||||
|
||||
PcbMergeTool.removeNodes(node);
|
||||
|
||||
node.write(outputFileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PcbNode{" +
|
||||
nodeName +
|
||||
", children=" + children.size() +
|
||||
'}';
|
||||
}
|
||||
|
||||
private static PcbNode parse(String s, int index, int depth) {
|
||||
log("Reading node from " + index, depth);
|
||||
if (s.charAt(index) != '(')
|
||||
throw new IllegalStateException("opening bracket expected");
|
||||
index++;
|
||||
String nodeName = readToken(s, index, depth);
|
||||
index += nodeName.length();
|
||||
|
||||
List<Object> children = new ArrayList<Object>();
|
||||
while (true) {
|
||||
while (isWhitespace(s.charAt(index)))
|
||||
index++;
|
||||
|
||||
char c = s.charAt(index);
|
||||
if (c == ')')
|
||||
break;
|
||||
|
||||
if (s.charAt(index) == '(') {
|
||||
PcbNode child = parse(s, index, depth + 1);
|
||||
children.add(child);
|
||||
index = child.closingIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
String child = readToken(s, index, depth);
|
||||
children.add(child);
|
||||
index += child.length();
|
||||
}
|
||||
if ("segment".equals(nodeName)) {
|
||||
return new SegmentNode(nodeName, index + 1, children);
|
||||
} else if ("pad".equals(nodeName)) {
|
||||
return PadNode.parse(nodeName, index + 1, children);
|
||||
} else if ("net".equals(nodeName)) {
|
||||
return new NetNode(nodeName, index + 1, children);
|
||||
} else if ("add_net".equals(nodeName)) {
|
||||
return new AddNetNode(nodeName, index + 1, children);
|
||||
} else if ("gr_line".equals(nodeName)) {
|
||||
return new GrLineNode(nodeName, index + 1, children);
|
||||
} else if ("layer".equals(nodeName)) {
|
||||
return new LayerNode(nodeName, index + 1, children);
|
||||
} else if ("module".equals(nodeName)) {
|
||||
return new ModuleNode(nodeName, index + 1, children);
|
||||
} else if ("size".equals(nodeName) || "width".equals(nodeName)) {
|
||||
return new SizeNode(nodeName, index + 1, children);
|
||||
} else if ("zone".equals(nodeName)) {
|
||||
return new ZoneNode(nodeName, index + 1, children);
|
||||
} else if ("via".equals(nodeName)) {
|
||||
return new ViaNode(nodeName, index + 1, children);
|
||||
} else if ("start".equals(nodeName) || "end".equals(nodeName) || "at".equals(nodeName)) {
|
||||
return new PointNode(nodeName, index + 1, children);
|
||||
}
|
||||
|
||||
return new PcbNode(nodeName, index + 1, children);
|
||||
}
|
||||
|
||||
private static String readToken(String s, int index, int depth) {
|
||||
log("Reading token from " + index, depth);
|
||||
if (s.charAt(index) == '"') {
|
||||
String result = s.substring(index, s.indexOf('"', index + 1) + 1);
|
||||
log("Got quoted token: " + result, depth);
|
||||
return result;
|
||||
}
|
||||
|
||||
String result = "";
|
||||
while (index < s.length()) {
|
||||
char c = s.charAt(index);
|
||||
if (c == ')' || isWhitespace(c))
|
||||
break;
|
||||
result += c;
|
||||
index++;
|
||||
}
|
||||
if (result.length() == 0)
|
||||
throw new IllegalStateException("Empty token");
|
||||
log("Got token: " + result, depth);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void log(String s, int depth) {
|
||||
// for (int i = 0; i < depth; i++)
|
||||
// System.out.print(' ');
|
||||
// System.out.println(s);
|
||||
}
|
||||
|
||||
private static void log(String s) {
|
||||
log(s, 0);
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(char c) {
|
||||
return c == ' ' || c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
public static PcbNode parse(String content) {
|
||||
return parse(content, 0, 0);
|
||||
}
|
||||
|
||||
public String pack() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
pack(sb, "");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void pack(StringBuilder sb, String prefix) {
|
||||
sb.append(prefix).append("(").append(nodeName);
|
||||
|
||||
for (Object child : children) {
|
||||
if (child instanceof String) {
|
||||
sb.append(" ").append(child);
|
||||
continue;
|
||||
}
|
||||
PcbNode p = (PcbNode) child;
|
||||
if (p == null)
|
||||
throw new NullPointerException("Null child node");
|
||||
sb.append("\r\n");
|
||||
p.pack(sb, prefix + " ");
|
||||
}
|
||||
|
||||
|
||||
sb.append(")\r\n");
|
||||
}
|
||||
|
||||
public void write(String fileName) throws IOException {
|
||||
System.out.println("Writing to " + fileName);
|
||||
String content = pack();
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
|
||||
bw.write(content);
|
||||
bw.close();
|
||||
}
|
||||
|
||||
public void setDouble(int i, double value) {
|
||||
children.set(i, "" + value);
|
||||
}
|
||||
|
||||
public double asDouble(int index) {
|
||||
return Double.parseDouble((String) children.get(index));
|
||||
}
|
||||
|
||||
public boolean hasChild(String key) {
|
||||
return !iterate(key).isEmpty();
|
||||
}
|
||||
|
||||
// @Nullable
|
||||
public PcbNode findIfExists(String key) {
|
||||
List<PcbNode> r = iterate(key);
|
||||
if (r.isEmpty())
|
||||
return null;
|
||||
return find(key);
|
||||
}
|
||||
|
||||
// @NotNull
|
||||
public PcbNode find(String key) {
|
||||
List<PcbNode> r = iterate(key);
|
||||
if (r.size() != 1)
|
||||
throw new IllegalStateException("More that one " + key + " in " + nodeName);
|
||||
return r.get(0);
|
||||
}
|
||||
|
||||
public List<PcbNode> nodes() {
|
||||
List<PcbNode> result = new ArrayList<PcbNode>();
|
||||
for (Object child : children) {
|
||||
if (child instanceof String)
|
||||
continue;
|
||||
result.add((PcbNode) child);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<PcbNode> iterate(String key) {
|
||||
List<PcbNode> result = new ArrayList<PcbNode>();
|
||||
for (PcbNode p : nodes()) {
|
||||
if (p.nodeName.equals(key))
|
||||
result.add(p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addChild(PcbNode node) {
|
||||
children.add(node);
|
||||
}
|
||||
|
||||
public List<Object> getChildren() {
|
||||
return Collections.unmodifiableList(children);
|
||||
}
|
||||
|
||||
public String getChild(int index) {
|
||||
return (String) children.get(index);
|
||||
}
|
||||
|
||||
public void setString(int index, String value) {
|
||||
children.set(index, value);
|
||||
}
|
||||
|
||||
public void setInt(int index, int value) {
|
||||
children.set(index, "" + value);
|
||||
}
|
||||
|
||||
public boolean removeChild(Object child) {
|
||||
return children.remove(child);
|
||||
}
|
||||
|
||||
public boolean isConnected(PointNode point) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class PointNode extends PcbNode {
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double angle;
|
||||
|
||||
public PointNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
if (children.size() == 1) {
|
||||
// xyz use-case
|
||||
x = 0;
|
||||
y = 0;
|
||||
angle = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (children.size() != 2 && children.size() != 3)
|
||||
throw new IllegalStateException("Unexpected children count");
|
||||
x = Double.parseDouble((String) children.get(0));
|
||||
y = Double.parseDouble((String) children.get(1));
|
||||
angle = children.size() == 2 ? 0 : Double.parseDouble((String) children.get(2));
|
||||
}
|
||||
|
||||
public PointNode(double x, double y) {
|
||||
this(x, y, 0);
|
||||
}
|
||||
|
||||
public PointNode(double x, double y, double angle) {
|
||||
super("", 0, Collections.emptyList());
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
public boolean isConnected(PointNode at, SizeNode size) {
|
||||
boolean isConnectedX = (x >= at.x - size.w / 2) && (x <= at.x + size.w / 2);
|
||||
boolean isConnectedY = (y >= at.y - size.h / 2) && (y <= at.y + size.h / 2);
|
||||
return isConnectedX && isConnectedY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PointNode{" +
|
||||
"x=" + x +
|
||||
", y=" + y +
|
||||
", angle=" + angle +
|
||||
'}';
|
||||
}
|
||||
|
||||
// public boolean isSameLocation(PointNode point) {
|
||||
// return x == point.x && y == point.y;
|
||||
// }
|
||||
|
||||
public PointNode translate(PointNode at) {
|
||||
double nx = at.x - x;
|
||||
double ny = at.y - y;
|
||||
|
||||
double radian = angle / 180 * Math.PI;
|
||||
double rx = Math.cos(radian) * nx - Math.sin(radian) * ny;
|
||||
double ry = Math.sin(radian) * nx + Math.cos(radian) * ny;
|
||||
|
||||
return new PointNode(rx, ry);
|
||||
}
|
||||
|
||||
public void setLocation(double x, double y) {
|
||||
children.set(0, Double.toString(x));
|
||||
children.set(1, Double.toString(y));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PadNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 1/21/14.
|
||||
*/
|
||||
public class RectPadNode extends PadNode {
|
||||
public RectPadNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RectPadNode{" +
|
||||
"name=" + name +
|
||||
", at=" + at +
|
||||
", size=" + size +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class SegmentNode extends PcbNode {
|
||||
public final NetNode net;
|
||||
public final PointNode start;
|
||||
public final PointNode end;
|
||||
private final SizeNode size;
|
||||
|
||||
public SegmentNode(String nodeName, int closingIndex, List<Object> children) {
|
||||
super(nodeName, closingIndex, children);
|
||||
net = (NetNode) find("net");
|
||||
start = (PointNode) find("start");
|
||||
end = (PointNode) find("end");
|
||||
size = (SizeNode) find("width");
|
||||
}
|
||||
|
||||
public boolean isConnected(PointNode point) {
|
||||
return point.isConnected(start, size) || point.isConnected(end, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SegmentNode{" +
|
||||
"net=" + net +
|
||||
", start=" + start +
|
||||
", end=" + end +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class SizeNode extends PcbNode {
|
||||
public final double w;
|
||||
public final double h;
|
||||
|
||||
public SizeNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
if (children.size() == 1) {
|
||||
w = h = Double.parseDouble((String) children.get(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (children.size() != 2)
|
||||
throw new IllegalStateException("Size: " + children.size());
|
||||
w = Double.parseDouble((String) children.get(0));
|
||||
h = Double.parseDouble((String) children.get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SizeNode{" +
|
||||
"w=" + w +
|
||||
", h=" + h +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
import com.rusefi.pcb.nodes.PointNode;
|
||||
import com.rusefi.pcb.nodes.SizeNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrey Belomutskiy
|
||||
* 1/21/14
|
||||
*/
|
||||
public class ViaNode extends PcbNode {
|
||||
public final PointNode location;
|
||||
final SizeNode size;
|
||||
public final int netId;
|
||||
|
||||
public ViaNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
location = (PointNode) find("at");
|
||||
size = (SizeNode) find("size");
|
||||
netId = Integer.parseInt(find("net").getChild(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ViaNode{" +
|
||||
"location=" + location +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected(PointNode point) {
|
||||
return point.isConnected(location, size);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.rusefi.pcb.nodes;
|
||||
|
||||
import com.rusefi.pcb.nodes.LayerNode;
|
||||
import com.rusefi.pcb.nodes.PcbNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 2/11/14.
|
||||
*/
|
||||
public class ZoneNode extends PcbNode {
|
||||
private final LayerNode layerNode;
|
||||
|
||||
public ZoneNode(String nodeName, int i, List<Object> children) {
|
||||
super(nodeName, i, children);
|
||||
layerNode = (LayerNode) find("layer");
|
||||
}
|
||||
|
||||
public LayerNode getLayerNode() {
|
||||
return layerNode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.rusefi.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Generic file utilities
|
||||
* <p/>
|
||||
* 12/9/13
|
||||
* (c) Andrey Belomutskiy
|
||||
*/
|
||||
public class FileUtils {
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName
|
||||
* @return Full content of the file as one String
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String readFile(String fileName) throws IOException {
|
||||
checkExistence(fileName);
|
||||
|
||||
System.out.println("Reading " + fileName);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
BufferedReader br = new BufferedReader(new FileReader(fileName));
|
||||
|
||||
while (((line = br.readLine()) != null))
|
||||
sb.append(line).append("\r\n");
|
||||
br.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void checkExistence(String fileName) {
|
||||
if (!new File(fileName).isFile()) {
|
||||
System.err.println("File not found: " + fileName);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> readFileToList(String fileName) throws IOException {
|
||||
checkExistence(fileName);
|
||||
|
||||
List<String> result = new ArrayList<String>();
|
||||
|
||||
System.out.println("Reading " + fileName);
|
||||
String line;
|
||||
BufferedReader br = new BufferedReader(new FileReader(fileName));
|
||||
|
||||
while (((line = br.readLine()) != null))
|
||||
result.add(line);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.rusefi.netlist;
|
||||
|
||||
import com.rusefi.pcb.NameAndOffset;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class NameAndOffsetTest {
|
||||
@Test
|
||||
public void test() {
|
||||
NameAndOffset n = NameAndOffset.parseNameAndOffset("1 2 3");
|
||||
assertEquals("1", n.getName());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue