--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2022 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.connection;
+
+import gnu.trove.map.hash.THashMap;
+
+/**
+ * Route point that is connected to two direct terminals.
+ *
+ * @author Hannu Niemisto
+ */
+public class DegeneratedRoutePoint extends RoutePoint {
+
+ public DegeneratedRoutePoint() {
+ super();
+ }
+
+ public DegeneratedRoutePoint(double x, double y) {
+ super(x, y);
+ }
+
+ @Override
+ DegeneratedRoutePoint copy(THashMap<Object, Object> map) {
+ DegeneratedRoutePoint copy = (DegeneratedRoutePoint) map.get(this);
+ if (copy == null) {
+ copy = new DegeneratedRoutePoint(x, y);
+ map.put(this, copy);
+ }
+ return copy;
+ }
+
+}
\ No newline at end of file
needsUpdate = true;
}
+ private boolean isDirectDirectConnection() {
+ return !isSimpleConnection && terminals.size() == 2 && terminals.get(0).hasDirectConnection()
+ && terminals.get(1).hasDirectConnection() && lines.size() <= 1;
+ }
+
/**
* Updates transient route lines, route link positions
* and sorts route points of each route line.
}
}
}
+ else if(isFullyDirectConnectionCase()) {
+ routeDirectDirectOneLineCase();
+ return;
+ }
else {
caseId = SimpleConnectionUtility.COMPLEX_CONNECTION;
routeFromTerminals(false);
line.sortPoints();
}
}
-
+
+ private boolean isFullyDirectConnectionCase() {
+ if (lines.size() != 1 && terminals.size() > 0)
+ return false;
+ for (RouteTerminal t : terminals) {
+ if (!t.hasDirectConnection())
+ return false;
+ }
+ return true;
+ }
+
+ private void routeDirectDirectOneLineCase() {
+ RouteLine line = lines.get(0);
+ double x = 0, y = 0;
+ double scale = 1 / terminals.size();
+ if(line.isHorizontal) {
+ y = line.position;
+ for (RouteTerminal t : terminals)
+ x += t.x;
+ x *= scale;
+ }
+ else {
+ x = line.position;
+ for (RouteTerminal t : terminals)
+ y += t.y;
+ y *= scale;
+ }
+ line.addPoint(new DegeneratedRoutePoint(x, y));
+ }
+
static class Interval {
public final double min;
public final double max;
public RouteLine pickLine(double x, double y, double tolerance, int mask) {
if(needsUpdate)
update();
- if(isSimpleConnection && transientLines.isEmpty()) {
+ if( (isSimpleConnection && transientLines.isEmpty()) || isDirectDirectConnection() ) {
if(terminals.size() == 2) {
if((mask & PICK_TRANSIENT_LINES) == 0)
return null;
public void getPath2D(Path2D path) {
if(needsUpdate)
update();
-
- if(isSimpleConnection && transientLines.isEmpty()) {
- if(terminals.size() == 2) {
- RouteTerminal a = terminals.get(0);
- RouteTerminal b = terminals.get(1);
- if(a.hasDirectConnection() || b.hasDirectConnection()) {
- path.moveTo(a.x, a.y);
- path.lineTo(b.x, b.y);
- return;
- }
+
+ if((isSimpleConnection && transientLines.isEmpty() && terminals.size() == 2) || isDirectDirectConnection()) {
+ RouteTerminal a = terminals.get(0);
+ RouteTerminal b = terminals.get(1);
+ if(a.hasDirectConnection() || b.hasDirectConnection()) {
+ path.moveTo(a.x, a.y);
+ path.lineTo(b.x, b.y);
+ return;
}
}
while(true) {
if(cur != curLine.getEnd())
cur = curLine.getEnd();
- else
- cur = curLine.getBegin();
+ else {
+ RoutePoint next = curLine.getBegin();
+ // Break if stuck at the same RoutePoint.
+ // This can happen with fully direct-routed connections.
+ if (next == cur)
+ return;
+ cur = next;
+ }
if(begins.remove(cur) != null || !(cur instanceof RouteLink)) {
addPathEnd(path, cur, curLine);
return;