Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 75.4% 132 / 0 / 175
Functions: -% 0 / 1 / 1
Branches: 56.7% 34 / 0 / 60

OMCompiler/Compiler/BackEnd/VisualXML.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package VisualXML
37 " file: VisualXML
38 package: VisualXML
39 description: This package gathers all information about visualization objects from the MultiBody lib and outputs them as an XML file.
40 This can be used together with the result file to visualize the system.
41
42
43
44 "
45
46 protected
47
48 import Absyn;
49 import Array;
50 import Error;
51 import ExpressionBasics;
52 import ProgramUtil;
53 import AbsynUtil;
54 import BackendDAE;
55 import BackendDAEUtil;
56 import BackendEquation;
57 import BackendVariable;
58 import ComponentReference;
59 protected import ComponentReferenceBasics;
60 import DAE;
61 import DAEUtil;
62 import ElementSource;
63 import Expression;
64 import ExpressionDump;
65 import ExpressionSolve;
66 import List;
67 import Util;
68 import Tpl;
69 import VisualXMLTpl;
70 import System;
71
72 //----------------------------
73 // Visualization types
74 //----------------------------
75
76 public
77 uniontype Visualization
78 record SHAPE
79 DAE.ComponentRef ident;
80 DAE.Exp shapeType;
81 array<list<DAE.Exp>> T;
82 array<DAE.Exp> r;
83 array<DAE.Exp> r_shape;
84 array<DAE.Exp> lengthDir;
85 array<DAE.Exp> widthDir;
86 DAE.Exp length;
87 DAE.Exp width;
88 DAE.Exp height;
89 DAE.Exp extra;
90 array<DAE.Exp> color;
91 DAE.Exp specularCoeff;
92 end SHAPE;
93
94 record VECTOR
95 DAE.ComponentRef ident;
96 array<list<DAE.Exp>> T;
97 array<DAE.Exp> r;
98 array<DAE.Exp> coordinates;
99 array<DAE.Exp> color;
100 DAE.Exp specularCoeff;
101 DAE.Exp quantity;
102 DAE.Exp headAtOrigin;
103 DAE.Exp twoHeadedArrow;
104 end VECTOR;
105
106 record SURFACE
107 DAE.ComponentRef ident;
108 array<list<DAE.Exp>> T;
109 array<DAE.Exp> r_0;
110 DAE.Exp nu;
111 DAE.Exp nv;
112 // surfaceCharacteristic
113 DAE.Exp wireframe;
114 DAE.Exp multiColored;
115 array<DAE.Exp> color;
116 DAE.Exp specularCoeff;
117 DAE.Exp transparency;
118 end SURFACE;
119 end Visualization;
120
121 //-------------------------
122 // dump visualization xml
123 //-------------------------
124
125 public
126 function visualizationInfoXML"dumps an xml containing information about visualization objects.
127 author:Waurich TUD 2015-04"
128 input BackendDAE.BackendDAE daeIn;
129 input String fileName;
130 input Absyn.Program program;
131 output BackendDAE.BackendDAE daeOut;
132 protected
133 BackendDAE.EqSystems eqs, eqs0;
134 BackendDAE.Shared shared;
135 BackendDAE.Variables globalKnownVars, aliasVars, constVars;
136 list<BackendDAE.Var> globalKnownVarLst, allVarLst, aliasVarLst;
137 list<Visualization> visuals;
138 list<tuple<DAE.ComponentRef, String>> allVisuals;
139 algorithm
140 3 BackendDAE.DAE(eqs=eqs0, shared=shared) := daeIn;
141 3 BackendDAE.SHARED(globalKnownVars=globalKnownVars,aliasVars=aliasVars) := shared;
142 //in case we have a time dependent, protected variable, set the solved equation as binding
143 3 eqs := List.map(eqs0,BackendDAEUtil.copyEqSystem);
144 3 eqs := List.map(eqs,setBindingForProtectedVars);
145
146 //get all variables that contain visualization vars
147 3 globalKnownVarLst := BackendVariable.varList(globalKnownVars);
148 3 aliasVarLst := BackendVariable.varList(aliasVars);
149 3 allVarLst := List.flatten(List.mapMap(eqs, BackendVariable.daeVars,BackendVariable.varList));
150
151 //collect all visualization objects
152 3 (globalKnownVarLst,allVisuals) := List.fold(globalKnownVarLst,isVisualizationVarFold,({},{}));
153 3 (allVarLst,allVisuals) := List.fold(allVarLst,isVisualizationVarFold,({},allVisuals));
154 3 (aliasVarLst,allVisuals) := List.fold(aliasVarLst,isVisualizationVarFold,({},allVisuals));
155 //print("ALL VISUALS "+stringDelimitList(List.map(allVisuals,ComponentReferenceBasics.printComponentRefStr)," |")+"\n");
156
157 //fill theses visualization objects with information
158 3 allVarLst := listAppend(globalKnownVarLst,listAppend(allVarLst,aliasVarLst));
159 3 visuals := List.mapFold2(allVisuals, fillVisualizationObjects,allVarLst, program);
160 //some expressions refer to other known parameters, get them
161 3 visuals := List.map2(visuals,replaceVisualBinding,globalKnownVars,program);
162 //print("\nvisuals :\n"+stringDelimitList(List.map(visuals,printVisualization),"\n")+"\n");
163
164 // Inline constant attributes so the xml survives an FMU export folding them away.
165 3 constVars := BackendVariable.mergeVariables(globalKnownVars, aliasVars);
166 3 visuals := List.map1(visuals, inlineConstVisAttributes, constVars);
167
168 //dump xml file
169 3 dumpVis(listArray(visuals), fileName+"_visual.xml");
170
171 //update the variabels
172 3 globalKnownVars := BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars, setVisVarsPublic,"");
173 3 aliasVars := BackendVariable.traverseBackendDAEVarsWithUpdate(aliasVars, setVisVarsPublic,"");
174 3 daeOut := BackendDAE.DAE(eqs=eqs, shared=shared);
175 end visualizationInfoXML;
176
177 protected
178 function replaceVisualBinding
179 "Replace the cref binding for the given visualization shapeType with the constant expression of its alias.
180 author: vwaurich 2016-10"
181 input output Visualization vis;
182 input BackendDAE.Variables varArray;
183 input Absyn.Program program;
184 algorithm
185 () := matchcontinue vis
186 local
187 DAE.ComponentRef cr;
188 String s;
189
190 case SHAPE(shapeType = DAE.CREF(componentRef = cr))
191 algorithm
192 ✗ vis.shapeType := getConstCrefBinding(cr, varArray);
193 then
194 ();
195
196 case SHAPE(shapeType = DAE.SCONST(string=s))
197 algorithm
198 64 vis.shapeType := DAE.SCONST(getFullCADFilePath(s, program));
199 then
200 ();
201
202 else ();
203 end matchcontinue;
204 end replaceVisualBinding;
205
206 function inlineConstVisAttributes
207 "Inline attributes that resolve to a genuine constant, so the _visual.xml is
208 self-contained for constants an FMU export folds away (e.g. axis-label frames)."
209 input output Visualization vis;
210 input BackendDAE.Variables vars;
211 algorithm
212 () := match vis
213 case SHAPE()
214 algorithm
215 32 vis.T := Array.map1(vis.T, inlineConstExpList, vars);
216 32 vis.r := Array.map1(vis.r, inlineConstExp, vars);
217 32 vis.r_shape := Array.map1(vis.r_shape, inlineConstExp, vars);
218 32 vis.lengthDir := Array.map1(vis.lengthDir, inlineConstExp, vars);
219 32 vis.widthDir := Array.map1(vis.widthDir, inlineConstExp, vars);
220 32 vis.length := inlineConstExp(vis.length, vars);
221 32 vis.width := inlineConstExp(vis.width, vars);
222 32 vis.height := inlineConstExp(vis.height, vars);
223 32 vis.extra := inlineConstExp(vis.extra, vars);
224 32 vis.color := Array.map1(vis.color, inlineConstExp, vars);
225 32 vis.specularCoeff := inlineConstExp(vis.specularCoeff, vars);
226 then ();
227
228 case VECTOR()
229 algorithm
230 ✗ vis.T := Array.map1(vis.T, inlineConstExpList, vars);
231 ✗ vis.r := Array.map1(vis.r, inlineConstExp, vars);
232 ✗ vis.coordinates := Array.map1(vis.coordinates, inlineConstExp, vars);
233 ✗ vis.color := Array.map1(vis.color, inlineConstExp, vars);
234 then ();
235
236 case SURFACE()
237 algorithm
238 5 vis.T := Array.map1(vis.T, inlineConstExpList, vars);
239 5 vis.r_0 := Array.map1(vis.r_0, inlineConstExp, vars);
240 5 vis.color := Array.map1(vis.color, inlineConstExp, vars);
241 then ();
242
243 else ();
244 end match;
245 end inlineConstVisAttributes;
246
247 function inlineConstExpList
248 input output list<DAE.Exp> exps;
249 input BackendDAE.Variables vars;
250 algorithm
251 111 exps := List.map1(exps, inlineConstExp, vars);
252 end inlineConstExpList;
253
254 function inlineConstExp
255 input output DAE.Exp exp;
256 input BackendDAE.Variables vars;
257 algorithm
258 exp := matchcontinue exp
259 local
260 DAE.ComponentRef cr;
261 453 case DAE.CREF(componentRef = cr) then tryConstCrefValue(cr, vars);
262 761 else exp;
263 end matchcontinue;
264 end inlineConstExp;
265
266 function tryConstCrefValue
267 "`cr`'s value when it resolves through alias bindings to a literal, never via a
268 parameter (settable in an FMU, so must stay a cref). Fails otherwise."
269 input DAE.ComponentRef cr;
270 input BackendDAE.Variables vars;
271 output DAE.Exp exp;
272 protected
273 BackendDAE.Var var;
274 DAE.Exp bind;
275 algorithm
276
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 731 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 731 times.
816 ({var}, _) := BackendVariable.getVar(cr, vars); // only known/alias vars; dynamic ones fail
277
2/2
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 625 times.
731 false := BackendVariable.isParam(var); // parameter: keep the cref
278 625 bind := BackendVariable.varBindExp(var); // fails when there is no binding
279 exp := match bind
280 case _ guard Expression.isConst(bind) then bind;
281 363 case DAE.CREF() then tryConstCrefValue(Expression.expCref(bind), vars);
282 end match;
283 end tryConstCrefValue;
284
285 function getConstCrefBinding
286 "Get the const binding for the cref. It has to be somewhere in the vars.
287 author: vwaurich 2016-10"
288 input DAE.ComponentRef cr;
289 input BackendDAE.Variables vars;
290 output DAE.Exp eOut;
291 protected
292 DAE.Exp e;
293 BackendDAE.Var var;
294 algorithm
295 try
296 ✗ ({var},_) := BackendVariable.getVar(cr,vars);
297 ✗ e := BackendVariable.varBindExp(var);
298 eOut := matchcontinue e
299 ✗ case _ guard Expression.isConst(e) then e;
300 ✗ case DAE.CREF(_) then getConstCrefBinding(Expression.expCref(e),vars);
301 /*
302 case(DAE.CALL(Absyn.FULLYQUALIFIED(Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Utilities",Absyn.QUALIFIED("Files",Absyn.IDENT("fullPathName"))))),{DAE.SCONST(s)},_))
303 algorithm
304 then System.realpath(s);
305 */
306 else
307 algorithm
308 ✗ Error.addCompilerWarning("The binding expression "+ExpressionBasics.printExpStr(e)+" of the visualization type component " +ComponentReference.crefStr(cr)+ " cannot be evaluated. Please specify a visualization type (CAD files are specified as modelica://packagename/filename.stl)");
309 ✗ then e;
310 end matchcontinue;
311 else
312 ✗ Error.addInternalError("VisualXMl.getConstCrefBinding failed for "+ComponentReference.crefStr(cr)+"\n", sourceInfo());
313 ✗ fail();
314 end try;
315 end getConstCrefBinding;
316
317 function setVisVarsPublic
318 "Sets the VariableAttributes of protected visualization vars to public.
319 author: waurich TUD 08-2016"
320 input BackendDAE.Var inVar;
321 input String dummyArgIn;
322 output BackendDAE.Var outVar = inVar;
323 output String dummyArgOut = dummyArgIn;
324 algorithm
325
2/2
✓ Branch 1 taken 1038 times.
✓ Branch 2 taken 1106 times.
2144 if isVisualizationVar(inVar) then
326 1106 outVar := makeVarPublicHideResultFalse(inVar);
327 end if;
328 end setVisVarsPublic;
329
330 function makeVarPublicHideResultFalse
331 "Sets the VariableAttributes to public and hideResult to false
332 author: waurich TUD 08-2016"
333 input BackendDAE.Var inVar;
334 output BackendDAE.Var outVar;
335 protected
336 Option<DAE.VariableAttributes> vals;
337 algorithm
338 1175 vals := inVar.values;
339 1175 vals := DAEUtil.setProtectedAttr(vals,false);
340 1175 outVar := BackendVariable.setVarAttributes(inVar,vals);
341 1175 outVar := BackendVariable.setHideResult(outVar,SOME(DAE.BCONST(false)));
342 end makeVarPublicHideResultFalse;
343
344 function setBindingForProtectedVars
345 "searches for protected vars and sets the binding exp with their equation.
346 This is needed since protected, time-dependent variables are not stored in result files (in OMC and Dymola)"
347 input BackendDAE.EqSystem eqSysIn;
348 output BackendDAE.EqSystem eqSysOut;
349 protected
350 array<Integer> ass1;
351 BackendDAE.Variables vars;
352 BackendDAE.EquationArray eqs;
353 algorithm
354 try
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 BackendDAE.EQSYSTEM(orderedEqs=eqs, orderedVars=vars, matching=BackendDAE.MATCHING(ass1=ass1)) := eqSysIn;
356 20 BackendVariable.traverseBackendDAEVarsWithUpdate(vars, setBindingForProtectedVars1, (1, ass1, eqs));
357 else
358 end try;
359
360 eqSysOut := eqSysIn;
361 end setBindingForProtectedVars;
362
363 function setBindingForProtectedVars1
364 "checks if the var is protected and sets the binding (i.e. the solved equation)"
365 input BackendDAE.Var varIn;
366 input tuple<Integer,array<Integer>,BackendDAE.EquationArray> tplIn;
367 output BackendDAE.Var varOut;
368 output tuple<Integer,array<Integer>,BackendDAE.EquationArray> tplOut;
369 algorithm
370 (varOut, tplOut) := matchcontinue (varIn, tplIn)
371 local
372 Integer idx;
373 array<Integer> ass1;
374 BackendDAE.EquationArray eqs;
375 BackendDAE.Equation eq;
376 BackendDAE.Var var;
377 DAE.Exp exp1, exp2;
378
379 case (BackendDAE.VAR(bindExp=NONE(), values=SOME(_)) , (idx, ass1, eqs))
380 guard BackendVariable.isProtectedVar(varIn) and isVisualizationVar(varIn)
381 algorithm
382 69 eq := BackendEquation.get(eqs, arrayGet(ass1, idx));
383
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 60 times.
69 BackendDAE.EQUATION(exp=exp1, scalar=exp2) := eq;
384 60 (exp1,_) := ExpressionSolve.solve(exp1, exp2, BackendVariable.varExp(varIn));
385 60 var := BackendVariable.setBindExp(varIn, SOME(exp1));
386 60 var := makeVarPublicHideResultFalse(var);
387 60 then
388 (var, (idx+1, ass1, eqs));
389
390 case (_, (idx, ass1, eqs))
391 algorithm
392
4/4
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 27 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 55 times.
91 if (BackendVariable.isProtectedVar(varIn) and isVisualizationVar(varIn)) then
393 9 var := makeVarPublicHideResultFalse(varIn);
394 else
395 var := varIn;
396 end if;
397 91 then (var, (idx+1, ass1, eqs));
398 end matchcontinue;
399 end setBindingForProtectedVars1;
400
401 function fillVisualizationObjects
402 "gets the identifier of a visualization object as an input and collects all information from allVars.
403 author:Waurich TUD 2015-04"
404 input tuple<DAE.ComponentRef, String> visVar;
405 input list<BackendDAE.Var> allVarsIn;
406 input Absyn.Program programIn;
407 output Visualization visOut;
408 output list<BackendDAE.Var> allVarsOut = allVarsIn;
409 output Absyn.Program programOut = programIn;
410 protected
411 DAE.ComponentRef cref;
412 String vis_name;
413 Visualization vis;
414 algorithm
415 try
416 //nameChars := stringListStringChar(nameIn);
417 //(prefix,nameChars) := List.split(nameChars,6);
418 //name := stringCharListString(nameChars);
419 //name := Util.stringReplaceChar(name,"$",".");
420 //true := stringEqual(stringCharListString(prefix),"Shape$");
421 //name := ComponentReferenceBasics.printComponentRefStr(crefIn);
422 37 (cref, vis_name) := visVar;
423 37 vis := newVisualizer(cref, vis_name);
424
1/2
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 (_, visOut) := List.fold2(allVarsIn,fillVisualizationObjects1,true,programIn,({},vis));
425 else
426 ✗ print("fillVisualizationObjects failed! - not yet supported type");
427 ✗ fail();
428 end try;
429 end fillVisualizationObjects;
430
431 function newVisualizer
432 input DAE.ComponentRef cref;
433 input String visualizerName;
434 output Visualization vis;
435 algorithm
436 vis := match visualizerName
437 case "Shape"
438 32 then SHAPE(cref,
439 DAE.SCONST("DUMMY"),
440 arrayCreate(3, {DAE.RCONST(-1),DAE.RCONST(-1),DAE.RCONST(-1)}),
441 arrayCreate(3, DAE.RCONST(-1)),
442 arrayCreate(3, DAE.RCONST(-1)),
443 arrayCreate(3, DAE.RCONST(-1)),
444 arrayCreate(3, DAE.RCONST(-1)),
445 DAE.RCONST(-1),
446 DAE.RCONST(-1),
447 DAE.RCONST(-1),
448 DAE.RCONST(-1),
449 arrayCreate(3, DAE.RCONST(-1)),
450 DAE.RCONST(-1));
451
452 case "Vector"
453 ✗ then VECTOR(cref,
454 arrayCreate(3, {DAE.RCONST(-1), DAE.RCONST(-1), DAE.RCONST(-1)}),
455 arrayCreate(3, DAE.RCONST(-1)),
456 arrayCreate(3, DAE.RCONST(-1)),
457 arrayCreate(3, DAE.RCONST(-1)),
458 DAE.RCONST(-1),
459 DAE.RCONST(-1),
460 DAE.BCONST(false),
461 DAE.BCONST(false));
462
463 case "Surface"
464 5 then SURFACE(cref,
465 arrayCreate(3, {DAE.RCONST(-1), DAE.RCONST(-1), DAE.RCONST(-1)}),
466 arrayCreate(3, DAE.RCONST(-1)),
467 DAE.ICONST(-1),
468 DAE.ICONST(-1),
469 // surfaceCharacteristic
470 DAE.BCONST(false),
471 DAE.BCONST(false),
472 arrayCreate(3, DAE.RCONST(-1)),
473 DAE.RCONST(-1),
474 DAE.RCONST(-1));
475
476 else
477 algorithm
478 ✗ Error.addInternalError(getInstanceName() + " failed on " +
479 visualizerName + "\n", sourceInfo());
480 ✗ then
481 fail();
482 end match;
483 end newVisualizer;
484
485 function makeCrefQualFromString
486 "generates a qualified cref from the '.' separated string.
487 author: Waurich TUD 2015-04"
488 input String s;
489 output DAE.ComponentRef crefOut;
490 protected
491 list<String> sLst;
492 DAE.ComponentRef cref;
493 list<DAE.ComponentRef> crefs;
494 algorithm
495 ✗ sLst := Util.stringSplitAtChar(s,".");
496 ✗ crefs := List.map2(sLst,ComponentReferenceBasics.makeCrefIdent,DAE.T_REAL_DEFAULT,{});
497 ✗ cref::crefs := crefs;
498 ✗ crefOut := List.foldr(crefs,ComponentReference.joinCrefs,cref);
499 end makeCrefQualFromString;
500
501 function splitCrefAfter
502 "checks if crefCut exists in the crefIn and outputs the appending crefs
503 author:Waurich TUD 2015-04"
504 input DAE.ComponentRef crefIn;
505 input DAE.ComponentRef crefCut;
506 output DAE.ComponentRef crefOut;
507 output Boolean wasCut;
508 algorithm
509 (crefOut, wasCut) := matchcontinue(crefIn, crefCut)
510 local
511 DAE.ComponentRef crefCut1, crefIn1;
512 /* Issue #5953
513 case(DAE.CREF_QUAL(componentRef=crefIn1),DAE.CREF_QUAL())
514 algorithm
515 // the crefs are not equal, check the next cref in crefIn
516 true := not ComponentReferenceBasics.crefFirstCrefEqual(crefIn,crefCut);
517 then
518 splitCrefAfter(crefIn1,crefCut);
519 */
520 case(DAE.CREF_QUAL(componentRef=crefIn1),DAE.CREF_QUAL(componentRef=crefCut1))
521 algorithm
522 // the crefs are equal, continue checking
523
2/2
✓ Branch 1 taken 10470 times.
✓ Branch 2 taken 17037 times.
27507 true := ComponentReferenceBasics.crefFirstCrefEqual(crefIn,crefCut);
524 17037 then
525 splitCrefAfter(crefIn1,crefCut1);
526
527 case(DAE.CREF_QUAL(componentRef=crefIn1),DAE.CREF_IDENT(_))
528 algorithm
529 // the cref has to be cut after this step
530
2/2
✓ Branch 1 taken 9420 times.
✓ Branch 2 taken 1176 times.
10596 true := ComponentReferenceBasics.crefFirstCrefEqual(crefIn,crefCut);
531 1176 then
532 (crefIn1, true);
533
534 case(DAE.CREF_QUAL(componentRef=crefIn1),DAE.CREF_IDENT(_))
535 algorithm
536 // there is no identical cref
537
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9420 times.
9420 true := not ComponentReferenceBasics.crefFirstCrefEqual(crefIn,crefCut);
538 9420 then
539 (crefIn1, false);
540
541 10470 else (crefCut, false);
542 end matchcontinue;
543 end splitCrefAfter;
544
545 function fillVisualizationObjects1
546 "checks if a variable belongs to a certain visualization var. if true, add information to the visualization object
547 author:Waurich TUD 2015-04"
548 input BackendDAE.Var varIn; //check this var
549 input Boolean storeProtectedCrefs; // if you want to store the protected crefs instead of the bidning expression
550 input Absyn.Program program;
551 input tuple<list<BackendDAE.Var>,Visualization> tplIn; // fold <vars for other visualization objects, the current visualization >
552 output tuple<list<BackendDAE.Var>,Visualization> tplOut;
553 algorithm
554 tplOut := matchcontinue(varIn, tplIn)
555 local
556 list<BackendDAE.Var> vars;
557 DAE.ComponentRef cref,cref1,ident;
558 Visualization vis, filled_vis;
559
560 case (BackendDAE.VAR(varName=cref), (vars, vis as SHAPE(ident=ident)))
561 algorithm
562 //this var belongs to the visualization object
563 //crefIdent := makeCrefQualFromString(ident); // make a qualified cref out of the visualizer ident
564
2/2
✓ Branch 1 taken 16770 times.
✓ Branch 2 taken 1056 times.
17826 (cref1,true) := splitCrefAfter(cref,ident); // check if this occurs in the qualified var cref
565 1056 filled_vis := fillShapeObject(cref1,varIn,storeProtectedCrefs,program,vis);
566 1056 then
567 (vars, filled_vis);
568
569 case (BackendDAE.VAR(varName=cref), (vars, vis as VECTOR(ident=ident)))
570 algorithm
571 //this var belongs to the visualization object
572 //crefIdent := makeCrefQualFromString(ident); // make a qualified cref out of the visualizer ident
573 ✗ (cref1,true) := splitCrefAfter(cref,ident); // check if this occurs in the qualified var cref
574 ✗ filled_vis := fillVectorObject(cref1,varIn,storeProtectedCrefs,program,vis);
575 ✗ then
576 (vars, filled_vis);
577
578 case (BackendDAE.VAR(varName=cref), (vars, vis as SURFACE(ident=ident)))
579 algorithm
580 //this var belongs to the visualization object
581 //crefIdent := makeCrefQualFromString(ident); // make a qualified cref out of the visualizer ident
582
2/2
✓ Branch 1 taken 3120 times.
✓ Branch 2 taken 120 times.
3240 (cref1,true) := splitCrefAfter(cref,ident); // check if this occurs in the qualified var cref
583 120 filled_vis := fillSurfaceObject(cref1,varIn,storeProtectedCrefs,program,vis);
584 120 then
585 (vars, filled_vis);
586
587 else
588 algorithm
589 19890 (vars, vis) := tplIn;
590 19890 then
591 (varIn::vars, vis);
592
593 end matchcontinue;
594 end fillVisualizationObjects1;
595
596 function getFullCADFilePath
597 "Get the absolute path for the given modelica uri.
598 author: vwaurich TUD 2016-10"
599 input String sIn;
600 input Absyn.Program program;
601 output String sOut = sIn;
602 protected
603 list<String> chars;
604 algorithm
605 32 chars := stringListStringChar(sIn);
606
1/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
32 if listLength(chars) > 11 and stringEqual(stringDelimitList(List.firstN(chars,11),""),"modelica://") then
607 ✗ sOut := "file://"+ProgramUtil.getFullPathFromUri(program,sIn,true);
608 end if;
609 end getFullCADFilePath;
610
611 function fillShapeObject
612 "sets the visualization info in the visualization object
613 author:Waurich TUD 2015-04"
614 input DAE.ComponentRef cref;
615 input BackendDAE.Var var;
616 input Boolean storeProtectedCrefs;
617 input Absyn.Program program;
618 input output Visualization vis;
619 algorithm
620 () := matchcontinue (cref, vis)
621 local
622 Option<DAE.Exp> bind;
623 DAE.Exp exp;
624 Integer pos, pos1;
625 list<DAE.Exp> T0;
626
627 case (DAE.CREF_IDENT(ident="shapeType"), SHAPE())
628 algorithm
629 32 BackendDAE.VAR(bindExp = bind) := var;
630
631
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if isSome(bind) then
632 32 vis.shapeType := Util.getOption(bind);
633 end if;
634 then
635 ();
636
637 case (DAE.CREF_QUAL(ident="R", componentRef=DAE.CREF_IDENT(ident="T",
638 subscriptLst = {DAE.INDEX(DAE.ICONST(pos)), DAE.INDEX(DAE.ICONST(pos1))})), SHAPE())
639 algorithm
640 288 exp := getVariableBinding(var, storeProtectedCrefs);
641 288 T0 := arrayGet(vis.T, pos);
642 288 T0 := List.replaceAt(exp, pos1, T0);
643 288 arrayUpdate(vis.T, pos, T0);
644 then
645 ();
646
647 case (DAE.CREF_IDENT(ident="r", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SHAPE())
648 algorithm
649 96 exp := getVariableBinding(var, storeProtectedCrefs);
650 96 arrayUpdate(vis.r, pos, exp);
651 then
652 ();
653
654 case (DAE.CREF_IDENT(ident="r_shape", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SHAPE())
655 algorithm
656 96 exp := getVariableBinding(var, storeProtectedCrefs);
657 96 arrayUpdate(vis.r_shape, pos, exp);
658 then
659 ();
660
661 case (DAE.CREF_IDENT(ident="lengthDirection", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SHAPE())
662 algorithm
663 96 exp := getVariableBinding(var, storeProtectedCrefs);
664 96 arrayUpdate(vis.lengthDir, pos, exp);
665 then
666 ();
667
668 case (DAE.CREF_IDENT(ident="widthDirection", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SHAPE())
669 algorithm
670 96 exp := getVariableBinding(var, storeProtectedCrefs);
671 96 arrayUpdate(vis.widthDir, pos, exp);
672 then
673 ();
674
675 case (DAE.CREF_IDENT(ident="length"), SHAPE())
676 algorithm
677 32 vis.length := getVariableBinding(var, storeProtectedCrefs);
678 then
679 ();
680
681 case (DAE.CREF_IDENT(ident="width"), SHAPE())
682 algorithm
683 32 vis.width := getVariableBinding(var, storeProtectedCrefs);
684 then
685 ();
686
687 case (DAE.CREF_IDENT(ident="height"), SHAPE())
688 algorithm
689 32 vis.height := getVariableBinding(var, storeProtectedCrefs);
690 then
691 ();
692
693 case (DAE.CREF_IDENT(ident="extra"), SHAPE())
694 algorithm
695 32 vis.extra := getVariableBinding(var, storeProtectedCrefs);
696 then
697 ();
698
699 case (DAE.CREF_IDENT(ident="color", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SHAPE())
700 algorithm
701 96 exp := getVariableBinding(var, storeProtectedCrefs);
702 96 arrayUpdate(vis.color, pos, exp);
703 then
704 ();
705
706 case (DAE.CREF_IDENT(ident="specularCoefficient"), SHAPE())
707 algorithm
708 32 vis.specularCoeff := getVariableBinding(var, storeProtectedCrefs);
709 then
710 ();
711
712 else ();
713 end matchcontinue;
714 end fillShapeObject;
715
716 function fillVectorObject
717 "sets the visualization info in the visualization object"
718 input DAE.ComponentRef cref;
719 input BackendDAE.Var var;
720 input Boolean storeProtectedCrefs;
721 input Absyn.Program program;
722 input output Visualization vis;
723 algorithm
724 () := matchcontinue (cref, vis)
725 local
726 DAE.Exp exp;
727 Integer pos, pos1;
728 list<DAE.Exp> T0;
729
730 case (DAE.CREF_QUAL(ident="R", componentRef=DAE.CREF_IDENT(ident="T",
731 subscriptLst = {DAE.INDEX(DAE.ICONST(pos)), DAE.INDEX(DAE.ICONST(pos1))})), VECTOR())
732 algorithm
733 ✗ exp := getVariableBinding(var, storeProtectedCrefs);
734 ✗ T0 := arrayGet(vis.T, pos);
735 ✗ T0 := List.replaceAt(exp, pos1, T0);
736 ✗ arrayUpdate(vis.T, pos, T0);
737 then
738 ();
739
740 case (DAE.CREF_IDENT(ident="r", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), VECTOR())
741 algorithm
742 ✗ exp := getVariableBinding(var, storeProtectedCrefs);
743 ✗ arrayUpdate(vis.r, pos, exp);
744 then
745 ();
746
747 case (DAE.CREF_IDENT(ident="coordinates", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), VECTOR())
748 algorithm
749 ✗ exp := getVariableBinding(var, storeProtectedCrefs);
750 ✗ arrayUpdate(vis.coordinates, pos, exp);
751 then
752 ();
753
754 case (DAE.CREF_IDENT(ident="color", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), VECTOR())
755 algorithm
756 ✗ exp := getVariableBinding(var, storeProtectedCrefs);
757 ✗ arrayUpdate(vis.color, pos, exp);
758 then
759 ();
760
761 case (DAE.CREF_IDENT(ident="specularCoefficient"), VECTOR())
762 algorithm
763 ✗ vis.specularCoeff := getVariableBinding(var, storeProtectedCrefs);
764 then
765 ();
766
767 case (DAE.CREF_IDENT(ident="quantity"), VECTOR())
768 algorithm
769 ✗ vis.quantity := getVariableBinding(var, storeProtectedCrefs);
770 then
771 ();
772
773 case (DAE.CREF_IDENT(ident="headAtOrigin"), VECTOR())
774 algorithm
775 ✗ vis.headAtOrigin := getVariableBinding(var, storeProtectedCrefs);
776 then
777 ();
778
779 case (DAE.CREF_IDENT(ident="twoHeadedArrow"), VECTOR())
780 algorithm
781 ✗ vis.twoHeadedArrow := getVariableBinding(var, storeProtectedCrefs);
782 then
783 ();
784
785 else ();
786 end matchcontinue;
787 end fillVectorObject;
788
789 function fillSurfaceObject
790 "sets the visualization info in the visualization object"
791 input DAE.ComponentRef cref;
792 input BackendDAE.Var var;
793 input Boolean storeProtectedCrefs;
794 input Absyn.Program program;
795 input output Visualization vis;
796 algorithm
797 () := matchcontinue (cref, vis)
798 local
799 DAE.Exp exp;
800 Integer pos, pos1;
801 list<DAE.Exp> T0;
802
803 case (DAE.CREF_QUAL(ident="R", componentRef=DAE.CREF_IDENT(ident="T",
804 subscriptLst = {DAE.INDEX(DAE.ICONST(pos)), DAE.INDEX(DAE.ICONST(pos1))})), SURFACE())
805 algorithm
806 45 exp := getVariableBinding(var, storeProtectedCrefs);
807 45 T0 := arrayGet(vis.T, pos);
808 45 T0 := List.replaceAt(exp, pos1, T0);
809 45 arrayUpdate(vis.T, pos, T0);
810 then
811 ();
812
813 case (DAE.CREF_IDENT(ident="r_0", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SURFACE())
814 algorithm
815 15 exp := getVariableBinding(var, storeProtectedCrefs);
816 15 arrayUpdate(vis.r_0, pos, exp);
817 then
818 ();
819
820 case (DAE.CREF_IDENT(ident="nu"), SURFACE())
821 algorithm
822 5 vis.nu := getVariableBinding(var, storeProtectedCrefs);
823 then
824 ();
825
826 case (DAE.CREF_IDENT(ident="nv"), SURFACE())
827 algorithm
828 5 vis.nv := getVariableBinding(var, storeProtectedCrefs);
829 then
830 ();
831
832 //case (DAE.CREF_IDENT(ident="surfaceCharacteristic"), SURFACE())
833 // algorithm
834 // then
835 // ();
836
837 case (DAE.CREF_IDENT(ident="wireframe"), SURFACE())
838 algorithm
839 5 vis.wireframe := getVariableBinding(var, storeProtectedCrefs);
840 then
841 ();
842
843 case (DAE.CREF_IDENT(ident="multiColored"), SURFACE())
844 algorithm
845 ✗ vis.multiColored := getVariableBinding(var, storeProtectedCrefs);
846 then
847 ();
848
849 case (DAE.CREF_IDENT(ident="color", subscriptLst = {DAE.INDEX(DAE.ICONST(pos))}), SURFACE())
850 algorithm
851 15 exp := getVariableBinding(var, storeProtectedCrefs);
852 15 arrayUpdate(vis.color, pos, exp);
853 then
854 ();
855
856 case (DAE.CREF_IDENT(ident="specularCoefficient"), SURFACE())
857 algorithm
858 5 vis.specularCoeff := getVariableBinding(var, storeProtectedCrefs);
859 then
860 ();
861
862 case (DAE.CREF_IDENT(ident="transparency"), SURFACE())
863 algorithm
864 5 vis.transparency := getVariableBinding(var, storeProtectedCrefs);
865 then
866 ();
867
868 else ();
869 end matchcontinue;
870 end fillSurfaceObject;
871
872 function getVariableBinding
873 input BackendDAE.Var var;
874 input Boolean storeProtectedCrefs;
875 output DAE.Exp exp;
876 protected
877 Option<DAE.Exp> binding;
878 algorithm
879 1028 BackendDAE.VAR(bindExp = binding) := var;
880
881
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1028 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1018 times.
1028 if isSome(binding) then
882 1018 SOME(exp) := binding;
883
884
3/4
✓ Branch 1 taken 455 times.
✓ Branch 2 taken 563 times.
✓ Branch 3 taken 455 times.
✗ Branch 4 not taken.
1018 if not Expression.isConstValue(exp) and storeProtectedCrefs then
885 455 exp := BackendVariable.varExp(var);
886 end if;
887 else
888 10 exp := BackendVariable.varExp(var);
889 end if;
890 end getVariableBinding;
891
892 function printVisualization
893 "printing function for debugging.
894 author:Waurich TUD 2015-04"
895 input Visualization vis;
896 output String s;
897 algorithm
898 s := match vis
899 local
900 DAE.ComponentRef ident;
901 DAE.Exp length, width, height, extra, shapeType;
902 array<DAE.Exp> color, r, widthDir, lengthDir;
903 array<list<DAE.Exp>> T;
904 case SHAPE(ident=ident, shapeType=shapeType, color=color, r=r, lengthDir=lengthDir, widthDir=widthDir, T=T, length=length, width=width, height=height, extra=extra)
905 ✗ then ("SHAPE "+ComponentReferenceBasics.printComponentRefStr(ident)+" '"+ExpressionBasics.printExpStr(shapeType) + "'\n r{"+stringDelimitList(list(ExpressionDump.dumpExpStr(e, 0) for e in r),",")+"}" +
906 "\nlD{"+stringDelimitList(List.mapArray(lengthDir, ExpressionBasics.printExpStr),",")+"}"+" wD{"+stringDelimitList(List.mapArray(widthDir, ExpressionBasics.printExpStr),",")+"}"+
907 "\ncolor("+stringDelimitList(List.mapArray(color, ExpressionBasics.printExpStr),",")+")"+" w: "+ExpressionBasics.printExpStr(width)+" h: "+ExpressionBasics.printExpStr(height)+" l: "+ExpressionBasics.printExpStr(length) +
908 "\nT {"+ stringDelimitList(List.map(List.flatten(arrayList(T)),ExpressionBasics.printExpStr),", ")+"}"+"\nextra{"+ExpressionBasics.printExpStr(extra)+"}");
909 else
910 then "-";
911 end match;
912 end printVisualization;
913
914 function isVisualizationVar
915 "the var inherits from an visualization object. Therefore, the paths are checked.
916 author:Waurich TUD 2015-04"
917 input BackendDAE.Var var;
918 output Boolean isVisVar;
919 algorithm
920 isVisVar := match var
921 local
922 DAE.ElementSource source;
923 String obj;
924 list<Absyn.Path> paths;
925
926 case BackendDAE.VAR(source=source)
927 algorithm
928 2332 paths := ElementSource.getElementSourceTypes(source);
929 //_ := list(AbsynUtil.pathString(p) for p in paths);
930 //print("paths_lst "+stringDelimitList(paths_lst, "; ")+"\n");
931 2332 obj := hasVisPath(paths, 1);
932 2332 then
933 Util.stringNotEqual(obj, "");
934
935 else false;
936 end match;
937 end isVisualizationVar;
938
939 function isVisualizationVarFold
940 "the var inherits from an visualization object. Therefore, the paths are checked.
941 author:Waurich TUD 2015-04"
942 input BackendDAE.Var var;
943 input tuple<list<BackendDAE.Var>,list<tuple<DAE.ComponentRef, String>>> tplIn;//visualizationVars, visualization Identifiers
944 output tuple<list<BackendDAE.Var>,list<tuple<DAE.ComponentRef, String>>> tplOut;
945 algorithm
946 tplOut := matchcontinue(var,tplIn)
947 local
948 Integer idx;
949 DAE.ComponentRef varName, cref;
950 list<tuple<DAE.ComponentRef, String>> crefs;
951 DAE.ElementSource source;
952 list<BackendDAE.Var> varLst;
953 String obj;
954 list<Absyn.Path> paths;
955
956 case (BackendDAE.VAR(varName=varName, source=source), (varLst,crefs))
957 algorithm
958 2295 paths := ElementSource.getElementSourceTypes(source);
959 //print("Component " + ComponentReferenceBasics.printComponentRefStr(varName) + ":\n");
960 //print(List.toString(paths, AbsynUtil.pathStringDefault, "", " ", "\n ", "", false) + "\n");
961 2295 (obj, idx) := hasVisPath(paths, 1);
962
2/2
✓ Branch 1 taken 1119 times.
✓ Branch 2 taken 1176 times.
2295 true := Util.stringNotEqual(obj, "");
963 //print("ComponentRef "+ComponentReferenceBasics.printComponentRefStr(varName)+" path: "+obj+ " idx: "+intString(idx)+"\n");
964 1176 cref := ComponentReference.firstNCrefs(varName, idx-1);
965 2352 crefs := List.unique((cref, obj)::crefs);
966 1176 then
967 (var::varLst, crefs);
968
969 else tplIn;
970 end matchcontinue;
971 end isVisualizationVarFold;
972
973 function hasVisPath
974 "checks if the path is a known visualization type and outputs its name if true.
975 These are Modelica.Mechanics.MultiBody.Visualizers.Advanced.{Shape,Vector,Surface}
976 and the underlying ModelicaServices.Animation.{Shape,Vector,Surface} they extend,
977 so that shapes instantiated directly from ModelicaServices are visualized as well.
978 outputs which path is the vis path
979 author:Waurich TUD 2015-04"
980 input list<Absyn.Path> pathsIn;
981 input Integer numIn;
982 output String visPath;
983 output Integer numOut;
984 algorithm
985 (visPath, numOut) := match pathsIn
986 local
987 String name;
988 Absyn.Path path;
989 list<Absyn.Path> rest;
990
991 case {} then ("", -1);
992 ✗ case Absyn.FULLYQUALIFIED(path=path)::rest then hasVisPath(path::rest, numIn);
993
994 case Absyn.QUALIFIED(name="Modelica",
995 path=Absyn.QUALIFIED(name="Mechanics",
996 path=Absyn.QUALIFIED(name="MultiBody",
997 path=Absyn.QUALIFIED(name="Visualizers",
998 path=Absyn.QUALIFIED(name="Advanced",
999 path=Absyn.IDENT(name=name))))))::_
1000 guard isVisualizerName(name)
1001 then
1002 (name, numIn);
1003
1004 case Absyn.QUALIFIED(name="ModelicaServices",
1005 path=Absyn.QUALIFIED(name="Animation",
1006 path=Absyn.IDENT(name=name)))::_
1007 guard isVisualizerName(name)
1008 then
1009 (name, numIn);
1010
1011 12163 case _::rest then hasVisPath(rest,numIn+1);
1012 end match;
1013 end hasVisPath;
1014
1015 function isVisualizerName
1016 "true if the name is one of the supported visualization types"
1017 input String name;
1018 output Boolean isVisualizer;
1019 algorithm
1020 isVisualizer := match name
1021 case "Shape" then true;
1022 case "Vector" then true;
1023 case "Surface" then true;
1024 else false;
1025 end match;
1026 end isVisualizerName;
1027
1028 function dumpVis
1029 "author: waurich TUD
1030 Dumps the graph into a *.xml-file."
1031 input array<Visualization> visIn;
1032 input String iFileName;
1033 algorithm
1034 print("");
1035 3 Tpl.tplNoret2(VisualXMLTpl.dumpVisXML, visIn, iFileName);
1036 end dumpVis;
1037
1038 annotation(__OpenModelica_Interface="backend");
1039 end VisualXML;
1040