]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
Reversing pipe runs was never implemented properly 72/3172/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Thu, 29 Aug 2019 15:53:37 +0000 (18:53 +0300)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Thu, 29 Aug 2019 15:53:37 +0000 (18:53 +0300)
gitlab #12

Change-Id: I0cdc134cdea887717237b6dc428c86e8681ac595

org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java
org.simantics.plant3d/scl/Plant3d/Test/Test1.scl
org.simantics.plant3d/scl/Plant3d/Test/Test1b.scl
org.simantics.plant3d/scl/Plant3d/Test/Test2.scl
org.simantics.plant3d/scl/Plant3d/Test/Test3.scl [new file with mode: 0644]
org.simantics.plant3d/scl/Plant3d/Test/Test3b.scl [new file with mode: 0644]
org.simantics.plant3d/scl/Plant3d/Test/Test3c.scl [new file with mode: 0644]
org.simantics.plant3d/scl/Plant3d/Test/Test3d.scl [new file with mode: 0644]
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java

index 63a1924dcaad8621a9f9968e478fbe05b7909c70..14618318abbaba810f6bc4013043d05dc05ce4a4 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.scenegraph.base;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import org.simantics.utils.datastructures.MapList;\r
-\r
-public abstract class ParentNode<T extends INode> extends Node {\r
-\r
-       private MapList<String, T> children = new MapList<String, T>();\r
-\r
-       public synchronized void addNode(String relName, T child) {\r
-               if (child.getParent() != null)\r
-                       child.getParent().removeNode(child.getParentRel(), child);\r
-\r
-               child.setParent(this, relName);\r
-               children.add(relName, (T) child);\r
-\r
-               childrenChanged();\r
-               fireNodeAdded(child, relName);\r
-       }\r
-\r
-       /**\r
-        * Removes child node and it's hierarchy.\r
-        * @param relName\r
-        * @param child\r
-        * @return\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       public synchronized final boolean removeNode(String relName, INode child) {\r
-               if (children.remove(relName, (T) child)) {\r
-                       fireNodeRemoved(child, relName);\r
-                   child.remove();\r
-                       child.setParent(null, null);\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       /**\r
-        * Removes child node. The child nodes hierarchy is left intact.\r
-        * @param relName\r
-        * @param child\r
-        * @return\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       public synchronized final boolean deattachNode(String relName, INode child) {\r
-               if (children.remove(relName, (T) child)) {\r
-                       fireNodeRemoved(child, relName);\r
-                       child.setParent(null, null);\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       public synchronized final boolean removeNodes(String relName) {\r
-               List<T> nodes = children.getValues(relName);\r
-               for (T child : nodes) {\r
-                       if (children.remove(relName, (T) child)) {\r
-                               fireNodeRemoved(child, relName);\r
-                           child.remove();\r
-                               child.setParent(null, null);\r
-                               \r
-                       }\r
-               }\r
-               return nodes.size() > 0;\r
-       }\r
-\r
-       public synchronized final void removeNodes() {\r
-               synchronized (children) {\r
-                       boolean changed = false;\r
-                       for (String key : children.getKeys()) {\r
-                               for (T child : children.getValues(key)) {\r
-                                       if (child != null) {\r
-                                               changed = true;\r
-                                               if (child instanceof ParentNode<?>) {\r
-                                                       ((ParentNode<?>) child).removeNodes();\r
-                                               }\r
-                                               child.cleanup();\r
-                                               child.setParent(null, null);\r
-                                               // if (propertyChangeListener != null) {\r
-                                               // propertyChangeListener.propertyChange(new\r
-                                               // PropertyChangeEvent(this,\r
-                                               // "children["+child.getId()+"]", child.getClass(),\r
-                                               // NULL)); // "children" is a special field name\r
-                                               // }\r
-                                       }\r
-                               }\r
-                       }\r
-                       children.clear();\r
-                       if (changed)\r
-                               childrenChanged();\r
-               }\r
-       }\r
-\r
-       public synchronized List<T> getNodes(String rel) {\r
-               return children.getValues(rel);\r
-       }\r
-\r
-       public synchronized List<T> getNodes() {\r
-               List<T> result = new ArrayList<T>();\r
-               for (String s : children.getKeys())\r
-                       result.addAll(children.getValues(s));\r
-               return result;\r
-       }\r
-\r
-       protected void childrenChanged() {\r
-       }\r
-\r
-\r
-       @Override\r
-       public void remove() {\r
-               synchronized (children) {\r
-                       List<T> toRemove = new ArrayList<T>();\r
-               \r
-                       for (String key : children.getKeys()) {\r
-               \r
-                               for (T child : children.getValues(key)) {\r
-                                       if (child != null) {\r
-                                               toRemove.add(child);\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       for (T n : toRemove) {\r
-                               n.remove();\r
-                       }\r
-                       \r
-                       children.clear();\r
-                       if (toRemove.size() > 0)\r
-                               childrenChanged();\r
-                       super.remove();\r
-                       \r
-               }\r
-       }\r
-       \r
-       \r
-       \r
-       \r
-       protected void fireNodeAdded(INode node, String rel) {\r
-               for (NodeListener listener : listeners) {\r
-                       listener.nodeAdded(this, node, rel);\r
-               }\r
-       }\r
-       \r
-       protected void fireNodeRemoved(INode node, String rel) {\r
-               for (NodeListener listener : listeners) {\r
-                       listener.nodeRemoved(this, node, rel);\r
-               }\r
-       }\r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 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:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.scenegraph.base;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.simantics.utils.datastructures.MapList;
+
+public abstract class ParentNode<T extends INode> extends Node {
+
+       private MapList<String, T> children = new MapList<String, T>();
+
+       public synchronized void addNode(String relName, T child) {
+               if (child.getParent() != null)
+                       child.getParent().deattachNode(child.getParentRel(), child);
+
+               child.setParent(this, relName);
+               children.add(relName, (T) child);
+
+               childrenChanged();
+               fireNodeAdded(child, relName);
+       }
+
+       /**
+        * Removes child node and it's hierarchy.
+        * @param relName
+        * @param child
+        * @return
+        */
+       @SuppressWarnings("unchecked")
+       public synchronized final boolean removeNode(String relName, INode child) {
+               if (children.remove(relName, (T) child)) {
+                       fireNodeRemoved(child, relName);
+                   child.remove();
+                       child.setParent(null, null);
+                       return true;
+               }
+               return false;
+       }
+       
+       /**
+        * Removes child node. The child nodes hierarchy is left intact.
+        * @param relName
+        * @param child
+        * @return
+        */
+       @SuppressWarnings("unchecked")
+       public synchronized final boolean deattachNode(String relName, INode child) {
+               if (children.remove(relName, (T) child)) {
+                       fireNodeRemoved(child, relName);
+                       child.setParent(null, null);
+                       return true;
+               }
+               return false;
+       }
+       
+       public synchronized final boolean removeNodes(String relName) {
+               List<T> nodes = children.getValues(relName);
+               for (T child : nodes) {
+                       if (children.remove(relName, (T) child)) {
+                               fireNodeRemoved(child, relName);
+                           child.remove();
+                               child.setParent(null, null);
+                               
+                       }
+               }
+               return nodes.size() > 0;
+       }
+
+       public synchronized final void removeNodes() {
+               synchronized (children) {
+                       boolean changed = false;
+                       for (String key : children.getKeys()) {
+                               for (T child : children.getValues(key)) {
+                                       if (child != null) {
+                                               changed = true;
+                                               if (child instanceof ParentNode<?>) {
+                                                       ((ParentNode<?>) child).removeNodes();
+                                               }
+                                               child.cleanup();
+                                               child.setParent(null, null);
+                                               // if (propertyChangeListener != null) {
+                                               // propertyChangeListener.propertyChange(new
+                                               // PropertyChangeEvent(this,
+                                               // "children["+child.getId()+"]", child.getClass(),
+                                               // NULL)); // "children" is a special field name
+                                               // }
+                                       }
+                               }
+                       }
+                       children.clear();
+                       if (changed)
+                               childrenChanged();
+               }
+       }
+
+       public synchronized List<T> getNodes(String rel) {
+               return children.getValues(rel);
+       }
+
+       public synchronized List<T> getNodes() {
+               List<T> result = new ArrayList<T>();
+               for (String s : children.getKeys())
+                       result.addAll(children.getValues(s));
+               return result;
+       }
+
+       protected void childrenChanged() {
+       }
+
+
+       @Override
+       public void remove() {
+               synchronized (children) {
+                       List<T> toRemove = new ArrayList<T>();
+               
+                       for (String key : children.getKeys()) {
+               
+                               for (T child : children.getValues(key)) {
+                                       if (child != null) {
+                                               toRemove.add(child);
+                                       }
+                               }
+                       }
+
+                       for (T n : toRemove) {
+                               n.remove();
+                       }
+                       
+                       children.clear();
+                       if (toRemove.size() > 0)
+                               childrenChanged();
+                       super.remove();
+                       
+               }
+       }
+       
+       
+       
+       
+       protected void fireNodeAdded(INode node, String rel) {
+               for (NodeListener listener : listeners) {
+                       listener.nodeAdded(this, node, rel);
+               }
+       }
+       
+       protected void fireNodeRemoved(INode node, String rel) {
+               for (NodeListener listener : listeners) {
+                       listener.nodeRemoved(this, node, rel);
+               }
+       }
+       
+}
index 879a540acf9ac4d81606362947a549bea5eea02d..71ec5cc09c63c5293d49274cdab60d8d65c81d44 100644 (file)
@@ -18,6 +18,7 @@ import "Plant3d/Utils/P3DUtil" as P3DUtil
 import "Plant3d/Utils/ComponentUtils" as CU
 import "http://www.simantics.org/Layer0-1.1" as L0
 
