]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
latest release (0.41), third attempt
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 29 Sep 2008 11:10:38 +0000 (11:10 +0000)
committerluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 29 Sep 2008 11:10:38 +0000 (11:10 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/3d/trunk@6850 ac1ea38d-2e2b-0410-8846-a27921b304fc

39 files changed:
org.simantics.proconf.g3d.shapeeditor/.classpath [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/.project [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/META-INF/MANIFEST.MF [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/build.properties [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/difference.png [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/difference.svg [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/intersection.png [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/intersection.svg [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/link.png [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/link.svg [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/union.png [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/union.svg [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/unlink.png [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/icons/unlink.svg [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/plugin.xml [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/Activator.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/ShapeEditorResources.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ExportAction.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ImportAction.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFileAction.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFolderAction.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/common/ViewpointGenerator.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/dialogs/PropertySelectionDialog.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectAdapter.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectType.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/NewCSGModelHandler.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter1.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter3.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/perspectives/CSGModellingPerspective.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/scenegraph/CSGShapeNode.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/AnimationContribution.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/CSGModellingContribution.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/ParameterizationContribution.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/CSGModellingView.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorBase.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorView.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureOutlinePage.java [new file with mode: 0644]
org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureView.java [new file with mode: 0644]

diff --git a/org.simantics.proconf.g3d.shapeeditor/.classpath b/org.simantics.proconf.g3d.shapeeditor/.classpath
new file mode 100644 (file)
index 0000000..0215967
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/.project b/org.simantics.proconf.g3d.shapeeditor/.project
new file mode 100644 (file)
index 0000000..875413f
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.proconf.g3d.shapeeditor</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/META-INF/MANIFEST.MF b/org.simantics.proconf.g3d.shapeeditor/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..332d852
--- /dev/null
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Shapeeditor Plug-in
+Bundle-SymbolicName: org.simantics.proconf.g3d.shapeeditor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.simantics.proconf.g3d.shapeeditor.Activator
+Bundle-Vendor: VTT
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.views.properties.tabbed,
+ com.jme.eclipse,
+ javax.vecmath,
+ org.jcae.opencascade.jni,
+ org.simantics.proconf.g3d,
+ org.simantics.image.stubs,
+ org.simantics.layer0.stubs,
+ org.simantics.layer0.utils,
+ org.simantics.g2d.stubs,
+ org.simantics.utils,
+ org.simantics.proconf.g3d.occ,
+ org.simantics.proconf.ui,
+ org.simantics.animation,
+ org.simantics.proconf.ode,
+ org.simantics.utils.ui,
+ org.simantics.equation,
+ org.simantics.db,
+ org.simantics.utils.ui.workbench,
+ org.simantics.proconf.browsing,
+ org.simantics.db.services,
+ org.simantics.proconf.g3d.csg
+Eclipse-LazyStart: true
+Export-Package: org.simantics.proconf.g3d.shapeeditor.views
diff --git a/org.simantics.proconf.g3d.shapeeditor/build.properties b/org.simantics.proconf.g3d.shapeeditor/build.properties
new file mode 100644 (file)
index 0000000..6f20375
--- /dev/null
@@ -0,0 +1,5 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               plugin.xml\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/difference.png b/org.simantics.proconf.g3d.shapeeditor/icons/difference.png
new file mode 100644 (file)
index 0000000..d7b2747
Binary files /dev/null and b/org.simantics.proconf.g3d.shapeeditor/icons/difference.png differ
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/difference.svg b/org.simantics.proconf.g3d.shapeeditor/icons/difference.svg
new file mode 100644 (file)
index 0000000..d358465
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
+<svg\r
+   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
+   xmlns:cc="http://web.resource.org/cc/"\r
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+   xmlns:svg="http://www.w3.org/2000/svg"\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
+   width="744.09448819"\r
+   height="1052.3622047"\r
+   id="svg2"\r
+   sodipodi:version="0.32"\r
+   inkscape:version="0.44"\r
+   sodipodi:docbase="D:\työt"\r
+   sodipodi:docname="difference.svg"\r
+   inkscape:export-filename="D:\työt\difference.png"\r
+   inkscape:export-xdpi="4.612184"\r
+   inkscape:export-ydpi="4.612184">\r
+  <defs\r
+     id="defs4" />\r
+  <sodipodi:namedview\r
+     id="base"\r
+     pagecolor="#ffffff"\r
+     bordercolor="#666666"\r
+     borderopacity="1.0"\r
+     gridtolerance="10000"\r
+     guidetolerance="10"\r
+     objecttolerance="10"\r
+     inkscape:pageopacity="0.0"\r
+     inkscape:pageshadow="2"\r
+     inkscape:zoom="2.5664702"\r
+     inkscape:cx="171.53487"\r
+     inkscape:cy="890.09888"\r
+     inkscape:document-units="px"\r
+     inkscape:current-layer="layer1"\r
+     showgrid="true"\r
+     inkscape:window-width="1280"\r
+     inkscape:window-height="968"\r
+     inkscape:window-x="-4"\r
+     inkscape:window-y="-4" />\r
+  <metadata\r
+     id="metadata7">\r
+    <rdf:RDF>\r
+      <cc:Work\r
+         rdf:about="">\r
+        <dc:format>image/svg+xml</dc:format>\r
+        <dc:type\r
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
+      </cc:Work>\r
+    </rdf:RDF>\r
+  </metadata>\r
+  <g\r
+     inkscape:label="Layer 1"\r
+     inkscape:groupmode="layer"\r
+     id="layer1">\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:navy;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1876"\r
+       width="303.06973"\r
+       height="299.80225"\r
+       x="20"\r
+       y="12.362183" />\r
+    <path\r
+       style="fill:lime;fill-opacity:1;stroke:none;stroke-width:27.12068065;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:27.12068065,54.2413613;stroke-dashoffset:0;stroke-opacity:1"\r
+       d="M 130.1875 26 C 73.425961 26 27.343749 73.576037 27.34375 132.21875 C 27.34375 187.17447 67.823401 232.43322 119.625 237.90625 L 119.625 110.625 L 230.875 110.625 C 221.21132 62.322879 179.78947 26 130.1875 26 z "\r
+       id="path14325" />\r
+    <path\r
+       sodipodi:type="arc"\r
+       style="fill:none;fill-opacity:1;stroke:blue;stroke-width:27.12068065;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:27.12068065,54.2413613;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="path9884"\r
+       sodipodi:cx="113.82415"\r
+       sodipodi:cy="116.55048"\r
+       sodipodi:rx="86.560883"\r
+       sodipodi:ry="90.650368"\r
+       d="M 200.38503 116.55048 A 86.560883 90.650368 0 1 1  27.263268,116.55048 A 86.560883 90.650368 0 1 1  200.38503 116.55048 z"\r
+       transform="matrix(1.187937,0,0,1.17194,-5.033825,-4.36331)" />\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:red;stroke-width:32;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:32,64;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1880"\r
+       width="181.57614"\r
+       height="182.39815"\r
+       x="119.61777"\r
+       y="110.61679" />\r
+  </g>\r
+</svg>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/intersection.png b/org.simantics.proconf.g3d.shapeeditor/icons/intersection.png
new file mode 100644 (file)
index 0000000..95915d3
Binary files /dev/null and b/org.simantics.proconf.g3d.shapeeditor/icons/intersection.png differ
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/intersection.svg b/org.simantics.proconf.g3d.shapeeditor/icons/intersection.svg
new file mode 100644 (file)
index 0000000..d12d668
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
+<svg\r
+   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
+   xmlns:cc="http://web.resource.org/cc/"\r
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+   xmlns:svg="http://www.w3.org/2000/svg"\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
+   width="744.09448819"\r
+   height="1052.3622047"\r
+   id="svg2"\r
+   sodipodi:version="0.32"\r
+   inkscape:version="0.44"\r
+   sodipodi:docbase="D:\työt"\r
+   sodipodi:docname="intersection.svg"\r
+   inkscape:export-filename="D:\työt\union.png"\r
+   inkscape:export-xdpi="4.7871981"\r
+   inkscape:export-ydpi="4.7871981">\r
+  <defs\r
+     id="defs4" />\r
+  <sodipodi:namedview\r
+     id="base"\r
+     pagecolor="#ffffff"\r
+     bordercolor="#666666"\r
+     borderopacity="1.0"\r
+     gridtolerance="10000"\r
+     guidetolerance="10"\r
+     objecttolerance="10"\r
+     inkscape:pageopacity="0.0"\r
+     inkscape:pageshadow="2"\r
+     inkscape:zoom="2.5664702"\r
+     inkscape:cx="171.53487"\r
+     inkscape:cy="890.09888"\r
+     inkscape:document-units="px"\r
+     inkscape:current-layer="layer1"\r
+     showgrid="true"\r
+     inkscape:window-width="1280"\r
+     inkscape:window-height="968"\r
+     inkscape:window-x="-4"\r
+     inkscape:window-y="-4" />\r
+  <metadata\r
+     id="metadata7">\r
+    <rdf:RDF>\r
+      <cc:Work\r
+         rdf:about="">\r
+        <dc:format>image/svg+xml</dc:format>\r
+        <dc:type\r
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
+      </cc:Work>\r
+    </rdf:RDF>\r
+  </metadata>\r
+  <g\r
+     inkscape:label="Layer 1"\r
+     inkscape:groupmode="layer"\r
+     id="layer1">\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:navy;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1876"\r
+       width="303.06973"\r
+       height="299.80225"\r
+       x="20"\r
+       y="12.362183" />\r
+    <path\r
+       style="fill:lime;fill-opacity:1;stroke:none;stroke-width:32;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:32,64;stroke-dashoffset:0;stroke-opacity:1"\r
+       d="M 119.625 110.625 L 119.625 237.90625 C 123.10038 238.27344 126.61878 238.46875 130.1875 238.46875 C 186.94904 238.46875 233 190.86146 233 132.21875 C 233 124.82191 232.26986 117.59694 230.875 110.625 L 119.625 110.625 z "\r
+       id="rect13432" />\r
+    <path\r
+       sodipodi:type="arc"\r
+       style="fill:none;fill-opacity:1;stroke:blue;stroke-width:27.12068065;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:27.12068065,54.2413613;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="path9884"\r
+       sodipodi:cx="113.82415"\r
+       sodipodi:cy="116.55048"\r
+       sodipodi:rx="86.560883"\r
+       sodipodi:ry="90.650368"\r
+       d="M 200.38503 116.55048 A 86.560883 90.650368 0 1 1  27.263268,116.55048 A 86.560883 90.650368 0 1 1  200.38503 116.55048 z"\r
+       transform="matrix(1.187937,0,0,1.17194,-5.033825,-4.36331)" />\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:red;stroke-width:32;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:32,64;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1880"\r
+       width="181.57614"\r
+       height="182.39815"\r
+       x="119.61777"\r
+       y="110.61679" />\r
+  </g>\r
+</svg>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/link.png b/org.simantics.proconf.g3d.shapeeditor/icons/link.png
new file mode 100644 (file)
index 0000000..b8ac73c
Binary files /dev/null and b/org.simantics.proconf.g3d.shapeeditor/icons/link.png differ
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/link.svg b/org.simantics.proconf.g3d.shapeeditor/icons/link.svg
new file mode 100644 (file)
index 0000000..2ad1a0a
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="100"
+   height="100"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44"
+   version="1.0"
+   sodipodi:docname="link.svg"
+   sodipodi:docbase="D:\dev\icons"
+   inkscape:export-filename="D:\dev\icons\link.png"
+   inkscape:export-xdpi="14.4"
+   inkscape:export-ydpi="14.4">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient4583">
+      <stop
+         style="stop-color:#0049ff;stop-opacity:1;"
+         offset="0"
+         id="stop4585" />
+      <stop
+         style="stop-color:#00b3b3;stop-opacity:1;"
+         offset="1"
+         id="stop4587" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3686">
+      <stop
+         style="stop-color:red;stop-opacity:0;"
+         offset="0"
+         id="stop3688" />
+      <stop
+         style="stop-color:red;stop-opacity:1;"
+         offset="1"
+         id="stop3690" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3133">
+      <stop
+         style="stop-color:#4c4c4c;stop-opacity:1;"
+         offset="0"
+         id="stop3135" />
+      <stop
+         id="stop3141"
+         offset="0.5"
+         style="stop-color:#cbcbcb;stop-opacity:1;" />
+      <stop
+         style="stop-color:#4c4c4c;stop-opacity:1;"
+         offset="1"
+         id="stop3137" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="7.72"
+     inkscape:cx="50"
+     inkscape:cy="55.181347"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     width="100px"
+     height="100px"
+     inkscape:window-width="1280"
+     inkscape:window-height="968"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       sodipodi:type="arc"
+       style="fill:none;fill-opacity:1;stroke:#fd2306;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path3660"
+       sodipodi:cx="45.142487"
+       sodipodi:cy="45.272022"
+       sodipodi:rx="7.7072539"
+       sodipodi:ry="7.9663215"
+       d="M 52.849741 45.272022 A 7.7072539 7.9663215 0 1 1  37.435233,45.272022 A 7.7072539 7.9663215 0 1 1  52.849741 45.272022 z"
+       transform="translate(-3.238342,-1.813472)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:none;fill-opacity:1;stroke:#fd2306;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path4547"
+       sodipodi:cx="45.142487"
+       sodipodi:cy="45.272022"
+       sodipodi:rx="7.7072539"
+       sodipodi:ry="7.9663215"
+       d="M 52.849741 45.272022 A 7.7072539 7.9663215 0 1 1  37.435233,45.272022 A 7.7072539 7.9663215 0 1 1  52.849741 45.272022 z"
+       transform="translate(4.468912,7.189118)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:none;fill-opacity:1;stroke:#fd2306;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path4549"
+       sodipodi:cx="45.142487"
+       sodipodi:cy="45.272022"
+       sodipodi:rx="7.7072539"
+       sodipodi:ry="7.9663215"
+       d="M 52.849741 45.272022 A 7.7072539 7.9663215 0 1 1  37.435233,45.272022 A 7.7072539 7.9663215 0 1 1  52.849741 45.272022 z"
+       transform="translate(12.37046,15.60881)" />
+    <rect
+       style="fill:#009bff;fill-opacity:1;stroke:#009aff;stroke-width:1.72972977;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1886"
+       width="30.270269"
+       height="30.270269"
+       x="9.8648653"
+       y="9.8648653" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#2fc82f;fill-opacity:1;stroke:#2fc82f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path1884"
+       sodipodi:cx="72.5"
+       sodipodi:cy="72.5"
+       sodipodi:rx="17.5"
+       sodipodi:ry="17.5"
+       d="M 90 72.5 A 17.5 17.5 0 1 1  55,72.5 A 17.5 17.5 0 1 1  90 72.5 z" />
+  </g>
+</svg>
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/union.png b/org.simantics.proconf.g3d.shapeeditor/icons/union.png
new file mode 100644 (file)
index 0000000..7ffeedb
Binary files /dev/null and b/org.simantics.proconf.g3d.shapeeditor/icons/union.png differ
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/union.svg b/org.simantics.proconf.g3d.shapeeditor/icons/union.svg
new file mode 100644 (file)
index 0000000..9f64f67
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
+<svg\r
+   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
+   xmlns:cc="http://web.resource.org/cc/"\r
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+   xmlns:svg="http://www.w3.org/2000/svg"\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
+   width="744.09448819"\r
+   height="1052.3622047"\r
+   id="svg2"\r
+   sodipodi:version="0.32"\r
+   inkscape:version="0.44"\r
+   sodipodi:docbase="D:\työt"\r
+   sodipodi:docname="union.svg"\r
+   inkscape:export-filename="D:\työt\union.png"\r
+   inkscape:export-xdpi="4.612184"\r
+   inkscape:export-ydpi="4.612184">\r
+  <defs\r
+     id="defs4" />\r
+  <sodipodi:namedview\r
+     id="base"\r
+     pagecolor="#ffffff"\r
+     bordercolor="#666666"\r
+     borderopacity="1.0"\r
+     gridtolerance="10000"\r
+     guidetolerance="10"\r
+     objecttolerance="10"\r
+     inkscape:pageopacity="0.0"\r
+     inkscape:pageshadow="2"\r
+     inkscape:zoom="2.5664702"\r
+     inkscape:cx="171.53487"\r
+     inkscape:cy="890.09888"\r
+     inkscape:document-units="px"\r
+     inkscape:current-layer="layer1"\r
+     showgrid="true"\r
+     inkscape:window-width="1280"\r
+     inkscape:window-height="968"\r
+     inkscape:window-x="-4"\r
+     inkscape:window-y="-4" />\r
+  <metadata\r
+     id="metadata7">\r
+    <rdf:RDF>\r
+      <cc:Work\r
+         rdf:about="">\r
+        <dc:format>image/svg+xml</dc:format>\r
+        <dc:type\r
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
+      </cc:Work>\r
+    </rdf:RDF>\r
+  </metadata>\r
+  <g\r
+     inkscape:label="Layer 1"\r
+     inkscape:groupmode="layer"\r
+     id="layer1">\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:navy;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1876"\r
+       width="303.06973"\r
+       height="299.80225"\r
+       x="20"\r
+       y="12.362183" />\r
+    <path\r
+       style="fill:lime;fill-opacity:1;stroke:blue;stroke-width:3.39008508;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"\r
+       d="M 130.1875 26 C 73.425961 26 27.343749 73.576037 27.34375 132.21875 C 27.34375 187.17447 67.823401 232.43322 119.625 237.90625 L 119.625 293 L 301.1875 293 L 301.1875 110.625 L 230.875 110.625 C 221.21132 62.322879 179.78947 26 130.1875 26 z "\r
+       id="path1878" />\r
+    <path\r
+       sodipodi:type="arc"\r
+       style="fill:none;fill-opacity:1;stroke:blue;stroke-width:27.12068065;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:27.12068065,54.2413613;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="path9884"\r
+       sodipodi:cx="113.82415"\r
+       sodipodi:cy="116.55048"\r
+       sodipodi:rx="86.560883"\r
+       sodipodi:ry="90.650368"\r
+       d="M 200.38503 116.55048 A 86.560883 90.650368 0 1 1  27.263268,116.55048 A 86.560883 90.650368 0 1 1  200.38503 116.55048 z"\r
+       transform="matrix(1.187937,0,0,1.17194,-5.033825,-4.36331)" />\r
+    <rect\r
+       style="fill:none;fill-opacity:1;stroke:red;stroke-width:32;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:32,64;stroke-dashoffset:0;stroke-opacity:1"\r
+       id="rect1880"\r
+       width="181.57614"\r
+       height="182.39815"\r
+       x="119.61777"\r
+       y="110.61679" />\r
+  </g>\r
+</svg>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/unlink.png b/org.simantics.proconf.g3d.shapeeditor/icons/unlink.png
new file mode 100644 (file)
index 0000000..5db0efc
Binary files /dev/null and b/org.simantics.proconf.g3d.shapeeditor/icons/unlink.png differ
diff --git a/org.simantics.proconf.g3d.shapeeditor/icons/unlink.svg b/org.simantics.proconf.g3d.shapeeditor/icons/unlink.svg
new file mode 100644 (file)
index 0000000..ca82a54
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="100"
+   height="100"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.44"
+   version="1.0"
+   sodipodi:docname="unlink.svg"
+   sodipodi:docbase="D:\dev\icons"
+   inkscape:export-filename="D:\dev\icons\unlink.png"
+   inkscape:export-xdpi="14.4"
+   inkscape:export-ydpi="14.4">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient4583">
+      <stop
+         style="stop-color:#0049ff;stop-opacity:1;"
+         offset="0"
+         id="stop4585" />
+      <stop
+         style="stop-color:#00b3b3;stop-opacity:1;"
+         offset="1"
+         id="stop4587" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3686">
+      <stop
+         style="stop-color:red;stop-opacity:0;"
+         offset="0"
+         id="stop3688" />
+      <stop
+         style="stop-color:red;stop-opacity:1;"
+         offset="1"
+         id="stop3690" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3133">
+      <stop
+         style="stop-color:#4c4c4c;stop-opacity:1;"
+         offset="0"
+         id="stop3135" />
+      <stop
+         id="stop3141"
+         offset="0.5"
+         style="stop-color:#cbcbcb;stop-opacity:1;" />
+      <stop
+         style="stop-color:#4c4c4c;stop-opacity:1;"
+         offset="1"
+         id="stop3137" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="7.72"
+     inkscape:cx="50"
+     inkscape:cy="55.181347"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     width="100px"
+     height="100px"
+     inkscape:window-width="1280"
+     inkscape:window-height="968"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       sodipodi:type="arc"
+       style="fill:none;fill-opacity:1;stroke:#fd2306;stroke-width:4.10961773;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:4.10961773,4.10961773;stroke-dashoffset:4.10961773;stroke-opacity:1"
+       id="path4549"
+       sodipodi:cx="45.142487"
+       sodipodi:cy="45.272022"
+       sodipodi:rx="7.7072539"
+       sodipodi:ry="7.9663215"
+       d="M 52.849741 45.272022 A 7.7072539 7.9663215 0 1 1  37.435233,45.272022 A 7.7072539 7.9663215 0 1 1  52.849741 45.272022 z"
+       transform="matrix(2.507716,0,0,2.361124,-67.73823,-58.31771)" />
+    <rect
+       style="fill:#0052ff;fill-opacity:1;stroke:#0052ff;stroke-width:1.93978441;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect1886"
+       width="33.946224"
+       height="33.946224"
+       x="9.9698925"
+       y="9.9698925" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#2faa2f;fill-opacity:1;stroke:#2fab2f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="path1884"
+       sodipodi:cx="72.5"
+       sodipodi:cy="72.5"
+       sodipodi:rx="17.5"
+       sodipodi:ry="17.5"
+       d="M 90 72.5 A 17.5 17.5 0 1 1  55,72.5 A 17.5 17.5 0 1 1  90 72.5 z"
+       transform="matrix(1.133035,0,0,1.133035,-12.10615,-12.10615)" />
+  </g>
+</svg>
diff --git a/org.simantics.proconf.g3d.shapeeditor/plugin.xml b/org.simantics.proconf.g3d.shapeeditor/plugin.xml
new file mode 100644 (file)
index 0000000..e54575c
--- /dev/null
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?eclipse version="3.2"?>\r
+<plugin>\r
+   <extension\r
+         point="org.eclipse.ui.commands">\r
+      <command\r
+            categoryId="org.simantics.proconf.shapeeditor.commands"\r
+            description="New CSG-Model"\r
+            id="org.simantics.proconf.shapeeditor.commands.newCSG"\r
+            name="New CSG-Model">\r
+      </command>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.handlers">\r
+      <handler\r
+            class="org.simantics.proconf.g3d.shapeeditor.handlers.NewCSGModelHandler"\r
+            commandId="org.simantics.proconf.shapeeditor.commands.newCSG">\r
+      </handler>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.menus">\r
+      <menuContribution\r
+            locationURI="popup:#OEPopup?after=additions">\r
+         <command\r
+               commandId="org.simantics.proconf.shapeeditor.commands.newCSG"\r
+               icon="icons/union.png"\r
+               id="org.simantics.proconf.shapeeditor.popups.newCSG"\r
+               label="New CSG-Model"\r
+               style="push">\r
+            <visibleWhen>\r
+               <and>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.proconf.shapeeditor.csg">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+                  <with\r
+                        variable="selection">\r
+                     <and>\r
+                        <test\r
+                              args="http://www.vtt.fi/Simantics/Layer0/1.0/Types#Library"\r
+                              property="org.simantics.graph.resourceType">\r
+                        </test>\r
+                     </and>\r
+                  </with>\r
+               </and>\r
+            </visibleWhen>\r
+         </command>\r
+      </menuContribution>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.proconf.ui.resourceEditorAdapter">\r
+      <adapterClass\r
+            class="org.simantics.proconf.g3d.shapeeditor.handlers.ResourceEditorAdapter1"\r
+            id="org.simantics.proconf.shapeeditor.ResourceEditorDescription1">\r
+      </adapterClass>\r
+      <adapterClass\r
+            class="org.simantics.proconf.g3d.shapeeditor.handlers.ResourceEditorAdapter3"\r
+            id="org.simantics.proconf.shapeeditor.ResourceEditorDescription3">\r
+      </adapterClass>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.editors">\r
+      <editor\r
+            class="org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorView"\r
+            icon="icons/union.png"\r
+            id="org.simantics.proconf.shapeeditor.editor1"\r
+            name="ShapeEditor">\r
+      </editor>\r
+      <editor\r
+            class="org.simantics.proconf.g3d.shapeeditor.views.ParameterizationEditor"\r
+            icon="icons/unlink.png"\r
+            id="org.simantics.proconf.shapeeditor.editor3"\r
+            name="ParameterizationEditor">\r
+      </editor>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.views">\r
+      <view\r
+            class="org.simantics.proconf.g3d.shapeeditor.views.StructureView"\r
+            icon="icons/union.png"\r
+            id="org.simantics.shapeeditor.views.structure"\r
+            name="Structure View">\r
+      </view>\r
+      <view\r
+            class="org.simantics.proconf.g3d.shapeeditor.views.CSGModellingView"\r
+            icon="icons/union.png"\r
+            id="org.simantics.proconf.shapeeditor.views.modelling"\r
+            name="CSG Modelling View">\r
+      </view>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.db.resourceAdapter">\r
+      <resource_adapter\r
+            adapter_class="org.simantics.proconf.g3d.shapeeditor.handlers.CSGProjectAdapter"\r
+            operation="http://www.vtt.fi/Simantics/Layer0/1.0/Relations#HasProjectTypeAdapter"\r
+            type_uri="http://www.vtt.fi/Simantics/CSG/1.0/Types#CSGProjectType">\r
+      </resource_adapter>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.perspectives">\r
+      <perspective\r
+            class="org.simantics.proconf.g3d.shapeeditor.perspectives.CSGModellingPerspective"\r
+            icon="icons/union.png"\r
+            id="org.simantics.proconf.shapeeditor.perspectives.csg"\r
+            name="CSG Modelling">\r
+      </perspective>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.perspectiveExtensions">\r
+      <perspectiveExtension\r
+            targetID="org.simantics.proconf.shapeeditor.perspectives.csg">\r
+         <view\r
+               id="org.simantics.proconf.shapeeditor.views.modelling"\r
+               ratio="0.3"\r
+               relationship="left"\r
+               relative="org.eclipse.ui.editorss"\r
+               visible="true">\r
+         </view>\r
+         <view\r
+               id="org.simantics.proconf.browsing.views.property"\r
+               ratio="0.7"\r
+               relationship="bottom"\r
+               relative="org.simantics.proconf.shapeeditor.views.modelling"\r
+               visible="true">\r
+         </view>\r
+         <view\r
+               id="org.eclipse.pde.runtime.LogView"\r
+               relationship="fast"\r
+               relative="fi.vtt.proconf.ui.views.property"\r
+               visible="false">\r
+         </view>\r
+         <view\r
+               id="org.simantics.shapeeditor.views.structure"\r
+               relationship="stack"\r
+               relative="org.simantics.proconf.shapeeditor.views.modelling">\r
+         </view>\r
+         <view\r
+               id="org.simantics.g3d.views.scenegraph"\r
+               ratio="0.3"\r
+               relationship="right"\r
+               relative="org.eclipse.ui.editorss"\r
+               visible="true">\r
+         </view>\r
+      </perspectiveExtension>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.contexts">\r
+      <context\r
+            id="org.simantics.proconf.shapeeditor.csg"\r
+            name="name">\r
+      </context>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.proconf.ui.perspectiveContextBinding">\r
+      <binding\r
+            contextIds="org.simantics.proconf.shapeeditor.csg"\r
+            perspectiveId="org.simantics.proconf.shapeeditor.perspectives.csg">\r
+      </binding>\r
+   </extension>\r
+\r
+</plugin>\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/Activator.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/Activator.java
new file mode 100644 (file)
index 0000000..e256c29
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor;\r
+\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.osgi.framework.BundleContext;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextChangedListener;\r
+import org.simantics.db.management.SessionContextChangedEvent;\r
+import org.simantics.proconf.ui.ProConfUI;\r
+\r
+/**\r
+ * The activator class controls the plug-in life cycle\r
+ */\r
+public class Activator extends AbstractUIPlugin {\r
+\r
+       // The plug-in ID\r
+       public static final String PLUGIN_ID = "org.simantics.proconf.g3d.shapeeditor";\r
+\r
+       // The shared instance\r
+       private static Activator plugin;\r
+       \r
+       /**\r
+        * The constructor\r
+        */\r
+       public Activator() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;\r
+               ProConfUI.getSessionContextProvider().addContextChangedListener(new ISessionContextChangedListener() {\r
+                       @Override\r
+                       public void sessionContextChanged(SessionContextChangedEvent event) {\r
+                               ISessionContext ctx = event.getNewValue();\r
+                               if (ctx != null) {\r
+                                       ctx.getSession().asyncRead(new GraphRequestAdapter() {\r
+                                               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                                       ShapeEditorResources.initialize(g);\r
+                                                       return GraphRequestStatus.transactionComplete();\r
+                                               };\r
+                                       });\r
+                               } else {\r
+                                       ShapeEditorResources.deinitialize();\r
+                               }\r
+                       }\r
+               });\r
+               try {\r
+                       ProConfUI.getSession().asyncRead(new GraphRequestAdapter() {\r
+                               @Override\r
+                               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                       ShapeEditorResources.initialize(g);\r
+                                       return GraphRequestStatus.transactionComplete();\r
+                               }\r
+                       });\r
+               } catch (Exception e) {\r
+                       \r
+               }\r
+               \r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               plugin = null;\r
+               super.stop(context);\r
+       }\r
+\r
+       /**\r
+        * Returns the shared instance\r
+        *\r
+        * @return the shared instance\r
+        */\r
+       public static Activator getDefault() {\r
+               return plugin;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/ShapeEditorResources.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/ShapeEditorResources.java
new file mode 100644 (file)
index 0000000..1548881
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor;\r
+\r
+import org.simantics.proconf.g3d.csg.stubs.CSGResource;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Graph;\r
+import org.simantics.equation.stubs.EquationResource;\r
+import org.simantics.g2d.stubs.anim.AnimationResource;\r
+import org.simantics.animation.curve.CurveBuilder;\r
+import org.simantics.animation.curve.CurveBuilderImpl;\r
+import org.simantics.proconf.g3d.stubs.G3DResource;\r
+\r
+public class ShapeEditorResources {\r
+       public static Builtins builtins;\r
+       public static G3DResource g3dResource;\r
+       public static CSGResource csgResource;\r
+       public static AnimationResource animationResource;\r
+       public static CurveBuilder curveBuilder;\r
+       public static EquationResource equationResource;\r
+       \r
+       public static void initialize(Graph g) {\r
+               builtins = g.getBuiltins();\r
+               animationResource = AnimationResource.getInstance(g);\r
+               csgResource = CSGResource.getInstance(g);\r
+               g3dResource = G3DResource.getInstance(g);\r
+               curveBuilder = new CurveBuilderImpl(ShapeEditorResources.animationResource);\r
+               equationResource = EquationResource.getInstance(g);\r
+       }\r
+       \r
+       public static void deinitialize() {\r
+               builtins = null;\r
+               g3dResource = null;\r
+               csgResource = null;\r
+               animationResource = null;\r
+               curveBuilder = null;\r
+               equationResource = null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ExportAction.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ExportAction.java
new file mode 100644 (file)
index 0000000..eca9989
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.proconf.g3d.shapeeditor.actions;\r
+\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.util.Collection;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.layer0.utils.extent.Extent;\r
+import org.simantics.layer0.utils.extent.ExtentUtils;\r
+import org.simantics.layer0.utils.extent.IExtentAdvisor;\r
+import org.simantics.layer0.utils.serialization.ConnectionPointMap;\r
+import org.simantics.layer0.utils.serialization.TransferableGraph;\r
+import org.simantics.layer0.utils.serialization.TransferableGraphUtils;\r
+import org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorBase;\r
+import org.simantics.utils.ErrorLogger;\r
+\r
+\r
+public class ExportAction extends Action{\r
+       private ShapeEditorBase parent;\r
+       \r
+       public ExportAction(ShapeEditorBase parent) {\r
+               this.parent = parent;\r
+               this.setText("Export");\r
+               this.setId("g3d shape export");\r
+       }\r
+       \r
+       @Override\r
+       public void run() {\r
+               try {\r
+                       doExport();\r
+               } catch (IOException e) {\r
+                       ErrorLogger.defaultLogError(e);\r
+               }\r
+       }\r
+       \r
+       private void doExport() throws IOException {\r
+               FileDialog dialog = new FileDialog(parent.getRenderingComposite().getShell(),SWT.SAVE);\r
+               String filename = dialog.open();\r
+               if (filename == null)\r
+                       return;\r
+               \r
+               final File file = new File(filename);\r
+               final FileOutputStream fos = new FileOutputStream(file);\r
+               \r
+               parent.getSession().asyncRead(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               Resource modelResource = parent.getModelResource();\r
+                               System.out.println("Exporting " + modelResource);\r
+                               Collection<Statement> model = ExtentUtils.determineExtent(g, new ExtentAdvisor(), modelResource);\r
+                               \r
+                               for (Statement s : model)                \r
+                                       System.out.println(GraphUtils.getReadableName(g, s.getSubject())+", "+GraphUtils.getReadableName(g, s.getPredicate())+", "+GraphUtils.getReadableName(g, s.getObject()));                \r
+                               \r
+                               ConnectionPointMap purposeProvider = new ConnectionPointMap();\r
+                               purposeProvider.put(modelResource, TransferableGraphUtils.CP_OBJECT);\r
+                               \r
+                               TransferableGraph dbIndependentSubgraph = TransferableGraphUtils.extractTransferableGraph(g, model, purposeProvider, null); \r
+                               \r
+                               byte[] data = TransferableGraphUtils.serialize(dbIndependentSubgraph);\r
+                               \r
+                               fos.write(data);\r
+                               \r
+                               System.out.println("Exporting done.");\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void requestCompleted(GraphRequestStatus status) {\r
+                               try {\r
+                                       fos.close();\r
+                               } catch (IOException e) {\r
+                                       ErrorLogger.defaultLogError(e);\r
+                               }\r
+                               \r
+                       }\r
+               });\r
+       }\r
+       \r
+       public class ExtentAdvisor implements IExtentAdvisor {\r
+               @Override\r
+               public ExtentAdvice getAdvice(Graph g, Extent currentState, Resource extent) {\r
+                       System.out.println("Extent advice : " + currentState + " : " + extent);\r
+                       \r
+                       //if (extent.equals(ShapeEditorResources.equationResource.Expression)) return ExtentAdvice.Include;\r
+                       //return ExtentAdvice.Exclude;\r
+                       return ExtentAdvice.Include;\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ImportAction.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/ImportAction.java
new file mode 100644 (file)
index 0000000..7a4d063
--- /dev/null
@@ -0,0 +1,81 @@
+package org.simantics.proconf.g3d.shapeeditor.actions;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.layer0.utils.serialization.ConnectionPointList;\r
+import org.simantics.layer0.utils.serialization.TransferableGraph;\r
+import org.simantics.layer0.utils.serialization.TransferableGraphUtils;\r
+import org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorBase;\r
+import org.simantics.utils.ErrorLogger;\r
+\r
+public class ImportAction extends Action {\r
+       \r
+       private ShapeEditorBase parent;\r
+       \r
+       public ImportAction(ShapeEditorBase parent) {\r
+               this.parent = parent;\r
+               setText("Import");\r
+               setId("g3d shape import");\r
+       }\r
+       \r
+       @Override\r
+       public void run() {\r
+               try {\r
+                       doImport();\r
+               } catch (IOException e) {\r
+                       ErrorLogger.defaultLogError(e);\r
+               }\r
+       }\r
+       \r
+       private void doImport() throws IOException {\r
+               FileDialog dialog = new FileDialog(parent.getRenderingComposite().getShell(),SWT.OPEN);\r
+               String filename = dialog.open();\r
+               if (filename == null)\r
+                       return;\r
+               File file = new File(filename);\r
+               FileInputStream fis = new FileInputStream(file);\r
+               BufferedInputStream bis = new BufferedInputStream(fis);\r
+               byte[] data = new byte[0];\r
+               byte[] buf = new byte[256];\r
+               int res = 0;\r
+               while ((res = bis.read(buf)) != -1) {\r
+                       byte[] newData = new byte[data.length + res];\r
+                       System.arraycopy(data, 0, newData, 0, data.length);\r
+                       System.arraycopy(buf, 0, newData, data.length, res);\r
+                       data = newData;\r
+               }\r
+               bis.close();\r
+               final byte fdata[] = data;\r
+               parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               TransferableGraph sg = TransferableGraphUtils.deserialize(fdata);\r
+                               ConnectionPointList purposes = TransferableGraphUtils.integrateTransferableGraph(g, sg, null);\r
+                               Resource modelResource = purposes.getSingleByDescription(TransferableGraphUtils.CP_OBJECT).resource;\r
+                   Resource currentModelResource = parent.getModelResource();\r
+                   for (Statement s : g.getStatements(modelResource)) {\r
+                       g.removeStatements(currentModelResource, s.getPredicate());\r
+                   }\r
+                               for (Statement s : g.getStatements(modelResource)) {\r
+                                       \r
+                                       g.removeStatement(s);\r
+                                       g.addStatement(currentModelResource, s.getPredicate(), s.getObject());\r
+                               }\r
+                   \r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFileAction.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFileAction.java
new file mode 100644 (file)
index 0000000..193fe45
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.actions;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.occ.geometry.OccTriangulator;\r
+\r
+import com.jme.renderer.ColorRGBA;\r
+import com.jme.scene.Geometry;\r
+import com.jme.scene.state.MaterialState;\r
+\r
+\r
+public class LoadFileAction extends Action {\r
+       private ThreeDimensionalEditorBase editor;\r
+       \r
+       public LoadFileAction(ThreeDimensionalEditorBase editor) {\r
+               super("Load file");\r
+               this.editor = editor;\r
+               \r
+       }\r
+       \r
+       public void run() {\r
+        FileDialog loadDialog = new FileDialog(editor.getRenderingComposite().getShell(), SWT.OPEN);\r
+        String exts[] = { "*.stp;*.step", "*.iges", "*.brep", "*.ply" }; //$NON-NLS-1$\r
+        String names[] = { "STEP (AP214/AP203)", "IGES", "BREP", "PLY" }; //$NON-NLS-1$\r
+        loadDialog.setFilterNames(names);\r
+        loadDialog.setFilterExtensions(exts);\r
+        loadDialog.setText("Load model");\r
+\r
+        String filename = loadDialog.open();\r
+        if (filename != null) {\r
+            Geometry g = OccTriangulator.getGeometryFromFile(filename)[0];\r
+            MaterialState ms = editor.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
+            ms.setAmbient(new ColorRGBA(0.f,0.f,0.f,0.f));\r
+            ms.setEmissive(new ColorRGBA(0.f,0.f,0.f,0.f));\r
+            ms.setShininess(128.f);\r
+            ms.setDiffuse(new ColorRGBA(0.8f,0.8f,0.8f,0.f));\r
+            ms.setSpecular(new ColorRGBA(1.f,1.f,1.f,0.f));\r
+            ms.setMaterialFace(MaterialState.MF_FRONT_AND_BACK);\r
+            if (g.getColorBuffer(0) != null) {\r
+               ms.setColorMaterial(MaterialState.CM_DIFFUSE);\r
+            }\r
+            g.setRenderState(ms);\r
+            editor.getRenderingComponent().getShadowRoot().attachChild(g);\r
+            // mo.setGeometry(mesh, filename);\r
+            // xithComposite.getScene().compile();\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFolderAction.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/actions/LoadFolderAction.java
new file mode 100644 (file)
index 0000000..2b7d49e
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.actions;\r
+\r
+import java.io.File;\r
+import java.io.FilenameFilter;\r
+import java.util.Stack;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.DirectoryDialog;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.occ.geometry.OccTriangulator;\r
+\r
+import com.jme.bounding.BoundingBox;\r
+import com.jme.renderer.ColorRGBA;\r
+import com.jme.scene.Geometry;\r
+import com.jme.scene.state.MaterialState;\r
+\r
+\r
+public class LoadFolderAction extends Action {\r
+       private ThreeDimensionalEditorBase editor;\r
+       \r
+       public LoadFolderAction(ThreeDimensionalEditorBase editor) {\r
+               super("Load folder");\r
+               this.editor = editor;\r
+               \r
+       }\r
+       \r
+       public void run() {\r
+        \r
+      DirectoryDialog loadDialog = new DirectoryDialog(editor.getRenderingComposite().getShell(), SWT.OPEN);\r
+      loadDialog.setText("Select directory");\r
+\r
+      String directory = loadDialog.open();\r
+      if (directory != null) {\r
+          File file = new File(directory);\r
+          if (!file.isDirectory())\r
+              return;\r
+          Stack<File> directories = new Stack<File>();\r
+          directories.push(file);\r
+          boolean recursive = true;\r
+          while (!directories.empty()) {\r
+              File dir = directories.pop();\r
+\r
+              String[] files = dir.list(new PLYFilter());\r
+              for (String filename : files) {\r
+                  Geometry g = OccTriangulator.getGeometryFromFile(dir.getAbsolutePath() + "/" + filename)[0];\r
+                MaterialState ms = editor.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
+                ms.setAmbient(new ColorRGBA(0.f,0.f,0.f,0.f));\r
+                ms.setEmissive(new ColorRGBA(0.f,0.f,0.f,0.f));\r
+                ms.setShininess(128.f);\r
+                ms.setDiffuse(new ColorRGBA(0.8f,0.8f,0.8f,0.f));\r
+                ms.setSpecular(new ColorRGBA(1.f,1.f,1.f,0.f));\r
+                ms.setMaterialFace(MaterialState.MF_FRONT_AND_BACK);\r
+                if (g.getColorBuffer(0) != null) {\r
+                       ms.setColorMaterial(MaterialState.CM_DIFFUSE);\r
+                }\r
+                g.setModelBound(new BoundingBox());\r
+                g.updateModelBound();\r
+                g.setRenderState(ms);\r
+                editor.getRenderingComponent().getShadowRoot().attachChild(g);\r
+                g.updateWorldBound();\r
+                g.lock();\r
+               \r
+              }\r
+              if (recursive) {\r
+                  File[] newDirs = dir.listFiles(new DirectoryFilter());\r
+                  for (File d : newDirs)\r
+                      directories.push(d);\r
+              }\r
+          }\r
+          \r
+      }\r
+\r
+\r
+    }\r
+       \r
+        protected class DirectoryFilter implements FilenameFilter {\r
+               public boolean accept(File dir, String name) {\r
+                   File file = new File(dir.getAbsolutePath() + "/" + name);\r
+                   return file.isDirectory();\r
+               }\r
+           }\r
+\r
+           protected class PLYFilter implements FilenameFilter {\r
+               public boolean accept(File dir, String name) {\r
+                   return (name.endsWith("ply"));\r
+               }\r
+           }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/common/ViewpointGenerator.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/common/ViewpointGenerator.java
new file mode 100644 (file)
index 0000000..6873736
--- /dev/null
@@ -0,0 +1,196 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.common;\r
+\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.layer0.utils.Statement;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.viewpoints.AcceptDecision;\r
+import org.simantics.layer0.utils.viewpoints.AcceptRule;\r
+import org.simantics.layer0.utils.viewpoints.PlainStateFactory;\r
+import org.simantics.layer0.utils.viewpoints.ResourceViewpoint;\r
+import org.simantics.layer0.utils.viewpoints.State;\r
+import org.simantics.layer0.utils.viewpoints.StateFactory;\r
+import org.simantics.layer0.utils.viewpoints.TraversalDecision;\r
+import org.simantics.layer0.utils.viewpoints.TraversalRule;\r
+import org.simantics.layer0.utils.viewpoints.rules.AcceptAllResourceAcceptRule;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+\r
+\r
+public class ViewpointGenerator {\r
+       \r
+       public static ResourceViewpoint createStuctureViewpoint() {\r
+               StateFactory f = new PlainStateFactory();\r
+               final State rootState = f.newState();\r
+               final State projectState = f.newState();\r
+               final State libraryState = f.newState();\r
+\r
+               return new ResourceViewpoint(new TraversalRule() {\r
+                       @Override\r
+                       public TraversalDecision makeTraversalDecision(State state,\r
+                                       Statement statement) {\r
+                               Builtins b = statement.getGraph().getBuiltins();\r
+                               if (state.equals(rootState)) {\r
+                                       if (!statement.getPredicate().equals(b.ConsistsOf))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       //if (!statement.getObject().isInstanceOf(b.Project))\r
+                                       //    return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(projectState);\r
+                               } else if (state.equals(projectState)) {\r
+                                       if (!statement.getPredicate().equals(b.ConsistsOf))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       //if (!statement.getObject().isInstanceOf(b.Library))\r
+                                       //    return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(libraryState);\r
+                               } else if (state.equals(libraryState)) {\r
+                                       if (!statement.getPredicate().equals(b.ConsistsOf)\r
+                                                       && !statement.getPredicate().isSubrelationOf(\r
+                                                                       ShapeEditorResources.g3dResource.HasChild))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(libraryState);\r
+                               }\r
+                               return TraversalDecision.stopTraversal;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean areAllStatesRelevant() {\r
+                               return true;\r
+                       }\r
+\r
+                       @Override\r
+                       public Collection<State> relevantStates() {\r
+                               return null;\r
+                       }\r
+               }, new AcceptAllResourceAcceptRule(), rootState);\r
+       }\r
+       \r
+       public static ResourceViewpoint createObjectStructureViewpoint() {\r
+               StateFactory f = new PlainStateFactory();\r
+               final State rootState = f.newState();\r
+\r
+               return new ResourceViewpoint(new TraversalRule() {\r
+                       @Override\r
+                       public TraversalDecision makeTraversalDecision(State state,\r
+                                       Statement statement) {\r
+                               if (state.equals(rootState)) {\r
+                                       if (!statement.getPredicate().isSubrelationOf(\r
+                                                       ShapeEditorResources.g3dResource.HasChild))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(rootState);\r
+                               }\r
+                               return TraversalDecision.stopTraversal;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean areAllStatesRelevant() {\r
+                               return true;\r
+                       }\r
+\r
+                       @Override\r
+                       public Collection<State> relevantStates() {\r
+                               return null;\r
+                       }\r
+               }, new AcceptAllResourceAcceptRule(), rootState);\r
+       }\r
+       \r
+       public static ResourceViewpoint createObjectSizingParameterViewpoint(Resource modelToParameterRelation) {\r
+               StateFactory f = new PlainStateFactory();\r
+               final State rootState = f.newState();\r
+               final State endState = f.newState();\r
+               final Resource relation = modelToParameterRelation;\r
+\r
+               return new ResourceViewpoint(new TraversalRule() {\r
+                       @Override\r
+                       public TraversalDecision makeTraversalDecision(State state,\r
+                                       Statement statement) {\r
+                               if (state.equals(rootState)) {\r
+                                       if (!statement.getPredicate().isSubrelationOf(relation))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(endState);\r
+                               }\r
+                               return TraversalDecision.stopTraversal;\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean areAllStatesRelevant() {\r
+                               return true;\r
+                       }\r
+\r
+                       @Override\r
+                       public Collection<State> relevantStates() {\r
+                               return null;\r
+                       }\r
+               }, new AcceptAllResourceAcceptRule(), rootState);\r
+       }\r
+       \r
+       public static ResourceViewpoint createViewpoint() {\r
+               StateFactory f = new PlainStateFactory();\r
+               final State rootState = f.newState();\r
+               final State projectState = f.newState();\r
+               final State libraryState = f.newState();\r
+               \r
+               return new ResourceViewpoint(new TraversalRule() {\r
+                       @Override\r
+                       public TraversalDecision makeTraversalDecision(State state, Statement statement) {\r
+                               Builtins b = statement.getGraph().getBuiltins();\r
+                               if (state.equals(rootState)) {\r
+                                       if (statement.getObject().isInstanceOf(b.Ontology))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       if(!statement.getPredicate().equals(b.ConsistsOf))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(projectState);\r
+                               } else if (state.equals(projectState)) {\r
+                                       if(!statement.getPredicate().equals(b.ConsistsOf))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(libraryState);\r
+                               } else if (state.equals(libraryState)) {\r
+                                       if(!statement.getPredicate().equals(b.ConsistsOf))\r
+                                               return TraversalDecision.stopTraversal;\r
+                                       return TraversalDecision.continueTraversal(libraryState);\r
+                               }\r
+                               return TraversalDecision.stopTraversal;\r
+                       }\r
+                       \r
+                       @Override\r
+                       public boolean areAllStatesRelevant() {\r
+                               return true;\r
+                       }\r
+                       \r
+                       @Override\r
+                       public Collection<State> relevantStates() {\r
+                               return null;\r
+                       }\r
+               }, new AcceptRule<IEntity>() {\r
+               @Override\r
+                       public AcceptDecision makeAcceptDecision(State state, IEntity obj) {\r
+                               Builtins b = obj.getGraph().getBuiltins();\r
+                               //NOSEResource nr = NOSEResource.getInstance(obj.getGraph());\r
+                               if(obj.isInstanceOf(b.Project)) return AcceptDecision.REJECT;\r
+                               else if (obj.isInstanceOf(b.Ontology)) return AcceptDecision.REJECT;\r
+                               else return AcceptDecision.ACCEPT;\r
+                       }\r
+               \r
+                       @Override\r
+                       public boolean areAllStatesRelevant() {\r
+                               return true;\r
+                       }\r
+                       \r
+                       @Override\r
+                       public Collection<State> relevantStates() {\r
+                               return null;\r
+                       }\r
+               }, rootState);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/dialogs/PropertySelectionDialog.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/dialogs/PropertySelectionDialog.java
new file mode 100644 (file)
index 0000000..09a5add
--- /dev/null
@@ -0,0 +1,112 @@
+package org.simantics.proconf.g3d.shapeeditor.dialogs;\r
+\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.dialogs.IDialogConstants;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.proconf.g3d.tools.PropertyTree;\r
+\r
+public class PropertySelectionDialog extends Dialog {\r
+    String title = null;\r
+    String message = null;\r
+    \r
+    Session session;\r
+    PropertyTree propertyTree;\r
+    Resource[] selectedTypes = null;\r
+    List<Resource> selectedPropertyInstances = null;\r
+    List<Resource> selectedInstances = null;\r
+    \r
+    public PropertySelectionDialog(Shell parentShell, String dialogTitle, String dialogMessage, Session session, List<Resource> selectedResources) {\r
+        super(parentShell);\r
+        this.session = session;\r
+        this.title = dialogTitle;\r
+        this.message = dialogMessage;\r
+        this.selectedInstances = selectedResources;\r
+    }\r
+    \r
+    @Override\r
+    protected void configureShell(Shell newShell) {\r
+        \r
+        super.configureShell(newShell);\r
+        if (title != null)\r
+            newShell.setText(title);\r
+    }\r
+    \r
+    protected Control createDialogArea(Composite parent) {\r
+        Composite composite = (Composite) super.createDialogArea(parent);\r
+        \r
+        Label label = new Label(composite, SWT.WRAP);\r
+        label.setText(message);\r
+        GridData data = new GridData(GridData.GRAB_HORIZONTAL\r
+                | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL\r
+                | GridData.VERTICAL_ALIGN_CENTER);\r
+        data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);\r
+        label.setLayoutData(data);\r
+        label.setFont(parent.getFont());\r
+        \r
+        Tree tree = new Tree(composite,SWT.SINGLE);\r
+        propertyTree = new PropertyTree(tree,session);\r
+\r
+        GridData data2 = new GridData(GridData.GRAB_HORIZONTAL\r
+                | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL\r
+                | GridData.VERTICAL_ALIGN_FILL);\r
+        data2.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);\r
+        data2.heightHint = 200;\r
+        tree.setLayoutData(data2);\r
+        tree.setFont(parent.getFont());\r
+        \r
+        tree.showSelection();\r
+        \r
+        applyDialogFont(composite);\r
+        \r
+        //propertyTree.setProperties(selectionAdapter.getCurrentSelection());\r
+        propertyTree.setProperties(selectedInstances);\r
+        return composite;\r
+    }\r
+    \r
+    @Override\r
+    public boolean close() {\r
+        TreeItem selected[] = propertyTree.getTree().getSelection();\r
+        if (selected.length == 0) {\r
+            selectedTypes = null;\r
+        } else {\r
+            selectedTypes = new Resource[selected.length];\r
+            for (int i = 0; i < selected.length; i++) {\r
+                selectedTypes[i] = (Resource)selected[i].getData();\r
+            }\r
+        }\r
+        //final ArrayList<Resource> instances = new ArrayList<Resource>();\r
+//        for (Resource rs : selectionAdapter.getCurrentSelection().getSelectionList()) {\r
+//            instances.add(rs);\r
+//        }\r
+\r
+        \r
+        session.syncRead(new GraphRequestAdapter() {\r
+               @Override\r
+               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                       selectedPropertyInstances = propertyTree.findPropertyInstances(g,selectedInstances);\r
+                       return GraphRequestStatus.transactionComplete();\r
+               }\r
+        });\r
+\r
+        return super.close();\r
+    }\r
+    \r
+    public List<Resource> getSelectedPropertyInstances() {\r
+        return selectedPropertyInstances;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectAdapter.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectAdapter.java
new file mode 100644 (file)
index 0000000..5c0835d
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.handlers;\r
+\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.adaption.AdaptionException;\r
+import org.simantics.db.adaption.ResourceAdapter;\r
+\r
+\r
+public class CSGProjectAdapter implements ResourceAdapter {\r
+       @SuppressWarnings("unchecked")\r
+       @Override\r
+       public <T> T adapt(Graph graph, Resource resource, Resource mia) throws AdaptionException {\r
+               return (T) new CSGProjectType(graph, resource);\r
+\r
+       }\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectType.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/CSGProjectType.java
new file mode 100644 (file)
index 0000000..a220f78
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.handlers;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.proconf.ui.projects.IProject;\r
+import org.simantics.proconf.ui.projects.ProjectType;\r
+\r
+public class CSGProjectType extends ProjectType {\r
+\r
+       public CSGProjectType(Graph graph, Resource projectTypeResource) {\r
+               super(graph, projectTypeResource);\r
+       }\r
+\r
+       @Override\r
+       public Resource createProject(Graph g, String name) throws Exception {\r
+               Resource project = super.createProject(g, name);\r
+               Builtins b = g.getBuiltins();\r
+               \r
+               {   // Models\r
+         Resource modelLibrary = g.newResource();                \r
+         g.addStatement(modelLibrary, b.InstanceOf, b.ModelLibrary);\r
+         GraphUtils.addRelatedScalarString(g, modelLibrary, b.HasName, "Models");\r
+         g.addStatement(project, b.ConsistsOf, modelLibrary);        \r
+               }\r
+       \r
+               \r
+               \r
+               return project;\r
+       }\r
+       \r
+       @Override\r
+       public IProject loadProject(Graph g, Resource r) {\r
+               IProject project = super.loadProject(g, r);\r
+               project.set(DefaultPerspective, "org.simantics.proconf.shapeeditor.perspectives.csg");\r
+               Collection<String> perspectives = new ArrayList<String>();\r
+               perspectives.add("org.simantics.proconf.shapeeditor.perspectives.csg");\r
+               project.set(Perspectives, perspectives);\r
+               \r
+               return project;\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/NewCSGModelHandler.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/NewCSGModelHandler.java
new file mode 100644 (file)
index 0000000..be79363
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.proconf.g3d.csg.stubs.CSGModel;\r
+\r
+import org.simantics.proconf.ui.ProConfUI;\r
+import org.simantics.proconf.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.layer0.stubs.Library;\r
+\r
+\r
+public class NewCSGModelHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               ISelection s = HandlerUtil.getCurrentSelectionChecked(event);\r
+        IStructuredSelection ss = (IStructuredSelection) s;\r
+        if (ss.size() != 1)\r
+            return null;\r
+        final Resource lib = ResourceAdaptionUtils.toSingleResource(ss);\r
+               ProConfUI.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               CSGModel model = CSGModel.createDefault(g);\r
+                               Library l = new Library(g, lib);\r
+                               l.addStatement(g.getBuiltins().ConsistsOf, model);\r
+                               \r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+               \r
+               \r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter1.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter1.java
new file mode 100644 (file)
index 0000000..41f07ad
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.handlers;\r
+\r
+import org.simantics.proconf.g3d.shapeeditor.Activator;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.ui.workbench.ResourceEditorInput;\r
+import org.simantics.proconf.ui.workbench.editor.SimpleEditorAdapter;\r
+\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.BundleUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+\r
+public class ResourceEditorAdapter1 extends SimpleEditorAdapter {\r
+\r
+       public ResourceEditorAdapter1() {\r
+               super("ShapeEditor",\r
+                       BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/union.png"),\r
+                       null,null,null);\r
+       }\r
+\r
+       @Override\r
+       public boolean canHandle(Graph g, Resource r) {\r
+               if(ShapeEditorResources.csgResource == null) return false; \r
+               if(ShapeEditorResources.csgResource.CSGModel == null) return false; \r
+               return g.isInstanceOf(r, ShapeEditorResources.csgResource.CSGModel);\r
+       }\r
+\r
+\r
+       @Override\r
+       public void openEditor(Resource r) throws Exception {\r
+               WorkbenchUtils.openEditor("org.simantics.proconf.shapeeditor.editor1", new ResourceEditorInput("org.simantics.proconf.shapeeditor.editor1",r));\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter3.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/handlers/ResourceEditorAdapter3.java
new file mode 100644 (file)
index 0000000..f861179
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.handlers;\r
+\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.proconf.g3d.shapeeditor.Activator;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.ui.workbench.ResourceEditorInput;\r
+import org.simantics.proconf.ui.workbench.editor.SimpleEditorAdapter;\r
+import org.simantics.utils.ui.BundleUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+\r
+public class ResourceEditorAdapter3 extends SimpleEditorAdapter {\r
+\r
+       public ResourceEditorAdapter3() {\r
+               super("Parameterization Editor",\r
+                       BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/unlink.png"),\r
+                       null,null,null);\r
+       }\r
+\r
+       @Override\r
+       public boolean canHandle(Graph g, Resource r) {\r
+               if(ShapeEditorResources.csgResource == null) return false; \r
+               if(ShapeEditorResources.csgResource.CSGModel == null) return false; \r
+               return g.isInstanceOf(r, ShapeEditorResources.csgResource.CSGModel);\r
+       }\r
+\r
+\r
+       @Override\r
+       public void openEditor(Resource r) throws Exception {\r
+               WorkbenchUtils.openEditor("org.simantics.proconf.shapeeditor.editor3", new ResourceEditorInput("org.simantics.proconf.shapeeditor.editor3",r));\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/perspectives/CSGModellingPerspective.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/perspectives/CSGModellingPerspective.java
new file mode 100644 (file)
index 0000000..f6c6a58
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.perspectives;\r
+\r
+import org.eclipse.ui.IPageLayout;\r
+import org.eclipse.ui.IPerspectiveFactory;\r
+\r
+public class CSGModellingPerspective implements IPerspectiveFactory {\r
+\r
+       @Override\r
+       public void createInitialLayout(IPageLayout layout) {\r
+       \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/scenegraph/CSGShapeNode.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/scenegraph/CSGShapeNode.java
new file mode 100644 (file)
index 0000000..1bf8fe7
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.scenegraph;\r
+\r
+\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.proconf.g3d.base.GeometryProviderRegistry;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
+import org.simantics.proconf.g3d.scenegraph.ShapeNode;\r
+\r
+import com.jme.scene.Geometry;\r
+import com.jme.scene.state.AlphaState;\r
+import com.jme.scene.state.ZBufferState;\r
+\r
+\r
+\r
+public class CSGShapeNode extends ShapeNode{\r
+\r
+       \r
+    //protected Geometry axesGeometry = null;\r
+    protected boolean axesVisible = false;\r
+\r
+    public CSGShapeNode(ThreeDimensionalEditorBase editor,IGraphicsNode parent, Graph graph, Resource shapeResource) {\r
+        super(editor,parent, graph,shapeResource);\r
+        //axesGeometry = AxesShape.getShape(editor.getRenderingComponent().getDisplaySystem().getRenderer());\r
+        ZBufferState zs = editor.getRenderingComponent().getDisplaySystem().getRenderer().createZBufferState();\r
+        zs.setFunction(ZBufferState.CF_ALWAYS);\r
+        AlphaState as = editor.getRenderingComponent().getDisplaySystem().getRenderer().createAlphaState();\r
+        as.setBlendEnabled(true);\r
+        as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);\r
+        as.setSrcFunction(AlphaState.DB_SRC_ALPHA);\r
+//        axesGeometry.setRenderState(zs);\r
+//        axesGeometry.setRenderState(as);\r
+//        axesGeometry.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);\r
+    }\r
+\r
+    \r
+\r
+   public Geometry[] getGeometry(Graph graph) {\r
+          \r
+       return GeometryProviderRegistry.getGeometry(getG3DNode(graph), false);\r
+   }\r
+   \r
+   public void updateAllGeometry() {\r
+          //System.out.println("CSGSHapeNode.updateAllGeometry " + shapeResource.getResourceId());\r
+          editor.getScenegraphAdapter().updateGeometry(shapeResource);\r
+       if (parent != null && parent instanceof CSGShapeNode) {\r
+           ((CSGShapeNode)parent).updateAllGeometry();\r
+       }\r
+       \r
+   }\r
+   \r
+   @Override\r
+       public void updateGeometry(Graph graph) {\r
+               super.updateGeometry(graph);\r
+               if (isAxesVisible()) {\r
+                       //getGroup().attachChild(axesGeometry);\r
+               } else {\r
+                       //axesGeometry.removeFromParent();\r
+               }\r
+       }\r
+\r
+\r
+   \r
+   public boolean isAxesVisible() {\r
+       return axesVisible;\r
+   }\r
+\r
+   public void setAxesVisible(boolean axesVisible) {\r
+       \r
+       if (this.axesVisible == axesVisible)\r
+           return;\r
+       this.axesVisible = axesVisible;\r
+       if (isAxesVisible()) {\r
+               //getGroup().getParent().attachChild(axesGeometry);\r
+          //getGroup().attachChild(axesGeometry);\r
+       } else {\r
+               //axesGeometry.removeFromParent();\r
+       }\r
+   }\r
+   \r
+   public void setSelected(boolean selected) {\r
+       if (this.selected == selected)\r
+           return;\r
+       this.selected = selected;\r
+       if (selected) {\r
+\r
+           setSelectedVisible(true);\r
+           setAxesVisible(true);\r
+           setTransparentVisible(true);\r
+       } else {\r
+           setSelectedVisible(false);\r
+           setAxesVisible(false);\r
+           setTransparentVisible(false);\r
+       }\r
+   }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/AnimationContribution.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/AnimationContribution.java
new file mode 100644 (file)
index 0000000..c3f7f61
--- /dev/null
@@ -0,0 +1,774 @@
+package org.simantics.proconf.g3d.shapeeditor.tools;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import javax.vecmath.AxisAngle4d;\r
+import javax.vecmath.Quat4d;\r
+\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.IToolBarManager;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.dialogs.InputDialog;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.KeyAdapter;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.layout.FormAttachment;\r
+import org.eclipse.swt.layout.FormData;\r
+import org.eclipse.swt.layout.FormLayout;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Slider;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.db.ContextGraph;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.GraphRequestWithResult;\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.stubs.anim.Animation;\r
+import org.simantics.g2d.stubs.anim.Interpolator;\r
+import org.simantics.g2d.stubs.anim.ScalarInterpolator;\r
+import org.simantics.g2d.stubs.anim.SlerpInterpolator;\r
+import org.simantics.layer0.utils.EntityFactory;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.Property;\r
+import org.simantics.animation.curve.SlerpCurve;\r
+import org.simantics.animation.curve.TCBCurve;\r
+import org.simantics.proconf.g3d.actions.ContextAction;\r
+import org.simantics.proconf.g3d.actions.RotateAction;\r
+import org.simantics.proconf.g3d.actions.TranslateAction;\r
+import org.simantics.proconf.g3d.animation.Animatable;\r
+import org.simantics.proconf.g3d.base.EditorContribution;\r
+import org.simantics.proconf.g3d.base.G3DTools;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.base.VisualizationScheduler;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
+import org.simantics.proconf.g3d.scenegraph.ISelectableNode;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.g3d.shapeeditor.dialogs.PropertySelectionDialog;\r
+import org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorBase;\r
+import org.simantics.proconf.g3d.stubs.G3DModel;\r
+import org.simantics.proconf.g3d.stubs.Orientation;\r
+import org.simantics.utils.ErrorLogger;\r
+\r
+public class AnimationContribution implements EditorContribution {\r
+       List<ContextAction> actions = new ArrayList<ContextAction>();\r
+       \r
+       private ShapeEditorBase parent;\r
+       \r
+       private final String NO_ANIMATION = "None";\r
+\r
+       private Slider timeSlider;\r
+       private double key = 0;\r
+       private Composite buttonComposite;\r
+       private Button insertKeyFrameButton;\r
+       private Button clearKeyFrameButton;\r
+       private CCombo animationCombo;\r
+       private Button addAnimationButton;\r
+       private Button removeAnimationButton;\r
+       private Button clearAnimationButton;\r
+       private Button animateButton;\r
+       private Button usePrecalculation;\r
+       private Text timeText;\r
+       private Composite infoComposite;\r
+       private Text infoText;\r
+\r
+       private Resource animationResource;\r
+       \r
+       private ContextAction translateAction;\r
+       private ContextAction rotateAction;\r
+       \r
+       public AnimationContribution(ThreeDimensionalEditorBase parent) {\r
+               this.parent = (ShapeEditorBase)parent;\r
+       }\r
+       \r
+       @Override\r
+       public String getName() {\r
+               return "Animator";\r
+       }\r
+       \r
+       @Override\r
+       public void createControl(Composite parent) {\r
+               FormLayout flayout = new FormLayout();\r
+               parent.setLayout(flayout);\r
+               infoComposite = new Composite(parent, SWT.BORDER);\r
+               FormData data = new FormData();\r
+               data.top = new FormAttachment(0, 0);\r
+               data.left = new FormAttachment(0, 0);\r
+               data.right = new FormAttachment(100, 0);\r
+               data.bottom = new FormAttachment(infoComposite, 0, SWT.TOP);\r
+               this.parent.getRenderingComposite().setLayoutData(data);\r
+\r
+               infoComposite.setLayout(new FillLayout(SWT.VERTICAL));\r
+               infoText = new Text(infoComposite, SWT.NONE);\r
+               GridLayout layout = new GridLayout(2, false);\r
+               layout.horizontalSpacing = 2;\r
+               layout.verticalSpacing = 2;\r
+               layout.marginWidth = 1;\r
+               layout.marginHeight = 1;\r
+               infoComposite.setLayout(layout);\r
+               GridData gdata = new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 2, 1);\r
+               // FIXME : allows text widget to take all available space (horizontal / width)\r
+               gdata.widthHint = 2000;\r
+               infoText.setLayoutData(gdata);\r
+               timeSlider = new Slider(infoComposite, SWT.NONE);\r
+               timeSlider.setValues(0, 0, 100, 1, 1, 1);\r
+               timeSlider.addSelectionListener(new SelectionAdapter() {\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               key = ((double) timeSlider.getSelection()) / 100.0;\r
+                               updateTime();\r
+                       }\r
+               });\r
+               timeSlider.setLayoutData(new GridData(SWT.FILL, 1, true, false));\r
+               timeText = new Text(infoComposite, SWT.SINGLE);\r
+               timeText.addFocusListener(new FocusAdapter() {\r
+                       @Override\r
+                       public void focusLost(FocusEvent e) {\r
+                               updateTime();\r
+                       }\r
+               });\r
+               timeText.addKeyListener(new KeyAdapter() {\r
+                       @Override\r
+                       public void keyReleased(KeyEvent e) {\r
+                               if (e.keyCode == SWT.CR)\r
+                                       updateTime();\r
+                       }\r
+               });\r
+\r
+               buttonComposite = new Composite(infoComposite, SWT.NONE);\r
+               buttonComposite.setLayout(new FillLayout(SWT.HORIZONTAL));\r
+               buttonComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 2, 1));\r
+               insertKeyFrameButton = new Button(buttonComposite, SWT.PUSH);\r
+               insertKeyFrameButton.setText("Insert Keyframe");\r
+               insertKeyFrameButton.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               insertKeyFrame();\r
+                       }\r
+               });\r
+\r
+               clearKeyFrameButton = new Button(buttonComposite, SWT.PUSH);\r
+               clearKeyFrameButton.setText("Clear Keyframe");\r
+\r
+               animationCombo = new CCombo(buttonComposite, SWT.NONE);\r
+               animationCombo.add(NO_ANIMATION);\r
+               animationCombo.select(0);\r
+               animationCombo.setEditable(false);\r
+               animationCombo.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               selectAnimation();\r
+                       }\r
+               });\r
+\r
+               addAnimationButton = new Button(buttonComposite, SWT.PUSH);\r
+               addAnimationButton.setText("New Animation");\r
+               addAnimationButton.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               addAnimation();\r
+                       }\r
+               });\r
+\r
+               clearAnimationButton = new Button(buttonComposite, SWT.PUSH);\r
+               clearAnimationButton.setText("Clear Animation");\r
+               clearAnimationButton.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               clearAnimation();\r
+                       }\r
+               });\r
+\r
+               removeAnimationButton = new Button(buttonComposite, SWT.PUSH);\r
+               removeAnimationButton.setText("Remove Animation");\r
+               removeAnimationButton.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               removeAnimation();\r
+                       }\r
+               });\r
+\r
+               animateButton = new Button(buttonComposite, SWT.TOGGLE);\r
+               animateButton.setText("Animate");\r
+               animateButton.addSelectionListener(new SelectionAdapter() {\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               animate();\r
+                       }\r
+               });\r
+\r
+               usePrecalculation = new Button(buttonComposite, SWT.CHECK);\r
+               usePrecalculation.setText("Precalc");\r
+\r
+               data = new FormData();\r
+               data.left = new FormAttachment(0, 0);\r
+               data.right = new FormAttachment(100, 0);\r
+               data.bottom = new FormAttachment(100, 0);\r
+               // FIXME : take account font size\r
+               data.height = 20 * 3;\r
+               infoComposite.setLayoutData(data);\r
+\r
+               this.parent.getSelectionAdapter().addSelectionChangedListener(new ISelectionChangedListener() {\r
+                       public void selectionChanged(SelectionChangedEvent event) {\r
+                               updateUI();\r
+                       }\r
+               });\r
+               updateUI();\r
+               \r
+               this.parent.getSession().asyncRead(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               G3DModel m = new G3DModel(g,AnimationContribution.this.parent.getModelResource());\r
+                       Collection<Animation> animations = m.getAnimation();\r
+\r
+                       final List<String> animationNames = new ArrayList<String>();\r
+                       for (Animation a : animations) {\r
+                               animationNames.add(a.getName());\r
+                       }\r
+                       AnimationContribution.this.parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
+                               public void run() {\r
+                                       for (String s : animationNames)\r
+                                               animationCombo.add(s);\r
+                               }\r
+                       });\r
+                       return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+               });\r
+       }\r
+       \r
+       @Override\r
+       public void disposeControl() {\r
+               if (animateRunnable != null)\r
+               VisualizationScheduler.getInstance().removeVisualization(animateRunnable);\r
+       animateRunnable = null;\r
+       \r
+       infoComposite.dispose();\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void fillContextMenu(Graph graph, IMenuManager manager, StructuredResourceSelection selection) {\r
+\r
+       }\r
+       \r
+       \r
+       \r
+       @Override\r
+       public Collection<ContextAction> getActions() {\r
+               return actions;\r
+       }\r
+       \r
+       @Override\r
+       public void initialize(Graph graph) {\r
+               actions.add(translateAction = new TranslateAction(parent) {\r
+                       @Override\r
+                       public void setInfoText(String text) {\r
+                               infoText.setText(text);\r
+                       }\r
+               });\r
+               actions.add(rotateAction = new RotateAction(parent){\r
+                       @Override\r
+                       public void setInfoText(String text) {\r
+                               infoText.setText(text);\r
+                       }\r
+               });\r
+       }\r
+       \r
+       private double getCurrentKey() {\r
+       return key;\r
+    }\r
+    \r
+    private void updateTime() {\r
+        final double t = getCurrentKey();\r
+        timeText.setText(Double.toString(t));\r
+        if (animationResource == null)\r
+            return;\r
+        if (usePrecalculation.getSelection()) {\r
+            for (IGraphicsNode n : parent.getScenegraphAdapter().getNodes()) {\r
+                if (n instanceof Animatable) {\r
+                       // TODO : frame-rate dependent animations\r
+                    ((Animatable)n).animate(t,0.0);\r
+                }\r
+                parent.setViewChanged(true);\r
+            }    \r
+        } else {\r
+               parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               Collection<IEntity> interpolators = getAnimation(g).getRelatedObjects(ShapeEditorResources.animationResource.HasInterpolator);\r
+                    for (IEntity i : interpolators) {\r
+                        if (i.isInstanceOf(ShapeEditorResources.animationResource.ScalarInterpolator)) {\r
+                            // TODO : creating curve each time when time is set is\r
+                            // slow. Curve should be cached\r
+                            TCBCurve c = (TCBCurve) ShapeEditorResources.curveBuilder.loadInterpolator(i);\r
+                            double out = c.evaluate(t);\r
+                            g.setScalarDouble(i.getSingleRelatedObject(ShapeEditorResources.animationResource.HasTarget).getResource(), out);\r
+                        } else if (i.isInstanceOf(ShapeEditorResources.animationResource.SlerpInterpolator)) {\r
+                            // TODO : creating curve each time when time is set is slow.\r
+                            // Curve should be cached\r
+                            SlerpCurve c = (SlerpCurve) ShapeEditorResources.curveBuilder.loadInterpolator(i);\r
+                            Quat4d out = c.evaluate(t);\r
+                            Orientation r = new Orientation(i.getSingleRelatedObject(ShapeEditorResources.animationResource.HasTarget));\r
+                            AxisAngle4d aa = new AxisAngle4d();\r
+                            aa.set(out);\r
+                            G3DTools.setOrientation(r, aa);\r
+                        }\r
+                    }\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void requestCompleted(GraphRequestStatus status) {\r
+                               parent.getScenegraphAdapter().setChanged(true);\r
+                       }\r
+               });   \r
+        }\r
+    }\r
+    \r
+    private IEntity findPropertyInterpolator(Graph g, Resource property) {\r
+       Collection<IEntity> interpolators = getAnimation(g).getRelatedObjects(ShapeEditorResources.animationResource.HasInterpolator);\r
+        for (IEntity i : interpolators) {\r
+            IEntity e = i.getAtMostOneRelatedObject(ShapeEditorResources.animationResource.HasTarget);\r
+            if (e == null)\r
+                continue;\r
+            if (e.getResource().equals(property)) {\r
+                return i;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    private void insertKeyFrame() {\r
+       ArrayList<Resource> instances = new ArrayList<Resource>();\r
+       for (Resource rs : parent.getSelectionAdapter().getCurrentSelection().getSelectionList()) {\r
+               instances.add(rs);\r
+       }\r
+        PropertySelectionDialog dialog = new PropertySelectionDialog(parent.getRenderingComposite().getShell(),"Select property","Select animated property",parent.getSession(),instances);\r
+        if (dialog.open() == Dialog.CANCEL) {\r
+            return;\r
+        }\r
+        final List<Resource> properties = dialog.getSelectedPropertyInstances(); \r
+        parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+               @Override\r
+               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                       for (Resource r : properties) {\r
+                               IEntity t = EntityFactory.create(g,r);\r
+                    IEntity current = findPropertyInterpolator(g, r);\r
+                    if (t.isInstanceOf(ShapeEditorResources.g3dResource.Position)) {\r
+                        \r
+                        for (int i = 0; i < 3; i++) {\r
+                               IEntity d = null;\r
+                            switch (i) {\r
+                            case 0:\r
+                                d = t.getSingleRelatedObject(ShapeEditorResources.g3dResource.HasX);\r
+                                break;\r
+                            case 1:\r
+                               d = t.getSingleRelatedObject(ShapeEditorResources.g3dResource.HasY);\r
+                               break;\r
+                            case 2:\r
+                               d = t.getSingleRelatedObject(ShapeEditorResources.g3dResource.HasZ);\r
+                               break;\r
+                            }\r
+                            current = findPropertyInterpolator(g, d.getResource());\r
+                            addScalarKey(current,d);\r
+                        }\r
+                        \r
+                    } else if (t.isInstanceOf(ShapeEditorResources.g3dResource.Orientation)) {\r
+                        Orientation rot = new Orientation(t);\r
+                        addSlerpKey(current, rot);\r
+                    } else if (t.isInstanceOf(ShapeEditorResources.g3dResource.Color)) {\r
+                        for (int i = 0; i < 3; i++) {\r
+                            IEntity d = null;\r
+                               switch (i) {\r
+                            case 0:\r
+                               d = t.getSingleRelatedObject(ShapeEditorResources.g3dResource.HasRed);\r
+                                break;\r
+                            case 1:\r
+                                break;\r
+                            case 2:\r
+                                break;\r
+                            }\r
+                            current = findPropertyInterpolator(g, d.getResource());\r
+                               addScalarKey(current,d);\r
+                        }\r
+                    } else if (t.isInstanceOf(g.getBuiltins().Double)) {\r
+                       addScalarKey(current,t);\r
+                    } else {\r
+                        // TODO: basic cases are handled, only way to support\r
+                        // is to find all doubles from property structure and\r
+                        // interpolators attached to them, if there's any\r
+                        ErrorLogger.getDefault().logWarning("Default keyframe adding has not been implemented", null);\r
+                    }\r
+                }\r
+                       return GraphRequestStatus.transactionComplete();\r
+               }\r
+        });\r
+    }\r
+    \r
+    private void addScalarKey(IEntity current, IEntity d) {\r
+        \r
+       Graph graph = d.getGraph();\r
+       if (current == null) {\r
+            current = ScalarInterpolator.createDefault(graph).toInterpolator(); // FIXME : stubcast\r
+            getAnimation(graph).addStatement(ShapeEditorResources.animationResource.HasInterpolator, current);\r
+            current.addStatement(ShapeEditorResources.animationResource.HasTarget, d);\r
+        }\r
+        ShapeEditorResources.curveBuilder.addKey(current,getCurrentKey(),new double[]{d.getGraph().getScalarDouble(d.getResource()),0.0,0.0,0.0});\r
+    }\r
+    \r
+    private void addSlerpKey(IEntity current, Orientation r) {\r
+        Graph graph = r.getGraph();\r
+       if (current == null) {\r
+            current = SlerpInterpolator.createDefault(graph).toInterpolator(); // FIXME : stubcast\r
+            getAnimation(graph).addStatement(ShapeEditorResources.animationResource.HasInterpolator, current);\r
+            current.addStatement(ShapeEditorResources.animationResource.HasTarget, r);\r
+            \r
+        }\r
+        AxisAngle4d aa = G3DTools.getOrientation(r);\r
+        Quat4d q = new Quat4d();\r
+        q.set(aa);\r
+        ShapeEditorResources.curveBuilder.addKey(current,getCurrentKey(),new double[]{q.w,q.x,q.y,q.z});  \r
+    }\r
+    \r
+    private void selectAnimation() {\r
+        if (animationCombo.getSelectionIndex() == 0) {\r
+            animationResource = null;\r
+            updateUI();\r
+        } else {\r
+               final String name = animationCombo.getItem(animationCombo.getSelectionIndex());\r
+               parent.getSession().asyncRead(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               \r
+                    Resource modelResource = parent.getModelResource();\r
+                    G3DModel m = new G3DModel(g, modelResource);\r
+                    Collection<Animation> animations = m.getAnimation();\r
+                    boolean found = false;\r
+                    for (Animation a : animations) {\r
+                        if (a.getName().startsWith(name) && a.getName().length() == name.length()) {\r
+                            animationResource = a.getResource();\r
+                            found = true;\r
+                            break;\r
+                        }\r
+                    }\r
+                    if (!found) {\r
+                        ErrorLogger.defaultLogError("Could find animation " + name + " for model " + m.getResource(), null);\r
+                        animationResource = null;\r
+                    }\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       @Override\r
+                       public void requestCompleted(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
+                                       @Override\r
+                                       public void run() {\r
+                                                updateUI();    \r
+                                       }\r
+                               });\r
+                       }\r
+               });\r
+        }       \r
+    }\r
+    \r
+    private Animation getAnimation(Graph graph) {\r
+       return new Animation(graph, animationResource);\r
+    }\r
+\r
+    private void addAnimation() {\r
+        InputDialog d = new InputDialog(parent.getRenderingComposite().getShell(),"Animation name","Animation name","",null);\r
+        if (d.open() == InputDialog.CANCEL) {\r
+            return;\r
+        }\r
+        final String name = d.getValue();\r
+        if (name == null || name.length() == 0) {\r
+            return;\r
+        }\r
+        parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+               @Override\r
+               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                       G3DModel m = parent.getModel(g);\r
+                       Collection<IEntity> animations = m.getRelatedObjects(ShapeEditorResources.animationResource.HasAnimation);\r
+                       for (IEntity a : animations) {\r
+                        if (a.getName().startsWith(name) && a.getName().length() == name.length()) {\r
+                        ErrorLogger.getDefault().logWarning("Cannot add animation with the same name " + name, null);\r
+                        return GraphRequestStatus.transactionCancel();\r
+                    }\r
+                }\r
+\r
+                Animation newAnimation = Animation.createDefault(g);\r
+                newAnimation.setName(name);\r
+                m.addStatement(ShapeEditorResources.animationResource.HasAnimation, newAnimation);\r
+                \r
+                       return GraphRequestStatus.transactionComplete();\r
+               }\r
+\r
+               @Override\r
+               public void requestCompleted(GraphRequestStatus status) {\r
+                       parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
+                               public void run() {\r
+                                       animationCombo.add(name);\r
+                        animationCombo.select(animationCombo.indexOf(name));\r
+                        selectAnimation();\r
+                               }\r
+                       });\r
+               }\r
+        });    \r
+    }\r
+    \r
+    private void removeAnimation() {\r
+        assert(animationResource != null);\r
+        GraphRequestWithResult<String> r = new GraphRequestWithResult<String>() {\r
+               public String performWithResult(Graph g) throws Exception {\r
+                       return getAnimation(g).getName();\r
+               };\r
+        };\r
+        parent.getSession().syncRead(r);\r
+        MessageDialog dialog = new MessageDialog(parent.getRenderingComposite().getShell(),"Confirm",null,"Do you want to remove animation " + r.getResult() ,MessageDialog.QUESTION,new String[]{"Yes","No"},1);\r
+        if (dialog.open() == 1)\r
+               return;\r
+        parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+               String name;\r
+               @Override\r
+               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                       \r
+                       Animation currentAnimation = getAnimation(g);\r
+                       name = currentAnimation.getName();\r
+                parent.getModel(g).removeStatement(ShapeEditorResources.animationResource.HasAnimation, currentAnimation);\r
+                \r
+                       return GraphRequestStatus.transactionComplete();\r
+               }\r
+               \r
+               @Override\r
+               public void requestCompleted(GraphRequestStatus status) {\r
+                       parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
+                               public void run() {\r
+                                       animationCombo.remove(animationCombo.indexOf(name));\r
+                               }\r
+                       });     \r
+               }\r
+        });\r
+    }\r
+    \r
+    private void clearAnimation() {\r
+        assert(animationResource != null);  \r
+        \r
+        parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+               \r
+               boolean proceed;\r
+               @Override\r
+               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                       int size = getAnimation(g).getInterpolator().size();\r
+                       if (size == 0)\r
+                               return GraphRequestStatus.transactionCancel();\r
+                       final String name = getAnimation(g).getName();\r
+                       parent.getRenderingComposite().getDisplay().syncExec(new Runnable() {\r
+                               public void run() {\r
+                                       MessageDialog dialog = new MessageDialog(parent.getRenderingComposite().getShell(),"Confirm",null,"Do you want to clear animation " + name ,MessageDialog.QUESTION,new String[]{"Yes","No"},1);\r
+                           proceed = (dialog.open() != MessageDialog.CANCEL);\r
+                               }\r
+                       });\r
+                       if (proceed) {\r
+                               //getAnimation(g).getInterpolator().clear();\r
+                               getAnimation(g).removeRelatedStatements(ShapeEditorResources.animationResource.HasInterpolator);\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       } else {\r
+                               return GraphRequestStatus.transactionCancel();\r
+                       }\r
+               }\r
+        });\r
+    }\r
\r
+    public Graph createAnimationParameterization(Graph g) {\r
+               if (g.getObjects(parent.getModelResource(), ShapeEditorResources.g3dResource.HasSizingParameter).size() > 0) {\r
+                       ContextGraph graph;\r
+                       if (!(g instanceof ContextGraph)) {\r
+                               graph = new ContextGraph(g);\r
+                               graph.setContext(parent.getModelResource());\r
+                       } else {\r
+                               graph = (ContextGraph)g;\r
+                       }\r
+                       Animation animation = getAnimation(graph);\r
+                       Collection<Interpolator> interpolators = animation.getInterpolator();\r
+                       for (org.simantics.g2d.stubs.anim.Interpolator interpolator : interpolators) {\r
+                       IEntity target = interpolator.getTarget();\r
+                       // check all model properties\r
+                       G3DModel model = parent.getModel(graph);\r
+                       Collection<Property> modelProperties = model.getRelatedProperties(ShapeEditorResources.g3dResource.HasSizingParameter);\r
+                       for (Property p : modelProperties) {\r
+                               IEntity t = EntityFactory.create(graph,p.getResource());\r
+                               // get parameterization equations\r
+                               Collection<IEntity> equations = t.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget);\r
+                               // get parameterized values\r
+                               Collection<IEntity> parameterTargets = new ArrayList<IEntity>();\r
+                               for (IEntity eq : equations) {\r
+                                       Collection<IEntity> tgts = eq.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget);\r
+                                       assert(tgts.size() == 1);\r
+                                       parameterTargets.add(tgts.iterator().next());\r
+                               }\r
+                               // do matching between interpolator targets and parameterized values\r
+                               // TODO : old system did not have inverse relations but current system does.\r
+                               //                it is possible to take interpolation target and find if it is connected to an equation\r
+                               //                this would make code much faster (no more stupid loops over everything)\r
+                               for (IEntity d : parameterTargets) {\r
+                                       if (d.getResource().equals(target.getResource())) {\r
+                                               // get default value for sizing property\r
+                                               Collection<IEntity> prop = t.getRelatedObjects(ShapeEditorResources.g3dResource.HasDefaultDoubleValue);\r
+                                               if (prop.size() == 1) {\r
+                                                       ShapeEditorResources.curveBuilder.parameterize(interpolator, prop.iterator().next().toProperty().getDoubleArray(), p.getDoubleArray());\r
+                                       } else {\r
+                                               ErrorLogger.defaultLogError("Cannot parameterize interpolator " + interpolator.getResource() + " of animation " + animation.getResource() + " since parameter " + p.getResource() + " has no default value", null);\r
+                                       }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+                       \r
+                       return graph;\r
+               } else {\r
+                       return g;\r
+               }\r
+       }\r
+    \r
+    private AnimateRunnable animateRunnable = null;\r
+    \r
+    private void animate() {\r
+        updateUI();\r
+        if (animateButton.getSelection()) {\r
+            if (animateRunnable != null)\r
+                return;\r
+            if (usePrecalculation.getSelection()) {\r
+               parent.getSession().asyncRead(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               Graph graph = parent.createParameterization(g);\r
+                               createAnimationParameterization(graph);\r
+                               for (IGraphicsNode n : parent.getScenegraphAdapter().getNodes()) {\r
+                                       if (n instanceof ISelectableNode) {\r
+                                               if (!((ISelectableNode)n).isVisible())\r
+                                                       continue;\r
+                                       }\r
+                            if (n instanceof Animatable) {\r
+                                ((Animatable)n).setAnimation(graph,animationResource);\r
+                            }\r
+                        }\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void requestCompleted(GraphRequestStatus status) {\r
+                               animateRunnable = new AnimateRunnable();\r
+                        VisualizationScheduler.getInstance().addVisualization(animateRunnable);\r
+                       }\r
+               });\r
+            } else {\r
+               animateRunnable = new AnimateRunnable();\r
+                VisualizationScheduler.getInstance().addVisualization(animateRunnable);\r
+            }\r
+            \r
+        } else {\r
+            if (animateRunnable == null)\r
+                return;       \r
+            VisualizationScheduler.getInstance().removeVisualization(animateRunnable);\r
+            animateRunnable = null;\r
+            if (usePrecalculation.getSelection()) {\r
+               // updateTime updates values to graph if precalculation is not used.\r
+               // we must store current values from animation to synchronize view and graph\r
+               // information so that use can modify animation properly.\r
+               usePrecalculation.setSelection(false);\r
+               updateTime();\r
+               usePrecalculation.setSelection(true);\r
+               for (IGraphicsNode n : parent.getScenegraphAdapter().getNodes()) {\r
+                  if (n instanceof Animatable) {\r
+                      ((Animatable)n).setAnimation(null,null);\r
+                  }\r
+              }\r
+            }\r
+        }\r
+    }\r
+    \r
+    private void updateUI() {\r
+        if (animationResource != null) {\r
+            animateButton.setEnabled(true);\r
+            timeSlider.setEnabled(true);\r
+            if (animateButton.getSelection()) {\r
+                addAnimationButton.setEnabled(false);\r
+                insertKeyFrameButton.setEnabled(false);\r
+                removeAnimationButton.setEnabled(false);\r
+                clearKeyFrameButton.setEnabled(false);\r
+                animationCombo.setEnabled(false);\r
+                usePrecalculation.setEnabled(false);\r
+                clearAnimationButton.setEnabled(false);\r
+            } else {\r
+                addAnimationButton.setEnabled(true);\r
+                insertKeyFrameButton.setEnabled(!parent.getSelectionAdapter().getCurrentSelection().isEmpty());\r
+                removeAnimationButton.setEnabled(true);\r
+                clearKeyFrameButton.setEnabled(false); //FIXME : detect keyframes\r
+                animationCombo.setEnabled(true);\r
+                usePrecalculation.setEnabled(true);\r
+                clearAnimationButton.setEnabled(true);\r
+            }    \r
+        } else {\r
+            timeSlider.setEnabled(false);\r
+            addAnimationButton.setEnabled(true);\r
+            insertKeyFrameButton.setEnabled(false);\r
+            removeAnimationButton.setEnabled(false);\r
+            clearKeyFrameButton.setEnabled(false);\r
+            animateButton.setEnabled(false);\r
+            animateButton.setSelection(false);\r
+            animationCombo.setEnabled(true);\r
+            usePrecalculation.setEnabled(false);\r
+            clearAnimationButton.setEnabled(false);\r
+        }\r
+    }\r
+    \r
+    private void updateKey(double k) {\r
+       key = k;\r
+       if (key >= 1.0)\r
+               key = 0.0;\r
+       else if (key < 0.0)\r
+               key = 1.0;\r
+       timeSlider.setSelection((int)(key*100.0));\r
+    }\r
+    \r
+    private class AnimateRunnable implements Runnable {\r
+        public void run() {\r
+               try {\r
+                       updateKey(key + 0.01);\r
+                       updateTime();\r
+               } catch (Exception e) {\r
+                        VisualizationScheduler.getInstance().removeVisualization(animateRunnable);\r
+               }\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public void fillLocalToolBar(IToolBarManager manager) {\r
+\r
+    }\r
+    \r
+    @Override\r
+    public void fillLocalPullDown(IMenuManager manager) {\r
+       \r
+    }\r
+    \r
+    @Override\r
+    public void dispose() {\r
+       \r
+    }\r
+    \r
+    @Override\r
+    public void run() {\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/CSGModellingContribution.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/CSGModellingContribution.java
new file mode 100644 (file)
index 0000000..dd80c96
--- /dev/null
@@ -0,0 +1,777 @@
+package org.simantics.proconf.g3d.shapeeditor.tools;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.TreeMap;\r
+import java.util.Map.Entry;\r
+\r
+import javax.vecmath.AxisAngle4d;\r
+import javax.vecmath.Point3d;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.IToolBarManager;\r
+import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.FormAttachment;\r
+import org.eclipse.swt.layout.FormData;\r
+import org.eclipse.swt.layout.FormLayout;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.ISharedImages;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.layer0.stubs.Property;\r
+import org.simantics.layer0.utils.EntityFactory;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.instantiation.Instance;\r
+import org.simantics.layer0.utils.instantiation.InstanceFactory;\r
+import org.simantics.proconf.g3d.actions.ContextAction;\r
+import org.simantics.proconf.g3d.actions.FocusAction;\r
+import org.simantics.proconf.g3d.actions.RemoveAction;\r
+import org.simantics.proconf.g3d.actions.RotateAction;\r
+import org.simantics.proconf.g3d.actions.TranslateAction;\r
+import org.simantics.proconf.g3d.actions.WriteAction;\r
+import org.simantics.proconf.g3d.base.EditorContribution;\r
+import org.simantics.proconf.g3d.base.G3DAPI;\r
+import org.simantics.proconf.g3d.base.G3DTools;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.csg.stubs.BooleanOperation;\r
+import org.simantics.proconf.g3d.csg.stubs.CSGModel;\r
+import org.simantics.proconf.g3d.csg.stubs.CSGShape;\r
+import org.simantics.proconf.g3d.csg.stubs.Difference;\r
+import org.simantics.proconf.g3d.csg.stubs.Intersection;\r
+import org.simantics.proconf.g3d.csg.stubs.Primitive;\r
+import org.simantics.proconf.g3d.csg.stubs.Union;\r
+import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
+import org.simantics.proconf.g3d.shapeeditor.Activator;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorBase;\r
+import org.simantics.proconf.g3d.stubs.G3DNode;\r
+import org.simantics.proconf.g3d.stubs.Shape;\r
+import org.simantics.utils.ErrorLogger;\r
+\r
+public class CSGModellingContribution implements EditorContribution {\r
+       \r
+       private static ImageDescriptor INTERSECTION_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID,"icons/intersection.png");\r
+       private static ImageDescriptor UNION_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/union.png");\r
+       private static ImageDescriptor DIFFERENCE_IMAGE = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID,"icons/difference.png");\r
+\r
+       private ShapeEditorBase parent;\r
+       \r
+       private List<ContextAction> actions = new ArrayList<ContextAction>();\r
+       \r
+       private List<Action> addActions = new ArrayList<Action>();\r
+       private ContextAction unionAction;\r
+       private ContextAction differenceAction;\r
+       private ContextAction intersectionAction;\r
+       private ContextAction splitAction;\r
+       private ContextAction linkAction;\r
+       private ContextAction unlinkAction;\r
+       private ContextAction translateAction;\r
+       private ContextAction rotateAction;\r
+       private ContextAction removeAction;\r
+       \r
+       private Composite infoComposite;\r
+       private Text infoText;\r
+       \r
+       \r
+       public CSGModellingContribution(ThreeDimensionalEditorBase parent) {\r
+               this.parent = (ShapeEditorBase)parent;  \r
+       }\r
+       \r
+       @Override\r
+       public String getName() {\r
+               return "Shape Editing";\r
+       }\r
+       \r
+       @Override\r
+       public void initialize(Graph graph) {\r
+               makeActions(graph);\r
+       }\r
+       \r
+       @Override\r
+       public void createControl(Composite parent) {\r
+               FormLayout flayout = new FormLayout();\r
+               parent.setLayout(flayout);\r
+               infoComposite = new Composite(parent, SWT.BORDER);\r
+               FormData data = new FormData();\r
+               data.top = new FormAttachment(0, 0);\r
+               data.left = new FormAttachment(0, 0);\r
+               data.right = new FormAttachment(100, 0);\r
+               data.bottom = new FormAttachment(infoComposite, 0, SWT.TOP);\r
+               this.parent.getRenderingComposite().setLayoutData(data);\r
+               data = new FormData();\r
+               data.left = new FormAttachment(0, 0);\r
+               data.right = new FormAttachment(100, 0);\r
+               data.bottom = new FormAttachment(100, 0);\r
+               data.height = 18;\r
+               infoComposite.setLayoutData(data);\r
+               GridLayout layout = new GridLayout(1,false);\r
+               layout.marginWidth = 1;\r
+               layout.marginHeight = 1;\r
+               infoComposite.setLayout(layout);\r
+               infoText = new Text(infoComposite, SWT.NONE);\r
+               GridData gdata = new GridData();\r
+               gdata.grabExcessHorizontalSpace = true;\r
+               gdata.horizontalAlignment = SWT.FILL;\r
+               infoText.setLayoutData(gdata);\r
+       }\r
+       \r
+       @Override\r
+       public void disposeControl() {\r
+               infoComposite.dispose();\r
+       }\r
+       \r
+       @Override\r
+       public void fillContextMenu(Graph graph, IMenuManager manager, StructuredResourceSelection selection) {\r
+\r
+               if (selection.isEmpty()) {\r
+                       MenuManager addMenu = new MenuManager("Add", "add");\r
+                       addMenu.setRemoveAllWhenShown(false);\r
+                       for (Action a : addActions) {\r
+                               addMenu.add(a);\r
+                       }\r
+                       manager.add(addMenu);\r
+               }\r
+\r
+       }\r
+       \r
+       protected void makeActions(Graph graph) {\r
+               actions.add(translateAction = new TranslateAction(parent) {\r
+                       @Override\r
+                       public void setInfoText(String text) {\r
+                               infoText.setText(text);\r
+                       }\r
+               });\r
+               actions.add(rotateAction = new RotateAction(parent){\r
+                       @Override\r
+                       public void setInfoText(String text) {\r
+                               infoText.setText(text);\r
+                       }\r
+               });\r
+               actions.add(removeAction = new RemoveAction(parent));\r
+               actions.add(new FocusAction(parent));\r
+\r
+               \r
+               IEntity primitive = EntityFactory.create(graph,ShapeEditorResources.csgResource.Primitive);\r
+               \r
+               Collection<IEntity> primitives = primitive.getRelatedObjects(graph.getBuiltins().SupertypeOf);\r
+\r
+               TreeMap<String, Resource> sorter = new TreeMap<String, Resource>();\r
+               for (IEntity p : primitives) {\r
+                       String key = p.getName();\r
+                       if (key.equals(""))\r
+                               key = "ERROR (" + p.getURI() + ")";\r
+                       sorter.put(key, p.getResource());\r
+               }\r
+\r
+               for (Entry<String, Resource> e : sorter.entrySet()) {\r
+                       final String name = e.getKey();\r
+                       final Resource r = e.getValue();\r
+                       Action a = new Action() {\r
+                               Resource res;\r
+                               public void run() {\r
+                                       parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                                               @Override\r
+                                               public GraphRequestStatus perform(Graph g) throws Exception {\r
+\r
+                                                       Instance ins = InstanceFactory.getInstanceOfType(g,r);\r
+                                                       Resource instance = ins.instantiate(g);\r
+                                                       Shape shape = new Shape(g,instance);\r
+                                                       res = shape.getResource();\r
+                                                       resetShape(shape);\r
+                                                       CSGModel model = new CSGModel(g,parent.getModelResource());\r
+                                                       model.addStatement(ShapeEditorResources.g3dResource.HasChild, shape.getResource());\r
+                                                       return GraphRequestStatus.transactionComplete();\r
+                                               }\r
+                                               \r
+                                               @Override\r
+                                               public void handleException(Throwable e) {\r
+                                                       super.handleException(e);\r
+                                                       ErrorLogger.defaultLogError("Adding " + name + " failed.", e);\r
+                                               }\r
+                                               \r
+                                               @Override\r
+                                               public void requestCompleted(GraphRequestStatus status) {\r
+                                                       parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                                               public void run() {\r
+                                                                       parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(res));\r
+                                                               }\r
+                                                       });\r
+                                               }\r
+                                       });\r
+                               }\r
+                       };\r
+                       a.setText(name);\r
+                       a.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));\r
+                       addActions.add(a);\r
+\r
+               }\r
+\r
+               unionAction = new WriteAction(parent,false) {\r
+\r
+                       Resource r;\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() >= 2)\r
+                                       return true;\r
+                               return false;\r
+                       }\r
+\r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter().getSelectedObjects();\r
+                               if (list.size() < 2) {\r
+                                       showMessage("Union works between two objects");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               Resource r1 = list.get(0).getResource();\r
+                               CSGShape shape1 = new CSGShape(graph,r1);\r
+\r
+                               G3DNode parent = shape1.getParent();\r
+                               if (parent == null) {\r
+                                       showMessage("Primary shape has no parent, don't know what to do");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               BooleanOperation op = Union.createDefault(graph).toBooleanOperation(); //FIXME : stubcast\r
+                               r = op.getResource();\r
+                               if (createBooleanOp(op, parent, shape1, list))\r
+                                       return GraphRequestStatus.transactionComplete();\r
+                               else\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void afterChanges(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                       public void run() {\r
+                                               parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(r));\r
+                                       }\r
+                               });\r
+                       }\r
+               };\r
+               unionAction.setText("Union");\r
+               unionAction.setToolTipText("Union");\r
+               unionAction.setImageDescriptor(UNION_IMAGE);\r
+\r
+               differenceAction = new WriteAction(parent,false) {\r
+\r
+                       Resource r;\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() >= 2)\r
+                                       return true;\r
+                               return false;\r
+                       }\r
+\r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter().getSelectedObjects();\r
+                               if (list.size() < 2) {\r
+                                       showMessage("Difference works between two objects");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               CSGShape shape1 = new CSGShape(graph,list.get(0).getResource());\r
+                               G3DNode parent = shape1.getParent();\r
+                               if (parent == null) {\r
+                                       showMessage("Primary shape has no parent, don't know what to do");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               BooleanOperation op = Difference.createDefault(graph).toBooleanOperation(); //FIXME : stubcast\r
+                               r = op.getResource();\r
+                               if (createBooleanOp(op, parent, shape1, list))\r
+                                       return GraphRequestStatus.transactionComplete();\r
+                               else\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void afterChanges(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                       public void run() {\r
+                                               parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(r));\r
+                                       }\r
+                               });\r
+                       }\r
+               };\r
+               differenceAction.setText("Difference");\r
+               differenceAction.setToolTipText("Difference");\r
+               differenceAction.setImageDescriptor(DIFFERENCE_IMAGE);\r
+\r
+               intersectionAction = new WriteAction(parent,false) {\r
+                       Resource r;\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() >= 2)\r
+                                       return true;\r
+                               return false;\r
+                       }\r
+\r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter()\r
+                                               .getSelectedObjects();\r
+                               if (list.size() < 2) {\r
+                                       showMessage("Intersection works between two objects");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               CSGShape shape1 = new CSGShape(graph,list.get(0).getResource());\r
+                               G3DNode parent = shape1.getParent();\r
+                               if (parent == null) {\r
+                                       showMessage("Primary shape has no parent, don't know what to do");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               BooleanOperation op = Intersection.createDefault(graph).toBooleanOperation(); //FIXME : stubcast\r
+                               r = op.getResource();\r
+                               if (createBooleanOp(op, parent, shape1, list))\r
+                                       return GraphRequestStatus.transactionComplete();\r
+                               else\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void afterChanges(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                       public void run() {\r
+                                               parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(r));\r
+                                       }\r
+                               });\r
+                               \r
+                       }\r
+               };\r
+               intersectionAction.setText("Intersection");\r
+               intersectionAction.setToolTipText("Intersection");\r
+               intersectionAction.setImageDescriptor(INTERSECTION_IMAGE);\r
+\r
+               splitAction = new WriteAction(parent,false) {\r
+\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() == 1) {\r
+                                       Resource r = resources.iterator().next();\r
+                                       IEntity t = EntityFactory.create(graph,r);\r
+                                       if (t.isInstanceOf(ShapeEditorResources.csgResource.BooleanOperation)) {\r
+                                               return true;\r
+                                       }\r
+                               }\r
+\r
+                               return false;\r
+                       }\r
+                       \r
+                       \r
+                       \r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter().getSelectedObjects();\r
+                               if (list.size() != 1) {\r
+                                       showMessage("Split requires one object");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               Resource deletedResource = list.get(0).getResource();\r
+                               IEntity deletedEntity = EntityFactory.create(graph,deletedResource);\r
+                               if (!deletedEntity.isInstanceOf(ShapeEditorResources.csgResource.BooleanOperation)) {\r
+                                       showMessage("Split requires boolean operation");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               Collection<IEntity> parents = deletedEntity.getRelatedObjects(ShapeEditorResources.g3dResource.HasParent);\r
+                               if (parents.size() != 1) {\r
+                                       showMessage("Shape has " + parents.size()\r
+                                                       + " parents, don't know what to do");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               IEntity parent = parents.iterator().next();\r
+                               // find all shapes and their positions and orientations relative to world coordinates\r
+                               BooleanOperation op = new BooleanOperation(deletedEntity);\r
+                               CSGShape shape1 = op.getMainShape();\r
+                               Point3d shape1WorldPos = G3DTools.getPoint(shape1.getWorldPosition());\r
+                               AxisAngle4d shape1WorldRot = G3DTools.getOrientation(shape1.getWorldOrientation());\r
+                               //System.out.println(shape1WorldPos + " " + shape1WorldRot);\r
+                               Collection<CSGShape> shape2s = op.getSecondaryShape();\r
+\r
+                               ArrayList<Point3d> shape2WorldPos = new ArrayList<Point3d>();\r
+                               ArrayList<AxisAngle4d> shape2WorldRot = new ArrayList<AxisAngle4d>();\r
+                               for (CSGShape shape : shape2s) {\r
+                                       Point3d pos = G3DTools.getPoint(shape.getWorldPosition());\r
+                                       AxisAngle4d rot = G3DTools.getOrientation(shape.getWorldOrientation());\r
+                                       shape2WorldPos.add(pos);\r
+                                       shape2WorldRot.add(rot);\r
+                                       //System.out.println(pos + " " + rot);\r
+                               }\r
+\r
+                               // removed boolean operation is either connected to model or another boolean operation.\r
+                               CSGModel m = new CSGModel(graph,CSGModellingContribution.this.parent.getModelResource());\r
+                               if (parent.getResource().equals(CSGModellingContribution.this.parent.getModelResource())) {\r
+                                       // if deleted boolean operation is connected to the model,\r
+                                       // all its children are added to the model\r
+\r
+                                       m.removeStatement(ShapeEditorResources.g3dResource.HasChild, op);\r
+                                       m.addStatement(ShapeEditorResources.g3dResource.HasChild, shape1);\r
+                                       for (CSGShape shape2 : shape2s) {\r
+                                               m.addStatement(ShapeEditorResources.g3dResource.HasChild, shape2);\r
+                                       }\r
+\r
+                               } else {\r
+                                       // deleted boolean operation is connected to another boolean\r
+                                       // operation\r
+                                       // if the deleted boolean operation is primary child, we'll\r
+                                       // must replace it with deleted boolean operations\r
+                                       // primary child\r
+                                       if (!parent.isInstanceOf(ShapeEditorResources.csgResource.BooleanOperation)) {\r
+                                               ErrorLogger.defaultLogError("Parent shape is not a boolean operation nor model ?!", null);\r
+                                               return GraphRequestStatus.transactionCancel();\r
+                                       }\r
+                                       BooleanOperation parentOp = new BooleanOperation(parent);\r
+                                       // we'll have to list all secondary shapes in parent boolean\r
+                                       // op so that we can find the correct relatio\r
+                                       Collection<IEntity> parentShape2s = parentOp.getRelatedObjects(ShapeEditorResources.csgResource.HasSecondaryShape);\r
+\r
+                                       if (parentOp.getMainShape().getResource().equals(deletedResource)) {\r
+                                               // split boolean operation is the primary child in the\r
+                                               // parent boolean operation\r
+                                               parent.removeStatement(ShapeEditorResources.csgResource.HasMainShape,deletedResource);\r
+                                               // graph.commitChanges(ShapeEditorView.this);\r
+                                               parent.addStatement(ShapeEditorResources.csgResource.HasMainShape, shape1);\r
+                                               // graph.commitChanges(ShapeEditorView.this);\r
+                                               for (CSGShape shape2 : shape2s) {\r
+                                                       m.addStatement(ShapeEditorResources.g3dResource.HasChild, shape2);\r
+                                               }\r
+                                       } else if (contains(parentShape2s, deletedResource)) {\r
+                                               // split boolean operation is one of the secondary\r
+                                               // shapes in the parent boolean operation\r
+                                               parent.removeStatement(ShapeEditorResources.csgResource.HasSecondaryShape,deletedResource);\r
+                                               // graph.commitChanges(ShapeEditorView.this);\r
+                                               parent.addStatement(ShapeEditorResources.csgResource.HasSecondaryShape,shape1);\r
+                                               // graph.commitChanges(ShapeEditorView.this);\r
+\r
+                                               // model.getConsistOfShapeSet().add(shape2);\r
+                                               for (CSGShape shape2 : shape2s) {\r
+                                                       m.addStatement(ShapeEditorResources.g3dResource.HasChild, shape2);\r
+                                               }\r
+                                       } else {\r
+                                               ErrorLogger.defaultLogError("Parent shape is not a boolean operation nor model ?!", null);\r
+                                               return GraphRequestStatus.transactionCancel();\r
+                                       }\r
+                               }\r
+                               deletedEntity.removeStatement(ShapeEditorResources.csgResource.HasMainShape, shape1);\r
+                               for (CSGShape shape2 : shape2s)\r
+                                       deletedEntity.removeStatement(ShapeEditorResources.csgResource.HasSecondaryShape, shape2);\r
+                               //graph.commit();\r
+                               //System.out.println("Setting original transformations");\r
+                               //G3DTools.setTuple3(shape1.getWorldPosition(), shape1WorldPos);\r
+                               //G3DTools.setOrientation(shape1.getWorldOrientation(), shape1WorldRot);\r
+                               G3DAPI.setWorldTransformation(shape1, shape1WorldPos,shape1WorldRot);\r
+                               \r
+                               int i = 0;\r
+                               for (CSGShape shape : shape2s) {\r
+                                       G3DAPI.setWorldTransformation(shape, shape2WorldPos.get(i),shape2WorldRot.get(i));\r
+                                       //G3DTools.setTuple3(shape.getWorldPosition(), shape2WorldPos.get(i));\r
+                                       //G3DTools.setOrientation(shape.getWorldOrientation(),shape2WorldRot.get(i));\r
+                                       i++;\r
+                               }\r
+                               return GraphRequestStatus.transactionComplete();\r
+\r
+                       }\r
+               };\r
+               splitAction.setText("Split");\r
+               splitAction.setToolTipText("Split");\r
+               splitAction.setImageDescriptor(PlatformUI.getWorkbench()\r
+                               .getSharedImages().getImageDescriptor(\r
+                                               ISharedImages.IMG_OBJS_INFO_TSK));\r
+\r
+               linkAction = new WriteAction(parent,false) {\r
+                       Resource r;\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() == 2) {\r
+                                       Iterator<Resource> i = resources.iterator();\r
+                                       Shape s1 = new Shape(graph,i.next());\r
+                                       Shape s2 = new Shape(graph,i.next());\r
+                                       if (s1.getRelatedObjects(ShapeEditorResources.g3dResource.GeometryDefinitionOf).size() == 0 &&\r
+                                               s2.getRelatedObjects(ShapeEditorResources.g3dResource.GeometryDefinitionOf).size() == 0)\r
+                                               return true;\r
+\r
+                               }\r
+                               return false;\r
+                       }\r
+\r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter().getSelectedObjects();\r
+                               if (list.size() != 2) {\r
+                                       showMessage("Link works between two objects");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               Resource r1 = list.get(0).getResource();\r
+                               Resource r2 = list.get(1).getResource();\r
+\r
+                               CSGShape shape1 = new CSGShape(graph,r1);\r
+                               CSGShape shape2 = new CSGShape(graph,r2);\r
+                               \r
+                               Point3d p = G3DTools.getPoint(shape2.getWorldPosition());\r
+                               AxisAngle4d aa = G3DTools.getOrientation(shape2.getWorldOrientation());\r
+                               //System.out.println(p + " " + aa);\r
+                               shape2.removeRelatedStatements(ShapeEditorResources.g3dResource.HasParent);\r
+                               r = shape2.getResource();\r
+                               //System.out.println("Link remove commit");\r
+                               //graph.commitChanges(ShapeEditorView.this);\r
+                               //shape1.getChild().add(shape2.toG3DNode()); //FIXME : stubcast\r
+                               shape1.addStatement(ShapeEditorResources.g3dResource.HasChild, shape2);\r
+                               // FIXME : this is needed\r
+                               //System.out.println("Link add commit");\r
+                               //graph.commitChanges(ShapeEditorView.this);\r
+                               //G3DTools.setTuple3(shape2.getWorldPosition(), p);\r
+                               //G3DTools.setOrientation(shape2.getWorldOrientation(), aa);\r
+                               G3DAPI.setWorldTransformation(shape2, p, aa);\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void afterChanges(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                       public void run() {\r
+                                               parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(r));\r
+                                       }\r
+                               });\r
+                       }\r
+               };\r
+               linkAction.setText("Link");\r
+               linkAction.setToolTipText("Link");\r
+               linkAction.setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/link.png"));\r
+\r
+               unlinkAction = new WriteAction(parent,false) {\r
+                       Resource r;\r
+                       @Override\r
+                       public boolean usable(Graph graph,List<Resource> resources) {\r
+                               if (resources.size() == 1) {\r
+                                       Iterator<Resource> i = resources.iterator();\r
+                                       Shape s1 = new Shape(graph,i.next());\r
+                                       return (s1.getRelatedObjects(ShapeEditorResources.g3dResource.GeometryDefinitionOf).size() == 0\r
+                                                       && s1.getParent() != null && !s1.getParent()\r
+                                                       .getResource().equals(CSGModellingContribution.this.parent.getModelResource()));\r
+\r
+                               }\r
+                               return false;\r
+                       }\r
+\r
+                       public GraphRequestStatus doChanges(Graph graph) {\r
+                               List<IGraphicsNode> list = parent.getSelectionAdapter().getSelectedObjects();\r
+                               if (list.size() != 1) {\r
+                                       showMessage("Unlink works with one object");\r
+                                       return GraphRequestStatus.transactionCancel();\r
+                               }\r
+                               Resource r1 = list.get(0).getResource();\r
+\r
+                               CSGShape shape1 = new CSGShape(graph,r1);\r
+                               CSGModel m = new CSGModel(graph,CSGModellingContribution.this.parent.getModelResource());\r
+                               Point3d p = G3DTools.getPoint(shape1.getWorldPosition());\r
+                               AxisAngle4d aa = G3DTools.getOrientation(shape1.getWorldOrientation());\r
+                               shape1.removeRelatedStatements(ShapeEditorResources.g3dResource.HasParent);\r
+                               //graph.commitChanges(ShapeEditorView.this);\r
+                               m.addStatement(ShapeEditorResources.g3dResource.HasChild, shape1);\r
+                               // FIXME : this is needed\r
+                               //graph.commitChanges(ShapeEditorView.this);\r
+                               //G3DTools.setTuple3(shape1.getWorldPosition(), p);\r
+                               //G3DTools.setOrientation(shape1.getWorldOrientation(), aa);\r
+                               G3DAPI.setWorldTransformation(shape1, p, aa);\r
+                               r = shape1.getResource();\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void afterChanges(GraphRequestStatus status) {\r
+                               parent.getRenderingComposite().getDisplay().asyncExec(new Runnable(){\r
+                                       public void run() {\r
+                                               parent.getSelectionAdapter().updateSelection(new StructuredResourceSelection(r));\r
+                                       }\r
+                               });\r
+                       }\r
+               };\r
+               unlinkAction.setText("Unlink");\r
+               unlinkAction.setToolTipText("Unlink");\r
+               unlinkAction.setImageDescriptor(Activator.imageDescriptorFromPlugin(\r
+                               Activator.PLUGIN_ID, "icons/unlink.png"));\r
+\r
+               actions.add(unionAction);\r
+               actions.add(intersectionAction);\r
+               actions.add(differenceAction);\r
+               actions.add(splitAction);\r
+               actions.add(linkAction);\r
+               actions.add(unlinkAction);\r
+       }\r
+       \r
+       boolean contains(ArrayList<Resource> parentShape2sIds, Resource id) {\r
+               for (int i = 0; i < parentShape2sIds.size(); i++) {\r
+                       if (parentShape2sIds.get(i).equals(id))\r
+                               return true;\r
+\r
+               }\r
+               return false;\r
+       }\r
+       \r
+       boolean contains(Collection<IEntity> parentShape2sIds, Resource id) {\r
+               for (IEntity e : parentShape2sIds) {\r
+                       if (e.getResource().equals(id))\r
+                               return true;\r
+\r
+               }\r
+               return false;\r
+       }\r
+\r
+       private boolean createBooleanOp(BooleanOperation op, G3DNode parent,\r
+                       CSGShape shape1, List<IGraphicsNode> list) {\r
+\r
+               resetShape(op.toShape()); //FIXME : stubcast\r
+               // new boolean operation is added to the first shape's parent\r
+               // the parent is the model\r
+\r
+               Point3d refPos = G3DTools.getPoint(shape1.getLocalPosition());\r
+               G3DTools.setTuple3(op.getLocalPosition(), refPos);\r
+               refPos.negate();\r
+               G3DTools.addTuple3(shape1.getLocalPosition(), refPos);\r
+               op.removeRelatedStatements(ShapeEditorResources.csgResource.HasMainShape);\r
+               op.addStatement(ShapeEditorResources.csgResource.HasMainShape, shape1);\r
+               \r
+               if (!replaceShape(parent, shape1.toShape(), op.toShape())) { //FIXME : stubcast\r
+                       return false;\r
+               }\r
+               //model.getConsistOfSet().remove(shape1);\r
+               for (int i = 1; i < list.size(); i++) {\r
+                       CSGShape shape2 = new CSGShape(op.getGraph(),list.get(i).getResource());\r
+                       G3DTools.addTuple3(shape2.getLocalPosition(), refPos);\r
+                       G3DNode shape2parent = shape2.getParent();\r
+                       if (shape2parent != null) {\r
+                               // we'll must link before removing or shape will be deleted\r
+                               //op.addStatement(ShapeEditorResources.csgResource.HasSecondaryShape,shape2);                   \r
+                               //if (!replaceShape(shape2parent, shape2, null)) {\r
+                               //      op.removeStatement(ShapeEditorResources.csgResource.HasSecondaryShape, shape2);\r
+                               //      // shape couldn't be removed so we'll remove the link\r
+                               //}\r
+                               \r
+                               if (replaceShape(shape2parent, shape2.toShape(), null)) { //FIXME : stubcast\r
+                                       op.addStatement(ShapeEditorResources.csgResource.HasSecondaryShape,shape2);\r
+                               }\r
+                       }\r
+               }\r
+               // Commit is not needed because this is final call in all transactions\r
+               //graph.commitChanges(ShapeEditorView.this);\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Replaces or removes parent from shape\r
+        * @param parent parent containing shape\r
+        * @param removed the shape\r
+        * @param added the replacing shape or null\r
+        * @return true if replacing or removing was successful\r
+        * @throws TransactionException\r
+        */\r
+       private boolean replaceShape(G3DNode parent, Shape removed, Shape added) {\r
+               assert (parent != null);\r
+               assert (removed != null);\r
+\r
+               \r
+               //CSGModel m = CSGModelFactory.create(parent.getGraph(),model);\r
+               if (parent.getResource().equals(this.parent.getModelResource())) {\r
+                       // parent is model (rootnode). \r
+                       // shape is connected to it with "Has Child" relation\r
+                       parent.removeStatement(ShapeEditorResources.g3dResource.HasChild, removed);\r
+                       if (added != null) {\r
+                               parent.addStatement(ShapeEditorResources.g3dResource.HasChild, added);\r
+                       }\r
+               } else {\r
+                       // the first shape's parent is boolean operation\r
+                       // so we must know if its connected as a primary shape or as a secondary shape\r
+                       if (!parent.isInstanceOf(ShapeEditorResources.csgResource.BooleanOperation)) {\r
+                               ErrorLogger.defaultLogError("Parent shape is not a boolean operation nor model ?!",null);\r
+                               return false;\r
+                       }\r
+                       BooleanOperation parentOp = new BooleanOperation(parent);\r
+                       // listing all secondary shapes in the parent boolean operation\r
+                       Collection<CSGShape> parentShape2s = parentOp.getSecondaryShape();\r
+                       ArrayList<Resource> parentShape2sIds = new ArrayList<Resource>();\r
+                       for (CSGShape shape2 : parentShape2s)\r
+                               parentShape2sIds.add(shape2.getResource());\r
+                       if (parentOp.getMainShape().getResource().equals(removed.getResource())) {\r
+                               if (added == null) {\r
+                                       return false;\r
+                               }\r
+                               parent.removeStatement(ShapeEditorResources.csgResource.HasMainShape, removed);\r
+                               parent.addStatement(ShapeEditorResources.csgResource.HasMainShape, added);\r
+                       \r
+                       } else if (contains(parentShape2sIds, removed.getResource())) {\r
+\r
+                               parent.removeStatement(ShapeEditorResources.csgResource.HasSecondaryShape, removed);\r
+                               parent.addStatement(ShapeEditorResources.csgResource.HasSecondaryShape, added); \r
+               \r
+                       } else {\r
+                               ErrorLogger.defaultLogError("Parent shape is not a boolean operation nor model ?!",null);\r
+                               //coreTC.cancelTransaction();\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Resets shape to identity rotation and zero translation\r
+        * \r
+        * @param shape\r
+        */\r
+       private void resetShape(Shape shape) {\r
+               G3DTools.resetTransformation(shape);\r
+               Graph graph = shape.getGraph();\r
+               if (shape.isInstanceOf(ShapeEditorResources.csgResource.Primitive)) {\r
+                       Primitive prim = new Primitive(shape);\r
+                       Collection<Property> c = prim.getSizingProperty();\r
+                       if (c.size() == 0)\r
+                               ErrorLogger.getDefault().logWarning("Shape does not contain sizing properties.", null);\r
+                       \r
+                       for (Property p : c) {\r
+                               if (p.isInstanceOf(graph.getBuiltins().Double)) {\r
+                                       graph.setScalarDouble(p.getResource(), 1.0);\r
+                               } else if (p.isInstanceOf(graph.getBuiltins().Integer)) {\r
+                                       graph.setScalarInteger(p.getResource(), 1);\r
+                               } else {\r
+                                       ErrorLogger.getDefault().logWarning("Cannot handle sizing property " + p.getName() , null);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+       }\r
+       \r
+       protected void showMessage(String s) {\r
+               parent.showMessage(s);\r
+       }\r
+       \r
+       @Override\r
+       public Collection<ContextAction> getActions() {\r
+               return actions;\r
+       }\r
+       \r
+       \r
+       @Override\r
+       public void fillLocalToolBar(IToolBarManager manager) {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void fillLocalPullDown(IMenuManager manager) {\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void dispose() {\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void run() {\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/ParameterizationContribution.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/tools/ParameterizationContribution.java
new file mode 100644 (file)
index 0000000..3f1fefa
--- /dev/null
@@ -0,0 +1,680 @@
+package org.simantics.proconf.g3d.shapeeditor.tools;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.IToolBarManager;\r
+import org.eclipse.jface.dialogs.InputDialog;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.layout.FormAttachment;\r
+import org.eclipse.swt.layout.FormData;\r
+import org.eclipse.swt.layout.FormLayout;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Sash;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.forms.IFormColors;\r
+import org.eclipse.ui.forms.events.ExpansionAdapter;\r
+import org.eclipse.ui.forms.events.ExpansionEvent;\r
+import org.eclipse.ui.forms.widgets.FormToolkit;\r
+import org.eclipse.ui.forms.widgets.ScrolledForm;\r
+import org.eclipse.ui.forms.widgets.Section;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.equation.stubs.SecondOrderScalarPolynomial;\r
+import org.simantics.g2d.stubs.anim.Animation;\r
+import org.simantics.g2d.stubs.anim.Interpolator;\r
+import org.simantics.layer0.utils.EntityFactory;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.ResourceDebugUtils;\r
+import org.simantics.proconf.browsing.GraphExplorer;\r
+import org.simantics.proconf.browsing.GraphExplorerInputFactory;\r
+import org.simantics.proconf.browsing.views.PropertyTable;\r
+import org.simantics.proconf.g3d.actions.ContextAction;\r
+import org.simantics.proconf.g3d.base.EditorContribution;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator;\r
+import org.simantics.proconf.g3d.shapeeditor.views.ShapeEditorBase;\r
+import org.simantics.proconf.g3d.stubs.G3DModel;\r
+import org.simantics.proconf.g3d.tools.OESelectionListener;\r
+import org.simantics.proconf.g3d.tools.PropertyTree;\r
+import org.simantics.utils.ui.jface.BaseSelectionProvider;\r
+\r
+\r
+public class ParameterizationContribution implements EditorContribution {\r
+\r
+       private ShapeEditorBase parent;\r
+       private List<ContextAction> actions = new ArrayList<ContextAction>();\r
+       private Composite sideComposite;\r
+       private Sash sash;\r
+       \r
+       \r
+       public ParameterizationContribution(ThreeDimensionalEditorBase parent) {\r
+               this.parent = (ShapeEditorBase) parent;\r
+       }\r
+       \r
+       @Override\r
+       public void createControl(final Composite parentComposite) {\r
+               FormLayout flayout = new FormLayout();\r
+               parentComposite.setLayout(flayout);\r
+               sash = new Sash(parentComposite,SWT.VERTICAL);\r
+               \r
+               sideComposite = new Composite(parentComposite,SWT.BORDER);\r
+               FormData data = new FormData();\r
+               data.top = new FormAttachment(0, 0);\r
+               data.left = new FormAttachment(0, 0);\r
+               data.right = new FormAttachment(sash, 0, SWT.LEFT);\r
+               data.bottom = new FormAttachment(100,0);\r
+               this.parent.getRenderingComposite().setLayoutData(data);\r
+               sideComposite.setLayout(new FillLayout(SWT.VERTICAL));\r
+               data = new FormData();\r
+               data.top = new FormAttachment(0, 0);\r
+               data.bottom = new FormAttachment(100,0);\r
+               data.right = new FormAttachment(100,0);\r
+               data.left = new FormAttachment(sash,0,SWT.RIGHT);\r
+               sideComposite.setLayoutData(data);\r
+               \r
+               final int limit = 20, percent = 50;\r
+               final FormData sashData = new FormData();\r
+               sashData.left = new FormAttachment (percent, 0);\r
+               sashData.top = new FormAttachment(0, 0);\r
+               sashData.bottom = new FormAttachment(100,0);\r
+               \r
+               sash.setLayoutData (sashData);\r
+               sash.addListener (SWT.Selection, new Listener () {\r
+                       public void handleEvent (Event e) {\r
+                               Rectangle sashRect = sash.getBounds ();\r
+                               Rectangle shellRect = parentComposite.getClientArea ();\r
+                               int right = shellRect.width - sashRect.width - limit;\r
+                               e.x = Math.max (Math.min (e.x, right), limit);\r
+                               if (e.x != sashRect.x)  {\r
+                                       sashData.left = new FormAttachment (0, e.x);\r
+                                       parentComposite.layout ();\r
+                               }\r
+                       }\r
+               });\r
+               createForm(sideComposite);\r
+               \r
+               hierarchyExplorer.setInput(parent.getSessionContext(),GraphExplorerInputFactory.clone(hierarchyExplorer.getInput())\r
+                   .input(parent.getModelResource())\r
+                   .viewpoint(ViewpointGenerator.createObjectStructureViewpoint())\r
+                   .toInput());\r
+\r
+//        parameterExplorer.setInput(parent.getSessionContext(),GraphExplorerInputFactory.clone(parameterExplorer.getInput())\r
+//                .input(parent.getModelResource())\r
+//                .viewpoint(ViewpointGenerator.createObjectSizingParameterViewpoint(ShapeEditorResources.g3dResource.HasSizingParameter))\r
+//                .toInput());\r
+               parameterTable.setSession(parent.getSession());\r
+               parameterTable.setInput(new StructuredResourceSelection(parent.getModelResource()));\r
+        \r
+       }\r
+       \r
+       @Override\r
+       public void disposeControl() {\r
+               sideComposite.dispose();\r
+               sash.dispose();\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void dispose() {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void fillContextMenu(Graph graph, IMenuManager manager,\r
+                       StructuredResourceSelection selection) {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void fillLocalPullDown(IMenuManager manager) {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void fillLocalToolBar(IToolBarManager manager) {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public Collection<ContextAction> getActions() {\r
+               return actions;\r
+       }\r
+       \r
+       @Override\r
+       public String getName() {\r
+               return "Parameterization";\r
+       }\r
+       \r
+       @Override\r
+       public void initialize(Graph graph) {\r
+\r
+       }\r
+       \r
+       @Override\r
+       public void run() {\r
+               \r
+       }\r
+       \r
+       private ScrolledForm form;\r
+       private BaseSelectionProvider defaultInputSelectionProvider = new BaseSelectionProvider();\r
+       protected FormToolkit toolkit;\r
+       \r
+\r
+    \r
+    private void createForm(Composite parent) {\r
+       toolkit = new FormToolkit(parent.getDisplay());\r
+               form = getToolkit().createScrolledForm(parent);\r
+\r
+               GridLayout layout = new GridLayout(2, false);\r
+               form.getBody().setLayout(layout);\r
+               form.getBody().setLayoutData(\r
+                               new GridData(GridData.FILL, GridData.FILL, true, true));\r
+\r
+               // By default make this ViewPart use a default ISelectionProvider\r
+               // that will offer the viewparts input resource as its selection.\r
+               // The Resource is wrapped into a ResourceSelection object.\r
+               // Any widgets created in createWidgets may override the default\r
+               // selection provider.\r
+               //getEditorSite().setSelectionProvider(defaultInputSelectionProvider);\r
+\r
+               beforeCreateWidgets();\r
+               createWidgets();\r
+\r
+               //reload();\r
+\r
+               form.setText(getFormText());\r
+\r
+               // Finally Set the default selection which will have an effect only\r
+               // if nothing in createWidgets has overridden the default selection\r
+               // provider.\r
+//             ISelection s = ISelectionUtils\r
+//                             .createSelection(new StructuredResourceSelection(\r
+//                                             getInputResource()));\r
+//             defaultInputSelectionProvider.setSelection(s);\r
+    }\r
+    \r
+       \r
+       public ScrolledForm getActiveForm() {\r
+               return form;\r
+       }\r
+\r
+       protected Composite getBody() {\r
+               return form.getBody();\r
+       }\r
+       \r
+       public Composite newGridSection(int formColumns, int childColumns,\r
+                       boolean equalWidth, boolean grabVertical, String text,\r
+                       String description) {\r
+               return newGridSection(getBody(), formColumns, childColumns, equalWidth,\r
+                               grabVertical, text, description);\r
+       }\r
+\r
+       public Composite newGridSection(Composite parent, int formColumns,\r
+                       int childColumns, boolean equalWidth, boolean grabVertical,\r
+                       String text, String description) {\r
+               FormToolkit toolkit = getToolkit();\r
+\r
+               Section section = toolkit.createSection(parent, Section.DESCRIPTION\r
+                               | Section.TWISTIE | Section.TITLE_BAR | Section.EXPANDED);\r
+               section.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true,\r
+                               grabVertical, formColumns, 1));\r
+               section.addExpansionListener(new ExpansionAdapter() {\r
+                       public void expansionStateChanged(ExpansionEvent e) {\r
+                               //System.out.println("SinglePageTypeEditor: expansionStateChanged " + e);\r
+                               //reflow(true);\r
+                       }\r
+               });\r
+               section.setText(text);\r
+               section.setDescription(description);\r
+               Composite sectionClient = toolkit.createComposite(section);\r
+               sectionClient.setLayout(new GridLayout(childColumns, equalWidth));\r
+               sectionClient.setLayoutData(new GridData());\r
+               section.setClient(sectionClient);\r
+               return sectionClient;\r
+       }\r
+       \r
+       public FormToolkit getToolkit() {\r
+               return toolkit;\r
+       }\r
+       \r
+       public void reflow(boolean flushCache) {\r
+               //System.out.println("FormTypeEditorBase.reflow(" + flushCache + ")");\r
+               getActiveForm().reflow(flushCache);\r
+       }\r
+       \r
+       protected void beforeCreateWidgets() {\r
+       }\r
+       \r
+//     private TrackedText modelName = null;\r
+    StructuredResourceSelection hierarchySelection = new StructuredResourceSelection();\r
+    StructuredResourceSelection parameterSelection = new StructuredResourceSelection();\r
+    //GraphExplorer parameterExplorer;\r
+    PropertyTable parameterTable;\r
+    GraphExplorer hierarchyExplorer;\r
+    Button deleteParameterButton;\r
+    Button clearButton;\r
+    PropertyTree propertiesTree;\r
+    Button generateButton;\r
+    Button askButton;\r
+    Button overrideButton;\r
+    \r
+    protected String getFormText() {\r
+        return "Parameterization Editor";\r
+    }\r
+\r
+    protected void createWidgets() {\r
+        createModelPropertiesGroup(newGridSection(2, 1, false, false, "Model Properties",\r
+        "Basic properties for this viewpoint"));\r
+        createParametrizationGroup(newGridSection(2, 1, false, false, "Parameterization",\r
+        "Create parameterization for selected shapes"));\r
+        //getSite().setSelectionProvider(this);\r
+    }\r
+    \r
+    private void createParametrizationGroup(Composite parent) {\r
+        toolkit.paintBordersFor(parent);\r
+        toolkit.setBorderStyle(SWT.BORDER);\r
+        \r
+        overrideButton = toolkit.createButton(parent, "Overwrite previous parameterizations", SWT.CHECK);\r
+        overrideButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                askButton.setEnabled(overrideButton.getSelection());\r
+                \r
+            }\r
+        });\r
+\r
+        \r
+        askButton = toolkit.createButton(parent, "Ask before overwriting", SWT.CHECK);\r
+        askButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                \r
+                \r
+            }\r
+        });\r
+        askButton.setEnabled(false);\r
+        \r
+        generateButton = toolkit.createButton(parent, "Generate linear parameterization", SWT.PUSH);\r
+        generateButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                generateMappings();\r
+                \r
+            }\r
+        });\r
+        generateButton.setEnabled(false);\r
+        \r
+        \r
+    }\r
+    \r
+    private void createModelPropertiesGroup(final Composite parent) {\r
+  \r
+        toolkit.paintBordersFor(parent);\r
+        toolkit.setBorderStyle(SWT.BORDER);\r
+        \r
+        GridData gridData1 = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1);\r
+        \r
+        \r
+        // Parameters\r
+        Label parameterLabel = toolkit.createLabel(parent, "Parameters:");\r
+        parameterLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        parameterLabel.setLayoutData(gridData1);\r
+        \r
+//        parameterExplorer = new GraphExplorer(parent, SWT.SINGLE); //new OntologyExplorer("ParameterExplorer", this, getInput("ParameterExplorer", model.getId()));\r
+//        parameterExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() {\r
+//\r
+//           protected void resourceSelectionUpdated(StructuredResourceSelection sel) {\r
+//                parameterSelection = sel;\r
+//               if (parameterSelection.size() == 0) {\r
+//                   deleteParameterButton.setEnabled(false);\r
+//                   clearButton.setEnabled(false);\r
+//               } else {\r
+//                   deleteParameterButton.setEnabled(true);\r
+//                   clearButton.setEnabled(true);\r
+//               }\r
+//               updateGenerateButtonStatus();\r
+//           }\r
+//             \r
+//        });\r
+//        Tree oe = parameterExplorer.getTree();\r
+//        toolkit.adapt(oe, true, true);\r
+        \r
+        parameterTable = new PropertyTable(parent,SWT.NONE);\r
+        parameterTable.getViewer().addPostSelectionChangedListener(new OESelectionListener() {\r
+\r
+           protected void resourceSelectionUpdated(StructuredResourceSelection sel) {\r
+                  parameterSelection = sel;\r
+               if (parameterSelection.size() == 0) {\r
+                   deleteParameterButton.setEnabled(false);\r
+                   clearButton.setEnabled(false);\r
+               } else {\r
+                   deleteParameterButton.setEnabled(true);\r
+                   clearButton.setEnabled(true);\r
+               }\r
+               updateGenerateButtonStatus();\r
+           }\r
+               \r
+        });\r
+        \r
+        GridData gd3 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd3.heightHint = 50;\r
+        //oe.setLayoutData(gd3);\r
+\r
+        parameterTable.setLayoutData(gd3);\r
+        \r
+        // Buttons to add and remove parameters\r
+        toolkit.createLabel(parent, "");\r
+        Composite buttons = toolkit.createComposite(parent);\r
+\r
+        buttons.setLayout(new FillLayout(SWT.HORIZONTAL));\r
+        Button newParameterButton = toolkit.createButton(buttons, "New Parameter", SWT.PUSH);\r
+        newParameterButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                InputDialog dialog = new InputDialog(ParameterizationContribution.this.parent.getRenderingComposite().getShell(),"New Parameter","Enter parameter's name","new parameter",null);\r
+                if (dialog.open() == InputDialog.CANCEL)\r
+                    return;\r
+                final String name = dialog.getValue();\r
+                if (name.length() < 1) \r
+                    return; // TODO : show error\r
+                \r
+                ParameterizationContribution.this.parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.createDefault(g);\r
+                        //getModel(g).addStatement(ShapeEditorResources.g3dResource.HasSizingParameter, parameter);\r
+                        //parameter.setValue(new double[]{1.0});\r
+                        //parameter.setName(name);\r
+                               Resource parameter = ParameterizationContribution.this.parent.getModel(g).addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasSizingParameter, 1.0).getResource();\r
+                               IEntity thing = EntityFactory.create(g,parameter);\r
+                               thing.setName(name);\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       };\r
+                });\r
+                    \r
+                \r
+            }\r
+        });\r
+        deleteParameterButton = toolkit.createButton(buttons, "Delete Parameter", SWT.PUSH);\r
+        deleteParameterButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                //StructuredResourceSelection s = (StructuredResourceSelection)parameterScheme.getSelection();\r
+               final StructuredResourceSelection s = parameterSelection;\r
+               if (s.size() != 1)\r
+                    return;\r
+               // we'll have to start write transaction, since we may have to change the graph\r
+               ParameterizationContribution.this.parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       boolean proceed;\r
+                       IEntity selectedParameter;\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0));\r
+                               \r
+                        Collection<IEntity> parameters = selectedParameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasSizingParameter);\r
+                        if (parameters.size() > 0) {\r
+                            final MessageDialog dialog = new MessageDialog(ParameterizationContribution.this.parent.getRenderingComposite().getShell(),"Deleting a parameter",null,"Parameter is in use, doe you wan't to remove it?",MessageDialog.QUESTION,new String[]{"OK","Cancel"},1);\r
+                            parent.getDisplay().syncExec(new Runnable() {\r
+                               @Override\r
+                               public void run() {\r
+                                        proceed = (dialog.open() != 1);\r
+                               }\r
+                            });\r
+                            if (proceed) {\r
+                               ParameterizationContribution.this.parent.getModel(g).removeStatement(ShapeEditorResources.g3dResource.HasSizingParameter,selectedParameter);\r
+                                       }\r
+                        }\r
+                       \r
+                        return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+            }\r
+        });\r
+        deleteParameterButton.setEnabled(false);\r
+        \r
+        clearButton = toolkit.createButton(buttons, "Clear Parameter", SWT.PUSH);\r
+        clearButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                final StructuredResourceSelection s = parameterSelection;\r
+                if (s.size() != 1)\r
+                    return;\r
+                ParameterizationContribution.this.parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       boolean proceed;\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                IEntity selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0));\r
+                         Collection<IEntity> equations = selectedParameter.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget);\r
+                                final String name = selectedParameter.getName();\r
+                                if (equations.size() > 0) {\r
+                                        final MessageDialog dialog = new MessageDialog(ParameterizationContribution.this.parent.getRenderingComposite().getShell(),"Clearing a parameter",null,"Do you wan't to clear parameterization for "+ name + " ?\nIt has " + equations.size() + " mappings.",MessageDialog.QUESTION,new String[]{"OK","Cancel"},1);     \r
+                                        parent.getDisplay().syncExec(new Runnable() {\r
+                                                public void run() {\r
+                                                        proceed = (dialog.open() != 1);\r
+                                                };\r
+                                        });\r
+                                        if (proceed) {\r
+                                                for (IEntity eq : equations) {\r
+                                                        eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource);\r
+                                                        eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget);\r
+                                                }\r
+                                                return GraphRequestStatus.transactionComplete();\r
+                                        }\r
+                                }\r
+                                return GraphRequestStatus.transactionCancel();\r
+                       }\r
+                });\r
+            \r
+                \r
+            }\r
+        });\r
+        clearButton.setEnabled(false);\r
+        \r
+        Label hierarchyLabel = toolkit.createLabel(parent, "Model Hierarchy:");\r
+        hierarchyLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        hierarchyLabel.setLayoutData(gridData1);\r
+        \r
+        hierarchyExplorer = new GraphExplorer(parent,SWT.MULTI); //new OntologyExplorer("HierarchyExplorer", this, getInput("HierarchyExplorer", model.getId()));\r
+        Tree oeh = hierarchyExplorer.getTree();//hierarchyExplorer.getControl(parent, 1, OntologyExplorer.OntologyTree, SWT.MULTI);\r
+        toolkit.adapt(oeh, true, true);\r
+        \r
+        GridData gd4 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd4.heightHint = 200;\r
+        oeh.setLayoutData(gd4);\r
+        hierarchyExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() {\r
+\r
+          protected void resourceSelectionUpdated(StructuredResourceSelection sel) {\r
+                 hierarchySelection = sel;\r
+              updatePropertiesTable();\r
+              updateGenerateButtonStatus();\r
+          }\r
+  \r
+          private void updatePropertiesTable() {\r
+              propertiesTree.setProperties(hierarchySelection);\r
+              \r
+          }\r
+               \r
+        });\r
+\r
+        Label propertiesLabel = toolkit.createLabel(parent, "Available properties:");\r
+        propertiesLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        propertiesLabel.setLayoutData(gridData1); \r
+        \r
+        //propertiesTable = toolkit.createTable(parent, SWT.MULTI);\r
+        Tree tree = toolkit.createTree(parent, SWT.MULTI);\r
+        propertiesTree = new PropertyTree(tree,ParameterizationContribution.this.parent.getSession());\r
+        //\r
+        GridData gd5 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd5.heightHint = 200;\r
+        //propertiesTable.setLayoutData(gd5);\r
+        tree.setLayoutData(gd5);\r
+        tree.addSelectionListener(new SelectionAdapter() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                updateGenerateButtonStatus();\r
+            }\r
+            \r
+        });\r
+\r
+        \r
+    }\r
+       \r
+    private void updateGenerateButtonStatus() {\r
+        if (parameterSelection.size() == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        if (hierarchySelection.size() == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        if (propertiesTree.getTree().getSelection().length == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        generateButton.setEnabled(true);\r
+    }\r
+    \r
+    List<Resource> res;\r
+    \r
+    private void generateMappings() {\r
+               final StructuredResourceSelection selectedShapes = hierarchySelection;\r
+               final StructuredResourceSelection selectedParameter = parameterSelection;\r
+               \r
+               final boolean override = overrideButton.getSelection();\r
+               final boolean ask = askButton.getSelection();\r
+               //TreeItem[] selectedProperties = propertiesTree.getTree().getSelection();\r
+               \r
+               assert (selectedParameter.size() == 1);\r
+               assert (selectedShapes.size() > 0);\r
+               //assert(selectedProperties.length > 0);\r
+               parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.create(g,selectedParameter.getSelectionList().get(0));\r
+                               IEntity parameter = EntityFactory.create(g,selectedParameter.getSelectionList().get(0));\r
+                               Collection<IEntity> prop = parameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasDefaultDoubleValue);\r
+                               //fi.vtt.simantics.layer0.stubs.Double defaultValue;\r
+                               double value = g.getScalarDouble(parameter.getResource());\r
+                               if (prop.size() == 0) {\r
+                                       //defaultValue = DoubleFactory.createDefault(g);\r
+                                       //parameter.addStatement(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, defaultValue);\r
+                                       parameter.addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, value);\r
+                               } else {\r
+                                       //defaultValue = DoubleFactory.create(prop.iterator().next());\r
+                                       g.setScalarDouble(prop.iterator().next().getResource(),value);\r
+                               }\r
+                               //defaultValue.setValue(parameter.getValue());\r
+                               final Graph graph = g;\r
+                               parent.getRenderingComposite().getDisplay().syncExec(new Runnable() {\r
+                                       public void run() {\r
+                                               res = propertiesTree.findLeafPropertyInstances(graph, selectedShapes.getSelectionList());\r
+                                       };\r
+                               });\r
+                                \r
+                               \r
+                               double refValue = parameter.toProperty().getScalarDouble();\r
+                               ArrayList<Resource> mappedProperties = new ArrayList<Resource>();\r
+                               \r
+                               for (Resource r : res) {\r
+                                       IEntity propertyThing = EntityFactory.create(g,r);\r
+                                       assert (propertyThing.isInstanceOf(g.getBuiltins().Double));\r
+                                       final String name = ResourceDebugUtils.getReadableNameForEntity(propertyThing);\r
+                                       double rb = propertyThing.toProperty().getScalarDouble();\r
+                                       System.out.println("Mapping to " + name + " " + rb);\r
+                                       Collection<IEntity> equations = propertyThing.getRelatedObjects(ShapeEditorResources.equationResource.HasSource);\r
+                                       if (equations.size() != 0) {\r
+                                               mappedProperties.add(propertyThing.getResource());\r
+                                               if (override) {\r
+                                                       System.out.println("Override");\r
+                                                       boolean over = true;\r
+                                                       if (ask) {\r
+                                                               IEntity t = propertyThing;\r
+                                                               while (t.isInstanceOf(g.getBuiltins().Property)) {\r
+                                                                       Collection<IEntity> ts = t.getRelatedObjects(g.getBuiltins().PropertyOf);\r
+                                                                       // FIXME : traverse all possible routes\r
+                                                                       t = ts.iterator().next();\r
+                                                               }\r
+                                                               //StructuredResourceSelection selection = new StructuredResourceSelection(t.getResource());\r
+                                                               // TODO : do the selection!\r
+                                                               //hierarchyScheme.setSelection(selection);\r
+                                                               //fireSelectionChanged();\r
+                                                               MessageDialog dialog = new MessageDialog(ParameterizationContribution.this.parent.getRenderingComposite().getShell(),\r
+                                                                               "Override mapping",\r
+                                                                               null,\r
+                                                                               "Override mapping to property of highlighted shape?",\r
+                                                                               MessageDialog.QUESTION, new String[] {\r
+                                                                                               "Yes","No", "Cancel" }, 0);\r
+                                                               int i = dialog.open();\r
+                                                               if (i == 2)\r
+                                                                       return GraphRequestStatus.transactionCancel();\r
+                                                               over = (i == 0);\r
+                                                       }\r
+                                                       if (over) {\r
+                                                               \r
+                                                       }\r
+                                               } else {\r
+                                                       if (equations.size() != 1) {\r
+                                                               throw new RuntimeException("One property can have only one euquation as source function.");\r
+                                                       }\r
+                                                       IEntity equation = equations.iterator().next();\r
+                                                       if (!equation.isInstanceOf(ShapeEditorResources.equationResource.SecondOrderScalarPolynomial)) {\r
+                                                               throw new RuntimeException("Only Second order scalar polynomials are supported");\r
+                                                       }\r
+                                                       SecondOrderScalarPolynomial s = new SecondOrderScalarPolynomial(equation);\r
+                                                       s.setA(new double[]{0.0});\r
+                                                       s.setB(new double[]{rb / refValue});\r
+                                                       s.setC(new double[]{0.0});\r
+                                                               \r
+                                               }\r
+                                       } else { //override\r
+                                               // create relation\r
+                                               SecondOrderScalarPolynomial s = SecondOrderScalarPolynomial.createDefault(g);\r
+                                               s.setA(new double[]{0.0});\r
+                                               s.setB(new double[]{rb / refValue});\r
+                                               s.setC(new double[]{0.0});\r
+                                               \r
+                                               // these relations have been instantiated, but addStatements won't delete them so we have to delete them manually.\r
+                                               s.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget);\r
+                                               s.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource);\r
+                                               \r
+                                               parameter.addStatement(ShapeEditorResources.equationResource.HasTarget, s);\r
+                                               \r
+                                               s.addStatement(ShapeEditorResources.equationResource.HasTarget, propertyThing);\r
+                                               mappedProperties.add(propertyThing.getResource());\r
+                                       }\r
+                                       \r
+                               }\r
+                               G3DModel model = parent.getModel(g);\r
+                               Collection<Animation> animations = model.getAnimation();\r
+                               for (Animation animation : animations) {\r
+                                       Collection<Interpolator> interpolators = animation.getInterpolator();\r
+                                       for (Interpolator interpolator : interpolators) {\r
+                                               IEntity target = interpolator.getTarget();\r
+                                               for (Resource property : mappedProperties) {\r
+                                                       if (target.getResource().equals(property)) {\r
+                                                               ShapeEditorResources.curveBuilder.createDefault(interpolator);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+\r
+\r
+\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/CSGModellingView.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/CSGModellingView.java
new file mode 100644 (file)
index 0000000..f2b8c84
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.utils.viewpoints.ResourceViewpoint;\r
+import org.simantics.proconf.browsing.GraphExplorer;\r
+import org.simantics.proconf.browsing.views.GraphExplorerView;\r
+import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator;\r
+\r
+public class CSGModellingView extends GraphExplorerView {\r
+\r
+       @Override\r
+       protected GraphExplorer createExplorer(Composite parent) {\r
+               return super.createExplorer(parent);\r
+       }\r
+       \r
+       @Override\r
+       protected ResourceViewpoint getViewpoint(ISessionContext context) {\r
+               return ViewpointGenerator.createViewpoint();\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java
new file mode 100644 (file)
index 0000000..07dc17c
--- /dev/null
@@ -0,0 +1,587 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.dialogs.InputDialog;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.forms.IFormColors;\r
+import org.simantics.proconf.g3d.csg.stubs.CSGModel;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.equation.stubs.SecondOrderScalarPolynomial;\r
+import org.simantics.g2d.stubs.anim.Animation;\r
+import org.simantics.g2d.stubs.anim.Interpolator;\r
+import org.simantics.layer0.utils.ResourceDebugUtils;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.EntityFactory;\r
+import org.simantics.proconf.browsing.GraphExplorer;\r
+import org.simantics.proconf.browsing.GraphExplorerInputFactory;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator;\r
+import org.simantics.proconf.g3d.tools.OESelectionListener;\r
+import org.simantics.proconf.g3d.tools.PropertyTree;\r
+import org.simantics.proconf.g3d.views.SinglePageResourceEditor;\r
+import org.simantics.utils.ui.widgets.TrackedModifyEvent;\r
+import org.simantics.utils.ui.widgets.TrackedModifyListener;\r
+import org.simantics.utils.ui.widgets.TrackedText;\r
+\r
+\r
+public class ParameterizationEditor extends SinglePageResourceEditor { //implements ISelectionProvider{\r
+    \r
+    //ParameterizedCSGModel model;\r
+       Resource modelResource;\r
+    private TrackedText modelName = null;\r
+    StructuredResourceSelection hierarchySelection = new StructuredResourceSelection();\r
+    StructuredResourceSelection parameterSelection = new StructuredResourceSelection();\r
+    GraphExplorer parameterExplorer;\r
+    GraphExplorer hierarchyExplorer;\r
+    Button deleteParameterButton;\r
+    Button clearButton;\r
+    PropertyTree propertiesTree;\r
+    Button generateButton;\r
+    Button askButton;\r
+    Button overrideButton;\r
+    Composite parent;\r
+    \r
+    \r
+    @Override\r
+    protected String getFormText() {\r
+        return "Parameterization Editor";\r
+    }\r
+\r
+//    @Override\r
+//    protected void beforeCreateWidgets() {\r
+//        if (!(getInputResource().isInstanceOf(GlobalIdMap.get(CSGModelingOntologyMapping.PARAMETERIZED_CSG_MODEL))))\r
+//            throw new RuntimeException("Trying to open resource that is not paramaterized CSG model");\r
+//        model = ParameterizedCSGModelFactory.create(getInputResource());\r
+//    }\r
+    \r
+    \r
+\r
+    @Override\r
+    protected void createWidgets() {\r
+        createModelPropertiesGroup(newGridSection(2, 2, false, false, "Model Properties",\r
+        "Basic properties for this viewpoint"));\r
+        createParametrizationGroup(newGridSection(2, 2, false, false, "Parameterization",\r
+        "Create parameterization for selected shapes"));\r
+        //getSite().setSelectionProvider(this);\r
+    }\r
+\r
+    @Override\r
+    public void reload(Graph graph) {\r
+       modelResource = getInputResource();\r
+       parent.getDisplay().asyncExec(new Runnable() {\r
+        @Override\r
+       public void run() {\r
+               reload();\r
+       }  \r
+       });\r
+\r
+    }\r
+    \r
+    public void reload() {\r
+\r
+           hierarchyExplorer.setInput(getSessionContext(),GraphExplorerInputFactory.clone(hierarchyExplorer.getInput())\r
+                   .input(modelResource)\r
+                   .viewpoint(ViewpointGenerator.createObjectStructureViewpoint())\r
+                   .toInput());\r
+\r
+            parameterExplorer.setInput(getSessionContext(),GraphExplorerInputFactory.clone(parameterExplorer.getInput())\r
+                    .input(modelResource)\r
+                    .viewpoint(ViewpointGenerator.createObjectSizingParameterViewpoint(ShapeEditorResources.g3dResource.HasSizingParameter))\r
+                    .toInput());\r
+\r
+    }\r
+    \r
+    private void createParametrizationGroup(Composite parent) {\r
+        toolkit.paintBordersFor(parent);\r
+        toolkit.setBorderStyle(SWT.BORDER);\r
+        \r
+        overrideButton = toolkit.createButton(parent, "Overwrite previous parameterizations", SWT.CHECK);\r
+        overrideButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                askButton.setEnabled(overrideButton.getSelection());\r
+                \r
+            }\r
+        });\r
+\r
+        \r
+        askButton = toolkit.createButton(parent, "Ask before overwriting", SWT.CHECK);\r
+        askButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                \r
+                \r
+            }\r
+        });\r
+        askButton.setEnabled(false);\r
+        \r
+        generateButton = toolkit.createButton(parent, "Generate linear parameterization", SWT.PUSH);\r
+        generateButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                generateMappings();\r
+                \r
+            }\r
+        });\r
+        generateButton.setEnabled(false);\r
+        \r
+        \r
+    }\r
+    \r
+    private CSGModel getModel(Graph graph) {\r
+       return new CSGModel(graph, modelResource);\r
+    }\r
+    \r
+    private void createModelPropertiesGroup(Composite p) {\r
+       parent = p;\r
+        toolkit.paintBordersFor(parent);\r
+        toolkit.setBorderStyle(SWT.BORDER);\r
+        \r
+        GridData gridData1 = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1);\r
+        GridData gridData2 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);\r
+\r
+        // Name\r
+        Label l1 = toolkit.createLabel(parent, "Name:");\r
+        l1.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        Text text = toolkit.createText(parent, "TODO: Insert model's name here", SWT.SINGLE);\r
+        GridData textLayout = new GridData(GridData.FILL, GridData.FILL, true, true);\r
+        text.setLayoutData(textLayout);\r
+        modelName = new TrackedText(text);\r
+        modelName.addModifyListener(new TrackedModifyListener(){\r
+               @Override\r
+               public void modifyText(TrackedModifyEvent e) {\r
+                       final String name = e.getText();\r
+                       getSession().asyncWrite(new GraphRequestAdapter() {\r
+                               @Override\r
+                               public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                       getModel(g).setName(name);\r
+                                       return GraphRequestStatus.transactionComplete();\r
+                               }\r
+                       });\r
+               }\r
+        });\r
+        \r
+        l1.setLayoutData(gridData1);\r
+        text.setLayoutData(gridData2);\r
+        \r
+        \r
+        // Parameters\r
+        Label parameterLabel = toolkit.createLabel(parent, "Parameters:");\r
+        parameterLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        parameterLabel.setLayoutData(gridData1);\r
+        \r
+        parameterExplorer = new GraphExplorer(parent, SWT.SINGLE); //new OntologyExplorer("ParameterExplorer", this, getInput("ParameterExplorer", model.getId()));\r
+        parameterExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() {\r
+\r
+           protected void resourceSelectionUpdated(StructuredResourceSelection sel) {\r
+                  parameterSelection = sel;\r
+               if (parameterSelection.size() == 0) {\r
+                   deleteParameterButton.setEnabled(false);\r
+                   clearButton.setEnabled(false);\r
+               } else {\r
+                   deleteParameterButton.setEnabled(true);\r
+                   clearButton.setEnabled(true);\r
+               }\r
+               updateGenerateButtonStatus();\r
+           }\r
+               \r
+        });\r
+        Tree oe = parameterExplorer.getTree();\r
+        toolkit.adapt(oe, true, true);\r
+        GridData gd3 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd3.heightHint = 50;\r
+        oe.setLayoutData(gd3);\r
+//        parameterExplorer.init(getLastMemento(), ViewpointUtils.getModelledHandler(parameterExplorer.getGraph(), Builtins.DefaultViewpointId), null, ViewLabelProviderDecorationSettings.DEFAULT, new MenuAboutToShowAction(), new NullAdditionAction(), false);\r
+//        parameterScheme = new ParameterSelectionScheme(parameterExplorer);\r
+//        parameterExplorer.setSelectionScheme(parameterScheme);\r
+        \r
+        // Buttons to add and remove parameters\r
+        toolkit.createLabel(parent, "");\r
+        Composite buttons = toolkit.createComposite(parent);\r
+\r
+        buttons.setLayout(new FillLayout(SWT.HORIZONTAL));\r
+        Button newParameterButton = toolkit.createButton(buttons, "New Parameter", SWT.PUSH);\r
+        newParameterButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                InputDialog dialog = new InputDialog(ParameterizationEditor.this.getSite().getShell(),"New Parameter","Enter parameter's name","new parameter",null);\r
+                if (dialog.open() == InputDialog.CANCEL)\r
+                    return;\r
+                final String name = dialog.getValue();\r
+                if (name.length() < 1) \r
+                    return; // TODO : show error\r
+                \r
+                getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.createDefault(g);\r
+                        //getModel(g).addStatement(ShapeEditorResources.g3dResource.HasSizingParameter, parameter);\r
+                        //parameter.setValue(new double[]{1.0});\r
+                        //parameter.setName(name);\r
+                               Resource parameter = getModel(g).addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasSizingParameter, 1.0).getResource();\r
+                               IEntity thing = EntityFactory.create(g,parameter);\r
+                               thing.setName(name);\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       };\r
+                });\r
+                    \r
+                \r
+            }\r
+        });\r
+        deleteParameterButton = toolkit.createButton(buttons, "Delete Parameter", SWT.PUSH);\r
+        deleteParameterButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                //StructuredResourceSelection s = (StructuredResourceSelection)parameterScheme.getSelection();\r
+               final StructuredResourceSelection s = parameterSelection;\r
+               if (s.size() != 1)\r
+                    return;\r
+               // we'll have to start write transaction, since we may have to change the graph\r
+               getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       boolean proceed;\r
+                       IEntity selectedParameter;\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0));\r
+                               \r
+                        Collection<IEntity> parameters = selectedParameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasSizingParameter);\r
+                        if (parameters.size() > 0) {\r
+                            final MessageDialog dialog = new MessageDialog(ParameterizationEditor.this.getSite().getShell(),"Deleting a parameter",null,"Parameter is in use, doe you wan't to remove it?",MessageDialog.QUESTION,new String[]{"OK","Cancel"},1);\r
+                            parent.getDisplay().syncExec(new Runnable() {\r
+                               @Override\r
+                               public void run() {\r
+                                        proceed = (dialog.open() != 1);\r
+                               }\r
+                            });\r
+                            if (proceed) {\r
+                                               getModel(g).removeStatement(ShapeEditorResources.g3dResource.HasSizingParameter,selectedParameter);\r
+                                       }\r
+                        }\r
+                       \r
+                        return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+            }\r
+        });\r
+        deleteParameterButton.setEnabled(false);\r
+        \r
+        clearButton = toolkit.createButton(buttons, "Clear Parameter", SWT.PUSH);\r
+        clearButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                final StructuredResourceSelection s = parameterSelection;\r
+                if (s.size() != 1)\r
+                    return;\r
+                getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       boolean proceed;\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                IEntity selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0));\r
+                         Collection<IEntity> equations = selectedParameter.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget);\r
+                                final String name = selectedParameter.getName();\r
+                                if (equations.size() > 0) {\r
+                                        final MessageDialog dialog = new MessageDialog(ParameterizationEditor.this.getSite().getShell(),"Clearing a parameter",null,"Do you wan't to clear parameterization for "+ name + " ?\nIt has " + equations.size() + " mappings.",MessageDialog.QUESTION,new String[]{"OK","Cancel"},1);        \r
+                                        parent.getDisplay().syncExec(new Runnable() {\r
+                                                public void run() {\r
+                                                        proceed = (dialog.open() != 1);\r
+                                                };\r
+                                        });\r
+                                        if (proceed) {\r
+                                                for (IEntity eq : equations) {\r
+                                                        eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource);\r
+                                                        eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget);\r
+                                                }\r
+                                                return GraphRequestStatus.transactionComplete();\r
+                                        }\r
+                                }\r
+                                return GraphRequestStatus.transactionCancel();\r
+                       }\r
+                });\r
+            \r
+                \r
+            }\r
+        });\r
+        clearButton.setEnabled(false);\r
+        \r
+        Label hierarchyLabel = toolkit.createLabel(parent, "Model Hierarchy:");\r
+        hierarchyLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        hierarchyLabel.setLayoutData(gridData1);\r
+        \r
+        hierarchyExplorer = new GraphExplorer(parent,SWT.MULTI); //new OntologyExplorer("HierarchyExplorer", this, getInput("HierarchyExplorer", model.getId()));\r
+        Tree oeh = hierarchyExplorer.getTree();//hierarchyExplorer.getControl(parent, 1, OntologyExplorer.OntologyTree, SWT.MULTI);\r
+        toolkit.adapt(oeh, true, true);\r
+        \r
+        GridData gd4 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd4.heightHint = 200;\r
+        oeh.setLayoutData(gd4);\r
+        hierarchyExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() {\r
+\r
+          protected void resourceSelectionUpdated(StructuredResourceSelection sel) {\r
+                 hierarchySelection = sel;\r
+              updatePropertiesTable();\r
+              updateGenerateButtonStatus();\r
+          }\r
+  \r
+          private void updatePropertiesTable() {\r
+              propertiesTree.setProperties(hierarchySelection);\r
+              \r
+          }\r
+               \r
+        });\r
+        //hierarchyExplorer.init(getLastMemento(), ViewpointUtils.getModelledHandler(hierarchyExplorer.getGraph(), CSGModelingOntologyMapping.CSG_MODEL_HIERARCHY_VIEWPOINT), null, ViewLabelProviderDecorationSettings.DEFAULT, new MenuAboutToShowAction(), new NullAdditionAction(), false);\r
+//        hierarchyScheme = new HierarchySelectionScheme(hierarchyExplorer);\r
+//        hierarchyExplorer.setSelectionScheme(hierarchyScheme);\r
+//        hierarchyExplorer.hookPageSelection(this);\r
+        Label propertiesLabel = toolkit.createLabel(parent, "Available properties:");\r
+        propertiesLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));\r
+        propertiesLabel.setLayoutData(gridData1); \r
+        \r
+        //propertiesTable = toolkit.createTable(parent, SWT.MULTI);\r
+        Tree tree = toolkit.createTree(parent, SWT.MULTI);\r
+        propertiesTree = new PropertyTree(tree,getSession());\r
+        //\r
+        GridData gd5 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1);\r
+        gd5.heightHint = 200;\r
+        //propertiesTable.setLayoutData(gd5);\r
+        tree.setLayoutData(gd5);\r
+        tree.addSelectionListener(new SelectionAdapter() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                updateGenerateButtonStatus();\r
+            }\r
+            \r
+        });\r
+\r
+        \r
+    }\r
+    \r
+//    private class ParameterSelectionScheme extends AbstractSelectionScheme {\r
+//        \r
+//        public ParameterSelectionScheme(OntologyExplorer explorer) {\r
+//            super(explorer);\r
+//        }\r
+//\r
+//        @Override\r
+//        protected Resource getResourceForSelection(TreeNode selected) {\r
+//            Resource resource = explorer.getCoreResource(selected);\r
+//            System.out.println("Parameter Tree Selection : " + resource.getId());\r
+//            return resource;\r
+//        }\r
+//\r
+//        @Override\r
+//        protected void resourceSelectionUpdated() {\r
+//            if (selection.size() == 0) {\r
+//                deleteParameterButton.setEnabled(false);\r
+//                clearButton.setEnabled(false);\r
+//            } else {\r
+//                deleteParameterButton.setEnabled(true);\r
+//                clearButton.setEnabled(true);\r
+//            }\r
+//            updateGenerateButtonStatus();\r
+//        }\r
+//    }\r
+//    \r
+//    private class HierarchySelectionScheme extends AbstractSelectionScheme {\r
+//\r
+//        public HierarchySelectionScheme(OntologyExplorer explorer) {\r
+//            super(explorer);\r
+//        }\r
+//        \r
+//        @Override\r
+//        protected Resource getResourceForSelection(TreeNode selected) {\r
+//            Resource resource = explorer.getCoreResource(selected);\r
+//            System.out.println("Hierarchy Tree Selection : " + resource.getId());\r
+//            return resource;\r
+//        }\r
+//        \r
+//        @Override\r
+//        protected void resourceSelectionUpdated() {\r
+//            updatePropertiesTable();\r
+//            updateGenerateButtonStatus();\r
+//        }\r
+//\r
+//        private void updatePropertiesTable() {\r
+//            propertiesTree.setProperties(selection);\r
+//            \r
+//        }\r
+//        \r
+//    }\r
+    \r
+//    private boolean contains(Resource list[], Resource value) {\r
+//        for (int i = 0; i < list.length; i++) {\r
+//            if (list[i].equals(value))\r
+//                return true;\r
+//        }\r
+//        return false;\r
+//    }\r
+    \r
+    private void updateGenerateButtonStatus() {\r
+        if (parameterSelection.size() == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        if (hierarchySelection.size() == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        if (propertiesTree.getTree().getSelection().length == 0) {\r
+            generateButton.setEnabled(false);\r
+            return;\r
+        }\r
+        generateButton.setEnabled(true);\r
+    }\r
+    \r
+    List<Resource> res;\r
+    \r
+    private void generateMappings() {\r
+               final StructuredResourceSelection selectedShapes = hierarchySelection;\r
+               final StructuredResourceSelection selectedParameter = parameterSelection;\r
+               \r
+               final boolean override = overrideButton.getSelection();\r
+               final boolean ask = askButton.getSelection();\r
+               //TreeItem[] selectedProperties = propertiesTree.getTree().getSelection();\r
+               \r
+               assert (selectedParameter.size() == 1);\r
+               assert (selectedShapes.size() > 0);\r
+               //assert(selectedProperties.length > 0);\r
+               getSession().asyncWrite(new GraphRequestAdapter() {\r
+                       @Override\r
+                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                               //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.create(g,selectedParameter.getSelectionList().get(0));\r
+                               IEntity parameter = EntityFactory.create(g,selectedParameter.getSelectionList().get(0));\r
+                               Collection<IEntity> prop = parameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasDefaultDoubleValue);\r
+                               //fi.vtt.simantics.layer0.stubs.Double defaultValue;\r
+                               double value = g.getScalarDouble(parameter.getResource());\r
+                               if (prop.size() == 0) {\r
+                                       //defaultValue = DoubleFactory.createDefault(g);\r
+                                       //parameter.addStatement(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, defaultValue);\r
+                                       parameter.addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, value);\r
+                               } else {\r
+                                       //defaultValue = DoubleFactory.create(prop.iterator().next());\r
+                                       g.setScalarDouble(prop.iterator().next().getResource(),value);\r
+                               }\r
+                               //defaultValue.setValue(parameter.getValue());\r
+                               final Graph graph = g;\r
+                               parent.getDisplay().syncExec(new Runnable() {\r
+                                       public void run() {\r
+                                               res = propertiesTree.findLeafPropertyInstances(graph, selectedShapes.getSelectionList());\r
+                                       };\r
+                               });\r
+                                \r
+                               \r
+                               double refValue = parameter.toProperty().getScalarDouble();\r
+                               ArrayList<Resource> mappedProperties = new ArrayList<Resource>();\r
+                               \r
+                               for (Resource r : res) {\r
+                                       IEntity propertyThing = EntityFactory.create(g,r);\r
+                                       assert (propertyThing.isInstanceOf(g.getBuiltins().Double));\r
+                                       final String name = ResourceDebugUtils.getReadableNameForEntity(propertyThing);\r
+                                       double rb = propertyThing.toProperty().getScalarDouble();\r
+                                       System.out.println("Mapping to " + name + " " + rb);\r
+                                       Collection<IEntity> equations = propertyThing.getRelatedObjects(ShapeEditorResources.equationResource.HasSource);\r
+                                       if (equations.size() != 0) {\r
+                                               mappedProperties.add(propertyThing.getResource());\r
+                                               if (override) {\r
+                                                       System.out.println("Override");\r
+                                                       boolean over = true;\r
+                                                       if (ask) {\r
+                                                               IEntity t = propertyThing;\r
+                                                               while (t.isInstanceOf(g.getBuiltins().Property)) {\r
+                                                                       Collection<IEntity> ts = t.getRelatedObjects(g.getBuiltins().PropertyOf);\r
+                                                                       // FIXME : traverse all possible routes\r
+                                                                       t = ts.iterator().next();\r
+                                                               }\r
+                                                               //StructuredResourceSelection selection = new StructuredResourceSelection(t.getResource());\r
+                                                               // TODO : do the selection!\r
+                                                               //hierarchyScheme.setSelection(selection);\r
+                                                               //fireSelectionChanged();\r
+                                                               MessageDialog dialog = new MessageDialog(ParameterizationEditor.this.getSite().getShell(),\r
+                                                                               "Override mapping",\r
+                                                                               null,\r
+                                                                               "Override mapping to property of highlighted shape?",\r
+                                                                               MessageDialog.QUESTION, new String[] {\r
+                                                                                               "Yes","No", "Cancel" }, 0);\r
+                                                               int i = dialog.open();\r
+                                                               if (i == 2)\r
+                                                                       return GraphRequestStatus.transactionCancel();\r
+                                                               over = (i == 0);\r
+                                                       }\r
+                                                       if (over) {\r
+                                                               \r
+                                                       }\r
+                                               } else {\r
+                                                       if (equations.size() != 1) {\r
+                                                               throw new RuntimeException("One property can have only one euquation as source function.");\r
+                                                       }\r
+                                                       IEntity equation = equations.iterator().next();\r
+                                                       if (!equation.isInstanceOf(ShapeEditorResources.equationResource.SecondOrderScalarPolynomial)) {\r
+                                                               throw new RuntimeException("Only Second order scalar polynomials are supported");\r
+                                                       }\r
+                                                       SecondOrderScalarPolynomial s = new SecondOrderScalarPolynomial(equation);\r
+                                                       s.setA(new double[]{0.0});\r
+                                                       s.setB(new double[]{rb / refValue});\r
+                                                       s.setC(new double[]{0.0});\r
+                                                               \r
+                                               }\r
+                                       } else { //override\r
+                                               // create relation\r
+                                               SecondOrderScalarPolynomial s = SecondOrderScalarPolynomial.createDefault(g);\r
+                                               s.setA(new double[]{0.0});\r
+                                               s.setB(new double[]{rb / refValue});\r
+                                               s.setC(new double[]{0.0});\r
+                                               \r
+                                               // FIXME : these relations have been instantiated, but addStatements won't delete them so we have to delete them manually.\r
+                                               s.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget);\r
+                                               s.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource);\r
+                                               \r
+                                               parameter.addStatement(ShapeEditorResources.equationResource.HasTarget, s);\r
+                                               \r
+                                               s.addStatement(ShapeEditorResources.equationResource.HasTarget, propertyThing);\r
+                                               mappedProperties.add(propertyThing.getResource());\r
+                                       }\r
+                                       \r
+                               }\r
+                               CSGModel model = getModel(g);\r
+                               Collection<Animation> animations = model.getAnimation();\r
+                               for (Animation animation : animations) {\r
+                                       Collection<Interpolator> interpolators = animation.getInterpolator();\r
+                                       for (Interpolator interpolator : interpolators) {\r
+                                               IEntity target = interpolator.getTarget();\r
+                                               for (Resource property : mappedProperties) {\r
+                                                       if (target.getResource().equals(property)) {\r
+                                                               ShapeEditorResources.curveBuilder.createDefault(interpolator);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               return GraphRequestStatus.transactionComplete();\r
+                       }\r
+               });\r
+\r
+\r
+\r
+       }\r
+   \r
+}\r
+\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorBase.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorBase.java
new file mode 100644 (file)
index 0000000..9c1490d
--- /dev/null
@@ -0,0 +1,628 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionChangedListener;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
+import org.simantics.db.ContextGraph;\r
+import org.simantics.db.Graph;\r
+import org.simantics.db.GraphRequestAdapter;\r
+import org.simantics.db.GraphRequestStatus;\r
+import org.simantics.db.GraphRequestWithResult;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.equation.solver.Solver;\r
+import org.simantics.layer0.stubs.Property;\r
+import org.simantics.layer0.utils.EntityFactory;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.proconf.g3d.actions.InteractiveAction;\r
+import org.simantics.proconf.g3d.actions.TranslateAction;\r
+import org.simantics.proconf.g3d.base.G3DTools;\r
+import org.simantics.proconf.g3d.base.JmeRenderingComponent;\r
+import org.simantics.proconf.g3d.base.ScenegraphAdapter;\r
+import org.simantics.proconf.g3d.base.ScenegraphAdapterImpl;\r
+import org.simantics.proconf.g3d.base.SelectionAdapter;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorProvider;\r
+import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
+import org.simantics.proconf.g3d.csg.stubs.CSGModel;\r
+import org.simantics.proconf.g3d.csg.stubs.Primitive;\r
+import org.simantics.proconf.g3d.dnd.DropListener;\r
+import org.simantics.proconf.g3d.scenegraph.AbstractGraphicsNode;\r
+import org.simantics.proconf.g3d.scenegraph.IGeometryNode;\r
+import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
+import org.simantics.proconf.g3d.scenegraph.ISelectableNode;\r
+import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources;\r
+import org.simantics.proconf.g3d.shapeeditor.actions.ExportAction;\r
+import org.simantics.proconf.g3d.shapeeditor.actions.ImportAction;\r
+import org.simantics.proconf.g3d.shapeeditor.scenegraph.CSGShapeNode;\r
+import org.simantics.proconf.g3d.shapeeditor.tools.AnimationContribution;\r
+import org.simantics.proconf.g3d.shapeeditor.tools.CSGModellingContribution;\r
+import org.simantics.proconf.g3d.shapeeditor.tools.ParameterizationContribution;\r
+import org.simantics.proconf.g3d.shapes.GridShape;\r
+import org.simantics.proconf.g3d.stubs.G3DModel;\r
+import org.simantics.proconf.g3d.stubs.G3DNode;\r
+import org.simantics.proconf.g3d.stubs.Shape;\r
+import org.simantics.utils.ErrorLogger;\r
+import org.simantics.utils.ui.jface.MenuTools;\r
+\r
+public class ShapeEditorBase extends ThreeDimensionalEditorBase {\r
+\r
+       // currently each 3D-model has a root object which is ShapeGroup\r
+       protected Resource model = null;\r
+       \r
+       protected boolean isParameterized;\r
+       \r
+       private Action exportAction;\r
+       private Action importAction;\r
+       \r
+       public ShapeEditorBase(ISessionContext session) {\r
+               super(session);\r
+               addEditorContribution(new CSGModellingContribution(this));\r
+               addEditorContribution(new AnimationContribution(this));\r
+               addEditorContribution(new ParameterizationContribution(this));\r
+       }\r
+\r
+       public ShapeEditorBase(ISessionContext session, JmeRenderingComponent component) {\r
+               super(session,component);\r
+               addEditorContribution(new CSGModellingContribution(this));\r
+               addEditorContribution(new AnimationContribution(this));\r
+               addEditorContribution(new ParameterizationContribution(this));\r
+       }\r
+\r
+       @Override\r
+       protected ScenegraphAdapter createScenegraphAdapter() {\r
+               return new ShapeEditorAdapter(session, getRenderingComponent());\r
+       }\r
+\r
+       @Override\r
+       public void createControl(Graph graph,Composite parent) {\r
+               super.createControl(graph,parent);\r
+               getRenderingComponent().getNoCastRoot().attachChild(GridShape.getShape(getRenderingComponent().getDisplaySystem().getRenderer(), 10, 1.f));\r
+       }\r
+\r
+//     private void loadGroup(Graph graph) {\r
+//             assert (model != null);\r
+//             adapter.addOutbound(EntityFactory.create(graph,model));\r
+//             //assert (abstractGraphicsNodes.size() == 1);\r
+//\r
+//     }\r
+\r
+       protected void makeActions(Graph graph) {\r
+               super.makeActions(graph);\r
+               exportAction = new ExportAction(this);\r
+               importAction = new ImportAction(this);\r
+       }\r
+\r
+       @Override\r
+       protected void fillLocalPullDown() {\r
+               super.fillLocalPullDown();\r
+               MenuTools.getOrCreate(getMenuID(),"Model", menuManager).add(exportAction);\r
+               MenuTools.getOrCreate(getMenuID(),"Model", menuManager).add(importAction);\r
+       }\r
+       \r
+\r
+       \r
+       /*\r
+        * These are used for updating CSG models geometry when internal shapes are moved. Interactive update is not possible\r
+        * because recalculation of geometry takes too much time. There are several problems in this method:\r
+        * 1. it relies on instanceof check \r
+        * 2. when shape is moved, transformations of its children are updated, which causes all\r
+        *    child geometries to be updated, which is not necessary. We want to update only moved\r
+        *    shape, since updateAllGemetry method takes care of parents. \r
+        * \r
+        *  TODO : this functionality should be moved to TranslateAction\r
+        *  TODO : prevent moved shape's children to be updated.\r
+        */\r
+       \r
+       @Override\r
+       public void setCurrentAction(InteractiveAction action) {\r
+               if (getCurrentAction() == action)\r
+               return;\r
+               if (getCurrentAction() != null && getCurrentAction() instanceof TranslateAction) {\r
+                       runGeometryUpdates();\r
+               }\r
+               super.setCurrentAction(action);\r
+       }\r
+       \r
+       private void runGeometryUpdates() {\r
+               // now we'll just filter out all parents so that they won't be updated multiple times.\r
+               HashSet<CSGShapeNode> parents = new HashSet<CSGShapeNode>();\r
+               for (CSGShapeNode n : geometryUpdates) {\r
+                       IGraphicsNode parent = n.getParent();\r
+                       if (parent instanceof CSGShapeNode)\r
+                               parents.add((CSGShapeNode)parent);\r
+               }\r
+               for (CSGShapeNode n : geometryUpdates) {\r
+                       if (!parents.contains(n))\r
+                               n.updateAllGeometry();\r
+               }\r
+               geometryUpdates.clear();\r
+       }\r
+       \r
+       private HashSet<CSGShapeNode> geometryUpdates = new HashSet<CSGShapeNode>();\r
+       \r
+       private void geometryUpdate(CSGShapeNode shape) {\r
+               \r
+               if (!(getCurrentAction() instanceof TranslateAction)) {\r
+                       shape.updateAllGeometry();\r
+               } else {\r
+                       geometryUpdates.add(shape);\r
+               }\r
+       }\r
+       \r
+       public Graph createParameterization(Graph g) {\r
+               if (isParameterized) {\r
+                       ContextGraph graph;\r
+                       if (!(g instanceof ContextGraph)) {\r
+                               graph = new ContextGraph(g);\r
+                               graph.setContext(model);\r
+                       } else {\r
+                               graph = (ContextGraph)g;\r
+                       }\r
+                       Solver solver = new Solver();\r
+                       Collection<org.simantics.layer0.utils.Property> parameters = getModel(graph).getRelatedProperties(ShapeEditorResources.g3dResource.HasSizingParameter);\r
+                       for (org.simantics.layer0.utils.Property p : parameters) {\r
+                               IEntity t = EntityFactory.create(graph, p.getResource());\r
+                               Collection<IEntity> exp = t.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget);\r
+                               if (exp.size() > 0) {\r
+                                       Iterator<IEntity> i = exp.iterator();\r
+                                       while (i.hasNext())\r
+                                               solver.evaluate(i.next());\r
+                               } else {\r
+                                       ErrorLogger.defaultLogWarning("Model property " + p + " is not bound to a expression", null);\r
+                               }\r
+                       }\r
+                       solver.pushToGraph(graph);\r
+                       return graph;\r
+               } else {\r
+                       return g;\r
+               }\r
+       }\r
+       \r
+       \r
+\r
+       protected class ShapeEditorAdapter extends ScenegraphAdapterImpl {\r
+\r
+               public ShapeEditorAdapter(Session session,JmeRenderingComponent component) {\r
+                       super(session,component);\r
+               }\r
+               \r
+               @Override\r
+               public synchronized void updateGeometry(Graph graph) {\r
+                       if (isParameterized) {\r
+                               graph = createParameterization(graph);  \r
+                       }\r
+                       super.updateGeometry(graph);\r
+               }\r
+               \r
+               \r
+               \r
+               protected AbstractGraphicsNode instantiateNode(IGraphicsNode comp,\r
+                               G3DNode node) {\r
+                       CSGShapeNode mo = new CSGShapeNode(ShapeEditorBase.this, comp, node.getGraph(),node.getResource());\r
+                       updateGeometry(mo);\r
+                       return mo;\r
+               }\r
+\r
+               \r
+               private class ShapeEditorScenegraphQuery extends ScenegraphQuery {\r
+                       \r
+                       public ShapeEditorScenegraphQuery(Resource nodeResource) {\r
+                               super(nodeResource);\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void shapeAdded(Graph graph,IGraphicsNode n) {\r
+                               updateGeometry((CSGShapeNode) n);\r
+\r
+                                       if (n.getG3DNode(graph).getParent() == null) {\r
+                                               if (DEBUG)System.out.println("ShapeSubnodeListener "\r
+                                                               + n.getResource()\r
+                                                               + " has no parent");\r
+                                               return;\r
+                                       }\r
+                                       if (DEBUG) System.out.print("ShapeSubnodeListener " + n.getResource());\r
+                                       if (n.getG3DNode(graph).getRelatedObjects(ShapeEditorResources.g3dResource.GeometryDefinitionOf).size() == 0) {\r
+                                               if (DEBUG) System.out.println(" visible");\r
+                                               ((ISelectableNode)n).setVisible(true);\r
+                                       } else {\r
+                                               if (DEBUG) System.out.println(" invisible");\r
+                                               ((ISelectableNode)n).setVisible(false);\r
+                                       }\r
+                       }\r
+                       \r
+//                     @Override\r
+//                     public NodeQuery instantiateQuery(Resource node) {\r
+//                             return new ShapeEditorScenegraphQuery(node);\r
+//                     }\r
+               }\r
+               \r
+               @Override\r
+               protected ScenegraphQuery newSubnodeListener(G3DNode node) {\r
+                       return new ShapeEditorScenegraphQuery(node.getResource());\r
+               }\r
+               \r
+               private class ShapeEditorNodePropertyQuery extends NodePropertyQuery {\r
+                       public ShapeEditorNodePropertyQuery(Resource nodeResource) {\r
+                               super(nodeResource);\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void shapeUpdated(Graph graph,final IGraphicsNode shape) {\r
+                               if (DEBUG) System.out.println("Tri - Shape id " + shape + " modified");\r
+                               ((CSGShapeNode) shape).updateAllGeometry();\r
+                       }\r
+                       \r
+//                     @Override\r
+//                     public NodeQuery instantiateQuery(Resource node) {\r
+//                             return new ShapeEditorNodePropertyQuery(node);\r
+//                     }\r
+               }\r
+\r
+               @Override\r
+               protected NodePropertyQuery newPropertyListener(G3DNode node) {\r
+                       return new ShapeEditorNodePropertyQuery(node.getResource());\r
+               }\r
+               \r
+               private class ShapeEditorNodeTransformationQuery extends NodeTransformationQuery {\r
+                       public ShapeEditorNodeTransformationQuery(Resource nodeResource) {\r
+                               super(nodeResource);\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void shapeUpdated(Graph graph,final IGraphicsNode shape) {\r
+                               if (DEBUG) System.out.println("Tra - Shape id " + shape + " modified");\r
+                               ((CSGShapeNode) shape).updateTransform(graph);\r
+                               geometryUpdate((CSGShapeNode)shape);\r
+                       }\r
+                       \r
+//                     @Override\r
+//                     public NodeQuery instantiateQuery(Resource node) {\r
+//                             return new ShapeEditorNodePropertyQuery(node);\r
+//                     }\r
+               }\r
+\r
+               @Override\r
+               protected NodeTransformationQuery newTransformationListener(G3DNode node) {\r
+                       return new ShapeEditorNodeTransformationQuery(node.getResource());\r
+               }\r
+               \r
+               private class ShapeEditorRootPropertyQuery extends NodePropertyQuery {\r
+                       public ShapeEditorRootPropertyQuery(Resource nodeResource) {\r
+                               super(nodeResource);\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void shapeUpdated(Graph graph, final IGraphicsNode shape) {\r
+                               if (DEBUG)System.out.println("Tri - Shape id " + shape + " modified");\r
+\r
+                               updateParameterizationStatus(graph);\r
+                               if (isParameterized) {\r
+                                       for (IGraphicsNode n : getNodes())\r
+                                               if (n instanceof IGeometryNode)\r
+                                                       updateGeometry((IGeometryNode) n);\r
+                               }\r
+                       }\r
+                       \r
+//                     @Override\r
+//                     public NodeQuery instantiateQuery(Resource node) {\r
+//                             return new ShapeEditorRootPropertyQuery(node);\r
+//                     }\r
+               }\r
+               \r
+               @Override\r
+               protected NodePropertyQuery newRootPropertyListener(G3DNode root) {\r
+                       return new ShapeEditorRootPropertyQuery(root.getResource());\r
+               }\r
+               \r
+       }\r
+\r
+       protected void contributeStatusBar(IStatusLineManager manager) {\r
+       }\r
+\r
+       /**\r
+        * Loads the initial scene: all further updates to the view are done by\r
+        * listening changes in the shapes and int the shape group\r
+        * \r
+        * @param resource\r
+        */\r
+       protected void reloadFrom(IEntity thing) {\r
+               if (model != null) {\r
+                       throw new UnsupportedOperationException(\r
+                                       "Reloading instantiated viewer not supported");\r
+\r
+               }\r
+               if (thing.isInstanceOf(ShapeEditorResources.csgResource.CSGModel)) {\r
+                       //System.out.print("ShapeEditorView.reloadFrom() : model");\r
+                       Graph g = thing.getGraph();\r
+                       model = thing.getResource();\r
+                       //System.out.println(" " + model.getResource());\r
+                       adapter.setRootNode(new G3DNode(thing));\r
+                       updateParameterizationStatus(g);\r
+                       \r
+                       //loadGroup(thing.getGraph());\r
+                       \r
+               } else {\r
+                       throw new UnsupportedOperationException("Cannot load ShapeViewer for Resource:" + thing);\r
+               }\r
+\r
+       }\r
+       \r
+       private void updateParameterizationStatus(Graph graph) {\r
+               G3DModel model = getModel(graph);\r
+               if(model.getRelatedObjects(ShapeEditorResources.g3dResource.HasSizingParameter).size() > 0) {\r
+                       isParameterized = true;\r
+               } else {\r
+                       isParameterized = false;\r
+               }\r
+               parent.getDisplay().asyncExec(new Runnable() {\r
+                       @Override\r
+                       public void run() {\r
+//                             for (Action a : addActions)\r
+//                                     a.setEnabled(!isParameterized);\r
+//                             unionAction.setEnabled(!isParameterized);\r
+//                             differenceAction.setEnabled(!isParameterized);\r
+//                             intersectionAction.setEnabled(!isParameterized);\r
+//                             linkAction.setEnabled(!isParameterized);\r
+//                             unlinkAction.setEnabled(!isParameterized);\r
+//                             translateAction.setEnabled(!isParameterized);\r
+//                             rotateAction.setEnabled(!isParameterized);\r
+//                             removeAction.setEnabled(!isParameterized);\r
+                       }\r
+                       \r
+               });\r
+       }\r
+\r
+       public Resource getModelResource() {\r
+               return model;\r
+       }\r
+       \r
+       public G3DModel getModel(Graph graph) {\r
+               return new G3DModel(graph, model);\r
+       }\r
+\r
+       @Override\r
+       protected SelectionAdapter createSelectionAdapter() {\r
+               return new ShapeEditorSelectionAdapter(adapter);\r
+       }\r
+\r
+       protected class ShapeEditorSelectionAdapter extends SelectionAdapter {\r
+\r
+               public ShapeEditorSelectionAdapter(ScenegraphAdapter adapter) {\r
+                       super(adapter);\r
+               }\r
+\r
+               public void setEditorSelection() {\r
+                       List<IGraphicsNode> sel = getSelectedObjects();\r
+                       for (IGraphicsNode o : adapter.getNodes())\r
+                               if (o instanceof ISelectableNode) {\r
+                                       ISelectableNode n = (ISelectableNode)o;\r
+                                       if (sel.contains(o))\r
+                                               n.setSelected(true);\r
+                                       else\r
+                                               n.setSelected(false);\r
+                               }\r
+                       List<Resource> selected = getSelectedResources();\r
+                       for (Resource r : selected) {\r
+                               if (!adapter.hasNode(r)) {\r
+                                       //adapter.addInbound(r).setSelected(true);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               public void setEditorHighlightSelection() {\r
+                       List<IGraphicsNode> sel = getInteractiveSelectedObjects();\r
+                       for (IGraphicsNode o : adapter.getNodes())\r
+                               if (o instanceof CSGShapeNode) {\r
+                                       if (sel.contains(o))\r
+                                               ((CSGShapeNode) o).setHighlighted(true);\r
+                                       else\r
+                                               ((CSGShapeNode) o).setHighlighted(false);\r
+                               }\r
+               }\r
+\r
+               public void setEditorSelection(boolean addShapes) {\r
+\r
+                       List<IGraphicsNode> sel = getSelectedObjects();\r
+                       for (IGraphicsNode o : adapter.getNodes()) \r
+                               if (o instanceof ISelectableNode) {\r
+                                       ISelectableNode n = (ISelectableNode)o;\r
+                                       if (sel.contains(o)) \r
+                                               n.setSelected(true);\r
+                                       else\r
+                                               n.setSelected(false);\r
+                               }\r
+                       viewChanged = true;\r
+                       if (addShapes) {\r
+                               session.syncRead(new GraphRequestAdapter() {\r
+                                       @Override\r
+                                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                               List<Resource> selected = getSelectedResources();\r
+                                               for (Resource r : selected) {\r
+                                                       if (!adapter.hasNode(r)) {\r
+                                                               IEntity t = EntityFactory.create(g, r);\r
+                                                               if (t.isInstanceOf(ShapeEditorResources.g3dResource.Shape)) {\r
+                                                                       G3DNode group = G3DTools.getModelFromResource(g,r);\r
+                                                                       if (group != null\r
+                                                                                       && group.getResource().equals(model.getResource())) {\r
+                                                                               //adapter.addInbound(g).setSelected(true);\r
+                                                                       }\r
+\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                               return GraphRequestStatus.transactionComplete();\r
+                                       }\r
+                               });\r
+                               \r
+                       }\r
+               }\r
+\r
+               public StructuredResourceSelection filterSelection(ISelection selection) {\r
+                       if (!(selection instanceof StructuredResourceSelection))\r
+                               return new StructuredResourceSelection();\r
+                       return (StructuredResourceSelection) selection;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Receives selection changes\r
+        * \r
+        * @param part\r
+        * @param selection\r
+        */\r
+       protected void pageSelectionChanged(IWorkbenchPart part, ISelection selection) {\r
+               \r
+               StructuredResourceSelection s = SelectionAdapter.transformSelection(selection);\r
+               //System.out.println("ShapeEditorBase.pageSelectionChanged " + s);\r
+               selectionAdapter.setCurrentSelection(s);\r
+\r
+               if (!(part instanceof ThreeDimensionalEditorProvider)) {\r
+                       ((ShapeEditorSelectionAdapter) selectionAdapter).setEditorSelection(true);\r
+                       return;\r
+               }\r
+               ThreeDimensionalEditorBase e = ((ThreeDimensionalEditorProvider)part).getEditor();\r
+               if (!(e instanceof ShapeEditorBase)) {\r
+                       ((ShapeEditorSelectionAdapter) selectionAdapter).setEditorSelection(true);\r
+                       return;\r
+               }\r
+               \r
+               ShapeEditorBase editor = (ShapeEditorBase)e;\r
+               \r
+               if (!editor.getModelResource().equals(model.getResource())) {\r
+                       selectionAdapter.setCurrentSelection(new StructuredResourceSelection());\r
+                       ((ShapeEditorSelectionAdapter) selectionAdapter).setEditorSelection(false);\r
+                       return;\r
+               }\r
+               selectionAdapter.setEditorSelection();\r
+       }\r
+\r
+       @Override\r
+       protected void hookDragAndDrop() {\r
+               super.hookDragAndDrop();\r
+               dropTarget.addDropListener(new DropListener() {\r
+                       public boolean acceptDrop(StructuredResourceSelection s, Resource[] ids) {\r
+                               if (!s.isEmpty())\r
+                                       return false;\r
+                               if (ids == null)\r
+                                       return false;\r
+                               if (ids.length != 1)\r
+                                       return false;\r
+                               final Resource r = ids[0];\r
+                               GraphRequestWithResult<Boolean> rq = new GraphRequestWithResult<Boolean>() {\r
+                                       @Override\r
+                                       public Boolean performWithResult(Graph g) throws Exception {\r
+                                               IEntity t = EntityFactory.create(g, r);\r
+                                               return t.isInstanceOf(ShapeEditorResources.csgResource.Primitive);\r
+                                       }\r
+                               };\r
+                               session.syncRead(rq);\r
+                               return rq.getResult();\r
+                       }\r
+\r
+                       public void doDrop(StructuredResourceSelection s, Resource[] ids) {\r
+                               session.asyncWrite(new GraphRequestAdapter() {\r
+                                       Resource r;\r
+\r
+                                       public GraphRequestStatus perform(Graph g) throws Exception {\r
+                                               IEntity type = EntityFactory.create(g);\r
+                                               IEntity instance = type.instantiate();\r
+                                               Shape shape = new Shape(instance);\r
+                                               resetShape(shape);\r
+                                               CSGModel m = new CSGModel(g, model);\r
+                                               m.getChild().add(shape.toG3DNode()); // FIXME : stubcast\r
+                                               return GraphRequestStatus.transactionComplete();\r
+                                               \r
+                                       };\r
+                                       \r
+                                       @Override\r
+                                       public void requestCompleted(GraphRequestStatus status) {\r
+                                               selectionAdapter\r
+                                               .updateSelection(new StructuredResourceSelection(r));\r
+                                               super.requestCompleted(status);\r
+                                       }\r
+                               }\r
+                               );\r
+\r
+                       }\r
+               });\r
+       }\r
+       \r
+       private void resetShape(Shape shape) {\r
+               G3DTools.resetTransformation(shape);\r
+               Graph graph = shape.getGraph();\r
+               if (shape.isInstanceOf(ShapeEditorResources.csgResource.Primitive)) {\r
+                       Primitive prim = new Primitive(shape);\r
+                       Collection<Property> c = prim.getSizingProperty();\r
+                       if (c.size() == 0)\r
+                               ErrorLogger.getDefault().logWarning("Shape does not contain sizing properties.", null);\r
+                       \r
+                       for (Property p : c) {\r
+                               if (p.isInstanceOf(graph.getBuiltins().Double)) {\r
+                                       graph.setScalarDouble(p.getResource(), 1.0);\r
+                               } else if (p.isInstanceOf(graph.getBuiltins().Integer)) {\r
+                                       graph.setScalarInteger(p.getResource(), 1);\r
+                               } else {\r
+                                       ErrorLogger.getDefault().logWarning("Cannot handle sizing property " + p.getName() , null);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public Object getAdapter(Class adapter) {\r
+               if (adapter == IContentOutlinePage.class) {\r
+                       if (getModelResource() == null)\r
+                               return null;\r
+                       final StructureOutlinePage page = new StructureOutlinePage(sessionContext,getModelResource());\r
+                       \r
+                       getSelectionAdapter().addSelectionChangedListener(new ISelectionChangedListener() {\r
+                               @Override\r
+                               public void selectionChanged(SelectionChangedEvent event) {\r
+                                       page.setSelection(event.getSelection());\r
+                                       \r
+                               }\r
+                       });\r
+                       parent.getDisplay().asyncExec(new Runnable() {\r
+                               @Override\r
+                               public void run() {\r
+                                       page.addSelectionChangedListener(new ISelectionChangedListener() {\r
+                                               @Override\r
+                                               public void selectionChanged(SelectionChangedEvent event) {\r
+                                                       selectionAdapter.setSelection(SelectionAdapter.transformSelection(event.getSelection()));\r
+                                               }\r
+                                       });\r
+                               }\r
+                       });\r
+                       \r
+                       \r
+                       \r
+                       return page;\r
+               }\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorView.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ShapeEditorView.java
new file mode 100644 (file)
index 0000000..8fa7a37
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
+import org.simantics.proconf.g3d.base.ThreeDimensionalEditorPart;\r
+\r
+\r
+\r
+\r
+/**\r
+ * Shape Editor / CGS-modeling\r
+ * \r
+ * \r
+ * @author Marko Luukkainen\r
+ * \r
+ */\r
+public class ShapeEditorView extends ThreeDimensionalEditorPart {\r
+    \r
+    \r
+       @Override\r
+       protected ThreeDimensionalEditorBase createEditor(ISessionContext session) {\r
+               return new ShapeEditorBase(session);\r
+       }\r
+\r
+}\r
+\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureOutlinePage.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureOutlinePage.java
new file mode 100644 (file)
index 0000000..c0ddb2a
--- /dev/null
@@ -0,0 +1,21 @@
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.utils.viewpoints.ResourceViewpoint;\r
+import org.simantics.proconf.browsing.views.GraphExplorerOutlinePage;\r
+import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator;\r
+\r
+public class StructureOutlinePage extends GraphExplorerOutlinePage {\r
+       \r
+       \r
+       public StructureOutlinePage(ISessionContext session, Resource model) {\r
+               super(session,model);\r
+       }\r
+       \r
+       @Override\r
+       public ResourceViewpoint getViewPoint(ISessionContext sessionContext) {\r
+               return ViewpointGenerator.createObjectStructureViewpoint();\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureView.java b/org.simantics.proconf.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/StructureView.java
new file mode 100644 (file)
index 0000000..f747d49
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.shapeeditor.views;\r
+\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.utils.viewpoints.ResourceViewpoint;\r
+import org.simantics.proconf.browsing.views.GraphExplorerView;\r
+import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator;\r
+\r
+public class StructureView extends GraphExplorerView {\r
+\r
+    @Override\r
+    protected void contributeActions() {\r
+    }\r
+\r
+    @Override\r
+    protected ResourceViewpoint getViewpoint(ISessionContext context) {\r
+        return ViewpointGenerator.createStuctureViewpoint();\r
+    }\r
+\r
+    /*\r
+    @Override\r
+    public String getContributorId() {\r
+        return "fi.vtt.simantics.shapeeditor.pcid";\r
+    }\r
+\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if (adapter == IPropertySheetPage.class) {\r
+            return new TabbedPropertySheetPage(this);\r
+        }\r
+        return super.getAdapter(adapter);\r
+    }\r
+    */\r
+\r
+}\r