From ce1395110dd0db27c7c99c426181b49d22211264 Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Fri, 29 Nov 2019 12:44:52 +0200 Subject: [PATCH] Handle PipeRun removals with detaching Components. Some operations can move Components between PipeRuns. If we create a PipeRun within such operation, and the undo the modification, removal of the created PipeRun may remove Components before they are attached to their original PipeRuns. 1. Now PipeRun removal detaches Components, so that Component structure remains intact. 2. PipeCOntrolPoint removal work without PipeRun. 3. AbstractVTKNodeMap calls INode.remove() all removed nodes. gitlab #35 Change-Id: I37ec56302581ab176fe630c91b3cddb301ad1210 (cherry picked from commit f346390a5a8cd4262a9aa68951e55d504d412549) --- .../g3d/vtk/common/AbstractVTKNodeMap.java | 49 ++++++++----------- .../simantics/plant3d/scenegraph/PipeRun.java | 16 +++++- .../plant3d/scenegraph/PipelineComponent.java | 2 + .../controlpoint/PipeControlPoint.java | 33 ++++++++----- 4 files changed, 60 insertions(+), 40 deletions(-) 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 a03e89cb..f4458fc3 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 @@ -121,8 +121,16 @@ public abstract class AbstractVTKNodeMap implements VT protected void removeMap(E node) { Collection coll = nodeToActor.getValuesUnsafe(node); - for (vtkProp p : coll) { - actorToNode.remove(p); + if (coll.size() > 0) { + view.lock(); + for (vtkProp p : coll) { + actorToNode.remove(p); + if (p.GetVTKId() != 0) { + view.getRenderer().RemoveActor(p); + p.Delete(); + } + } + view.unlock(); } nodeToActor.remove(node); } @@ -352,7 +360,7 @@ public abstract class AbstractVTKNodeMap implements VT if (runUndo && useFullSyncWithUndo) { reset(graph); } else { - synchronized (syncMutex) { + synchronized (syncMutex) { graphUpdates = true; for (DBObject domainObject : mapping.getDomainModified()) { @SuppressWarnings("unchecked") @@ -365,7 +373,7 @@ public abstract class AbstractVTKNodeMap implements VT syncDeletes(); clearDeletes(); graphUpdates = false; - } + } } if (mapping.isRangeModified() && !runUndo && !runRedo) @@ -477,10 +485,10 @@ public abstract class AbstractVTKNodeMap implements VT E n = stack.pop(); boolean conflict = filterChange(removed, n); if (conflict) { - System.out.println("Prevent removing " + n); + if (DEBUG) System.out.println("Prevent removing " + n); //filterChange(added, n) if (filterChange(added, n)) - System.out.println("Prevent adding " + n); + if (DEBUG) System.out.println("Prevent adding " + n); } if (n instanceof ParentNode) { ParentNode pn = (ParentNode)n; @@ -504,16 +512,16 @@ public abstract class AbstractVTKNodeMap implements VT } - for (Pair n : rem) { stopListening(n.first); removeActor(n.first); + n.first.remove(); } - for (Pair n : add) { - addActor(n.first); - listen(n.first); - } + for (Pair n : add) { + addActor(n.first); + listen(n.first); + } for (E e : mod.getKeys()) { Set ids = mod.getValues(e); @@ -547,26 +555,11 @@ public abstract class AbstractVTKNodeMap implements VT } } -// synchronized (syncMutex) { -// rem.addAll(removed); -// add.addAll(added); -// //mod.addAll(updated); -// for (E e : updated.getKeys()) { -// for (String s : updated.getValues(e)) -// mod.add(e, s); -// } -// -// removed.clear(); -// added.clear(); -// updated.clear(); -// } - for (E e : mod.getKeys()) { Set ids = mod.getValues(e); updateActor(e,ids); } - - + for (Pair n : rem) { for (NodeListener l : nodeListeners) l.nodeRemoved(null, n.first, n.second); @@ -638,7 +631,7 @@ public abstract class AbstractVTKNodeMap implements VT //FIXME : 1. sometimes removed structural models cause ObjMap to add their children again. // removing the listener here prevents corruption of visual model, but better fix is needed. - // 2. detach causes nodeRemoved event, which then causes other critical events to be missed. Took out th + // 2. detach causes nodeRemoved event, which then causes other critical events to be missed. Took out call: //stopListening(child); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java index 2c334c1f..1d199f53 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java @@ -112,8 +112,22 @@ public class PipeRun extends P3DParentNode { } @RelatedElementsRem(Plant3D.URIs.children) + public void _remChild(PipelineComponent node) { + //since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals. + deattachNode(Plant3D.URIs.children, node); + } + public void remChild(PipelineComponent node) { - removeNode(Plant3D.URIs.children, node); + removeNode(Plant3D.URIs.children, node); + } + + @Override + public void remove() { + // since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals. + Collection comps = getChild(); + for (PipelineComponent c : comps) + c.deattach(); + super.remove(); } 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 61e48585..ad1c2b7a 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java @@ -455,6 +455,7 @@ public abstract class PipelineComponent extends GeometryNode { if (pcp != null && pcp.getPipelineComponent() != null) { pcp.remove(); } + setPipeRun(null); super.remove(); } @@ -464,6 +465,7 @@ public abstract class PipelineComponent extends GeometryNode { if (pcp != null && pcp.getPipelineComponent() != null) { pcp.removeAndSplit(); } + setPipeRun(null); super.remove(); } 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 aa5eacf9..8b1455ca 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 @@ -43,6 +43,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private boolean isSizeChange = false; // changes size of the pipe. The next control point / component is on different PipeRun private boolean isSub = false; // child point for offset / size change + private boolean disposed = false; + public PipeControlPoint(PipelineComponent component) { this.component = component; if (component.getPipeRun() != null) @@ -1065,17 +1067,19 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void _remove(boolean renconnect) { - if (component == null && next == null && previous == null) - return; - if (DEBUG) System.out.println(this + " Remove " + renconnect); + if (disposed) + return; + + if (DEBUG) System.out.println(this + " Remove " + renconnect); if (getParentPoint() != null) { getParentPoint()._remove(renconnect); return; } PipeRun pipeRun = getPipeRun(); - if (pipeRun == null) - return; +// PipeRUn removal has been changed, so pipeRun may be null. +// if (pipeRun == null) +// return; PipeControlPoint additionalRemove = null; if (!PipingRules.isEnabled()) { @@ -1088,8 +1092,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint currentNext = next; if (currentNext == null && currentPrev == null) { removeComponent(); - pipeRun.remChild(this); - checkRemove(pipeRun); + if (pipeRun != null) { + pipeRun.remChild(this); + checkRemove(pipeRun); + } return; } if (currentNext != null && currentPrev != null) { @@ -1255,12 +1261,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } removeComponent(); - pipeRun.remChild(this); - checkRemove(pipeRun); - if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0) - PipingRules.validate(pipeRun); + if (pipeRun != null) { + pipeRun.remChild(this); + checkRemove(pipeRun); + if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0) + PipingRules.validate(pipeRun); + } if (additionalRemove != null) additionalRemove.remove(); + disposed = true; } /** @@ -1353,6 +1362,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } private boolean checkRemove(PipeRun pipeRun) { + if (pipeRun == null) + return false; Collection points = pipeRun.getControlPoints(); if (points.size() == 0) { pipeRun.remove(); -- 2.45.2