+"Creates a pump, a pipeline, a tank and the connects the end of the pipe to the tank."
 doTest :: <Proc> ()
 doTest = do
 
@@ -70,7 +71,7 @@ doTest = do
     TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
     P3S.commit p3dmap "Created a elbow"
     P3S.update p3dmap
-    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.85)
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
     P3S.commit p3dmap "Created a pipe"
     P3S.update p3dmap
     elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
index a5f9b81c1dac37ed8479654463279ad42506edd6..38ba18a3e2586cc9bf2c3c377b96b26f38041eca 100644 (file)
@@ -18,7 +18,7 @@ import "Plant3d/Utils/P3DUtil" as P3DUtil
 import "Plant3d/Utils/ComponentUtils" as CU
 import "http://www.simantics.org/Layer0-1.1" as L0
 
-
+"Creates the same pipeline as Test1, but creates connection to the tanks nozzle in opposite direction. This causes the pipeline direction to be reversed."
 doTest :: () 
 doTest = do
 
index 354a49f7b2c2540f6ebbc371d77225756b91d22e..de3c3265261701469cc937ca6992574df0d8ff58 100644 (file)
@@ -18,6 +18,7 @@ import "Plant3d/Utils/P3DUtil" as P3DUtil
 import "Plant3d/Utils/ComponentUtils" as CU
 import "http://www.simantics.org/Layer0-1.1" as L0
 
