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.common.VTKNodeMap; import org.simantics.g3d.vtk.swt.InteractiveVtkComposite; import org.simantics.g3d.vtk.swt.TranslateAction; 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 boolean inline; private Vector3d s; private Vector3d e; private Vector3d dir; public TranslateInlineAction(InteractiveVtkComposite 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) { InlineComponent comp = (InlineComponent)node; if (comp.isVariableLength()) { setEnabled(false); } else if (comp.getNext() == null || comp.getPrevious() == null) { setEnabled(true); inline = false; dir = comp.getControlPoint().getPathLegDirection(Direction.NEXT); dir.normalize(); } else { setEnabled(true); inline = true; PipelineComponent prev = comp.getPrevious(); PipelineComponent next = comp.getNext(); if (prev == null || next == null) { // TODO : we should support open ended translation (when translated component is the first or last of the run). setEnabled(false); return; } if (prev.getControlPoint().isInline() && !prev.getControlPoint().isFixedLength() && prev.getPrevious() != null) prev = prev.getPrevious(); if (next.getControlPoint().isInline() && !next.getControlPoint().isFixedLength() && next.getNext() != null) { next = next.getNext(); } Point3d ns = new Point3d(); Point3d ne = new Point3d(); Point3d ps = new Point3d(); Point3d pe = new Point3d(); next.getEnds(ns, ne); prev.getEnds(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(); if (prev.getControlPoint().isVariableLength()) s = MathTools.closestPointOnStraight(ps, wp, dir); else s = MathTools.closestPointOnStraight(pe, wp, dir); if (next.getControlPoint().isVariableLength()) e = MathTools.closestPointOnStraight(ne, wp, dir); else 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 boolean keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) panel.useDefaultAction(); if (!inline) { return super.keyPressed(e); } else { if (valid) return true; update(); return true; } } @Override public void setWorldCoord(boolean b) { } @Override public boolean mouseDragged(MouseEvent e) { //if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { if (e.getButton() == MouseEvent.BUTTON1 && valid) { if (inline) { Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate); //System.out.println("translate " + translate); if (translate == null) return true; //boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0); Vector3d pos = new Vector3d(node.getWorldPosition()); System.out.println(pos + " " + translate); //pos.add(translate); pos.set(translate); //pos = constaints(pos, step); setWorldPos(pos); update(); } else { super.mouseDragged(e); } } else { getDefaultAction().mouseDragged(e); update(); } return true; } protected Vector3d getTranslate(double x, double y, Vector3d offset) { Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y); Vector3d p = node.getWorldPosition(); if (inline) { 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; } else { return super.getTranslate(x, y, offset); } } }