1 package org.simantics.plant3d.actions;
3 import java.awt.event.KeyEvent;
4 import java.awt.event.MouseEvent;
5 import java.util.HashSet;
8 import javax.vecmath.Vector3d;
10 import org.eclipse.swt.widgets.Display;
11 import org.simantics.g3d.scenegraph.NodeMap;
12 import org.simantics.g3d.scenegraph.base.INode;
13 import org.simantics.g3d.vtk.action.vtkAction;
14 import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
15 import org.simantics.plant3d.Activator;
16 import org.simantics.plant3d.dialog.ComponentSelectionDialog;
17 import org.simantics.plant3d.gizmo.TerminalSelectionGizmo;
18 import org.simantics.plant3d.scenegraph.InlineComponent;
19 import org.simantics.plant3d.scenegraph.P3DRootNode;
20 import org.simantics.plant3d.scenegraph.PipeRun;
21 import org.simantics.plant3d.scenegraph.PipelineComponent;
22 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
23 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
24 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
25 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
26 import org.simantics.plant3d.utils.ComponentUtils;
27 import org.simantics.plant3d.utils.Item;
28 import org.simantics.plant3d.utils.Item.Type;
29 import org.simantics.utils.threads.AWTThread;
30 import org.simantics.utils.threads.ThreadUtils;
31 import org.simantics.utils.ui.ExceptionUtils;
35 public class AddComponentAction extends vtkAction {
38 private P3DRootNode root;
39 private PipelineComponent component;
40 private NodeMap<vtkProp,INode> nodeMap;
42 private TerminalSelectionGizmo gizmo;
44 private Set<PositionType> allowed = new HashSet<PositionType>();
46 private Item toAdd = null;
48 public AddComponentAction(InteractiveVtkPanel panel, P3DRootNode root) {
51 setText("Add Component");
52 setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Component.png"));
53 nodeMap = root.getNodeMap();
54 gizmo = new TerminalSelectionGizmo(panel);
57 public void setComponent(PipelineComponent component) {
58 this.component = component;
61 if (component.getNext() == null) {
62 allowed.add(PositionType.NEXT);
64 if (component.getPrevious() == null) {
65 allowed.add(PositionType.PREVIOUS);
67 if (component instanceof InlineComponent && !component.getControlPoint().isFixed()){
68 allowed.add(PositionType.SPLIT);
70 setEnabled(allowed.size() > 0);
73 private Double length;
75 private Double diameter;
76 private Double turnRadius;
80 ComponentSelectionDialog dialog = new ComponentSelectionDialog(Display.getCurrent().getActiveShell(), allowed);
81 if (dialog.open() == ComponentSelectionDialog.CANCEL)
83 toAdd = dialog.getSelected();
86 this.length = dialog.getLength();
87 this.angle = dialog.getAngle();
88 this.diameter = dialog.getDiameter();
89 this.turnRadius = dialog.getTurnRadius();
90 allowed = dialog.filterAllowed();
91 gizmo.setComponent(component, allowed);
97 public void keyPressed(KeyEvent e) {
98 if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
99 panel.useDefaultAction();
104 public void attach() {
105 if (component == null)
109 ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
117 public void deattach() {
126 private void attachUI() {
127 //panel.setCursor(activeCursor);
128 gizmo.attach(panel.GetRenderer());
131 private void deattachUI() {
132 //panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
137 public void mouseMoved(MouseEvent e) {
138 panel.getDefaultAction().mouseMoved(e);
142 public void mousePressed(MouseEvent e) {
143 panel.getDefaultAction().mousePressed(e);
147 public void mouseReleased(MouseEvent e) {
148 panel.getDefaultAction().mouseReleased(e);
152 public void mouseDragged(MouseEvent e) {
153 panel.getDefaultAction().mouseDragged(e);
156 public void doInsert(PositionType position) {
158 PipelineComponent newComponent = ComponentUtils.createComponent(root,toAdd.getUri());
159 PipeControlPoint newPcp = newComponent.getControlPoint();
161 PipeControlPoint toPcp = component.getControlPoint();
162 Vector3d start = new Vector3d();
163 Vector3d end = new Vector3d();
164 Vector3d dir = new Vector3d();
165 toPcp.getInlineControlPointEnds(start, end, dir);
170 if (toPcp.isDualInline())
171 toPcp = toPcp.getSubPoint().get(0);
175 if (toPcp.isDualSub())
176 toPcp = toPcp.parent;
178 PipeRun pipeRun = toPcp.getPipeRun();
180 if (!toAdd.isSizeChange()) {
181 String name = component.getPipeRun().getUniqueName(toAdd.getName());
182 newComponent.setName(name);
184 pipeRun.addChild(newComponent);
185 if (toAdd.isVariable()) {
186 // TODO: these options are not stored into DB. Should they?!
187 if (toAdd.getType() == Type.INLINE) {
188 newPcp.setLength(length);
189 // newPcp.setFixed(true);
190 } else if (toAdd.getType() == Type.TURN) {
191 newPcp.setTurnAngle(angle);
192 // newPcp.setFixed(true);
195 newComponent.updateParameters();
197 dir.scale(newComponent.getControlPoint().getLength()*0.5);
202 if (toPcp.isDualInline())
203 toPcp = toPcp.getSubPoint().get(0);
204 newPcp.insert(toPcp, Direction.NEXT);
205 newPcp.setWorldPosition(end);
208 if (toPcp.isDualSub())
209 toPcp = toPcp.parent;
210 newPcp.insert(toPcp, Direction.PREVIOUS);
211 newPcp.setWorldPosition(start);
214 PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true);
219 PipeRun other = new PipeRun();
220 String n = root.getUniqueName("PipeRun");
222 other.setPipeDiameter(diameter);
223 other.setTurnRadius(turnRadius);
224 root.addChild(other);
228 if (position == PositionType.NEXT) {
229 PipingRules.addSizeChange(false, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
230 newPcp.setWorldPosition(end);
231 } else if (position == PositionType.PREVIOUS){
232 PipingRules.addSizeChange(true, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
233 newPcp.setWorldPosition(start);
235 // TODO : chicken-egg problem
236 newComponent.updateParameters();
237 dir.scale(newComponent.getControlPoint().getLength()*0.5);
240 if (position == PositionType.NEXT) {
241 newPcp.setWorldPosition(end);
242 } else if (position == PositionType.PREVIOUS){
243 newPcp.setWorldPosition(start);
248 } catch (Exception e) {
249 ExceptionUtils.logAndShowError("Cannot add component", e);
253 public void mouseClicked(MouseEvent e) {
254 if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) {
255 int type = panel.getPickType();
256 panel.setPickType(0);
257 vtkProp[] picked = panel.pick(e.getX(), e.getY());
258 panel.setPickType(type);
259 PositionType position = gizmo.getPickedPosition(picked);
260 if (position != null) {
262 panel.useDefaultAction();
266 panel.getDefaultAction().mouseClicked(e);