+"Creates a similar pipeline to Test1 by setting coordinates to Elbows."
 doTest :: <Proc> ()
 doTest = do
 
diff --git a/org.simantics.plant3d/scl/Plant3d/Test/Test3.scl b/org.simantics.plant3d/scl/Plant3d/Test/Test3.scl
new file mode 100644 (file)
index 0000000..8fe6b83
--- /dev/null
@@ -0,0 +1,103 @@
+import "Plant3d/Utils/P3DUtil"
+import "Simantics/DB"
+import "Plant3d/Utils/Loader"
+import "G3D/SCLUtil"
+import "JavaBuiltin"
+import "G3D/Math/Tuple3d" as T3D
+import "G3D/Math/Vector3d" as V3D
+import "G3D/Scenegraph/G3DNode" as G3D
+import "Plant3d/Scenegraph/P3DRootNode" as P3R
+import "Plant3d/Scenegraph/P3DNode" as P3N
+import "Plant3d/Scenegraph/Equipment" as E
+import "Plant3d/Scenegraph/PipelineComponent" as PC
+import "Plant3d/Scenegraph/EndComponent" as EC
+import "Plant3d/Scenegraph/InlineComponent" as IC
+import "Plant3d/Scenegraph/TurnComponent" as TC
+import "Plant3d/Utils/P3DScriptNodeMap" as P3S
+import "Plant3d/Utils/P3DUtil" as P3DUtil
+import "Plant3d/Utils/ComponentUtils" as CU
+import "http://www.simantics.org/Layer0-1.1" as L0
+
+"Creates a similar pipeline to Test1, but changes the tank's nozzles size, which force connection function to create a reducer"
+doTest :: <Proc> ()
+doTest = do
+
+    myModel = syncWrite(\_ -> do
+          myModel = P3DUtil.createModel "Test3"
+          claim (resource "http://Projects/Development%20Project") L0.ConsistsOf myModel
+          myModel)
+    p3dmap = load myModel
+    rootMaybe = javaSafeCoerce (P3S.getRootNode p3dmap) :: Maybe P3R.P3DRootNode
+    root = fromJust rootMaybe
+    pump = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/Pump"
+    P3N.setName pump "My Pump"
+    P3S.commit p3dmap "Created a pump"
+    P3S.update p3dmap
+    n1 = CU.createDefaultNozzle root pump
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce n1) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 90.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    tank = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/HorizontalTank"
+    P3N.setName tank "My Tank"
+    G3D.setPosition tank (V3D.createVector3d 0.0 0.0 3.0)
+    P3S.commit p3dmap "Created a tank"
+    P3S.update p3dmap
+    n2 = CU.createDefaultNozzle root tank
+    G3D.setPosition n2 (V3D.createVector3d 0.6 0.3 0.0)
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    piperun = PC.getPipeRun n2
+    PC.setPipeDiameter piperun 0.2
+    PC.setTurnRadius piperun 0.3
+    P3S.commit p3dmap "Set pipe spec"
+    P3S.update p3dmap
+    
+    CU.connect pipe (unsafeCoerce n2)
+    P3S.commit p3dmap "Connected a pipe to a nozzle"
+    P3S.update p3dmap
+    ()
\ No newline at end of file
diff --git a/org.simantics.plant3d/scl/Plant3d/Test/Test3b.scl b/org.simantics.plant3d/scl/Plant3d/Test/Test3b.scl
new file mode 100644 (file)
index 0000000..2532eb4
--- /dev/null
@@ -0,0 +1,111 @@
+import "Plant3d/Utils/P3DUtil"
+import "Simantics/DB"
+import "Plant3d/Utils/Loader"
+import "G3D/SCLUtil"
+import "JavaBuiltin"
+import "G3D/Math/Tuple3d" as T3D
+import "G3D/Math/Vector3d" as V3D
+import "G3D/Scenegraph/G3DNode" as G3D
+import "Plant3d/Scenegraph/P3DRootNode" as P3R
+import "Plant3d/Scenegraph/P3DNode" as P3N
+import "Plant3d/Scenegraph/Equipment" as E
+import "Plant3d/Scenegraph/PipelineComponent" as PC
+import "Plant3d/Scenegraph/EndComponent" as EC
+import "Plant3d/Scenegraph/InlineComponent" as IC
+import "Plant3d/Scenegraph/TurnComponent" as TC
+import "Plant3d/Utils/P3DScriptNodeMap" as P3S
+import "Plant3d/Utils/P3DUtil" as P3DUtil
+import "Plant3d/Utils/ComponentUtils" as CU
+import "http://www.simantics.org/Layer0-1.1" as L0
+
+doTest :: <Proc> ()
+doTest = do
+
+    myModel = syncWrite(\_ -> do
+          myModel = P3DUtil.createModel "Test3b"
+          claim (resource "http://Projects/Development%20Project") L0.ConsistsOf myModel
+          myModel)
+    p3dmap = load myModel
+    rootMaybe = javaSafeCoerce (P3S.getRootNode p3dmap) :: Maybe P3R.P3DRootNode
+    root = fromJust rootMaybe
+    pump = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/Pump"
+    P3N.setName pump "My Pump"
+    P3S.commit p3dmap "Created a pump"
+    P3S.update p3dmap
+    n1 = CU.createDefaultNozzle root pump
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce n1) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 90.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    reducer = CU.addComponent root (unsafeCoerce pipe) (CU.createSizeChange "http://www.simantics.org/Plant3D-0.1/Builtin/ConcentricReducer" PC.NEXT PC.NEXT 0.2 0.3)
+    P3S.commit p3dmap "Created a reducer"
+    P3S.update p3dmap
+    
+    pipe = CU.addComponent root (unsafeCoerce reducer) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    tank = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/HorizontalTank"
+    P3N.setName tank "My Tank"
+    G3D.setPosition tank (V3D.createVector3d 0.0 0.0 3.0)
+    P3S.commit p3dmap "Created a tank"
+    P3S.update p3dmap
+    n2 = CU.createDefaultNozzle root tank
+    G3D.setPosition n2 (V3D.createVector3d 0.6 0.3 0.0)
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    piperun = PC.getPipeRun n2
+    PC.setPipeDiameter piperun 0.2
+    PC.setTurnRadius piperun 0.3
+    P3S.commit p3dmap "Set pipe spec"
+    P3S.update p3dmap
+    
+    CU.connect pipe (unsafeCoerce n2)
+    P3S.commit p3dmap "Connected a pipe to a nozzle"
+    P3S.update p3dmap
+    ()
\ No newline at end of file
diff --git a/org.simantics.plant3d/scl/Plant3d/Test/Test3c.scl b/org.simantics.plant3d/scl/Plant3d/Test/Test3c.scl
new file mode 100644 (file)
index 0000000..4a7705c
--- /dev/null
@@ -0,0 +1,106 @@
+import "Plant3d/Utils/P3DUtil"
+import "Simantics/DB"
+import "Plant3d/Utils/Loader"
+import "G3D/SCLUtil"
+import "JavaBuiltin"
+import "G3D/Math/Tuple3d" as T3D
+import "G3D/Math/Vector3d" as V3D
+import "G3D/Scenegraph/G3DNode" as G3D
+import "Plant3d/Scenegraph/P3DRootNode" as P3R
+import "Plant3d/Scenegraph/P3DNode" as P3N
+import "Plant3d/Scenegraph/Equipment" as E
+import "Plant3d/Scenegraph/PipelineComponent" as PC
+import "Plant3d/Scenegraph/EndComponent" as EC
+import "Plant3d/Scenegraph/InlineComponent" as IC
+import "Plant3d/Scenegraph/TurnComponent" as TC
+import "Plant3d/Utils/P3DScriptNodeMap" as P3S
+import "Plant3d/Utils/P3DUtil" as P3DUtil
+import "Plant3d/Utils/ComponentUtils" as CU
+import "http://www.simantics.org/Layer0-1.1" as L0
+
+doTest :: <Proc> ()
+doTest = do
+
+    myModel = syncWrite(\_ -> do
+          myModel = P3DUtil.createModel "Test3c"
+          claim (resource "http://Projects/Development%20Project") L0.ConsistsOf myModel
+          myModel)
+    p3dmap = load myModel
+    rootMaybe = javaSafeCoerce (P3S.getRootNode p3dmap) :: Maybe P3R.P3DRootNode
+    root = fromJust rootMaybe
+    pump = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/Pump"
+    P3N.setName pump "My Pump"
+    P3S.commit p3dmap "Created a pump"
+    P3S.update p3dmap
+    n1 = CU.createDefaultNozzle root pump
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce n1) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 90.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    reducer = CU.addComponent root (unsafeCoerce pipe) (CU.createSizeChange "http://www.simantics.org/Plant3D-0.1/Builtin/ConcentricReducer" PC.NEXT PC.NEXT 0.2 0.3)
+    P3S.commit p3dmap "Created a reducer"
+    P3S.update p3dmap
+    
+    pipe = CU.addComponent root (unsafeCoerce reducer) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    tank = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/HorizontalTank"
+    P3N.setName tank "My Tank"
+    G3D.setPosition tank (V3D.createVector3d 0.0 0.0 3.0)
+    P3S.commit p3dmap "Created a tank"
+    P3S.update p3dmap
+    n2 = CU.createDefaultNozzle root tank
+    G3D.setPosition n2 (V3D.createVector3d 0.6 0.3 0.0)
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    
+    CU.connect pipe (unsafeCoerce n2)
+    P3S.commit p3dmap "Connected a pipe to a nozzle"
+    P3S.update p3dmap
+    ()
\ No newline at end of file
diff --git a/org.simantics.plant3d/scl/Plant3d/Test/Test3d.scl b/org.simantics.plant3d/scl/Plant3d/Test/Test3d.scl
new file mode 100644 (file)
index 0000000..3a41525
--- /dev/null
@@ -0,0 +1,106 @@
+import "Plant3d/Utils/P3DUtil"
+import "Simantics/DB"
+import "Plant3d/Utils/Loader"
+import "G3D/SCLUtil"
+import "JavaBuiltin"
+import "G3D/Math/Tuple3d" as T3D
+import "G3D/Math/Vector3d" as V3D
+import "G3D/Scenegraph/G3DNode" as G3D
+import "Plant3d/Scenegraph/P3DRootNode" as P3R
+import "Plant3d/Scenegraph/P3DNode" as P3N
+import "Plant3d/Scenegraph/Equipment" as E
+import "Plant3d/Scenegraph/PipelineComponent" as PC
+import "Plant3d/Scenegraph/EndComponent" as EC
+import "Plant3d/Scenegraph/InlineComponent" as IC
+import "Plant3d/Scenegraph/TurnComponent" as TC
+import "Plant3d/Utils/P3DScriptNodeMap" as P3S
+import "Plant3d/Utils/P3DUtil" as P3DUtil
+import "Plant3d/Utils/ComponentUtils" as CU
+import "http://www.simantics.org/Layer0-1.1" as L0
+
+doTest :: <Proc> ()
+doTest = do
+
+    myModel = syncWrite(\_ -> do
+          myModel = P3DUtil.createModel "Test3d"
+          claim (resource "http://Projects/Development%20Project") L0.ConsistsOf myModel
+          myModel)
+    p3dmap = load myModel
+    rootMaybe = javaSafeCoerce (P3S.getRootNode p3dmap) :: Maybe P3R.P3DRootNode
+    root = fromJust rootMaybe
+    pump = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/Pump"
+    P3N.setName pump "My Pump"
+    P3S.commit p3dmap "Created a pump"
+    P3S.update p3dmap
+    n1 = CU.createDefaultNozzle root pump
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce n1) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 90.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    reducer = CU.addComponent root (unsafeCoerce pipe) (CU.createSizeChange "http://www.simantics.org/Plant3D-0.1/Builtin/ConcentricReducer" PC.NEXT PC.NEXT 0.2 0.3)
+    P3S.commit p3dmap "Created a reducer"
+    P3S.update p3dmap
+    
+    pipe = CU.addComponent root (unsafeCoerce reducer) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 180.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 4.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 2.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    elbow = CU.addComponent root (unsafeCoerce pipe) (CU.createFixedTurn "http://www.simantics.org/Plant3D-0.1/Builtin/Elbow90" PC.NEXT PC.NEXT)
+    TC.setRotationAngle (unsafeCoerce elbow) (Just 270.0)
+    P3S.commit p3dmap "Created a elbow"
+    P3S.update p3dmap
+    pipe = CU.addComponent root (unsafeCoerce elbow) (CU.createVariableLength "http://www.simantics.org/Plant3D-0.1/Builtin/Straight" PC.NEXT PC.NEXT 1.0)
+    P3S.commit p3dmap "Created a pipe"
+    P3S.update p3dmap
+    
+    tank = CU.createEquipmentWithURI root "http://www.simantics.org/Plant3D-0.1/Builtin/HorizontalTank"
+    P3N.setName tank "My Tank"
+    G3D.setPosition tank (V3D.createVector3d 0.0 0.0 3.0)
+    P3S.commit p3dmap "Created a tank"
+    P3S.update p3dmap
+    n2 = CU.createDefaultNozzle root tank
+    G3D.setPosition n2 (V3D.createVector3d 0.6 0.3 0.0)
+    P3S.commit p3dmap "Created a nozzle"
+    P3S.update p3dmap
+    
+    CU.connect (unsafeCoerce n2) pipe 
+    P3S.commit p3dmap "Connected a pipe to a nozzle"
+    P3S.update p3dmap
+    ()
\ No newline at end of file
index 9e163c2e79ba70669ca10e16a75b08c4a7596905..748141a586ed7438a3e4d6a329be3a51756dc420 100644 (file)
@@ -105,26 +105,29 @@ public class PipeRun extends P3DParentNode<IP3DNode> {
                Collections.sort(coll, new ComponentComparator());
                return coll;
        }
