From 9274c5e8b5477ebf0739fb46dbab66aad5a93fbf Mon Sep 17 00:00:00 2001 From: jkauttio Date: Mon, 31 Mar 2014 07:45:08 +0000 Subject: [PATCH] Update vensim import, partial equation handling present but subscript support missing refs #2924 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches@29218 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../ui/handlers/imports/ImportMdlHandler.java | 3 +- .../org.simantics.sysdyn.ui/sysdyn.product | 6 +- .../sysdyn/modelImport/MdlParser2.java | 254 +++++++++--------- .../sysdyn/modelImport/MdlUtils.java | 167 ++++++++++-- .../sysdyn/modelImport/model/Auxiliary2.java | 14 +- .../sysdyn/modelImport/model/Cloud2.java | 11 +- .../sysdyn/modelImport/model/Comment2.java | 8 +- .../sysdyn/modelImport/model/Connection2.java | 30 ++- .../modelImport/model/DelayExpression.java | 28 ++ .../sysdyn/modelImport/model/Dependency2.java | 22 +- .../sysdyn/modelImport/model/Element2.java | 46 +++- .../sysdyn/modelImport/model/Flow2.java | 15 +- .../modelImport/model/IWriteableObject.java | 2 +- .../modelImport/model/IntegralExpression.java | 2 +- .../modelImport/model/LookupExpression.java | 14 + .../sysdyn/modelImport/model/MdlModel.java | 47 +++- .../sysdyn/modelImport/model/Model2.java | 15 +- .../model/ModelElementFactory.java | 68 +++++ .../modelImport/model/ModelVariable.java | 14 +- .../modelImport/model/NormalExpression.java | 2 +- .../sysdyn/modelImport/model/Range.java | 2 +- .../sysdyn/modelImport/model/Shadow2.java | 16 +- .../sysdyn/modelImport/model/Sketch2.java | 40 +-- .../modelImport/model/SketchComment.java | 15 +- .../modelImport/model/SketchConnection.java | 62 ++++- .../modelImport/model/SketchElement.java | 47 +++- .../modelImport/model/SketchObject.java | 4 +- .../sysdyn/modelImport/model/SketchValve.java | 16 +- .../modelImport/model/SketchVariable.java | 16 +- .../sysdyn/modelImport/model/Stock2.java | 14 +- .../sysdyn/modelImport/model/Valve2.java | 42 ++- .../modelImport/model/WriteContext.java | 40 +++ 32 files changed, 801 insertions(+), 281 deletions(-) create mode 100644 dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/DelayExpression.java create mode 100644 dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/LookupExpression.java create mode 100644 dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelElementFactory.java create mode 100644 dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/WriteContext.java diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java index fe212805..7bd39e6f 100644 --- a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java @@ -29,6 +29,7 @@ import org.simantics.sysdyn.modelImport.MdlParser; import org.simantics.sysdyn.modelImport.MdlParser2; import org.simantics.sysdyn.modelImport.model.Model; import org.simantics.sysdyn.modelImport.model.Model2; +import org.simantics.sysdyn.modelImport.model.WriteContext; import org.simantics.sysdyn.ui.Activator; import org.simantics.ui.SimanticsUI; @@ -74,7 +75,7 @@ public class ImportMdlHandler extends AbstractHandler { @Override public void perform(WriteGraph graph) throws DatabaseException { - model.write(graph, project); + model.write(graph, project, new WriteContext()); } }); diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product b/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product index 5c3c71bb..01a866ef 100644 --- a/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product +++ b/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product @@ -13,9 +13,8 @@ - -fixerrors ---launcher.XXMaxPermSize 192m --data @noDefault + -fixerrors +--launcher.XXMaxPermSize 192m -ea -Xmx768M -XX:MaxPermSize=192m -Xshare:off -Dorg.simantics.undo.enabled=false -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -Dorg.osgi.framework.os.name=win32 @@ -32,7 +31,6 @@ - org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java index f5e8b642..aa667ca1 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java @@ -26,6 +26,7 @@ import org.simantics.sysdyn.modelImport.model.Comment2; import org.simantics.sysdyn.modelImport.model.Connection2; import org.simantics.sysdyn.modelImport.model.Element2; import org.simantics.sysdyn.modelImport.model.IntegralExpression; +import org.simantics.sysdyn.modelImport.model.MdlModel; import org.simantics.sysdyn.modelImport.model.Model2; import org.simantics.sysdyn.modelImport.model.Shadow2; import org.simantics.sysdyn.modelImport.model.Sketch2; @@ -51,229 +52,220 @@ public class MdlParser2 { private static final String UTF_8 = "{UTF-8}"; private static final String SKETCH_VERSION = "V300"; - + private static final String CATEGORY_CONTROL = "Control"; - + // each .mdl is divided into three sections, these are the the delimiter // strings used to identify where each section starts private static final String SKETCH_START = "\\\\\\---///"; private static final String SKETCH_END = "///---\\\\\\"; - - private static final double H_SPACE = 10; - private static final double V_SPACE = 0; - - private HashMap variables; - private HashMap controls; - private ArrayList sketches; - - public MdlParser2() { - variables = new HashMap(); - controls = new HashMap(); - sketches = new ArrayList(); - } - public Model2 parse(File file) { - try { - // peek at the first line to see if we need to use UTF-8 - BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); - String line = reader.readLine(); - - if (line == null) { - // file is empty, nothing to do here - reader.close(); - return null; - } + private static final double H_SPACE = 0; + private static final double V_SPACE = 10; - if (line.startsWith(UTF_8)) { - reader.close(); - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); - // skip the first line - reader.readLine(); - line = reader.readLine(); - } - - // read variable data - line = readVariables(reader, line); - - if (line == null) { - // unexpected end of file - System.err.println("unexpected end of file"); - reader.close(); - return null; - } - - // read sketch data - line = readSketches(reader, line); - - if (line == null) { - // unexpected end of file - System.err.println("unexpected end of file"); - reader.close(); - return null; - } - - // read other data - - do { - // ignore other data for now - } while ((line = reader.readLine()) != null); - - reader.close(); + public static Model2 parse(File file) { + // generate a mdl model based on the contents of the file + MdlModel mdl; + try { + mdl = parseFile(file); } catch (IOException e) { e.printStackTrace(); return null; } - - // create new model + // generate a sysdyn model from the mdl model Model2 model = new Model2(file.getName()); - - double hOffset = 0; - double vOffset = V_SPACE; - + + double offset = 0; + // do this in several passes - - HashMap allVariables = new HashMap(); + + HashMap variableToElement = new HashMap(); + ArrayList shadows = new ArrayList(); // add sketch labels and independent elements - for (int i = 0; i < sketches.size(); i++) { - Sketch2 sketch = sketches.get(i); - - sketch.hOffset = hOffset; - sketch.vOffset = vOffset; - - model.addElement(new Comment2(sketch.getWidth() / 2 + sketch.hOffset, 0, sketch.getName())); - + for (Sketch2 sketch : mdl.getSketches()) { + sketch.setEdges(); + + sketch.hOffset = 0; + sketch.vOffset = 0 - sketch.topEdge + 10 + offset; + + model.addElement(new Comment2(0, offset, -1, -1, sketch.getName())); + for (SketchComment comment : sketch.getComments()) { if (comment.isInputOutput()) { // input / output objects are not supported yet System.err.println("input / output objects are not supported yet"); continue; } - + Element2 modelElement = comment.getModelElement(sketch.hOffset, sketch.vOffset); model.addElement(modelElement); sketch.elements.put(comment.getId(), modelElement); } - + for (SketchValve valve : sketch.getValves()) { Element2 modelElement = valve.getModelElement(sketch.hOffset, sketch.vOffset); model.addElement(modelElement); sketch.elements.put(valve.getId(), modelElement); sketch.elements.put(valve.getAttachedVariable().getId(), modelElement); - allVariables.put(valve.getAttachedVariable().getVariable(), modelElement); + variableToElement.put(valve.getAttachedVariable().getVariable(), modelElement); } - + for (SketchVariable variable : sketch.getVariables()) { if (!variable.allowsIn()) { // the variable is a shadow variable, skip these for now continue; } - + if (variable.isAttached()) { // the variable is attached to a valve, already handled continue; } - + Element2 modelElement = variable.getModelElement(sketch.hOffset, sketch.vOffset); model.addElement(modelElement); sketch.elements.put(variable.getId(), modelElement); - allVariables.put(variable.getVariable(), modelElement); + variableToElement.put(variable.getVariable(), modelElement); } - - hOffset += sketch.getWidth() + H_SPACE; + + offset += (sketch.bottomEdge - sketch.topEdge + V_SPACE); } - + // add dependent elements - for (int i = 0; i < sketches.size(); i++) { - Sketch2 sketch = sketches.get(i); - + for (Sketch2 sketch : mdl.getSketches()) { for (SketchVariable variable : sketch.getVariables()) { if (!variable.allowsIn()) { // the variable is a shadow variable - Element2 original = allVariables.get(variable.getVariable()); + Element2 original = variableToElement.get(variable.getVariable()); if (original == null) { System.err.println("original not found"); continue; } - Shadow2 modelElement = new Shadow2(variable.getX(sketch.hOffset), variable.getY(sketch.vOffset), allVariables.get(variable.getVariable())); + Shadow2 modelElement = new Shadow2( + variable.getSysdyndX() + sketch.hOffset, + variable.getSysdyndY() + sketch.vOffset, + variable.getSysdynWidth(), + variable.getSysdynHeight(), + variableToElement.get(variable.getVariable())); model.addShadow(modelElement); sketch.elements.put(variable.getId(), modelElement); } } - + for (SketchConnection connection : sketch.getConnections()) { Element2 head = sketch.elements.get(connection.getTo()); Element2 tail = sketch.elements.get(connection.getFrom()); - Connection2 c = connection.getWriteableConnection(head, tail); + Connection2 c = connection.getWriteableConnection(head, tail, sketch.vOffset); if (c != null) { model.addConnection(c); } } } - + return model; } - - private String readVariables(BufferedReader reader, String line) + + private static MdlModel parseFile(File file) throws IOException { + MdlModel mdl = new MdlModel(file.getName()); + // peek at the first line to see if we need to use UTF-8 + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + String line = reader.readLine(); + + if (line == null) { + // file is empty, nothing to do here + reader.close(); + return null; + } + + if (line.startsWith(UTF_8)) { + reader.close(); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); + // skip the first line + reader.readLine(); + line = reader.readLine(); + } + + // read variable data + line = parseVariables(reader, line, mdl); + + if (line == null) { + System.err.println("unexpected end of file"); + reader.close(); + return null; + } + + // read sketch data + line = parseSketches(reader, line, mdl); + + if (line == null) { + System.err.println("unexpected end of file"); + reader.close(); + return null; + } + + // read other data + do { + // TODO: is there anything relevant here? + } while ((line = reader.readLine()) != null); + + reader.close(); + return mdl; + } + + private static String parseVariables(BufferedReader reader, String line, MdlModel mdl) + throws IOException { String category = null; - + do { - if (line.isEmpty()) { + if (line.isEmpty()) continue; - } - - StringBuilder buffer = new StringBuilder(line); - + + StringBuilder buffer = new StringBuilder(); do { if (line.endsWith("\\")) buffer.append(line.substring(0, line.length()-1)); else buffer.append(line); - + if (line.endsWith("|")) break; } while ((line = reader.readLine()) != null); - String str = buffer.toString(); - // handle category declarations String cat = MdlUtils.getPossibleCategory(str); if (cat != null) { category = cat; continue; } - + Variable2 var = MdlUtils.getPossibleVariable(str, category); if (var != null) { - if (CATEGORY_CONTROL.equals(category)) { - controls.put(var.getName(), var); - } - else { - variables.put(var.getName(), var); - } + mdl.addVariable(var, category); continue; } - + + // if we got this far, the variable could not be parsed System.err.println("unrecognized variable "+str); - } while ((line = reader.readLine()) != null && !line.startsWith(SKETCH_START)); - + return line; } - - private String readSketches(BufferedReader reader, String line) + + private static String parseSketches(BufferedReader reader, String line, MdlModel mdl) throws IOException { - Sketch2 sketch = null; - + do { + if (line.isEmpty()) + continue; + if (line.startsWith(SKETCH_START)) { sketch = new Sketch2(); - sketches.add(sketch); + mdl.addSketch(sketch); continue; } else if (line.startsWith(SKETCH_VERSION)) { @@ -288,25 +280,24 @@ public class MdlParser2 { // font declaration, nothing to do here continue; } - + SketchConnection connection = MdlUtils.getPossibleSketchConnection(line); if (connection != null) { sketch.addConnection(connection); continue; } - - SketchVariable variable = MdlUtils.getPossibleSketchVariable(line, variables); + + SketchVariable variable = MdlUtils.getPossibleSketchVariable(line, mdl); if (variable != null) { sketch.addVariable(variable); continue; } - + SketchValve valve = MdlUtils.getPossibleSketchValve(line); if (valve != null) { // the next row after a valve should always the variable associated with the valve - SketchVariable attached = MdlUtils.getPossibleSketchVariable(reader.readLine(), variables); + SketchVariable attached = MdlUtils.getPossibleSketchVariable(reader.readLine(), mdl); if (attached == null || !attached.isAttached()) { - // TODO: should also verify that the variable is in fact attached System.err.println("attached variable not found for valve"); continue; } @@ -315,7 +306,7 @@ public class MdlParser2 { sketch.addVariable(attached); continue; } - + SketchComment comment = MdlUtils.getPossibleSketchComment(line); if (comment != null) { if (comment.hasTextLine()) { @@ -324,12 +315,11 @@ public class MdlParser2 { sketch.addComment(comment); continue; } - - // if we got this far, the element was not recognized + + // if we got this far, the element could not be parsed System.err.println("unrecognized element "+line); - } while ((line = reader.readLine()) != null && !line.startsWith(SKETCH_END)); - + return line; } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java index 7a814889..eda44c42 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java @@ -1,11 +1,12 @@ package org.simantics.sysdyn.modelImport; -import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.simantics.sysdyn.modelImport.model.DelayExpression; import org.simantics.sysdyn.modelImport.model.IExpression; import org.simantics.sysdyn.modelImport.model.IntegralExpression; +import org.simantics.sysdyn.modelImport.model.MdlModel; import org.simantics.sysdyn.modelImport.model.NormalExpression; import org.simantics.sysdyn.modelImport.model.Range; import org.simantics.sysdyn.modelImport.model.SketchComment; @@ -79,6 +80,9 @@ public class MdlUtils { private static final int variableUnit = 3; private static final int variableDesc = 4; + private static final String NUMBER = + "-?\\d+(?:.\\d+)?"; + public static Variable2 getPossibleVariable(String line, String category) { Matcher matcher = Pattern.compile(variablePattern).matcher(line); @@ -86,7 +90,7 @@ public class MdlUtils { return null; } - String name = matcher.group(variableName); + String name = normalize(matcher.group(variableName)); IExpression expression = parseEquation(matcher.group(variableEquation)); String unit = matcher.group(variableUnit); @@ -100,23 +104,48 @@ public class MdlUtils { } private static IExpression parseEquation(String equation) { - Matcher matcher = Pattern.compile("INTEG\\s*\\((.*),(.*)\\)").matcher(equation); - if (matcher.matches()) { - return new IntegralExpression(matcher.group(1), matcher.group(2)); + if (equation.startsWith("INTEG")) { + return parseIntegralExpression(equation); + } + else if (equation.startsWith("GAME")) { + // game expressions are treated as normal parameters as we do not + // have equivalent functionality in sysdyn + return parseNormalExpression(equation); } else { - return new NormalExpression(""); + return parseNormalExpression(equation); } } + private static IntegralExpression parseIntegralExpression(String equation) { + Matcher matcher = Pattern.compile("INTEG \\((.*),(.*)\\)").matcher(equation); + if (!matcher.matches()) { + System.err.println("could not parse integral expression: "+equation); + return null; + } + + String integral = normalize(matcher.group(1)); + String initial = normalize(matcher.group(2)); + + return new IntegralExpression(integral, initial); + } + + private static DelayExpression parseDelayExpression(String equation) { + return null; + } + + private static NormalExpression parseNormalExpression(String equation) { + return new NormalExpression(normalize(equation)); + } + private static Range parseRange(String unit) { - Matcher matcher = Pattern.compile("\\[(-?\\d+|\\?),(-?\\d+|\\?)\\]").matcher(unit); + Matcher matcher = Pattern.compile("\\[("+NUMBER+"),("+NUMBER+"|\\?)\\]").matcher(unit); if (matcher.find()) { String start = matcher.group(1); String end = matcher.group(2); // TODO: and step is? return new Range( - start.equals("?") ? null : Double.parseDouble(start), + Double.parseDouble(start), end.equals("?") ? null : Double.parseDouble(end), null, matcher.group()); @@ -189,11 +218,27 @@ public class MdlUtils { int from = Integer.parseInt(matcher.group(connectionFrom)); int to = Integer.parseInt(matcher.group(connectionTo)); ConnectionType type = getConnectionType(matcher); + int[] points = parsePoints(matcher.group(connectionPoints)); - return new SketchConnection(id, from, to, type); + return new SketchConnection(id, from, to, type, points); } - public static SketchVariable getPossibleSketchVariable(String line, HashMap variables) { + private static int[] parsePoints(String points) { + // points should be a well formed points string + int sep = points.indexOf('|'); + int count = Integer.parseInt(points.substring(0, sep)); + int[] array = new int[count*2]; + for (int i = 0; i < count; i++) { + int start = sep + 1; + sep = points.indexOf('|', start); + String[] pair = points.substring(start+1, sep-1).split(","); + array[i*2] = Integer.parseInt(pair[0]); + array[i*2+1] = Integer.parseInt(pair[1]); + } + return array; + } + + public static SketchVariable getPossibleSketchVariable(String line, MdlModel mdl) { Matcher matcher = Pattern.compile(sketchVariable).matcher(line); if (!matcher.matches()) { @@ -201,7 +246,7 @@ public class MdlUtils { } int id = Integer.parseInt(matcher.group(elementId)); - Variable2 var = variables.get(matcher.group(elementName)); + Variable2 var = mdl.getVariable((normalize(matcher.group(elementName)))); SketchVariable variable = new SketchVariable(id, var); @@ -218,8 +263,9 @@ public class MdlUtils { } int id = Integer.parseInt(matcher.group(elementId)); + TextPosition pos = getTextPos(matcher); - SketchValve valve = new SketchValve(id); + SketchValve valve = new SketchValve(id, pos); initializeElement(valve, matcher); @@ -312,9 +358,75 @@ public class MdlUtils { str = str.replaceAll("\t", ""); // remove inline :AND: and :OR: etc (not done currently) + str = removeInlineOperation(str, "AND"); + str = removeInlineOperation(str, "OR"); + + // rename vensim method calls to sysdyn equivalents + str = str.replaceAll("IF THEN ELSE", "IFTHENELSE"); + + // TODO: replace array slice operations - // transform all variable names to (single-)quoted modelica syntax + // normalize variable names + str = processVariables(str); + + return str; + } + + private static String removeInlineOperation(String str, String op) { + while (str.contains(":"+op+":")) { + // this should work in most cases, even with nested parentheses + // in the left and right hand side expression + + // the regular expression can be split into 5 parts: + // 1. delimiter character on the left (either start of string, ',' or '(': + // (?:^|[(,]) + // 2. left hand side expression, anything except ',' unless it is + // enclosed in parentheses which is allowed: + // ([^(,]*(?:\\(.*\\)[^(,])*) + // 3. the inlined operation: + // :OPERATION: + // 4. right hand side expression, similar to left hand side expression + // but with ')' instead of '(': + // ([^),]*(?:\\(.*\\)[^),])*) + // 5. delimiter character on the right (either end of string, ',' or ')'): + // (?:$|[),]) + + // note that the expression also makes heavy use of both non-capturing and + // capturing groups ("(?:)" and "()") + Matcher matcher = Pattern.compile( + "(?:^|[(,])([^(,]*(?:\\(.*\\)[^(,])*):" + op + ":([^),]*(?:\\(.*\\)[^),])*)(?:$|[),])").matcher(str); + + if (!matcher.find()) { + System.err.println("inlined operation not found"); + return str; + } + + StringBuilder buf = new StringBuilder(); + + // part before left hand side + buf.append(str.substring(0, matcher.start(1))); + // operation open + buf.append(op); + buf.append('('); + // left hand side + buf.append(matcher.group(1).trim()); + // delimiter + buf.append(','); + // right hand side + buf.append(matcher.group(2).trim()); + // operation close + buf.append(')'); + // part after right hand side + buf.append(str.substring(matcher.end(2))); + + str = buf.toString(); + } + return str; + } + + private static String processVariables(String str) { StringBuilder result = new StringBuilder(); + int offset = 0; Matcher matcher = Pattern.compile(VAR_NAME).matcher(str); @@ -322,24 +434,37 @@ public class MdlUtils { result.append(str.substring(offset, matcher.start())); String replacement = matcher.group(); - + if (replacement.startsWith("\"")) { - replacement = replacement.substring(1, replacement.length() - 1); + // if the variable name is quoted, change the quotes to modelica syntax + replacement = "'" + replacement.substring(1, replacement.length() - 1) + "'"; + } + else if (Pattern.compile("[-+*/]").matcher(replacement).find()) { + // if the variable name contains "bad" characters, quote it + replacement = "'" + replacement + "'"; + } + else { + // otherwise simply capitalize the variable name properly + String[] parts = replacement.split("\\s+"); + StringBuilder buf = new StringBuilder(); + for (String part : parts) { + part = part.substring(0, 1).toUpperCase() + part.substring(1); + if (buf.length() > 0) + buf.append(' '); + buf.append(part); + } + replacement = buf.toString(); } - result.append('\''); result.append(replacement); - result.append('\''); offset = matcher.end(); } if (offset < str.length()) { result.append(str.substring(offset)); } - - str = result.toString(); - - return str; + + return result.toString(); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Auxiliary2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Auxiliary2.java index 16facada..cbca5c98 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Auxiliary2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Auxiliary2.java @@ -7,21 +7,21 @@ import org.simantics.sysdyn.SysdynResource; public class Auxiliary2 extends ModelVariable { - public Auxiliary2(double x, double y, + public Auxiliary2(double x, double y, double w, double h, String name, IExpression expression, Range range, String unit, String description) { - super(x, y, name, expression, range, unit, description); + super(x, y, w, h, name, expression, range, unit, description); } - public Auxiliary2(double x, double y, Variable2 variable) { - super(x, y, variable); + public Auxiliary2(double x, double y, double w, double h, Variable2 variable) { + super(x, y, w, h, variable); } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - Resource variable = createVariable(graph, sr.Auxiliary, parent); - createSymbol(graph, sr.AuxiliarySymbol, variable, parent); + Resource variable = createVariable(graph, sr.Auxiliary, parent, context); + createSymbol(graph, sr.AuxiliarySymbol, variable, parent, context); setResource(variable); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Cloud2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Cloud2.java index 68301a27..14d39b63 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Cloud2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Cloud2.java @@ -9,19 +9,20 @@ import org.simantics.sysdyn.SysdynResource; public class Cloud2 extends Element2 { - public Cloud2(double x, double y) { - super(x, y); + public Cloud2(double x, double y, double w, double h) { + super(x, y, w, h); } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); - Resource cloud = GraphUtils.create2(graph, sr.Cloud, + Resource cloud = GraphUtils.create2(graph, sr.Cloud, + l0.HasName, context.getNextCloud(), l0.PartOf, parent); - createSymbol(graph, sr.CloudSymbol, cloud, parent); + createSymbol(graph, sr.CloudSymbol, cloud, parent, context); setResource(cloud); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Comment2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Comment2.java index fc5264de..985fc73a 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Comment2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Comment2.java @@ -13,17 +13,17 @@ public class Comment2 extends Element2 { private String text; - public Comment2(double x, double y, String text) { - super(x, y); + public Comment2(double x, double y, double w, double h, String text) { + super(x, y, w, h); this.text = text; } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); - Resource comment = createSymbol(graph, sr.AdditionalSymbols_MultilineText, null, parent); + Resource comment = createSymbol(graph, sr.AdditionalSymbols_MultilineText, null, parent, context); graph.claimLiteral(comment, dr.HasText, text, Bindings.STRING); diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Connection2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Connection2.java index 455f0be6..c034f638 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Connection2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Connection2.java @@ -21,14 +21,8 @@ public abstract class Connection2 implements IWriteableObject { this.tail = tail; } - protected Resource createConnection(WriteGraph graph, Resource type, Resource symbol, Resource parent) + protected Resource createConnection(WriteGraph graph, Resource type, Resource parent, WriteContext context) throws DatabaseException { - // TODO: remove this - if (head == null || tail == null) { - return null; - } - - // create connection Layer0 l0 = Layer0.getInstance(graph); ModelingResources mr = ModelingResources.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); @@ -38,10 +32,19 @@ public abstract class Connection2 implements IWriteableObject { sr.Variable_HasTail, tail.getResource(), l0.PartOf, parent); graph.claim(connection, mr.Mapped, connection); - - // create symbol + + return connection; + } + + protected Resource createSymbol(WriteGraph graph, Resource type, Resource connection, Resource parent, WriteContext context) + throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource diagram = graph.getSingleObject(parent, mr.CompositeToDiagram); Resource diagramTail = graph.getPossibleObject(tail.getResource(), mr.ComponentToElement); Resource tailConnector = GraphUtils.create2(graph, dr.Connector, @@ -52,16 +55,17 @@ public abstract class Connection2 implements IWriteableObject { sr.HasHeadTerminal, diagramHead, dr.AreConnected, tailConnector); - Resource diagramConnection = GraphUtils.create2(graph, symbol, + Resource diagramConnection = GraphUtils.create2(graph, type, + l0.HasName, context.getNextObject(), + l0.PartOf, diagram, sr2.HasConnectionType, sr.SysdynConnectionType, mr.DiagramConnectionToConnection, connection, dr.HasArrowConnector, headConnector, dr.HasPlainConnector, tailConnector); - Resource diagram = graph.getSingleObject(parent, mr.CompositeToDiagram); OrderedSetUtils.add(graph, diagram, diagramConnection); - - return connection; + + return diagramConnection; } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/DelayExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/DelayExpression.java new file mode 100644 index 00000000..ccb552ba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/DelayExpression.java @@ -0,0 +1,28 @@ +package org.simantics.sysdyn.modelImport.model; + +import java.util.Arrays; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +public class DelayExpression implements IExpression { + + @Override + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + +// Resource expression = GraphUtils.create2(graph, sr.DelayExpression, +// sr.StockExpression_integralEquation, integral, +// sr.StockExpression_initialEquation, initial, +// l0.PartOf, parent); +// // TODO: why is the expression stored in two places? +// graph.claim(parent, sr.Variable_expressionList, ListUtils.create(graph, Arrays.asList(expression))); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Dependency2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Dependency2.java index d4fa8e40..973d1ebf 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Dependency2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Dependency2.java @@ -1,27 +1,41 @@ package org.simantics.sysdyn.modelImport.model; +import org.simantics.databoard.Bindings; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; public class Dependency2 extends Connection2 { private boolean showArrow; private boolean showDelay; + private double angle; - public Dependency2(Element2 head, Element2 tail, boolean showArrow, boolean showDelay) { + public Dependency2(Element2 head, Element2 tail, boolean showArrow, boolean showDelay, double angle) { super(head, tail); this.showArrow = showArrow; this.showDelay = showDelay; + this.angle = angle; } @Override - public void write(WriteGraph graph, Resource parent) - throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { + if (head == null || tail == null) { + System.err.println("dependency missing head or tail"); + return; + } + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); - Resource dependency = createConnection(graph, sr.Dependency, sr.DependencyConnection, parent); + Resource dependency = createConnection(graph, sr.Dependency, parent, context); + graph.claimLiteral(dependency, l0.HasName, context.getNextDependency(), Bindings.STRING); + Resource symbol = createSymbol(graph, sr.DependencyConnection, dependency, parent, context); + + graph.claimLiteral(symbol, sr.Dependency_angle, angle, Bindings.DOUBLE); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Element2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Element2.java index 43914ccc..005ca18c 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Element2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Element2.java @@ -7,21 +7,31 @@ import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.modeling.ModelingResources; public abstract class Element2 implements IWriteableObject { - private static final double SCALE = 1.0 / 3.0; - private double x; private double y; + private double width; + private double height; private Resource resource; - public Element2(double x, double y) { - this.x = x * SCALE; - this.y = y * SCALE; + public Element2(double x, double y, double width, double height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public Element2(SketchElement element, double hOffset, double vOffset) { + this.x = element.getSysdyndX() + hOffset; + this.y = element.getSysdyndY() + vOffset; + this.width = element.getSysdynWidth(); + this.height = element.getSysdynHeight(); } public Resource getResource() { @@ -31,13 +41,34 @@ public abstract class Element2 implements IWriteableObject { public void setResource(Resource resource) { this.resource = resource; } + + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getWidth() { + return width; + } + + public double getHeight() { + return height; + } - public Resource createSymbol(WriteGraph graph, Resource type, Resource variable, Resource parent) throws DatabaseException { + public Resource createSymbol(WriteGraph graph, Resource type, Resource variable, Resource parent, WriteContext context) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(graph); G2DResource g2d = G2DResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); ModelingResources mr = ModelingResources.getInstance(graph); - Resource symbol = GraphUtils.create2(graph, type); + Resource diagram = graph.getSingleObject(parent, mr.CompositeToDiagram); + + Resource symbol = GraphUtils.create2(graph, type, + l0.HasName, context.getNextObject(), + l0.PartOf, diagram); if (variable != null) { graph.claim(symbol, mr.ElementToComponent, variable); @@ -46,7 +77,6 @@ public abstract class Element2 implements IWriteableObject { double[] transform = { 1.0, 0.0, 0.0, 1.0, x, y }; graph.claimLiteral(symbol, dr.HasTransform, g2d.Transform, transform, Bindings.DOUBLE_ARRAY); - Resource diagram = graph.getSingleObject(parent, mr.CompositeToDiagram); OrderedSetUtils.add(graph, diagram, symbol); return symbol; diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Flow2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Flow2.java index d631439f..fc3b5979 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Flow2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Flow2.java @@ -1,8 +1,10 @@ package org.simantics.sysdyn.modelImport.model; +import org.simantics.databoard.Bindings; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; public class Flow2 extends Connection2 { @@ -12,10 +14,19 @@ public class Flow2 extends Connection2 { } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { + if (head == null || tail == null) { + System.err.println("flow missing head or tail"); + return; + } + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); - Resource flow = createConnection(graph, sr.Flow, sr.FlowConnection, parent); + Resource flow = createConnection(graph, sr.Flow, parent, context); + graph.claimLiteral(flow, l0.HasName, context.getNextFlow(), Bindings.STRING); + Resource symbol = createSymbol(graph, sr.FlowConnection, flow, parent, context); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IWriteableObject.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IWriteableObject.java index 9929c80c..c704b7c4 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IWriteableObject.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IWriteableObject.java @@ -22,5 +22,5 @@ public interface IWriteableObject { * @param parent The resource where the object is located * @throws DatabaseException */ - public void write(WriteGraph graph, Resource parent) throws DatabaseException; + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException; } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IntegralExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IntegralExpression.java index 40d096b4..783b181d 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IntegralExpression.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/IntegralExpression.java @@ -21,7 +21,7 @@ public class IntegralExpression implements IExpression { } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/LookupExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/LookupExpression.java new file mode 100644 index 00000000..1ee58312 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/LookupExpression.java @@ -0,0 +1,14 @@ +package org.simantics.sysdyn.modelImport.model; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; + +public class LookupExpression implements IExpression { + + @Override + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { + // TODO: implementation + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java index c1dbceb4..1a5519e8 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java @@ -1,5 +1,50 @@ package org.simantics.sysdyn.modelImport.model; -public class MdlModel { +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +public class MdlModel { + + private String name; + + private HashMap variables; + private HashMap> groups; + + private ArrayList sketches; + + public MdlModel(String name) { + this.name = name; + this.variables = new HashMap(); + this.groups = new HashMap>(); + this.sketches = new ArrayList(); + } + + public void addVariable(Variable2 variable, String group) { + if (variables.get(variable.getName()) != null) { + System.err.println("warning, duplicate variable "+variable.getName()); + } + + variables.put(variable.getName(), variable); + + if (group != null) { + if (groups.get(group) == null) { + groups.put(group, new ArrayList()); + } + groups.get(group).add(variable); + } + } + + public Variable2 getVariable(String name) { + return variables.get(name); + } + + public void addSketch(Sketch2 sketch) { + sketches.add(sketch); + } + + public List getSketches() { + return sketches; + } + } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model2.java index c6bce0cb..4189cd19 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model2.java @@ -17,7 +17,9 @@ import org.simantics.databoard.Bindings; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.DiagramResource; import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.sysdyn.utils.ModelUtils; @@ -77,8 +79,10 @@ public class Model2 implements IWriteableObject { } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { + DiagramResource dr = DiagramResource.getInstance(graph); Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); SimulationResource sim = SimulationResource.getInstance(graph); Resource model = ModelUtils.createModel(graph); @@ -89,16 +93,19 @@ public class Model2 implements IWriteableObject { Resource configuration = graph.getSingleObject(model, sim.HasConfiguration); for (Element2 e : elements) { - e.write(graph, configuration); + e.write(graph, configuration, context); } for (Shadow2 s : shadows) { - s.write(graph, configuration); + s.write(graph, configuration, context); } for (Connection2 c : connections) { - c.write(graph, configuration); + c.write(graph, configuration, context); } + + Resource diagram = graph.getSingleObject(configuration, mr.CompositeToDiagram); + graph.claimLiteral(diagram, dr.HasModCount, context.getObjectCount(), Bindings.LONG); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelElementFactory.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelElementFactory.java new file mode 100644 index 00000000..01b3a125 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelElementFactory.java @@ -0,0 +1,68 @@ +package org.simantics.sysdyn.modelImport.model; + +import org.simantics.sysdyn.modelImport.MdlUtils.CommentIcon; + +public class ModelElementFactory { + + public static void getConnection() { + + } + + public static void getDependency() { + + } + + public static void getFlow() { + + } + + public static Element2 getElement(SketchVariable variable) { + if (variable.getVariable().getExpression() instanceof IntegralExpression) { + return getStock(variable); + } + else { + return getAuxiliary(variable); + } + } + + public static Element2 getElement(SketchValve valve) { + return getValve(valve); + } + + public static Element2 getElement(SketchComment comment) { + if (comment.getIcon().equals(CommentIcon.CLOUD)) { + return getCloud(comment); + } + else { + return getComment(comment); + } + } + + public static Auxiliary2 getAuxiliary(SketchVariable variable) { + return null; + } + + public static Stock2 getStock(SketchVariable variable) { + assert variable.getVariable().getExpression() instanceof IntegralExpression; + + return null; + } + + public static Valve2 getValve(SketchValve valve) { + return null; + } + + public static Cloud2 getCloud(SketchComment comment) { + assert comment.getIcon().equals(CommentIcon.CLOUD); + return null; + } + + public static Comment2 getComment(SketchComment comment) { + return null; + } + + public static Shadow2 getShadow(SketchVariable variable) { + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelVariable.java index 81b66a14..1a5c496d 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelVariable.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelVariable.java @@ -17,8 +17,8 @@ public abstract class ModelVariable extends Element2 { protected String unit; protected String description; - public ModelVariable(double x, double y, String name, IExpression expression, Range range, String unit, String description) { - super(x, y); + public ModelVariable(double x, double y, double w, double h, String name, IExpression expression, Range range, String unit, String description) { + super(x, y, w, h); this.name = name; this.expression = expression; this.range = range; @@ -26,8 +26,8 @@ public abstract class ModelVariable extends Element2 { this.description = description; } - public ModelVariable(double x, double y, Variable2 variable) { - super(x, y); + public ModelVariable(double x, double y, double w, double h, Variable2 variable) { + super(x, y, w, h); this.name = variable.getName(); this.expression = variable.getExpression(); this.range = variable.getRange(); @@ -35,7 +35,7 @@ public abstract class ModelVariable extends Element2 { this.description = variable.getDescription(); } - public Resource createVariable(WriteGraph graph, Resource type, Resource parent) + public Resource createVariable(WriteGraph graph, Resource type, Resource parent, WriteContext context) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); ModelingResources mr = ModelingResources.getInstance(graph); @@ -46,10 +46,10 @@ public abstract class ModelVariable extends Element2 { l0.PartOf, parent); graph.claim(variable, mr.Mapped, variable); - expression.write(graph, variable); + expression.write(graph, variable, context); if (range != null) { - range.write(graph, variable); + range.write(graph, variable, context); } if (unit != null && !unit.isEmpty()) { graph.claimLiteral(variable, sr.Variable_unit, unit, Bindings.STRING); diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/NormalExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/NormalExpression.java index e7b0fb52..f84bcc05 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/NormalExpression.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/NormalExpression.java @@ -19,7 +19,7 @@ public class NormalExpression implements IExpression { } @Override - public void write(WriteGraph graph, Resource variable) throws DatabaseException { + public void write(WriteGraph graph, Resource variable, WriteContext context) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Range.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Range.java index 638ef7ba..9a7ca8a0 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Range.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Range.java @@ -35,7 +35,7 @@ public class Range implements IWriteableObject { } @Override - public void write(WriteGraph graph, Resource variable) throws DatabaseException { + public void write(WriteGraph graph, Resource variable, WriteContext context) throws DatabaseException { // TODO: implementation } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Shadow2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Shadow2.java index 4b51e424..f386fbcc 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Shadow2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Shadow2.java @@ -11,22 +11,28 @@ public class Shadow2 extends Element2 { private Element2 original; - public Shadow2(double x, double y, Element2 original) { - super(x, y); + public Shadow2(double x, double y, double w, double h, Element2 original) { + super(x, y, w, h); + this.original = original; + } + + public Shadow2(SketchVariable variable, double hOffset, double vOffset, Element2 original) { + super(variable, hOffset, vOffset); this.original = original; } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); - Resource shadow = GraphUtils.create2(graph, sr.Shadow, + Resource shadow = GraphUtils.create2(graph, sr.Shadow, + l0.HasName, context.getNextShadow(), l0.PartOf, parent); graph.claim(shadow, sr.Shadow_original, original.getResource()); - createSymbol(graph, sr.ShadowSymbol, shadow, parent); + createSymbol(graph, sr.ShadowSymbol, shadow, parent, context); setResource(shadow); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Sketch2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Sketch2.java index 5512c8d6..b2f86ae8 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Sketch2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Sketch2.java @@ -68,28 +68,36 @@ public class Sketch2 { return list; } - public int getWidth() { - int width = 0; - for (SketchElement e : getAllElements()) { - width = Math.max(width, e.getX()+e.getWidth()); - } - return width; - } - - public int getHeight() { - int height = 0; - for (SketchElement e : getAllElements()) { - height = Math.max(height, e.getY()+e.getHeight()); - } - return height; - } - // relevant for sysdyn model creation, this is not the cleanest place to // store this information but it works public double hOffset = 0; public double vOffset = 0; + public double topEdge = 0; + public double bottomEdge = 0; + public double leftEdge = 0; + public double rightEdge = 0; + public HashMap elements = new HashMap(); + + public void setEdges() { + boolean first = true; + for (SketchElement e : getAllElements()) { + if (first) { + topEdge = e.getSysdynTopEdge(); + bottomEdge = e.getSysdynBottomEdge(); + leftEdge = e.getSysdynLeftEdge(); + rightEdge = e.getSysdynRightEdge(); + first = false; + } + else { + topEdge = Math.min(topEdge, e.getSysdynTopEdge()); + bottomEdge = Math.max(bottomEdge, e.getSysdynBottomEdge()); + leftEdge = Math.min(leftEdge, e.getSysdynLeftEdge()); + rightEdge = Math.max(rightEdge, e.getSysdynRightEdge()); + } + } + } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchComment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchComment.java index f077379f..d053a5c0 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchComment.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchComment.java @@ -24,12 +24,21 @@ public class SketchComment extends SketchElement { return icon; } - public Element2 getModelElement(double xOffset, double yOffset) { + public Element2 getModelElement(double hOffset, double vOffset) { if (icon.equals(CommentIcon.CLOUD)) { - return new Cloud2(getX(xOffset), getY(yOffset)); + return new Cloud2( + getSysdyndX() + hOffset, + getSysdyndY() + vOffset, + getSysdynWidth(), + getSysdynHeight()); } else { - return new Comment2(getX(xOffset), getY(yOffset), text); + return new Comment2( + getSysdyndX() + hOffset, + getSysdyndY() + vOffset, + getSysdynWidth(), + getSysdynHeight(), + text); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchConnection.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchConnection.java index 6207d692..5968eb8e 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchConnection.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchConnection.java @@ -7,29 +7,31 @@ public class SketchConnection extends SketchObject { private int from; private int to; private ConnectionType type; - - public SketchConnection(int id, int from, int to, ConnectionType type) { + int[] points; + + public SketchConnection(int id, int from, int to, ConnectionType type, int[] points) { super(id); this.from = from; this.to = to; this.type = type; + this.points = points; } - + public int getFrom() { return from; } - + public int getTo() { return to; } - + public ConnectionType getType() { return type; } - - public Connection2 getWriteableConnection(Element2 head, Element2 tail) { + + public Connection2 getWriteableConnection(Element2 head, Element2 tail, double offset) { if (type.equals(ConnectionType.ARROW)) { - return new Dependency2(head, tail, false, false); + return new Dependency2(head, tail, false, false, getSysdynAngle(tail, head, offset)); } else if (type.equals(ConnectionType.LINE_ARROW)) { return new Flow2(head, tail); @@ -40,5 +42,47 @@ public class SketchConnection extends SketchObject { } return null; } - + + // TODO: comment this? + public double getSysdynAngle(Element2 from, Element2 to, double voffset) { + if (points == null || points.length == 0) { + return 0; + } + + // 'from' element is in (x0, y0) and 'to' element is in (x2, y2) + double x0 = from.getX() + (from.getWidth() / 2); + double y0 = from.getY() + (from.getHeight() / 2); + double x2 = to.getX() + (to.getWidth() / 2); + double y2 = to.getY() + (to.getHeight() / 2); + + // treat the first points in points as the control point (x1, y1) + double x1 = (double)points[0] * SCALE_MULTIPLIER; + double y1 = (double)points[1] * SCALE_MULTIPLIER + voffset; + + //System.err.println("("+x0+","+y0+") -> ("+x1+","+y1+") -> ("+x2+","+y2+")"); + + double dx0 = x1 - x0; + double dy0 = y1 - y0; + double dx1 = x1 - x2; + double dy1 = y1 - y2; + double dx = x2 - x0; + double dy = y2 - y0; + + // length of (p1-p0) x (p2-p0) + double dd = dx0*dy - dy0*dx; + + if (Math.abs(dd) < 1e-5) { + // Points are (almost) collinear + return 0; + } + else { + // (p1-p0) * (p1-p2) / dd + double offset = (dx0*dx1 + dy0*dy1) / dd; + double angle = Math.PI*0.5 - Math.atan(offset); + if (dd > 0.0) + angle = angle - Math.PI; + return angle; + } + } + } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchElement.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchElement.java index ef54a017..34ce854d 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchElement.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchElement.java @@ -34,18 +34,10 @@ public abstract class SketchElement extends SketchObject { return x; } - public double getX(double offset) { - return x + offset; - } - public int getY() { return y; } - public double getY(double offset) { - return y + offset; - } - public int getWidth() { return width; } @@ -54,6 +46,43 @@ public abstract class SketchElement extends SketchObject { return height; } + // in vensim the coordinates refer to the center of the element with + // width and height being the distances between the center and the edges, + // whereas in sysdyn the coordinates refer to the top-left corner of the + // element + + public double getSysdyndX() { + return getSysdynLeftEdge(); + } + + public double getSysdyndY() { + return getSysdynTopEdge(); + } + + public double getSysdynWidth() { + return ((double)width) * 2 * SCALE_MULTIPLIER; + } + + public double getSysdynHeight() { + return ((double)height) * 2 * SCALE_MULTIPLIER; + } + + public double getSysdynTopEdge() { + return (double)(y - height) * SCALE_MULTIPLIER; + } + + public double getSysdynBottomEdge() { + return (double)(y + height) * SCALE_MULTIPLIER; + } + + public double getSysdynLeftEdge() { + return (double)(x - width) * SCALE_MULTIPLIER; + } + + public double getSysdynRightEdge() { + return (double)(x + width) * SCALE_MULTIPLIER; + } + public boolean isAttached() { return attached; } @@ -74,6 +103,6 @@ public abstract class SketchElement extends SketchObject { return textLine; } - public abstract Element2 getModelElement(double xOffset, double yOffset); + public abstract Element2 getModelElement(double hOffset, double vOffset); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchObject.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchObject.java index 89b1933c..003741c7 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchObject.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchObject.java @@ -1,10 +1,12 @@ package org.simantics.sysdyn.modelImport.model; public abstract class SketchObject { + + protected static final double SCALE_MULTIPLIER = 0.4; private int id; - SketchObject(int id) { + public SketchObject(int id) { this.id = id; } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchValve.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchValve.java index 6b8161f4..670e23cc 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchValve.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchValve.java @@ -1,11 +1,15 @@ package org.simantics.sysdyn.modelImport.model; +import org.simantics.sysdyn.modelImport.model.Valve2.TextPosition; + public class SketchValve extends SketchElement { private SketchVariable variable; + private TextPosition textPosition; - public SketchValve(int id) { + public SketchValve(int id, TextPosition textPosition) { super(id); + this.textPosition = textPosition; } public SketchVariable getAttachedVariable() { @@ -17,8 +21,14 @@ public class SketchValve extends SketchElement { } @Override - public Element2 getModelElement(double xOffset, double yOffset) { - return new Valve2(getX(xOffset), getY(yOffset), variable.getVariable()); + public Element2 getModelElement(double hOffset, double vOffset) { + return new Valve2( + getSysdyndX() + hOffset, + getSysdyndY() + vOffset, + getSysdynWidth(), + getSysdynHeight(), + variable.getVariable(), + textPosition); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchVariable.java index 1d86295f..6a0fabb7 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchVariable.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SketchVariable.java @@ -14,12 +14,22 @@ public class SketchVariable extends SketchElement { } @Override - public Element2 getModelElement(double xOffset, double yOffset) { + public Element2 getModelElement(double hOffset, double vOffset) { if (variable.getExpression() instanceof IntegralExpression) { - return new Stock2(getX(xOffset), getY(yOffset), variable); + return new Stock2( + getSysdyndX() + hOffset, + getSysdyndY() + vOffset, + getSysdynWidth(), + getSysdynHeight(), + variable); } else { - return new Auxiliary2(getX(xOffset), getY(yOffset), variable); + return new Auxiliary2( + getSysdyndX() + hOffset, + getSysdyndY() + vOffset, + getSysdynWidth(), + getSysdynHeight(), + variable); } } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Stock2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Stock2.java index 41d424c4..412cf35d 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Stock2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Stock2.java @@ -7,20 +7,20 @@ import org.simantics.sysdyn.SysdynResource; public class Stock2 extends ModelVariable { - public Stock2(double x, double y, + public Stock2(double x, double y, double w, double h, String name, IntegralExpression expression, Range range, String unit, String description) { - super(x, y, name, expression, range, unit, description); + super(x, y, w, h, name, expression, range, unit, description); } - public Stock2(double x, double y, Variable2 variable) { - super(x, y, variable); + public Stock2(double x, double y, double w, double h, Variable2 variable) { + super(x, y, w, h, variable); } - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - Resource stock = createVariable(graph, sr.Stock, parent); - createSymbol(graph, sr.StockSymbol, stock, parent); + Resource stock = createVariable(graph, sr.Stock, parent, context); + createSymbol(graph, sr.StockSymbol, stock, parent, context); setResource(stock); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Valve2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Valve2.java index 5ea5a99b..0abd36da 100644 --- a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Valve2.java +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Valve2.java @@ -15,21 +15,47 @@ public class Valve2 extends ModelVariable { INSIDE, BELOW, LEFT, ABOVE, RIGHT, UNSET } - public Valve2(double x, double y, - String name, IExpression expression, Range range, String unit, String description) { - super(x, y, name, expression, range, unit, description); + private TextPosition position; + + public Valve2(double x, double y, double w, double h, + String name, IExpression expression, Range range, String unit, String description, TextPosition position) { + super(x, y, w, h, name, expression, range, unit, description); + this.position = position; } - public Valve2(double x, double y, Variable2 variable) { - super(x, y, variable); + public Valve2(double x, double y, double w, double h, Variable2 variable, TextPosition position) { + super(x, y, w, h, variable); + this.position = position; } @Override - public void write(WriteGraph graph, Resource parent) throws DatabaseException { + public void write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(graph); - Resource valve = createVariable(graph, sr.Valve, parent); - createSymbol(graph, sr.ValveSymbol, valve, parent); + Resource valve = createVariable(graph, sr.Valve, parent, context); + Resource symbol = createSymbol(graph, sr.ValveSymbol, valve, parent, context); + + Resource location = null; + switch (position) { + case BELOW: + location = sr.Bottom; + break; + case LEFT: + location = sr.Left; + break; + case ABOVE: + location = sr.Top; + break; + case RIGHT: + location = sr.Right; + break; + default: + System.err.println("unrecognized text location"); + location = sr.Bottom; + break; + } + + graph.claim(symbol, sr.ValveSymbol_textLocation, location); setResource(valve); } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/WriteContext.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/WriteContext.java new file mode 100644 index 00000000..80f3ba1e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/WriteContext.java @@ -0,0 +1,40 @@ +package org.simantics.sysdyn.modelImport.model; + +public class WriteContext { + + private long objectCount; + + private long cloudCount; + private long shadowCount; + private long dependencyCount; + private long flowCount; + + public WriteContext() { + this.objectCount = 0; + } + + public String getNextObject() { + return Long.toString(objectCount++); + } + + public long getObjectCount() { + return objectCount; + } + + public String getNextCloud() { + return "Cloud" + cloudCount++; + } + + public String getNextShadow() { + return "Shadow" + shadowCount++; + } + + public String getNextDependency() { + return "Dependency" + dependencyCount++; + } + + public String getNextFlow() { + return "Flow" + flowCount++; + } + +} -- 2.47.1