/******************************************************************************* * 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(); } }); } }