]> gerrit.simantics Code Review - simantics/3d.git/blob
beaf9f45a8237d4c70566e4ff32ea2941e2ad6a9
[simantics/3d.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
3  * All rights reserved. This program and the accompanying materials\r
4  * are made available under the terms of the Eclipse Public License v1.0\r
5  * which accompanies this distribution, and is available at\r
6  * http://www.eclipse.org/legal/epl-v10.html\r
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.processeditor.tools;\r
12 \r
13 import java.util.ArrayList;\r
14 import java.util.Collection;\r
15 import java.util.Iterator;\r
16 import java.util.List;\r
17 \r
18 import org.eclipse.jface.action.Action;\r
19 import org.eclipse.jface.action.IMenuManager;\r
20 import org.eclipse.jface.action.IToolBarManager;\r
21 import org.eclipse.jface.dialogs.MessageDialog;\r
22 import org.eclipse.swt.SWT;\r
23 import org.eclipse.swt.layout.FormAttachment;\r
24 import org.eclipse.swt.layout.FormData;\r
25 import org.eclipse.swt.layout.FormLayout;\r
26 import org.eclipse.swt.layout.GridData;\r
27 import org.eclipse.swt.layout.GridLayout;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.eclipse.swt.widgets.Text;\r
30 import org.simantics.db.Graph;\r
31 import org.simantics.db.GraphRequestStatus;\r
32 import org.simantics.db.Resource;\r
33 import org.simantics.layer0.utils.EntityFactory;\r
34 import org.simantics.layer0.utils.IEntity;\r
35 import org.simantics.processeditor.Activator;\r
36 import org.simantics.processeditor.ProcessResource;\r
37 import org.simantics.processeditor.actions.InsertComponentAction;\r
38 import org.simantics.processeditor.actions.InsertEquipmentAction;\r
39 import org.simantics.processeditor.actions.InsertNozzleAction;\r
40 import org.simantics.processeditor.actions.ReversePipelineAction;\r
41 import org.simantics.processeditor.actions.RoutePipeAction;\r
42 import org.simantics.processeditor.actions.TranslateElbowAction;\r
43 import org.simantics.processeditor.actions.TranslateInlineComponentAction;\r
44 import org.simantics.processeditor.actions.TranslateStraightAction;\r
45 import org.simantics.processeditor.common.ControlPointTools;\r
46 import org.simantics.processeditor.stubs.InlineComponent;\r
47 import org.simantics.processeditor.stubs.PipeControlPoint;\r
48 import org.simantics.proconf.g3d.actions.ContextAction;\r
49 import org.simantics.proconf.g3d.actions.FocusAction;\r
50 import org.simantics.proconf.g3d.actions.RemoveAction;\r
51 import org.simantics.proconf.g3d.actions.RotateAction;\r
52 import org.simantics.proconf.g3d.actions.TranslateAction;\r
53 import org.simantics.proconf.g3d.base.EditorContribution;\r
54 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
55 import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
56 import org.simantics.utils.ui.jface.MenuTools;\r
57 \r
58 import com.jme.intersection.CollisionData;\r
59 import com.jme.intersection.CollisionResults;\r
60 import com.jme.intersection.TriangleCollisionResults;\r
61 import com.jme.scene.Geometry;\r
62 import com.jme.scene.Node;\r
63 import com.jme.scene.Spatial;\r
64 \r
65 \r
66 public class PlantEditContribution implements EditorContribution {\r
67         private List<ContextAction> actions = new ArrayList<ContextAction>();\r
68         private ThreeDimensionalEditorBase parent;\r
69         private Composite infoComposite;\r
70         private Text infoText;\r
71         \r
72         private Action checkInterferencesAction = null;\r
73         \r
74         public PlantEditContribution(ThreeDimensionalEditorBase parent) {\r
75                 this.parent = parent;\r
76         }\r
77         \r
78         @Override\r
79         public void createControl(Composite parent) {\r
80                 FormLayout flayout = new FormLayout();\r
81                 parent.setLayout(flayout);\r
82                 infoComposite = new Composite(parent, SWT.BORDER);\r
83                 FormData data = new FormData();\r
84                 data.top = new FormAttachment(0, 0);\r
85                 data.left = new FormAttachment(0, 0);\r
86                 data.right = new FormAttachment(100, 0);\r
87                 data.bottom = new FormAttachment(infoComposite, 0, SWT.TOP);\r
88                 this.parent.getRenderingComposite().setLayoutData(data);\r
89                 data = new FormData();\r
90                 data.left = new FormAttachment(0, 0);\r
91                 data.right = new FormAttachment(100, 0);\r
92                 data.bottom = new FormAttachment(100, 0);\r
93                 data.height = 18;\r
94                 infoComposite.setLayoutData(data);\r
95                 GridLayout layout = new GridLayout(1,false);\r
96                 layout.marginWidth = 1;\r
97                 layout.marginHeight = 1;\r
98                 infoComposite.setLayout(layout);\r
99                 infoText = new Text(infoComposite, SWT.NONE);\r
100                 GridData gdata = new GridData();\r
101                 gdata.grabExcessHorizontalSpace = true;\r
102                 gdata.horizontalAlignment = SWT.FILL;\r
103                 infoText.setLayoutData(gdata);\r
104                 \r
105         }\r
106         \r
107         @Override\r
108         public void disposeControl() {\r
109                 infoComposite.dispose();\r
110                 \r
111         }\r
112         \r
113         @Override\r
114         public void dispose() {\r
115 \r
116         }\r
117         \r
118         \r
119         \r
120         @Override\r
121         public void fillContextMenu(Graph graph, IMenuManager manager,\r
122                         StructuredResourceSelection selection) {\r
123 \r
124         }\r
125         \r
126         @Override\r
127         public void fillLocalPullDown(IMenuManager manager) {\r
128                 MenuTools.getOrCreate(parent.getMenuID(),"Advanced", manager).add(checkInterferencesAction);\r
129                 \r
130         }\r
131         \r
132         @Override\r
133         public void fillLocalToolBar(IToolBarManager manager) {\r
134 \r
135         }\r
136         \r
137         @Override\r
138         public Collection<ContextAction> getActions() {\r
139                 return actions;\r
140         }\r
141         \r
142         @Override\r
143         public String getName() {\r
144                 return "Plant Editing";\r
145         }\r
146         \r
147         @Override\r
148         public void initialize(Graph graph) {\r
149                 actions.add(new TranslateAction(parent){\r
150             @Override\r
151             public boolean usable(Graph graph,List<Resource> resources) {\r
152                 if (super.usable(graph, resources)) {\r
153                     for (Resource r : resources) {\r
154                         // FIXME : use new ontology :\r
155                         // 1. lose ends works like end components (just what this code does, but type checks are not correct)\r
156                         // 2. connected components are moved inline. (TranslateInlineAction)\r
157                         IEntity t = EntityFactory.create(graph, r);\r
158                         if (t.isInstanceOf(ProcessResource.plant3Dresource.InlineComponent)) {\r
159                             InlineComponent component = new InlineComponent(t);\r
160                                 PipeControlPoint pcp = component.getControlPoint();\r
161                                 if (pcp.getNext() != null && pcp.getPrevious() != null)\r
162                                         return false;\r
163                         }\r
164                     }\r
165                     return true;\r
166                 }\r
167                 return false;\r
168             }\r
169             \r
170             @Override\r
171             public void setInfoText(String text) {\r
172                 infoText.setText(text);\r
173             }\r
174         });\r
175         actions.add(new TranslateInlineComponentAction(parent) {\r
176                 @Override\r
177                 public void setInfoText(String text) {\r
178                         infoText.setText(text);\r
179                 }\r
180         });\r
181         actions.add(new TranslateStraightAction(parent) {\r
182                 @Override\r
183                 public void setInfoText(String text) {\r
184                         infoText.setText(text);\r
185                 }\r
186         });\r
187         actions.add(new TranslateElbowAction(parent) {\r
188                 @Override\r
189                 public void setInfoText(String text) {\r
190                         infoText.setText(text);\r
191                 }\r
192         });\r
193         actions.add(new RotateAction(parent){\r
194             @Override\r
195             public boolean usable(Graph graph,List<Resource> resources) {\r
196                 if (super.usable(graph,resources)) {\r
197                     for (Resource r : resources) {\r
198                         IEntity t = EntityFactory.create(graph,r);\r
199                         // FIXME : use new ontology\r
200                         // TODO : create rotate action that can rotate inline components\r
201                         // TODO : ontology change: pipes and similar components cannot be rotated, since there is no point to do that.\r
202                         if (t.isInstanceOf(ProcessResource.plant3Dresource.InlineComponent)) {\r
203                                 return false;\r
204                         }\r
205                     }\r
206                     return true;\r
207                 }\r
208                 \r
209                 return false;\r
210             }\r
211             \r
212             @Override\r
213             public void setInfoText(String text) {\r
214                 infoText.setText(text);\r
215             }\r
216         });\r
217         actions.add(new RemoveAction(parent) {\r
218                 @Override\r
219                         public GraphRequestStatus doChanges(Graph graph) {\r
220                                 Iterator<Resource> i = parent.getSelectionAdapter().getCurrentSelection().iterator();\r
221                                 while (i.hasNext()) {\r
222                                                 Resource s = i.next();\r
223                                                 IEntity r = EntityFactory.create(graph, s);\r
224                                                 if (r.isInstanceOf(ProcessResource.g3dResource.G3DNode)) {\r
225                                                         Collection<IEntity> parentNode= r.getRelatedObjects(ProcessResource.g3dResource.HasParent);\r
226                                                         if (parentNode.size() == 1) {\r
227                                                                 Collection<IEntity> rs = r.getRelatedObjects(ProcessResource.plant3Dresource.HasControlPoint);\r
228                                                                 for (IEntity cp  : rs) {\r
229                                                                         ControlPointTools.removeControlPoint(new PipeControlPoint(cp));\r
230                                                                 }\r
231                                                                 r.removeRelatedStatements(ProcessResource.g3dResource.HasParent);\r
232                                                         } else {\r
233                                                                 if (parentNode.size() == 0) {\r
234                                                                         parent.showMessage("Object has no parent, don't know what to do!");\r
235                                                                 } else {\r
236                                                                         parent.showMessage("Object has more than one parent, don't know what to do!");\r
237                                                                 }\r
238                                                         }\r
239                                                 }\r
240 \r
241                                         }\r
242                                         //parent.getSelectionAdapter().setSelection(new StructuredResourceSelection());\r
243                                 return GraphRequestStatus.transactionComplete();\r
244                         }\r
245                 });\r
246         actions.add(new FocusAction(parent));\r
247         actions.add(new RoutePipeAction(parent){\r
248                 @Override\r
249                 public void setInfoText(String text) {\r
250                         infoText.setText(text);\r
251                 }\r
252         });   \r
253         actions.add(new InsertComponentAction(parent));\r
254         actions.add(new InsertEquipmentAction(parent));\r
255         actions.add(new InsertNozzleAction(parent));\r
256         actions.add(new ReversePipelineAction(parent));\r
257         \r
258         checkInterferencesAction = new Action() {\r
259                 public void run() {\r
260                         CollisionResults results = new TriangleCollisionResults();\r
261                         //getRenderingComponent().getNormalRoot().calculateCollisions(getRenderingComponent().getNormalRoot(), results);\r
262                         collide(parent.getRenderingComponent().getShadowRoot(),parent.getRenderingComponent().getShadowRoot(),results);\r
263                         results = filterResults(results);\r
264                         for (int i = 0; i < results.getNumber(); i++) {\r
265                                 CollisionData data = results.getCollisionData(i);\r
266                                 Geometry s =  data.getSourceMesh();\r
267                                 Geometry t = data.getTargetMesh();\r
268                                 MessageDialog dialog = new MessageDialog(parent.getRenderingComposite().getShell(),"Interference " + i + " / " + results.getNumber(), null, "Interference between " + s + " and " + t,MessageDialog.WARNING,new String[]{"Next","Cancel"},0);\r
269                                 try {\r
270                                         Resource sid = parent.getScenegraphAdapter().getNodeResource(s.getName());\r
271                                         Resource tid = parent.getScenegraphAdapter().getNodeResource(t.getName());\r
272 \r
273                                         StructuredResourceSelection sel = new StructuredResourceSelection();\r
274                                         if (sid == tid) {\r
275                                                 sel.add(sid);\r
276                                         } else {\r
277                                                 sel.add(sid);\r
278                                                 sel.add(tid);\r
279                                         }\r
280                                         parent.getSelectionAdapter().setSelection(sel);\r
281                                 } catch(NumberFormatException e) {\r
282                                         \r
283                                 }\r
284                                 if (dialog.open() == 1)\r
285                                         break;\r
286                         }\r
287                 }\r
288                 \r
289                 private void collide(Spatial s, Spatial p, CollisionResults r) {\r
290                         s.calculateCollisions(p, r);\r
291                         if (s instanceof Node) {\r
292                                 Node n = (Node)s;\r
293                                 for (Spatial t : n.getChildren())\r
294                                         collide(t,p,r);\r
295                         }\r
296                 }\r
297                 \r
298                 private CollisionResults filterResults(CollisionResults results) {\r
299                         CollisionResults r = new TriangleCollisionResults();\r
300                         for (int i = 0; i < results.getNumber(); i++) {\r
301                                 CollisionData d = results.getCollisionData(i);\r
302                                 if (d.getSourceMesh() == d.getTargetMesh())\r
303                                         continue;\r
304                                 boolean found = false;\r
305                                 for (int j = 0; j < r.getNumber(); j++) {\r
306                                         CollisionData d2 = r.getCollisionData(j);\r
307                                         if (d2.getSourceMesh() == d.getSourceMesh() &&\r
308                                                 d2.getTargetMesh() == d.getTargetMesh()) {\r
309                                                 found = true;\r
310                                                 break;\r
311                                         }\r
312                                         if (d2.getSourceMesh() == d.getTargetMesh() &&\r
313                                         d2.getTargetMesh() == d.getSourceMesh()) {\r
314                                         found = true;\r
315                                         break;\r
316                                 }               \r
317                                 }\r
318                                 if (!found) {\r
319                                         if (d.getSourceTris().size() == 0)\r
320                                                 continue;\r
321                                         if (d.getTargetTris().size() == 0)\r
322                                                 continue;\r
323                                         r.addCollisionData(d);\r
324                                 }\r
325                         }\r
326                         return r;\r
327                 }\r
328 \r
329         };\r
330         checkInterferencesAction.setText("Interferences");\r
331         checkInterferencesAction.setImageDescriptor(Activator.imageDescriptorFromPlugin("fi.vtt.proconf.ode", "icons/silk/delete.png"));\r
332         \r
333         }\r
334         \r
335         @Override\r
336         public void run() {\r
337                 \r
338         }\r
339 \r
340 }\r