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