From: Reino Ruusu Date: Wed, 13 Mar 2019 10:38:14 +0000 (+0200) Subject: Select midpoint of network branches for flow velocity arrows. X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=799658ba71ffc6bf8aececcebc6d9a5baf476251;p=simantics%2Fdistrict.git Select midpoint of network branches for flow velocity arrows. gitlab #39 Change-Id: Icdfdf511d85de428f22623f0e697b51265c9e7e4 --- diff --git a/org.simantics.district.network/scl/Simantics/District/Algorithm.scl b/org.simantics.district.network/scl/Simantics/District/Algorithm.scl index f8852bdb..259ad087 100644 --- a/org.simantics.district.network/scl/Simantics/District/Algorithm.scl +++ b/org.simantics.district.network/scl/Simantics/District/Algorithm.scl @@ -1,7 +1,10 @@ import "Simantics/Model" import "http://www.simantics.org/DistrictNetwork-1.0" as DN +import "Map" as Map +import "MMap" as MMap import "Comparator" + @private importJava "org.simantics.utils.strings.AlphanumComparator" where @JavaName CASE_INSENSITIVE_COMPARATOR @@ -114,3 +117,68 @@ reportDisconnectedSubnetworks vertexThreshold (diagram, subgraphs) = do forI (sortStrings (map showVertex vs)) (\i s -> print "* v\(i): \(s)") print "" forI (sortStrings (map showEdge es)) (\i s -> print "* e\(i): \(s)") + +""" +Get a set of the edges that are at the middle points of each span between branch points. +""" +midBranchEdges :: Resource -> [Resource] +midBranchEdges networkDiagram = runProc let + for edges storeDistance + in + filter isMiddle edges + where + all = if isInstanceOf networkDiagram DIA.Diagram + then networkDiagram # L0.ConsistsOf + else singleObject networkDiagram MOD.CompositeToDiagram # L0.ConsistsOf + vertices = filter (flip isInstanceOf DN.Vertex) all + edges = filter (flip isInstanceOf DN.Edge) all + edgeLen = fromJust . (index $ flip map edges \e -> do + v1 = singleObject e DN.HasStartVertex + v2 = singleObject e DN.HasEndVertex + [x1, y1] = relatedValue v1 DIA.HasLocation :: [Double] + [x2, y2] = relatedValue v2 DIA.HasLocation :: [Double] + (e, sqrt ((x2 - x1)^2 + (y2 - y1)^2))) + distances = runProc $ MMap.create () :: MMap.T Resource Double + isBranchPoint v = length (v # DN.HasEndVertex_Inverse) != 1 || length (v # DN.HasStartVertex_Inverse) != 1 + setDistance e d = MMap.put distances e d + getDistance e = fromJust $ MMap.get distances e + forward r1 r2 e cont = do + v = singleObject e r1 + l = edgeLen e + if isBranchPoint v + then do + setDistance e (l / 2) + cont l + else do + e2 = singleObject v r2 + forward r1 r2 e2 (\d2 -> do + setDistance e (d2 + l/2) + cont (d2 + l)) + backward r1 r2 e d = do + l = edgeLen e + setDistance e $ min (d + l/2) (getDistance e) + v = singleObject e r1 + if isBranchPoint v then () else backward r1 r2 (singleObject v r2) (d + l) + storeDistance e = if MMap.containsKey distances e + then () + else do + l = edgeLen e + forwardTo e (const ()) + d1 = getDistance e + forwardFrom e (const ()) + d2 = getDistance e + setDistance e (min d1 d2) + backwardFrom e (d1 - l/2) + backwardTo e (d2 - l/2) + where + forwardTo = forward DN.HasEndVertex DN.HasStartVertex_Inverse + forwardFrom = forward DN.HasStartVertex DN.HasEndVertex_Inverse + backwardTo = backward DN.HasEndVertex DN.HasStartVertex_Inverse + backwardFrom = backward DN.HasStartVertex DN.HasEndVertex_Inverse + isMiddle e = let + v1 = singleObject e DN.HasStartVertex + v2 = singleObject e DN.HasEndVertex + d = getDistance e + in + (isBranchPoint v1 || d > getDistance (singleObject v1 DN.HasEndVertex_Inverse)) && + (isBranchPoint v2 || d > getDistance (singleObject v2 DN.HasStartVertex_Inverse)) diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java index 3b0524d4..2e8c3458 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java @@ -1,10 +1,16 @@ package org.simantics.district.network.profile; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; -import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.nodes.ConnectionNode; @@ -18,7 +24,12 @@ public class ArrowLengthStyle extends ThrottledStyleBase { @Override public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { - DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); + Resource diagram = graph.getSingleObject(groupItem, Layer0.getInstance(graph).PartOf); + Set edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance()); + if (!edgesToUse.contains(groupItem)) + return null; + + DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheListener.instance()); // Prevent PendingVariableExceptions from coming through boolean wasSynchronous = graph.setSynchronous(true); try { @@ -61,4 +72,16 @@ public class ArrowLengthStyle extends ThrottledStyleBase { ProfileVariables.claimNodeProperty(nn, "arrowLength", null, evaluationContext); } + private static final class MidBranchEdgeSetRequest extends ResourceRead> { + private MidBranchEdgeSetRequest(Resource resource) { + super(resource); + } + + @Override + public Set perform(ReadGraph graph) throws DatabaseException { + List edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource); + return new HashSet<>(edges); + } + } + }