From 46c28cc32944d0f73c5ab4062bd6b0b232143be7 Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Thu, 17 Oct 2019 14:25:45 +0300 Subject: [PATCH] Remove/Split action removes pipeline components without reconnecting gitlab #33 Change-Id: I9bd2df03b9d4f4b8abea03c15e22dcce39fb70bb --- .../g3d/vtk/common/AbstractVTKNodeMap.java | 25 +++++++++++ .../org/simantics/g3d/scl/ScriptNodeMap.java | 23 ++++++++++ .../plant3d/actions/RemoveAndSplitAction.java | 34 ++++++++++++++ .../plant3d/editor/Plant3DEditor.java | 21 ++++++--- .../plant3d/scenegraph/PipelineComponent.java | 9 ++++ .../controlpoint/PipeControlPoint.java | 45 ++++++++++++++++++- 6 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 org.simantics.plant3d/src/org/simantics/plant3d/actions/RemoveAndSplitAction.java diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java index 674a71f2..d9b754b4 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java @@ -11,9 +11,11 @@ *******************************************************************************/ package org.simantics.g3d.vtk.common; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -435,6 +437,27 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< synchronized (syncMutex) { + // Check for overlapping additions and deletions, prevent deleting objects that are also added. + Deque stack = new ArrayDeque(); + for (Pair n : added) { + stack.add(n.first); + } + while (!stack.isEmpty()) { + E n = stack.pop(); + for (int i = removed.size()-1; i >= 0; i--) { + if (removed.get(i).first == n) { + removed.remove(i); + break; + } + } + if (n instanceof ParentNode) { + ParentNode pn = (ParentNode)n; + for (INode cn : pn.getNodes()) { + stack.push((E)cn); + } + } + } + rem.addAll(removed); add.addAll(added); for (E e : updated.getKeys()) { @@ -448,6 +471,8 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< updated.clear(); } + + for (Pair n : rem) { stopListening(n.first); removeActor(n.first); diff --git a/org.simantics.g3d/src/org/simantics/g3d/scl/ScriptNodeMap.java b/org.simantics.g3d/src/org/simantics/g3d/scl/ScriptNodeMap.java index 37b124e3..cd2447b3 100644 --- a/org.simantics.g3d/src/org/simantics/g3d/scl/ScriptNodeMap.java +++ b/org.simantics.g3d/src/org/simantics/g3d/scl/ScriptNodeMap.java @@ -1,8 +1,10 @@ package org.simantics.g3d.scl; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -360,6 +362,27 @@ public abstract class ScriptNodeMap implements NodeMap stack = new ArrayDeque(); + for (Pair n : added) { + stack.add(n.first); + } + while (!stack.isEmpty()) { + E n = stack.pop(); + for (int i = removed.size()-1; i >= 0; i--) { + if (removed.get(i).first == n) { + removed.remove(i); + break; + } + } + if (n instanceof ParentNode) { + ParentNode pn = (ParentNode)n; + for (INode cn : pn.getNodes()) { + stack.push((E)cn); + } + } + } + rem.addAll(removed); add.addAll(added); for (E e : updated.getKeys()) { diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RemoveAndSplitAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RemoveAndSplitAction.java new file mode 100644 index 00000000..d20a59c0 --- /dev/null +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RemoveAndSplitAction.java @@ -0,0 +1,34 @@ +package org.simantics.plant3d.actions; + +import org.simantics.g3d.scenegraph.IG3DNode; +import org.simantics.g3d.vtk.action.RemoveAction; +import org.simantics.g3d.vtk.common.VTKNodeMap; +import org.simantics.plant3d.scenegraph.PipelineComponent; + +public class RemoveAndSplitAction extends RemoveAction { + + public RemoveAndSplitAction(VTKNodeMap nodeMap) { + super(nodeMap); + setText("Remove/Split"); + } + + @Override + public boolean isRemovable(IG3DNode node) { + if (!super.isRemovable(node)) + return false; + if (!(node instanceof PipelineComponent)) + return false; + PipelineComponent pc = (PipelineComponent)node; + if (pc.getNext() != null && pc.getPrevious() != null) + return true; + else return false; + } + + + @Override + protected void doRemove(IG3DNode node) { + PipelineComponent pc = (PipelineComponent)node; + pc.removeAndSplit(); + } + +} diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java b/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java index ba56f2f9..8387650b 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java @@ -42,6 +42,7 @@ import org.simantics.objmap.graph.schema.IMappingSchema; import org.simantics.plant3d.actions.AddComponentAction; import org.simantics.plant3d.actions.AddEquipmentAction; import org.simantics.plant3d.actions.AddNozzleAction; +import org.simantics.plant3d.actions.RemoveAndSplitAction; import org.simantics.plant3d.actions.RoutePipeAction; import org.simantics.plant3d.actions.TranslateInlineAction; import org.simantics.plant3d.scenegraph.EndComponent; @@ -50,12 +51,10 @@ import org.simantics.plant3d.scenegraph.IP3DNode; import org.simantics.plant3d.scenegraph.InlineComponent; import org.simantics.plant3d.scenegraph.Nozzle; import org.simantics.plant3d.scenegraph.P3DRootNode; -import org.simantics.plant3d.scenegraph.PipeRun; import org.simantics.plant3d.scenegraph.PipelineComponent; import org.simantics.plant3d.scenegraph.SchemaBuilder; import org.simantics.plant3d.scenegraph.TurnComponent; import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory; -import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint; import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; import org.simantics.plant3d.utils.ComponentUtils; import org.simantics.plant3d.utils.Item; @@ -94,6 +93,7 @@ public class Plant3DEditor extends ResourceEditorPart { private TranslateInlineAction translateInlineAction; private RotateAction rotateAction; private RemoveAction removeAction; + private RemoveAndSplitAction removeSplitAction; private RoutePipeAction routePipeAction; private AddComponentAction addComponentAction; @@ -215,10 +215,10 @@ public class Plant3DEditor extends ResourceEditorPart { removeAction = new RemoveAction(nodeMap) { public void setNode(IG3DNode node) { super.setNode(node); - - } }; + + removeSplitAction = new RemoveAndSplitAction(nodeMap); routePipeAction = new RoutePipeAction(panel,rootNode); addComponentAction = new AddComponentAction(panel, rootNode); } @@ -325,6 +325,7 @@ public class Plant3DEditor extends ResourceEditorPart { add.setEquipment((Equipment)node); m.add(add); } + m.add(removeAction); } else if (node instanceof Nozzle) { Nozzle nozzle = (Nozzle)node; if (!nozzle.isFixed()) { @@ -336,6 +337,7 @@ public class Plant3DEditor extends ResourceEditorPart { routePipeAction.setEnabled(nozzle.getNext() == null && nozzle.getPrevious() == null); m.add(addComponentAction); addComponentAction.setComponent(nozzle); + m.add(removeAction); } else if (node instanceof TurnComponent) { m.add(translateAction); TurnComponent component = (TurnComponent)node; @@ -344,10 +346,14 @@ public class Plant3DEditor extends ResourceEditorPart { routePipeAction.setEnabled(component.getNext() == null || component.getPrevious() == null); m.add(addComponentAction); addComponentAction.setComponent(component); + m.add(removeAction); + m.add(removeSplitAction); + removeSplitAction.setNode(node); } else if (node instanceof EndComponent) { m.add(translateAction); m.add(addComponentAction); addComponentAction.setComponent((PipelineComponent)node); + m.add(removeAction); } else if (node instanceof InlineComponent) { //m.add(translateInlineAction); InlineComponent component = (InlineComponent)node; @@ -356,9 +362,14 @@ public class Plant3DEditor extends ResourceEditorPart { routePipeAction.setComponent(component); m.add(addComponentAction); addComponentAction.setComponent(component); + m.add(removeAction); + m.add(removeSplitAction); + removeSplitAction.setNode(node); + } else { + m.add(removeAction); } - m.add(removeAction); + translateAction.setNode(node); translateInlineAction.setNode(node); rotateAction.setNode(node); diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java index d66869ea..3f393364 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java @@ -388,6 +388,15 @@ public abstract class PipelineComponent extends GeometryNode { } super.remove(); } + + public void removeAndSplit() { + PipeControlPoint pcp = getControlPoint(); + // Second check is needed, when remove process is initiated from control point. + if (pcp != null && pcp.getPipelineComponent() != null) { + pcp.removeAndSplit(); + } + super.remove(); + } @Override protected double[] getColor() { diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java index 93186779..daab2d11 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java @@ -16,6 +16,8 @@ import org.simantics.g3d.math.MathTools; import org.simantics.g3d.property.annotations.GetPropertyValue; import org.simantics.g3d.scenegraph.G3DNode; import org.simantics.plant3d.scenegraph.IP3DNode; +import org.simantics.plant3d.scenegraph.Nozzle; +import org.simantics.plant3d.scenegraph.P3DRootNode; import org.simantics.plant3d.scenegraph.PipeRun; import org.simantics.plant3d.scenegraph.PipelineComponent; @@ -938,8 +940,12 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } } } - + public void _remove() { + _remove(true); + } + + public void _remove(boolean renconnect) { if (component == null && next == null && previous == null) return; if (isDualInline() || isDualSub()) { @@ -964,7 +970,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return; } if (currentNext != null && currentPrev != null) { - boolean link = true; + boolean link = renconnect; if (currentNext.isBranchEnd()) { link = false; // currentNext.setPrevious(null); @@ -1125,6 +1131,41 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { e.printStackTrace(); } } + + public void removeAndSplit() { + PipeControlPoint currentPrev = previous; + PipeControlPoint currentNext = next; + + if (next != null && previous != null) { + P3DRootNode root = (P3DRootNode)getPipelineComponent().getRootNode(); + PipeRun nextPipeRun = new PipeRun(); + nextPipeRun.setName(root.getUniqueName("PipeRun")); + root.addChild(nextPipeRun); + + PipeRun previousRun = previous.getPipeRun(); + nextPipeRun.setPipeDiameter(previousRun.getPipeDiameter()); + nextPipeRun.setTurnRadius(previousRun.getTurnRadius()); + + PipelineComponent n = next.getPipelineComponent(); + while (n != null) { + if (! (n instanceof Nozzle)) { + n.deattach(); + nextPipeRun.addChild(n); + } else + n.setPipeRun(nextPipeRun); + n = n.getNext(); + } + } + _remove(false); + try { + if (currentNext != null) + PipingRules.requestUpdate(currentNext); + if (currentPrev != null) + PipingRules.requestUpdate(currentPrev); + } catch (Exception e) { + e.printStackTrace(); + } + } private void checkRemove(PipeRun pipeRun) { Collection points = pipeRun.getControlPoints(); -- 2.45.2