]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
Showing error messages when components overlap each other 59/3659/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 2 Dec 2019 12:53:07 +0000 (14:53 +0200)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 2 Dec 2019 13:04:52 +0000 (13:04 +0000)
* Removed code that forced PipingRules to iterate whole connected
segment.
* Adjusted PipingRule excecution on editor load.
* Fixed inline coomponent updated, when the component was also path leg
end.
* Fixed variable length adjusting / removal code.

gitlab #59

Change-Id: I4e1152f2a37b9a7cc7f93f18a9cf54616c62bbfd
(cherry picked from commit 3c9eba53de061b8c5c5863dc05855dc0e71781b1)

org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java
org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DContentOutlinePage.java
org.simantics.plant3d/src/org/simantics/plant3d/geometry/StraightGeometryProvider.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java
org.simantics.plant3d/src/org/simantics/plant3d/utils/P3DUtil.java

index 9001d0a7124011fb20567fdd18249a443548f6d2..3aac1fd99b005f50473c46c7ee0d025360900023 100644 (file)
@@ -127,7 +127,7 @@ public class TranslateInlineAction extends TranslateAction{
                        //boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
                        Vector3d pos = new Vector3d(node.getWorldPosition());
                        
-                       System.out.println(pos + " " + translate);
+//                     System.out.println(pos + " " + translate);
                        //pos.add(translate);
                        pos.set(translate);
                        //pos = constaints(pos, step);
index 893a07300cd2c95db095123c3794e7dbfdf53a54..ed9c4a5baf8eed40b62c3e23c1e98c403b96c7dd 100644 (file)
@@ -6,8 +6,11 @@ import java.util.List;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.viewers.DecorationOverlayIcon;
+import org.eclipse.jface.viewers.IDecoration;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.events.MenuDetectEvent;
 import org.eclipse.swt.events.MenuDetectListener;
@@ -42,14 +45,33 @@ public class P3DContentOutlinePage extends VTKContentOutlinePage<Resource, INode
        private Image elbowImage;
        private Image componentImage;
        
+       
+       private Image nozzleErrorImage;
+    private Image pipeErrorImage;
+    private Image tankErrorImage;
+    private Image elbowErrorImage;
+    private Image componentErrorImage;
+    
        public  P3DContentOutlinePage(ParentNode<? extends INode> rootNode, NodeSelectionProvider2<Resource,INode> provider) {
                super(rootNode,provider);
                
-               nozzleImage = manager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Nozzle.png"));
-               pipeImage = manager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png"));
-               tankImage = manager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/tank.png"));
-               elbowImage = manager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Elbow.png"));
-               componentImage = manager.createImage(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Component.png"));
+               ImageDescriptor nozzleDesc = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Nozzle.png");
+               ImageDescriptor straightDesc = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png");
+               ImageDescriptor tankDesc = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/tank.png");
+               ImageDescriptor elbowDesc = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Elbow.png");
+               ImageDescriptor componentDesc = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Component.png");
+               nozzleImage = manager.createImage(nozzleDesc);
+               pipeImage = manager.createImage(straightDesc);
+               tankImage = manager.createImage(tankDesc);
+               elbowImage = manager.createImage(elbowDesc);
+               componentImage = manager.createImage(componentDesc);
+               
+               ImageDescriptor error = Activator.imageDescriptorFromPlugin("org.simantics.issues.ui", "icons/warning_decoration.png");
+               nozzleErrorImage = manager.createImage(new DecorationOverlayIcon(nozzleDesc, error, IDecoration.BOTTOM_RIGHT));
+               pipeErrorImage = manager.createImage(new DecorationOverlayIcon(straightDesc, error, IDecoration.BOTTOM_RIGHT));
+               tankErrorImage = manager.createImage(new DecorationOverlayIcon(tankDesc, error, IDecoration.BOTTOM_RIGHT));
+               elbowErrorImage = manager.createImage(new DecorationOverlayIcon(elbowDesc, error, IDecoration.BOTTOM_RIGHT));
+               componentErrorImage = manager.createImage(new DecorationOverlayIcon(componentDesc, error, IDecoration.BOTTOM_RIGHT));
        }
        
        @Override
@@ -157,15 +179,30 @@ public class P3DContentOutlinePage extends VTKContentOutlinePage<Resource, INode
                        if (element instanceof PipelineComponent) {
                                PipelineComponent comp = (PipelineComponent)element;
                                if (comp instanceof TurnComponent) {
-                                       return elbowImage;
+                                   if (comp.getError() == null)
+                                       return elbowImage;
+                                   else
+                                       return elbowErrorImage;
                                } else if (comp instanceof EndComponent) {
-                                       return componentImage;
+                                   if (comp.getError() == null)
+                                       return componentImage;
+                                   else
+                                       return componentErrorImage;
                                } else if (comp instanceof Nozzle) {
-                                       return nozzleImage;
+                                   if (comp.getError() == null)
+                                       return nozzleImage;
+                                   else
+                                       return nozzleErrorImage;
                                } else if (comp.getControlPoint().isFixed()) {
-                                       return componentImage;
+                                   if (comp.getError() == null)
+                                       return componentImage;
+                                   else
+                                       return componentErrorImage;
                                }
-                               return pipeImage;
+                               if (comp.getError() == null)
+                                   return pipeImage;
+                               else
+                                   return pipeErrorImage;
                        } else if (element instanceof Equipment) {
                                return tankImage;
                        } else if (element instanceof PipeRun) {
index c7df71a1ea3d2f3f6281ee5af576c5bdabc5942c..cdbd3431da0c046f15235b490220291f8a5ecfe8 100644 (file)
@@ -32,7 +32,7 @@ public class StraightGeometryProvider extends BuiltinMeshProvider {
        
        @Override
        public Mesh getMesh() {
-               if (length < .001 || radius < MathTools.NEAR_ZERO )
+               if (length < .0001 || radius < MathTools.NEAR_ZERO )
                        return null;
                Tube tube = new Tube();
                tube.setResolution(16);
index 7726b203005611c05b89a739b634617018f79295..e1a24f10369024c61a29a1b3d1e8e525039cac3f 100644 (file)
@@ -675,4 +675,32 @@ public abstract class PipelineComponent extends GeometryNode {
                        throw new IllegalStateException("No centroid defined");
                }
        }
+       
+       
+       private String error;
+       
+       /**
+        * Returns possible pipe modelling error, or null;
+        * @return
+        */
+       @GetPropertyValue(name="Error", value="error", tabId = "Default")
+       public String getError() {
+           return error;
+       }
+       
+       /**
+        * Sets pipe modelling error. 
+        * 
+        * Error is usually set by PipingRules.
+        * @param error
+        */
+       public void setError(String error) {
+           if (this.error == null) {
+               if (error == null)
+                   return;
+           } else if (this.error.equals(error))
+               return;
+           this.error = error;         
+           firePropertyChanged("error");
+       }
 }
index 8b1455ca2980a8f4927b291299efff2102d5606f..8616e70352815a50256a1b16e32afdbe1c52c787 100644 (file)
@@ -147,6 +147,11 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        public boolean isInline() {
                return type == PointType.INLINE;
        }
+       
+       public boolean asPathLegEnd() {
+           // Ends and Turns are path leg ends by default, but also unconnected inline are path leg ends.
+           return isPathLegEnd() || getNext() == null || getPrevious() == null;
+       }
 
        /**
         * True for end components, if control point defines absolute position direction, which rules cannot modify. 
@@ -343,6 +348,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
         if (MathTools.createRotation(dirOutN, dirOut, dir, aa)) {
             setRotationAngle(aa.angle);
             setTurnAngle(angle);
+            if (DEBUG) System.out.println("convertToFixed " + dir + " " + dirOut + " " +dirOutN + " " +angle + " "+ aa.angle);
         }
        }
 
index 3ab4cca46892795d3f3931b1b00a651a5f0518a3..688e50f9f6485824a6f51efb4abfcf86e85eaf80 100644 (file)
@@ -2,9 +2,7 @@ package org.simantics.plant3d.scenegraph.controlpoint;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.vecmath.Point3d;
 import javax.vecmath.Quat4d;
@@ -12,7 +10,6 @@ import javax.vecmath.Vector3d;
 
 import org.simantics.g3d.math.MathTools;
 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;
@@ -25,8 +22,9 @@ public class PipingRules {
        private static final boolean DEBUG = false;
        private static final boolean DUMMY = false;
 
-       private static double MIN_TURN_ANGLE = 0.001; // Threshold for removing turn components.
-       private static double ALLOWED_OFFSET = 0.001; // Allowed offset for directed path legs
+       private static double MIN_TURN_ANGLE = 0.001;    // Threshold for removing turn components.
+       private static double ALLOWED_OFFSET = 0.001;    // Allowed offset for directed path legs
+       private static double MIN_INLINE_LENGTH = 0.001; // Minimum length of inline components, when component removal is not allowed. 
 
        private static final int REMOVE_NONE = 0;
        private static final int REMOVE_START = 1;
@@ -34,11 +32,16 @@ public class PipingRules {
        private static final int REMOVE_BOTH = 3;
        
 
+       // PathLeg iteration indicator. NEXT_S > NEXT > NONE  PREV_S > PREV > NONE 
        private enum PathLegUpdateType {
-               NONE, PREV, NEXT, PREV_S, NEXT_S
+               NONE,   // Only current path leg needs to be updated  (for example, inline comp was moved)
+               PREV,   // Current and previous path leg need to be updated 
+               NEXT,   // Current and next path leg need to be updated
+               PREV_S, // Current and previous two path legs need to be updated (turn was moved, which affect other path leg end turns, and thus following path legs
+               NEXT_S  // Current and next two path legs need to be updated
        };
        
-       private static boolean enabled = true;
+       private static boolean enabled = true;  // 
        private static boolean updating = false;
        private static boolean allowInsertRemove = true;
        private static boolean triedIR = false;
@@ -113,12 +116,12 @@ public class PipingRules {
                        allowInsertRemove = allowIR;
                        triedIR = false;
                        validate(pcp.getPipeRun());
-                       if (pcp.isPathLegEnd()) {
+                       if (pcp.asPathLegEnd()) {
                                updatePathLegEndControlPoint(pcp); // FIXME: Rules won't work properly, if they are not run twice.
-                               updatePathLegEndControlPoint(pcp);
+                               //updatePathLegEndControlPoint(pcp);
                        } else {
                                updateInlineControlPoint(pcp);
-                               updateInlineControlPoint(pcp);
+                               //updateInlineControlPoint(pcp);
                        }
                        validate(pcp.getPipeRun());
                        if (!allowInsertRemove)
@@ -139,10 +142,6 @@ public class PipingRules {
        public static boolean isEnabled() {
                return enabled;
        }
-       
-//     private void commit() {
-//             root.getNodeMap().commit();
-//     }
 
        public static class ExpandIterInfo {
                // these two are turn control points
@@ -301,14 +300,7 @@ public class PipingRules {
        }
 
        private static void updatePathLegNext(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
-
                UpdateStruct2 us = createUS(start, Direction.NEXT, 0, new ArrayList<ExpandIterInfo>(), updated);
-               if (lengthChange == PathLegUpdateType.NONE) {
-                       if (start.equals(updated))
-                               lengthChange = PathLegUpdateType.NEXT;
-                       else if (us.end.equals(updated))
-                               lengthChange = PathLegUpdateType.PREV;
-               }
                if (us == null) {
                    System.out.println("Null update struct " + start);
                    return; 
@@ -317,14 +309,7 @@ public class PipingRules {
        }
        
        private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
-               // TODO: this method is not symmetric with updatePathLegNext, which may alter lengthChange parameter?
                UpdateStruct2 us = createUS(start, Direction.PREVIOUS, 0, new ArrayList<ExpandIterInfo>(), updated);
-//        if (lengthChange == PathLegUpdateType.NONE) {
-//            if (start.equals(updated))
-//                lengthChange = PathLegUpdateType.NEXT;
-//            else if (us.end.equals(updated))
-//                lengthChange = PathLegUpdateType.PREV;
-//        }
                if (us == null) {
             System.out.println("Null update struct " + start);
             return; 
@@ -476,11 +461,27 @@ public class PipingRules {
        }
  
        private static void updatePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception {
+           boolean rs = true;
+           boolean re = true;
+           if (lengthChange == PathLegUpdateType.NONE) {
+               rs = false;
+               re = false;
+           }
+           updatePathLeg(u, lengthChange, rs, re);
+       }
+       
+       private static void updatePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange, boolean rs, boolean re) throws Exception {
                int directed = 0;
                if (asDirected(u.start, Direction.NEXT))
                        directed++;
                if (asDirected(u.end, Direction.PREVIOUS))
                        directed++;
+               if (rs)
+                   u.start.getPipelineComponent().setError(null);
+               if (re)
+                   u.end.getPipelineComponent().setError(null);
+        for (PipeControlPoint pcp : u.list)
+            pcp.getPipelineComponent().setError(null);
                switch (directed) {
                case 0:
                        updateFreePathLeg(u, lengthChange);
@@ -512,10 +513,12 @@ public class PipingRules {
                
                if (checkSizes) {
                        // create offsets for leg ends.
-                       MathTools.mad(start, u.dir, u.start.getInlineLength());
-                       MathTools.mad(end, u.dir, -u.end.getInlineLength());
+                   if (u.start.isTurn())
+                       MathTools.mad(start, u.dir, u.start.getInlineLength());
+                   if (u.end.isTurn())
+                       MathTools.mad(end, u.dir, -u.end.getInlineLength());   
                }
-               
+
                boolean recalcline = false;
                if (!u.hasOffsets) {
                        
@@ -533,16 +536,28 @@ public class PipingRules {
                                return;                 
 
                        ArrayList<PipeControlPoint> pathLegPoints = new ArrayList<PipeControlPoint>();
+                       ArrayList<PipeControlPoint> fixedLengthPoints = new ArrayList<PipeControlPoint>();
                        pathLegPoints.add(u.start);
+                       
                        for (PipeControlPoint icp : u.list) {
                                // updateInlineControlPoint(icp, u.startPoint,
                                // u.endPoint,u.dir);
                                updateBranchControlPointBranches(icp);
                                pathLegPoints.add(icp);
+                               if (!icp.isVariableLength())
+                                   fixedLengthPoints.add(icp);
                        }
                        pathLegPoints.add(u.end);
 
-                       // TODO : values can be cached in the loop
+                       // updateInlineControlPoint keeps components between path leg ends, but does not ensure that fixed length components do no overlap each other
+                       
+                       for (int i = 0; i < fixedLengthPoints.size(); i++) {
+                           PipeControlPoint prev = i == 0 ? null : fixedLengthPoints.get(i-1);
+                           PipeControlPoint curr = fixedLengthPoints.get(i);
+                           PipeControlPoint next = i == fixedLengthPoints.size() -1 ? null : fixedLengthPoints.get(i+1);
+                           updateFixedLength(curr, prev, next, start,end, u.dir);
+                       }
+
                        for (int i = 0; i < pathLegPoints.size(); i++) {
                                PipeControlPoint icp = pathLegPoints.get(i);
 
@@ -645,48 +660,72 @@ public class PipingRules {
                if (recalcline) {
                        u.list.clear();
                        u.start.findNextEnd(u.list);
+               } 
+               if (checkSizes) {
+                   double pathLegLength = MathTools.distance(u.startPoint, u.endPoint);
+            double availableLength = pathLegLength;
+            if (u.start.isTurn())
+                availableLength -= u.start.getInlineLength();
+            if (u.end.isTurn())
+                availableLength -= u.end.getInlineLength();
+            for (PipeControlPoint pcp : u.list) {
+                if (!pcp.isVariableLength())
+                    availableLength-= pcp.getLength();
+                   }
+            if (availableLength < 0.0) {
+                u.start.getPipelineComponent().setError("Not enough available space");
+                u.end.getPipelineComponent().setError("Not enough available space");
+                for (PipeControlPoint pcp : u.list)
+                    pcp.getPipelineComponent().setError("Not enough available space");
+            }
+//            System.out.println(u.start.getPipelineComponent().toString() + " " + pathLegLength + " " + availableLength + " " + u.end.getPipelineComponent().toString() + " " + u.start.getInlineLength() + " " + u.end.getInlineLength());
                }
        }
        
+       private static void updateFixedLength(PipeControlPoint icp, PipeControlPoint prev,  PipeControlPoint next, Vector3d s, Vector3d e, Vector3d dir) {
+           if (prev != null) {
+              checkOverlap(icp, prev);
+           }
+           if (next != null)
+               checkOverlap(icp, next);
+       }
+       
+       private static void checkOverlap(PipeControlPoint icp, PipeControlPoint prev) {
+           double d = MathTools.distance(prev.getWorldPosition(), icp.getWorldPosition());
+        double r = icp.getInlineLength() + prev.getInlineLength();
+        if (d < r) {
+            if (icp.getPipelineComponent().getError() == null)
+                icp.getPipelineComponent().setError("Overlapping");
+            if (prev.getPipelineComponent().getError() == null)
+                prev.getPipelineComponent().setError("Overlapping");
+        }
+       }
+       
        private static boolean updateVariableLength(PipeControlPoint icp, PipeControlPoint prev,  PipeControlPoint next) {
                Vector3d prevPos = prev.getWorldPosition();
                Vector3d nextPos = next.getWorldPosition();
                
                Vector3d dir = new Vector3d(nextPos);
                dir.sub(prevPos);
-               double l = dir.lengthSquared(); // distance between
-                                                                               // control points
-                                                                               // (square)
-               double l2prev = prev.getInlineLength(); // distance
-                                                                                                                                       // taken
-                                                                                                                                       // by
-                                                                                                                                       // components
+               double l = dir.length();                // distance between control points
+               double l2prev = prev.getInlineLength(); // distance taken by components
                double l2next = next.getInlineLength();
                double l2 = l2prev + l2next;
-               double l2s = MathTools.square(l2);
-               if (l2s < l) { // check if there is enough space for
-                                               // variable length component.
+               double length = l - l2;                 // true length of the variable length component
+               if (length >= MIN_INLINE_LENGTH) {      // check if there is enough space for variable length component.
                        // components fit
                        dir.normalize();
-                       double length = Math.sqrt(l) - l2; // true length of
-                                                                                               // the variable
-                                                                                               // length
-                                                                                               // component
-                       dir.scale(length * 0.5 + l2prev); // calculate
-                                                                                               // center
-                                                                                               // position of
-                                                                                               // the component
+                       dir.scale(length * 0.5 + l2prev);   // calculate center position of the component
                        dir.add(prevPos);
                        icp.setWorldPosition(dir);
                        icp.setLength(length);
                        return false;
                } else {
-                       // components leave no space to the component and it
-                       // must be removed
-                       
+                       // components leave no space to the component and it must be removed
                        if (icp.isDeletable()) {
                            if (!allowInsertRemove) {
-                               icp.setLength(0.0001);
+                               icp.setLength(MIN_INLINE_LENGTH);
+                               icp.getPipelineComponent().setError("Not enough available space");
                                triedIR = true;
                                return false;
                            }
@@ -694,6 +733,9 @@ public class PipingRules {
                                        System.out.println("PipingRules.updateVariableLength removing " + icp);
                                icp._remove();
                                return true;
+                       } else {
+                           icp.setLength(MIN_INLINE_LENGTH);
+                           icp.getPipelineComponent().setError("Not enough available space");
                        }
                        return false;
                }
@@ -712,12 +754,8 @@ public class PipingRules {
                if (l > l2s) {
                        if (allowInsertRemove) {
                                dir.normalize();
-                               double length = Math.sqrt(l) - l2; // true length of the
-                                                                                                       // variable length
-                                                                                                       // component
-                               dir.scale(length * 0.5 + l2prev); // calculate center
-                                                                                                       // position of the
-                                                                                                       // component
+                               double length = Math.sqrt(l) - l2; // true length of the variable length component
+                               dir.scale(length * 0.5 + l2prev); // calculate center position of the component
                                dir.add(prevPos);
                                insertStraight(prev, icp, dir, length);
                                return true;
index 18d5b2cd2e9e0e908e532e619e22890b0f7f7d56..055ffa11df29a5f388b9eea4e67089862247b40a 100644 (file)
@@ -253,16 +253,17 @@ public class P3DUtil {
                }
        }
        
-   public static void finalizeDBLoad2(P3DRootNode rootNode) throws Exception{
-       PipingRules.setEnabled(true);
+    public static void finalizeDBLoad2(P3DRootNode rootNode) throws Exception {
+        PipingRules.setEnabled(true);
         for (INode node : rootNode.getChild()) {
             if (node instanceof PipeRun) {
-                PipeRun run = (PipeRun)node;
+                PipeRun run = (PipeRun) node;
                 for (PipeControlPoint pcp : run.getControlPoints())
-                    PipingRules.positionUpdate(pcp);
-                    //PipingRules.requestUpdate(pcp);
+                    if (pcp.asPathLegEnd())
+                        PipingRules.requestUpdate(pcp);
             }
         }
-   }
+        PipingRules.update();
+    }
 
 }