+       private static String PIPECP = "pipecp";
+       
        public void addChild(PipeControlPoint node) {
-               addNode("pipecp",node);
+               addNode(PIPECP,node);
        }
        
        public void remChild(PipeControlPoint node) {
-               removeNode("pipecp", node);
+               removeNode(PIPECP, node);
        }
        
        public void deattachChild(PipeControlPoint node) {
-               deattachNode("pipecp", node);
+               deattachNode(PIPECP, node);
        }
        
        public Collection<PipeControlPoint> getControlPoints() {
                Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
-               for (IG3DNode n : getNodes("pipecp")) {
+               for (IG3DNode n : getNodes(PIPECP)) {
                        coll.add((PipeControlPoint)n);
                }
                return coll;
        }
        
+       
        public boolean equalSpecs(PipeRun other) {
                if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
                        return false;
@@ -158,4 +161,5 @@ public class PipeRun extends P3DParentNode<IP3DNode> {
                        
                }
        }
+       
 }
index 2fef57fbeb6af4f92db459c8c87062349e053323..7b0d3bf7bd31682d2d25dcc1be431cc8c03f75aa 100644 (file)
@@ -1602,6 +1602,7 @@ public class PipingRules {
                 dir = prev;
             } else {
                 dir = next;
+                dir.negate();
             }
             if (dir == null) {
                 return Math.PI; // FIXME : argh
@@ -1612,7 +1613,9 @@ public class PipingRules {
             MathTools.rotate(q, MathTools.Y_AXIS,v);
             tcp.setTurnAxis(v);
             tcp.setWorldOrientation(q);
-            return tcp.getTurnAngle();
+            if (tcp.getTurnAngle() != null)
+                return tcp.getTurnAngle();
+            return Math.PI; // FIXME : argh
            }
                
                
@@ -1643,60 +1646,120 @@ public class PipingRules {
        }
        
        public static void reverse(PipeRun pipeRun) {
-               List<PipeControlPoint> list = getControlPoints(pipeRun);
-               if (list.size() <= 1)
-                       return; // nothing to do.
                
-               for (int i = 0 ; i < list.size(); i++) {
-                       boolean first = i == 0;
-                       boolean last = i == list.size() - 1;
-                       PipeControlPoint current = list.get(i);
-                       PipeControlPoint currentSub = null;
-                       if (current.isDualInline())
-                               currentSub = current.getSubPoint().get(0);
-                       if (first) {
-                               PipeControlPoint next = list.get(i+1);
-                               if (next.isDualInline())
-                                       next = next.getSubPoint().get(0);
-                               current.setNext(null);
-                               current.setPrevious(next);
-                               if (currentSub != null) {
-                                       currentSub.setNext(null);
-                                       currentSub.setPrevious(next);           
-                               }
-                       } else if (last) {
-                               PipeControlPoint prev = list.get(i-1);
-                               
-                               current.setPrevious(null);
-                               current.setNext(prev);
-                               
-                               if (currentSub != null) {
-                                       currentSub.setPrevious(null);
-                                       currentSub.setNext(prev);               
-                               }
-                       } else {
-                               PipeControlPoint prev = list.get(i-1);
-                               PipeControlPoint next = list.get(i+1);
-                               if (next.isDualInline())
-                                       next = next.getSubPoint().get(0);
-                               
-                               
-                               current.setPrevious(next);
-                               current.setNext(prev);
-                               
-                               if (currentSub != null) {
-                                       currentSub.setPrevious(next);
-                                       currentSub.setNext(prev);               
-                               }
-                               
-                       }
-                       if (current.isTurn() && current.isFixed()) {
-                           current.setReversed(!current._getReversed());
-                       }
-                       if (current.isInline() && current.isReverse()) {
-                           current.setReversed(!current._getReversed());
-                       }   
+               while (true) {
+                   List<PipeControlPoint> points = getControlPoints(pipeRun);
+                   PipeControlPoint pcp = points.get(0);
+                   if (pcp.isSizeChange() && pcp.getSubPoint().size() > 0) {
+                       pipeRun = pcp.getPipeRun();
+                   } else {
+                       break;
+                   }
+               }
+               List<PipeRun> all = new ArrayList<PipeRun>();
+               List<List<PipeControlPoint>> pcps = new ArrayList<List<PipeControlPoint>>();
+               while (true) {
+                   all.add(pipeRun);
+                   List<PipeControlPoint> points = getControlPoints(pipeRun);
+                   pcps.add(points);
+                   PipeControlPoint pcp = points.get(points.size()-1);
+                   if (pcp.getSubPoint().size() > 0) {
+                       pipeRun = pcp.getSubPoint().get(0).getPipeRun();
+                   } else {
+                       break;
+                   }
+               }
+               for (int i = 0 ; i < all.size(); i++) {
+                   List<PipeControlPoint> list = pcps.get(i);
+                   _reverse(list);
+               }
+               for (int i = 0 ; i < all.size(); i++) {
+                   boolean last = i == all.size() - 1;
+            List<PipeControlPoint> list = pcps.get(i);
+            
+            if (!last) {
+                List<PipeControlPoint> list2 = pcps.get(i+1);
+                PipeControlPoint prev = list.get(list.size()-1);
+                PipeControlPoint next = list2.get(0);
+                System.out.println();
+                if (prev == next) {
+                    // Reverse the component on the boundary.
+                    InlineComponent ic = (InlineComponent)prev.getPipelineComponent();
+                    PipeRun r1 = ic.getPipeRun();
+                    PipeRun r2 = ic.getAlternativePipeRun();
+                    if (r1 == null || r2 == null)
+                        throw new RuntimeException("Components on PipeRun changes should refer to bot PipeRuns");
+                    ic.deattach();
+                    r2.addChild(ic);
+                    ic.setPipeRun(r2);
+                    ic.setAlternativePipeRun(r1);
+                } else {
+                    throw new RuntimeException("PipeRun changes should contain shared control points");
+                }
+                
+            }
                }
+                   
+       }
+       
+       private static void _reverse(List<PipeControlPoint> list) {
+           if (list.size() <= 1)
+            return; // nothing to do.
+        
+        for (int i = 0 ; i < list.size(); i++) {
+            boolean first = i == 0;
+            boolean last = i == list.size() - 1;
+            PipeControlPoint current = list.get(i);
+            PipeControlPoint currentSub = null;
+            if (current.isDualInline())
+                currentSub = current.getSubPoint().get(0);
+            if (first) {
+                PipeControlPoint next = list.get(i+1);
+                if (next.isDualInline())
+                    next = next.getSubPoint().get(0);
+                if (current.getNext() == next)
+                    current.setNext(null);
+                current.setPrevious(next);
+                if (currentSub != null) {
+                    if (currentSub.getNext() == next)
+                        currentSub.setNext(null);
+                    currentSub.setPrevious(next);       
+                }
+            } else if (last) {
+                PipeControlPoint prev = list.get(i-1);
+                
+                if (current.getPrevious() == prev)
+                    current.setPrevious(null);
+                current.setNext(prev);
+                
+                if (currentSub != null) {
+                    if (currentSub.getPrevious() == prev)
+                        currentSub.setPrevious(null);
+                    currentSub.setNext(prev);       
+                }
+            } else {
+                PipeControlPoint prev = list.get(i-1);
+                PipeControlPoint next = list.get(i+1);
+                if (next.isDualInline())
+                    next = next.getSubPoint().get(0);
+                
+                
+                current.setPrevious(next);
+                current.setNext(prev);
+                
+                if (currentSub != null) {
+                    currentSub.setPrevious(next);
+                    currentSub.setNext(prev);       
+                }
+                
+            }
+            if (current.isTurn() && current.isFixed()) {
+                current.setReversed(!current._getReversed());
+            }
+            if (current.isInline() && current.isReverse()) {
+                current.setReversed(!current._getReversed());
+            }   
+        }
        }
        
        public static void merge(PipeRun run1, PipeRun r2) {