]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.proconf.processeditor/src/org/simantics/processeditor/tools/ControlPointContribution.java
46ca80563359cadc7f3d8569ed6400e1f29625b2
[simantics/3d.git] / org.simantics.proconf.processeditor / src / org / simantics / processeditor / tools / ControlPointContribution.java
1 package org.simantics.processeditor.tools;\r
2 \r
3 import java.io.ByteArrayInputStream;\r
4 import java.io.ByteArrayOutputStream;\r
5 import java.net.URL;\r
6 import java.util.ArrayList;\r
7 import java.util.Collection;\r
8 import java.util.List;\r
9 \r
10 import javax.vecmath.AxisAngle4d;\r
11 import javax.vecmath.Point3d;\r
12 import javax.vecmath.Quat4d;\r
13 import javax.vecmath.Vector3d;\r
14 \r
15 import org.eclipse.core.runtime.FileLocator;\r
16 import org.eclipse.core.runtime.Path;\r
17 import org.eclipse.jface.action.IMenuManager;\r
18 import org.eclipse.jface.action.IToolBarManager;\r
19 import org.eclipse.swt.SWT;\r
20 import org.eclipse.swt.events.SelectionAdapter;\r
21 import org.eclipse.swt.events.SelectionEvent;\r
22 import org.eclipse.swt.layout.FormAttachment;\r
23 import org.eclipse.swt.layout.FormData;\r
24 import org.eclipse.swt.layout.FormLayout;\r
25 import org.eclipse.swt.layout.GridLayout;\r
26 import org.eclipse.swt.widgets.Button;\r
27 import org.eclipse.swt.widgets.Composite;\r
28 import org.simantics.db.Graph;\r
29 import org.simantics.db.GraphRequestAdapter;\r
30 import org.simantics.db.GraphRequestStatus;\r
31 import org.simantics.db.Resource;\r
32 import org.simantics.processeditor.Activator;\r
33 import org.simantics.processeditor.ProcessResource;\r
34 import org.simantics.processeditor.common.PipeComponentProvider;\r
35 import org.simantics.processeditor.stubs.DirectedControlPoint;\r
36 import org.simantics.processeditor.stubs.PipeControlPoint;\r
37 import org.simantics.proconf.g3d.actions.ContextAction;\r
38 import org.simantics.proconf.g3d.base.EditorContribution;\r
39 import org.simantics.proconf.g3d.base.G3DTools;\r
40 import org.simantics.proconf.g3d.base.MathTools;\r
41 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
42 import org.simantics.proconf.g3d.base.VecmathJmeTools;\r
43 import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
44 import org.simantics.utils.ui.ErrorLogger;\r
45 \r
46 import com.jme.renderer.ColorRGBA;\r
47 import com.jme.scene.Geometry;\r
48 import com.jme.scene.Node;\r
49 import com.jme.scene.Spatial;\r
50 import com.jme.scene.TriMesh;\r
51 import com.jme.scene.shape.Sphere;\r
52 import com.jme.scene.state.MaterialState;\r
53 import com.jme.util.export.Savable;\r
54 import com.jme.util.export.binary.BinaryImporter;\r
55 import com.jmex.model.converters.ObjToJme;\r
56 \r
57 \r
58 public class ControlPointContribution implements EditorContribution {\r
59         private List<ContextAction> actions = new ArrayList<ContextAction>();\r
60         private ThreeDimensionalEditorBase parent;\r
61         private Resource componentResource;\r
62         private Resource controlPointResource;\r
63         \r
64         private Composite sideComposite;\r
65         \r
66         private double radius = 0.2;\r
67         private double radius2 = 0.1;\r
68         private double angle = Math.PI / 4.0;\r
69         \r
70         public ControlPointContribution(ThreeDimensionalEditorBase parent) {\r
71                 this.parent = parent;\r
72         }\r
73         \r
74         @Override\r
75         public void createControl(Composite parent) {\r
76                 FormLayout flayout = new FormLayout();\r
77                 parent.setLayout(flayout);\r
78                 sideComposite = new Composite(parent,SWT.BORDER);\r
79                 FormData data = new FormData();\r
80                 data.top = new FormAttachment(0, 0);\r
81                 data.left = new FormAttachment(0, 0);\r
82                 data.right = new FormAttachment(sideComposite, 0, SWT.LEFT);\r
83                 data.bottom = new FormAttachment(100,0);\r
84                 this.parent.getRenderingComposite().setLayoutData(data);\r
85                 GridLayout layout = new GridLayout(1,false);\r
86                 layout.marginHeight = 1;\r
87                 layout.marginWidth = 1;\r
88                 sideComposite.setLayout(layout);\r
89                 data = new FormData();\r
90                 data.top = new FormAttachment(0, 0);\r
91                 data.bottom = new FormAttachment(100,0);\r
92                 data.right = new FormAttachment(100,0);\r
93                 sideComposite.setLayoutData(data);\r
94                 \r
95                 Button showCPButton = new Button(sideComposite,SWT.TOGGLE);\r
96                 showCPButton.setText("Show CtrlPts");\r
97                 showCPButton.addSelectionListener(new SelectionAdapter() {\r
98                         @Override\r
99                         public void widgetSelected(SelectionEvent e) {\r
100                                 Button b = (Button)e.widget;\r
101                                 showControlPoints(b.getSelection());\r
102                         }\r
103                 });\r
104                 \r
105                 Button addCPButton = new Button(sideComposite,SWT.PUSH);\r
106                 addCPButton.setText("Add CtrlPt");\r
107                 addCPButton.addSelectionListener(new SelectionAdapter() {\r
108                         @Override\r
109                         public void widgetSelected(SelectionEvent e) {\r
110                                 addControlPoint();\r
111                         }\r
112                 });\r
113                 \r
114                 Button removeCPButton = new Button(sideComposite,SWT.PUSH);\r
115                 removeCPButton.setText("Remove CtrlPt");\r
116                 removeCPButton.addSelectionListener(new SelectionAdapter() {\r
117                         @Override\r
118                         public void widgetSelected(SelectionEvent e) {\r
119                                 \r
120                         }\r
121                 });\r
122                 \r
123                 Button showPipesButton = new Button(sideComposite,SWT.TOGGLE);\r
124                 showPipesButton.setText("Pipes");\r
125                 showPipesButton.addSelectionListener(new SelectionAdapter() {\r
126                         @Override\r
127                         public void widgetSelected(SelectionEvent e) {\r
128                                 Button b = (Button)e.widget;\r
129                                 showPipes(b.getSelection());\r
130                         }\r
131                 });\r
132                 \r
133                 \r
134         }\r
135         \r
136         @Override\r
137         public void disposeControl() {\r
138                 sideComposite.dispose();        \r
139         }\r
140         \r
141         @Override\r
142         public void fillContextMenu(Graph graph, IMenuManager manager,\r
143                         StructuredResourceSelection selection) {\r
144 \r
145         }\r
146         \r
147         @Override\r
148         public void fillLocalPullDown(IMenuManager manager) {\r
149 \r
150         }\r
151         \r
152         @Override\r
153         public void fillLocalToolBar(IToolBarManager manager) {\r
154 \r
155         }\r
156         \r
157         @Override\r
158         public Collection<ContextAction> getActions() {\r
159                 return actions;\r
160         }\r
161         \r
162         @Override\r
163         public String getName() {\r
164                 return "Control Points";\r
165         }\r
166         \r
167         List<Node> pipes = new ArrayList<Node>();\r
168         List<Node> controlPoints = new ArrayList<Node>();\r
169         \r
170         private void showPipes(boolean show) {\r
171                 if (show) {\r
172                         if (!pipes.isEmpty()) {\r
173                                 for (Node n : pipes) {\r
174                                         n.removeFromParent();\r
175                                         n.dispose();\r
176                                 }\r
177                                 pipes.clear();\r
178                         }\r
179                         parent.getSession().asyncRead(new GraphRequestAdapter() {\r
180                                 @Override\r
181                                 public GraphRequestStatus perform(Graph g) throws Exception {\r
182                                         PipeControlPoint pcp = new PipeControlPoint(g,controlPointResource);\r
183                                         if (pcp.isInstanceOf(ProcessResource.plant3Dresource.EndComponentControlPoint)) {\r
184                                                 Node n = new Node();\r
185                                                 TriMesh mesh = new TriMesh();\r
186                                                 Point3d p1 = new Point3d(-10.0,0.0,0.0);\r
187                                                 Point3d p2 = new Point3d( 0.0,0.0,0.0);\r
188                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
189                                                 n.attachChild(mesh);\r
190                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
191                                                 pipes.add(n);\r
192                                                 \r
193                                         } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {\r
194                                                 \r
195                                                 double length = 0.5;\r
196                                                 Double d = pcp.getAtMostOneRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);\r
197                                                 if (d != null)\r
198                                                         length = d;\r
199                                                 \r
200                                                 double offset = 0.0;\r
201                                                 d = pcp.getAtMostOneRelatedScalarDouble(ProcessResource.plant3Dresource.HasOffset);\r
202                                                 if (d != null)\r
203                                                         offset = d;\r
204                                                 \r
205                                                 double r = radius;\r
206                                                 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeControlPoint)) {\r
207                                                         r = radius2;\r
208                                                 }\r
209                                                 \r
210                                                 Node n = new Node();\r
211                                                 TriMesh mesh = new TriMesh();\r
212                                                 Point3d p1 = new Point3d(-10.0,0.0,0.0);\r
213                                                 Point3d p2 = new Point3d( -length*0.5,0.0,0.0);\r
214                                                 \r
215                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
216                                                 n.attachChild(mesh);\r
217                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
218                                                 pipes.add(n);\r
219                                                 \r
220                                                 n = new Node();\r
221                                                 mesh = new TriMesh();\r
222                                                 p1 = new Point3d(10.0,offset,0.0);\r
223                                                 p2 = new Point3d(length*0.5,offset,0.0);\r
224                                                 \r
225                                                 PipeComponentProvider.createStraightGeometry(p1, p2, r, new Geometry[]{mesh});\r
226                                                 n.attachChild(mesh);\r
227                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
228                                                 pipes.add(n);   \r
229                                                 \r
230                                         } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {\r
231                                                 double length = 0.5;\r
232                                                 Double d = pcp.getAtMostOneRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);\r
233                                                 if (d != null)\r
234                                                         length = d;\r
235                                                 \r
236                                                 Node n = new Node();\r
237                                                 TriMesh mesh = new TriMesh();\r
238                                                 Point3d p1 = new Point3d(-10.0,0.0,0.0);\r
239                                                 Point3d p2 = new Point3d( -length*0.5,0.0,0.0);\r
240                                                 \r
241                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
242                                                 n.attachChild(mesh);\r
243                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
244                                                 pipes.add(n);\r
245                                                 \r
246                                                 n = new Node();\r
247                                                 mesh = new TriMesh();\r
248                                                 p1 = new Point3d(10.0,0.0,0.0);\r
249                                                 p2 = new Point3d(length*0.5,0.0,0.0);\r
250                                                 \r
251                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
252                                                 n.attachChild(mesh);\r
253                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
254                                                 pipes.add(n);\r
255                                         } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {\r
256                                                 double length = 0.5;\r
257                                                 Double d = pcp.getAtMostOneRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);\r
258                                                 if (d != null)\r
259                                                         length = d;\r
260                                                 \r
261                                                 Node n = new Node();\r
262                                                 TriMesh mesh = new TriMesh();\r
263                                                 Point3d p1 = new Point3d(-10.0,0.0,0.0);\r
264                                                 Point3d p2 = new Point3d( -length*0.5,0.0,0.0);\r
265                                                 \r
266                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
267                                                 n.attachChild(mesh);\r
268                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
269                                                 pipes.add(n);\r
270                                                 \r
271                                                 n = new Node();\r
272                                                 mesh = new TriMesh();\r
273                                                 p1 = new Point3d(10.0,0.0,0.0);\r
274                                                 p2 = new Point3d(length*0.5,0.0,0.0);\r
275                                                 Quat4d q = new Quat4d();\r
276                                                 q.set(new AxisAngle4d(0.0,1.0,0.0,angle));\r
277                                                 MathTools.rotate(q, p1, p1);\r
278                                                 MathTools.rotate(q, p2, p2);\r
279 \r
280                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
281                                                 n.attachChild(mesh);\r
282                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
283                                                 pipes.add(n);\r
284                                         } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {\r
285                                                 Node n = new Node();\r
286                                                 TriMesh mesh = new TriMesh();\r
287                                                 Point3d p1 = new Point3d(10.0,0.0,0.0);\r
288                                                 Point3d p2 = new Point3d( 0.0,0.0,0.0);\r
289                                                 PipeComponentProvider.createStraightGeometry(p1, p2, radius, new Geometry[]{mesh});\r
290                                                 n.attachChild(mesh);\r
291                                                 parent.getRenderingComponent().getShadowRoot().attachChild(n);\r
292                                                 pipes.add(n);\r
293                                         }\r
294                                         \r
295                                         if(!pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {\r
296                                                 Collection<PipeControlPoint> subPoints = pcp.getSubPoint();\r
297                                                 \r
298                                         }\r
299                                         \r
300                                         parent.setViewChanged(true);\r
301                                         return GraphRequestStatus.transactionComplete();\r
302                                 }\r
303                         });\r
304                 } else {\r
305                         if (!pipes.isEmpty()) {\r
306                                 for (Node n : pipes) {\r
307                                         n.removeFromParent();\r
308                                         n.dispose();\r
309                                 }\r
310                                 pipes.clear();\r
311                                 parent.setViewChanged(true);\r
312                         }\r
313                 }\r
314         }\r
315         \r
316         private void showControlPoints(boolean show) {\r
317                 if (show) {\r
318                         if (!controlPoints.isEmpty()) {\r
319                                 for (Node n : controlPoints) {\r
320                                         n.removeFromParent();\r
321                                         n.dispose();\r
322                                 }\r
323                                         \r
324                         }\r
325                         parent.getSession().asyncRead(new GraphRequestAdapter() {\r
326                                 @Override\r
327                                 public GraphRequestStatus perform(Graph g) throws Exception {\r
328                                         \r
329                                         PipeControlPoint pcp = new PipeControlPoint(g,controlPointResource);\r
330                                         Vector3d p = G3DTools.getVector(pcp.getWorldPosition());\r
331                                         Node n = new Node();\r
332                                         Spatial sphere = new Sphere("",5,8,0.1f);\r
333                                         n.attachChild(sphere);\r
334                                         n.setLocalTranslation(VecmathJmeTools.get(p));\r
335                                         MaterialState ms = parent.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
336                                         ms.setDiffuse(new ColorRGBA(1.f,0.f,0.f,0.f));\r
337                                         sphere.setRenderState(ms);\r
338                                         sphere.setName(Long.toString(pcp.getResource().getResourceId()));\r
339                                         parent.getRenderingComponent().getNoShadowRoot().attachChild(n);\r
340                                         controlPoints.add(n);\r
341                                         Collection<PipeControlPoint> subPoints = pcp.getSubPoint();\r
342                                         ms = parent.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
343                                         ms.setDiffuse(new ColorRGBA(0.f,1.f,0.f,0.f));\r
344                                         for (PipeControlPoint cp : subPoints) {\r
345                                                 p = G3DTools.getVector(cp.getWorldPosition());\r
346                                                 n = new Node();\r
347                                                 if (cp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {\r
348                                                         sphere = getDCPMesh();\r
349                                                         if (sphere == null)\r
350                                                                 sphere = new Sphere("",5,8,0.1f);\r
351                                                 } else {\r
352                                                         sphere = new Sphere("",5,8,0.1f);\r
353                                                 }\r
354                                                 sphere.setName(Long.toString(cp.getResource().getResourceId()));\r
355                                                 n.attachChild(sphere);\r
356                                                 n.setLocalTranslation(VecmathJmeTools.get(p));\r
357                                                 sphere.setRenderState(ms);\r
358                                                 parent.getRenderingComponent().getNoShadowRoot().attachChild(n);\r
359                                                 controlPoints.add(n);\r
360                                         }\r
361                                         parent.setViewChanged(true);\r
362                                         return GraphRequestStatus.transactionComplete();\r
363                                 }\r
364                         });\r
365                 } else {\r
366                         if (!controlPoints.isEmpty()) {\r
367                                 for (Node n : controlPoints) {\r
368                                         n.removeFromParent();\r
369                                         n.dispose();\r
370                                 }\r
371                                 parent.setViewChanged(true);\r
372                         }\r
373                 }\r
374         }\r
375         \r
376         @Override\r
377         public void initialize(Graph graph) {\r
378                 Resource modelResource = parent.getInputResource();\r
379                 Resource inverse = graph.getInverse(ProcessResource.plant3Dresource.HasGraphics);\r
380                 Collection<Resource> equipment = graph.getObjects(modelResource, inverse);\r
381                 if (equipment.size() != 1)\r
382                         throw new RuntimeException("Cannot find component for model " + modelResource);\r
383                 componentResource = equipment.iterator().next();\r
384                 Collection<Resource> pcp = graph.getObjects(componentResource, ProcessResource.plant3Dresource.HasControlPoint);\r
385                 if (pcp.size() != 1)\r
386                         throw new RuntimeException("Cannot find control point for component " + componentResource);\r
387                 controlPointResource = pcp.iterator().next();\r
388         }\r
389         \r
390         @Override\r
391         public void dispose() {\r
392                 \r
393         }\r
394         \r
395         @Override\r
396         public void run() {\r
397 \r
398         }\r
399         \r
400         private void addControlPoint() {\r
401                 parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
402                         @Override\r
403                         public GraphRequestStatus perform(Graph g) throws Exception {\r
404                                 DirectedControlPoint dcp = DirectedControlPoint.createDefault(g);\r
405                                 PipeControlPoint pcp = new PipeControlPoint(g,controlPointResource);\r
406                                 pcp.addStatement(ProcessResource.plant3Dresource.HasSubPoint, dcp);\r
407                                 return GraphRequestStatus.transactionComplete();\r
408                         }\r
409                 });\r
410         }\r
411         \r
412         private Spatial getDCPMesh() {\r
413                 try {\r
414                         ObjToJme converter=new ObjToJme();\r
415                         String file = "data/dcp.obj";\r
416                         URL objFile=FileLocator.find(Activator.getDefault().getBundle(),new Path(file),null);\r
417                         converter.setProperty("mtllib",objFile);\r
418                         ByteArrayOutputStream BO=new ByteArrayOutputStream();\r
419                         //System.out.println("Starting to convert .obj to .jme");\r
420                         converter.convert(objFile.openStream(),BO);\r
421         \r
422                         Savable s = BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));\r
423                         return (Spatial)s;\r
424                 } catch (Exception e) {\r
425                         ErrorLogger.defaultLogError(e);\r
426                         return null;\r
427                 }\r
428         }\r
429         \r
430         \r
431 }\r