]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
Translate action for inline components 58/3058/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 5 Aug 2019 11:29:58 +0000 (14:29 +0300)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Mon, 5 Aug 2019 11:29:58 +0000 (14:29 +0300)
gitlab #14

Change-Id: I4f051a585288130479049490337c0c46c1803c3f

org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java
org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java [new file with mode: 0644]
org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java

index 4d99999f576ad4cff57841917d2d3e960d211304..7000edaea2efd091b21bc6530ff16838c12e6b34 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.vtk.action;\r
-\r
-import java.awt.Cursor;\r
-import java.awt.event.KeyEvent;\r
-import java.awt.event.MouseEvent;\r
-import java.math.BigDecimal;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Point3d;\r
-import javax.vecmath.Quat4d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.simantics.g3d.math.MathTools;\r
-import org.simantics.g3d.math.Ray;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-import org.simantics.g3d.scenegraph.structural.IStructuralNode;\r
-import org.simantics.g3d.vtk.Activator;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.g3d.vtk.common.VTKNodeMap;\r
-import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;\r
-import org.simantics.g3d.vtk.utils.vtkUtil;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-import vtk.vtkProp;\r
-\r
-public class TranslateAction extends vtkAction{\r
-       \r
-       public static final int X = 0;\r
-    public static final int Y = 1;\r
-    public static final int Z = 2;\r
-    public static final int XY = 3;\r
-    public static final int XZ = 4;\r
-    public static final int YZ = 5;\r
-    public static final int P = 6;\r
-\r
-       private VTKNodeMap nodeMap;\r
-       //private TranslateGizmo  gizmo = new TranslateGizmo();\r
-       private TranslateAxisGizmo gizmo = new TranslateAxisGizmo();\r
-       private IG3DNode node;\r
-       \r
-       \r
-       \r
-       private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);\r
-       private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);\r
-       \r
-       public void setNode(IG3DNode node) {\r
-               this.node = node;\r
-               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {\r
-                       setEnabled(false);\r
-               } else {\r
-                       setEnabled(true);\r
-               }\r
-       }\r
-       \r
-       public IG3DNode getNode() {\r
-               return node;\r
-       }\r
-       \r
-       public TranslateAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {\r
-               super(panel);\r
-               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_out.png"));\r
-               setText("Translate");\r
-               this.nodeMap = nodeMap;\r
-       }\r
-       \r
-       public void attach() {\r
-               if (node == null)\r
-                       return;\r
-               \r
-               super.attach();\r
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                       public void run() {\r
-                               attachUI();\r
-                               update();\r
-                       }\r
-               });\r
-               \r
-               \r
-               \r
-       }\r
-       \r
-       public void deattach() {\r
-               \r
-               node = null;\r
-               nodeMap.commit();\r
-               deattachUI();\r
-               super.deattach();\r
-               panel.repaint();\r
-       }\r
-       \r
-       private void attachUI() {\r
-               panel.setCursor(activeCursor);\r
-               gizmo.attach(panel.GetRenderer());\r
-       }\r
-       \r
-       private void deattachUI() {\r
-               panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));\r
-               gizmo.deattach();\r
-       }\r
-       \r
-       @Override\r
-       public void keyPressed(KeyEvent e) {\r
-               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)\r
-                       panel.useDefaultAction();\r
-               if (valid)\r
-                       return;\r
-               if (e.getKeyCode() == KeyEvent.VK_X) {\r
-                       if (index != X)\r
-                               index = X;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_Y) {\r
-                       if (index != Y)\r
-                               index = Y;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_Z) {\r
-                       if (index != Z)\r
-                               index = Z;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_G) {\r
-                       worldCoord = !worldCoord;\r
-               }\r
-               gizmo.setType(index);\r
-               \r
-               update();\r
-               //panel.repaint();\r
-       }\r
-       \r
-       @Override\r
-       public void keyReleased(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void keyTyped(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseClicked(MouseEvent e) {\r
-               if (e.getClickCount() > 1) {\r
-                       if (isOverNode(e)) {\r
-                               return;\r
-                       } else {\r
-                               panel.useDefaultAction();\r
-                       }\r
-                       //if(!gizmo.isPartOf(actor))\r
-                       //      panel.useDefaultAction();\r
-                       \r
-               }\r
-       }\r
-       \r
-       private boolean isOverNode(MouseEvent e) {\r
-               vtkProp picked[] = panel.pick(e.getX(), e.getY());\r
-               if (picked !=null) {\r
-                       for (int i = 0; i < picked.length; i++) {\r
-                               if (node.equals(nodeMap.getNode(picked[i])))\r
-                                       return true;\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       @Override\r
-       public void mouseEntered(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseExited(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       int index = P;\r
-       boolean valid = false;\r
-       private boolean worldCoord = true;\r
-       private AxisAngle4d aa = null;\r
-       private Quat4d q = null;\r
-       \r
-       \r
-       public void setWorldCoord(boolean b) {\r
-               if (worldCoord == b)\r
-                       return;\r
-               worldCoord = b;\r
-               update();\r
-                                       \r
-       }\r
-       \r
-       \r
-       private void update() {\r
-               if (node == null)\r
-                       return;\r
-               if (worldCoord) {\r
-                       gizmo.setRotation(new AxisAngle4d());\r
-                       aa = null;\r
-                       q = null;\r
-               } else {\r
-                       aa = new AxisAngle4d();\r
-                       aa.set(((IG3DNode)node.getParent()).getWorldOrientation());\r
-                       gizmo.setRotation(aa);\r
-                       q = new Quat4d();\r
-                       MathTools.getQuat(aa, q);\r
-               }\r
-               \r
-               Vector3d nodePos = node.getWorldPosition();\r
-               //System.out.println(nodePos);\r
-               gizmo.setPosition(nodePos);\r
-\r
-               \r
-               Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());\r
-               Vector3d p = new Vector3d(nodePos);\r
-               p.sub(camPos);\r
-               \r
-               if (q != null) {\r
-                       Quat4d qi = new Quat4d(q);\r
-                       qi.inverse();\r
-                       MathTools.rotate(q, p, p);\r
-               }\r
-               if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {\r
-                       double distance = p.length();\r
-                       p.negate();\r
-            double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();\r
-            float s = (float) (Math.sin(fov) * distance * 0.1); \r
-\r
-            Vector3d scale = new Vector3d(1., 1., 1.);\r
-            \r
-//            if (p.x > 0.f)\r
-//                scale.x = -1.;\r
-//            if (p.y > 0.f)\r
-//                scale.y = -1.;\r
-//            if (p.z > 0.f)\r
-//                scale.z = -1.;\r
-            scale.scale(s);\r
-            gizmo.setScale(scale);\r
-                       \r
-               } else {\r
-                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);\r
-            double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;\r
-//            if (p.x > 0.f)\r
-//                scale.x = -1.;\r
-//            if (p.y > 0.f)\r
-//                scale.y = -1.;\r
-//            if (p.z > 0.f)\r
-//                scale.z = -1.;\r
-            scale.scale(s);\r
-            gizmo.setScale(scale);\r
-               }\r
-               \r
-               //panel.Render();\r
-               panel.repaint();\r
-       }\r
-       \r
-       Vector3d prevTranslate = null;\r
-       \r
-       @Override\r
-       public void mousePressed(MouseEvent e) {\r
-               if (e.getButton() == MouseEvent.BUTTON1) {\r
-\r
-                       if (isOverNode(e)) {\r
-                               prevTranslate = getTranslate(e.getX(), e.getY());\r
-                               valid = true;\r
-                               panel.setCursor(dragCursor);\r
-                       } else {\r
-                               valid = false;\r
-                               panel.getDefaultAction().mousePressed(e);\r
-                               panel.setCursor(activeCursor);\r
-                       }\r
-               } else {\r
-                       panel.getDefaultAction().mousePressed(e);\r
-               }\r
-               //index = gizmo.getTranslateAxis(actor);\r
-               //if (index == -1) {\r
-               //  valid = false;\r
-               //      panel.getDefaultAction().mousePressed(e);\r
-               //      return;\r
-               //}\r
-               //valid = true; \r
-               //prevTranslate = getTranslate(e.getX(), e.getY());\r
-               //System.out.println("start translate " + prevTranslate);\r
-       }\r
-       \r
-       \r
-       \r
-       @Override\r
-       public void mouseReleased(MouseEvent e) {\r
-               if (e.getButton() == MouseEvent.BUTTON1) {\r
-                       valid = false;\r
-                       prevTranslate = null;\r
-                       panel.setCursor(activeCursor);\r
-               } else {\r
-                       panel.getDefaultAction().mouseReleased(e);\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void mouseDragged(MouseEvent e) {\r
-               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { \r
-                       \r
-                       Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);\r
-                       //System.out.println("translate " + translate);\r
-                       if (translate == null)\r
-                               return;\r
-                       boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);\r
-                       if (worldCoord) {\r
-                               Vector3d pos = new Vector3d(node.getWorldPosition());\r
-                               pos.add(translate);\r
-                               pos = constaints(pos, step);\r
-                               setWorldPos(pos);\r
-                       } else {\r
-                               Vector3d pos = new Vector3d(node.getPosition());\r
-                               pos.add(translate);\r
-                               pos = constaints(pos, step);\r
-                               setPos(pos);\r
-                       }\r
-                       //mapping.rangeModified(node);\r
-                       \r
-                       //nodeMap.modified(node);\r
-                       update();\r
-               } else {\r
-                       panel.getDefaultAction().mouseDragged(e);\r
-                       update();\r
-               }\r
-       }\r
-       \r
-       protected void setPos(Vector3d pos) {\r
-               node.setPosition(pos);\r
-       }\r
-       \r
-       protected void setWorldPos(Vector3d pos) {\r
-               node.setWorldPosition(pos);\r
-       }\r
-       \r
-        private double istep = 10.0;\r
-        private int decimals = 2;\r
-       \r
-       private Vector3d constaints(Vector3d p, boolean step) {\r
-               if(!step)\r
-                       return p;\r
-               switch (index) {\r
-               case X:\r
-                        p.x = Math.round(istep * p.x) / istep;\r
-             BigDecimal bx = new BigDecimal(p.x);\r
-             bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
-             p.x = bx.doubleValue();\r
-                       break;\r
-               case Y:\r
-                        p.y = Math.round(istep * p.y) / istep;\r
-             BigDecimal by = new BigDecimal(p.y);\r
-             by.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
-             p.y = by.doubleValue();\r
-                       break;\r
-                       \r
-               case Z:\r
-                        p.z = Math.round(istep * p.z) / istep;\r
-             BigDecimal bz = new BigDecimal(p.z);\r
-             bz.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
-             p.z = bz.doubleValue();\r
-                       break;\r
-               }\r
-               return p;\r
-       }\r
-       \r
-       @Override\r
-       public void mouseMoved(MouseEvent e) {\r
-               panel.getDefaultAction().mouseMoved(e);\r
-       }\r
-       \r
-       Vector3d getTranslate(double x, double y) {\r
-               return getTranslate(x, y, new Vector3d());\r
-       }\r
-       \r
-       Vector3d getTranslate(double x, double y, Vector3d offset) {\r
-               Vector3d translate = new Vector3d();\r
-               \r
-               Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);\r
-               \r
-               Vector3d p = node.getWorldPosition();\r
-               Vector3d dir = null;\r
-               \r
-               switch (index) {\r
-               case P:\r
-                       Vector3d normal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetDirectionOfProjection());\r
-                       if (!worldCoord) {\r
-                               MathTools.rotate(q, normal, normal);\r
-                       }\r
-                       normal.normalize();\r
-                       double s[] = new double[1];\r
-            Vector3d r = new Vector3d();\r
-            if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {\r
-                r.sub(p);\r
-                translate.x = r.x;\r
-                translate.y = r.y;\r
-                translate.z = r.z;\r
-            }\r
-            break;\r
-\r
-                case X :\r
-                   dir = new Vector3d(1.0,0.0,0.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, dir, dir);\r
-                   Vector3d i1 = new Vector3d();\r
-                   Vector3d i2 = new Vector3d();\r
-                   s = new double[2];\r
-                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);\r
-                   translate.x = s[0];\r
-                   \r
-                   break;\r
-               case Y :\r
-                   dir = new Vector3d(0.0,1.0,0.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, dir, dir);\r
-                   i1 = new Vector3d();\r
-                   i2 = new Vector3d();\r
-                   s = new double[2];\r
-                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);\r
-                   translate.y = s[0];\r
-                   break;\r
-               case Z :\r
-                   dir = new Vector3d(0.0,0.0,1.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, dir, dir);\r
-                   i1 = new Vector3d();\r
-                   i2 = new Vector3d();\r
-                   s = new double[2];\r
-                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);\r
-                   translate.z = s[0];\r
-                   break;\r
-               case XY :\r
-                   normal = new Vector3d(0.0,0.0,1.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, normal, normal);\r
-                   r = new Vector3d();\r
-                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {\r
-                       r.sub(p);\r
-                       translate.x = r.x;\r
-                       translate.y = r.y;\r
-                   }\r
-                   break;\r
-               case XZ :\r
-                   normal = new Vector3d(0.0,1.0,0.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, normal, normal);\r
-                   r = new Vector3d();\r
-                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {\r
-                       r.sub(p);\r
-                       translate.x = r.x;\r
-                       translate.z = r.z;\r
-                   }\r
-                   break;\r
-               case YZ :\r
-                   normal = new Vector3d(1.0,0.0,0.0);\r
-                   if(!worldCoord)\r
-                       MathTools.rotate(q, normal, normal);\r
-                   r = new Vector3d();\r
-                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {\r
-                       r.sub(p);\r
-                       translate.y = r.y;\r
-                       translate.z = r.z;\r
-                   }\r
-                   break;\r
-               default :\r
-                   \r
-                   return null;\r
-               }\r
-               translate.sub(offset);\r
-               return translate;\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.vtk.action;
+
+import java.awt.Cursor;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.math.BigDecimal;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Point3d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.structural.IStructuralNode;
+import org.simantics.g3d.vtk.Activator;
+import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkProp;
+
+public class TranslateAction extends vtkAction{
+       
+       public static final int X = 0;
+    public static final int Y = 1;
+    public static final int Z = 2;
+    public static final int XY = 3;
+    public static final int XZ = 4;
+    public static final int YZ = 5;
+    public static final int P = 6;
+
+       private VTKNodeMap nodeMap;
+       //private TranslateGizmo  gizmo = new TranslateGizmo();
+       private TranslateAxisGizmo gizmo = new TranslateAxisGizmo();
+       protected IG3DNode node;
+       
+       
+       
+       private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+       private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+       
+       public void setNode(IG3DNode node) {
+               this.node = node;
+               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {
+                       setEnabled(false);
+               } else {
+                       setEnabled(true);
+               }
+       }
+       
+       public IG3DNode getNode() {
+               return node;
+       }
+       
+       public TranslateAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {
+               super(panel);
+               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_out.png"));
+               setText("Translate");
+               this.nodeMap = nodeMap;
+       }
+       
+       public void attach() {
+               if (node == null)
+                       return;
+               
+               super.attach();
+               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+                       public void run() {
+                               attachUI();
+                               update();
+                       }
+               });
+               
+               
+               
+       }
+       
+       public void deattach() {
+               
+               node = null;
+               nodeMap.commit();
+               deattachUI();
+               super.deattach();
+               panel.repaint();
+       }
+       
+       private void attachUI() {
+               panel.setCursor(activeCursor);
+               gizmo.attach(panel.GetRenderer());
+       }
+       
+       private void deattachUI() {
+               panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+               gizmo.deattach();
+       }
+       
+       @Override
+       public void keyPressed(KeyEvent e) {
+               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
+                       panel.useDefaultAction();
+               if (valid)
+                       return;
+               if (e.getKeyCode() == KeyEvent.VK_X) {
+                       if (index != X)
+                               index = X;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Y) {
+                       if (index != Y)
+                               index = Y;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Z) {
+                       if (index != Z)
+                               index = Z;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_G) {
+                       worldCoord = !worldCoord;
+               }
+               gizmo.setType(index);
+               
+               update();
+               //panel.repaint();
+       }
+       
+       @Override
+       public void keyReleased(KeyEvent e) {
+               
+       }
+       
+       @Override
+       public void keyTyped(KeyEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseClicked(MouseEvent e) {
+               if (e.getClickCount() > 1) {
+                       if (isOverNode(e)) {
+                               return;
+                       } else {
+                               panel.useDefaultAction();
+                       }
+                       //if(!gizmo.isPartOf(actor))
+                       //      panel.useDefaultAction();
+                       
+               }
+       }
+       
+       private boolean isOverNode(MouseEvent e) {
+               vtkProp picked[] = panel.pick(e.getX(), e.getY());
+               if (picked !=null) {
+                       for (int i = 0; i < picked.length; i++) {
+                               if (node.equals(nodeMap.getNode(picked[i])))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+       
+       @Override
+       public void mouseEntered(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseExited(MouseEvent e) {
+               
+       }
+       
+       int index = P;
+       protected boolean valid = false;
+       private boolean worldCoord = true;
+       private AxisAngle4d aa = null;
+       private Quat4d q = null;
+       
+       
+       public void setWorldCoord(boolean b) {
+               if (worldCoord == b)
+                       return;
+               worldCoord = b;
+               update();
+                                       
+       }
+       
+       
+       protected void update() {
+               if (node == null)
+                       return;
+               if (worldCoord) {
+                       gizmo.setRotation(new AxisAngle4d());
+                       aa = null;
+                       q = null;
+               } else {
+                       aa = new AxisAngle4d();
+                       aa.set(((IG3DNode)node.getParent()).getWorldOrientation());
+                       gizmo.setRotation(aa);
+                       q = new Quat4d();
+                       MathTools.getQuat(aa, q);
+               }
+               
+               Vector3d nodePos = node.getWorldPosition();
+               //System.out.println(nodePos);
+               gizmo.setPosition(nodePos);
+
+               
+               Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());
+               Vector3d p = new Vector3d(nodePos);
+               p.sub(camPos);
+               
+               if (q != null) {
+                       Quat4d qi = new Quat4d(q);
+                       qi.inverse();
+                       MathTools.rotate(q, p, p);
+               }
+               if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {
+                       double distance = p.length();
+                       p.negate();
+            double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();
+            float s = (float) (Math.sin(fov) * distance * 0.1); 
+
+            Vector3d scale = new Vector3d(1., 1., 1.);
+            
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+                       
+               } else {
+                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);
+            double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+               }
+               
+               //panel.Render();
+               panel.repaint();
+       }
+       
+       protected Vector3d prevTranslate = null;
+       
+       @Override
+       public void mousePressed(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+
+                       if (isOverNode(e)) {
+                               prevTranslate = getTranslate(e.getX(), e.getY());
+                               valid = true;
+                               panel.setCursor(dragCursor);
+                       } else {
+                               valid = false;
+                               panel.getDefaultAction().mousePressed(e);
+                               panel.setCursor(activeCursor);
+                       }
+               } else {
+                       panel.getDefaultAction().mousePressed(e);
+               }
+               //index = gizmo.getTranslateAxis(actor);
+               //if (index == -1) {
+               //  valid = false;
+               //      panel.getDefaultAction().mousePressed(e);
+               //      return;
+               //}
+               //valid = true; 
+               //prevTranslate = getTranslate(e.getX(), e.getY());
+               //System.out.println("start translate " + prevTranslate);
+       }
+       
+       
+       
+       @Override
+       public void mouseReleased(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+                       valid = false;
+                       prevTranslate = null;
+                       panel.setCursor(activeCursor);
+               } else {
+                       panel.getDefaultAction().mouseReleased(e);
+               }
+       }
+       
+       @Override
+       public void mouseDragged(MouseEvent e) {
+               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
+                       
+                       Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);
+                       //System.out.println("translate " + translate);
+                       if (translate == null)
+                               return;
+                       boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
+                       if (worldCoord) {
+                               Vector3d pos = new Vector3d(node.getWorldPosition());
+                               pos.add(translate);
+                               pos = constaints(pos, step);
+                               setWorldPos(pos);
+                       } else {
+                               Vector3d pos = new Vector3d(node.getPosition());
+                               pos.add(translate);
+                               pos = constaints(pos, step);
+                               setPos(pos);
+                       }
+                       //mapping.rangeModified(node);
+                       
+                       //nodeMap.modified(node);
+                       update();
+               } else {
+                       panel.getDefaultAction().mouseDragged(e);
+                       update();
+               }
+       }
+       
+       protected void setPos(Vector3d pos) {
+               node.setPosition(pos);
+       }
+       
+       protected void setWorldPos(Vector3d pos) {
+               node.setWorldPosition(pos);
+       }
+       
+        private double istep = 10.0;
+        private int decimals = 2;
+       
+       protected Vector3d constaints(Vector3d p, boolean step) {
+               if(!step)
+                       return p;
+               switch (index) {
+               case X:
+                        p.x = Math.round(istep * p.x) / istep;
+             BigDecimal bx = new BigDecimal(p.x);
+             bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.x = bx.doubleValue();
+                       break;
+               case Y:
+                        p.y = Math.round(istep * p.y) / istep;
+             BigDecimal by = new BigDecimal(p.y);
+             by.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.y = by.doubleValue();
+                       break;
+                       
+               case Z:
+                        p.z = Math.round(istep * p.z) / istep;
+             BigDecimal bz = new BigDecimal(p.z);
+             bz.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.z = bz.doubleValue();
+                       break;
+               }
+               return p;
+       }
+       
+       @Override
+       public void mouseMoved(MouseEvent e) {
+               panel.getDefaultAction().mouseMoved(e);
+       }
+       
+       protected Vector3d getTranslate(double x, double y) {
+               return getTranslate(x, y, new Vector3d());
+       }
+       
+       protected Vector3d getTranslate(double x, double y, Vector3d offset) {
+               Vector3d translate = new Vector3d();
+               
+               Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
+               
+               Vector3d p = node.getWorldPosition();
+               Vector3d dir = null;
+               
+               switch (index) {
+               case P:
+                       Vector3d normal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetDirectionOfProjection());
+                       if (!worldCoord) {
+                               MathTools.rotate(q, normal, normal);
+                       }
+                       normal.normalize();
+                       double s[] = new double[1];
+            Vector3d r = new Vector3d();
+            if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                r.sub(p);
+                translate.x = r.x;
+                translate.y = r.y;
+                translate.z = r.z;
+            }
+            break;
+
+                case X :
+                   dir = new Vector3d(1.0,0.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   Vector3d i1 = new Vector3d();
+                   Vector3d i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.x = s[0];
+                   
+                   break;
+               case Y :
+                   dir = new Vector3d(0.0,1.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   i1 = new Vector3d();
+                   i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.y = s[0];
+                   break;
+               case Z :
+                   dir = new Vector3d(0.0,0.0,1.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   i1 = new Vector3d();
+                   i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.z = s[0];
+                   break;
+               case XY :
+                   normal = new Vector3d(0.0,0.0,1.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.x = r.x;
+                       translate.y = r.y;
+                   }
+                   break;
+               case XZ :
+                   normal = new Vector3d(0.0,1.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.x = r.x;
+                       translate.z = r.z;
+                   }
+                   break;
+               case YZ :
+                   normal = new Vector3d(1.0,0.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.y = r.y;
+                       translate.z = r.z;
+                   }
+                   break;
+               default :
+                   
+                   return null;
+               }
+               translate.sub(offset);
+               return translate;
+       }
+       
+}
diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java
new file mode 100644 (file)
index 0000000..2c10845
--- /dev/null
@@ -0,0 +1,129 @@
+package org.simantics.plant3d.actions;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+
+import javax.vecmath.Point3d;
+import javax.vecmath.Vector3d;
+
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.vtk.action.TranslateAction;
+import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.plant3d.Activator;
+import org.simantics.plant3d.scenegraph.InlineComponent;
+import org.simantics.plant3d.scenegraph.PipelineComponent;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
+
+public class TranslateInlineAction extends TranslateAction{
+       
+       private Vector3d s;
+       private Vector3d e;
+       private Vector3d dir;
+
+       public TranslateInlineAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {
+               super(panel, nodeMap);
+               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_refresh.png"));
+       }
+       
+       @Override
+       public void setNode(IG3DNode node) {
+               super.setNode(node);
+               if (node instanceof InlineComponent) {
+                       setEnabled(true);
+                       InlineComponent comp = (InlineComponent)node;
+                       
+                       PipelineComponent prev = comp.getPrevious();
+                       PipelineComponent next = comp.getNext();
+                       if (prev.getControlPoint().isInline() && !prev.getControlPoint().isFixed())
+                               prev = prev.getPrevious();
+                       if (next.getControlPoint().isInline() && !next.getControlPoint().isFixed()) {
+                               next = next.getNext();
+                       }
+                       Point3d ns = new Point3d();
+                       Point3d ne = new Point3d();
+                       Point3d ps = new Point3d();
+                       Point3d pe = new Point3d();
+                       next.getControlPointEnds(ns, ne);
+                       prev.getControlPointEnds(ps, pe);
+                       dir = comp.getControlPoint().getPathLegDirection(Direction.NEXT);
+                       dir.normalize();
+                       // We may have offsets in the path leg, hence we have to project the coordinates.
+                       Vector3d wp = node.getWorldPosition();
+                       s = MathTools.closestPointOnStraight(pe, wp, dir);
+                       e = MathTools.closestPointOnStraight(ns, wp, dir);
+                       // Remove component's own space from end points to get actual movement range
+                       double l = comp.getControlPoint().getInlineLength();
+                       Vector3d ld = new Vector3d(dir);
+                       ld.scale(l);
+                       s.add(ld);
+                       e.sub(ld);
+               } else {
+                       setEnabled(false);
+               }
+       }
+       
+       @Override
+       public void keyPressed(KeyEvent e) {
+               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
+                       panel.useDefaultAction();
+               if (valid)
+                       return;
+               
+               update();
+       }
+       
+       @Override
+       public void setWorldCoord(boolean b) {
+               
+       }
+       
+       @Override
+       public void mouseDragged(MouseEvent e) {
+               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
+                       
+                       Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);
+                       //System.out.println("translate " + translate);
+                       if (translate == null)
+                               return;
+                       boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
+                       Vector3d pos = new Vector3d(node.getWorldPosition());
+                       //pos.add(translate);
+                       pos.set(translate);
+                       //pos = constaints(pos, step);
+                       setWorldPos(pos);
+                       
+                       //mapping.rangeModified(node);
+                       
+                       //nodeMap.modified(node);
+                       update();
+               } else {
+                       panel.getDefaultAction().mouseDragged(e);
+                       update();
+               }
+       }
+       
+       
+       
+       protected Vector3d getTranslate(double x, double y, Vector3d offset) {
+               
+               Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
+               
+               Vector3d p = node.getWorldPosition();
+               
+               Vector3d i1 = new Vector3d();
+        Vector3d i2 = new Vector3d();
+        
+        double mu[] = new double[2];
+        MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,mu);
+        
+        Vector3d t = MathTools.closestPointOnEdge(i1, s, e);
+        return t;
+               
+       }
+
+
+}
index 618e08533f33b97cae6c583eddac57d5b802c7b9..033f8544cf6f71103130d6b7db37a986609959f0 100644 (file)
@@ -46,6 +46,7 @@ import org.simantics.plant3d.actions.AddComponentAction;
 import org.simantics.plant3d.actions.AddEquipmentAction;
 import org.simantics.plant3d.actions.AddNozzleAction;
 import org.simantics.plant3d.actions.RoutePipeAction;
