]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java
Merge changes Ib176f957,I9a82db4e,Id0fdacee
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / actions / AddComponentAction.java
1 package org.simantics.plant3d.actions;
2
3 import java.awt.event.KeyEvent;
4 import java.awt.event.MouseEvent;
5 import java.awt.event.MouseWheelEvent;
6 import java.util.HashSet;
7 import java.util.Set;
8
9 import javax.vecmath.Vector3d;
10
11 import org.eclipse.swt.widgets.Display;
12 import org.simantics.g3d.scenegraph.NodeMap;
13 import org.simantics.g3d.scenegraph.base.INode;
14 import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
15 import org.simantics.g3d.vtk.swt.vtkSwtAction;
16 import org.simantics.plant3d.Activator;
17 import org.simantics.plant3d.dialog.ComponentSelectionDialog;
18 import org.simantics.plant3d.gizmo.TerminalSelectionGizmo;
19 import org.simantics.plant3d.scenegraph.InlineComponent;
20 import org.simantics.plant3d.scenegraph.Nozzle;
21 import org.simantics.plant3d.scenegraph.P3DRootNode;
22 import org.simantics.plant3d.scenegraph.PipeRun;
23 import org.simantics.plant3d.scenegraph.PipelineComponent;
24 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
25 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
26 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
27 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
28 import org.simantics.plant3d.utils.ComponentUtils;
29 import org.simantics.plant3d.utils.Item;
30 import org.simantics.plant3d.utils.Item.Type;
31 import org.simantics.utils.threads.ThreadUtils;
32 import org.simantics.utils.ui.ExceptionUtils;
33
34 import vtk.vtkProp;
35
36 public class AddComponentAction extends vtkSwtAction {
37         
38
39         private P3DRootNode root;
40         private PipelineComponent component;
41         private NodeMap<vtkProp,INode> nodeMap;
42         
43         private TerminalSelectionGizmo gizmo;
44         
45         private Set<PositionType> allowed = new HashSet<PositionType>();
46         
47         private Item toAdd = null;
48         
49         public AddComponentAction(InteractiveVtkComposite panel, P3DRootNode root) {
50                 super(panel);
51                 this.root = root;
52                 setText("Add Component");
53                 setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Component.png"));
54                 nodeMap = root.getNodeMap();
55                 gizmo = new TerminalSelectionGizmo(panel);
56         }
57         
58         public void setComponent(PipelineComponent component) {
59                 this.component = component;
60                 
61                 allowed.clear();
62                 if (component instanceof Nozzle) {
63                     if (component.getNext() == null && component.getPrevious() == null) {
64                     allowed.add(PositionType.NEXT);
65                 }  
66                 } else {
67                 if (component.getNext() == null) {
68                         allowed.add(PositionType.NEXT);
69                 }
70                 if (component.getPrevious() == null) {
71                         allowed.add(PositionType.PREVIOUS);
72                 }
73                 if (component instanceof InlineComponent && !component.getControlPoint().isFixed()){
74                         allowed.add(PositionType.SPLIT);
75                 }
76                 }
77                 setEnabled(allowed.size() > 0);
78         }
79         
80         private Double length;
81         private Double angle;
82         private Double diameter;
83         private Double turnRadius;
84         
85         @Override
86         public void run() {
87                 ComponentSelectionDialog dialog = new ComponentSelectionDialog(Display.getCurrent().getActiveShell(), allowed);
88                 if (dialog.open() == ComponentSelectionDialog.CANCEL)
89                         return;
90                 toAdd = dialog.getSelected();
91                 if (toAdd == null)
92                         return;
93                 this.length = dialog.getLength();
94                 this.angle = dialog.getAngle();
95                 this.diameter = dialog.getDiameter();
96                 this.turnRadius = dialog.getTurnRadius();
97                 allowed = dialog.filterAllowed();
98                 gizmo.setComponent(component, allowed);
99                 super.run();
100                 panel.refresh();
101         }
102         
103         @Override
104         public boolean keyPressed(KeyEvent e) {
105                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
106                         panel.useDefaultAction();
107                 return true;
108                 
109         }
110         
111         public void attach() {
112                 if (component == null)
113                         return;
114                 
115                 super.attach();
116                 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
117                         public void run() {
118                                 attachUI();
119                         }
120                 });
121                 
122         }
123         
124         public void deattach() {
125 //              deactivate();
126                 component = null;
127                 nodeMap.commit("Add component");
128                 deattachUI();
129                 super.deattach();
130                 panel.refresh();
131         }
132         
133         private void attachUI() {
134                 //panel.setCursor(activeCursor);
135                 gizmo.attach(panel);
136         }
137         
138         private void deattachUI() {
139                 //panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
140                 gizmo.deattach();
141         }
142         
143         @Override
144         public boolean mouseMoved(MouseEvent e) {
145                 return getDefaultAction().mouseMoved(e);
146         }
147         
148         @Override
149         public boolean mousePressed(MouseEvent e) {
150                 return getDefaultAction().mousePressed(e);
151         }
152
153         @Override
154         public boolean mouseReleased(MouseEvent e) {
155                 return getDefaultAction().mouseReleased(e);
156         }
157         
158         @Override
159         public boolean mouseDragged(MouseEvent e) {
160                 return getDefaultAction().mouseDragged(e);
161         }
162         
163         public void doInsert(PositionType position) {
164                 try  {
165                         PipelineComponent newComponent = ComponentUtils.createComponent(root,toAdd.getUri());
166                         PipeControlPoint newPcp = newComponent.getControlPoint();
167                         
168                         PipeControlPoint toPcp = component.getControlPoint();
169                         PipeRun pipeRun = toPcp.getPipeRun();
170                         
171                         Vector3d dir = null;
172                         Vector3d pos = null;
173                 
174                         
175                         if (toPcp.isInline()) {
176                             switch (position) {
177                     case NEXT: 
178                         if (toPcp.isDualInline())
179                             toPcp = toPcp.getSubPoint().get(0);
180                         
181                         break;
182                     case PREVIOUS:
183                         if (toPcp.isDualSub())
184                             toPcp = toPcp.parent;
185                     }
186                             Vector3d start = new Vector3d();
187                             Vector3d end = new Vector3d();
188                     dir = new Vector3d();
189                     toPcp.getInlineControlPointEnds(start, end, dir);
190                     dir.normalize();
191                     switch (position) {
192                 case NEXT:
193                     pos = new Vector3d(end);
194                     break;
195                 case PREVIOUS:
196                     pos = new Vector3d(start);
197                     break;
198                 case SPLIT:
199                     break;
200                 }
201                    
202                         } else if (toPcp.isDirected()) {
203                             dir = new Vector3d(toPcp.getDirection(Direction.NEXT));
204                             pos = new Vector3d(toPcp.getWorldPosition());
205                         } else if (toPcp.isTurn() && toPcp.isFixed()) {
206                             dir = new Vector3d(toPcp.getDirection(position == PositionType.NEXT ? Direction.NEXT : Direction.PREVIOUS));
207                 pos = new Vector3d(toPcp.getWorldPosition());
208                 Vector3d v = new Vector3d(dir);
209                 v.scale(toPcp.getInlineLength());
210                 pos.add(v);
211                         }
212                         
213                         
214                         if (!toAdd.isSizeChange()) {
215                                 String name = component.getPipeRun().getUniqueName(toAdd.getName());
216                                 newComponent.setName(name);
217
218                                 pipeRun.addChild(newComponent);
219                                 if (toAdd.isVariable()) {
220                                         // TODO: these options are not stored into DB. Should they?!
221                                         if (toAdd.getType() == Type.INLINE) {
222                                                 newPcp.setLength(length);
223 //                                              newPcp.setFixed(true);
224                                         } else if (toAdd.getType() == Type.TURN) {
225                                                 newPcp.setTurnAngle(angle);
226 //                                              newPcp.setFixed(true);
227                                         }
228                                 }
229                                 newComponent.updateParameters();
230                                 
231                             Vector3d v = new Vector3d(dir);
232                 v.scale(newComponent.getControlPoint().getInlineLength());
233                 switch (position) {
234                 case NEXT:
235                     pos.add(v);
236                     break;
237                 case PREVIOUS:
238                     pos.sub(v);
239                     break;
240                 case SPLIT:
241                     break;
242                 }
243                                 
244                                 switch (position) {
245                                 case NEXT: 
246                                         if (toPcp.isDualInline())
247                                                 toPcp = toPcp.getSubPoint().get(0);
248                                         newPcp.insert(toPcp, Direction.NEXT);
249                                         newPcp.setWorldPosition(pos);
250                                         break;
251                                 case PREVIOUS:
252                                         if (toPcp.isDualSub())
253                                                 toPcp = toPcp.parent;
254                                         newPcp.insert(toPcp, Direction.PREVIOUS);
255                                         newPcp.setWorldPosition(pos);
256                                         break;
257                                 case SPLIT:
258                                         PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true);
259                                 }
260                         } else {
261                                 PipeRun other = new PipeRun();
262                                 String n = root.getUniqueName("PipeRun");
263                                 other.setName(n);
264                                 other.setPipeDiameter(diameter);
265                                 other.setTurnRadius(turnRadius);
266                                 root.addChild(other);
267                                 
268                                 
269                                 if (position == PositionType.NEXT) {
270                                         PipingRules.addSizeChange(false, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
271                         } else if (position == PositionType.PREVIOUS){
272                                 PipingRules.addSizeChange(true, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
273                         }
274                                 newPcp.setWorldPosition(pos);
275                                 // TODO : chicken-egg problem
276                                 newComponent.updateParameters();
277                             Vector3d v = new Vector3d(dir);
278                 v.scale(newComponent.getControlPoint().getLength()*0.5);
279                 switch (position) {
280                 case NEXT:
281                     pos.add(v);
282                     break;
283                 case PREVIOUS:
284                     pos.sub(v);
285                     break;
286                 case SPLIT:
287                     break;
288                 }
289                 newPcp.setWorldPosition(pos);
290                                 
291                         }
292                         
293                         
294                 } catch (Exception e) {
295                         ExceptionUtils.logAndShowError("Cannot add component", e);
296                 }
297         }
298         
299         public boolean mouseClicked(MouseEvent e) {
300                 if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) {
301                         int type = panel.getPickType();
302                         //panel.setPickType(0);
303                         panel.setPickType(5);
304                         vtkProp[] picked = panel.pick(e.getX(), e.getY());
305                         panel.setPickType(type);
306                         PositionType position = gizmo.getPickedPosition(picked);
307
308                         if (position != null) {
309                                 doInsert(position);
310                                 panel.useDefaultAction();
311                                 return true;
312                         }
313                 } 
314                 return getDefaultAction().mouseClicked(e);
315         }
316         
317         @Override
318         public boolean mouseWheelMoved(MouseWheelEvent e) {
319             return getDefaultAction().mouseWheelMoved(e);
320         }
321 }