From: Marko Luukkainen Date: Mon, 5 Aug 2019 11:29:58 +0000 (+0300) Subject: Translate action for inline components X-Git-Tag: v1.43.0~239 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=68bb44ea41644141aaaf7467ac3d201678e31db3;p=simantics%2F3d.git Translate action for inline components gitlab #14 Change-Id: I4f051a585288130479049490337c0c46c1803c3f --- diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java index 4d99999f..7000edae 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java @@ -1,486 +1,486 @@ -/******************************************************************************* - * 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(); - private 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; - 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(); - - } - - - private 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(); - } - - 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; - - private 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); - } - - Vector3d getTranslate(double x, double y) { - return getTranslate(x, y, new Vector3d()); - } - - 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; - } - -} +/******************************************************************************* + * 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 index 00000000..2c10845f --- /dev/null +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java @@ -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; + + } + + +} 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 618e0853..033f8544 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java @@ -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);