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