| /******************************************************************************* |
| * Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency |
| * 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: |
| * Pierre Allard, |
| * Regent L'Archeveque - initial API and implementation |
| * |
| * SPDX-License-Identifier: EPL-1.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.apogy.addons.impl; |
| |
| import javax.vecmath.Matrix4d; |
| import javax.vecmath.Point3d; |
| |
| import org.eclipse.apogy.addons.ApogyAddonsFactory; |
| import org.eclipse.apogy.addons.ApogyAddonsPackage; |
| import org.eclipse.apogy.addons.Ruler3dToolNode; |
| import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade; |
| import org.eclipse.apogy.common.math.ApogyCommonMathFacade; |
| import org.eclipse.apogy.common.math.Tuple3d; |
| import org.eclipse.apogy.common.topology.ApogyCommonTopologyFacade; |
| import org.eclipse.apogy.common.topology.GroupNode; |
| import org.eclipse.apogy.common.topology.Node; |
| import org.eclipse.apogy.common.topology.NodePath; |
| import org.eclipse.apogy.common.topology.ui.NodeSelection; |
| import org.eclipse.apogy.core.topology.ApogyCoreTopologyFacade; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| |
| public class Ruler3DToolCustomImpl extends Ruler3DToolImpl { |
| |
| public static int FROM_NODE_INDEX = 0; |
| public static int TO_NODE_INDEX = 1; |
| |
| private int nextNode = FROM_NODE_INDEX; |
| |
| @Override |
| public void initialise() { |
| if (getRuler3dToolNode() == null) { |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.RULER3_DTOOL__RULER3D_TOOL_NODE, createRuler3dToolNode()); |
| } |
| // Then, initialize the rest. |
| super.initialise(); |
| |
| // Forces the ruler to update. |
| updateRuler(); |
| } |
| |
| @Override |
| public void setActive(boolean newActive) { |
| super.setActive(newActive); |
| |
| if (newActive) { |
| forceToAndFromReload(); |
| |
| updateRuler(); |
| } |
| } |
| |
| @Override |
| public void setRootNode(Node newRootNode) { |
| super.setRootNode(newRootNode); |
| |
| // Ensure the Ruler3dToolNode is initialized. |
| if (getRuler3dToolNode() == null) { |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.RULER3_DTOOL__RULER3D_TOOL_NODE, createRuler3dToolNode()); |
| } |
| |
| if (this.getRootNode() != null) { |
| // Detach from previous root node. |
| detachRuler3dToolNode(); |
| } |
| |
| if (newRootNode instanceof GroupNode) { |
| ((GroupNode) newRootNode).getChildren().add(getRuler3dToolNode()); |
| getRuler3dToolNode().setParent(newRootNode); |
| } |
| |
| // Updates the ruler. |
| updateRuler(); |
| } |
| |
| @Override |
| public void variablesInstantiated() { |
| super.variablesInstantiated(); |
| |
| forceToAndFromReload(); |
| updateRuler(); |
| } |
| |
| @Override |
| public void selectionChanged(NodeSelection nodeSelection) { |
| if (!isDisposed()) { |
| Node node = nodeSelection.getSelectedNode(); |
| |
| Tuple3d relativePosition = null; |
| if (nodeSelection.getRelativeIntersectionPoint() != null) { |
| relativePosition = ApogyCommonMathFacade.INSTANCE |
| .createTuple3d(nodeSelection.getRelativeIntersectionPoint()); |
| } |
| |
| Tuple3d normal = null; |
| if (nodeSelection.getAbsoluteIntersectionNormal() != null) { |
| normal = ApogyCommonMathFacade.INSTANCE.createTuple3d(nodeSelection.getAbsoluteIntersectionNormal().x, |
| nodeSelection.getAbsoluteIntersectionNormal().y, |
| nodeSelection.getAbsoluteIntersectionNormal().z); |
| } |
| |
| if (this.nextNode == TO_NODE_INDEX) { |
| if (!isFromNodeLock()) { |
| updateFromNode(node, relativePosition, normal); |
| } else if (!isToNodeLock()) { |
| updateToNode(node, relativePosition, normal); |
| } |
| |
| this.nextNode = FROM_NODE_INDEX; |
| } else if (this.nextNode == FROM_NODE_INDEX) { |
| if (!isToNodeLock()) { |
| updateToNode(node, relativePosition, normal); |
| } else if (!isFromNodeLock()) { |
| updateFromNode(node, relativePosition, normal); |
| } |
| |
| this.nextNode = TO_NODE_INDEX; |
| } |
| } |
| } |
| |
| @Override |
| public void pointsRelativePoseChanged(Matrix4d newPose) { |
| if (!isDisposed()) |
| updateRuler(); |
| } |
| |
| @Override |
| public void dispose() { |
| // Detach the Ruler3dToolNode. |
| if (getRuler3dToolNode() != null) { |
| detachRuler3dToolNode(); |
| } |
| |
| // Clears the Ruler3dToolNode. |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.RULER3_DTOOL__RULER3D_TOOL_NODE, null); |
| |
| super.dispose(); |
| } |
| |
| protected Ruler3dToolNode createRuler3dToolNode() { |
| // Creates Ruler3dToolNode. |
| Ruler3dToolNode toolNode = ApogyAddonsFactory.eINSTANCE.createRuler3dToolNode(); |
| |
| if (getName() != null) { |
| toolNode.setDescription("Node associated with the Ruler3DTool named <" + getName() + ">"); |
| toolNode.setNodeId("RULER_TOOL_" + getName().replaceAll(" ", "_")); |
| } |
| |
| return toolNode; |
| } |
| |
| protected void updateFromNode(Node node, Tuple3d relativePosition, Tuple3d normal) { |
| // Update FromNode |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__FROM_NODE, node); |
| |
| if (relativePosition != null) { |
| Tuple3d newRelativePosition = EcoreUtil.copy(relativePosition); |
| |
| // Update FromRelativePosition |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__FROM_RELATIVE_POSITION, |
| newRelativePosition); |
| } |
| |
| // Update the node path. |
| NodePath nodePath = null; |
| if (node != null) { |
| Node root = ApogyCoreTopologyFacade.INSTANCE.getApogyTopology().getRootNode(); |
| nodePath = ApogyCommonTopologyFacade.INSTANCE.createNodePath(root, node); |
| } |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__FROM_NODE_NODE_PATH, nodePath); |
| |
| // Updates the ruler. |
| updateRuler(); |
| } |
| |
| protected void updateToNode(Node node, Tuple3d relativePosition, Tuple3d normal) { |
| // Update ToNode. |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__TO_NODE, node); |
| |
| if (relativePosition != null) { |
| Tuple3d newRelativePosition = EcoreUtil.copy(relativePosition); |
| |
| // Update ToRelativePosition. |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__TO_RELATIVE_POSITION, newRelativePosition); |
| } |
| |
| // Update the node path. |
| NodePath nodePath = null; |
| if (node != null) { |
| Node root = ApogyCoreTopologyFacade.INSTANCE.getApogyTopology().getRootNode(); |
| nodePath = ApogyCommonTopologyFacade.INSTANCE.createNodePath(root, node); |
| } |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__TO_NODE_NODE_PATH, nodePath); |
| |
| // Updates the ruler. |
| updateRuler(); |
| } |
| |
| protected void updateRuler() { |
| if (getFromNode() != null && getToNode() != null) { |
| if (getToAbsolutePosition() != null && getFromAbsolutePosition() != null) { |
| Point3d from = new Point3d(getFromAbsolutePosition().asTuple3d()); |
| Point3d to = new Point3d(getToAbsolutePosition().asTuple3d()); |
| |
| // Update distance |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__DISTANCE, from.distance(to)); |
| |
| return; |
| } else { |
| // Update distance to 0.0 |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__DISTANCE, 0.0); |
| |
| return; |
| } |
| } |
| |
| // Update distance to 0.0 |
| ApogyCommonTransactionFacade.INSTANCE.basicSet(this, |
| ApogyAddonsPackage.Literals.ABSTRACT_TWO_POINTS3_DTOOL__DISTANCE, 0.0); |
| } |
| |
| protected void detachRuler3dToolNode() { |
| if (getRuler3dToolNode() != null && getRuler3dToolNode().getParent() instanceof GroupNode) { |
| GroupNode parent = (GroupNode) getRuler3dToolNode().getParent(); |
| parent.getChildren().remove(getRuler3dToolNode()); |
| } |
| } |
| } // Ruler3DToolImpl |