X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d.shapeeditor%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fshapeeditor%2Fviews%2FParameterizationEditor.java;fp=org.simantics.g3d.shapeeditor%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fshapeeditor%2Fviews%2FParameterizationEditor.java;h=f758618574a78cad8dc5fcd6e480024d72bc5609;hb=8b42fcb0b43efb8caaca85dd722ae608b9a3a730;hp=0000000000000000000000000000000000000000;hpb=55702d303318f9d3dc0b5e20010cfc2c4ae0b88e;p=simantics%2F3d.git diff --git a/org.simantics.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java b/org.simantics.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java new file mode 100644 index 00000000..f7586185 --- /dev/null +++ b/org.simantics.g3d.shapeeditor/src/org/simantics/proconf/g3d/shapeeditor/views/ParameterizationEditor.java @@ -0,0 +1,587 @@ +/******************************************************************************* + * Copyright (c) 2007- VTT Technical Research Centre of Finland. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.proconf.g3d.shapeeditor.views; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.forms.IFormColors; +import org.simantics.proconf.g3d.csg.stubs.CSGModel; +import org.simantics.db.Graph; +import org.simantics.db.GraphRequestAdapter; +import org.simantics.db.GraphRequestStatus; +import org.simantics.db.Resource; +import org.simantics.equation.stubs.SecondOrderScalarPolynomial; +import org.simantics.animation.stubs.Animation; +import org.simantics.animation.stubs.Interpolator; +import org.simantics.layer0.utils.ResourceDebugUtils; +import org.simantics.layer0.utils.IEntity; +import org.simantics.layer0.utils.EntityFactory; +import org.simantics.proconf.browsing.GraphExplorer; +import org.simantics.proconf.browsing.GraphExplorerInputFactory; +import org.simantics.proconf.g3d.common.StructuredResourceSelection; +import org.simantics.proconf.g3d.shapeeditor.ShapeEditorResources; +import org.simantics.proconf.g3d.shapeeditor.common.ViewpointGenerator; +import org.simantics.proconf.g3d.tools.OESelectionListener; +import org.simantics.proconf.g3d.tools.PropertyTree; +import org.simantics.proconf.g3d.views.SinglePageResourceEditor; +import org.simantics.utils.ui.widgets.TrackedModifyEvent; +import org.simantics.utils.ui.widgets.TrackedModifyListener; +import org.simantics.utils.ui.widgets.TrackedText; + + +public class ParameterizationEditor extends SinglePageResourceEditor { //implements ISelectionProvider{ + + //ParameterizedCSGModel model; + Resource modelResource; + private TrackedText modelName = null; + StructuredResourceSelection hierarchySelection = new StructuredResourceSelection(); + StructuredResourceSelection parameterSelection = new StructuredResourceSelection(); + GraphExplorer parameterExplorer; + GraphExplorer hierarchyExplorer; + Button deleteParameterButton; + Button clearButton; + PropertyTree propertiesTree; + Button generateButton; + Button askButton; + Button overrideButton; + Composite parent; + + + @Override + protected String getFormText() { + return "Parameterization Editor"; + } + +// @Override +// protected void beforeCreateWidgets() { +// if (!(getInputResource().isInstanceOf(GlobalIdMap.get(CSGModelingOntologyMapping.PARAMETERIZED_CSG_MODEL)))) +// throw new RuntimeException("Trying to open resource that is not paramaterized CSG model"); +// model = ParameterizedCSGModelFactory.create(getInputResource()); +// } + + + + @Override + protected void createWidgets() { + createModelPropertiesGroup(newGridSection(2, 2, false, false, "Model Properties", + "Basic properties for this viewpoint")); + createParametrizationGroup(newGridSection(2, 2, false, false, "Parameterization", + "Create parameterization for selected shapes")); + //getSite().setSelectionProvider(this); + } + + @Override + public void reload(Graph graph) { + modelResource = getInputResource(); + parent.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + reload(); + } + }); + + } + + public void reload() { + + hierarchyExplorer.setInput(getSessionContext(),GraphExplorerInputFactory.clone(hierarchyExplorer.getInput()) + .input(modelResource) + .viewpoint(ViewpointGenerator.createObjectStructureViewpoint()) + .toInput()); + + parameterExplorer.setInput(getSessionContext(),GraphExplorerInputFactory.clone(parameterExplorer.getInput()) + .input(modelResource) + .viewpoint(ViewpointGenerator.createObjectSizingParameterViewpoint(ShapeEditorResources.g3dResource.HasSizingParameter)) + .toInput()); + + } + + private void createParametrizationGroup(Composite parent) { + toolkit.paintBordersFor(parent); + toolkit.setBorderStyle(SWT.BORDER); + + overrideButton = toolkit.createButton(parent, "Overwrite previous parameterizations", SWT.CHECK); + overrideButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + askButton.setEnabled(overrideButton.getSelection()); + + } + }); + + + askButton = toolkit.createButton(parent, "Ask before overwriting", SWT.CHECK); + askButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + + } + }); + askButton.setEnabled(false); + + generateButton = toolkit.createButton(parent, "Generate linear parameterization", SWT.PUSH); + generateButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + generateMappings(); + + } + }); + generateButton.setEnabled(false); + + + } + + private CSGModel getModel(Graph graph) { + return new CSGModel(graph, modelResource); + } + + private void createModelPropertiesGroup(Composite p) { + parent = p; + toolkit.paintBordersFor(parent); + toolkit.setBorderStyle(SWT.BORDER); + + GridData gridData1 = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1); + GridData gridData2 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1); + + // Name + Label l1 = toolkit.createLabel(parent, "Name:"); + l1.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); + Text text = toolkit.createText(parent, "TODO: Insert model's name here", SWT.SINGLE); + GridData textLayout = new GridData(GridData.FILL, GridData.FILL, true, true); + text.setLayoutData(textLayout); + modelName = new TrackedText(text); + modelName.addModifyListener(new TrackedModifyListener(){ + @Override + public void modifyText(TrackedModifyEvent e) { + final String name = e.getText(); + getSession().asyncWrite(new GraphRequestAdapter() { + @Override + public GraphRequestStatus perform(Graph g) throws Exception { + getModel(g).setName(name); + return GraphRequestStatus.transactionComplete(); + } + }); + } + }); + + l1.setLayoutData(gridData1); + text.setLayoutData(gridData2); + + + // Parameters + Label parameterLabel = toolkit.createLabel(parent, "Parameters:"); + parameterLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); + parameterLabel.setLayoutData(gridData1); + + parameterExplorer = new GraphExplorer(parent, SWT.SINGLE); //new OntologyExplorer("ParameterExplorer", this, getInput("ParameterExplorer", model.getId())); + parameterExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() { + + protected void resourceSelectionUpdated(StructuredResourceSelection sel) { + parameterSelection = sel; + if (parameterSelection.size() == 0) { + deleteParameterButton.setEnabled(false); + clearButton.setEnabled(false); + } else { + deleteParameterButton.setEnabled(true); + clearButton.setEnabled(true); + } + updateGenerateButtonStatus(); + } + + }); + Tree oe = parameterExplorer.getTree(); + toolkit.adapt(oe, true, true); + GridData gd3 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1); + gd3.heightHint = 50; + oe.setLayoutData(gd3); +// parameterExplorer.init(getLastMemento(), ViewpointUtils.getModelledHandler(parameterExplorer.getGraph(), Builtins.DefaultViewpointId), null, ViewLabelProviderDecorationSettings.DEFAULT, new MenuAboutToShowAction(), new NullAdditionAction(), false); +// parameterScheme = new ParameterSelectionScheme(parameterExplorer); +// parameterExplorer.setSelectionScheme(parameterScheme); + + // Buttons to add and remove parameters + toolkit.createLabel(parent, ""); + Composite buttons = toolkit.createComposite(parent); + + buttons.setLayout(new FillLayout(SWT.HORIZONTAL)); + Button newParameterButton = toolkit.createButton(buttons, "New Parameter", SWT.PUSH); + newParameterButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + InputDialog dialog = new InputDialog(ParameterizationEditor.this.getSite().getShell(),"New Parameter","Enter parameter's name","new parameter",null); + if (dialog.open() == InputDialog.CANCEL) + return; + final String name = dialog.getValue(); + if (name.length() < 1) + return; // TODO : show error + + getSession().asyncWrite(new GraphRequestAdapter() { + public GraphRequestStatus perform(Graph g) throws Exception { + //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.createDefault(g); + //getModel(g).addStatement(ShapeEditorResources.g3dResource.HasSizingParameter, parameter); + //parameter.setValue(new double[]{1.0}); + //parameter.setName(name); + Resource parameter = getModel(g).addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasSizingParameter, 1.0).getResource(); + IEntity thing = EntityFactory.create(g,parameter); + thing.setName(name); + return GraphRequestStatus.transactionComplete(); + }; + }); + + + } + }); + deleteParameterButton = toolkit.createButton(buttons, "Delete Parameter", SWT.PUSH); + deleteParameterButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + //StructuredResourceSelection s = (StructuredResourceSelection)parameterScheme.getSelection(); + final StructuredResourceSelection s = parameterSelection; + if (s.size() != 1) + return; + // we'll have to start write transaction, since we may have to change the graph + getSession().asyncWrite(new GraphRequestAdapter() { + boolean proceed; + IEntity selectedParameter; + public GraphRequestStatus perform(Graph g) throws Exception { + selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0)); + + Collection parameters = selectedParameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasSizingParameter); + if (parameters.size() > 0) { + 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); + parent.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + proceed = (dialog.open() != 1); + } + }); + if (proceed) { + getModel(g).removeStatement(ShapeEditorResources.g3dResource.HasSizingParameter,selectedParameter); + } + } + + return GraphRequestStatus.transactionComplete(); + } + }); + } + }); + deleteParameterButton.setEnabled(false); + + clearButton = toolkit.createButton(buttons, "Clear Parameter", SWT.PUSH); + clearButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + final StructuredResourceSelection s = parameterSelection; + if (s.size() != 1) + return; + getSession().asyncWrite(new GraphRequestAdapter() { + boolean proceed; + @Override + public GraphRequestStatus perform(Graph g) throws Exception { + IEntity selectedParameter = EntityFactory.create(g,s.getSelectionList().get(0)); + Collection equations = selectedParameter.getRelatedObjects(ShapeEditorResources.equationResource.HasTarget); + final String name = selectedParameter.getName(); + if (equations.size() > 0) { + 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); + parent.getDisplay().syncExec(new Runnable() { + public void run() { + proceed = (dialog.open() != 1); + }; + }); + if (proceed) { + for (IEntity eq : equations) { + eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource); + eq.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget); + } + return GraphRequestStatus.transactionComplete(); + } + } + return GraphRequestStatus.transactionCancel(); + } + }); + + + } + }); + clearButton.setEnabled(false); + + Label hierarchyLabel = toolkit.createLabel(parent, "Model Hierarchy:"); + hierarchyLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); + hierarchyLabel.setLayoutData(gridData1); + + hierarchyExplorer = new GraphExplorer(parent,SWT.MULTI); //new OntologyExplorer("HierarchyExplorer", this, getInput("HierarchyExplorer", model.getId())); + Tree oeh = hierarchyExplorer.getTree();//hierarchyExplorer.getControl(parent, 1, OntologyExplorer.OntologyTree, SWT.MULTI); + toolkit.adapt(oeh, true, true); + + GridData gd4 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1); + gd4.heightHint = 200; + oeh.setLayoutData(gd4); + hierarchyExplorer.getViewer().addPostSelectionChangedListener(new OESelectionListener() { + + protected void resourceSelectionUpdated(StructuredResourceSelection sel) { + hierarchySelection = sel; + updatePropertiesTable(); + updateGenerateButtonStatus(); + } + + private void updatePropertiesTable() { + propertiesTree.setProperties(hierarchySelection); + + } + + }); + //hierarchyExplorer.init(getLastMemento(), ViewpointUtils.getModelledHandler(hierarchyExplorer.getGraph(), CSGModelingOntologyMapping.CSG_MODEL_HIERARCHY_VIEWPOINT), null, ViewLabelProviderDecorationSettings.DEFAULT, new MenuAboutToShowAction(), new NullAdditionAction(), false); +// hierarchyScheme = new HierarchySelectionScheme(hierarchyExplorer); +// hierarchyExplorer.setSelectionScheme(hierarchyScheme); +// hierarchyExplorer.hookPageSelection(this); + Label propertiesLabel = toolkit.createLabel(parent, "Available properties:"); + propertiesLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); + propertiesLabel.setLayoutData(gridData1); + + //propertiesTable = toolkit.createTable(parent, SWT.MULTI); + Tree tree = toolkit.createTree(parent, SWT.MULTI); + propertiesTree = new PropertyTree(tree,getSession()); + // + GridData gd5 = new GridData(GridData.FILL, GridData.FILL, true, true,1,1); + gd5.heightHint = 200; + //propertiesTable.setLayoutData(gd5); + tree.setLayoutData(gd5); + tree.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + updateGenerateButtonStatus(); + } + + }); + + + } + +// private class ParameterSelectionScheme extends AbstractSelectionScheme { +// +// public ParameterSelectionScheme(OntologyExplorer explorer) { +// super(explorer); +// } +// +// @Override +// protected Resource getResourceForSelection(TreeNode selected) { +// Resource resource = explorer.getCoreResource(selected); +// System.out.println("Parameter Tree Selection : " + resource.getId()); +// return resource; +// } +// +// @Override +// protected void resourceSelectionUpdated() { +// if (selection.size() == 0) { +// deleteParameterButton.setEnabled(false); +// clearButton.setEnabled(false); +// } else { +// deleteParameterButton.setEnabled(true); +// clearButton.setEnabled(true); +// } +// updateGenerateButtonStatus(); +// } +// } +// +// private class HierarchySelectionScheme extends AbstractSelectionScheme { +// +// public HierarchySelectionScheme(OntologyExplorer explorer) { +// super(explorer); +// } +// +// @Override +// protected Resource getResourceForSelection(TreeNode selected) { +// Resource resource = explorer.getCoreResource(selected); +// System.out.println("Hierarchy Tree Selection : " + resource.getId()); +// return resource; +// } +// +// @Override +// protected void resourceSelectionUpdated() { +// updatePropertiesTable(); +// updateGenerateButtonStatus(); +// } +// +// private void updatePropertiesTable() { +// propertiesTree.setProperties(selection); +// +// } +// +// } + +// private boolean contains(Resource list[], Resource value) { +// for (int i = 0; i < list.length; i++) { +// if (list[i].equals(value)) +// return true; +// } +// return false; +// } + + private void updateGenerateButtonStatus() { + if (parameterSelection.size() == 0) { + generateButton.setEnabled(false); + return; + } + if (hierarchySelection.size() == 0) { + generateButton.setEnabled(false); + return; + } + if (propertiesTree.getTree().getSelection().length == 0) { + generateButton.setEnabled(false); + return; + } + generateButton.setEnabled(true); + } + + List res; + + private void generateMappings() { + final StructuredResourceSelection selectedShapes = hierarchySelection; + final StructuredResourceSelection selectedParameter = parameterSelection; + + final boolean override = overrideButton.getSelection(); + final boolean ask = askButton.getSelection(); + //TreeItem[] selectedProperties = propertiesTree.getTree().getSelection(); + + assert (selectedParameter.size() == 1); + assert (selectedShapes.size() > 0); + //assert(selectedProperties.length > 0); + getSession().asyncWrite(new GraphRequestAdapter() { + @Override + public GraphRequestStatus perform(Graph g) throws Exception { + //fi.vtt.simantics.layer0.stubs.Double parameter = DoubleFactory.create(g,selectedParameter.getSelectionList().get(0)); + IEntity parameter = EntityFactory.create(g,selectedParameter.getSelectionList().get(0)); + Collection prop = parameter.getRelatedObjects(ShapeEditorResources.g3dResource.HasDefaultDoubleValue); + //fi.vtt.simantics.layer0.stubs.Double defaultValue; + double value = g.getScalarDouble(parameter.getResource()); + if (prop.size() == 0) { + //defaultValue = DoubleFactory.createDefault(g); + //parameter.addStatement(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, defaultValue); + parameter.addRelatedScalarDouble(ShapeEditorResources.g3dResource.HasDefaultDoubleValue, value); + } else { + //defaultValue = DoubleFactory.create(prop.iterator().next()); + g.setScalarDouble(prop.iterator().next().getResource(),value); + } + //defaultValue.setValue(parameter.getValue()); + final Graph graph = g; + parent.getDisplay().syncExec(new Runnable() { + public void run() { + res = propertiesTree.findLeafPropertyInstances(graph, selectedShapes.getSelectionList()); + }; + }); + + + double refValue = parameter.toProperty().getScalarDouble(); + ArrayList mappedProperties = new ArrayList(); + + for (Resource r : res) { + IEntity propertyThing = EntityFactory.create(g,r); + assert (propertyThing.isInstanceOf(g.getBuiltins().Double)); + final String name = ResourceDebugUtils.getReadableNameForEntity(propertyThing); + double rb = propertyThing.toProperty().getScalarDouble(); + System.out.println("Mapping to " + name + " " + rb); + Collection equations = propertyThing.getRelatedObjects(ShapeEditorResources.equationResource.HasSource); + if (equations.size() != 0) { + mappedProperties.add(propertyThing.getResource()); + if (override) { + System.out.println("Override"); + boolean over = true; + if (ask) { + IEntity t = propertyThing; + while (t.isInstanceOf(g.getBuiltins().Property)) { + Collection ts = t.getRelatedObjects(g.getBuiltins().PropertyOf); + // FIXME : traverse all possible routes + t = ts.iterator().next(); + } + //StructuredResourceSelection selection = new StructuredResourceSelection(t.getResource()); + // TODO : do the selection! + //hierarchyScheme.setSelection(selection); + //fireSelectionChanged(); + MessageDialog dialog = new MessageDialog(ParameterizationEditor.this.getSite().getShell(), + "Override mapping", + null, + "Override mapping to property of highlighted shape?", + MessageDialog.QUESTION, new String[] { + "Yes","No", "Cancel" }, 0); + int i = dialog.open(); + if (i == 2) + return GraphRequestStatus.transactionCancel(); + over = (i == 0); + } + if (over) { + + } + } else { + if (equations.size() != 1) { + throw new RuntimeException("One property can have only one euquation as source function."); + } + IEntity equation = equations.iterator().next(); + if (!equation.isInstanceOf(ShapeEditorResources.equationResource.SecondOrderScalarPolynomial)) { + throw new RuntimeException("Only Second order scalar polynomials are supported"); + } + SecondOrderScalarPolynomial s = new SecondOrderScalarPolynomial(equation); + s.setA(new double[]{0.0}); + s.setB(new double[]{rb / refValue}); + s.setC(new double[]{0.0}); + + } + } else { //override + // create relation + SecondOrderScalarPolynomial s = SecondOrderScalarPolynomial.createDefault(g); + s.setA(new double[]{0.0}); + s.setB(new double[]{rb / refValue}); + s.setC(new double[]{0.0}); + + // FIXME : these relations have been instantiated, but addStatements won't delete them so we have to delete them manually. + s.removeRelatedStatements(ShapeEditorResources.equationResource.HasTarget); + s.removeRelatedStatements(ShapeEditorResources.equationResource.HasSource); + + parameter.addStatement(ShapeEditorResources.equationResource.HasTarget, s); + + s.addStatement(ShapeEditorResources.equationResource.HasTarget, propertyThing); + mappedProperties.add(propertyThing.getResource()); + } + + } + CSGModel model = getModel(g); + Collection animations = model.getAnimation(); + for (Animation animation : animations) { + Collection interpolators = animation.getInterpolator(); + for (Interpolator interpolator : interpolators) { + IEntity target = interpolator.getTarget(); + for (Resource property : mappedProperties) { + if (target.getResource().equals(property)) { + ShapeEditorResources.curveBuilder.createDefault(interpolator); + } + } + } + } + return GraphRequestStatus.transactionComplete(); + } + }); + + + + } + +} +