+import org.simantics.plant3d.actions.TranslateInlineAction;
 import org.simantics.plant3d.scenegraph.EndComponent;
 import org.simantics.plant3d.scenegraph.Equipment;
 import org.simantics.plant3d.scenegraph.IP3DNode;
@@ -96,6 +97,7 @@ public class Plant3DEditor extends ResourceEditorPart {
        
        private vtkCameraAndSelectorAction cameraAction;
        private TranslateAction translateAction;
+       private TranslateInlineAction translateInlineAction;
        private RotateAction rotateAction;
        private RemoveAction removeAction;
        private RoutePipeAction routePipeAction;
@@ -244,6 +246,7 @@ public class Plant3DEditor extends ResourceEditorPart {
                }
                
                translateAction = new TranslateAction(panel,nodeMap);
+               translateInlineAction = new TranslateInlineAction(panel, nodeMap);
                rotateAction = new RotateAction(panel,nodeMap);
                removeAction = new RemoveAction(nodeMap) {
                        public void setNode(IG3DNode node) {
@@ -382,6 +385,7 @@ public class Plant3DEditor extends ResourceEditorPart {
                                } else if (node instanceof InlineComponent) {
                                        //m.add(translateInlineAction);
                                        InlineComponent component = (InlineComponent)node;
+                                       m.add(translateInlineAction);
                                        m.add(routePipeAction);
                                        routePipeAction.setComponent(component);
                                        m.add(addComponentAction);
@@ -390,6 +394,7 @@ public class Plant3DEditor extends ResourceEditorPart {
                                
                                m.add(removeAction);
                                translateAction.setNode(node);
+                               translateInlineAction.setNode(node);
                                rotateAction.setNode(node);
                                removeAction.setNode(node);