X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fscenegraph%2FParameterizedModelNode.java;fp=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fproconf%2Fg3d%2Fscenegraph%2FParameterizedModelNode.java;h=1eb29bb41c72f50ba7ff9132ba24aa1705fff632;hb=10f144a2bb2d7bec98b812b83acecb333fd098ea;hp=0000000000000000000000000000000000000000;hpb=3055b543aa5afc0cca4bb3b341704e7c5103fa6a;p=simantics%2F3d.git diff --git a/org.simantics.g3d/src/org/simantics/proconf/g3d/scenegraph/ParameterizedModelNode.java b/org.simantics.g3d/src/org/simantics/proconf/g3d/scenegraph/ParameterizedModelNode.java new file mode 100644 index 00000000..1eb29bb4 --- /dev/null +++ b/org.simantics.g3d/src/org/simantics/proconf/g3d/scenegraph/ParameterizedModelNode.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * 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.scenegraph; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.simantics.db.Builtins; +import org.simantics.db.ContextGraph; +import org.simantics.db.Graph; +import org.simantics.db.Resource; +import org.simantics.equation.solver.Solver; +import org.simantics.animation.stubs.Animation; +import org.simantics.layer0.utils.Property; +import org.simantics.layer0.utils.IEntity; +import org.simantics.layer0.utils.EntityFactory; +import org.simantics.layer0.utils.Statement; +import org.simantics.proconf.g3d.Resources; +import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase; +import org.simantics.proconf.g3d.stubs.G3DModel; +import org.simantics.proconf.g3d.stubs.G3DNode; +import org.simantics.utils.ui.ErrorLogger; + +/** + * IGraphicsNode for parameterized models. Implementation assumes that G3DNode itself does not contain + * graphical representation but has link to it. + * + * @author Marko Luukkainen + * + */ +public class ParameterizedModelNode extends ModelNode { + + /** + * @param editor + * @param parent + * @param graph + * @param resource this node (G3DNode). + * @param nodeToModelRelation relation from this node to the model, or from type of this node to the model. + * @param modelToParametersRelation relation from the model to its sizing parameters + */ + public ParameterizedModelNode(ThreeDimensionalEditorBase editor, IGraphicsNode parent, Graph graph, Resource resource, Resource nodeToModelRelation) { + super(editor,parent,graph,resource); + G3DNode shape = getG3DNode(graph); + List models = new ArrayList(); + models.addAll(shape.getRelatedObjects(nodeToModelRelation)); + if (models.size() == 0) { + Collection types = shape.getTypes(); + for (IEntity type : types) { + models.addAll(type.getRelatedObjects(nodeToModelRelation)); + } + } + if (models.size() != 1) + throw new IllegalArgumentException("Cannot find proper model: found " + models.size() + " models."); + + this.modelResource = models.iterator().next().getResource(); + } + + @Override + protected void createGeometry(Graph graph) { + super.createGeometry(createParameterization(graph)); + } + + @Override + public void updateGeometry(Graph graph) { + super.updateGeometry(createParameterization(graph)); + } + + private void updateSizeParameters(ContextGraph graph, Solver solver) { + Builtins builtins = graph.getBuiltins(); + + + G3DNode node = getG3DNode(graph); + //Collection nodeProperties = node.getRelatedProperties(builtins.HasProperty); + Collection nodeProperties = node.getRelatedStatements(builtins.HasProperty); + G3DModel model = getG3DModel(graph); + Collection modelProperties = model.getRelatedProperties(Resources.g3dResource.HasSizingParameter); + + // there are no relations between then nodes properties and the model's sizing parameters + // link between them is done by matching names + for (Property m : modelProperties) { + boolean set = false; + //if(m.canBeSet(builtins.HasName)) { + + String modelPropertyname = m.getAtMostOneRelatedProperty(builtins.HasName).getScalarString(); + for (Statement n : nodeProperties) { + String relationName = n.getPredicate().getName(); + if (relationName.startsWith("Has ")) + relationName = relationName.substring(4); + if (relationName.equalsIgnoreCase(modelPropertyname)) { + // found a match + // set property's value for Solver + solver.setValue(m.getResource(), graph.getValueAsObject(n.getObject().getResource())); + set = true; + break; + } + + } + if (!set) { + ErrorLogger.defaultLogError("Cannot map property " + modelPropertyname, null); + } + //} + + } + + for (Property p : modelProperties) { + IEntity t = EntityFactory.create(graph, p.getResource()); + Collection exp = t.getRelatedObjects(Resources.equationResource.HasTarget); + if (exp.size() > 0) { + Iterator i = exp.iterator(); + while(i.hasNext()) + solver.evaluate(i.next()); + } else + ErrorLogger.defaultLogError("Model property " + p + " is not bound to a expression",null); + } + solver.pushToGraph(graph); + Collection animations = model.getAnimation(); + for (Animation animation : animations) { + Collection interpolators = animation.getInterpolator(); + for (org.simantics.animation.stubs.Interpolator interpolator : interpolators) { + IEntity target = interpolator.getTarget(); + // check all model properties + for (Property p : modelProperties) { + IEntity t = EntityFactory.create(graph,p.getResource()); + // get parameterization equations + Collection equations = t.getRelatedObjects(Resources.equationResource.HasTarget); + // get parameterized values + Collection parameterTargets = new ArrayList(); + for (IEntity eq : equations) { + Collection tgts = eq.getRelatedObjects(Resources.equationResource.HasTarget); + assert(tgts.size() == 1); + parameterTargets.add(tgts.iterator().next()); + } + // do matching between interpolator targets and parameterized values + // TODO : old system did not have inverse relations but current system does. + // it is possible to take interpolation target and find if it is connected to an equation + // this would make code much faster (no more stupid loops over everything) + for (IEntity d : parameterTargets) { + if (d.getResource().equals(target.getResource())) { + // get default value for sizing property + Collection prop = t.getRelatedObjects(Resources.g3dResource.HasDefaultDoubleValue); + if (prop.size() == 1) { + Resources.curveBuilder.parameterize(interpolator, prop.iterator().next().toProperty().getDoubleArray(), p.getDoubleArray()); + } else { + ErrorLogger.defaultLogError("Cannot parameterize interpolator " + interpolator.getResource() + " of animation " + animation.getResource() + " since parameter " + p.getResource() + " has no default value", null); + } + } + } + } + } + } + + } + + protected Graph createParameterization(Graph graph) { + // create ContextGraph if needed + ContextGraph g; + if (!(graph instanceof ContextGraph)) + g = new ContextGraph(graph); + else + g = (ContextGraph)graph; + // set the context + g.setContext(this.shapeResource); + // create solver and calculate parameterized values + Solver solver = new Solver(); + updateSizeParameters(g, solver); + // push parameterized values to context + solver.pushToGraph(g); + // return graph with parameterized values + return g; + } + + @Override + public boolean setAnimation(Graph graph, Resource animation) { + return super.setAnimation(createParameterization(graph), animation); + } + + +}