--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+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
--- /dev/null
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+ .,\\r
+ plugin.xml\r
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+<?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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+/*******************************************************************************\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
--- /dev/null
+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
--- /dev/null
+/*******************************************************************************\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