diff --git a/diylc/diylc-core/src/org/diylc/common/PCBLayer.java b/diylc/diylc-core/src/org/diylc/common/PCBLayer.java index 4b8ffcad..b91b8a90 100644 --- a/diylc/diylc-core/src/org/diylc/common/PCBLayer.java +++ b/diylc/diylc-core/src/org/diylc/common/PCBLayer.java @@ -23,9 +23,13 @@ package org.diylc.common; public enum PCBLayer { - _1, _2, _3, _4, _5; + _1, _2, _3, _4, _5, _6, _7, _8; public String toString() { return name().substring(1); - }; + }; + + public int getId() { + return Integer.parseInt(toString()); + } } diff --git a/diylc/diylc-core/src/org/diylc/core/ComponentForRender.java b/diylc/diylc-core/src/org/diylc/core/ComponentForRender.java new file mode 100644 index 00000000..afd651b8 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/core/ComponentForRender.java @@ -0,0 +1,53 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2018 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.core; + +/** + * Component with all extra info for it to be rendered on the screen. + * + * @author Branislav Stojkovic + */ +public class ComponentForRender { + + private IDIYComponent component; + private ComponentState state; + private int zOrder; + + public ComponentForRender(IDIYComponent component, ComponentState state, int zOrder) { + super(); + this.component = component; + this.state = state; + this.zOrder = zOrder; + } + + public IDIYComponent getComponent() { + return component; + } + + public ComponentState getState() { + return state; + } + + public int getZOrder() { + return zOrder; + } +} diff --git a/diylc/diylc-core/src/org/diylc/core/ILayer.java b/diylc/diylc-core/src/org/diylc/core/ILayer.java new file mode 100644 index 00000000..4c350c0c --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/core/ILayer.java @@ -0,0 +1,6 @@ +package org.diylc.core; + +public interface ILayer { + + int getLayerId(); +} diff --git a/diylc/diylc-core/src/org/diylc/netlist/ContinuityGraph.java b/diylc/diylc-core/src/org/diylc/netlist/ContinuityGraph.java index 64cafc20..5a99b139 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/ContinuityGraph.java +++ b/diylc/diylc-core/src/org/diylc/netlist/ContinuityGraph.java @@ -23,6 +23,8 @@ import java.awt.geom.Point2D; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; +import org.diylc.presenter.ContinuityArea; import org.diylc.utils.RTree; /*** @@ -34,9 +36,9 @@ import org.diylc.utils.RTree; public class ContinuityGraph { private RTree groupTree; - private Map> areaGroupMap; + private Map> areaGroupMap; - public ContinuityGraph(RTree groupTree, Map> areaGroupMap) { + public ContinuityGraph(RTree groupTree, Map> areaGroupMap) { super(); this.groupTree = groupTree; this.areaGroupMap = areaGroupMap; @@ -44,22 +46,26 @@ public class ContinuityGraph { public List findAreasFor(Point2D point) { Optional first = groupTree.search(point, NetlistBuilder.eps).stream() - .filter(node -> node.getArea().contains(point)).findFirst(); + .filter(node -> node.getArea().getArea().contains(point)).findFirst(); - return first.map(node -> areaGroupMap.get(node.getGroupId())).orElse(null); + return first.map(node -> + areaGroupMap.get(node.getGroupId()) + .stream() + .map(x -> x.getArea()) + .collect(Collectors.toList())).orElse(null); } public static class ContinuityNode { - private Area area; + private ContinuityArea area; private Integer groupId; - public ContinuityNode(Area area, Integer groupId) { + public ContinuityNode(ContinuityArea area, Integer groupId) { super(); this.area = area; this.groupId = groupId; } - public Area getArea() { + public ContinuityArea getArea() { return area; } diff --git a/diylc/diylc-core/src/org/diylc/netlist/Group.java b/diylc/diylc-core/src/org/diylc/netlist/Group.java index e16b78d6..ed3423d6 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/Group.java +++ b/diylc/diylc-core/src/org/diylc/netlist/Group.java @@ -52,7 +52,11 @@ public class Group implements Comparable { } public Group connect(IDIYComponent component, int index) { - getNodes().add(new Node(component, index)); + return connect(component, index, 0); + } + + public Group connect(IDIYComponent component, int index, int zOrder) { + getNodes().add(new Node(component, index, zOrder)); return this; } diff --git a/diylc/diylc-core/src/org/diylc/netlist/NetlistAnalyzer.java b/diylc/diylc-core/src/org/diylc/netlist/NetlistAnalyzer.java index 51f426b8..9fcc3ba5 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/NetlistAnalyzer.java +++ b/diylc/diylc-core/src/org/diylc/netlist/NetlistAnalyzer.java @@ -80,7 +80,7 @@ public abstract class NetlistAnalyzer { for (int i = 0; i < c.getControlPointCount(); i++) { if (i != n.getPointIndex() && c.getInternalLinkName(i, n.getPointIndex()) != null) { TreeLeaf l = new TreeLeaf(c, i, n.getPointIndex()); - Node newNodeA = new Node(c, i); + Node newNodeA = new Node(c, i, n.getZIndex()); if (!visited.contains(newNodeA)) { // visited.add(n); Tree newCurrentPath = null; diff --git a/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java b/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java index 9c216646..0994b242 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java +++ b/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java @@ -22,6 +22,7 @@ import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -39,6 +40,7 @@ import org.diylc.lang.LangUtil; import org.diylc.netlist.ContinuityGraph.ContinuityNode; import org.diylc.presenter.ComponentProcessor; import org.diylc.presenter.Connection; +import org.diylc.presenter.ContinuityArea; import org.diylc.utils.RTree; import com.google.common.graph.GraphBuilder; import com.google.common.graph.ImmutableGraph; @@ -55,36 +57,39 @@ public class NetlistBuilder { .translate("Maximum number of switching combinations exceeded. Allowed: %s, actual: %s"); @SuppressWarnings("unchecked") - public static List extractNetlists(boolean includeSwitches, Project project, List continuityAreas) - throws NetlistException { + public static List extractNetlists(boolean includeSwitches, Project project, + List continuityAreas) throws NetlistException { Map result = new HashMap(); List nodes = new ArrayList(); List switches = new ArrayList(); - + Set commonNodes = new HashSet(); - for (IDIYComponent c : project.getComponents()) { + for (int j = 0; j < project.getComponents().size(); j++) { + IDIYComponent c = project.getComponents().get(j); ComponentType type = ComponentProcessor.getInstance() .extractComponentTypeFrom((Class>) c.getClass()); // extract nodes if (!(c instanceof IContinuity) && !(c instanceof ICommonNode)) { + // regular components, create a node per control point for (int i = 0; i < c.getControlPointCount(); i++) { String nodeName = c.getControlPointNodeName(i); - if (nodeName != null + if (c.isControlPointSticky(i) && nodeName != null && (!includeSwitches || !ISwitch.class.isAssignableFrom(type.getInstanceClass()))) { - nodes.add(new Node(c, i)); + nodes.add(new Node(c, i, j)); } } } - - // create only one node per common label to avoid duplications in the netlist, as they will get eventually connected anyways + + // create only one node per common label to avoid duplications in the netlist, as they will + // get eventually connected anyways if (c instanceof ICommonNode) { - String label = ((ICommonNode)c).getCommonNodeLabel(); + String label = ((ICommonNode) c).getCommonNodeLabel(); if (!commonNodes.contains(label)) { commonNodes.add(label); - nodes.add(new Node(c, 0)); + nodes.add(new Node(c, 0, j)); } } @@ -142,8 +147,8 @@ public class NetlistBuilder { } List connections = getConnections(project, switchPositions); - Netlist netlist = NetlistBuilder.buildNetlist(project.getComponents(), nodes, - continuityAreas, connections); + Netlist netlist = + NetlistBuilder.buildNetlist(project.getComponents(), nodes, continuityAreas, connections); // merge graphs that are effectively the same if (result.containsKey(netlist)) { @@ -176,7 +181,7 @@ public class NetlistBuilder { } public static Netlist buildNetlist(List> components, Collection nodes, - Collection continuityAreas, Collection connections) { + Collection continuityAreas, Collection connections) { ImmutableGraph graph = buildGraph(nodes, continuityAreas, connections); Traverser traverser = Traverser.forGraph(graph); @@ -211,7 +216,7 @@ public class NetlistBuilder { return netlist; } - public static ContinuityGraph buildContinuityGraph(Collection continuityAreas, + public static ContinuityGraph buildContinuityGraph(Collection continuityAreas, Collection connections) { ImmutableGraph graph = buildGraph(new ArrayList(), continuityAreas, connections); @@ -224,7 +229,7 @@ public class NetlistBuilder { int groupId = 1; RTree groupTree = new RTree(); - Map> areaGroupMap = new HashMap>(); + Map> areaGroupMap = new HashMap>(); while (true) { @@ -237,12 +242,13 @@ public class NetlistBuilder { final int finalGroupId = groupId; - List areaList = new ArrayList(); + List areaList = new ArrayList(); traverser.breadthFirst(nodeArr[i]).forEach(node -> { visited.add(node); if (node.getArea() != null) { areaList.add(node.getArea()); - groupTree.insert(node.getArea(), new ContinuityNode(node.getArea(), finalGroupId)); + groupTree.insert(node.getArea().getArea(), + new ContinuityNode(node.getArea(), finalGroupId)); } }); @@ -257,7 +263,7 @@ public class NetlistBuilder { /**** * Build an {@link ImmutableGraph} containing the following nodes: project nodes, both ends of - * each connection and one node per continuity areas. All vertices are added based on object + * each connection and one node per continuity area. All vertices are added based on object * proximity or intersection. * * @param nodes @@ -266,45 +272,52 @@ public class NetlistBuilder { * @return */ private static ImmutableGraph buildGraph(Collection nodes, - Collection continuityAreas, Collection connections) { - Map> nodeMap = new HashMap>(); + Collection continuityAreas, Collection connections) { - RTree nodeTree = new RTree(); + Map> nodeMapByPoint = + new HashMap>(); + + // RTree nodeTree = new RTree(); RTree areaTree = new RTree(); Builder builder = GraphBuilder.undirected().immutable(); + List controlPointNodeList = new ArrayList(); + for (Node node : nodes) { Point2D p = snapToEps(node.getPoint2D(), eps); ProjectGraphNode graphNode = new ProjectGraphNode(p, node); builder.addNode(graphNode); - nodeTree.insert(new float[] {(float) (p.getX() - eps), (float) (p.getY() - eps)}, - new float[] {eps * 2, eps * 2}, graphNode); - nodeMap.computeIfAbsent(p, (point) -> new ArrayList()) + // nodeTree.insert(new float[] {(float) (p.getX() - eps), (float) (p.getY() - eps)}, + // new float[] {eps * 2, eps * 2}, graphNode); + nodeMapByPoint.computeIfAbsent(p, (point) -> new ArrayList()) .add(new ProjectGraphNode(p, node)); + controlPointNodeList.add(graphNode); } for (Connection conn : connections) { Point2D p1 = snapToEps(conn.getP1(), eps); Point2D p2 = snapToEps(conn.getP2(), eps); - ProjectGraphNode graphNode1 = new ProjectGraphNode(p1); - ProjectGraphNode graphNode2 = new ProjectGraphNode(p2); + ProjectGraphNode graphNode1 = new ProjectGraphNode(p1, conn.getZIndex()); + ProjectGraphNode graphNode2 = new ProjectGraphNode(p2, conn.getZIndex()); - nodeTree.insert(new float[] {(float) p1.getX() - eps, (float) p1.getY() - eps}, - new float[] {eps * 2, eps * 2}, graphNode1); - nodeTree.insert(new float[] {(float) p2.getX() - eps, (float) p2.getY() - eps}, - new float[] {eps * 2, eps * 2}, graphNode2); + // nodeTree.insert(new float[] {(float) p1.getX() - eps, (float) p1.getY() - eps}, + // new float[] {eps * 2, eps * 2}, graphNode1); + // nodeTree.insert(new float[] {(float) p2.getX() - eps, (float) p2.getY() - eps}, + // new float[] {eps * 2, eps * 2}, graphNode2); builder.addNode(graphNode1); builder.addNode(graphNode2); builder.putEdge(graphNode1, graphNode2); - nodeMap.computeIfAbsent(p1, (point) -> new ArrayList()).add(graphNode1); - nodeMap.computeIfAbsent(p2, (point) -> new ArrayList()).add(graphNode2); + nodeMapByPoint.computeIfAbsent(p1, (point) -> new ArrayList()) + .add(graphNode1); + nodeMapByPoint.computeIfAbsent(p2, (point) -> new ArrayList()) + .add(graphNode2); } - for (Map.Entry> entry : nodeMap.entrySet()) { + for (Map.Entry> entry : nodeMapByPoint.entrySet()) { ProjectGraphNode[] nodeArr = entry.getValue().toArray(new ProjectGraphNode[0]); for (int i = 0; i < nodeArr.length - 1; i++) { for (int j = i + 1; j < nodeArr.length; j++) { @@ -313,30 +326,36 @@ public class NetlistBuilder { } } - for (Area area : continuityAreas) { + for (ContinuityArea area : continuityAreas) { ProjectGraphNode areaNode = new ProjectGraphNode(area); builder.addNode(areaNode); - ProjectGraphNode[] nodeArr = nodeTree.search(area).stream() - .filter(graphNode -> area.contains(graphNode.getPoint()) - || area.intersects(graphNode.getPoint().getX() - eps / 2, - graphNode.getPoint().getY() - eps / 2, eps, eps)) - .collect(Collectors.toList()).toArray(new ProjectGraphNode[0]); + // List candidateNodes = nodeTree.search(area.getArea()).stream() + // .filter(graphNode -> area.getArea().contains(graphNode.getPoint()) + // || area.getArea().intersects(graphNode.getPoint().getX() - eps / 2, + // graphNode.getPoint().getY() - eps / 2, eps, eps)) + // .collect(Collectors.toList()); + // + // List nodesAbove = candidateNodes.stream() + // .filter(x -> x.getNode().getZIndex() > area.getZOrder()) + // .sorted(Comparator.comparing(x -> x.getNode().getZIndex(), Comparator.reverseOrder())) + // .collect(Collectors.toList()); + // + // for (ProjectGraphNode node : nodeArr) { + // builder.putEdge(node, areaNode); + // } - for (ProjectGraphNode node : nodeArr) { - builder.putEdge(node, areaNode); - } + // for (int i = 0; i < nodeArr.length - 1; i++) { + // for (int j = i + 1; j < nodeArr.length; j++) { + // builder.putEdge(nodeArr[i], nodeArr[j]); + // } + // } - for (int i = 0; i < nodeArr.length - 1; i++) { - for (int j = i + 1; j < nodeArr.length; j++) { - builder.putEdge(nodeArr[i], nodeArr[j]); - } - } - - areaTree.search(area).stream().filter(graphNode -> { - if (graphNode.getArea() != null && graphNode.getArea() != area) { - Area a = new Area(graphNode.getArea()); - a.intersect(area); + areaTree.search(area.getArea()).stream().filter(graphNode -> { + if (graphNode.getArea() != null && graphNode.getArea() != area + && graphNode.getArea().getLayerId() == area.getLayerId()) { + Area a = new Area(graphNode.getArea().getArea()); + a.intersect(area.getArea()); return !a.isEmpty(); } return false; @@ -344,36 +363,68 @@ public class NetlistBuilder { builder.putEdge(graphNode, areaNode); }); - areaTree.insert(area, areaNode); + areaTree.insert(area.getArea(), areaNode); + } + + for (Map.Entry> entry : nodeMapByPoint.entrySet()) { + + final Point2D point = entry.getKey(); + + List candidateAreaNodes = areaTree.search(point, eps).stream() + .filter(graphNode -> graphNode.getArea().getArea().contains(point) + || graphNode.getArea().getArea().intersects(point.getX() - eps / 2, + point.getY() - eps / 2, eps, eps)) + .collect(Collectors.toList()); + + if (candidateAreaNodes.isEmpty()) + continue; + + for (ProjectGraphNode pointNode : entry.getValue()) { + + List areaNodesBelowPoint = candidateAreaNodes.stream() + .filter(x -> x.getArea().getZIndex() < pointNode.getZIndex()) + .sorted(Comparator.comparing(x -> x.getArea().getZIndex(), Comparator.reverseOrder())) + .collect(Collectors.toList()); + + if (areaNodesBelowPoint.isEmpty()) { + builder.putEdge(pointNode, candidateAreaNodes.get(0)); + } else { + builder.putEdge(pointNode, areaNodesBelowPoint.get(0)); + } + } } return builder.build(); } - + @SuppressWarnings({"unchecked", "unlikely-arg-type"}) - private static List getConnections(Project project, Map switchPositions) { + private static List getConnections(Project project, + Map switchPositions) { Set connections = new TreeSet(); - - Map>> commonNodeMap = new HashMap>>(); - - for (IDIYComponent c : project.getComponents()) { - ComponentType type = - ComponentProcessor.getInstance().extractComponentTypeFrom((Class>) c.getClass()); + + Map>> commonNodeMap = + new HashMap>>(); + + for (int z = 0; z < project.getComponents().size(); z++) { + IDIYComponent c = project.getComponents().get(z); + ComponentType type = ComponentProcessor.getInstance() + .extractComponentTypeFrom((Class>) c.getClass()); // handle direct connections if (c instanceof IContinuity) { for (int i = 0; i < c.getControlPointCount() - 1; i++) for (int j = i + 1; j < c.getControlPointCount(); j++) if (((IContinuity) c).arePointsConnected(i, j)) - connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j))); + connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j), z)); } // handle switches - if (ISwitch.class.isAssignableFrom(type.getInstanceClass()) && switchPositions.containsKey(c)) { + if (ISwitch.class.isAssignableFrom(type.getInstanceClass()) + && switchPositions.containsKey(c)) { int position = switchPositions.get(c); ISwitch s = (ISwitch) c; for (int i = 0; i < c.getControlPointCount() - 1; i++) for (int j = i + 1; j < c.getControlPointCount(); j++) if (s.arePointsConnected(i, j, position)) - connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j))); + connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j), z)); } // handle common nodes if (ICommonNode.class.isAssignableFrom(type.getInstanceClass())) { @@ -382,12 +433,13 @@ public class NetlistBuilder { commonNodeMap.computeIfAbsent(label, (key) -> new ArrayList>()).add(c); } } - + // connect common nodes together by chaining them one by one for (List> commonPoints : commonNodeMap.values()) { IDIYComponent[] commonPointArr = commonPoints.toArray(new IDIYComponent[0]); for (int i = 0; i < commonPointArr.length - 1; i++) { - connections.add(new Connection(commonPointArr[i].getControlPoint(0), commonPointArr[i + 1].getControlPoint(0))); + connections.add(new Connection(commonPointArr[i].getControlPoint(0), + commonPointArr[i + 1].getControlPoint(0), 0)); } } @@ -399,19 +451,22 @@ public class NetlistBuilder { Math.round(point.getY() / eps) * eps); } - private static class ProjectGraphNode { + static class ProjectGraphNode { private Point2D point; private Node node; - private Area area; + private ContinuityArea area; + private int zIndex; - public ProjectGraphNode(Area area) { + public ProjectGraphNode(ContinuityArea area) { super(); this.area = area; + this.zIndex = area.getZIndex(); } - public ProjectGraphNode(Point2D point) { + public ProjectGraphNode(Point2D point, int zIndex) { super(); this.point = point; + this.zIndex = zIndex; this.node = null; } @@ -419,17 +474,22 @@ public class NetlistBuilder { super(); this.point = point; this.node = node; + this.zIndex = node.getZIndex(); } public Point2D getPoint() { return point; } + + public int getZIndex() { + return zIndex; + } public Node getNode() { return node; } - public Area getArea() { + public ContinuityArea getArea() { return area; } } diff --git a/diylc/diylc-core/src/org/diylc/netlist/Node.java b/diylc/diylc-core/src/org/diylc/netlist/Node.java index 659c03c1..238d24ec 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/Node.java +++ b/diylc/diylc-core/src/org/diylc/netlist/Node.java @@ -34,11 +34,13 @@ public class Node implements Comparable { private IDIYComponent component; private int pointIndex; + private int zIndex; - public Node(IDIYComponent component, int pointIndex) { + public Node(IDIYComponent component, int pointIndex, int zIndex) { super(); this.component = component; this.pointIndex = pointIndex; + this.zIndex = zIndex; } public IDIYComponent getComponent() { @@ -49,6 +51,10 @@ public class Node implements Comparable { return pointIndex; } + public int getZIndex() { + return zIndex; + } + public String getDisplayName() { String[] section = component.getSectionNames(pointIndex); return (section == null || section.length > 1 ? "" : section[0] + ".") + component.getControlPointNodeName(pointIndex); diff --git a/diylc/diylc-core/src/org/diylc/presenter/ComponentArea.java b/diylc/diylc-core/src/org/diylc/presenter/ComponentArea.java index c6140807..4544ad4a 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/ComponentArea.java +++ b/diylc/diylc-core/src/org/diylc/presenter/ComponentArea.java @@ -29,6 +29,7 @@ public class ComponentArea implements Serializable { private static final long serialVersionUID = 1L; + private int zOrder; private Area outlineArea; private Collection continuityPositiveAreas; private Collection continuityNegativeAreas; @@ -36,12 +37,17 @@ public class ComponentArea implements Serializable { public ComponentArea() { } - public ComponentArea(Area outlineArea, Collection continuityPositiveAreas, Collection continuityNegativeAreas) { + public ComponentArea(int zOrder, Area outlineArea, Collection continuityPositiveAreas, Collection continuityNegativeAreas) { super(); + this.zOrder = zOrder; this.outlineArea = outlineArea; this.continuityPositiveAreas = continuityPositiveAreas; this.continuityNegativeAreas = continuityNegativeAreas; } + + public int getZOrder() { + return zOrder; + } public Area getOutlineArea() { return outlineArea; diff --git a/diylc/diylc-core/src/org/diylc/presenter/Connection.java b/diylc/diylc-core/src/org/diylc/presenter/Connection.java index acdf49b3..7efda682 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Connection.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Connection.java @@ -28,10 +28,12 @@ public class Connection implements Comparable { private Point2D p1; private Point2D p2; + private int zIndex; - public Connection(Point2D p1, Point2D p2) { + public Connection(Point2D p1, Point2D p2, int zIndex) { this.p1 = p1.getX() < p2.getX() || p1.getX() == p2.getX() && p1.getY() < p2.getY() ? p1 : p2; this.p2 = p1.getX() < p2.getX() || p1.getX() == p2.getX() && p1.getY() < p2.getY() ? p2 : p1; + this.zIndex = zIndex; } public Point2D getP1() { @@ -41,6 +43,10 @@ public class Connection implements Comparable { public Point2D getP2() { return p2; } + + public int getZIndex() { + return zIndex; + } @Override public int hashCode() { @@ -48,6 +54,7 @@ public class Connection implements Comparable { int result = 1; result = prime * result + ((p1 == null) ? 0 : p1.hashCode()); result = prime * result + ((p2 == null) ? 0 : p2.hashCode()); + result = prime * result + zIndex; return result; } @@ -70,6 +77,8 @@ public class Connection implements Comparable { return false; } else if (!p2.equals(other.p2)) return false; + if (zIndex != other.zIndex) + return false; return true; } diff --git a/diylc/diylc-core/src/org/diylc/presenter/ContinuityArea.java b/diylc/diylc-core/src/org/diylc/presenter/ContinuityArea.java new file mode 100644 index 00000000..b30b5f58 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/presenter/ContinuityArea.java @@ -0,0 +1,52 @@ +/* + * + * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors. + * + * This file is part of DIYLC. + * + * DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with DIYLC. If not, see + * . + * + */ +package org.diylc.presenter; + +import java.awt.geom.Area; +import java.io.Serializable; + +public class ContinuityArea implements Serializable { + + private static final long serialVersionUID = 1L; + + private int zIndex; + private int layerId; + private Area area; + + public ContinuityArea() {} + + public ContinuityArea(int zIndex, int layerId, Area area) { + super(); + this.zIndex = zIndex; + this.layerId = layerId; + this.area = area; + } + + public int getZIndex() { + return zIndex; + } + + public Area getArea() { + return area; + } + + public int getLayerId() { + return layerId; + } +} diff --git a/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java b/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java index 357d8cf2..2338b64e 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java +++ b/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.apache.log4j.Logger; import org.diylc.common.ComponentType; +import org.diylc.core.ComponentForRender; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.Project; @@ -63,14 +64,14 @@ public class DrawingCache { * @param zoom */ @SuppressWarnings("unchecked") - public void bulkPrepare(Map, ComponentState> components, G2DWrapper g2d, boolean outlineMode, Project project, double zoom) { + public void bulkPrepare(Collection components, G2DWrapper g2d, boolean outlineMode, Project project, double zoom) { // run all renders in parallel to utilize all CPU cores - components.entrySet().stream().parallel().forEach(x -> { + components.stream().parallel().forEach(x -> { ComponentType type = ComponentProcessor.getInstance() - .extractComponentTypeFrom((Class>) x.getKey().getClass()); + .extractComponentTypeFrom((Class>) x.getComponent().getClass()); if (type != null && type.getEnableCache()) { - renderAndCache(x.getKey(), g2d, x.getValue(), outlineMode, project, zoom); + renderAndCache(x.getComponent(), g2d, x.getState(), outlineMode, project, zoom, x.getZOrder()); } }); } @@ -88,7 +89,7 @@ public class DrawingCache { */ @SuppressWarnings("unchecked") public void draw(IDIYComponent component, G2DWrapper g2d, ComponentState componentState, - boolean outlineMode, Project project, double zoom, Rectangle2D visibleRect) { + boolean outlineMode, Project project, double zoom, int zOrder, Rectangle2D visibleRect) { ComponentType type = ComponentProcessor.getInstance() .extractComponentTypeFrom((Class>) component.getClass()); @@ -96,7 +97,7 @@ public class DrawingCache { // if we need to apply caching Point2D firstPoint = component.getControlPoint(0); - CacheValue value = renderAndCache(component, g2d, componentState, outlineMode, project, zoom); + CacheValue value = renderAndCache(component, g2d, componentState, outlineMode, project, zoom, zOrder); if (value == null) { return; @@ -175,7 +176,7 @@ public class DrawingCache { } private CacheValue renderAndCache(IDIYComponent component, G2DWrapper g2d, ComponentState componentState, - boolean outlineMode, Project project, double zoom) { + boolean outlineMode, Project project, double zoom, int zOrder) { // if we need to apply caching Point2D firstPoint = component.getControlPoint(0); @@ -225,7 +226,7 @@ public class DrawingCache { G2DWrapper wrapper = new G2DWrapper(cg2d, zoom); // initialize wrapper - wrapper.startedDrawingComponent(); + wrapper.startedDrawingComponent(zOrder); long componentStart = System.nanoTime(); diff --git a/diylc/diylc-core/src/org/diylc/presenter/DrawingManager.java b/diylc/diylc-core/src/org/diylc/presenter/DrawingManager.java index 55c08180..25c26aac 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/DrawingManager.java +++ b/diylc/diylc-core/src/org/diylc/presenter/DrawingManager.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -52,9 +53,11 @@ import org.diylc.common.GridType; import org.diylc.common.IComponentFilter; import org.diylc.common.IPlugInPort; import org.diylc.common.ObjectCache; +import org.diylc.core.ComponentForRender; import org.diylc.core.ComponentState; import org.diylc.core.IContinuity; import org.diylc.core.IDIYComponent; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.Theme; import org.diylc.core.VisibilityPolicy; @@ -136,7 +139,7 @@ public class DrawingManager { configManager.writeValue(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); } - componentAreaMap = new HashMap, ComponentArea>(); + componentAreaMap = new LinkedHashMap, ComponentArea>(); lastDrawnStateMap = new HashMap, ComponentState>(); String debugComponentAreasStr = System.getProperty(DEBUG_COMPONENT_AREAS); debugComponentAreas = @@ -252,9 +255,10 @@ public class DrawingManager { // g2dWrapper.resetTx(); // put components and their states in a map - Map, ComponentState> componentStateMap = - new HashMap, ComponentState>(); - for (IDIYComponent component : project.getComponents()) { + Map, ComponentState> componentStateMap = new HashMap, ComponentState>(); + List componentForRenderList = new ArrayList(); + for (int i = 0; i < project.getComponents().size(); i++) { + IDIYComponent component = project.getComponents().get(i); ComponentState state = ComponentState.NORMAL; if (drawOptions.contains(DrawOption.SELECTION) && selectedComponents.contains(component)) { if (dragInProgress) { @@ -264,17 +268,21 @@ public class DrawingManager { } } componentStateMap.put(component, state); + componentForRenderList.add(new ComponentForRender(component, state, i)); } boolean outlineMode = drawOptions.contains(DrawOption.OUTLINE_MODE); // give the cache a chance to prepare all the components in multiple threads if (drawOptions.contains(DrawOption.ENABLE_CACHING)) { - DrawingCache.Instance.bulkPrepare(componentStateMap, g2dWrapper, outlineMode, project, zoom); + DrawingCache.Instance.bulkPrepare(componentForRenderList, g2dWrapper, outlineMode, project, zoom); } // componentAreaMap.clear(); - for (IDIYComponent component : project.getComponents()) { + + for (int i = 0; i < project.getComponents().size(); i++) { + IDIYComponent component = project.getComponents().get(i); + // Do not draw the component if it's filtered out. if (filter != null && !filter.testComponent(component)) { continue; @@ -285,7 +293,7 @@ public class DrawingManager { boolean trackArea = lastDrawnStateMap.get(component) != state; synchronized (g2d) { - g2dWrapper.startedDrawingComponent(); + g2dWrapper.startedDrawingComponent(i); if (!trackArea) { g2dWrapper.stopTracking(); } @@ -300,7 +308,7 @@ public class DrawingManager { if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache DrawingCache.Instance.draw(component, g2dWrapper, state, - drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, visibleRect); + drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, i, visibleRect); else // go straight to the wrapper component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper); @@ -386,7 +394,7 @@ public class DrawingManager { // Draw component slot in a separate composite. if (componentSlot != null) { - g2dWrapper.startedDrawingComponent(); + g2dWrapper.startedDrawingComponent(project.getComponents().size()); g2dWrapper.setComposite(slotComposite); for (IDIYComponent component : componentSlot) { try { @@ -684,77 +692,100 @@ public class DrawingManager { messageDispatcher.dispatchMessage(EventType.REPAINT); } - public void findContinuityAreaAtPoint(Project project, Point2D p) { + public void findContinuityAreaAtPoint(Point2D p) { if (continuityGraphCache == null) - continuityGraphCache = getContinuityGraph(project); + continuityGraphCache = getContinuityGraph(); currentContinuityAreas = continuityGraphCache.findAreasFor(p); } - public List getContinuityAreas(Project project) { + public List getContinuityAreas() { // Find all individual continuity areas for all components - List preliminaryAreas = new ArrayList(); + List preliminaryAreas = new ArrayList(); List checkBreakout = new ArrayList(); - for (IDIYComponent c : project.getComponents()) { - ComponentArea a = getComponentArea(c); + for (Map.Entry, ComponentArea> entry : this.componentAreaMap.entrySet()) { + ComponentArea a = entry.getValue(); if (a == null || a.getOutlineArea() == null) continue; + + IDIYComponent component = entry.getKey(); + + int layerId; + + if (component instanceof ILayer) { + layerId = ((ILayer)component).getLayerId(); + } else { + layerId = component.hashCode(); + } + Collection positiveAreas = a.getContinuityPositiveAreas(); - if (positiveAreas != null) + if (positiveAreas != null) { for (Area a1 : positiveAreas) { - preliminaryAreas.add(a1); + preliminaryAreas.add(new ContinuityArea(a.getZOrder(), layerId, a1)); checkBreakout.add(false); } + } + Collection negativeAreas = a.getContinuityNegativeAreas(); if (negativeAreas != null) { - for (Area na : negativeAreas) + for (Area na : negativeAreas) { for (int i = 0; i < preliminaryAreas.size(); i++) { - Area a1 = preliminaryAreas.get(i); - if (a1.intersects(na.getBounds2D())) { - a1.subtract(na); + ContinuityArea a1 = preliminaryAreas.get(i); + if (a1.getLayerId() == layerId && a1.getArea().intersects(na.getBounds2D())) { + a1.getArea().subtract(na); checkBreakout.set(i, true); } } + } } } // Check if we need to break some areas out in case they are interrupted - List areas = new ArrayList(); + List areas = new ArrayList(); for (int i = 0; i < preliminaryAreas.size(); i++) { - Area a = preliminaryAreas.get(i); - if (checkBreakout.get(i)) - areas.addAll(AreaUtils.tryAreaBreakout(a)); - else + ContinuityArea a = preliminaryAreas.get(i); + if (checkBreakout.get(i)) { + List breakoutAreas = AreaUtils.tryAreaBreakout(a.getArea()); + if (breakoutAreas.size() == 1) { + areas.add(a); + } else { + areas.addAll(breakoutAreas.stream() + .map(area -> new ContinuityArea(a.getZIndex(), a.getLayerId(), area)) + .collect(Collectors.toList())); + } + } else areas.add(a); } return areas; } - public ContinuityGraph getContinuityGraph(Project project) { + public ContinuityGraph getContinuityGraph() { Set connections = new HashSet(); - for (IDIYComponent c : project.getComponents()) { + int z = 0; + for (IDIYComponent c : this.componentAreaMap.keySet()) { if (c instanceof IContinuity) { for (int i = 0; i < c.getControlPointCount() - 1; i++) for (int j = i + 1; j < c.getControlPointCount(); j++) if (((IContinuity) c).arePointsConnected(i, j)) - connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j))); + connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j), z)); } + z++; } - List areas = getContinuityAreas(project); + List areas = getContinuityAreas(); return NetlistBuilder.buildContinuityGraph(areas, connections); } - public List getContinuityAreaProximity(Project project, float threshold) { - List continuityAreas = getContinuityAreas(project); + public List getContinuityAreaProximity(float threshold) { + List continuityAreas = getContinuityAreas(); Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for // approx good results List expanded = continuityAreas.parallelStream() - .map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList()); + .map((a) -> new Area(s.createStrokedShape(a.getArea()))).collect(Collectors.toList()); List intersections = new ArrayList(); for (int i = 0; i < expanded.size() - 1; i++) { for (int j = i + 1; j < expanded.size(); j++) { diff --git a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java index 3122828e..39a426bf 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java +++ b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java @@ -103,7 +103,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver { private String continuityMarker; private Shape lastShape; - private double zoom; + private double zoom; + private int zOrder; /** * Creates a wrapper around specified {@link Graphics2D} object. @@ -127,22 +128,25 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver { /** * Clears out the current area and caches canvas settings. + * + * @param zOrder */ - public void startedDrawingComponent() { - drawingComponent = true; - currentArea = new Area(); - continuityPositiveAreas = new HashMap(); - continuityNegativeAreas = new HashMap(); + public void startedDrawingComponent(int zOrder) { + this.zOrder = zOrder; + this.drawingComponent = true; + this.currentArea = new Area(); + this.continuityPositiveAreas = new HashMap(); + this.continuityNegativeAreas = new HashMap(); // trackingStacks.clear(); - continuityMarker = null; - originalStroke = canvasGraphics.getStroke(); - originalColor = canvasGraphics.getColor(); - originalTx = canvasGraphics.getTransform(); - originalComposite = canvasGraphics.getComposite(); - originalFont = canvasGraphics.getFont(); - currentTx = new AffineTransform(); - initialTx = canvasGraphics.getTransform(); - lastShape = null; + this.continuityMarker = null; + this.originalStroke = canvasGraphics.getStroke(); + this.originalColor = canvasGraphics.getColor(); + this.originalTx = canvasGraphics.getTransform(); + this.originalComposite = canvasGraphics.getComposite(); + this.originalFont = canvasGraphics.getFont(); + this.currentTx = new AffineTransform(); + this.initialTx = canvasGraphics.getTransform(); + this.lastShape = null; startTracking(); } @@ -159,7 +163,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver { canvasGraphics.setComposite(originalComposite); canvasGraphics.setFont(originalFont); // Map sorted = sortByComparator(trackingStacks, false); - return new ComponentArea(currentArea, new ArrayList(continuityPositiveAreas.values()), new ArrayList(continuityNegativeAreas.values())); + return new ComponentArea(zOrder,currentArea, new ArrayList(continuityPositiveAreas.values()), + new ArrayList(continuityNegativeAreas.values())); } // start - used for caching diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java index 481f4d1d..d0e2bc34 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java +++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java @@ -680,7 +680,7 @@ public class Presenter implements IPlugInPort { projectFileManager.notifyFileChange(); } } else if (configManager.readBoolean(HIGHLIGHT_CONTINUITY_AREA, false) || altDown) { - drawingManager.findContinuityAreaAtPoint(currentProject, scaledPoint); + drawingManager.findContinuityAreaAtPoint(scaledPoint); messageDispatcher.dispatchMessage(EventType.REPAINT); } else { List> newSelection = new ArrayList>(selectedComponents); @@ -2809,7 +2809,7 @@ public class Presenter implements IPlugInPort { @Override public List extractNetlists(boolean includeSwitches) throws NetlistException { - List continuityAreas = drawingManager.getContinuityAreas(currentProject); + List continuityAreas = drawingManager.getContinuityAreas(); return NetlistBuilder.extractNetlists(includeSwitches, currentProject, continuityAreas); } @@ -2874,11 +2874,12 @@ public class Presenter implements IPlugInPort { ComponentArea componentArea = drawingManager.getComponentArea(c); areas.put(c, componentArea); } - return new Snapshot(currentProject.clone(), new HashSet>(selectedComponents), areas, new HashSet(drawingManager.getContinuityAreas(currentProject))); + return new Snapshot(currentProject.clone(), new HashSet>(selectedComponents), areas, + new HashSet(drawingManager.getContinuityAreas())); } @Override public List checkContinuityAreaProximity(Size threshold) { - return drawingManager.getContinuityAreaProximity(this.currentProject, (float)threshold.convertToPixels()); + return drawingManager.getContinuityAreaProximity((float)threshold.convertToPixels()); } } diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml index 9fee9a08..7bd59522 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/update.xml +++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml @@ -4158,6 +4158,10 @@ BUG_FIX Fixed an issue that would cause capacitors to fail when creating, editing, moving or deleting + + IMPROVEMENT + Circuit analysis algorithm that supports netlist extraction, 'Highlight connected Areas' and 'Guitar Wiring Analyzer' features improved to take PCB trace layer and component z-order into account for better accuracy + NEW_FEATURE Added standard models in the drop down menu of the component toolbar diff --git a/diylc/diylc-core/src/org/diylc/test/Snapshot.java b/diylc/diylc-core/src/org/diylc/test/Snapshot.java index 29af9e9d..c8b68c55 100644 --- a/diylc/diylc-core/src/org/diylc/test/Snapshot.java +++ b/diylc/diylc-core/src/org/diylc/test/Snapshot.java @@ -1,12 +1,12 @@ package org.diylc.test; -import java.awt.geom.Area; import java.io.Serializable; import java.util.Map; import java.util.Set; import org.diylc.core.IDIYComponent; import org.diylc.core.Project; import org.diylc.presenter.ComponentArea; +import org.diylc.presenter.ContinuityArea; public class Snapshot implements Serializable { @@ -15,13 +15,13 @@ public class Snapshot implements Serializable { private Project project; private Set> selection; private Map, ComponentArea> areas; - private Set continuityAreas; + private Set continuityAreas; public Snapshot() { } public Snapshot(Project project, Set> selection, - Map, ComponentArea> areas, Set continuityAreas) { + Map, ComponentArea> areas, Set continuityAreas) { super(); this.project = project; this.selection = selection; @@ -41,7 +41,7 @@ public class Snapshot implements Serializable { return areas; } - public Set getContinuityAreas() { + public Set getContinuityAreas() { return continuityAreas; } diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 2754ec2f..b36ee17c 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/components/boards/PerfBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/PerfBoard.java index 7711a178..3f9935ea 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/PerfBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/PerfBoard.java @@ -30,6 +30,7 @@ import org.diylc.components.transform.AbstractBoardTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.annotations.BomPolicy; import org.diylc.core.annotations.ComponentDescriptor; @@ -44,7 +45,7 @@ import org.diylc.utils.Constants; zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with solder pads", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "Perf Board", transformer = AbstractBoardTransformer.class, enableCache = true) -public class PerfBoard extends AbstractBoard { +public class PerfBoard extends AbstractBoard implements ILayer { private static final long serialVersionUID = 1L; @@ -119,6 +120,11 @@ public class PerfBoard extends AbstractBoard { @Override public String getControlPointNodeName(int index) { return null; + } + + @Override + public int getLayerId() { + return 1; } @Override diff --git a/diylc/diylc-library/src/org/diylc/components/boards/TriPadBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/TriPadBoard.java index 6c3fe623..2a8d0688 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/TriPadBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/TriPadBoard.java @@ -31,6 +31,7 @@ import org.diylc.components.transform.VeroBoardTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.annotations.ComponentDescriptor; import org.diylc.core.annotations.EditableProperty; @@ -41,7 +42,7 @@ import org.diylc.utils.Constants; instanceNamePrefix = "Board", description = "Perforated FR4 board with copper strips connecting 3 holes in a row (aka TriPad Board)", keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = VeroBoardTransformer.class, enableCache = true) -public class TriPadBoard extends AbstractVeroBoard { +public class TriPadBoard extends AbstractVeroBoard implements ILayer { private static final long serialVersionUID = 1L; @@ -202,5 +203,10 @@ public class TriPadBoard extends AbstractVeroBoard { @Override public String getControlPointNodeName(int index) { return null; + } + + @Override + public int getLayerId() { + return 1; } } diff --git a/diylc/diylc-library/src/org/diylc/components/boards/VeroBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/VeroBoard.java index 5d8cd16c..8848b8a0 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/VeroBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/VeroBoard.java @@ -31,6 +31,7 @@ import org.diylc.components.transform.VeroBoardTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.annotations.BomPolicy; import org.diylc.core.annotations.ComponentDescriptor; @@ -42,7 +43,7 @@ import org.diylc.utils.Constants; description = "Perforated FR4 board with copper strips connecting all holes in a row", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = VeroBoardTransformer.class, enableCache = true) -public class VeroBoard extends AbstractVeroBoard { +public class VeroBoard extends AbstractVeroBoard implements ILayer { private static final long serialVersionUID = 1L; @@ -110,7 +111,10 @@ public class VeroBoard extends AbstractVeroBoard { } } - + @Override + public int getLayerId() { + return 1; + } @Override public String getControlPointNodeName(int index) { diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/CopperTrace.java b/diylc/diylc-library/src/org/diylc/components/connectivity/CopperTrace.java index 70cc903c..efe3e93c 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/CopperTrace.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/CopperTrace.java @@ -27,6 +27,7 @@ import org.diylc.components.transform.SimpleComponentTransformer; import org.diylc.core.ComponentState; import org.diylc.core.CreationMethod; import org.diylc.core.IDIYComponent; +import org.diylc.core.ILayer; import org.diylc.core.VisibilityPolicy; import org.diylc.core.annotations.BomPolicy; import org.diylc.core.annotations.ComponentDescriptor; @@ -40,7 +41,7 @@ import org.diylc.core.measures.SizeUnit; description = "Straight copper trace", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class) -public class CopperTrace extends AbstractLeadedComponent { +public class CopperTrace extends AbstractLeadedComponent implements ILayer { private static final long serialVersionUID = 1L; @@ -99,6 +100,11 @@ public class CopperTrace extends AbstractLeadedComponent { public void setLayer(PCBLayer layer) { this.layer = layer; } + + @Override + public int getLayerId() { + return getLayer().getId(); + } @Override protected float getLeadThickness() { diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java b/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java index ff3930b1..74b999d1 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java @@ -28,6 +28,7 @@ import org.diylc.components.transform.SimpleComponentTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.annotations.BomPolicy; import org.diylc.core.annotations.ComponentDescriptor; import org.diylc.core.annotations.EditableProperty; @@ -40,7 +41,7 @@ import org.diylc.core.measures.SizeUnit; zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class, enableCache = true) -public class CurvedTrace extends AbstractCurvedComponent { +public class CurvedTrace extends AbstractCurvedComponent implements ILayer { private static final long serialVersionUID = 1L; @@ -88,6 +89,11 @@ public class CurvedTrace extends AbstractCurvedComponent { public void setLayer(PCBLayer layer) { this.layer = layer; } + + @Override + public int getLayerId() { + return getLayer().getId(); + } @Override public Void getValue() { diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/GroundFill.java b/diylc/diylc-library/src/org/diylc/components/connectivity/GroundFill.java index 5e1f11eb..d9d817f9 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/GroundFill.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/GroundFill.java @@ -32,6 +32,7 @@ import org.diylc.components.transform.SimpleComponentTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.VisibilityPolicy; import org.diylc.core.annotations.BomPolicy; @@ -43,7 +44,7 @@ import org.diylc.core.measures.SizeUnit; @ComponentDescriptor(name = "Ground Fill", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "GF", description = "Polygonal ground fill area", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) -public class GroundFill extends AbstractComponent { +public class GroundFill extends AbstractComponent implements ILayer { private static final long serialVersionUID = 1L; @@ -148,7 +149,11 @@ public class GroundFill extends AbstractComponent { public void setLayer(PCBLayer layer) { this.layer = layer; } - + + @Override + public int getLayerId() { + return getLayer().getId(); + } @Deprecated @Override diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/SolderPad.java b/diylc/diylc-library/src/org/diylc/components/connectivity/SolderPad.java index fb265cdd..0de9bfdf 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/SolderPad.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/SolderPad.java @@ -28,6 +28,7 @@ import org.diylc.components.transform.SimpleComponentTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; +import org.diylc.core.ILayer; import org.diylc.core.Project; import org.diylc.core.VisibilityPolicy; import org.diylc.core.annotations.BomPolicy; @@ -44,7 +45,7 @@ import org.diylc.utils.Constants; description = "Copper solder pad, round or square", instanceNamePrefix = "Pad", zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class, enableCache = true) -public class SolderPad extends AbstractComponent { +public class SolderPad extends AbstractComponent implements ILayer { private static final long serialVersionUID = 1L; @@ -128,6 +129,11 @@ public class SolderPad extends AbstractComponent { public void setLayer(PCBLayer layer) { this.layer = layer; } + + @Override + public int getLayerId() { + return getLayer().getId(); + } @Override public String getName() { diff --git a/diylc/diylc-library/src/org/diylc/netlist/SpiceAnalyzer.java b/diylc/diylc-library/src/org/diylc/netlist/SpiceAnalyzer.java index 8d1e3864..981743a2 100644 --- a/diylc/diylc-library/src/org/diylc/netlist/SpiceAnalyzer.java +++ b/diylc/diylc-library/src/org/diylc/netlist/SpiceAnalyzer.java @@ -93,7 +93,7 @@ public class SpiceAnalyzer extends NetlistAnalyzer implements INetlistAnalyzer { if (c instanceof ISpiceMapper) pointIndex = ((ISpiceMapper)c).mapToSpiceNode(pointIndex); - int nodeIndex = find(new Node(c, pointIndex), groups); + int nodeIndex = find(new Node(c, pointIndex, 0), groups); if (nodeIndex < 0) nodeIndex = unconnectedIndex++; diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 2754ec2f..b36ee17c 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index 910a532b..643977a4 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