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 }