1 //#**************************************************************
2 //#
3 //# filename: script_parser.cpp
4 //#
5 //# author: Gerstmayr Johannes
6 //#
7 //# generated: July 2004
8 //# description: parser for creating objects in script language
9 //#
10 //# remarks:
11 //#
12 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian
13 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the
14 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved.
15 //#
16 //# This file is part of HotInt.
17 //# HotInt is free software: you can redistribute it and/or modify it under the terms of
18 //# the HOTINT license. See folder 'licenses' for more details.
19 //#
20 //# bug reports are welcome!!!
21 //# WWW: www.hotint.org
22 //# email: bug_reports@hotint.org or support@hotint.org
23 //#**************************************************************
24 #include "mbs_interface.h"
25 #include "element.h"
26 #include "options_class_auto.h"
27 #include "script_parser.h"
28 //$ YV 2012-12-14: the following include is to be removed; general object factory should be used in the future
29 //#include "sensorsSpecific.h" //$ DR 2012-10: necessary to include for CEDCParser
30 #include "elementdataaccess.h"
31 #include "graphicsconstants.h"
32 #include "material.h"
33 #include "geomelements.h"
34 #include "femathhelperfunctions.h"
35 #include "sensors.h"
36 #include "parser.h"
37 #include "elementsandmodelslibraryinterface.h"
38 #include "node.h"
39
40
41
42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43 //++++++++++++++++++++++++++++EvaluateTextualParameterEntry++++++++++++++++++++++++++++++++++++++++++
44 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EvaluateTextualParameterEntry(MBS * mbs,CEDCParser * edcParser,ElementDataContainer * param_edc)45 int CEDC_Command::EvaluateTextualParameterEntry(MBS *mbs, CEDCParser *edcParser, ElementDataContainer *param_edc)
46 {
47 // convert any textual entry to scalar,vector,matrix
48 // assume that the parameter EDC has only a single entry
49 ElementData* edp = param_edc->GetPtr(1);
50 if(edp->IsText())
51 {
52 mystr entry = mystr(edp->GetDataName()) + mystr("= ") + mystr(edp->GetText());
53 ElementDataContainer tmp;
54
55 // evaluate the textual entry
56 edcParser->ParseAndExecuteString(entry,tmp);
57
58 param_edc->Delete(1);
59 param_edc->TreeReplaceEDCDataWith(&tmp);
60
61 return 1;
62 }
63 return 0;
64 }
65
66
67 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68 //++++++++++++++++++++++++++++++++ExecuteCommand ++++++++++++++++++++++++++++++++++++++++++++++++++++
69 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)70 int CEDC_ComAddElement::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
71 {
72 int rv_error = 0;
73 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
74 int element_type_index = edc->Find("element_type"); //find index in element EDC
75 if (element_type_index)
76 {
77 if (!edc->Get(element_type_index).IsText()) {assert(0);}
78
79 int listindex;
80 mystr element_type_str = edc->Get(element_type_index).GetText();
81 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCElement, element_type_str);
82 if (type_id < 0 )
83 {
84 edcParser->EDCError(mystr("Element type '") + element_type_str + mystr("' not found in command AddElement(...)!"));
85 return_value.SetInt(rv_error, ""); //return value has no name!
86 return 0;
87 } //does not exist in element type list
88
89 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCElement, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
90
91 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
92 {
93 edcParser->EDCError(mystr("ERROR: ") + element_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
94 return_value.SetInt(rv_error, ""); //return value has no name!
95 return 0;
96 }
97 else
98 {
99 if (IsAddElement() && (typeflags & TAEconstraint)) //constraints are in the same list, but should not be added with "AddElement"
100 {
101 edcParser->EDCError(mystr("Connector '")+element_type_str+mystr("' can not be added with command AddElement(...), use AddConnector(...) instead!"));
102 }
103 else if (!IsAddElement() && !(typeflags & TAEconstraint)) //constraints are in the same list, but should not be added with "AddElement"
104 {
105 edcParser->EDCError(mystr("Element '")+element_type_str+mystr("' can not be added with command AddConnector(...), use AddElement(...) instead!"));
106 }
107
108 //add new element of selected type to MBS
109 //int elnum = edcParser->AddElement(type_id, option); //old: AddElement(element_type_index, option);
110 int elnum = edcParser->GetObjectFactory()->AddObject(OFCElement, type_id);
111
112 //retrieve the default EDC for the new element
113 ElementDataContainer edc;
114 mbs->GetElement(elnum).GetElementData(edc);
115 //now overwrite the default with the user-defined values
116 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
117 //now set the user-defined EDC in the newly generated element
118 int rv = mbs->GetElement(elnum).SetElementData(edc);
119
120 return_value.SetInt(elnum, ""); //return value has no name!
121
122 return 1;
123 }
124 }
125 else
126 {
127 edcParser->EDCError(mystr("did not find 'element_type' in command ") + CommandName());
128 return_value.SetInt(rv_error, ""); //return value has no name!
129 return 0;
130 }
131 }
132
133 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
134 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)135 int CEDC_ComAddGeomElement::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
136 {
137 int rv_error = 0;
138 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
139 int element_type_index = edc->Find("geom_element_type"); //find index in element EDC
140 if (element_type_index)
141 {
142 if (!edc->Get(element_type_index).IsText()) {assert(0);}
143
144 int listindex;
145 mystr element_type_str = edc->Get(element_type_index).GetText();
146 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCGeomElement, element_type_str);
147 if (type_id < 0)
148 {
149 edcParser->EDCError(mystr("Element type '") + element_type_str + mystr("' not found in command AddGeomElement(...)!"));
150 return_value.SetInt(rv_error, ""); //return value has no name!
151 return 0;
152 }
153
154 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCGeomElement, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
155
156 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
157 {
158 edcParser->EDCError(mystr("ERROR: ") + element_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
159 return_value.SetInt(rv_error, ""); //return value has no name!
160 return 0;
161 }
162 else
163 {
164 //add new element of selected type to MBS
165 //int geom_elnum=edcParser->AddGeomElement(type_id,0); //Add GeomElement with default values
166 int geom_elnum = edcParser->GetObjectFactory()->AddObject(OFCGeomElement, type_id); //Add GeomElement with default values
167 //retrieve the default EDC for the new element
168 ElementDataContainer edc;
169 mbs->GetDrawElement(geom_elnum)->GetElementData(edc);
170 //now overwrite the default with the user-defined values
171 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
172 //now set the user-defined EDC in the newly generated element
173 int rv = mbs->GetDrawElement(geom_elnum)->SetElementData(edc);
174
175 return_value.SetInt(geom_elnum, ""); //return value has no name!
176
177 return 1;
178 }
179 }
180 else
181 {
182 edcParser->EDCError(mystr("did not find 'geom_element_type' in command ") + CommandName());
183 return_value.SetInt(rv_error, ""); //return value has no name!
184 return 0;
185 }
186 }
187
188 //$ DR 2012-11
189
GetCommandTexParameterDescription() const190 mystr CEDC_ComPrint::GetCommandTexParameterDescription() const
191 {
192 mystr descr;
193 descr += "There are three possibilities to use the command. The parameter can either be: \\\\ \n";
194 descr += mystr("\\begin{itemize} \n");
195 descr+= mystr(" \\item a text, e.g. Print(\"Hello world\") \n");
196 descr+= mystr(" \\item an ElementDataContainer, e.g. Print(my\\_mass) \n");
197 descr+= mystr(" \\item an ElementData, e.g. Print(my\\_mass.density) \n");
198 descr += mystr("\\end{itemize} \n");
199 descr += mystr("In the case of a text or an ElementData, only the text itself is printed. In the case of an ElementDataContainer, also the name of the ElementData is printed.");
200 return descr;
201 }
202
203
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)204 int CEDC_ComPrint::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
205 {
206 mystr str, num;
207
208 //symbols defined in CEDCParser:
209 mystr el = "\n"; //end of line
210 mystr ob = "{"; //open brace
211 mystr cb = "}"; //closing brace
212 mystr osb = "["; //open square bracket
213 mystr csb = "]"; //closing square bracket
214 mystr ds = ": "; //double stop
215 mystr semicolon = ";"; //semicolon
216 char commentc = '%'; //comment
217 mystr doublequote = mystr('"'); //for strings or text
218
219 //symbols with additional whitespaces:
220 mystr eq = "= "; //equal sign
221 mystr comma = ", "; //comma
222 mystr comment = mystr(" ")+mystr(commentc); //comment
223 mystr matrixsep = el; //may be changed to semicolon ...
224
225
226 ElementData ed = parameter_EDCs(1)->Get(1);
227 if ((parameter_EDCs(1)->Length()==1) && (! ed.IsEDC())) // if it is not an EDC, than do not write "text = my text" but only "my text"
228 {
229 if (ed.IsText())
230 {
231 str = parameter_EDCs(1)->Get(1).GetText();
232 str.Replace("\\n","\n");
233 }
234 else if (ed.IsBool())
235 {
236 str += mystr(ed.GetBool());
237 }
238 else if (ed.IsInt())
239 {
240 str += mystr(ed.GetInt());
241 }
242 else if (ed.IsDouble())
243 {
244 num.SmartDouble2String(ed.GetDouble());
245 str += num;
246 }
247 else if (ed.IsText())
248 {
249 str += mystr(doublequote) + mystr(ed.GetText()) + mystr(doublequote);
250 }
251 else if (ed.IsVector())
252 {
253 str += osb;
254 for (int j = 1; j <= ed.GetVectorLen(); j++)
255 {
256 num.SmartDouble2String(ed.GetVectorVal(j));
257 str += num;
258 if (j < ed.GetVectorLen()) str += comma;
259 }
260 str += csb;
261 }
262 else if (ed.IsMatrix())
263 {
264 str += osb;
265 for (int j1 = 1; j1 <= ed.GetMatrixRows(); j1++)
266 {
267 for (int j2 = 1; j2 <= ed.GetMatrixCols(); j2++)
268 {
269 num.SmartDouble2String(ed.GetMatrixVal(j1, j2));
270 str += num;
271 if (j2 < ed.GetMatrixCols()) str += comma;
272 }
273 if (j1 < ed.GetMatrixRows()) str += matrixsep + mystr(" ");
274 }
275 str += csb;
276 }
277 }
278 else
279 {
280 ElementDataContainer edc;
281 edc.CopyFrom(*parameter_EDCs(1));
282 edcParser->EDC2String(edc, str,"");
283 }
284 //mbs->UO(UO_LVL_warn) << str;
285 mbs->UO(UO_LVL_0) << str;
286
287 return 1;
288 }
289
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)290 int CEDC_ComInclude::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
291 {
292 if (!parameter_EDCs(1)->Get(1).IsText())
293 {
294 edcParser->EDCError(mystr("Error happened during parsing command ") + CommandName());
295 return 0;
296 }
297
298 mystr param_text = parameter_EDCs(1)->Get(1).GetText(); // filename is absolute or alternatively relative to hid-file
299
300
301 mystr filename = param_text; // param_text contains filename without double quotes
302
303 int rv = 1; // success
304 edcParser->MakeFilenameAbsolute(filename); //$ DR 2013-07-04
305 //$ MSax 2013-07-18 :[ begin
306 //int pos = 1;
307 //int isRelativePath = filename.PosPeek(pos) != ':';
308 //if(isRelativePath)
309 //{
310 // mystr rel_path("");
311 // {
312 // mystr last_file_name = mbs->GetModelDataContainer()->TreeGetString("last_file_name");
313 // {
314 // int until;
315 // for(until=last_file_name.Length()-1;until>=0;until--)
316 // {
317 // if(last_file_name.PosPeek(until) == '\\')
318 // break; // until <=> last backslash
319 // }
320 // for(int i=0;i<=until;i++)
321 // {
322 // rel_path += last_file_name.PosPeek(i); // path until last backslash
323 // }
324 // }
325 // }
326 //
327 // // remove ..\
328 // {
329 // int pos=rel_path.Length()-1;
330 // if(rel_path.PosPeek(pos)=='\\')
331 // {
332 // rel_path.EraseChar(pos+1);
333 // }
334 // }
335
336 // int replaced = filename.Replace(mystr("..\\"), mystr("")); //find string searchstr, replace with string replacestr; this is done repeatedly; the return value counts the number of replacements
337 //
338 // //for(int pos=rel_path.Length();pos--;pos>0) //$ DR 2013-01-10 does not make sense
339 // for(int pos=rel_path.Length();pos>0;pos--)
340 // {
341 // if(!replaced){break;}
342 // int prev = pos-1;
343 // if(rel_path.PosPeek(prev)=='\\')
344 // {
345 // replaced --;
346 // }
347 // rel_path.EraseChar(pos);
348 // }
349 // filename = rel_path + mystr("\\") + filename;
350 //}
351 //$ MSax 2013-07-18 :] end
352 if (DoesFileExist(filename))
353 {
354 ElementDataContainer edc_file;
355 if(mbs->GetModelDataContainer() == 0)
356 {
357 rv = mbs->ReadModelData(filename); // empty model data container --> create new one
358 }
359 else
360 {
361 rv = mbs->AddModelData(filename); // model data container has contents --> add and replace
362 }
363 }
364 else
365 {
366 edcParser->EDCError(mystr("Error in Include - command: Can not find 'filename' '") + filename + mystr("'!"));
367 rv = 0;
368 }
369 return rv;
370 }
371
372 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
373 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
374 //$ DR 2012-10
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)375 int CEDC_ComAddLoad::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
376 {
377 int rv_error = 0;
378 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
379 int load_type_index = edc->Find("load_type"); //find index in element EDC
380 if (load_type_index)
381 {
382 if (!edc->Get(load_type_index).IsText()) {assert(0);}
383
384 //int listindex;
385 mystr load_type_str = edc->Get(load_type_index).GetText();
386 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCLoad, load_type_str);
387
388 if (type_id < 0)
389 {
390 edcParser->EDCError(mystr("Load type '") + load_type_str + mystr("' not found in command AddLoad(...)!"));
391 return_value.SetInt(rv_error, ""); //return value has no name!
392 return 0;
393 }
394
395 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCLoad, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
396
397 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
398 {
399 edcParser->EDCError(mystr("ERROR: ") + load_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
400 return_value.SetInt(rv_error, ""); //return value has no name!
401 return 0;
402 }
403 else
404 {
405 //add new load of selected type to MBS
406 int load_elnum = edcParser->GetObjectFactory()->AddObject(OFCLoad, type_id); //Add Load with default values
407
408 //retrieve the default EDC for the new element
409 ElementDataContainer edc;
410 mbs->GetLoad(load_elnum).GetElementData(edc);
411 //now overwrite the default with the user-defined values
412 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
413 //now set the user-defined EDC in the newly generated element
414 int rv = mbs->GetLoad(load_elnum).SetElementData(edc);
415
416 return_value.SetInt(load_elnum, ""); //return value has no name!
417
418 return 1;
419 }
420 }
421 else
422 {
423 edcParser->EDCError(mystr("did not find 'load_type' in command ") + CommandName());
424 return_value.SetInt(rv_error, ""); //return value has no name!
425 return 0;
426 }
427 }
428 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
429 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
430 //$ DR 2012-10
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)431 int CEDC_ComAddSensor::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
432 {
433 int rv_error = 0;
434 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
435 int sensor_type_index = edc->Find("sensor_type"); //find index in element EDC
436 if (sensor_type_index)
437 {
438 if (!edc->Get(sensor_type_index).IsText()) {assert(0);}
439
440 //int listindex;
441 mystr sensor_type_str = edc->Get(sensor_type_index).GetText();
442 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCSensor, sensor_type_str);
443
444 if (type_id < 0)
445 {
446 edcParser->EDCError(mystr("Sensor type '") + sensor_type_str + mystr("' not found in command AddSensor(...)!"));
447 return_value.SetInt(rv_error, ""); //return value has no name!
448 return 0;
449 }
450
451 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCSensor, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
452
453 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
454 {
455 edcParser->EDCError(mystr("ERROR: ") + sensor_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
456 return_value.SetInt(rv_error, ""); //return value has no name!
457 return 0;
458 }
459 else
460 {
461 //add new sensor of selected type to MBS
462 int sensor_elnum = edcParser->GetObjectFactory()->AddObject(OFCSensor, type_id); //Add Load with default values
463 //retrieve the default EDC for the new element
464 ElementDataContainer edc;
465 mbs->GetSensor(sensor_elnum).GetElementData(edc);
466 //now overwrite the default with the user-defined values
467 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
468 //now set the user-defined EDC in the newly generated element
469 int rv = mbs->GetSensor(sensor_elnum).SetElementData(edc);
470
471 return_value.SetInt(sensor_elnum, ""); //return value has no name!
472
473 return 1;
474 }
475 }
476 else
477 {
478 edcParser->EDCError(mystr("did not find 'sensor_type' in command ") + CommandName());
479 return_value.SetInt(rv_error, ""); //return value has no name!
480 return 0;
481 }
482 }
483
484 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
485 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
486 //$ DR 2012-10
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)487 int CEDC_ComLoadSTL::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
488 {
489 if (!parameter_EDCs(1)->Get(1).IsText())
490 {
491 edcParser->EDCError(mystr("Error happened during parsing command ") + CommandName());
492 return 0;
493 }
494
495 mystr param_text = parameter_EDCs(1)->Get(1).GetText(); // filename is absolute or alternatively relative to hid-file
496
497 mystr filename = param_text; // param_text contains filename without double quotes
498
499 int rv = 1; // success
500 rv = edcParser->MakeFilenameAbsolute(filename); //$ DR 2013-07-04
501 //int pos = 1;
502 //int isRelativePath = filename.PosPeek(pos) != ':';
503 //if(isRelativePath)
504 //{
505 // mystr rel_path("");
506 // {
507 // mystr last_file_name = mbs->GetModelDataContainer()->TreeGetString("last_file_name");
508 // {
509 // int until;
510 // for(until=last_file_name.Length()-1;until>=0;until--)
511 // {
512 // if(last_file_name.PosPeek(until) == '\\')
513 // break; // until <=> last backslash
514 // }
515 // for(int i=0;i<=until;i++)
516 // {
517 // rel_path += last_file_name.PosPeek(i); // path until last backslash
518 // }
519 // }
520 // }
521 //
522 // // remove ..\
523 // {
524 // int pos=rel_path.Length()-1;
525 // if(rel_path.PosPeek(pos)=='\\')
526 // {
527 // rel_path.EraseChar(pos+1);
528 // }
529 // }
530
531 // int replaced = filename.Replace(mystr("..\\"), mystr("")); //find string searchstr, replace with string replacestr; this is done repeatedly; the return value counts the number of replacements
532 //
533 // //for(int pos=rel_path.Length();pos--;pos>0) //$ DR 2013-01-10 does not make sense
534 // for(int pos=rel_path.Length();pos>0;pos--)
535 // {
536 // if(!replaced){break;}
537 // int prev = pos-1;
538 // if(rel_path.PosPeek(prev)=='\\')
539 // {
540 // replaced --;
541 // }
542 // rel_path.EraseChar(pos);
543 // }
544 // filename = rel_path + mystr("\\") + filename;
545 //}
546
547 ElementDataContainer edc;
548
549 if(rv)
550 {
551 rv = mbs->File2EDC(filename, &edc);
552 return_value.SetEDC(&edc,"MeshData");
553 }
554 return rv;
555
556 }
557 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
558 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
559 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)560 int CEDC_ComAddMaterial::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
561 {
562 int rv_error = 0;
563 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
564 int continuum_type_index = edc->Find("material_type"); //find index in element EDC
565 mystr type = edc->TreeGetString("material_type");
566 if (continuum_type_index)
567 {
568 if (!edc->Get(continuum_type_index).IsText()) {assert(0);}
569
570 int listindex;
571 mystr mat_type_str = edc->Get(continuum_type_index).GetText();
572 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCMaterial, mat_type_str);
573
574 if (type_id < 0)
575 {
576 edcParser->EDCError(mystr("Material type '") + mat_type_str + mystr("' not found in command AddMaterial(...)!"));
577 return_value.SetInt(rv_error, ""); //return value has no name!
578 return 0;
579 }
580
581 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCMaterial, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
582
583 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
584 {
585 edcParser->EDCError(mystr("ERROR: ") + mat_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
586 return_value.SetInt(rv_error, ""); //return value has no name!
587 return 0;
588 }
589 else
590 {
591 //add new material to MBS
592 int mat_num = edcParser->GetObjectFactory()->AddObject(OFCMaterial, type_id); //Add Material with default values
593 //retrieve the default EDC for the new material
594 ElementDataContainer edc;
595 mbs->GetMaterial(mat_num).GetElementData(edc);
596 //now overwrite the default with the user-defined values
597 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
598 //now set the user-defined EDC in the newly generated material
599 int rv = mbs->GetMaterial(mat_num).SetElementData(edc);
600
601 return_value.SetInt(mat_num, ""); //return value has no name!
602
603 return 1;
604 }
605 }
606 else
607 {
608 edcParser->EDCError(mystr("did not find 'material_type' in command ") + CommandName());
609 return_value.SetInt(rv_error, ""); //return value has no name!
610 return 0;
611 }
612 }
613
614 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
615 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
616 //$ DR 2013-01
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)617 int CEDC_ComAddBeam3DProperties::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
618 {
619 int rv_error = 0;
620 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
621 int beam_property_type_index = edc->Find("material_type"); //find index in element EDC
622 if (beam_property_type_index)
623 {
624 if (!edc->Get(beam_property_type_index).IsText()) {assert(0);}
625
626 //int listindex;
627 mystr beam_property_type_str = edc->Get(beam_property_type_index).GetText();
628 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCBeamProperties, beam_property_type_str);
629
630 if (type_id < 0)
631 {
632 edcParser->EDCError(mystr("BeamProperty type '") + beam_property_type_str + mystr("' not found in command AddBeamProperties(...)!"));
633 return_value.SetInt(rv_error, ""); //return value has no name!
634 return 0;
635 }
636
637 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCBeamProperties, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
638 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
639 {
640 edcParser->EDCError(mystr("ERROR: ") + beam_property_type_str + mystr(" is not implemented yet. Check Homepage for available updates."));
641 return_value.SetInt(rv_error, ""); //return value has no name!
642 return 0;
643 }
644 else
645 {
646 //add new beam property of selected type to MBS
647 int beamProp_matnum = edcParser->GetObjectFactory()->AddObject(OFCBeamProperties, type_id); //Add beam property with default values
648 //retrieve the default EDC for the new element
649 ElementDataContainer edc;
650 mbs->GetMaterial(beamProp_matnum).GetElementData(edc);
651 //now overwrite the default with the user-defined values
652 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
653 //now set the user-defined EDC in the newly generated element
654 int rv = mbs->GetMaterial(beamProp_matnum).SetElementData(edc);
655
656 return_value.SetInt(beamProp_matnum, ""); //return value has no name!
657
658 return 1;
659 }
660 }
661 else
662 {
663 edcParser->EDCError(mystr("did not find 'beam_poperty_type' in command ") + CommandName());
664 return_value.SetInt(rv_error, ""); //return value has no name!
665 return 0;
666 }
667 }
668
669 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
670 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
671 //$ DR 2013-01
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)672 int CEDC_ComAddNode::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
673 {
674 int rv_error = 0;
675 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
676 int node_type_index = edc->Find("node_type"); //find index in element EDC
677 if (node_type_index)
678 {
679 if (!edc->Get(node_type_index).IsText()) {assert(0);}
680
681 //int listindex;
682 mystr node_property_str = edc->Get(node_type_index).GetText();
683 int type_id = edcParser->GetObjectFactory()->GetObjectTypeId(OFCNode, node_property_str);
684
685 if (type_id < 0)
686 {
687 edcParser->EDCError(mystr("Node type '") + node_property_str + mystr("' not found in command AddNode(...)!"));
688 return_value.SetInt(rv_error, ""); //return value has no name!
689 return 0;
690 }
691 int typeflags = edcParser->GetObjectFactory()->GetTypeFlags(OFCNode, type_id); //this are the typeflags, e.g. constraint, 2D, etc.
692 if( (typeflags & TAENotInRelease) && (edcParser->GetObjectFactory()->ExcludeExperimentalObjects()) )
693 {
694 edcParser->EDCError(mystr("ERROR: ") + node_property_str + mystr(" is not implemented yet. Check Homepage for available updates."));
695 return_value.SetInt(rv_error, ""); //return value has no name!
696 return 0;
697 }
698 else
699 {
700 //add new node of selected type to MBS
701 int node_num = edcParser->GetObjectFactory()->AddObject(OFCNode, type_id); //Add Node with default values
702 //retrieve the default EDC for the new element
703 ElementDataContainer edc;
704 mbs->GetNode(node_num).GetElementData(edc);
705 //now overwrite the default with the user-defined values
706 edc.TreeReplaceEDCDataWith(parameter_EDCs(1),1);
707 //now set the user-defined EDC in the newly generated element
708 int rv = mbs->GetNode(node_num).SetElementData(edc);
709
710 return_value.SetInt(node_num, ""); //return value has no name!
711
712 return 1;
713 }
714 }
715 else
716 {
717 edcParser->EDCError(mystr("did not find 'node_type' in command ") + CommandName());
718 return_value.SetInt(rv_error, ""); //return value has no name!
719 return 0;
720 }
721 }
722
723 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
724 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
725 //$ DR 2013-01-30
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)726 int CEDC_ComComputeInertia::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
727 {
728 ElementDataContainer* edc = parameter_EDCs(1); //this contains the element Data
729 ElementDataContainer edc_rv;
730 int rv = mbs->ComputeInertia(edc,&edc_rv);
731 if(rv)
732 {
733 return_value.SetEDC(&edc_rv,"InertiaValues");
734 }
735 return rv;
736 }
GetCommandTexParameterDescription() const737 mystr CEDC_ComComputeInertia::GetCommandTexParameterDescription() const
738 {
739 mystr descr = mystr("The parameter of this command is an ElementDataContainer, with the following entries: \n");
740 descr += mystr("\\begin{itemize} \n");
741 descr += mystr(" \\item density or material\\_number (one of these 2 has to be set!) \n");
742 descr += mystr(" \\item One of the following options to define the geometry: \n");
743 descr += mystr(" \\begin{itemize} \n");
744 descr += mystr(" \\item MeshData.triangles and MeshData.points \\\\ \n");
745 descr += mystr(" both entries are Matrices with 3 columns \n");
746 descr += mystr(" \\item Cube.body\\_dimensions \n");
747 descr += mystr(" \\end{itemize} \n");
748 descr += mystr("\\end{itemize} \n");
749 descr += mystr("-"); //DR hack, to avoid bugs in latex
750
751 return descr;
752 };
753 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
754 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
755 //$ DR 2013-02-19
756
GetCommandTexParameterDescription() const757 mystr CEDC_ComTransformPoints::GetCommandTexParameterDescription() const
758 {
759 mystr descr = mystr("The parameters of this command are as follows \n");
760 descr += mystr("\\begin{enumerate} \n");
761 descr += mystr(" \\item points: Matrix of the points: Each line represents a point p. The 3 columns are the x-, y- and z-coordinate \n");
762 descr += mystr(" \\item trans: Vector of translation, 3 dimensions! \n");
763 descr += mystr(" \\item rot: rotation matrix (3x3), can be used for scaling as well as rotation \n");
764 descr += mystr("\\end{enumerate} \n");
765 descr += mystr("-"); //DR hack, to avoid bugs in latex
766
767 return descr;
768 };
769
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)770 int CEDC_ComTransformPoints::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
771 {
772 ElementDataContainer* edcpoints = parameter_EDCs(1); //the points that should be transformed
773 ElementDataContainer* edcvec = parameter_EDCs(2); //translation
774 ElementDataContainer* edcMat = parameter_EDCs(3); //rotation matrix
775
776 int nRows = 0;
777 int nCols = 3;
778 double * p;
779
780 ElementData* edp = edcMat->GetPtr(1);
781 p = edp->GetMatrix();
782 nRows = edp->GetMatrixRows();
783 Matrix rotation(nRows,nCols,p);
784
785 edp = edcpoints->GetPtr(1);
786 p = edp->GetMatrix();
787 nRows = edp->GetMatrixRows();
788 Matrix points(nRows,nCols,p);
789
790 Matrix new_points;
791 new_points.SetSize(nRows,nCols);
792
793 Vector3D translation;
794 edp = edcvec->GetPtr(1);
795 edp->GetVector(translation.X(),translation.Y(),translation.Z());
796
797 Vector3D help;
798 for (int i=1; i<=nRows; i++)
799 {
800 help = Vector3D(points(i,1),points(i,2),points(i,3));
801 help = translation + rotation*help;
802 new_points(i,1)=help.X();
803 new_points(i,2)=help.Y();
804 new_points(i,3)=help.Z();
805 }
806
807 return_value.SetMatrix(new_points.GetMatPtr(),new_points.Getrows(),new_points.Getcols(),"points");
808
809 int rv = 1;
810 return rv;
811 }
812
813 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
814 //$ DR 2013-07-04
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)815 int CEDC_ComLoadVecFromFile::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
816 {
817 ElementDataContainer* edc = parameter_EDCs(1);
818 mystr filename;
819 if(edc->Get(1).IsText())
820 {
821 filename = edc->Get(1).GetText();
822 }
823 else
824 {
825 filename = edc->TreeGetString("parameter1");
826 }
827 edcParser->MakeFilenameAbsolute(filename);
828
829 edc = parameter_EDCs(2);
830 mystr tmp;
831 int col = 0;
832 if(edc->Get(1).IsDouble())
833 {
834 col = edc->Get(1).GetDouble();
835 }
836 else if(edc->Get(1).IsInt())
837 {
838 col = edc->Get(1).GetInt();
839 }
840 else
841 {
842 tmp = edc->TreeGetString("parameter2");
843 }
844
845 if(tmp.IsValidNumber())
846 {
847 col = tmp.MakeInt();
848 }
849 else
850 {
851 if(col<=0)
852 {
853 edcParser->EDCError("Error while executing command 'LoadVectorFromFile': 2nd parameter has to be an integer!\n");
854 }
855 }
856
857 ElementDataContainer edc_rv;
858 int rv = mbs->LoadVectorFromFile(filename, col, &edc_rv);
859 if(rv)
860 {
861 double* vptr;
862 int len;
863 edc_rv.TreeGetVector("Vector",&vptr,len);
864 return_value.SetVector(vptr,len,"vector");
865 }
866 else
867 {
868 edcParser->EDCError("Error while executing command 'LoadVectorFromFile': could not read file!\n");
869 }
870 return rv;
871 }
872
GetCommandTexParameterDescription() const873 mystr CEDC_ComLoadVecFromFile::GetCommandTexParameterDescription() const
874 {
875 mystr descr = mystr("The parameters of this command are \n");
876 descr += mystr("\\begin{enumerate} \n");
877 descr += mystr(" \\item The name of the file as string\n");
878 descr += mystr(" \\item An integer defining in which column of the file the vector is stored\n");
879 descr += mystr("\\end{enumerate} \n");
880 descr += mystr("-"); //DR hack, to avoid bugs in latex
881
882 return descr;
883 };
884
885 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
886 //$ AD 2013-07-11
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)887 int CEDC_ComSum::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
888 {
889 ElementDataContainer* summand1 = parameter_EDCs(1); // first summand
890 ElementDataContainer* summand2 = parameter_EDCs(2); // second summand
891 ElementData *edp1, *edp2;
892
893 edp1 = summand1->GetPtr(1);
894 edp2 = summand2->GetPtr(1);
895
896 int rv = 1;
897 // scalar+scalar
898 if (edp1->IsDouble() && edp2->IsDouble())
899 {
900 double s1 = edp1->GetDouble();
901 double s2 = edp2->GetDouble();
902 return_value.SetDouble(s1+s2,"sum");
903 }
904 // vector+vector
905 else if (edp1->IsVector() && edp2->IsVector())
906 {
907 int l1 = edp1->GetVectorLen();
908 int l2 = edp2->GetVectorLen();
909 if(l1==l2)
910 {
911 Vector v1,v2;
912 v1.LinkWith(edp1->GetVector(),l1);
913 v2.LinkWith(edp2->GetVector(),l2);
914
915 //+++++++++++++++++++++++++++++++++++++++++++
916 Vector res = v1+v2; //internal representation of command
917 //+++++++++++++++++++++++++++++++++++++++++++
918
919 return_value.SetVector(res.GetVecPtr(), res.GetLen(), "sum");
920 }
921 else
922 {
923 edcParser->EDCError("Error while executing command 'Add': adding two vectors of different length\n");
924 }
925 }
926 // matrix + matrix ( this includes Vector Transposed )
927 else if (edp1->IsMatrix() && edp2->IsMatrix())
928 {
929 int r1 = edp1->GetMatrixRows();
930 int r2 = edp2->GetMatrixRows();
931 int c1 = edp1->GetMatrixCols();
932 int c2 = edp2->GetMatrixCols();
933
934 if(r1==r2 && c1==c2)
935 {
936 Matrix m1(r1, c1, edp1->GetMatrix());
937 Matrix m2(r2, c2, edp2->GetMatrix());
938
939 //+++++++++++++++++++++++++++++++++++++++++++
940 Matrix res = m1+m2; //internal representation of command
941 //+++++++++++++++++++++++++++++++++++++++++++
942
943 return_value.SetMatrix(res.GetMatPtr(), res.Getrows(), res.Getcols(), "sum");
944 }
945 else
946 {
947 edcParser->EDCError("Error while executing command 'Add': adding two matrixes of different length\n");
948 }
949 }
950 else
951 {
952 edcParser->EDCError("Error while executing command 'Add': cannot add different types of scalar/vector/matrix\n");
953 }
954 return rv;
955 }
956
GetCommandTexParameterDescription() const957 mystr CEDC_ComSum::GetCommandTexParameterDescription() const
958 {
959 mystr descr = mystr("The parameters of this command are \n");
960 descr += mystr("\\begin{enumerate} \n");
961 descr += mystr(" \\item $1^{st}$ summand, either scalar, vector or matrix \n");
962 descr += mystr(" \\item $2^{nd}$ summand, either scalar, vector or matrix \n");
963 descr += mystr("\\end{enumerate} \n");
964 descr += mystr("-"); //DR hack, to avoid bugs in latex
965
966 return descr;
967 };
968
969 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
970 //$ AD 2013-07-11
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)971 int CEDC_ComProduct::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
972 {
973 ElementDataContainer* summand1 = parameter_EDCs(1); // first summand
974 ElementDataContainer* summand2 = parameter_EDCs(2); // second summand
975 ElementData *edp1, *edp2;
976
977 // when parameters are defined inline the parameter EDC contains text.
978 if(summand1->GetPtr(1)->IsText())
979 EvaluateTextualParameterEntry(mbs, edcParser, summand1);
980 if(summand2->GetPtr(1)->IsText())
981 EvaluateTextualParameterEntry(mbs, edcParser, summand2);
982
983 edp1 = summand1->GetPtr(1);
984 edp2 = summand2->GetPtr(1);
985
986
987 int rv = 1;
988 // involving a scalar: {s*s, s*v, s*m, v*s, m*s}
989 if (edp1->IsDouble() || edp2->IsDouble())
990 {
991 double s;
992 ElementData *any;
993 if (edp1->IsDouble())
994 {
995 s = edp1->GetDouble();
996 any = edp2;
997 }
998 else
999 {
1000 s = edp2->GetDouble();
1001 any = edp1;
1002 }
1003
1004 if(any->IsDouble()) //s*s
1005 {
1006 double r = any->GetDouble();
1007 return_value.SetDouble(s*r,"product");
1008 }
1009 else //s*v, s*m,
1010 {
1011 if(any->IsVector())
1012 {
1013 Vector V;
1014 V.LinkWith(any->GetVector(),any->GetVectorLen());
1015
1016 //+++++++++++++++++++++++++++++++++++++++++++
1017 Vector res = V*s; //internal representation of command
1018 //+++++++++++++++++++++++++++++++++++++++++++
1019
1020 return_value.SetVector(res.GetVecPtr(), res.GetLen(), "product");
1021 }
1022 else
1023 {
1024 Matrix M(any->GetMatrixRows(), any->GetMatrixCols(), any->GetMatrix());
1025
1026 //+++++++++++++++++++++++++++++++++++++++++++
1027 Matrix res = M*s; //internal representation of command
1028 //+++++++++++++++++++++++++++++++++++++++++++
1029
1030 return_value.SetMatrix(res.GetMatPtr(), res.Getrows(), res.Getcols(), "product");
1031 }
1032 }
1033 }
1034 // involving only vector and matrix: {v*v, v*m, m*v, m*m}
1035 else
1036 {
1037 Vector V1,V2;
1038 Matrix M1,M2;
1039
1040 //left factor
1041 if(edp1->IsVector())
1042 {
1043 V1.LinkWith(edp1->GetVector(), edp1->GetVectorLen());
1044 }
1045 else if(edp1->IsMatrix())
1046 {
1047 M1 = Matrix(edp1->GetMatrixRows(),edp1->GetMatrixCols(),edp1->GetMatrix());
1048 }
1049 else
1050 {
1051 edcParser->EDCError("Error while executing command 'Product': first factor neither scalar nor vector nor matrix \n");
1052 }
1053 // right factor
1054 if(edp2->IsVector())
1055 {
1056 V2.LinkWith(edp2->GetVector(), edp2->GetVectorLen());
1057 }
1058 else if(edp2->IsMatrix())
1059 {
1060 M2 = Matrix(edp2->GetMatrixRows(),edp2->GetMatrixCols(),edp2->GetMatrix());
1061 }
1062 else
1063 {
1064 edcParser->EDCError("Error while executing command 'Product': second factor neither scalar nor vector nor matrix \n");
1065 }
1066
1067 // compute the product
1068 // case m*m = m --> matrix product
1069 if(edp1->IsMatrix()&&edp2->IsMatrix())
1070 {
1071 if(M1.Getcols() == M2.Getrows())
1072 {
1073 //+++++++++++++++++++++++++++++++++++++++++++
1074 //internal representation of command
1075 Matrix res;
1076 Mult(M1,M2,res);
1077 //+++++++++++++++++++++++++++++++++++++++++++
1078 return_value.SetMatrix(res.GetMatPtr(), res.Getrows(), res.Getcols(), "product");
1079 }
1080 else
1081 {
1082 edcParser->EDCError("Error while executing command 'Product': dimension check failed - number of columns in left factor must be equal to number of rows in right factor \n");
1083 }
1084 }
1085 // case v*m = v --> matrix product
1086 else if(edp1->IsVector()&&edp2->IsMatrix())
1087 {
1088 if(V1.GetLen() == M2.Getrows())
1089 {
1090 //+++++++++++++++++++++++++++++++++++++++++++
1091 //internal representation of command
1092 Vector res;
1093 Mult(V1,M2,res);
1094 //+++++++++++++++++++++++++++++++++++++++++++
1095 return_value.SetVector(res.GetVecPtr(), res.GetLen(), "product");
1096 }
1097 else
1098 {
1099 edcParser->EDCError("Error while executing command 'Product': dimension check failed - number of columns in left factor must be equal to number of rows in right factor \n");
1100 }
1101 }
1102
1103 //! AD: !!! MAYBE TAKE THESE CASES OUT !!! more commands eg transpose(), scalarproduct()
1104 // case v*v =s -> scalar product
1105 else if(edp1->IsVector()&&edp2->IsVector())
1106 {
1107 //$ AD: warning removed, now in docu
1108 //edcParser->EDCError("WARNING: multiplying two (row-)vectors is autmatically assumed to compute the scalar product of the two vectors \n");
1109 if(V1.GetLen() == V2.GetLen())
1110 {
1111 double scalarproduct = 0;
1112 for(int i=1; i<=V1.GetLen(); i++)
1113 {
1114 scalarproduct += ( V1(i)*V2(i) );
1115 }
1116 return_value.SetDouble(scalarproduct,"product");
1117 }
1118 else
1119 {
1120 edcParser->EDCError("Error while executing command 'Product': factors (vector) must have same length \n");
1121 }
1122 }
1123 // case m*v --> m*vT=vT
1124 else if(edp1->IsMatrix()&&edp2->IsVector())
1125 {
1126 //$ AD: warning removed, now in docu
1127 //edcParser->EDCError("WARNING: multiplying a matrix with a (row-)vector is autmatically assumed to compute the product with the transposed vector \n");
1128 if(M1.Getcols() == V2.GetLen())
1129 {
1130 //+++++++++++++++++++++++++++++++++++++++++++
1131 //internal representation of command
1132 Vector res;
1133 Mult(M1,V2,res);
1134 //+++++++++++++++++++++++++++++++++++++++++++
1135 return_value.SetMatrix(res.GetVecPtr(), res.GetLen(), 1, "product");
1136 }
1137 else
1138 {
1139 edcParser->EDCError("Error while executing command 'Product': dimension check failed - number of columns in left factor must be equal to number of rows in right factor \n");
1140 }
1141 }
1142 else
1143 {
1144 edcParser->EDCError("Error while executing command 'Product': dimension check failed - number of columns in left factor must be equal to number of rows in right factor \n");
1145 }
1146 }
1147 return rv;
1148 }
1149
GetCommandTexParameterDescription() const1150 mystr CEDC_ComProduct::GetCommandTexParameterDescription() const
1151 {
1152 mystr descr = mystr("The parameters of this command are \n");
1153 descr += mystr("\\begin{enumerate} \n");
1154 descr += mystr(" \\item $1^{st}$ factor, either scalar, vector or matrix \n");
1155 descr += mystr(" \\item $2^{nd}$ factor, either scalar, vector or matrix \n");
1156 descr += mystr("\\end{enumerate} \n");
1157 descr += mystr(" product of two vectors is always computed as scalar product \n");
1158 descr += mystr(" for vector times Matrix the vector is automatically transposed if required \n");
1159 descr += mystr("-"); //DR hack, to avoid bugs in latex
1160 return descr;
1161 };
1162
1163 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1164 //$ AD 2013-07-11
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1165 int CEDC_ComTranspose::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1166 {
1167 ElementDataContainer* edc1 = parameter_EDCs(1); // sole input
1168 ElementData *edp1;
1169 edp1 = edc1->GetPtr(1);
1170
1171 int rv = 1;
1172 // transpose a vector -> vT is a matrix
1173 if (edp1->IsVector())
1174 {
1175 Vector V;
1176 V.LinkWith(edp1->GetVector(), edp1->GetVectorLen());;
1177 //+++++++++++++++++++++++++++++++++++++++++++
1178 //internal representation of command
1179 Matrix res(V.GetLen(), 1, V.GetVecPtr());
1180 //+++++++++++++++++++++++++++++++++++++++++++
1181 return_value.SetMatrix(res.GetMatPtr(), res.Getrows(), res.Getcols(), "transposed");
1182 }
1183 else if (edp1->IsMatrix())
1184 {
1185 Matrix M(edp1->GetMatrixRows(),edp1->GetMatrixCols(),edp1->GetMatrix());
1186 //+++++++++++++++++++++++++++++++++++++++++++
1187 //internal representation of command
1188 Matrix res = M.GetTp();
1189 //+++++++++++++++++++++++++++++++++++++++++++
1190 if(res.Getrows() == 1)
1191 {
1192 // this is actually a vector ...
1193 return_value.SetVector(res.GetMatPtr(), res.Getcols(), "product");
1194 }
1195 else
1196 {
1197 return_value.SetMatrix(res.GetMatPtr(), res.Getrows(), res.Getcols(), "product");
1198 }
1199 }
1200 else
1201 {
1202 edcParser->EDCError("Error while executing command 'Transpose': only vectors and matrices can be transposed\n");
1203 }
1204 return rv;
1205 }
1206
GetCommandTexParameterDescription() const1207 mystr CEDC_ComTranspose::GetCommandTexParameterDescription() const
1208 {
1209 mystr descr = mystr("The parameters of this command are \n");
1210 descr += mystr("\\begin{enumerate} \n");
1211 descr += mystr(" \\item vector or matrix to be transposed\n");
1212 descr += mystr("\\end{enumerate} \n");
1213 descr += mystr("-"); //DR hack, to avoid bugs in latex
1214
1215 return descr;
1216 };
1217
1218 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1219 //$ AD 2013-07-11
1220 //$! AD 2013-07-15 commented out Class Scalar product for the time being, functionality is in ComProduct...
1221
1222 ////int CEDC_ComScalarProduct::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1223 ////{
1224 //// ElementDataContainer* summand1 = parameter_EDCs(1); // first summand
1225 //// ElementDataContainer* summand2 = parameter_EDCs(2); // second summand
1226 //// ElementData *edp1, *edp2;
1227 ////
1228 //// edp1 = summand1->GetPtr(1);
1229 //// edp2 = summand2->GetPtr(1);
1230 ////
1231 //// int rv = 1;
1232 //// if(edp1->IsVector()&&edp2->IsVector())
1233 //// {
1234 //// Vector V1,V2;
1235 //// V1.LinkWith(edp1->GetVector(), edp1->GetVectorLen());
1236 //// V2.LinkWith(edp2->GetVector(), edp2->GetVectorLen());
1237 ////
1238 //// if(V1.GetLen() == V2.GetLen())
1239 //// {
1240 //// double scalarproduct = 0;
1241 //// for(int i=1; i<=V1.GetLen(); i++)
1242 //// {
1243 //// scalarproduct += ( V1(i)*V2(i) );
1244 //// }
1245 //// return_value.SetDouble(scalarproduct,"product");
1246 //// }
1247 //// else
1248 //// {
1249 //// edcParser->EDCError("Error while executing command 'ScalarProduct': vectors must have same length \n");
1250 //// }
1251 //// }
1252 //// else
1253 //// {
1254 //// edcParser->EDCError("Error while executing command 'ScalarProduct': scalar product only defined for two vectors\n");
1255 //// }
1256 //// return rv;
1257 ////}
1258 ////
1259 ////mystr CEDC_ComScalarProduct::GetCommandTexParameterDescription() const
1260 ////{
1261 //// mystr descr = mystr("The parameters of this command are \n");
1262 //// descr += mystr("\\begin{enumerate} \n");
1263 //// descr += mystr(" \\item 1^{st} vector \n");
1264 //// descr += mystr(" \\item 2^{nd} vector \n");
1265 //// descr += mystr("\\end{enumerate} \n");
1266 //// descr += mystr("-"); //DR hack, to avoid bugs in latex
1267 ////
1268 //// return descr;
1269 ////};
1270
1271 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1272 //$ AD 2013-07-11
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1273 int CEDC_ComCrossProduct::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1274 {
1275 ElementDataContainer* summand1 = parameter_EDCs(1); // first summand
1276 ElementDataContainer* summand2 = parameter_EDCs(2); // second summand
1277 ElementData *edp1, *edp2;
1278
1279 edp1 = summand1->GetPtr(1);
1280 edp2 = summand2->GetPtr(1);
1281
1282 int rv = 1;
1283 if(edp1->IsVector()&&edp2->IsVector())
1284 {
1285 Vector V1,V2;
1286 V1.LinkWith(edp1->GetVector(), edp1->GetVectorLen());
1287 V2.LinkWith(edp2->GetVector(), edp2->GetVectorLen());
1288
1289 if(V1.GetLen() == V2.GetLen() && (V1.GetLen() == 3 || V1.GetLen() == 2) ) // allow 3Dx3D and 2Dx2D
1290 {
1291 Vector3D v1,v2;
1292 if(V1.GetLen() == 2)
1293 {
1294 v1 = Vector3D(V1(1), V1(2), 0.);
1295 v2 = Vector3D(V2(1), V2(2), 0.);
1296 }
1297 else
1298 {
1299 v1 = Vector3D(V1(1), V1(2), V1(3));
1300 v2 = Vector3D(V2(1), V2(2), V2(3));
1301 }
1302
1303 //+++++++++++++++++++++++++++++++++++++++++++
1304 //internal representation of command
1305 Vector3D res = v1.Cross(v2);
1306 //+++++++++++++++++++++++++++++++++++++++++++
1307 if(V1.GetLen() == 3)
1308 {
1309 return_value.SetVector(res.GetVecPtr(), 3, "crossproduct"); // return 3D Vector 3Dx3D -> 3D
1310 }
1311 else if(V1.GetLen() == 2)
1312 {
1313 return_value.SetDouble(res(3), "crossproduct"); // return scalar 2Dx2D -> scalar
1314 }
1315 }
1316 else
1317 {
1318 edcParser->EDCError("Error while executing command 'CrossProduct': vectors must have same length (2D or 3D)\n");
1319 }
1320 }
1321 else
1322 {
1323 edcParser->EDCError("Error while executing command 'CrossProduct': scalar product only defined for two vectors\n");
1324 }
1325 return rv;
1326 }
1327
GetCommandTexParameterDescription() const1328 mystr CEDC_ComCrossProduct::GetCommandTexParameterDescription() const
1329 {
1330 mystr descr = mystr("The parameters of this command are \n");
1331 descr += mystr("\\begin{enumerate} \n");
1332 descr += mystr(" \\item $1^{st}$ vector (2D or 3D)\n");
1333 descr += mystr(" \\item $2^{nd}$ vector (2D or 3D)\n");
1334 descr += mystr("\\end{enumerate} \n");
1335 descr += mystr("for two 3D vectors the retuen value is also a 3D vector. For two 2D vectors the return value is a scalar.\n");
1336 descr += mystr("-"); //DR hack, to avoid bugs in latex
1337
1338 return descr;
1339 };
1340
1341 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1342 //$ AD 2013-09-13
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1343 int CEDC_ComFor::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1344 {
1345 int rv = 0;
1346
1347 ElementData* ED_loop_init = parameter_EDCs(1)->GetPtr(1);
1348 ElementData* ED_loop_cond = parameter_EDCs(2)->GetPtr(1);
1349 ElementData* ED_loop_incr = parameter_EDCs(3)->GetPtr(1);
1350 ElementData* ED_loop_code = parameter_EDCs(4)->GetPtr(1);
1351
1352 int err = 0;
1353 int suc = 1;
1354
1355 // CHECK PARAMETERS:
1356 // parameter 1: loop initialization
1357 mystr str_loop_init;
1358 if(ED_loop_init->IsText())
1359 {
1360 str_loop_init = ED_loop_init->GetText();
1361 }
1362 else
1363 {
1364 edcParser->EDCError("Error while executing FOR loop: first parameter is not a text (loop initialization)");
1365 return rv;
1366 }
1367 // parameter 2: loop condition
1368 mystr str_loop_cond;
1369 if(ED_loop_cond->IsText())
1370 {
1371 str_loop_cond = ED_loop_cond->GetText();
1372 }
1373 else
1374 {
1375 edcParser->EDCError("Error while executing FOR loop: second parameter is not a text (loop condition)");
1376 return rv;
1377 }
1378 // parameter 3: loop increment
1379 mystr str_loop_incr;
1380 if(ED_loop_incr->IsText())
1381 {
1382 str_loop_incr = ED_loop_incr->GetText();
1383 }
1384 else
1385 {
1386 edcParser->EDCError("Error while executing FOR loop: third parameter is not a text (loop increment)");
1387 return rv;
1388 }
1389
1390 // parameter 4: loop code
1391 mystr str_loop_code;
1392 if(ED_loop_code->IsText())
1393 {
1394 str_loop_code = ED_loop_code->GetText();
1395 }
1396 else
1397 {
1398 edcParser->EDCError("Error while executing FOR loop: loop code is to text (text in brackets required)");
1399 return rv;
1400 }
1401
1402 // the actual FOR Loop
1403
1404 // initialize local loop variable container
1405 ElementDataContainer& localEDC = *(edcParser->GetMBSParser()->GetLocalEDC()); // existing local EDC for the FOR command ("outside" the FOR command)
1406
1407 // initialize the loop variable
1408 suc = edcParser->ParseAndExecuteString(str_loop_init, localEDC);
1409 if(!suc)
1410 {
1411 edcParser->EDCError("Error while executing FOR loop: first parameter could not be translated to a loop initialization statement (\"i=1\")");
1412 return rv;
1413 }
1414
1415
1416 // loop condition 1st time
1417 int flag_loop_condition = (int) (edcParser->GetMBSParser()->ExpressionToDouble(str_loop_cond,err)+0.5); // loop condition
1418
1419 while(flag_loop_condition)
1420 {
1421 // execute loop code
1422 suc = edcParser->ParseAndExecuteString(str_loop_code, localEDC);
1423 if(!suc)
1424 {
1425 edcParser->EDCError("Error while executing FOR loop: failed to execute loop code)");
1426 return rv;
1427 }
1428 rv++;
1429
1430 // increment
1431 suc = edcParser->ParseAndExecuteString(str_loop_incr, localEDC);
1432
1433 // condition
1434 flag_loop_condition = (int) (edcParser->GetMBSParser()->ExpressionToDouble(str_loop_cond,err)+0.5);
1435 }
1436
1437 return rv;
1438 }
1439
GetCommandTexParameterDescription() const1440 mystr CEDC_ComFor::GetCommandTexParameterDescription() const
1441 {
1442 mystr descr = mystr("The parameters of this command are \n");
1443 descr += mystr("\\begin{enumerate} \n");
1444 descr += mystr(" \\item $1^{st}$ define and initialize loop variable (\"i=1\")\n");
1445 descr += mystr(" \\item $2^{nd}$ loop condition (\"i<5\")\n");
1446 descr += mystr(" \\item $3^{rd}$ loop increment (\"i=i+1\")\n");
1447 descr += mystr("\\end{enumerate} \n");
1448 descr += mystr("the command must be followed by a container for the loop code \n");
1449 descr += mystr("-"); //DR hack, to avoid bugs in latex
1450 return descr;
1451 };
1452 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1453
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1454 int CEDC_ComIf::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1455 {
1456 int rv = 0;
1457
1458 ElementData* ED_loop_cond = parameter_EDCs(1)->GetPtr(1);
1459 ElementData* ED_loop_code = parameter_EDCs(2)->GetPtr(1);
1460
1461 int err = 0;
1462 int suc = 1;
1463
1464 // CHECK PARAMETERS:
1465 // parameter 1: loop condition
1466 mystr str_loop_cond;
1467 if(ED_loop_cond->IsText())
1468 {
1469 str_loop_cond = ED_loop_cond->GetText();
1470 }
1471 else
1472 {
1473 edcParser->EDCError("Error while executing IF condition: second parameter is not a text (loop condition)");
1474 return rv;
1475 }
1476 // parameter 2: loop code
1477 mystr str_loop_code;
1478 if(ED_loop_code->IsText())
1479 {
1480 str_loop_code = ED_loop_code->GetText();
1481 }
1482 else
1483 {
1484 edcParser->EDCError("Error while executing IF condition: loop code is to text (text in brackets required)");
1485 return rv;
1486 }
1487
1488 // the actual IF condition
1489
1490 // initialize local loop variable container
1491 ElementDataContainer& localEDC = *(edcParser->GetMBSParser()->GetLocalEDC()); // existing local EDC for the IF command ("outside" the IF command)
1492
1493 // loop condition 1st time
1494 int flag_loop_condition = (int) (edcParser->GetMBSParser()->ExpressionToDouble(str_loop_cond,err)+0.5); // loop condition
1495
1496 if(flag_loop_condition)
1497 {
1498 // execute conditional code
1499 suc = edcParser->ParseAndExecuteString(str_loop_code, localEDC);
1500 }
1501 return flag_loop_condition;
1502 /*return rv;*/
1503 }
1504
GetCommandTexParameterDescription() const1505 mystr CEDC_ComIf::GetCommandTexParameterDescription() const
1506 {
1507 mystr descr = mystr("The parameters of this command are \n");
1508 descr += mystr("\\begin{enumerate} \n");
1509 descr += mystr(" \\item $1^{st}$ condition (\"i<10\")\n");
1510 descr += mystr("\\end{enumerate} \n");
1511 descr += mystr("the command must be followed by a container for the conditional code \n");
1512 descr += mystr("-"); //DR hack, to avoid bugs in latex
1513 return descr;
1514 };
1515 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1516
1517 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1518 //$ AD 2013-10-09
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1519 int CEDC_ComMesh_GenerateNewMesh::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1520 {
1521 int rv = 0;
1522 // MESH PROPERTIES
1523 // Default values for a MeshHandle
1524 // * this is to be autogenerated at a later time
1525 ElementDataContainer edc_meshproperties;
1526 ElementData ed;
1527 // why cant bool be locked ?
1528 ed.SetBool(1,"isHandle"); ed.SetLocked(1); ed.SetToolTipText("This Container represents a Handle. Commands may be executed for this object");
1529 edc_meshproperties.Add(ed);
1530 ed.SetText("generates discretized Beams","GenerateBeam"); ed.SetLocked(1); ed.SetToolTipText("This Command is registerd for this handle");
1531 edc_meshproperties.TreeAdd("Functions",ed);
1532 ed.SetText("generates discretized Plates","GeneratePlate"); ed.SetLocked(1); ed.SetToolTipText("This Command is registerd for this handle");
1533 edc_meshproperties.TreeAdd("Functions",ed);
1534 ed.SetText("remove redundant nodes or create constraints","GlueMesh"); ed.SetLocked(1); ed.SetToolTipText("This Command is registerd for this handle");
1535 edc_meshproperties.TreeAdd("Functions",ed);
1536 ed.SetText("returns nodes in the defined box","GetNodesInBox"); ed.SetLocked(1); ed.SetToolTipText("This Command is registerd for this handle");
1537 edc_meshproperties.TreeAdd("Functions",ed);
1538
1539 // Overwrite defaults with input from container 1
1540 ElementDataContainer* edc_override = parameter_EDCs(1);
1541 edc_meshproperties.TreeReplaceEDCDataWith(edc_override);
1542
1543 // TODO for script compatible mesh class
1544 // add a new MeshElement to the MBS
1545
1546 // MESH OBJECT AND VARIABLES
1547 // * this is to be replaced by members of the script compatible mesh class
1548 double dummy = 0;
1549 ed.SetVector(&dummy, 0, "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Mesh or empty");
1550 edc_meshproperties.Add(ed);
1551 ed.SetVector(&dummy, 0, "list_of_elements"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Elements associated with the Mesh or empty");
1552 edc_meshproperties.Add(ed);
1553 ed.SetVector(&dummy, 0, "list_of_redundant_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of redundant nodes in the mesh");
1554 edc_meshproperties.Add(ed);
1555
1556 return_value.SetEDC(&edc_meshproperties,"MeshProperties");
1557
1558 return 1;
1559 }
1560
1561
GetCommandTexParameterDescription() const1562 mystr CEDC_ComMesh_GenerateNewMesh::GetCommandTexParameterDescription() const
1563 {
1564 mystr descr = mystr("The parameters of this command are \n");
1565 descr += mystr("\\begin{enumerate} \n");
1566 descr += mystr(" \\item $1^{st}$ parameter EDC to overwrite the default properties\n");
1567 descr += mystr("\\end{enumerate} \n");
1568 descr += mystr("the return vaule of the command MUST be assigned to a new variable(handle) \n\n");
1569 descr += mystr("overwritable enties in the properties EDC are: \n");
1570 descr += mystr("\\begin{itemize} \n");
1571 descr += mystr(" \\item ... \n");
1572 descr += mystr("\\end{itemize} \n");
1573 descr += mystr("-"); //DR hack, to avoid bugs in latex
1574 return descr;
1575 };
1576
1577 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1578 int CEDC_ComMesh_GenerateBeam::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1579 {
1580 int rv = 0;
1581 ElementDataContainer edc_rv;
1582
1583 // Default values for a BeamParameters
1584 // * this is to be autogenerated at a later time
1585 ElementDataContainer edc_beamparameters;
1586 ElementData ed;
1587 ed.SetVector3D(0.,0.,0.,"P1"); edc_beamparameters.Add(ed);
1588 ed.SetVector3D(1.,0.,0.,"P2"); edc_beamparameters.Add(ed);
1589 ed.SetInt(1,"matnr"); edc_beamparameters.Add(ed);
1590 ed.SetInt(1,"discretization"); edc_beamparameters.Add(ed);
1591 ed.SetText("LinearBeam3D","element_type"); edc_beamparameters.Add(ed);
1592 ed.SetText("Node3DRxyz","node_type"); edc_beamparameters.Add(ed);
1593
1594 // Overwrite defaults with input from container 1
1595 ElementDataContainer* edc_override = parameter_EDCs(1);
1596 edc_beamparameters.TreeReplaceEDCDataWith(edc_override);
1597
1598 // container 2 contains the name of the handle ( can not pass the EDC* itself because that is going to be deleted... )
1599 // consistency already checked in ParseCommandParameters...
1600 mystr handlename = parameter_EDCs(2)->TreeGetString("handle");
1601 ElementDataContainer* edc_local = edcParser->GetMBSParser()->GetLocalEDC();
1602 int nr_handle = edc_local->Find(handlename);
1603 ElementDataContainer* edc_handle_mesh = edc_local->Get(nr_handle).GetEDC();
1604
1605
1606 // Actual Generation of BeamElements - to be a function of the MeshElement
1607 // read geometry parameters
1608 Vector3D p1,p2;
1609 edc_beamparameters.TreeGetVector3D("P1",p1.X(), p1.Y(), p1.Z());
1610 edc_beamparameters.TreeGetVector3D("P2",p2.X(), p2.Y(), p2.Z());
1611 int matnr = edc_beamparameters.TreeGetInt("matnr");
1612 int discr = edc_beamparameters.TreeGetInt("discretization");
1613
1614 // when more then one type of element is implemented, perform a type check
1615 mystr elem_type = edc_beamparameters.TreeGetString("element_type");
1616 mystr node_type = edc_beamparameters.TreeGetString("node_type");
1617
1618 // get current lists for mesh object
1619 double* vdata;
1620 int vlen;
1621 edc_handle_mesh->TreeGetVector("list_of_nodes",&vdata,vlen);
1622 TArray<double> mesh_nnrs; mesh_nnrs.CopyFrom(vdata,vlen); mesh_nnrs.SetLen(vlen); // node numbers already associated with the Mesh
1623 edc_handle_mesh->TreeGetVector("list_of_elements",&vdata,vlen);
1624 TArray<double> mesh_enrs; mesh_enrs.CopyFrom(vdata,vlen); mesh_enrs.SetLen(vlen); // element numbers already associated with the Mesh
1625
1626 // *******************
1627 // GENERATION OF NODES
1628
1629 // use existing script command AddNode
1630 mystr commandname("AddNode");
1631 int nparam, hasretval, c_option;
1632 CEDC_Command* command_addnode = edcParser->GetCommand( edcParser->GetCommandType(commandname, nparam, hasretval, c_option) );
1633
1634 // prepare EDC to be able to use existing script commands
1635 ElementDataContainer edc_nodeproperties;
1636 TArray<ElementDataContainer*> paramEDCforNode;
1637 paramEDCforNode.Add(&edc_nodeproperties);
1638 ed.SetText(node_type,"node_type"); edc_nodeproperties.Add(ed);
1639
1640 // todo: automatically compute orientation for all nodes - depending on node_type ...
1641 // Node3DRxyz
1642 Vector3D p12 = p2-p1;
1643 double pyth_xy= pow((p12.X()*p12.X()+p12.Y()*p12.Y()),(.5));
1644
1645 double roll = 0;
1646 double pitch = atan2(p12.Y(), p12.X());
1647 double yaw = atan2(p12.Z(), pyth_xy);
1648 ed.SetVector3D(roll,-yaw,pitch,"reference_rot_angles"); edc_nodeproperties.TreeAdd("Geometry",ed);
1649
1650
1651 // override discretization if entry element_size is present
1652 int j = edc_beamparameters.Find("element_size");
1653 if (j != 0 && edc_beamparameters.Get(j).IsDouble())
1654 {
1655 double elemsize = edc_beamparameters.TreeGetDouble("element_size");
1656 double total_length = p12.Norm();
1657 double required = total_length / elemsize;
1658 int discr_new = (int) ceil(required);
1659 discr = discr_new;
1660 }
1661
1662
1663 TArray<double> nnrs; // node numbers for the current call GenerateBeam
1664 for(int i=0; i<=discr; i++)
1665 {
1666 Vector3D pos = ( (discr-i)*p1 + i*p2 ) * (1./double(discr));
1667 ed.SetVector3D(pos.X(),pos.Y(),pos.Z(),"reference_position"); edc_nodeproperties.TreeAdd("Geometry",ed);
1668
1669 // call AddNode with prepared EDC, returnvalue is number of added node
1670 command_addnode->ExecuteCommand(mbs,edcParser,paramEDCforNode,ed,0);
1671
1672 nnrs.Add(ed.GetInt());
1673 }
1674 // return value:nodes from current generation function
1675 ed.SetVector( nnrs.GetDataPtr(), nnrs.Length(), "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Beam or empty");
1676 edc_rv.Add(ed);
1677 // update list_of_nodes in Mesh
1678 mesh_nnrs.Merge(nnrs);
1679 ed.SetVector( mesh_nnrs.GetDataPtr(), mesh_nnrs.Length(), "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Mesh or empty");
1680 ElementDataContainer update_nnrs; update_nnrs.Add(ed);
1681 edc_handle_mesh->TreeReplaceEDCDataWith(&update_nnrs);
1682
1683 // ***************************
1684 // GENERATION OF BEAM ELEMENTS
1685
1686 // use existing script command AddElement
1687 commandname = mystr("AddElement");
1688 CEDC_Command* command_addelement = edcParser->GetCommand( edcParser->GetCommandType(commandname, nparam, hasretval, c_option) );
1689
1690 // prepare EDC to be able to use existing script commands
1691 ElementDataContainer edc_elementproperties;
1692 ed.SetText(elem_type,"element_type"); edc_elementproperties.Add(ed);
1693 ed.SetInt(matnr,"material_number"); edc_elementproperties.TreeAdd("Physics",ed);
1694 TArray<ElementDataContainer*> paramEDCforElement;
1695 paramEDCforElement.Add(&edc_elementproperties);
1696
1697 TArray<double> enrs;
1698 for(int i=1; i<=discr; i++)
1699 {
1700 ed.SetInt(nnrs(i),"node_1"); edc_elementproperties.TreeAdd("Geometry",ed);
1701 ed.SetInt(nnrs(i+1),"node_2"); edc_elementproperties.TreeAdd("Geometry",ed);
1702
1703 // call AddElement with prepared EDC, returnvalue is number of added element
1704 command_addelement->ExecuteCommand(mbs,edcParser,paramEDCforElement,ed,0);
1705
1706 enrs.Add(ed.GetInt());
1707 }
1708
1709 // return value:nodes from current generation function
1710 ed.SetVector( enrs.GetDataPtr(), enrs.Length(), "list_of_elements"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Elements associated with the Beam or empty");
1711 edc_rv.Add(ed);
1712 // update list_of_nodes in Mesh
1713 mesh_enrs.Merge(enrs);
1714 ed.SetVector( mesh_enrs.GetDataPtr(), mesh_enrs.Length(), "list_of_elements"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Elements associated with the Mesh or empty");
1715 ElementDataContainer update_enrs; update_enrs.Add(ed);
1716 edc_handle_mesh->TreeReplaceEDCDataWith(&update_enrs);
1717
1718
1719 return_value.SetEDC(edc_rv.GetCopy(), "RV_Beam");
1720
1721 return 1;
1722 }
1723
GetCommandTexParameterDescription() const1724 mystr CEDC_ComMesh_GenerateBeam::GetCommandTexParameterDescription() const
1725 {
1726 mystr descr = mystr("The parameters of this command are \n");
1727 descr += mystr("\\begin{enumerate} \n");
1728 descr += mystr(" \\item $1^{st}$ parameter EDC containing the beam properties \n");
1729 descr += mystr("\\end{enumerate} \n");
1730 descr += mystr("enties in the properties EDC are: \n");
1731 descr += mystr("\\begin{itemize} \n");
1732 descr += mystr(" \\item P1 - position of left outer node \n");
1733 descr += mystr(" \\item P2 - position of right outer node \n");
1734 descr += mystr(" \\item matnr - number of the material to be used for the beam elements (Beam3DProperties) \n");
1735 descr += mystr(" \\item discretization - number of the beam elements \n");
1736 descr += mystr(" \\item elementsize - (optional) maximum element size ( if set has priority over discretization ) \n");
1737 descr += mystr("\\end{itemize} \n");
1738 descr += mystr("-"); //DR hack, to avoid bugs in latex
1739 return descr;
1740 };
1741
1742
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1743 int CEDC_ComMesh_GeneratePlate::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1744 {
1745 int rv = 0;
1746 ElementDataContainer edc_rv;
1747
1748 // Default values for a PlateParameters
1749 // * this is to be autogenerated at a later time
1750 ElementDataContainer edc_plateparameters;
1751 ElementData ed;
1752 ed.SetVector3D(0.,0.,0.,"P1"); edc_plateparameters.Add(ed);
1753 ed.SetVector3D(1.,0.,0.,"P2"); edc_plateparameters.Add(ed);
1754 ed.SetVector3D(0.,1.,0.,"P3"); edc_plateparameters.Add(ed);
1755 ed.SetInt(1,"matnr"); edc_plateparameters.Add(ed);
1756 ed.SetVector2D(1.,1.,"discretization"); ed.SetValuesInt(); edc_plateparameters.Add(ed);
1757
1758 ed.SetText("ANCFThinPlate3D","element_type"); edc_plateparameters.Add(ed);
1759 ed.SetText("Node3DS1S2","node_type"); edc_plateparameters.Add(ed);
1760 ed.SetBool(1, "nonlinear"); edc_plateparameters.Add(ed);
1761
1762 // Overwrite defaults with input from container 1
1763 ElementDataContainer* edc_override = parameter_EDCs(1);
1764 edc_plateparameters.TreeReplaceEDCDataWith(edc_override);
1765
1766 // container 2 contains the name of the handle ( can not pass the EDC* itself because that is going to be deleted... )
1767 // consistency already checked in ParseCommandParameters...
1768 mystr handlename = parameter_EDCs(2)->TreeGetString("handle");
1769 ElementDataContainer* edc_local = edcParser->GetMBSParser()->GetLocalEDC();
1770 int nr_handle = edc_local->Find(handlename);
1771 ElementDataContainer* edc_handle_mesh = edc_local->Get(nr_handle).GetEDC();
1772
1773
1774 // Actual Generation of PlateElements - to be a function of the MeshElement
1775 // read geometry parameters
1776 Vector3D p1,p2,p3;
1777 edc_plateparameters.TreeGetVector3D("P1",p1.X(), p1.Y(), p1.Z());
1778 edc_plateparameters.TreeGetVector3D("P2",p2.X(), p2.Y(), p2.Z());
1779 edc_plateparameters.TreeGetVector3D("P3",p3.X(), p3.Y(), p3.Z());
1780 int matnr = edc_plateparameters.TreeGetInt("matnr");
1781 double thickness = edc_plateparameters.TreeGetDouble("thickness");
1782 Vector2D discr;
1783 edc_plateparameters.TreeGetVector2D("discretization", discr.X(), discr.Y());
1784 int is_nonlinear = edc_plateparameters.TreeGetBool("nonlinear", 1);
1785
1786 TArray<double> loads;
1787 int i = edc_plateparameters.Find("load");
1788 if (i != 0)
1789 {
1790 int load = edc_plateparameters.TreeGetInt("load");
1791 if (load != 0)
1792 {
1793 loads.Add(load);
1794 }
1795 }
1796
1797 // when more then one type of element is implemented, perform a type check
1798 mystr elem_type = edc_plateparameters.TreeGetString("element_type");
1799 mystr node_type = edc_plateparameters.TreeGetString("node_type");
1800
1801 // get current lists for mesh object
1802 double* vdata;
1803 int vlen;
1804 edc_handle_mesh->TreeGetVector("list_of_nodes",&vdata,vlen);
1805 TArray<double> mesh_nnrs; mesh_nnrs.CopyFrom(vdata,vlen); mesh_nnrs.SetLen(vlen); // node numbers already associated with the Mesh
1806 edc_handle_mesh->TreeGetVector("list_of_elements",&vdata,vlen);
1807 TArray<double> mesh_enrs; mesh_enrs.CopyFrom(vdata,vlen); mesh_enrs.SetLen(vlen); // element numbers already associated with the Mesh
1808
1809 // *******************
1810
1811 // GENERATION OF NODES
1812
1813 // use existing script command AddNode
1814 mystr commandname("AddNode");
1815 int nparam, hasretval, c_option;
1816 CEDC_Command* command_addnode = edcParser->GetCommand( edcParser->GetCommandType(commandname, nparam, hasretval, c_option) );
1817
1818
1819 // prepare EDC to be able to use existing script commands
1820 ElementDataContainer edc_nodeproperties;
1821 TArray<ElementDataContainer*> paramEDCforNode;
1822 paramEDCforNode.Add(&edc_nodeproperties);
1823 ed.SetText(node_type,"node_type"); edc_nodeproperties.Add(ed);
1824
1825 // todo: automatically compute orientation for all nodes - depending on node_type ...
1826 Vector3D p12 = p2-p1; // e1 = p12/|p12|
1827 Vector3D p13 = p3-p1; // e2 = p13/|p13|
1828 Vector3D n(p12.Cross(p13)); // normal to the plane od the plate
1829
1830 Vector3D e1(p12); e1.Normalize();
1831 ed.SetVector3D(e1.X(), e1.Y(), e1.Z(), "reference_slope1"); edc_nodeproperties.TreeAdd("Geometry",ed);
1832 Vector3D e2(p13); e2.Normalize();
1833 ed.SetVector3D(e2.X(), e2.Y(), e2.Z(), "reference_slope2"); edc_nodeproperties.TreeAdd("Geometry",ed);
1834
1835 // override discretization if entry element_size is present
1836 int j = edc_plateparameters.Find("element_size");
1837 if (j != 0 && edc_plateparameters.Get(j).IsVector())
1838 {
1839 Vector2D elemsize;
1840 edc_plateparameters.TreeGetVector2D("element_size",elemsize.X(), elemsize.Y());
1841 double total_length, required;
1842 total_length = p12.Norm();
1843 required = total_length / elemsize.X();
1844 discr.X() = ceil(required);
1845 total_length = p13.Norm();
1846 required = total_length / elemsize.Y();
1847 discr.Y() = ceil(required);
1848 }
1849
1850
1851 TArray<double> nnrs; // node numbers for the current call GenerateBeam
1852 for(int i=0; i<=(int)discr.Y(); i++)
1853 {
1854 for(int j=0; j<=(int)discr.X(); j++)
1855 {
1856 Vector3D pos = p1 + p12*((double)j/discr.X()) + p13*((double)i/discr.Y());
1857 ed.SetVector3D(pos.X(),pos.Y(),pos.Z(),"reference_position"); edc_nodeproperties.TreeAdd("Geometry",ed);
1858
1859 // call AddNode with prepared EDC, returnvalue is number of added node
1860 command_addnode->ExecuteCommand(mbs,edcParser,paramEDCforNode,ed,0);
1861
1862 nnrs.Add(ed.GetInt());
1863 }
1864 }
1865 // return value:nodes from current generation function
1866 ed.SetVector( nnrs.GetDataPtr(), nnrs.Length(), "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Plate or empty");
1867 edc_rv.Add(ed);
1868 // update list_of_nodes in Mesh
1869 mesh_nnrs.Merge(nnrs);
1870 ed.SetVector( mesh_nnrs.GetDataPtr(), mesh_nnrs.Length(), "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Mesh or empty");
1871 ElementDataContainer update_nnrs; update_nnrs.Add(ed);
1872 edc_handle_mesh->TreeReplaceEDCDataWith(&update_nnrs);
1873
1874
1875 // ***************************
1876 // GENERATION OF PLATE ELEMENTS
1877
1878 double size1 = p12.Norm() / discr.X();
1879 double size2 = p13.Norm() / discr.Y();
1880
1881 // use existing script command AddElement
1882 commandname = mystr("AddElement");
1883 CEDC_Command* command_addelement = edcParser->GetCommand( edcParser->GetCommandType(commandname, nparam, hasretval, c_option) );
1884
1885 // prepare EDC to be able to use existing script commands
1886 ElementDataContainer edc_elementproperties;
1887 ed.SetText(elem_type,"element_type"); edc_elementproperties.Add(ed);
1888 ed.SetInt(matnr,"material_number"); edc_elementproperties.TreeAdd("Physics",ed);
1889 ed.SetDouble(thickness,"thickness"); edc_elementproperties.TreeAdd("Geometry",ed);
1890 ed.SetDouble(size1,"size1"); edc_elementproperties.TreeAdd("Geometry",ed);
1891 ed.SetDouble(size2,"size2"); edc_elementproperties.TreeAdd("Geometry",ed);
1892 ed.SetBool(is_nonlinear, "is_geometrically_nonlinear"); edc_elementproperties.TreeAdd("Physics",ed);
1893
1894 if (loads.Length() > 0)
1895 {
1896 ed.SetVector(loads.GetDataPtr(), loads.Length(), "loads"); edc_elementproperties.Add(ed);
1897 }
1898
1899 TArray<ElementDataContainer*> paramEDCforElement;
1900 paramEDCforElement.Add(&edc_elementproperties);
1901
1902
1903 TArray<double> enrs;
1904 for(int i=1; i<=discr.Y(); i++)
1905 {
1906 for(int j=1; j<=discr.X(); j++)
1907 {
1908 ed.SetInt(nnrs(j +(i-1)*(discr.X()+1)),"node_1"); edc_elementproperties.TreeAdd("Geometry",ed);
1909 ed.SetInt(nnrs(j+1 +(i-1)*(discr.X()+1)),"node_2"); edc_elementproperties.TreeAdd("Geometry",ed);
1910 ed.SetInt(nnrs(j+1 +(i )*(discr.X()+1)),"node_3"); edc_elementproperties.TreeAdd("Geometry",ed);
1911 ed.SetInt(nnrs(j +(i )*(discr.X()+1)),"node_4"); edc_elementproperties.TreeAdd("Geometry",ed);
1912
1913 // call AddElement with prepared EDC, returnvalue is number of added element
1914 command_addelement->ExecuteCommand(mbs,edcParser,paramEDCforElement,ed,0);
1915
1916 enrs.Add(ed.GetInt());
1917 }
1918 }
1919 // return value:elements from current generation function
1920 ed.SetVector( enrs.GetDataPtr(), enrs.Length(), "list_of_elements"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Elements associated with the Beam or empty");
1921 edc_rv.Add(ed);
1922 // update list_of_elements in Mesh
1923 mesh_enrs.Merge(enrs);
1924 ed.SetVector( mesh_enrs.GetDataPtr(), mesh_enrs.Length(), "list_of_elements"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Elements associated with the Mesh or empty");
1925 ElementDataContainer update_enrs; update_enrs.Add(ed);
1926 edc_handle_mesh->TreeReplaceEDCDataWith(&update_enrs);
1927
1928 // first approach, slow
1929
1930 return rv;
1931 }
1932
1933
GetCommandTexParameterDescription() const1934 mystr CEDC_ComMesh_GeneratePlate::GetCommandTexParameterDescription() const
1935 {
1936 mystr descr = mystr("The parameters of this command are \n");
1937 descr += mystr("\\begin{enumerate} \n");
1938 descr += mystr(" \\item $1^{st}$ parameter EDC containing the plate properties \n");
1939 descr += mystr("\\end{enumerate} \n");
1940 descr += mystr("enties in the properties EDC are: \n");
1941 descr += mystr("\\begin{itemize} \n");
1942 descr += mystr(" \\item P1 - position of first node \n");
1943 descr += mystr(" \\item P2 - position of outer node along first direction\n");
1944 descr += mystr(" \\item P3 - position of outer node along second direction \n");
1945 descr += mystr(" \\item matnr - number of the material \n");
1946 descr += mystr(" \\item discretization - number of the plate elements both\n");
1947 descr += mystr(" \\item elementsize - (optional) maximum element size ( if set has priority over discretization ) \n");
1948 descr += mystr("\\end{itemize} \n");
1949 descr += mystr("-"); //DR hack, to avoid bugs in latex
1950 return descr;
1951 };
1952
1953
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)1954 int CEDC_ComMesh_GetNodesInBox::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
1955 {
1956 int rv = 0;
1957 ElementDataContainer edc_rv;
1958
1959 // container 1 contains the corners of the box
1960 Vector3D p1, p2;
1961 ElementDataContainer* edc_boxparameters = parameter_EDCs(1);
1962 edc_boxparameters->TreeGetVector3D("P1",p1.X(), p1.Y(), p1.Z());
1963 edc_boxparameters->TreeGetVector3D("P2",p2.X(), p2.Y(), p2.Z());
1964 Box3D box(p1,p2);
1965
1966 // container 2 contains the name of the handle ( can not pass the EDC* itself because that is going to be deleted... )
1967 // consistency already checked in ParseCommandParameters...
1968 mystr handlename = parameter_EDCs(2)->TreeGetString("handle");
1969 ElementDataContainer* edc_local = edcParser->GetMBSParser()->GetLocalEDC();
1970 int nr_handle = edc_local->Find(handlename);
1971 ElementDataContainer* edc_handle_mesh = edc_local->Get(nr_handle).GetEDC();
1972
1973
1974 // get current lists for mesh object
1975 double* vdata;
1976 int vlen;
1977 edc_handle_mesh->TreeGetVector("list_of_nodes",&vdata,vlen);
1978 TArray<double> mesh_nnrs; mesh_nnrs.CopyFrom(vdata,vlen); mesh_nnrs.SetLen(vlen); // node numbers already associated with the Mesh
1979
1980 //edc_handle_mesh->TreeGetVector("list_of_redundant_nodes",&vdata,vlen);
1981 //TArray<double> mesh_redundant_nodes; mesh_redundant_nodes.CopyFrom(vdata,vlen); mesh_redundant_nodes.SetLen(vlen); // redundant nodes in mesh
1982
1983 TArray<double> nnrs;
1984 // loop over all nodes
1985 for (int i=1; i<= mesh_nnrs.Length(); i++)
1986 {
1987 Vector3D nodepos = mbs->GetNode(mesh_nnrs(i)).RefConfPos();
1988 if (box.IsIn(nodepos) /*&& !mesh_redundant_nodes.Find(mesh_nnrs(i))*/)
1989 {
1990 nnrs.Add(mesh_nnrs(i));
1991 }
1992 }
1993
1994 // return value:nodes from current generation function
1995 return_value.SetVector( nnrs.GetDataPtr(), nnrs.Length(), "list_of_nodes"); return_value.SetValuesInt(); return_value.SetVariableLength(); return_value.SetToolTipText("List of Nodes returned from GetNodesInBox");
1996
1997 return rv;
1998 }
1999
GetCommandTexParameterDescription() const2000 mystr CEDC_ComMesh_GetNodesInBox::GetCommandTexParameterDescription() const
2001 {
2002 mystr descr = mystr("The parameters of this command are \n");
2003 descr += mystr("\\begin{enumerate} \n");
2004 descr += mystr(" \\item $1^{st}$ parameter EDC containing the box (defined by two corners) \n");
2005 descr += mystr("\\end{enumerate} \n");
2006 descr += mystr("enties in the properties EDC are: \n");
2007 descr += mystr("\\begin{itemize} \n");
2008 descr += mystr(" \\item P1 - position of first corner \n");
2009 descr += mystr(" \\item P2 - position of second corner\n");
2010 descr += mystr("\\end{itemize} \n");
2011 descr += mystr("-"); //DR hack, to avoid bugs in latex
2012 return descr;
2013 };
2014
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)2015 int CEDC_ComMesh_GlueMesh::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
2016 {
2017 // default parameter values, to be overridden by user
2018 ElementDataContainer edc_glue_parameters;
2019 ElementData ed;
2020
2021 Vector nodes;
2022 ed.SetVector(nodes.GetVecPtr(), 0, "nodes_to_constrain"); ed.SetValuesInt(); ed.SetVariableLength(); edc_glue_parameters.Add(ed);
2023 ed.SetBool(0, "is_ground"); ed.SetToolTipText("default 0: constrain node pairs - set to 1 for ground constraint"); edc_glue_parameters.Add(ed);
2024 ed.SetBool(0, "remove_redundant_only"); ed.SetToolTipText("default 0: connect pairs - set to 1 to only remove redundant nodes"); edc_glue_parameters.Add(ed);
2025 ed.SetVector3D(1., 1., 1., "constrained_directions"); ed.SetValuesInt(); edc_glue_parameters.Add(ed);
2026 ed.SetVector3D(1., 1., 1., "constrained_rotations"); ed.SetValuesInt(); edc_glue_parameters.Add(ed);
2027
2028 edc_glue_parameters.TreeReplaceEDCDataWith(parameter_EDCs(1));
2029
2030 int len; double* p_vec;
2031 edc_glue_parameters.TreeGetVector("nodes_to_constrain", &p_vec, len); // ist das so gut????
2032 nodes.LinkWith(p_vec, len);
2033
2034 int is_ground = edc_glue_parameters.TreeGetBool("is_ground", 0);
2035 int redundant_only = edc_glue_parameters.TreeGetBool("remove_redundant_only", 0);
2036
2037
2038 Vector constrained_dirs, constrained_rots;
2039 edc_glue_parameters.TreeGetVector("constrained_directions", &p_vec, len);
2040 constrained_dirs.LinkWith(p_vec, len);
2041 edc_glue_parameters.TreeGetVector("constrained_rotations", &p_vec, len);
2042 constrained_rots.LinkWith(p_vec, len);
2043
2044 // HACK: first of all, build a node2elements list
2045 mystr handlename = parameter_EDCs(2)->TreeGetString("handle");
2046 ElementDataContainer* edc_local = edcParser->GetMBSParser()->GetLocalEDC();
2047 int nr_handle = edc_local->Find(handlename);
2048 ElementDataContainer* edc_handle_mesh = edc_local->Get(nr_handle).GetEDC();
2049
2050 double* elems_data, * nodes_data, * redundant_nodes_data;
2051 int elems_len, nodes_len, redundant_nodes_len;
2052
2053 edc_handle_mesh->TreeGetVector("list_of_nodes",&nodes_data,nodes_len);
2054 TArray<double> mesh_nodes; mesh_nodes.CopyFrom(nodes_data,nodes_len); mesh_nodes.SetLen(nodes_len); // node numbers already associated with the Mesh
2055
2056 edc_handle_mesh->TreeGetVector("list_of_elements",&elems_data,elems_len);
2057 TArray<double> mesh_elems; mesh_elems.CopyFrom(elems_data,elems_len); mesh_elems.SetLen(elems_len); // element numbers already associated with the Mesh
2058
2059 edc_handle_mesh->TreeGetVector("list_of_redundant_nodes",&redundant_nodes_data,redundant_nodes_len);
2060 TArray<double> mesh_redundant_nodes; mesh_redundant_nodes.CopyFrom(redundant_nodes_data,redundant_nodes_len); mesh_redundant_nodes.SetLen(redundant_nodes_len); // node numbers already associated with the Mesh
2061
2062 TArray<TArray<int>> nodes2elems;
2063 nodes2elems.SetLen(mesh_nodes.Length());
2064 for (int i = 1; i <= mesh_elems.Length(); i++)
2065 {
2066 Element& e = mbs->GetElement(mesh_elems(i));
2067 for (int j = 1; j <= e.NNodes(); j++)
2068 {
2069 nodes2elems(e.GetNode(j).NodeNum()).Add(mesh_elems(i));
2070 }
2071 }
2072
2073 ElementDataContainer edc_elementproperties;
2074 ed.SetText("GenericBodyJoint","element_type"); edc_elementproperties.Add(ed);
2075
2076 int ed_num = edc_glue_parameters.Find("constrained_directions");
2077 if (ed_num)
2078 {
2079 edc_elementproperties.TreeAdd("Physics.Lagrange", edc_glue_parameters.Get(ed_num));
2080 }
2081 ed_num = edc_glue_parameters.Find("constrained_rotations");
2082 if (ed_num)
2083 {
2084 edc_elementproperties.TreeAdd("Physics.Lagrange", edc_glue_parameters.Get(ed_num));
2085 }
2086 /*ed.SetText("UniversalJoint", "element_type"); edc_elementproperties.Add(ed);
2087 ed.SetVector3D(0., 0., 1., "axis"); edc_elementproperties.TreeAdd("Position1", ed);
2088 ed.SetVector3D(0., 0., 1., "axis"); edc_elementproperties.TreeAdd("Position2", ed);*/
2089
2090 mystr commandname = mystr("AddConnector");
2091 int nparam, hasretval, c_option;
2092 CEDC_Command* command_addrigidjoint = edcParser->GetCommand( edcParser->GetCommandType(commandname, nparam, hasretval, c_option) );
2093
2094 TArray<double> new_redundant_nodes; // nodes to remove from mbs
2095 // pairs
2096 if (!is_ground)
2097 {
2098 TArray<int2> node_pairs;
2099
2100 for (int i = 1; i <= nodes.Length(); i++)
2101 {
2102 for (int j = i+1; j <= nodes.Length(); j++)
2103 {
2104 if ( nodes(j)!=0 && nodes(i)!=0 ) // skip redundant nodes ( marked in a previous iteration )
2105 {
2106 Node& n1 = mbs->GetNode((int)nodes(i));
2107 Node& n2 = mbs->GetNode((int)nodes(j));
2108
2109 Vector3D dist = n1.RefConfPos() - n2.RefConfPos();
2110
2111 if (dist.Norm() < 1e-10)
2112 {
2113 // check if nodes are identical; if so, replace n2 by n1
2114 // TODO: == operator for nodes!
2115 if (typeid(n1) == typeid(ANCFNodeS1S2_3D) && typeid(n2) == typeid(ANCFNodeS1S2_3D) &&
2116 (dynamic_cast<ANCFNodeS1S2_3D&>(n1)).GetRefSlope1() == (dynamic_cast<ANCFNodeS1S2_3D&>(n2)).GetRefSlope1() &&
2117 (dynamic_cast<ANCFNodeS1S2_3D&>(n1)).GetRefSlope2() == (dynamic_cast<ANCFNodeS1S2_3D&>(n2)).GetRefSlope2())
2118 {
2119 // replace in elements
2120 for (int k = 1; k <= nodes2elems(nodes(j)).Length(); k++)
2121 {
2122 Element& e = mbs->GetElement(nodes2elems(nodes(j))(k));
2123 for (int l = 1; l <= e.NNodes(); l++)
2124 {
2125 if (e.NodeNum(l) == n2.NodeNum())
2126 {
2127 e.NodeNum(l) = n1.NodeNum();
2128 }
2129 }
2130 }
2131 // remove redundant entries from pair list
2132 for (int m = 1; m <= node_pairs.Length(); m++)
2133 {
2134 if( node_pairs(m)(1) == nodes(j) || node_pairs(m)(2) == nodes(j))
2135 {
2136 node_pairs.Erase(m);
2137 }
2138 }
2139 new_redundant_nodes.Add(nodes(j));
2140 nodes(j) = 0; // ignore this nodelist entry - has beed identified as redundant
2141 }
2142 // if not, apply RigidBodyJoint later on
2143 else
2144 {
2145 if (!redundant_only)
2146 {
2147 int2 pair(nodes(i),nodes(j));
2148 node_pairs.Add(pair);
2149 }
2150 }
2151 }
2152 }
2153 }
2154 }
2155
2156 for (int i = 1; i <= node_pairs.Length(); i++)
2157 {
2158 Node& n1 = mbs->GetNode(node_pairs(i)(1));
2159 Node& n2 = mbs->GetNode(node_pairs(i)(2));
2160
2161 Element& e1 = mbs->GetElement(nodes2elems(n1.NodeNum())(1));
2162 Element& e2 = mbs->GetElement(nodes2elems(n2.NodeNum())(1));
2163
2164 //mbs->UO() << n1.NodeNum() << " " << n2.NodeNum() << "\n";
2165 //mbs->UO() << nodes2elems(n1.NodeNum())(1) << " " << nodes2elems(n2.NodeNum())(1) << "\n";
2166
2167 // find the local position of a node within an element
2168 Vector3D p_loc_n1, p_loc_n2;
2169 for (int j = 1; j <= e1.NNodes(); j++)
2170 {
2171 if (e1.NodeNum(j) == n1.NodeNum())
2172 {
2173 p_loc_n1 = e1.GetNodeLocPos(j);
2174 }
2175 if (e2.NodeNum(j) == n2.NodeNum())
2176 {
2177 p_loc_n2 = e2.GetNodeLocPos(j);
2178 }
2179 }
2180 //mbs->UO() << p_loc_n1 << " " << p_loc_n2 << "\n";
2181
2182 // prepare EDC to be able to use existing script commands
2183 ed.SetInt(nodes2elems(n1.NodeNum())(1), "element_number"); edc_elementproperties.TreeAdd("Position1", ed);
2184 ed.SetInt(nodes2elems(n2.NodeNum())(1), "element_number"); edc_elementproperties.TreeAdd("Position2", ed);
2185 ed.SetVector3D(p_loc_n1.X(), p_loc_n1.Y(), p_loc_n1.Z(), "position"); edc_elementproperties.TreeAdd("Position1", ed);
2186 ed.SetVector3D(p_loc_n2.X(), p_loc_n2.Y(), p_loc_n2.Z(), "position"); edc_elementproperties.TreeAdd("Position2", ed);
2187
2188 TArray<ElementDataContainer*> paramEDCforElement;
2189 paramEDCforElement.Add(&edc_elementproperties);
2190
2191 command_addrigidjoint->ExecuteCommand(mbs,edcParser,paramEDCforElement,ed,0);
2192 }
2193 }
2194 else // is_ground
2195 {
2196 // again, find node pairs in order to avoid redundant constraints
2197 // assume, no redundant nodes exist eny longer
2198 TArray<int2> node_pairs;
2199 for (int i = 1; i <= nodes.Length(); i++)
2200 {
2201 for (int j = i+1; j <= nodes.Length(); j++)
2202 {
2203 Node& n1 = mbs->GetNode((int)nodes(i));
2204 Node& n2 = mbs->GetNode((int)nodes(j));
2205
2206 Vector3D dist = n1.RefConfPos() - n2.RefConfPos();
2207
2208 if (dist.Norm() < 1e-10)
2209 {
2210 int2 pair(nodes(i),nodes(j));
2211 node_pairs.Add(pair);
2212 }
2213 }
2214 }
2215
2216 for (int i = 1; i <= nodes.Length(); i++)
2217 {
2218 Node& n = mbs->GetNode(nodes(i));
2219 Vector3D refpos = n.RefConfPos();
2220
2221 Element& e = mbs->GetElement(nodes2elems(n.NodeNum())(1));
2222 int is_in_pair = 0;
2223 for (int j = 1; j <= node_pairs.Length(); j++)
2224 {
2225 if (node_pairs(j)(2) == nodes(i))
2226 {
2227 is_in_pair = 1; break;
2228 }
2229 }
2230
2231 if (!is_in_pair)
2232 {
2233 // find the local position of a node within an element
2234 Vector3D p_loc;
2235 for (int j = 1; j <= e.NNodes(); j++)
2236 {
2237 if (e.NodeNum(j) == n.NodeNum())
2238 {
2239 p_loc = e.GetNodeLocPos(j); break;
2240 }
2241 }
2242
2243 // prepare EDC to be able to use existing script commands
2244 ed.SetInt(nodes2elems(n.NodeNum())(1), "element_number"); edc_elementproperties.TreeAdd("Position1", ed);
2245 ed.SetInt(0, "element_number"); edc_elementproperties.TreeAdd("Position2", ed);
2246 ed.SetVector3D(p_loc.X(), p_loc.Y(), p_loc.Z(), "position"); edc_elementproperties.TreeAdd("Position1", ed);
2247 ed.SetVector3D(refpos.X(), refpos.Y(), refpos.Z(), "position"); edc_elementproperties.TreeAdd("Position2", ed);
2248
2249 TArray<ElementDataContainer*> paramEDCforElement;
2250 paramEDCforElement.Add(&edc_elementproperties);
2251
2252 command_addrigidjoint->ExecuteCommand(mbs,edcParser,paramEDCforElement,ed,0);
2253 }
2254 }
2255 }
2256
2257 TArray<int> permutation; permutation.SetLen(new_redundant_nodes.Length());
2258 QuicksortDouble(new_redundant_nodes, permutation);
2259
2260 for (int i = new_redundant_nodes.Length(); i >= 1; i--)
2261 {
2262 int node_to_delete = new_redundant_nodes(i);
2263 mbs->DeleteNode(node_to_delete);
2264 mesh_nodes.Erase(mesh_nodes.Find(new_redundant_nodes(i)));
2265
2266 for (int j = 1; j <= mesh_nodes.Length(); j++)
2267 {
2268 if (mesh_nodes(j) > node_to_delete)
2269 {
2270 mesh_nodes(j)--;
2271 }
2272 }
2273 }
2274
2275 ElementDataContainer update_nodes;
2276 mesh_redundant_nodes.Merge(new_redundant_nodes);
2277 ed.SetVector( mesh_redundant_nodes.GetDataPtr(), mesh_redundant_nodes.Length(), "list_of_redundant_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of redundant nodes in mesh");
2278 update_nodes.Add(ed);
2279 ed.SetVector( mesh_nodes.GetDataPtr(), mesh_nodes.Length(), "list_of_nodes"); ed.SetValuesInt(); ed.SetVariableLength(); ed.SetToolTipText("List of Nodes associated with the Plate or empty");
2280 update_nodes.Add(ed);
2281 edc_handle_mesh->TreeReplaceEDCDataWith(&update_nodes);
2282
2283 return 1;
2284 }
2285
2286
GetCommandTexParameterDescription() const2287 mystr CEDC_Check_Entry_Exists::GetCommandTexParameterDescription() const
2288 {
2289 mystr descr = mystr("The parameters of this command are \n");
2290 descr += mystr("\\begin{enumerate} \n");
2291 descr += mystr(" \\item $1^{st}$ parameter: string with the name and tree of the entry to check \n");
2292 descr += mystr("\\end{enumerate} \n");
2293 descr += mystr("-"); //DR hack, to avoid bugs in latex
2294 return descr;
2295 };
2296
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)2297 int CEDC_Check_Entry_Exists::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
2298 {
2299 ElementData* ED_treename = parameter_EDCs(1)->GetPtr(1);
2300 mystr str_treename;
2301 if(ED_treename->IsText())
2302 {
2303 str_treename = ED_treename->GetText();
2304 }
2305
2306 ElementDataContainer* localEDC = edcParser->GetMBSParser()->GetLocalEDC2(); // existing local EDC for the CHECK_ENTRY_EXISTS command
2307
2308 ElementData* ed = localEDC->TreeFind(str_treename);
2309 if(ed==NULL)
2310 {
2311 // Entry not found
2312 return_value.SetInt(0,"rv");
2313 }
2314 else if(ed!=NULL && !ed->IsEDC())
2315 {
2316 // Entry found, not an EDC
2317 return_value.SetInt(1,"rv");
2318 }
2319 else if(ed!=NULL && ed->IsEDC())
2320 {
2321 // Entry found, also an EDC
2322 return_value.SetInt(2,"rv");
2323 }
2324 return 1;
2325 }
2326
2327
GetCommandTexParameterDescription() const2328 mystr CEDC_Compare::GetCommandTexParameterDescription() const
2329 {
2330 mystr descr = mystr("The parameters of this command are \n");
2331 descr += mystr("\\begin{enumerate} \n");
2332 descr += mystr(" \\item $1^{st}$ parameter: string A \n");
2333 descr += mystr(" \\item $2^{nd}$ parameter: string B \n");
2334 descr += mystr("\\end{enumerate} \n");
2335 descr += mystr("-"); //DR hack, to avoid bugs in latex
2336 return descr;
2337 };
2338
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)2339 int CEDC_Compare::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
2340 {
2341 int rv = 0;
2342 ElementData* ED_strA = parameter_EDCs(1)->GetPtr(1);
2343 mystr strA;
2344 if(ED_strA->IsText())
2345 {
2346 strA = ED_strA->GetText();
2347 }
2348 else
2349 {
2350 edcParser->EDCError("Error while executing COMPARE operation: first parameter is not a string variable");
2351 return rv;
2352 }
2353 ElementData* ED_strB = parameter_EDCs(2)->GetPtr(1);
2354 mystr strB;
2355 if(ED_strB->IsText())
2356 {
2357 strB = ED_strB->GetText();
2358 }
2359 else
2360 {
2361 edcParser->EDCError("Error while executing COMPARE operation: second parameter is not a string variable");
2362 return rv;
2363 }
2364
2365 int result = strcmp(strA.c_str(), strB.c_str());
2366
2367 return_value.SetInt(result,"rv");
2368
2369 return 1;
2370 }
2371
2372
GetCommandTexParameterDescription() const2373 mystr CEDC_StrCat::GetCommandTexParameterDescription() const
2374 {
2375 mystr descr = mystr("The parameters of this command are \n");
2376 descr += mystr("\\begin{enumerate} \n");
2377 descr += mystr(" \\item $1^{st}$ parameter: string A \n");
2378 descr += mystr(" \\item $2^{nd}$ parameter: string B \n");
2379 descr += mystr("\\end{enumerate} \n");
2380 descr += mystr("-"); //DR hack, to avoid bugs in latex
2381 return descr;
2382 };
2383
ExecuteCommand(MBS * mbs,CEDCParser * edcParser,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)2384 int CEDC_StrCat::ExecuteCommand(MBS * mbs, CEDCParser * edcParser, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
2385 {
2386 int rv = 0;
2387 ElementData* ED_strA = parameter_EDCs(1)->GetPtr(1);
2388 mystr strA;
2389 if(ED_strA->IsText())
2390 {
2391 strA = ED_strA->GetText();
2392 }
2393 else
2394 {
2395 edcParser->EDCError("Error while executing COMPARE operation: first parameter is not a string variable");
2396 return rv;
2397 }
2398 ElementData* ED_strB = parameter_EDCs(2)->GetPtr(1);
2399 mystr strB;
2400 if(ED_strB->IsText())
2401 {
2402 strB = ED_strB->GetText();
2403 }
2404 else
2405 {
2406 edcParser->EDCError("Error while executing COMPARE operation: second parameter is not a string variable");
2407 return rv;
2408 }
2409
2410 mystr result = strA + strB;
2411
2412 return_value.SetText(result,"rv");
2413
2414 return 1;
2415 }
2416
2417
2418
2419 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2420 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2421 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2422 //void CEDCParser::EDC2TexTable(const ElementDataContainer& edc, mystr& str, const mystr& indent, const mystr& treename) //$ DR 2013-01-11 moved to models_auto_documentation
2423
2424 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2425 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GetParameterEDC(mystr text,TArray<ElementDataContainer * > & parameter_EDCs)2426 int CEDCParser::GetParameterEDC(mystr text, TArray<ElementDataContainer*>& parameter_EDCs)
2427 {
2428 int parPos = 0;
2429 int parCount = 1;
2430 mystr EDCtext;
2431
2432 text.GetUntil(parPos, ',', EDCtext, 0);
2433 while(1) // handle all parameters
2434 {
2435 bool success = false;
2436 //int future: this should be either an EDC name, or a structure defining an EDC {...}
2437 //at the moment, only an EDC-name is possible
2438 EDCtext.EraseSpacesHeadTail();
2439
2440 //the EDC must be either global or local
2441 ElementDataContainer* edc = mbsParser->GetLocalEDC(); //local
2442 ElementDataContainer* edc2 = mbsParser->GetLocalEDC2(); //global
2443 ElementDataContainer* edcMBS = mbs->GetModelDataContainer(); //$ DR 2013-07-25 added for the case of multiple input files
2444
2445 //$ RL 2012-7-19:[ new code with ExecuteCommand planned to be possible only with arguments
2446 ElementData* ed = 0;
2447 if(edc)
2448 {
2449 ed = edc->TreeFind(EDCtext); // search only if edc exists!!
2450 }
2451 ElementData* ed2 = 0;
2452 if(edc2)
2453 {
2454 ed2 = edc2->TreeFind(EDCtext); // search only if edc exists!!
2455 }
2456 ElementData* edMBS = 0;
2457 if(edcMBS)
2458 {
2459 edMBS = edcMBS->TreeFind(EDCtext); //$ DR 2013-07-25 added for the case of multiple input files
2460 }
2461
2462 if (!ed && ed2) {ed = ed2;}
2463 else if (!ed && !ed2 && edMBS) {ed = edMBS;} //$ DR 2013-07-25 added for the case of multiple input files
2464 //else if (!ed && !ed2)
2465 else if (!ed && !ed2 && !edMBS)
2466 {
2467 // no parameter edc found -> add parameter string to parameter_EDCs
2468 int pos=0;
2469 //if (text.PosPeek(pos) == doublequote)
2470 if (EDCtext.PosPeek(pos) == doublequote)
2471 {
2472 //pos = text.Length()-1;
2473 pos = EDCtext.Length()-1;
2474 //if(text.PosPeek(pos) == doublequote)
2475 if(EDCtext.PosPeek(pos) == doublequote)
2476 {
2477 // text is within doublequotes
2478 pos=0;
2479 //text = text.GetStringInBrackets(pos, doublequote, doublequote); // remove doublequotes
2480 EDCtext = EDCtext.GetStringInBrackets(pos, doublequote, doublequote); // remove doublequotes
2481 }
2482 }
2483 ElementData ed3;
2484 mystr parName = "parameter"+mystr(parCount);
2485 //ed3.SetText(text,parName); // store parameter text
2486 ed3.SetText(EDCtext,parName); // store parameter text
2487 ElementDataContainer edc_text;
2488 edc_text.Add(ed3);
2489 parameter_EDCs.Add(edc_text.GetCopy()); //parameter_EDCs are deleted outside this function
2490 //return 1;
2491 success = true;
2492 }
2493
2494 if(!success)
2495 {
2496 //$ DR 2012-11-29: [ also use element data, e.g. for CEDC_ComPrint
2497 if (!ed->IsEDC() && (ed->IsBool() || ed->IsInt() || ed->IsDouble() || ed->IsMatrix() || ed->IsText() || ed->IsVector()))
2498 {
2499 ElementDataContainer edc_ed;
2500 edc_ed.Add(*ed->GetCopy());
2501 parameter_EDCs.Add(edc_ed.GetCopy()); //parameter_EDCs are deleted outside this function
2502 //return 1;
2503 success = true;
2504 }
2505 //$ DR 2012-11-29: ]
2506 }
2507
2508 if(!success)
2509 {
2510 //always use ed, ed2 overrides ed:
2511 //now the parameter should indicate an EDC
2512 if (ed->IsEDC())
2513 {
2514 parameter_EDCs.Add((ed->GetEDC())->GetCopy()); //parameter_EDCs are deleted outside this function
2515 }
2516 else
2517 {
2518 //failed
2519 EDCError(mystr("ERROR: Expected a parameter set (ElementDataContainer) for function parameters"));
2520 return 0;
2521 }
2522 }
2523
2524 if(parPos == -1) return 1; // last parameter
2525 parPos++;
2526 text.GetUntil(parPos, ',', EDCtext, 0);
2527 parCount++;
2528 }
2529
2530 return 1;
2531 }
2532 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2533 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2534 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2535 //this function is already adapted for TreeEDCs!
2536 //$ DR 2013-01-31 empty subEDCs are not written at all, see log 384
EDC2String(const ElementDataContainer & edc,mystr & str,const mystr & indent)2537 void CEDCParser::EDC2String(const ElementDataContainer& edc, mystr& str, const mystr& indent)
2538 {
2539 //symbols already defined in CEDCParser:
2540 // mystr el = "\n"; //end of line
2541 // mystr ob = "{"; //open brace
2542 // mystr cb = "}"; //closing brace
2543 // mystr osb = "["; //open square bracket
2544 // mystr csb = "]"; //closing square bracket
2545 // mystr ds = ": "; //double stop
2546 // mystr semicolon = ";"; //semicolon
2547 // char commentc = '%'; //comment
2548 // mystr doublequote = mystr('"'); //for strings or text
2549
2550 //symbols with additional whitespaces:
2551 mystr eq = "= "; //equal sign
2552 mystr comma = ", "; //comma
2553 mystr comment = mystr(" ")+mystr(commentc); //comment
2554
2555 mystr matrixsep = el; //may be changed to semicolon ...
2556 str = "";
2557 mystr num;
2558
2559 for (int i=1; i <= edc.Length(); i++)
2560 {
2561 const ElementData& ed = edc.Get(i);
2562
2563 if (!ed.IsLocked() && !ed.IsElementInfo() && !ed.IsCompAction() && !ed.IsWCDriverAction())
2564 {
2565 //str += indent + ed.GetDataName();
2566 if (ed.IsEDC())
2567 { //hierarchically
2568 mystr substr;
2569 const ElementDataContainer* edcptr = ed.GetEDC();
2570 if (edcptr)
2571 {
2572 EDC2String(*edcptr, substr, indent+mystr(" "));
2573 }
2574 if(substr.Length())
2575 {
2576 str += indent + ed.GetDataName();
2577 str += el + indent + ob + el;
2578 str += substr;
2579 str += indent + cb + el;
2580 }
2581 }
2582 else
2583 { //just this list
2584 str += indent + ed.GetDataName();//
2585 str += eq;
2586 if (ed.IsBool())
2587 {
2588 str += mystr(ed.GetBool());
2589 }
2590 else if (ed.IsInt())
2591 {
2592 str += mystr(ed.GetInt());
2593 }
2594 else if (ed.IsDouble())
2595 {
2596 num.SmartDouble2String(ed.GetDouble());
2597 str += num;
2598 }
2599 else if (ed.IsText())
2600 {
2601 str += mystr(doublequote) + mystr(ed.GetText()) + mystr(doublequote);
2602 }
2603 else if (ed.IsVector())
2604 {
2605 str += osb;
2606 for (int j = 1; j <= ed.GetVectorLen(); j++)
2607 {
2608 num.SmartDouble2String(ed.GetVectorVal(j));
2609 str += num;
2610 if (j < ed.GetVectorLen()) str += comma;
2611 }
2612 str += csb;
2613 }
2614 else if (ed.IsMatrix())
2615 {
2616 str += osb;
2617 for (int j1 = 1; j1 <= ed.GetMatrixRows(); j1++)
2618 {
2619 for (int j2 = 1; j2 <= ed.GetMatrixCols(); j2++)
2620 {
2621 num.SmartDouble2String(ed.GetMatrixVal(j1, j2));
2622 str += num;
2623 if (j2 < ed.GetMatrixCols()) str += comma;
2624 }
2625 if (j1 < ed.GetMatrixRows()) str += matrixsep + indent + mystr(" ");
2626 }
2627 str += csb;
2628 }
2629 if (ed.HasToolTip())
2630 {
2631 str += comment + ed.GetToolTipText();
2632 }
2633 str += el;
2634 }
2635 }
2636 }
2637 }
2638
2639 //old version for saving MBS data, do not use!
2640 //$JG2012-01-27: mbs is available in CEDCParser
String2EDC(mystr & str,ElementDataContainer & edc,ElementDataContainer & testedc)2641 int CEDCParser::String2EDC(/*MBS* mbs, */mystr& str, ElementDataContainer& edc, ElementDataContainer& testedc)
2642 {
2643 char osb = '['; //open square bracket
2644 char csb = ']'; //closing square bracket
2645 char ds = ':'; //double stop
2646 char eq = '='; //equal sign
2647 char comma = ','; //comma sign
2648 char semicolon = ';'; //semicolon sign
2649
2650 int oo = 0;
2651 if (oo) mbs->UO() << "String2EDC\n";
2652
2653 mystr dataname, data, data2, data3;
2654 int endstr = 0;
2655 int pos = 0;
2656 int posold;
2657 TArray<double> datalist;
2658
2659
2660 while (!endstr)
2661 {
2662 posold = pos;
2663 dataname = str.GetWord(pos, 0);
2664 if (pos != -1 && str[pos] == ds)
2665 {
2666 str = str.Right(str.Length()-posold); return 1;
2667 }
2668 if (pos != -1)
2669 {
2670 if (oo) mbs->UO() << "Dataname='" << dataname << "'\n";
2671
2672 if (!str.GoUntil(pos, eq)) {return 0;}; //write error
2673
2674 int x = testedc.Find(dataname.c_str());
2675 if (x)
2676 {
2677 ElementData& ed = testedc.Get(x);
2678 if (ed.IsVector())
2679 {
2680 //read [ ... ]
2681 if (!str.GoUntil(pos, osb)) {LoadError("Vector '[...]' expected!"); return 0;}
2682
2683 if (!str.GetUntil(pos, csb, data, 0)) {LoadError(mystr("Vector '[...]' expected, but received '")+data+mystr("'")); return 0;};
2684
2685 int len = ed.GetVectorLen();
2686 datalist.SetLen(0);
2687
2688 int pos2 = 0;
2689 while (pos2 != -1 && (datalist.Length() <= len || ed.IsVariableLength()))
2690 {
2691 data.GetUntil(pos2, comma, data2, 0);
2692
2693 datalist.Add(data2.MakeDouble());
2694 if (pos2 != -1) data.GoUntil(pos2, comma);
2695 }
2696
2697 if (datalist.Length() != len && !ed.IsVariableLength()) {LoadError(mystr(ed.GetDataName())+mystr(": Vector of length ")+mystr(len)+mystr(" expected, but received length=")+mystr(datalist.Length())); return 0;};
2698
2699 len = datalist.Length();
2700 Vector v(len);
2701 for (int i=1; i <= len; i++) v(i) = datalist(i);
2702
2703 ed.SetVector(v.GetVecPtr(), len, dataname.c_str());
2704 edc.Add(ed);
2705 if (oo) mbs->UO() << v << "\n";
2706
2707 str.GoUntil(pos, csb); //read final square bracket
2708
2709
2710 }
2711 else if (ed.IsMatrix())
2712 {
2713 //read [ ... ]
2714 if (!str.GoUntil(pos, osb)) {LoadError("Matrix '[...]' expected!"); return 0;}
2715
2716 if (!str.GetUntil(pos, csb, data, 0)) {LoadError(mystr("Matrix '[...]' expected, but received '")+data+mystr("'")); return 0;};
2717
2718 int rows = ed.GetMatrixRows();
2719 int cols = ed.GetMatrixCols();
2720
2721
2722 TArray<double> doublelist;
2723
2724 //++++++++++++++++++++++++
2725 //same as in CustomEditDialog!
2726 char cstr[258];
2727 int limit = 256;
2728 int startpos = 0;
2729
2730 int end = 0;
2731 int endpos, endpos2;
2732 int maxcol = 0;
2733 int error = 0;
2734 int nrows = 0;
2735
2736 data = data+mystr("\n\n");
2737
2738 while (!end)
2739 {
2740 int emptystring = 1;
2741 int ncol = 0;
2742 int endcol = 0;
2743
2744 while (!endcol)
2745 {
2746 endpos = data.Find(startpos,',');
2747 endpos2 = data.FindEOL(startpos);
2748
2749 if (endpos2 < endpos || endpos == -1)
2750 {
2751 endpos = endpos2;
2752 endcol = 1;
2753 }
2754
2755 if (endpos != -1 && endpos != 0 && startpos < endpos && endpos+1 <= data.Length()-1 && data.Length() != 0)
2756 {
2757 int len = endpos-startpos;
2758 data.CopySubStringNoSpaces(cstr, startpos, endpos-1, limit);
2759
2760 if (strlen(cstr) != 0)
2761 {
2762 doublelist.Add(atof(cstr));
2763 ncol++;
2764
2765 startpos = endpos+1;
2766 emptystring = 0;
2767 }
2768 else
2769 {
2770 startpos = endpos+1;
2771 doublelist.Add(0);
2772 }
2773 }
2774 else
2775 {
2776 end = 1;
2777 endcol = 1;
2778 }
2779 }
2780 if (!end && !emptystring) nrows++;
2781 if (ncol != maxcol)
2782 {
2783 if (maxcol != 0 && ncol != 0)
2784 {
2785 error = 1;
2786 }
2787
2788 if (ncol > maxcol) maxcol = ncol;
2789 }
2790 }
2791
2792
2793
2794 //++++++++++++++++++++++++
2795
2796
2797 /*
2798 int pos2 = 0;
2799 int foundcols = 0;
2800 TArray<double> doublelist;
2801
2802 while (pos2 != -1)
2803 {
2804 data.GetUntil(pos2, semicolon, data3, 0);
2805
2806 int pos3 = 0;
2807 while (pos3 != -1)
2808 {
2809 data3.GetUntil(pos3, comma, data2, 0);
2810 doublelist.Add(data2.MakeDouble());
2811 if (pos3 != -1) data3.GoUntil(pos3, comma);
2812 }
2813 if (!foundcols) foundcols = doublelist.Length(); //take first number of columns for matrix
2814
2815 data.GoUntil(pos2, semicolon);
2816 }
2817 */
2818
2819 str.GoUntil(pos, csb); //read final square bracket
2820
2821 if (cols == 0 || ed.IsVariableLength()) cols = maxcol;
2822 else if (cols != maxcol || error) {LoadError(mystr("Matrix should contain ")+mystr(rows)+mystr("rows and ")+mystr(cols)+mystr("columns !!!")); return 0;}
2823
2824 Matrix m;
2825 if (cols != 0)
2826 {
2827 if (rows == 0 || ed.IsVariableLength()) rows = doublelist.Length()/cols;
2828 else if (doublelist.Length()/cols != rows) {LoadError(mystr("Matrix should contain ")+mystr(rows)+mystr("rows and ")+mystr(cols)+mystr("columns !!!")); return 0;}
2829
2830 m.SetSize(rows, cols);
2831 for (int i1=1; i1 <= rows; i1++)
2832 {
2833 for (int i2=1; i2 <= cols; i2++)
2834 {
2835 int ind = (i1-1)*cols+i2;
2836 if (ind <= doublelist.Length())
2837 {
2838 m(i1, i2) = doublelist(ind);
2839 }
2840 }
2841 }
2842 }
2843 else rows = 0;
2844
2845 ed.SetMatrix(m.GetMatPtr(), rows, cols, dataname.c_str());
2846 edc.Add(ed);
2847
2848 if (oo) mbs->UO() << m << "\n";
2849
2850 }
2851 else
2852 {
2853 //data = str.GetWord(pos, 0);
2854 str.GetUntil(pos, '\n', data);
2855 data.EraseSpaces();
2856 if (oo) mbs->UO() << "single data='" << data << "'\n";
2857 if (ed.IsBool())
2858 {
2859 ed.SetBool(data.MakeInt()); edc.Add(ed);
2860 }
2861 else if (ed.IsInt())
2862 {
2863 ed.SetInt(data.MakeInt()); edc.Add(ed);
2864 }
2865 else if (ed.IsDouble())
2866 {
2867 ed.SetDouble(data.MakeDouble()); edc.Add(ed);
2868 //if (oo) mbs->UO() << "double data='" << data.MakeDouble() << ", " << ed.GetDouble() << "'\n";
2869 }
2870 else if (ed.IsText())
2871 {
2872 ed.SetText(data.c_str()); edc.Add(ed);
2873 }
2874 else
2875 {
2876 //error should not happen
2877 }
2878 }
2879 }
2880 else
2881 {
2882 LoadError(mystr("Specifier '")+dataname+mystr("' is unknown"));
2883 str.GetUntil(pos, '\n', data); //one line unknown keywords are no problem!!!
2884 //return 0;
2885 }
2886 }
2887 else
2888 {
2889 str = str.Right(str.Length()-pos); return 1;
2890 }
2891
2892
2893 if (pos == -1) endstr = 1;
2894
2895 }
2896 return 1;
2897 }
2898
Initialize()2899 void CEDCParser::Initialize()
2900 {
2901 //here, things can be done during initialization of the CEDCparser
2902 el = "\n"; //end of line
2903 elc = '\n';
2904 obc = '{'; //open brace, for sub structure
2905 cbc = '}'; //closing brace
2906 ob = mystr(obc);
2907 cb = mystr(cbc);
2908 ofc = '('; //open function (round '(') bracket
2909 cfc = ')'; //close function (round ')') bracket
2910 of = mystr(ofc);
2911 cf = mystr(cfc);
2912 osbc = '['; //open square bracket, for vector or matrix
2913 csbc = ']'; //closing square bracket
2914 osb = osbc; //open square bracket, for vector or matrix
2915 csb = csbc; //closing square bracket
2916 ds = ": "; //double stop - not used any more
2917 eq = "="; //equal sign
2918 semicolon = ";"; //double stop
2919 semicolonc = ';'; //double stop
2920 commac = ','; //comma
2921 comma = commac; //comma
2922 doublequote = '"'; //for strings or text
2923 dotc = '.'; //dot
2924 dot = dotc; //dot
2925 space = ' '; //space
2926 spacec = ' ';
2927 tabc = '\t'; //tab
2928 tab = '\t';
2929 bool_yes = "yes";
2930 bool_no = "no";
2931 commentc = '%'; //comment
2932 comment = commentc; //comment
2933 matrixsep = el; //may be changed to semicolon ...
2934
2935 //intialize switches and others:
2936 oo = 0;
2937 line_cnt = 0;
2938 total_lines = 0;
2939
2940 version_check_performed = 0;
2941
2942 InitializeCommands();
2943 }
2944
2945 //read spaces, then comment sign, parse comment string into Tooltiptext of ed
2946 //return 1 if success, 0 if fail
ReadComment(mystr & str,int & pos,ElementData & ed,const mystr & dataname)2947 int CEDCParser::ReadComment(mystr& str, int& pos, ElementData& ed, const mystr& dataname)
2948 {
2949 mystr data;
2950 int rv = str.GetUntilEOL(pos, commentc, data);
2951 if (rv == 2) //comment found
2952 {
2953 //mbs->UO() << "comment='" << data << "'+";
2954 if (str.PosPeek(pos) != commentc)
2955 {
2956 mystr name = dataname;
2957 mbs->UO(UO_LVL_warn) << "Problem with comment in entry " << name <<". Check Textfile!\n";
2958 rv = 0;
2959 }
2960
2961 // comment --> ToolTipText (double)
2962 mystr dummycomment;
2963 str.GetUntilEOL(pos, (char)0, dummycomment);
2964 mystr comment = dummycomment.SubString(1, dummycomment.Length()-1);
2965 ed.SetToolTipText(comment);
2966 //mbs->UO() << "'" << comment << "'\n";
2967 }
2968
2969 return rv;
2970 }
2971
ReadBoolIntDoubleExpression(mystr & text,int & pos,ElementData & ed,const mystr & elemname)2972 int CEDCParser::ReadBoolIntDoubleExpression(mystr& text, int& pos, ElementData& ed, const mystr& elemname)
2973 {
2974 int rv = 1;
2975 text.EraseSpaces();
2976 if (PrintOutput()) mbs->UO() << "single text='" << text << "'\n";
2977 if (text[text.Length()-1] == ';') //accept ";" at end of statement
2978 {
2979 text.EraseChar(text.Length());
2980 }
2981
2982 if(text.IsValidNumber())
2983 {
2984 ed.SetDouble(text.MakeDouble(), elemname);
2985 }
2986 else // "expression"
2987 {
2988 if (PrintOutput()) mbs->UO() << "text='" << text << "' is no valid number\n";
2989 //bool variable
2990 if (bool_no.Compare(text))
2991 {
2992 ed.SetBool(0, elemname);
2993 }
2994 else if (bool_yes.Compare(text))
2995 {
2996 ed.SetBool(1, elemname);
2997 }
2998 else
2999 {
3000 // DR 2012-08-02
3001 // AD 2013-10-16: collected calls to parse command
3002 //AD: new procedure for commands
3003 mystr word = text; // "left hand side expression", not entire "str" and "pos" as for right hand side call
3004 int pos_tmp=0;
3005
3006 mystr dataname = word.GetIdentifier(pos_tmp, 0); //name of data structure or data variable
3007 int com_id = IdentifyAndExecuteCommand(dataname, word, pos_tmp, ed, 1/*right hand side call*/);
3008 ed.SetDataName(elemname);
3009
3010 if (com_id == -1)
3011 {
3012 rv = 0; // Parsing error occurred
3013 }
3014 else if (com_id > 0)
3015 {
3016 //rv = 1; // command executed
3017 }
3018 else //if (com_id == 0)
3019 // NOT A COMMAND
3020 {
3021 //!AD: 2012-12-11 assign entire EDCs: [
3022 // check if text is an EDC
3023 // this would be already available in
3024 // CParseObj* CMBSParser::GetVariable(mystr& str)
3025 // ElementDataContainer* CMBSParser::GetElementDataContainers(int i)
3026 int found_as_edc = 0;
3027 int found_as_entry = 0;
3028 ////while (i <= NElementDataContainers() && ! found)
3029 ////{
3030 //// ElementDataContainer* edc = GetElementDataContainers(i);
3031
3032 //ElementDataContainer* edc_existing = this->GetMBS()->GetModelDataContainer(); // GLOBAL
3033 //if (edc_existing && edc_existing->TreeFind(text))
3034 //{
3035 // ElementData* ed_other = edc_existing->TreeFind(text);
3036 // if (ed_other->IsEDC())
3037 // {
3038 // found_as_edc = 1;
3039 // ElementDataContainer* edc_new = new ElementDataContainer();
3040 // edc_new->TreeReplaceEDCDataWith(ed_other->GetEDC()); // use TreeReplaceEDCDataWith to add the entries not clear the old ones
3041 // ed.SetEDC(edc_new,elemname);
3042 // }
3043 //}
3044
3045 if (!(found_as_edc || found_as_entry))
3046 {
3047 // check if RightHandSide exists as entry in LOCAL EDC first
3048 ElementDataContainer* localEDC = this->GetMBSParser()->GetLocalEDC(); // local context of the existing EDC
3049 if(localEDC && localEDC->TreeFind(text))
3050 {
3051 ElementData* ed_other = localEDC->TreeFind(text);
3052 if(ed_other->IsEDC())
3053 {
3054 found_as_edc = 1;
3055 ElementDataContainer* edc_new = new ElementDataContainer();
3056 edc_new->TreeReplaceEDCDataWith(ed_other->GetEDC()); // use TreeReplaceEDCDataWith to add the entries not clear the old ones
3057 ed.SetEDC(edc_new,elemname);
3058 }
3059 else
3060 {
3061 found_as_entry = 1;
3062 ed.CopyFrom(*ed_other);
3063 ed.SetDataName(elemname);
3064 }
3065 }
3066 }
3067 if (!(found_as_edc || found_as_entry))
3068 {
3069 // check if RightHandSide exists as entry in GLOBAL EDC first
3070 ElementDataContainer* globalEDC = this->GetMBSParser()->GetLocalEDC2(); // ROOT of the existing EDC
3071 if(globalEDC && globalEDC->TreeFind(text))
3072 {
3073 ElementData* ed_other = globalEDC->TreeFind(text);
3074 if(ed_other->IsEDC())
3075 {
3076 found_as_edc = 1;
3077 ElementDataContainer* edc_new = new ElementDataContainer();
3078 edc_new->TreeReplaceEDCDataWith(ed_other->GetEDC()); // use TreeReplaceEDCDataWith to add the entries not clear the old ones
3079 ed.SetEDC(edc_new,elemname);
3080 }
3081 else
3082 {
3083 found_as_entry = 1;
3084 ed.CopyFrom(*ed_other);
3085 ed.SetDataName(elemname);
3086 }
3087 }
3088 }
3089
3090 //// i++;
3091 ////}
3092 //!AD: ]
3093 if (!(found_as_edc || found_as_entry))
3094 {
3095 int errorflag;
3096 //////JG 2011-03-24
3097 //////Expression parser, using MBS_EDCs (edc_modeldata, mbs_edc_options, mbs_edc_global_variables) as variables
3098 ////double value = ExpressionToDouble(mbs, text, errorflag, line_cnt);
3099 //// if (errorflag)
3100 ////{
3101 //// ed.SetDouble(0, elemname);
3102 //// rv = 0;
3103 ////}
3104 ////else
3105 ////{
3106 //// ed.SetDouble(value, elemname);
3107 //// rv = 1;
3108 ////}
3109
3110 //AD 2012-12-10
3111 //Expression parser extended to Vector and Matrix variables
3112 double d_value = 0;
3113 Vector v_value(0.);
3114 Matrix m_value(0.);
3115 int2 rv_rowscols = mbsParser->EvaluateExpression(text, errorflag, d_value, v_value, m_value, line_cnt);
3116
3117 if (rv_rowscols == int2(1,1)) // scalar
3118 {
3119 if (errorflag) { ed.SetDouble(0, elemname); rv = 0; }
3120 else { ed.SetDouble(d_value, elemname); rv = 1; }
3121 }
3122 else if (rv_rowscols(1)==1 || rv_rowscols(2)==1) // vector
3123 {
3124 if (errorflag) { ed.SetVector(v_value.GetVecPtr(), 1, elemname); rv = 0; }
3125 else { ed.SetVector(v_value.GetVecPtr(), v_value.Length(), elemname); rv = 1;}
3126 }
3127 else // matrix
3128 {
3129 if (errorflag) { ed.SetMatrix(m_value.GetMatPtr(), 1, 1, elemname); rv = 0; }
3130 else { ed.SetMatrix(m_value.GetMatPtr(), m_value.Getrows(), m_value.Getcols(), elemname); rv = 1; }
3131 }
3132 }
3133 }
3134 }
3135 }
3136 return rv;
3137 }
3138
3139 //read a matrix or vector into ElementData
ReadMatrixVector(const mystr & text,ElementData & ed,const mystr & elemname,const mystr & dataname)3140 int CEDCParser::ReadMatrixVector(const mystr& text, ElementData& ed, const mystr& elemname, const mystr& dataname)
3141 {
3142 int rv = 1;
3143
3144 // col seperators : " " ","
3145 // row seperators : "\n" ";"
3146 TArray<double> ta_vec;
3147 mystr string_value; // string containing the next value
3148 mystr string_entirerow; // string containing the processed row
3149 int pos_value = 0; // position of next value to read
3150 int pos_in_string = 0; // position to which the string is read
3151 int pos_in_row = 0; // position to which the substring (row) is read
3152 int found_rowsep = 0; // position of next row separator
3153 int found_colsep = 0; // position of next column separator
3154 int rows=0; int cols=0; // number of rows, columns of the matrix
3155
3156 // check which separation chars are used
3157 text.ReadLeadingSpacesAndCountLines(pos_in_string, line_cnt); // !skip spaces at the beginning of text to prevent pos_space==0 (for the case that ' ' is column separator)
3158 int pos_comma = text.Find(pos_in_string,commac);
3159 int pos_space = text.Find(pos_in_string,spacec);
3160 int pos_tab = text.Find(pos_in_string,tabc);
3161 int pos_semi = text.Find(pos_in_string,semicolonc);
3162 int pos_newline = text.Find(pos_in_string,elc);
3163
3164 char colsep, rowsep;
3165 if ((pos_comma==-1)&&(pos_space==-1)) { colsep = commac; } // separation will not be found since this is a column vector
3166 if ((pos_comma > 0)&&(pos_space==-1)) { colsep = commac; } // separation with ','
3167 if ((pos_comma==-1)&&((pos_space > 0) || (pos_tab > 0))) { colsep = spacec; } // separation with ' '
3168 if ((pos_comma > 0)&&((pos_space > 0) || (pos_tab > 0))) { colsep = commac; } //mbs->UO(UO_LVL_warn) << "String2TreeEDC found column separators \",\" and \" \" in entry " << dataname <<". Check Textfile!\n"; }
3169
3170 if ((pos_semi==-1)&&(pos_newline==-1)) { rowsep = semicolonc; } // separation will not be found since this is a row vector
3171 if ((pos_semi > 0)&&(pos_newline==-1)) { rowsep = semicolonc; } // separation with ';'
3172 if ((pos_semi==-1)&&(pos_newline > 0)) { rowsep = elc; } // separation with '\n'
3173 if ((pos_semi > 0)&&(pos_newline > 0)) { rowsep = semicolonc; } // mbs->UO(UO_LVL_warn) << "String2TreeEDC found row separators \";\" and \"\\n\" in entry " << dataname <<". Check Textfile!\n"; }
3174
3175 while(pos_in_string != -1) // get -1 at end of text
3176 {
3177
3178 rows++;
3179 found_rowsep = text.GetUntil(pos_in_string, rowsep, string_entirerow);
3180 string_entirerow.Replace(tab, space);
3181
3182 int ccols = 0;
3183 pos_in_row = 0;
3184 string_entirerow.EraseSpacesHeadTail();
3185 string_entirerow.ReadLeadingSpacesAndCountLines(pos_in_row, line_cnt); // !skip spaces at the beginning of a new row (for the case that ' ' is column separator)
3186
3187 while(pos_in_row != -1 && rv) // get -1 at end of row
3188 {
3189 ccols++;
3190 string_entirerow.ReadLeadingSpaces(pos_in_row);
3191 found_colsep = string_entirerow.GetUntil(pos_in_row, colsep, string_value);
3192
3193 if(string_value.IsValidNumber())
3194 {
3195 ta_vec.Add(string_value.MakeDouble());
3196 }
3197 else
3198 {
3199
3200 int errorflag;
3201 double value = mbsParser->ExpressionToDouble(string_value, errorflag, line_cnt);
3202
3203 if (errorflag)
3204 {
3205 ta_vec.Add(0);
3206 rv = 0;
3207 }
3208 else
3209 {
3210 ta_vec.Add(value);
3211 rv = 1;
3212 }
3213 }
3214
3215 if(found_colsep) pos_in_row++; // next value
3216 else // check consistency
3217 {
3218 if(rows == 1)
3219 {
3220 cols = ccols;
3221 }
3222 else
3223 {
3224 mystr name = dataname;
3225 if (cols!=ccols)
3226 {
3227 mbs->UO(UO_LVL_warn) << "String2TreeEDC found mismatch in number of columns in entry " << name <<". Check Textfile!\n";
3228 rv = 0;
3229 }
3230 }
3231 }
3232 }
3233 if(found_rowsep) {pos_in_string++;} // next row
3234
3235 }
3236 Vector vec(ta_vec);
3237 if (rows <= 1) //if rows == 0, then assume vector
3238 {
3239 ed.SetVector(vec.GetVecPtr(), vec.Length(), elemname.c_str()); // vector
3240 }
3241 else
3242 {
3243 ed.SetMatrix(vec.GetVecPtr(), rows, cols, elemname.c_str()); // matrix
3244 }
3245
3246 return rv;
3247 }
3248
3249
3250 //####################################################################
3251 //b: STANDARD VERSION of ParseAndExecuteString (f.k.a. String2TreeEDC)
3252 // new version for parsing a string into an ElementDataContainer inclusive ToolTipText
3253 // 6.9.10 added parameter treestr: name of tree structure for recursive calls (parent history...)
3254 // 11.5.11 RL, AD: String2TreeEDC calls following recursive function "String2TreeEDC_recursive"
3255 // Please use only "String2TreeEDC"!!!
3256 // **.10.13 AD: functionality now only in ParseAndExecuteString
3257 // !! removed all calls to String2TreeEDC, removed implementation !!
3258 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3259 //definition of EDC-structure:
3260 // '%' | [identifier //comment or identifier appears
3261 // if identifier is not a function:
3262 // ['{' | '=' | '(' | '%'] //after identifier, either a structure opens '{' or a variable is assigned '=', a function is called '(' or a comment appears '%'
3263 // '{' ==> ['{ recursive_EDC }']
3264 // '=' ==> ['"' | '[...]' | [+-.1234567890] | mathobject/variable/function //read assignement: either string starts '"', vector/matrix '[...]', number, sin(2*pi*x)
3265 // ['%'] //comment might appear
3266 // ']' //end of identifier structure
3267 // if identifier is a function/command
3268 // '(function_parameters)' //read function parameters in paranthesis ()
3269 // '%' //comment might appear
3270 // '{' ==> ['{ recursive_EDC }'] //if function supports a statement block (e.g. if/for/while/etc), then recursively read edc and execute function e.g. for-loop
3271 // %
3272 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3273
3274 // AD 2013-09-24: these functions parses a string ans applies it ENTRY BY ENTRY to the target element data container
3275 // this function should replace the function StringToTreeEDC for the Commands "include", "for", etc...
3276 // code is basically copied from function StringToTreeEDC
ParseAndExecuteString(mystr str,ElementDataContainer & edc)3277 int CEDCParser::ParseAndExecuteString(mystr str, ElementDataContainer& edc)
3278 {
3279 // statistics on the string
3280 line_cnt = 0; //line counter in EDC
3281 total_lines = str.CountLines();
3282 mbs->UO(UO_LVL_dbg1) << "EDC total lines=" << total_lines << "\n";
3283
3284 // remember previous local EDC
3285 ElementDataContainer* prevlocaledc = mbsParser->GetLocalEDC();
3286
3287 // Set local variable context for the parser
3288 mbsParser->SetLocalEDC(&edc); //parsed (root-)edc is stored in local edc
3289
3290 // cal the recursive part - the actual parsing
3291 int rv = ParseAndExecuteString_recursive(str, edc);
3292
3293 // set local EDC back to previous
3294 mbsParser->SetLocalEDC(prevlocaledc);
3295
3296 return rv;
3297 }
3298
ParseAndExecuteString_recursive(mystr str,ElementDataContainer & edc)3299 int CEDCParser::ParseAndExecuteString_recursive(mystr str, ElementDataContainer& edc)
3300 {
3301 int rv = 1; //success
3302 int endstr = 0;
3303 int pos = 0;
3304 mystr dataname; // full name, may contain (sub-)tree
3305 mystr treename; // tree only
3306 mystr elemname; // varname only
3307 char ch;
3308 ElementData ed, return_value;
3309 mystr dummycomment; //dummy comment string
3310
3311
3312 int is_first_command = 1;
3313 TArray<ElementDataContainer*> parameter_EDCs;
3314
3315 // main loop
3316 while (!endstr && rv != 0)
3317 {
3318 ch = str.ReadLeadingSpacesAndCountLines(pos, line_cnt);
3319
3320 // skip lines that begin with comments (e.g. file header, ...)
3321 while (ch == commentc && pos != -1)
3322 {
3323 str.GetUntilEOL(pos, (char)0, dummycomment);
3324 ch = str.ReadLeadingSpacesAndCountLines(pos, line_cnt);
3325 }
3326
3327 int command_found = 0;
3328 if (pos == -1) //regular end of structure!
3329 {
3330 endstr = 1;
3331 }
3332
3333 //$AD 10-2013: new procedure for commands
3334 else
3335 {
3336 dataname = str.GetIdentifier(pos, 0); //name of data structure or data variable
3337 int com_id = IdentifyAndExecuteCommand(dataname, str, pos, ed, 0/*left hand side call*/);
3338
3339 if (com_id == -1)
3340 {
3341 rv = 0; // Parsing error occurred
3342 }
3343 else if (com_id > 0)
3344 {
3345 command_found = 1;
3346 //rv = 1; // command executed
3347 }
3348 else //if (com_id == 0)
3349 // NOT A COMMAND
3350 {
3351 // split into tree name and element name for assignment without full tree structure
3352 edc.SplitIntoTreeAndElementName(dataname,treename,elemname);
3353 }
3354 }
3355 //$AD: end new procedure for commands
3356
3357 if (pos == -1) //regular end of structure!
3358 {
3359 endstr = 1;
3360 }
3361 else if (command_found)
3362 {
3363 //do nothing, command already processed
3364 }
3365
3366 // BEGIN PARSING BEYOND DATANAME
3367 else
3368 {
3369 if (PrintOutput()) mbs->UO() << "Dataname='" << dataname << "'\n";
3370
3371 ch = str.ReadLeadingSpacesAndCountLines(pos, line_cnt);
3372
3373 while (ch == commentc && pos != -1)
3374 {
3375 str.GetUntilEOL(pos, (char)0, dummycomment);
3376 ch = str.ReadLeadingSpacesAndCountLines(pos, line_cnt);
3377 }
3378
3379 // FOUND "=": ASSIGNMENT of various types
3380 if (ch == eq)
3381 {
3382 //read data:
3383 pos++; //go after eq sign
3384 ch = str.ReadLeadingSpacesAndCountLines(pos, line_cnt);
3385
3386 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3387 if (ch == osb) //vector/matrix
3388 {
3389 mystr text = str.GetStringInBrackets(pos, osbc, csbc);
3390 ReadMatrixVector(text, ed, elemname, dataname);
3391 ReadComment(str, pos, ed, dataname);
3392 edc.TreeSet(treename,ed);//$JG2012-01-27: old if/else cases replaced //$ RL 2011-6-28:
3393 }
3394 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3395 //string expected
3396 else if (ch == doublequote)
3397 {
3398 mystr text = str.GetStringInBrackets(pos, doublequote, doublequote);
3399 ed.SetText(text, elemname);
3400 ReadComment(str, pos, ed, dataname);
3401 edc.TreeSet(treename,ed);//$JG2012-01-27: old if/else cases replaced //$ RL 2011-6-28:
3402 }
3403 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3404 //int, double, bool or regular expression
3405 else //must be double or integer number or "expression"
3406 {
3407 mystr text;
3408 int rv2 = str.GetUntilEOL(pos, commentc, text);
3409 if (rv2 == 2) {pos--;} //go back one character in order to find comment character in ReadComment(...) function hereafter
3410 // EVALUATE RIGHT HAND SIDE OF THE ASSIGNMENT ( could include COMMANDS )
3411 rv = ReadBoolIntDoubleExpression(text, pos, ed, elemname);
3412
3413 ReadComment(str, pos, ed, dataname);
3414 // ADD OR REPLACE ENTRYs
3415 edc.TreeSet(treename,ed);
3416 }
3417 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3418 // LINE IS PARSED - APPLY TO THE MODEL EDC
3419 }
3420 else if (ch == ob)
3421 // FOUND "{": SUB TREE - RECURSION
3422 {
3423 //read sub item
3424 mystr substr = str.GetStringInBrackets(pos, obc, cbc);
3425 if (pos != -1)
3426 {
3427 // check if tree already exists
3428 int i = edc.Find(elemname);
3429 if ((i != 0)&&(edc.Get(i).IsEDC())) // already exists as sub-edc
3430 {
3431 mbsParser->SetLocalEDC(edc.Get(i).GetEDC()); //$ RL 2011-5-11: //$ AD 2011-5-11: set local edc.
3432 rv = ParseAndExecuteString_recursive(substr, *(edc.Get(i).GetEDC()));
3433 mbsParser->SetLocalEDC(&edc); //$ RL 2011-5-11: //$ AD 2011-5-11: set local context edc back to value before recursion
3434 }
3435 else
3436 {
3437 ElementDataContainer* edc_sub = new ElementDataContainer(); //this is deleted when new EDC is set or EDC is deleted (old entry is always deleted)
3438 ed.SetBool(0,"dummy");
3439 int n = edc.Add(ed);
3440 edc.Get(n).SetEDCno_copy(edc_sub, elemname);
3441 mbsParser->SetLocalEDC(edc_sub); //$ RL 2011-5-11: //$ AD 2011-5-11: store sub-edc in local parser edc.
3442 rv = ParseAndExecuteString_recursive(substr, *edc_sub);
3443 mbsParser->SetLocalEDC(&edc); //$ RL 2011-5-11: //$ AD 2011-5-11: set local context edc back to value before recursion
3444 }
3445 }
3446 else
3447 {
3448 mbs->UO(UO_LVL_err) << "ParseAndExecuteString_recursive: could not read item '" << dataname << "' !\n";
3449 return 0; //end of file reached, not valid!
3450 }
3451 }
3452 // ??? ADD LEFT SIDE LIST ACCESS RIGHT HERE ???
3453 // DATANAME WAS FOLLOWED BY INVALID CHARACTER
3454 else
3455 {
3456 mbs->UO(UO_LVL_warn) << "did not expect '" << mystr(ch) << "' at line " << line_cnt+1 << " !\n";
3457 pos++;
3458 return 0; //end of file reached, not valid!
3459 }
3460
3461
3462 }
3463 } // end main loop
3464 return rv;
3465 }
3466
3467 //e: STANDARD VERSION of ParseAndExecuteString
3468 //############################################
3469
3470
3471 // AD 2013-10-16: single call for commands - collect code from String2TreeEDC and ReadBoolIntDoubleExpression - returns "com_id" (including 0 for no command) or "-1" on error
IdentifyAndExecuteCommand(mystr & dataname,mystr & str,int & pos,ElementData & return_value,int flag_RHS)3472 int CEDCParser::IdentifyAndExecuteCommand(mystr& dataname, mystr& str, int& pos, ElementData& return_value, int flag_RHS)
3473 {
3474 int n_params, option, has_return_value;
3475 int com_id = IdentifyCommand(dataname, n_params, has_return_value, option, flag_RHS);
3476
3477 if (com_id > 0) // command found
3478 {
3479 if(!version_check_performed)
3480 {
3481 ElementDataContainer* edc_local = mbsParser->GetLocalEDC();
3482 HotintDataFileVersionCheck(version_check_performed, *edc_local);
3483 }
3484
3485 TArray<ElementDataContainer*> parameter_EDCs;
3486 int parse_success = ParseCommandParameter(parameter_EDCs, dataname, n_params, str, pos, option);
3487
3488 if (parse_success)
3489 {
3490 // COMMAND IS IMMEDIATELY EXECUTED
3491 int rv = ExecuteCommand(com_id, parameter_EDCs, return_value, option);
3492 if(rv = 0)
3493 {
3494 com_id = -1; // error occurred during execute command
3495 }
3496 }
3497 else
3498 {
3499 com_id = -1; // error occurred during parsing of the command parameters
3500 }
3501
3502 for(int np=1;np<=parameter_EDCs.Length();np++)
3503 {
3504 delete parameter_EDCs(np); // delete edc's
3505 }
3506 }
3507 return com_id;
3508 }
3509
3510 // AD 2013-10-16: identifies command type and checks restrictions - returns "com_id" (including 0 for no command) or "-1" on error
IdentifyCommand(mystr & dataname,int & n_params,int & has_return_value,int & option,int flag_RHS)3511 int CEDCParser::IdentifyCommand(mystr& dataname, int& n_params, int& has_return_value, int& option, int flag_RHS )
3512 {
3513 mystr handlename; // treename
3514 mystr commandname; // elementname
3515 ElementDataContainer* edc_local = mbsParser->GetLocalEDC();
3516 edc_local->SplitIntoTreeAndElementName(dataname, handlename, commandname);
3517
3518 // find registered command
3519 int com_id = GetCommandType(commandname, n_params, has_return_value, option);
3520
3521 if(com_id > 0)
3522 // perform consistency checks
3523 {
3524 // check 1: some commands are left hand side only (IF, FOR, ..)
3525 if ((option & TCO_LeftHandSideOnly) && flag_RHS)
3526 {
3527 EDCError(mystr("Right hand side call of Function '")+commandname+mystr("' is not allowed!"));
3528 return -1;
3529 }
3530
3531 // check 2: commands requiring a handle
3532 else if (option & TCO_RequiresHandle)
3533 {
3534 // call of a handle command is "HANDLE.COMMAND" so HANDLE must be registered in the current EDC
3535 if (handlename.Length())
3536 {
3537 int i = edc_local ->Find(handlename);
3538 if ((i != 0) && edc_local->Get(i).IsEDC())
3539 {
3540 // check if the handle is indeed a handle-object
3541 ElementDataContainer* edc_handle = edc_local->Get(i).GetEDC();
3542 int j = edc_handle->Find("isHandle");
3543 if (j==0)
3544 {
3545 EDCError(mystr("Handle '")+handlename+mystr("' for command '")+commandname+mystr("' is not a valid handle '"));
3546 return -1;
3547 }
3548 else
3549 {
3550 j = edc_handle->Find("Functions");
3551 if ((j!=0) && edc_handle->Get(j).IsEDC())
3552 {
3553 // check if the command is registered to the handle
3554 ElementDataContainer* edc_registered = edc_handle->Get(j).GetEDC();
3555 int k = edc_registered->Find(commandname);
3556 if (k!=0)
3557 {
3558 ;
3559 }
3560 else
3561 {
3562 EDCError(mystr("Function '")+commandname+mystr("' is not registered for Handle '")+handlename);
3563 return -1;
3564 }
3565 }
3566 else
3567 {
3568 EDCError(mystr("Handle '")+handlename+mystr("' has no allowed functions'"));
3569 return -1;
3570 }
3571 }
3572 }
3573 }
3574 }
3575 // check 2b: when a handle is present and
3576 else //(if !(option & TCO_RequiresHandle))
3577 {
3578 if (handlename.Length())
3579 {
3580 int i = edc_local ->Find(handlename);
3581 if ((i != 0) && edc_local->Get(i).IsEDC())
3582 {
3583 // check if the handle is indeed a handle-object
3584 ElementDataContainer* edc_handle = edc_local->Get(i).GetEDC();
3585 int j = edc_handle->Find("isHandle");
3586 if (j !=0)
3587 {
3588 EDCError(mystr("Function '")+commandname+mystr("' does not require a handle but is associated with one ('")+handlename+mystr("')"));
3589 return -1;
3590 }
3591 }
3592 }
3593 }
3594 }
3595 return com_id;
3596 }
3597
3598 // AD 2013-10-16: parses parameters into EDCs - returns "1" on success and "0" on error
ParseCommandParameter(TArray<ElementDataContainer * > & parameter_EDCs,mystr & dataname,int n_params,mystr & str,int & pos,int option)3599 int CEDCParser::ParseCommandParameter(TArray<ElementDataContainer*>& parameter_EDCs, mystr& dataname, int n_params, mystr& str, int& pos, int option)
3600 {
3601 int rv = 1;
3602 parameter_EDCs.SetLen(0);
3603
3604 //read parameter text
3605 mystr param_text = str.GetStringInBrackets(pos, ofc, cfc);
3606 if (param_text == mystr("") && n_params != 0)
3607 {
3608 EDCError(mystr("Expected ")+mystr(n_params)+mystr(" function parameters but received zero parameters in function '")+dataname+mystr("'"));
3609 rv = 0;
3610 }
3611 else
3612 {
3613 int prv = GetParameterEDC(param_text, parameter_EDCs); // fill parameter_EDCs with NEW edc's
3614 if (!prv)
3615 {
3616 EDCError(mystr("Function parameters '")+param_text+("' of function '")+dataname+mystr("' are not valid or incomplete"));
3617 rv = 0;
3618 }
3619 if (parameter_EDCs.Length() != n_params)
3620 {
3621 EDCError(mystr("Received ")+mystr(parameter_EDCs.Length())+(" function parameters, but function")+dataname+(" should have ")+mystr(n_params)+mystr(" parameters"));
3622 rv = 0;
3623 }
3624 else
3625 {
3626 // additional parameter EDC contains (code-)container
3627 if (option & TCO_FollowedByContainer)
3628 {
3629 while (str[pos] != obc) pos++;
3630 mystr codeincontainer = str.GetStringInBrackets(pos,obc,cbc);
3631 ElementData code;
3632 code.SetText(codeincontainer,"code");
3633 ElementDataContainer* codecontainer = new ElementDataContainer;
3634 codecontainer->Add(code);
3635 parameter_EDCs.Add(codecontainer);
3636 }
3637 // additional parameter EDC contains the handle
3638 if (option & TCO_RequiresHandle)
3639 {
3640 ElementDataContainer* local = mbsParser->GetLocalEDC();
3641 mystr handlename, commandname;
3642 local->SplitIntoTreeAndElementName(dataname, handlename, commandname);
3643
3644 //validity check only here
3645 int j = local->Find(handlename);
3646 if(j != 0 && local->Get(j).IsEDC())
3647 {
3648 //ElementDataContainer* edc_handle = local->Get(j).GetEDC();
3649 ElementData handle;
3650 handle.SetText(handlename,"handle");
3651 ElementDataContainer* handlecontainer = new ElementDataContainer;
3652 handlecontainer->Add(handle);
3653 parameter_EDCs.Add(handlecontainer);
3654 }
3655 else
3656 {
3657 EDCError(mystr("Handle '")+handlename+mystr("' could not be linked to Command '")+commandname+mystr("'. call only in local context!"));
3658 rv = 0;
3659 }
3660 }
3661 }
3662 }
3663 return rv;
3664 }
3665
3666 //execute a command with type_id, a list of EDCs for command parameters and an option
ExecuteCommand(int command_type_id,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)3667 int CEDCParser::ExecuteCommand(int command_type_id, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
3668 {
3669 return commands(command_type_id)->ExecuteCommand(GetMBS(), this, parameter_EDCs, return_value, option);
3670 }
3671
3672 // AD 2013-10-16: perform a check for the datafile version (once)
HotintDataFileVersionCheck(int & version_check_performed,ElementDataContainer & edc)3673 int CEDCParser::HotintDataFileVersionCheck(int& version_check_performed, ElementDataContainer& edc)
3674 {
3675 version_check_performed = 1;
3676 mystr tmp_str = edc.TreeGetString("HOTINT_data_file_version");
3677 if(tmp_str.Length())
3678 {
3679 HotintVersionInfo ver_file(tmp_str); // version in the input file
3680 HotintVersionInfo ver = mbs->GetHotintVersion();
3681 int ver_log = ver.GetLogNumber();
3682 int ver_file_log = ver_file.GetLogNumber();
3683 if((ver > ver_file) || ((ver == ver_file) && (ver_log > ver_file_log)))
3684 {
3685 mbs->UO(UO_LVL_warn) << "WARNING: The input file was created with an old version of HOTINT. This may be the reason for errors. The actual version of HOTINT is '" << mbs->GetHotintVersion().GetString() << "'. To avoid this warning, check the functionality of the input file and correct the HOTINT_data_file_version in the input file afterwards.\n";
3686 }
3687 }
3688 else
3689 {
3690 mbs->UO(UO_LVL_warn) << "WARNING: The input file does not contain the variable HOTINT_data_file_version which indicates, that it has probably been created with an old version of HOTINT. This may be the reason for errors. The actual version of HOTINT is '" << mbs->GetHotintVersion().GetString() << "'. To avoid this warning, check the functionality of the input file and set the variable HOTINT_data_file_version in the input file right at the beginning.\n";
3691 }
3692 return 1;
3693 }
3694
3695
3696
3697 // DR 2013-01-14: this function evaluates a command of the parser, using the parameter_EDC as additional input data
3698 // AD 2013-10-16: remark: can be called from .cpp model for a) testing new script function, b) use existing script routines
ExecuteParserCommand(mystr & command,TArray<ElementDataContainer * > & parameter_EDCs,ElementData & return_value,int option)3699 int CEDCParser::ExecuteParserCommand(mystr & command, TArray<ElementDataContainer*>& parameter_EDCs, ElementData& return_value, int option)
3700 {
3701 int pos = 0;
3702 mystr elemname = "element_name";
3703 ElementDataContainer *edc;
3704 ElementData ed;
3705
3706 if(parameter_EDCs.Length())
3707 {
3708 edc = parameter_EDCs(1);
3709 ed.SetEDC(edc, "parameter_EDC");
3710 mbsParser->SetLocalEDC(edc);
3711 }
3712 else
3713 {
3714 ed.SetBool(1,"empty");
3715 }
3716
3717 int rv = ReadBoolIntDoubleExpression(command, pos, ed, elemname);
3718
3719 return rv;
3720 }
3721
3722 //$ DR 2013-07-04:
3723 // checks if filename has relative path, and if yes, converts it into an absolute one
3724 // relative means relative to last_file_name and this is the file in which e.g. the command "Include" is used
MakeFilenameAbsolute(mystr & filename)3725 int CEDCParser::MakeFilenameAbsolute(mystr& filename)
3726 {
3727 int rv = 0; //1=success
3728 int pos = 1;
3729 int isRelativePath = filename.PosPeek(pos) != ':';
3730 if(isRelativePath)
3731 {
3732 mystr rel_path("");
3733 mystr last_file_name = mbs->GetModelDataContainer()->TreeGetString("last_file_name");
3734
3735 int until;
3736 for(until=last_file_name.Length()-1;until>=0;until--)
3737 {
3738 if(last_file_name.PosPeek(until) == '\\')
3739 break; // until <=> last backslash
3740 }
3741 for(int i=0;i<=until;i++)
3742 {
3743 rel_path += last_file_name.PosPeek(i); // path until last backslash
3744 }
3745
3746 // remove ..\
3747 int pos=rel_path.Length()-1;
3748 if(rel_path.PosPeek(pos)=='\\')
3749 {
3750 rel_path.EraseChar(pos+1);
3751 }
3752
3753 int replaced = filename.Replace(mystr("..\\"), mystr("")); //find string searchstr, replace with string replacestr; this is done repeatedly; the return value counts the number of replacements
3754
3755 for(int pos=rel_path.Length();pos>0;pos--)
3756 {
3757 if(!replaced){break;}
3758 int prev = pos-1;
3759 if(rel_path.PosPeek(prev)=='\\')
3760 {
3761 replaced --;
3762 }
3763 rel_path.EraseChar(pos);
3764 }
3765 filename = rel_path + mystr("\\") + filename;
3766 rv = MakeFilenameAbsolute(filename); // recursive check
3767 }
3768 else
3769 {
3770 rv = 1; // no change --> success
3771 }
3772 if(rv<1)
3773 {
3774 //edcParser->EDCError(mystr("Error happened during CEDCParser::MakeFilenameAbsolute ");
3775 }
3776 return rv;
3777 }