Added 'Check Trace Proximity' functionality under File -> Analyze menu

that checks if there are any traces or pads that are too close to each
other
This commit is contained in:
bancika
2020-12-20 12:48:12 +01:00
parent 26fa95670e
commit 3e5978beb7
19 changed files with 169 additions and 17 deletions
@@ -25,6 +25,7 @@ import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Area;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
@@ -40,6 +41,7 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.Template;
import org.diylc.core.Theme;
import org.diylc.core.measures.Size;
import org.diylc.test.ITestProcessor;
/**
@@ -396,5 +398,12 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/**
* Locks or unlocks a single component.
*/
void lockComponent(IDIYComponent<?> c, boolean locked);
void lockComponent(IDIYComponent<?> c, boolean locked);
/**
* Checks for proximity between continuity areas and creates additional components around any problematic areas to visually identify them.
*
* @param threshold
*/
List<Area> checkContinuityAreaProximity(Size threshold);
}
@@ -56,7 +56,7 @@ public interface IView {
int showConfirmDialog(String message, String title, int optionType, int messageType);
boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties);
boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties, String title);
String showInputDialog(String message, String title);
@@ -60,7 +60,7 @@ public class AreaUtils {
if (intersection != null && !intersection.isEmpty()) {
a1.add(a2);
consumed.set(j, true);
} else { // maybe there's a connection between them
} else if (connections != null) { // maybe there's a connection between them
for (Connection p : connections) { // use getBounds to optimize the computation, don't get into complex math if not needed
if ((a1.getBounds().contains(p.getP1()) && a2.getBounds().contains(p.getP2()) && a1.contains(p.getP1()) && a2.contains(p.getP2())) ||
(a1.getBounds().contains(p.getP2()) && a2.getBounds().contains(p.getP1())) && a1.contains(p.getP2()) && a2.contains(p.getP1())) {
@@ -26,8 +26,11 @@ import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
@@ -55,6 +58,8 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
/**
@@ -112,6 +117,8 @@ public class DrawingManager {
private IConfigurationManager<?> configManager;
private List<Area> proximityMarkers = null;
public DrawingManager(MessageDispatcher<EventType> messageDispatcher, IConfigurationManager<?> configManager) {
super();
this.messageDispatcher = messageDispatcher;
@@ -470,6 +477,14 @@ public class DrawingManager {
g2d.draw(a);
}
}
if (this.proximityMarkers != null)
{
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.setColor(Color.red);
for (Shape s : this.proximityMarkers)
g2d.draw(s);
}
if (currentContinuityArea != null) {
Composite oldComposite = g2d.getComposite();
@@ -524,6 +539,7 @@ public class DrawingManager {
public void invalidateComponent(IDIYComponent<?> component) {
componentAreaMap.remove(component);
lastDrawnStateMap.remove(component);
proximityMarkers = null;
}
public ComponentArea getComponentArea(IDIYComponent<?> component) {
@@ -533,11 +549,13 @@ public class DrawingManager {
public void clearComponentAreaMap() {
componentAreaMap.clear();
lastDrawnStateMap.clear();
proximityMarkers = null;
}
public void clearContinuityArea() {
currentContinuityArea = null;
continuityAreaCache = null;
proximityMarkers = null;
}
public List<IDIYComponent<?>> findComponentsAt(Point2D point, Project project) {
@@ -654,5 +672,41 @@ public class DrawingManager {
AreaUtils.crunchAreas(areas, connections);
return areas;
}
}
public List<Area> getContinuityAreaProximity(Project project, float threshold) {
List<Area> continuityAreas = getContinuityAreas(project);
Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for approx good results
List<Area> expanded = continuityAreas.parallelStream().map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList());
List<Area> intersections = new ArrayList<Area>();
for (int i = 0; i < expanded.size() - 1; i++) {
for (int j = i + 1; j < expanded.size(); j++) {
Area first = new Area(expanded.get(i));
Area second = expanded.get(j);
first.intersect(second);
if (!first.isEmpty())
intersections.add(first);
}
}
AreaUtils.crunchAreas(intersections, null);
double minSize = new Size(1d, SizeUnit.cm).convertToPixels();
List<Area> shapes = new ArrayList<Area>();
for (Area a : intersections) {
Rectangle2D bounds2d = a.getBounds2D();
if (bounds2d.getWidth() < minSize)
bounds2d = new Rectangle2D.Double(bounds2d.getCenterX() - minSize / 2, bounds2d.getY(), minSize, bounds2d.getHeight());
if (bounds2d.getHeight() < minSize)
bounds2d = new Rectangle2D.Double(bounds2d.getX(), bounds2d.getCenterY() - minSize / 2, bounds2d.getWidth(), minSize);
shapes.add(new Area(new Ellipse2D.Double(bounds2d.getX(), bounds2d.getY(), bounds2d.getWidth(), bounds2d.getHeight())));
}
//AreaUtils.crunchAreas(shapes, null);
this.proximityMarkers = shapes;
return shapes;
}
}
@@ -863,7 +863,7 @@ public class Presenter implements IPlugInPort {
List<PropertyWrapper> properties = getMutualSelectionProperties();
if (properties != null && !properties.isEmpty()) {
Set<PropertyWrapper> defaultedProperties = new HashSet<PropertyWrapper>();
boolean edited = view.editProperties(properties, defaultedProperties);
boolean edited = view.editProperties(properties, defaultedProperties, LangUtil.translate("Edit Selection"));
if (edited) {
try {
applyPropertiesToSelection(properties);
@@ -3412,4 +3412,9 @@ public class Presenter implements IPlugInPort {
}
return new Snapshot(currentProject.clone(), new HashSet<IDIYComponent<?>>(selectedComponents), areas, new HashSet<Area>(drawingManager.getContinuityAreas(currentProject)));
}
@Override
public List<Area> checkContinuityAreaProximity(Size threshold) {
return drawingManager.getContinuityAreaProximity(this.currentProject, (float)threshold.convertToPixels());
}
}
@@ -3354,6 +3354,10 @@
<releaseDate>2020-12-06 00:00:00.000 CET</releaseDate>
<name></name>
<changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added 'Check Trace Proximity' functionality under File -> Analyze menu that checks if there are any traces or pads that are too close to each other</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>'Tactile Micro-Switch' component added</description>