1 //#**************************************************************
2 //#
3 //# filename:             mbs_communication.cpp
4 //#
5 //# author:               Gerstmayr Johannes
6 //#
7 //# generated:						March 2010
8 //# description:          Load/Save mbs data, WCDriver and Windows communication
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 
25 #include "windows.h" //for shell execute
26 #include <direct.h>  //for getcwd
27 #include  <io.h>     //file operation _access
28 #include  <stdio.h>
29 #include  <stdlib.h>
30 
31 #include "mbs.h"
32 #include "parser.h"
33 #include "script_parser.h"
34 #include "myfile.h"
35 #include "element.h"
36 #include "sensors.h"
37 #include "node.h"
38 #include "material.h"
39 #include "elementdataaccess.h"
40 
41 
SaveSolutionVector(const mystr & filename)42 int MultiBodySystem::SaveSolutionVector(const mystr& filename)  //rv=1 --> OK
43 {
44 	int opt = ios::out;
45 
46 
47 	ofstream* storeout = new ofstream;
48 #ifdef my_new_stdiostream
49 	storeout->open(filename.c_str(), opt); //with read sharing allowed!
50 #else
51 	storeout->open(filename.c_str(), opt, filebuf::sh_read); //with read sharing allowed!
52 #endif
53 
54 	if ((int)storeout->good() == 0 || storeout->fail())
55 	{
56 		UO() << "ERROR: could not write solution!!!\n";
57 		UO() << "good=" << storeout->good() << ", fail=" << storeout->fail() << "\n";
58 		UO() << "file=" << filename.c_str() << "\n";
59 
60 		//storeout->close();
61 		//storeout->delete;
62 		//return 0;
63 	}
64 	storeout->precision(19);
65 	int len = GetSolVector().Length();
66 
67 	char str[256];
68 	sprintf(str, "HOTINTDataVersion%.3f", GetHotintVersion().GetDoubleValue());
69 	(*storeout) << str << "\n";
70 	(*storeout) << len << " 0" << "\n"; //checksums!
71 	(*storeout) << "1\n"; //only one step stored
72 
73 	char strtime[64];
74 	char strtime2[64];
75 	sprintf(strtime, "%.14f", GetTime());
76 	sprintf(strtime2, "%.17f", GetTime());
77 
78 	if (strlen(strtime) < strlen(strtime2)-4)
79 		(*storeout) << strtime << "\n";
80 	else
81 		(*storeout) << strtime2 << "\n";
82 
83 	(*storeout) << len << "\n";
84 	for (int i = 1; i <= len; i++)
85 	{
86 		(*storeout) << GetSol(i) << "\n";
87 	}
88 
89 	storeout->close();
90 	delete storeout;
91 
92 	return 1;
93 }
94 
LoadInitialVector(const mystr & filename)95 int MultiBodySystem::LoadInitialVector(const mystr& filename)  //rv=1 --> OK
96 {
97 	CMFile storein(filename, TFMread);
98 	Vector x0(GetSystemSize());
99 
100 	stored_initialconditions = GetSolVector();
101 
102 	if (!storein.IsGood())
103 	{
104 		UO() << "ERROR: could not open stored solution!!!\n";
105 		return 0;
106 	}
107 	else
108 	{
109 		//storein->seekg(0,ios::beg);
110 
111 		//read either version or length:
112 		mystr header;
113 		storein.RWSoleStr(header);
114 
115 		if (header.Length() > 17 && header.Left(17) == mystr("HOTINTDataVersion"))
116 		{
117 			//UO() << "Load initial vector with header\n"; //--> e.g. stored in Data manager
118 
119 			mystr version_str = header.Right(header.Length()-17);
120 			//UO() << "Version number ='" << version << "'\n";
121 
122 			HotintVersionInfo data_version(atof(version_str));
123 
124 			if (data_version > GetHotintVersion())
125 			{
126 				UO() << "Warning: This is a solution vector of another HOTINT version, the data may be corrupt!\n";
127 			}
128 
129 			int ndof, checksum2, nsteps;
130 			storein.RWInt(ndof);
131 			storein.RWInt(checksum2);
132 			storein.RWInt(nsteps);
133 
134 			if (ndof != x0.Length()) {UO() << "Warning: Stored solution does have different size!!!\n";}
135 			if (nsteps != 1) {UO() << "Warning: Stored solution contains " << nsteps << " data units, only the first data unit is loaded!\n";}
136 		}
137 
138 		double time;
139 		int len;
140 
141 		storein.RWDouble(time);
142 		storein.RWInt(len);
143 
144 		//UO() << "time=" << time << ", len=" << len << "\n";
145 
146 		if (len > x0.Length()) {UO() << "ERROR: Stored solution is incompatible!!!\n";}
147 		else
148 		{
149 			for (int i=1; i <= len; i++) //additionally check for storein->good() ....???
150 			{
151 				storein.RWDouble(x0(i));
152 			}
153 			stored_initialconditions = x0;
154 			//UO() << "WARNING: solution vector added!!!!!\n";
155 
156 			//UO() << "Stored solution loaded!\n";
157 		}
158 	}
159 
160 	return 1;
161 }
162 
163 
164 //type=1: element
165 //type=2: force	i				//$ DR 2012-10 old:force value of element i
166 //type=3: sensor i
167 //type=4: geomelement i
168 //type=5: node i
169 //type=6: material i
170 //type=50: KB options (old)
GetElementData(int i,int type,int value,ElementDataContainer & edc)171 void MultiBodySystem::GetElementData(int i, int type, int value, ElementDataContainer& edc)
172 {
173 	switch (type)
174 	{
175 	case 1: //element data
176 		{
177 			GetElement(i).GetElementData(edc);
178 			break;
179 		}
180 	case 2: //force value of element i, force value
181 		{
182 			//GetElement(i).GetLoad(value).GetElementData(edc); //$ DR 2012-10 old code
183 			GetLoad(i).GetElementData(edc);
184 			break;
185 		}
186 	case 3: //sensor i data
187 		{
188 			GetSensor(i).GetElementData(edc);
189 			break;
190 		}
191 	case 4: //geomelement i data
192 		{
193 			GetDrawElement(i)->GetElementData(edc);
194 			break;
195 		}
196 	case 5: //Node i data
197 		{
198 			GetNode(i).GetElementData(edc);
199 			break;
200 		}
201 	case 6: //Material i data
202 		{
203 			GetMaterial(i).GetElementData(edc);
204 			break;
205 		}
206 	default: ;
207 	}
208 }
209 
SetElementData(int i,int type,int value,ElementDataContainer & edc)210 int MultiBodySystem::SetElementData(int i, int type, int value, ElementDataContainer& edc)
211 {
212 	int rv = 1;
213 	switch (type)
214 	{
215 	case 1: //element data
216 		{
217 			rv = GetElement(i).SetElementData(edc);
218 			break;
219 		}
220 	case 2: //force value of element i, force value
221 		{
222 			//rv = GetElement(i).GetLoad(value).SetElementData(edc); //$ DR 2012-10 old code
223 			rv = GetLoad(i).SetElementData(edc);
224 			break;
225 		}
226 	case 3: //sensor i data
227 		{
228 			rv = GetSensor(i).SetElementData(edc);
229 			break;
230 		}
231 	case 4: //geomelement i data
232 		{
233 			rv = GetDrawElement(i)->SetElementData(edc);
234 			break;
235 		}
236 	case 5: //Node i data
237 		{
238 			rv = GetNode(i).SetElementData(edc);
239 			break;
240 		}
241 	case 6: //Node i data
242 		{
243 			rv = GetMaterial(i).SetElementData((ElementDataContainer &)edc);
244 			break;
245 		}
246 		//#ifdef KB_INCLUDES
247 		//	case 50: //edit KB menu
248 		//		{
249 		//			kbmenu.SetElementData(edc);
250 		//			break;
251 		//		}
252 		//#endif
253 	default: ;
254 	}
255 	return rv;
256 }
257 
258 //$AD 2013-07-08: Manipulate Content of arrays in IOElements from 2D Draw Window
InsertIOElemConNode(int elemnr,int list_idx,int input_nr,Vector2D pos)259 void MultiBodySystem::InsertIOElemConNode(int elemnr, int list_idx, int input_nr, Vector2D pos)
260 {
261 	GetElement(elemnr).InsertConNode(list_idx, input_nr, pos);
262 }
DeleteIOElemConNode(int elemnr,int list_idx)263 void MultiBodySystem::DeleteIOElemConNode(int elemnr, int list_idx)
264 {
265 	GetElement(elemnr).DeleteConNode(list_idx);
266 }
267 //$AD 2013-07-10: Change Position of a single element (MBS element, conNode, ...)
MoveConNode2D(int elemnr,int list_idx,double delta_x,double delta_y)268 void MultiBodySystem::MoveConNode2D(int elemnr, int list_idx, double delta_x, double delta_y)
269 {
270 	GetElement(elemnr).MoveConNode2D(list_idx, delta_x, delta_y);
271 }
MoveElement(int elemnr,double delta_x,double delta_y,double delta_z)272 void MultiBodySystem::MoveElement(int elemnr, double delta_x, double delta_y, double delta_z)
273 {
274 	GetElement(elemnr).MoveElement(delta_x, delta_y, delta_z);
275 }
276 
277 //action=1: option=0: Set initial conditions, option=1: Initialize
278 //action=2: Add Element: deprecated
279 //action=3: Assemble system
280 //action=4: Delete Element value
281 //action=5: Delete force value
282 //action=6: Add force: deprecated
283 //action=7: Add sensor:: deprecated
284 //action=8: Delete sensor value
285 //action=9: Add GeomElement: deprecated
286 //action=10:Delete GeomElement value
287 //action=11: Add Node: deprecated
288 //action=12: Delete Node value
289 //action=13: Swap element: deprecated
290 //action=14: Add Material: deprecated
291 //action=15: Delete Material value
292 
293 //action=20: ModelFunction: option=1: get ModelFunctionList
294 //
295 //action=30: Call Element functions in response to action in IOBlockView Window...
296 
297 //action=101: save MBS system to file (file name in edc.Find("File_name")+directory, .GetText() (option=1: with Options, =0: only MBS)
298 //action=102: load MBS system from file (file name in edc.Find("File_name")+directory, .GetText()
299 //action=103: save actual solution vector (file name in edc.Find("File_name")+directory, .GetText()
300 //action=104: load initial solution vector (file name in edc.Find("File_name")+directory, .GetText()
301 //action=105: clear initial solution vector (setlen = 0 means initial solution is not used)
302 //action=106: LoadMBSEDCConfiguration
303 //action=107: SaveMBSEDCConfiguration; ; all:value==0, solver:value==1, hotint:value==2;
304 //
305 //action=110: Load EDC from file (file name in edc.Find("File_name")+directory, .GetText()
306 //action=111: Save EDC to file (file name in edc.Find("File_name")+directory, .GetText()
307 //action=112: The input-edc gets written into a mystr, the mystr is returned in the same edc
308 //
309 //action=121: plot single sensor value in matlab
310 //action=122: plot two sensors (x-y-plot) in matlab
311 //action=123: plot n sensors (vs time) in matlab
312 //
313 //action=201: GetNSensors()
314 //action=202: Get Element Names in edc-data
315 //action=203: Get Sensor Names in edc-data
316 //            option 1: return writeresult flag as int element data
317 //action=204: Get Sensor value of sensor number 'value' in edc-data
318 //action=205: Get GeomElement Names in edc-data
319 //action=206: Get Number of nodes
320 //action=207: Get Name of nodes
321 //action=208: Get Number of total DOF
322 //action=209: Get Material Names in edc-data
323 //action=210: Get/Set EditAllOptions in edc-data Get:option==0, Set:option==1;    all:value==0, solver:value==1, hotint:value==2;
324 //action=211: Get/Set Model ElementDataContainer
325 //action=212: SetOptions: Options2EDC/EDC2Options, etc.
326 //action=213: Get Sensors data array(reference), DataArray:option=0, TimesArray:option=1
327 //action=214: Get Load Names in edc-data	//$ DR 2012-10
328 //
329 //action=301: Show System properties
330 //action=302: Check System properties
331 
332 //action=320: Compute Eigenmodes (option=1: sparse, =0: direct)
333 
CallCompFunction(int action,int option,int value,ElementDataContainer * edc)334 int MultiBodySystem::CallCompFunction(int action, int option, int value, ElementDataContainer* edc)
335 {
336 	Vector3D defaultbodycol(0.2,0.2,0.8);
337 	Vector3D defaultconstraintcol(0.2,0.8,0.2);
338 	Vector3D defaultbodypos(0.,0.,0.);
339 	Vector3D defaultbodyvel(0.,0.,0.);
340 	Vector3D defaultbodyangle(0.,0.,0.);
341 	Vector3D defaultbodyangularvel(0.,0.,0.);
342 	Vector3D defaultbodysize(1.,1.,1.);
343 	double defaultbodyrho = 1000;
344 	Vector3D defaultconstraintdim(0.1,0.1,16.);
345 
346 	int defaultsensorvisible = 1;
347 	SensorSignalStorageMode defaultSignalStorageMode = (SensorSignalStorageMode)(SSM_OwnFile | SSM_CommonFile);
348 	int defaultsensorprecision = 17;
349 	Vector3D defaultsensordrawdim(0.001,6,0);
350 
351 
352 	//flexible bodies:
353 	double defaultbodyEm = 1e8;
354 	double defaultbodynu = 0.;
355 
356 	int rv = 1;
357 	switch(action)
358 	{
359 	case 1: //Set initial conditions
360 		{
361 			if (option == 0)
362 				SetInitialConditions();
363 			else if (option == 1)
364 				Initialize(); //this resets the whole MBS model
365 
366 			break;
367 		}
368 	case 2: //Add Element of type "value"
369 		{
370 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
371 			break;
372 		}
373 	case 3: //Assemble system
374 		{
375 			Assemble();
376 			break;
377 		}
378 	case 4: //Delete element "value"
379 		{
380 			if(value<=NE())
381 			{
382 				DeleteElement(value);
383 			}
384 			else
385 			{
386 				UO() << "Error: element " << value << " does not exist!!!\n";
387 			}
388 			break;
389 		}
390 	case 5: //Delete force "value"
391 		{
392 			if(value<=NLoads())
393 			{
394 				DeleteLoad(value);
395 			}
396 			else
397 			{
398 				UO() << "Error: load " << value << " does not exist!!!\n";
399 			}
400 			break;
401 		}
402 	case 6: //Add Force type "value"
403 		{
404 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
405 			break;
406 		}
407 	case 7: //Add Sensor type "value"
408 		{
409 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
410 			break;		}
411 	case 8: //Delete sensor "value"
412 		{
413 			if (value >= 1 && value <= this->NSensors())
414 			{
415 				DeleteSensor(value);
416 			}
417 			else
418 			{
419 				UO() << "Error: sensor " << value << " does not exist!!!\n";
420 			}
421 			break;
422 		}
423 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
424 	case 9: //Add GeomElement SensorTypeNameList above!!!
425 		{
426 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
427 			break;		}
428 	case 10: //action: Delete GeomElement "value"
429 		{
430 			if (value >= 1 && value <= NDrawElements())
431 			{
432 				DeleteDrawElement(value);
433 			}
434 			else
435 			{
436 				UO() << "Error: geom element " << value << " does not exist!!!\n";
437 			}
438 			break;
439 		}
440 	case 11: //action: Add Node
441 		{
442 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
443 			break;
444 		}
445 	case 12: //action: Delete Node "value"
446 		{
447 			if (value >= 1 && value <= NNodes())
448 			{
449 				DeleteNode(value); //delte this node and reorder node references in elements!
450 			}
451 			else
452 			{
453 				UO() << "Error: Node " << value << " does not exist!!!\n";
454 			}
455 			break;
456 		}
457 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458 	case 13: //action: Swap element "value" with element "option"
459 		{
460 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
461 			break;		}
462 
463 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
464 	case 14: //action: Add Material
465 		{
466 			UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
467 			break;		}
468 	case 15: //action: Delete Material "value"
469 		{
470 			if (value >= 1 && value <= NMaterials())
471 			{
472 				DeleteMaterial(value); //delete this material and reorder material numbers in elements!
473 			}
474 			else
475 			{
476 				UO() << "Error: Material " << value << " does not exist!!!\n";
477 			}
478 			break;
479 		}
480 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
481 		//action=20: ModelFunction: option=1: get ModelFunctionList
482 	case 20: //action: Get ModelFunctionList
483 		{
484 			if (option == 1) //get ModelFunctionList
485 			{
486 				ElementData ed;
487 				//$ YV 2013-01-04: model function index is now 1-based
488 				for (int i=1; i <= GetModelsLibrary()->GetModelsCount(); i++)
489 				{
490 					ed.SetText(GetModelsLibrary()->GetModelInterface(i)->GetMBSModelName());
491 					ed.SetToolTipText(GetModelsLibrary()->GetModelInterface(i)->GetMBSModelDescription());
492 					edc->Add(ed);
493 				}
494 				//GetIOption(12) = GetModelFunctionsIndex0();
495 			}
496 			else if (option == 2) //ModelFunctionChanged
497 			{
498 				if (GetModelDataContainer()) {GetModelDataContainer()->Reset();}		// DR hack
499 				ModelFunctionChanged();
500 			}
501 			else if (option == 3) //Initialize
502 			{
503 				Initialize();
504 			}
505 			else if (option == 4) //get modelfunctionindex
506 			{
507 				ElementData ed;
508 				ed.SetInt(GetModelFunctionsIndex0(),"model_function_index");
509 				edc->Add(ed);
510 			}
511 			break;
512 		}
513 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
514 	case 30: //action: Call Element functions in response to action in IOBlockView Window...
515 		{
516 			int elnr = option;
517 			Element& elem = GetElement(elnr);
518 
519 			if (value == 0)
520 			{
521 				if (GetElement(elnr).GetElementSpecification().Compare(mystr("IOMouseResponseElement")) )
522 					rv = 1;
523 				else
524 					rv = 0;
525 			}
526 
527 			// allow modifications 1 -> add 1, and -1 -> subtract 1
528 			if (value == 1)
529 			{
530 				elem.Increase();
531 			}
532 			if (value == -1)
533 			{
534 				elem.Decrease();
535 			}
536 			break;
537 		}
538 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
539 	case 31: // action: call MBS-wide response to a Keyboard input
540 		{
541 			int key = option;
542 			int nr_of_changes = RespondToKey(key);
543 			rv = nr_of_changes;
544 			break;
545 		}
546 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
547 		//load/save etc.
548 	case 101: //save to file
549 		{
550 			mystr filename, dirname;
551 			GetElemDataText(this, *edc, "File_name", filename);
552 			GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
553 
554 			isloadsavemode = 1;
555 			SaveToFile(dirname+filename,option);
556 			isloadsavemode = 0;
557 			break;
558 		}
559 	case 102: //load from file
560 		{
561 			mystr filename, dirname;
562 			GetElemDataText(this, *edc, "File_name", filename);
563 			GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
564 
565 			isloadsavemode = 1;
566 			rv = LoadFromFile(dirname+filename);
567 			isloadsavemode = 0;
568 
569 			break;
570 		}
571 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
572 	case 103: //save actual solution vector
573 		{
574 			mystr filename, dirname;
575 			GetElemDataText(this, *edc, "File_name", filename);
576 			GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
577 
578 			SaveSolutionVector(dirname+filename);
579 			break;
580 		}
581 	case 104: //load initial solution vector
582 		{
583 			mystr filename, dirname;
584 			GetElemDataText(this, *edc, "File_name", filename);
585 			GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
586 
587 			LoadInitialVector(dirname+filename);
588 			break;
589 		}
590 	case 105: //clear initial solution vector (setlen = 0 means initial solution is not used)
591 		{
592 			//UO() << "Stored initial vector cleared!\n";
593 			stored_initialconditions.SetLen(0);
594 			break;
595 		}
596 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
597 	case 106: //Load_MBS_EDC_config_file
598 		{
599 			mystr filename = "hotint_cfg.txt";
600 			CMFile file(filename, TFMread);
601 
602 			//set default options, if file can not be loaded!
603 			SetSolverDialogOptions();
604 
605 			SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree to
606 
607 			OpenLogFile(0);
608 
609 			ElementDataContainer fileedc;
610 
611 			if (file.IsGood())
612 			{
613 				UO() << "load configuration file 'hotint_cfg.txt'\n";
614 
615 				mystr str;
616 				file.RWF(str); //read file
617 
618 				// AD 2013-10-22 use new routine to parse
619 				EDCParser().ParseAndExecuteString(str,fileedc);
620 //				EDCParser().String2TreeEDC(/*this, */str, fileedc);
621 
622 				//$ DR 2013-03-18 for release version, do not use stored model name
623 				if(!fileedc.TreeGetBool("GeneralOptions.Application.reload_last_model",0))
624 				{
625 					fileedc.TreeDelete("GeneralOptions.ModelFile.hotint_input_data_filename");
626 					fileedc.TreeDelete("GeneralOptions.ModelFile.internal_model_function_name");
627 					mystr tmp("");
628 					fileedc.TreeSetString("GeneralOptions.ModelFile.hotint_input_data_filename", tmp.c_str());
629 					tmp = mystr("new model");
630 					fileedc.TreeSetString("GeneralOptions.ModelFile.internal_model_function_name", tmp.c_str());
631 				}
632 
633 				//replace default option parameters with loaded parameters
634 				GetMBS_EDC_Options()->TreeReplaceEDCDataWith(&fileedc);
635 			}
636 			else
637 			{
638 				UO() << "Warning: Could not read hotint configuration file 'hotint_cfg.txt'. Default values are used instead. Press 'Save Hotint Options' to create this file.\n";
639 				rv = 0;
640 			}
641 
642 			//at this point, use arguments of program start to add some functionality:
643 			mystr modeldata_argstr = "";
644 			mystr mbsedc_argstr = "";
645 			int narg = __argc;
646 
647 			for (int i=0; i < narg; i++)
648 			{
649 				mystr argstr = __argv[i];
650 				UO(UO_LVL_ext) << "hotint.exe argument " << i << "='" << argstr << "'";
651 
652 				//$ RL 2012-7-25:[
653 				if(i == 0) // i==0 --> store application path
654 				{
655 					// get application path, (path of hotint.exe)
656 					mystr app_path("");
657 					{
658 						int until;
659 						for(until=argstr.Length()-1;until>=0;until--)
660 						{
661 							if(argstr.PosPeek(until) == '\\')
662 								break; // until <=> last backslash
663 						}
664 						for(int i=0;i<=until;i++)
665 						{
666 							app_path += argstr.PosPeek(i); // path until last backslash
667 						}
668 						argstr = "GeneralOptions.Paths.application_path=\"" + app_path+ "\"";
669 					}
670 				}
671 				else if(i == 1) // i==1 --> from drag&drop or command line
672 				{
673 					mystr hid_file("");
674 					int pos = argstr.Find(mystr(".hid"));
675 					if(pos == -1)
676 					{
677 						pos = argstr.Find(mystr(".hmc"));		//$ DR 2012-12-10 this ending is also supported
678 					}
679 					if(pos == -1 && GetMBS_EDC_Options()->TreeGetBool("GeneralOptions.ModelFile.accept_txt_file_as_model_file",0))
680 					{
681 						pos = argstr.Find(mystr(".txt"));
682 					}
683 					if (pos != -1)
684 					{
685 						if(DoesFileExist(argstr) && argstr.Find(mystr("=")) == -1)
686 						{
687 							hid_file = argstr;
688 							argstr = "GeneralOptions.ModelFile.hotint_input_data_filename=\"" + argstr+ "\"";
689 							// get path of Hotint Input Data file
690 							mystr path("");
691 							{
692 								int until;
693 								for(until=hid_file.Length()-1;until>=0;until--)
694 								{
695 									if(hid_file.PosPeek(until) == '\\')
696 										break; // until <=> last backslash
697 								}
698 								for(int i=0;i<=until;i++)
699 								{
700 									path += hid_file.PosPeek(i); // path until last backslash
701 								}
702 								GetMBS_EDC_Options()->TreeSetString("GeneralOptions.Paths.hotint_input_data_path", path.c_str());
703 							}
704 						}
705 					}
706 				}
707 				//$ RL 2012-7-25:]
708 
709 				int pos = argstr.Find('=');
710 				if (pos != -1)
711 				{
712 					mystr name = argstr.Left(pos);
713 					//UO(UO_LVL_ext) << "name = '" << name << "'\n";
714 					name.EraseSpaces(); //name anyway should not contain spaces ...
715 
716 					if (GetMBS_EDC_Options()->TreeFind(name))
717 					{
718 						UO(UO_LVL_ext) << " ... parsed to MBS_EDC_Option";
719 						mbsedc_argstr += argstr + mystr("\n");
720 					}
721 					else
722 					{
723 						UO(UO_LVL_ext) << " ... parsed to ModelData";
724 						modeldata_argstr += argstr + mystr("\n");
725 					}
726 				}
727 				UO() << "\n";
728 			}	// end of for loop narg
729 
730 			if (mbsedc_argstr.Length() != 0)
731 			{
732 				UO() << "mbs-edc-argstring=" << mbsedc_argstr << "\n";
733 				// AD 2013-10-22 use new routine to parse
734 				EDCParser().ParseAndExecuteString(mbsedc_argstr,mbs_edc_args);
735 //				EDCParser().String2TreeEDC(/*this, */mbsedc_argstr, mbs_edc_args);
736 				GetMBS_EDC_Options()->TreeReplaceEDCDataWith(&mbs_edc_args);
737 			}
738 			if (modeldata_argstr.Length() != 0) //write information in to modeldata container ==> will not be overwritten later
739 			{
740 				// AD 2013-10-22 use new routine to parse
741 				EDCParser().ParseAndExecuteString(modeldata_argstr,modeldata_edc_args);
742 //				EDCParser().String2TreeEDC(/*this, */modeldata_argstr, modeldata_edc_args);
743 
744 				if (GetModelDataContainer())
745 				{
746 					GetModelDataContainer()->TreeReplaceEDCDataWith(&modeldata_edc_args);
747 				}
748 				else
749 				{
750 					SetModelDataContainer(modeldata_edc_args);
751 				}
752 			}
753 
754 			edc->CopyFrom(*GetMBS_EDC_Options()); //some options are written in configuration
755 
756 			SetEDCOptions2Options(); //copy EDC Tree to numbered i/d/t options for fast access
757 			SetComputationSolverOptions(); //copy EDC Tree to MBSSolSet()
758 
759 			OpenLogFile(0);
760 
761 			break;
762 		}
763 	case 107: //Save_MBS_EDC_config_file
764 		{
765 //!AD 2012-06-26: revised
766 //!AD 2012-04-17: solver options and hotint options can be stored separately - use autogenerated functions, changed names to better distinguish various EDCs
767 			mystr filename = "hotint_cfg.txt";
768 			CMFile file_read(filename, TFMread);
769 
770 // read from current configuration file;
771 			ElementDataContainer edc_configfile;
772 			if (file_read.IsGood())
773 			{
774 			  mystr str;
775 				file_read.RWF(str);
776 				// AD 2013-10-22 use new routine to parse
777 				EDCParser().ParseAndExecuteString(str, edc_configfile);
778 //				EDCParser().String2TreeEDC(/*this, */str, edc_configfile);
779 			}
780 			else
781 			{
782 				UO() << "Error: could not read hotint configuration file 'hotint_cfg.txt'\n";
783 			}
784 		//	delete &file_read;
785 
786 
787 ////// actualize solver option part of the options edc //AD: revision
788 ////			SetComputationSolverOptions(); // <-- wrong
789 ////			SetOptions2EDCOptions();
790 			SetSolverDialogOptions();
791 			SetOptions2EDCOptions();
792 
793 // pick the data that will be written to file
794 			ElementDataContainer edc_tosave;
795 			if(value == 1) // save solver options only
796 			{
797 				SolverOptions2EDC(&edc_tosave);
798 				UO() << "save configuration file 'hotint_cfg.txt': solver options only\n";
799 			}
800 			else if(value == 2) // save hotint options only
801 			{
802 			  Options2EDC(&edc_tosave);
803 				UO() << "save configuration file 'hotint_cfg.txt': hotint options only\n";
804 			}
805 			else // rest of old code...
806 			{
807 				edc_tosave = *GetMBS_EDC_Options();
808 				UO() << "save configuration file 'hotint_cfg.txt': all options\n";
809 			}
810 // replace in the content of the config file
811 			edc_configfile.TreeReplaceEDCDataWith(&edc_tosave);
812 
813 			//$ AD 2011-09: do not write ComputationSteps to the config file
814 			RemoveVariableFromEDCTree(edc_configfile, mystr("SolverOptions.ComputationSteps"), 0);
815 
816 // edc contains window placement etc...
817 			if( value != 1 )
818 			{
819 				edc_configfile.TreeReplaceEDCDataWith(edc);
820 			}
821 
822 // write to configfile
823 			CMFile file_write(filename, TFMwrite);
824 
825 			//UO() << "load arrow=" << edcnew.TreeGetDouble("PostProcOptions.Loads.arrow_size") << "\n";
826 
827 			//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
828 			//set some default values, which should not be loaded:
829 			edc_configfile.TreeSetDouble("SolverOptions.start_time", 0.); //do not load any starttime except 0.
830 			edc_configfile.TreeSetBool("ViewingOptions.Animation.animate_deformation", 0); //animate at startup
831 			edc_configfile.TreeSetBool("ViewingOptions.Animation.RecordSingleFrames.record", 0); //do not record at beginning
832 			//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
833 
834 
835 			mystr str;
836 			EDCParser().EDC2String(edc_configfile, str);
837 
838 			if(UO().GetGlobalMessageLevel()==UO_LVL_dbg2)	//$ DR 2011-09-15
839 			{
840 				UO(UO_LVL_dbg2) << str << "\n";
841 			}
842 			file_write.RW(mystr("%HOTINT configuration file 'hotint_cfg.txt'\n"));
843 			file_write.RW(mystr("%handle this file with care, it can crash the startup of HOTINT\n"));
844 			file_write.RW(mystr("%in case that nothing works anymore ==> delete this file ==> defaults will be created ==> save configuration ==> new 'hotint_cfg.txt' will be created\n"));
845 			file_write.RW(mystr("%\n"));
846 			file_write.RW(str);
847 
848 			break;
849 		}
850 
851 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
852 		//Load and Save ANY EDC
853 //action=110: Load EDC from file (file name in edc.Find("File_name")+directory, .GetText()
854 	case 110:
855 		{
856 			mystr filename = edc->TreeGetString("File_name");
857 			mystr the_string;
858 			edc->Reset();
859 
860 			File2Str(filename, the_string);
861 			EDCParser().ParseAndExecuteString(the_string, *edc);
862 			break;
863 
864 			//the_file.RWF(the_string);
865 			//ElementDataContainer the_edc,testedc;
866 			////EDCParser().String2EDC(the_string, the_edc, testedc);
867 
868 			//EDCParser().String2TreeEDC(the_string, the_edc);
869 			//edc->CopyFrom(the_edc);
870 			//break;
871 		}
872 //action=111: Save EDC to file (file name in edc.Find("File_name")+directory, .GetText()
873 	case 111:
874 		{
875 			mystr filename = edc->TreeGetString("File_name");
876 			edc->Delete(edc->Find("File_name"));
877 			CMFile the_file(filename, TFMwrite);
878 			mystr the_string;
879 
880 			EDCParser().EDC2String(*edc, the_string);
881 			the_file.RW(the_string);
882 	    break;
883 		}
884 //action=112: The input-edc gets written into a mystr, the mystr is returned in the same edc
885 	case 112:
886 		{
887 			mystr clipboardtext;
888 			EDCParser().EDC2String(*edc, clipboardtext, mystr("  "));
889 
890 			//edc = new ElementDataContainer;
891 			ElementData ed;
892 			ed.SetText(clipboardtext, "ClipBoardText");
893 			edc->Add(ed);
894 			break;
895 		}
896 	case 113: //$ DR 2013-06-12
897 		{
898 			mystr str = edc->TreeGetString("File_name");
899 			int fromfile = edc->TreeGetInt("is_file");
900 			AddModelData(str/*,fromfile*/);
901 			break;
902 		}
903 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
904 		//plot in matlab
905 	case 121: //plot sensor 'value' in matlab
906 		{
907 			if (GetSensor(value).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
908 
909 			UO().CallWCDriverFunction(4); //Set Programm directory as current
910 
911 			mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
912 			//mystr filename = mystr("S")+mystr(GetSensor(value).GetSensorNumber())+mystr("-")+GetSensor(value).GetTypeName()+mystr(".txt");
913 			mystr filename = mystr("S")+mystr(value)+mystr("-")+GetSensor(value).GetSensorName()+mystr(".txt");
914 			mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
915 
916 			ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
917 
918 			char buffer[_MAX_PATH*4];
919 
920 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
921 			mystr oldpath = buffer;
922 
923 			_chdir(dir.c_str());
924 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
925 			mystr path = buffer;
926 
927 			char str[1024];
928 			//if (path[path.Length()-1] != '\\') path += '\\';
929 
930 			sprintf(str, "f1=load('%s');\n",(filename).c_str());
931 			plotfunc << str;
932 			plotfunc << "h=plot(f1(:,1),f1(:,2),'k');\n";
933 
934 			plotfunc << "title(' Y: " << GetSensor(value).GetSensorName() << "','Fontsize',16);\n";
935 			plotfunc << "xlabel(' Time [s] ','Fontsize',16);\n";
936 			//$ YV 2012-06: there is no type name for the sensors
937 			//plotfunc << "ylabel('" << GetSensor(value).GetTypeName() << "','Fontsize',16);\n";
938 			plotfunc << "set(h,'LineWidth',1.0);\n";
939 			//plotfunc << "legend('" << GetSensor(value).GetTypeName() << "');\n";
940 			plotfunc << "waitfor(h);\n"; //wait till window is closed
941 			plotfunc << "exit;\n";       //exit instance of matlab; too many instances will need enormous memory and may crash system
942 			plotfunc.close();
943 			ShellExecute(NULL, "open", "matlab",
944 				" -nosplash /r MBSplotfunc",
945 				path.c_str(), SW_HIDE);
946 			//path.c_str(), SW_SHOW);
947 
948 			_chdir(oldpath.c_str());
949 
950 			break;
951 		}
952 	case 122: //plot two sensors 'edc.xsensor' vs 'edc.ysensor'  in matlab
953 		{
954 			int xsensor = edc->TreeGetInt("xsensor");
955 			int ysensor = edc->TreeGetInt("ysensor");
956 
957 			if (GetSensor(xsensor).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
958 			if (GetSensor(ysensor).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
959 
960 			UO().CallWCDriverFunction(4); //Set Programm directory as current
961 
962 			mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
963 			mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
964 			mystr filename = mystr("S")+mystr(xsensor)+mystr("-")+GetSensor(xsensor).GetSensorName()+mystr(".txt");
965 			mystr filename2 = mystr("S")+mystr(ysensor)+mystr("-")+GetSensor(ysensor).GetSensorName()+mystr(".txt");
966 
967 			ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
968 
969 			char buffer[_MAX_PATH*4];
970 
971 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
972 			mystr oldpath = buffer;
973 
974 			_chdir(dir.c_str());
975 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
976 			mystr path = buffer;
977 
978 			char str[1024];
979 
980 			sprintf(str, "f1=load('%s');\n",(filename).c_str());
981 			plotfunc << str;
982 			sprintf(str, "f2=load('%s');\n",(filename2).c_str());
983 			plotfunc << str;
984 			plotfunc << "h=plot(f1(:,2),f2(:,2),'k');\n";
985 			plotfunc << "title({[' X: " << GetSensor(xsensor).GetSensorName() << " '];[' Y: " << GetSensor(ysensor).GetSensorName() << " ']},'Fontsize',16);\n";
986 			//$ YV 2012-06: there is no type name for the sensors
987 			//plotfunc << "xlabel('" << GetSensor(xsensor).GetTypeName() << "','Fontsize',16);\n";
988 			//plotfunc << "ylabel('" << GetSensor(ysensor).GetTypeName() << "','Fontsize',16);\n";
989 			plotfunc << "xlabel('" << GetSensor(xsensor).GetSensorName() << "','Fontsize',16);\n";
990 			plotfunc << "ylabel('" << GetSensor(ysensor).GetSensorName() << "','Fontsize',16);\n";
991 			plotfunc << "set(h,'LineWidth',1.0);\n";
992 			plotfunc << "waitfor(h);\n"; //wait till window is closed
993 			plotfunc << "exit;\n";       //exit instance of matlab; too many instances will need enormous memory and may crash system
994 			plotfunc.close();
995 			ShellExecute(NULL, "open", "matlab",
996 				" -nosplash /r MBSplotfunc",
997 				path.c_str(), SW_HIDE);
998 			//path.c_str(), SW_SHOW);
999 
1000 			_chdir(oldpath.c_str());
1001 
1002 			break;
1003 
1004 		}
1005 	case 123: //time plot of N sensors in matlab
1006 		{
1007 			if(option <=0)
1008 			{
1009 				return 0; //no sensors selected
1010 			}
1011 			TArray<int> ysensor;
1012 			ysensor.SetLen(option);
1013 
1014 			for(int sensNr=1;sensNr<=option;sensNr++)
1015 			{
1016 				ysensor(sensNr) = edc->TreeGetInt("y"+mystr(sensNr)+"sensor");
1017 				if (GetSensor(ysensor(sensNr)).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
1018 			}
1019 			UO().CallWCDriverFunction(4); //Set Programm directory as current
1020 
1021 			mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
1022 			mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
1023 
1024 
1025 			ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
1026 
1027 			char buffer[_MAX_PATH*4];
1028 
1029 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
1030 			mystr oldpath = buffer;
1031 
1032 			_chdir(dir.c_str());
1033 			_getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
1034 			mystr path = buffer;
1035 
1036 			char str[1024];
1037 			plotfunc << "scrsz = get(0,'ScreenSize');\n";
1038 			plotfunc << "fig = figure;\n";
1039 			plotfunc << "set(fig,'Position',[1 (scrsz(4)/2-60) scrsz(3)*2/3 scrsz(4)/2]);\n";
1040 			for(int sensNr=1;sensNr<=option;sensNr++)
1041 			{
1042 				mystr filename = mystr("S")+mystr(ysensor(sensNr))+mystr("-")+GetSensor(ysensor(sensNr)).GetSensorName()+mystr(".txt");
1043 				sprintf(str, mystr("f") + mystr(sensNr) + +mystr("=load('%s');\n"),(filename).c_str());
1044 				plotfunc << str;
1045 				plotfunc << "h(" << sensNr << ")=plot(f" << sensNr << "(:,1),f" << sensNr << "(:,2),";
1046 				if(sensNr==1){plotfunc << "'k'";}
1047 				else if(sensNr==1){plotfunc << "'k'";}
1048 				else if(sensNr==2){plotfunc << "'b'";}
1049 				else if(sensNr==3){plotfunc << "'g'";}
1050 				else if(sensNr==4){plotfunc << "'r'";}
1051 				else if(sensNr==5){plotfunc << "'c'";}
1052 				else if(sensNr==6){plotfunc << "'m'";}
1053 				else if(sensNr==7){plotfunc << "'k--'";}
1054 				else if(sensNr==8){plotfunc << "'b--'";}
1055 				else {plotfunc << "'k'";}
1056 				plotfunc << ",'linewidth',1);\n";
1057 				plotfunc << "hold on;\n";
1058 			}
1059 			//plotfunc << "title({[' Y1: " << GetSensor(ysensor(1)).GetSensorName() << " ']";
1060 			//for(int sensNr=2;sensNr<=option;sensNr++)
1061 			//{
1062 			//	plotfunc << ";[' Y" << sensNr << ": " << GetSensor(ysensor(sensNr)).GetSensorName() << " ']";
1063 			//}
1064 			//plotfunc << "},'Fontsize',16);\n";
1065 			int sameSensorType = 1;
1066 			for(int sensNr=2;sensNr<=option;sensNr++)
1067 			{
1068 				if(!GetSensor(ysensor(sensNr-1)).GetTypeName().Compare(GetSensor(ysensor(sensNr)).GetTypeName()))
1069 				{
1070 					sameSensorType = 0;
1071 					break;
1072 				}
1073 			}
1074 			if(sameSensorType)
1075 			{
1076 				plotfunc << "ylabel('" << GetSensor(ysensor(1)).GetTypeName() << "','Fontsize',16);\n";// same type
1077 			}
1078 			else
1079 			{
1080 				plotfunc << "ylabel({['" << GetSensor(ysensor(1)).GetTypeName() << "']";
1081 				for(int sensNr=2;sensNr<=option;sensNr++)
1082 				{
1083 					plotfunc << ";['" << GetSensor(ysensor(sensNr)).GetTypeName() << "']";	// different types
1084 				}
1085 				plotfunc << "},'Fontsize',16);\n"; //$ MS 2011-4-5
1086 			}
1087 
1088 			plotfunc << "xlabel('time','Fontsize',16);\n";
1089 			plotfunc << "legend('" << GetSensor(ysensor(1)).GetSensorName();
1090 			for(int sensNr=2;sensNr<=option;sensNr++)
1091 			{
1092 				plotfunc	<< "','" << GetSensor(ysensor(sensNr)).GetSensorName();
1093 			}
1094 			plotfunc << "');\n";
1095 			//plotfunc << "set(h,'LineWidth',1.0);\n";
1096 			plotfunc << "waitfor(h(1));\n"; //wait till window is closed
1097 			plotfunc << "exit;\n";       //exit instance of matlab; too many instances will need enormous memory and may crash system
1098 			plotfunc.close();
1099 			ShellExecute(NULL, "open", "matlab",
1100 				" -nosplash /r MBSplotfunc",
1101 				dir.c_str(), SW_HIDE);
1102 			//path.c_str(), SW_HIDE);
1103 			//path.c_str(), SW_SHOW);
1104 
1105 			_chdir(oldpath.c_str());
1106 
1107 			break;
1108 
1109 		}
1110 		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1111 		//information exchange, etc.
1112 	case 201: //NSensors
1113 		{
1114 			return NSensors();
1115 			break;
1116 		}
1117 	case 202: //Element names
1118 		{
1119 			for (int i=1; i <= NE(); i++)
1120 			{
1121 				int flag = 0; //add information on constraint, rigid, flexible, actuator, spring?
1122 				ElementData ed;
1123 				ed.SetInt(flag, GetElement(i).GetElementName().c_str()); edc->Add(ed);
1124 			}
1125 			break;
1126 		}
1127 	case 203: //Sensor names
1128 		{
1129 			for (int i=1; i <= NSensors(); i++)
1130 			{
1131 				int flag = 0; //add information on type?
1132 				if(value==1)
1133 				{
1134 					flag = GetSensor(i).GetSignalStorageMode() != SSM_None; // write result data
1135 				}
1136 				ElementData ed;
1137 				//$ YV 2012-06: display names do not seem to be actually used
1138 				/*
1139 				if(option ==1) // return the displaynames (plottool caption)
1140 				{
1141 					ed.SetInt(flag, GetSensor(i).GetDisplayName().c_str()); edc->Add(ed);
1142 				}
1143 				else //if(option==0) // return sensornames
1144 				{
1145 					ed.SetInt(flag, GetSensor(i).GetSensorName().c_str()); edc->Add(ed);
1146 				}
1147 				*/
1148 				ed.SetInt(flag, GetSensor(i).GetSensorName().c_str()); edc->Add(ed);
1149 			}
1150 			break;
1151 		}
1152 	case 204: //Sensor value
1153 		{
1154 			ElementData ed;
1155 			if(option==1) // return time & all system values
1156 			{
1157 				Vector v(1+NSensors());
1158 				v[0] = GetTime();
1159 				for(int i=1; i <= NSensors(); i++)
1160 				{
1161 					v[i] = GetSensor(i).GetLastValue();
1162 				}
1163 				ed.SetVector(v.GetVecPtr(),v.GetLen(),"values");
1164 				edc->Add(ed);
1165 			}
1166 			else //if(option==0) // return single value from sensor #value
1167 			{
1168 				double v = GetSensor(value).GetLastValue();
1169 				ed.SetDouble(v, "value"); edc->Add(ed);
1170 			}
1171 			break;
1172 		}
1173 	case 205: //GeomElement names //MBS: DrawElement == GeomElement
1174 		{
1175 			for (int i=1; i <= NDrawElements(); i++)
1176 			{
1177 				int flag = 0; //add information on type?
1178 				ElementData ed;
1179 				ed.SetInt(flag, GetDrawElement(i)->GetName().c_str()); edc->Add(ed);
1180 			}
1181 			break;
1182 		}
1183 	case 206: //NNodes
1184 		{
1185 			return NNodes();
1186 			break;
1187 		}
1188 	case 207: //Nodes names
1189 		{
1190 			for (int i=1; i <= NNodes(); i++)
1191 			{
1192 				int flag = 0; //add information on type?
1193 				ElementData ed;
1194 				ed.SetInt(flag, (GetNode(i).GetObjectName()+mystr("-")+mystr(GetNode(i).SOS())+("DOF")).c_str()); edc->Add(ed);
1195 			}
1196 			break;
1197 		}
1198 	case 208: //N initial values
1199 		{
1200 			int ss = GetSystemSize();
1201 			return ss;
1202 			break;
1203 		}
1204 	case 209: //Material names
1205 		{
1206 			for (int i=1; i <= NMaterials(); i++)
1207 			{
1208 				int flag = 0; //add information on type?
1209 				ElementData ed;
1210 				//ed.SetInt(flag, (GetMaterial(i).GetMaterialName()+mystr("-")+mystr(GetMaterial(i).GetTypeSpec())).c_str()); edc->Add(ed);
1211 				ed.SetInt(flag, (GetMaterial(i).GetMaterialName()).c_str()); edc->Add(ed);	//$ DR 2013-01-21 change for script language
1212 			}
1213 			break;
1214 		}
1215 	case 210: //EditAllOptions
1216 		//!AD: revised 2012-07-26
1217 		{
1218 			if (option==0) //Get all mbs_edc_options and mbssolset into edc
1219 			{
1220 				edc->Reset();
1221 
1222 				if(value == 1) // save solver options only
1223 				{
1224 					SolverOptions2EDC(edc);
1225 				}
1226 				else if(value == 2) // save hotint options only
1227 				{
1228 					Options2EDC(edc);
1229 				}
1230 				else if(value == 0) // entire edc - currently no dialog active for all options
1231 				{
1232 					SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options ==> this is because old dialogs modify the i/d/toptions //JG
1233 					edc->CopyFrom(*GetMBS_EDC_Options());
1234 				}
1235 
1236 				////--------------------------------------------
1237 				////RL:b
1238 				//ElementDataContainer edcnew;
1239 				////copy mbssolset to edc:
1240 				//Options2EDC(&edcnew);
1241 				////replace edcnew data in edc:
1242 				//edc->TreeReplaceEDCDataWith(&edcnew);
1243 				////RL:e
1244 				////--------------------------------------------
1245 			}
1246 			else if (option==1) //Write modified edc-data to mbs_edc_options
1247 			{
1248 				GetMBS_EDC_Options()->TreeReplaceEDCDataWith(edc); // overwrite MBS-EDC first
1249 
1250 				if(value == 1) // update solver options only
1251 				{
1252 					SetComputationSolverOptions();
1253 				}
1254 				else if(value == 2) // update hotint options only
1255 				{
1256 					SetEDCOptions2Options();
1257 				}
1258 				else if(value == 0) // update entire edc - currently no dialog active for all options
1259 				{
1260 					SetComputationSolverOptions();
1261 					SetEDCOptions2Options();
1262 				}
1263 
1264 				//==>this must always be done, otherwise the EDC options are overwritten by other functions!!!!
1265 //<<<<<<< mbs_communication.cpp
1266 //
1267 //				//$ JG: instantly change log values:
1268 //				MBSSolSet().nls_log_rel_error_goal = edc->TreeGetInt("SolverOptions.Newton.Log.rel_error_goal");
1269 //				MBSSolSet().nls_log_jacobian_update_info = edc->TreeGetInt("SolverOptions.Newton.Log.jacobian_update_info");
1270 //				MBSSolSet().nls_log_contractivity = edc->TreeGetInt("SolverOptions.Newton.Log.contractivity");
1271 //				MBSSolSet().nls_log_iteration_error = edc->TreeGetInt("SolverOptions.Newton.Log.iteration_error");
1272 //				MBSSolSet().nls_log_solution_vector = edc->TreeGetInt("SolverOptions.Newton.Log.solution_vector");
1273 //				MBSSolSet().nls_log_jacobian = edc->TreeGetInt("SolverOptions.Newton.Log.jacobian");
1274 //
1275 //				MBSSolSet().output_level = edc->TreeGetInt("SolverOptions.Log.output_level");
1276 //				MBSSolSet().outprec_double = edc->TreeGetInt("SolverOptions.Log.output_precision_double");
1277 //				MBSSolSet().outprec_vector = edc->TreeGetInt("SolverOptions.Log.output_precision_vector");
1278 //				MBSSolSet().outprec_matrix = edc->TreeGetInt("SolverOptions.Log.output_precision_matrix");
1279 //				MBSSolSet().max_errors = edc->TreeGetInt("SolverOptions.Log.max_error_messages");
1280 //				MBSSolSet().max_warnings = edc->TreeGetInt("SolverOptions.Log.max_warning_messages");
1281 //				MBSSolSet().log_detailed_comp_output = edc->TreeGetInt("SolverOptions.Log.detailed_computation_output");
1282 //				MBSSolSet().comp_output_every_x_sec = edc->TreeGetDouble("SolverOptions.Log.computation_output_every_x_sec");
1283 //				MBSSolSet().write_MK2file = edc->TreeGetInt("SolverOptions.Log.write_mass_and_stiffness_matrix");
1284 //
1285 //				MBSSolSet().withgraphics = edc->TreeGetDouble("SolverOptions.Misc.with_graphics");
1286 //=======
1287 
1288 				OpenLogFile(1);
1289 			}
1290 
1291 			break;
1292 		}
1293 		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1294 	case 211: //Model Data
1295 		{
1296 			if (option==0 && GetModelDataContainer() != 0) //Get Data in EDC
1297 			{
1298 				edc->Reset();
1299 				edc->CopyFrom(*GetModelDataContainer());
1300 			}
1301 			else if (option==1) //Set Data in EDC
1302 			{
1303 				if (!GetModelDataContainer()) //generate empty modeldatacontainer
1304 				{
1305 					ElementDataContainer edcnew;
1306 					SetModelDataContainer(edcnew);
1307 				}
1308 				else
1309 				{
1310 					GetModelDataContainer()->Reset();
1311 				}
1312 				GetModelDataContainer()->CopyFrom(*edc);
1313 			}
1314 			else if (option==2) //Load Model Data
1315 			{
1316 			}
1317 			else if (option==3) //Save Model Data
1318 			{
1319 				ElementDataContainer* medc = GetModelDataContainer();
1320 				mystr filestr;
1321 				EDCParser().EDC2String(*medc, filestr);
1322 
1323 				{
1324 					mystr filename = GetTOption( 88); //directory+filename
1325 					int opt = ios::out;
1326 
1327 
1328 					ofstream* storeout = new ofstream;
1329 #ifdef my_new_stdiostream
1330 					storeout->open(filename.c_str(), opt); //with read sharing allowed!
1331 #else
1332 					storeout->open(filename.c_str(), opt, filebuf::sh_read); //with read sharing allowed!
1333 #endif
1334 
1335 					if ((int)storeout->good() == 0 || storeout->fail())
1336 					{
1337 						UO() << "ERROR: could not write model data!!!\n";
1338 						UO() << "good=" << storeout->good() << ", fail=" << storeout->fail() << "\n";
1339 						UO() << "file=" << filename.c_str() << "\n";
1340 					}
1341 					else
1342 					{
1343 						(*storeout) << filestr.c_str() << "\n";
1344 					}
1345 
1346 					storeout->close();
1347 					delete storeout;
1348 
1349 				}
1350 			}
1351 
1352 			break;
1353 		}
1354 		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1355 	case 212: //SetOptions
1356 		{
1357 			if (option==1)
1358 			{
1359 				SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options
1360 			}
1361 			else if (option==2)
1362 			{
1363 				SetEDCOptions2Options();//copy EDC Tree options to numbered i/d/t options
1364 			}
1365 			break;
1366 		}
1367 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1368 	case 214: //Load names
1369 		{
1370 			for (int i=1; i <= NLoads(); i++)
1371 			{
1372 				int flag = 0; //add information on type?
1373 				ElementData ed;
1374 				ed.SetInt(flag, GetLoad(i).LoadName().c_str()); edc->Add(ed);
1375 			}
1376 			break;
1377 		}
1378 
1379 		//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1380 	case 301: //Compute system information
1381 		{
1382 			int rs = GetResortSize();
1383 			int sos = GetSecondOrderSize();
1384 			//int sos_rs = GetSecondOrderSize_RS();
1385 			int es = GetFirstOrderSize();
1386 			int is = GetImplicitSize();
1387 			int ss = GetSystemSize();
1388 
1389 			int nbodies=0;
1390 			int njoints=0;
1391 			for (int i=1; i <= NE(); i++)
1392 			{
1393 				if (GetElement(i).IsType(TBody)) nbodies++;
1394 				else njoints++;
1395 			}
1396 
1397 			UO() << "++++++++++++++++++++++++++++++++++\n";
1398 			UO() << "System properties:\n";
1399 			UO() << "2nd order ODE=" << sos << " (sos)\n";
1400 			UO() << "Algebraic Equ=" << is << " (is)\n";
1401 			UO() << "1st order ODE=" << es << " (es)\n";
1402 			UO() << "number of initial values=" << ss << " (=2*sos+es+is)\n";
1403 			UO() << "Resorted equ =" << rs << "\n";
1404 			UO() << "N. of bodies=" << nbodies << "\n";
1405 			UO() << "N. of joints=" << njoints << "\n";
1406 
1407 			UO() << "++++++++++++++++++++++++++++++++++\n";
1408 			break;
1409 		}
1410 	case 302: //check system; rv==0 --> OK, rv==1 --> can not compute, rv==2 --> can not draw and not compute
1411 		{
1412 			rv = CheckSystemConsistency();
1413 			break;
1414 		}
1415 
1416 	case 320:
1417 		{
1418 			rv = ComputeEigenmodes();
1419 			break;
1420 		}
1421 	default: ;
1422 	}
1423 
1424 	return rv;
1425 }
1426 
1427 //$ DR 2012-11-29 new code according to skript-language
SaveToFile(mystr filename,int save_options)1428 void MultiBodySystem::SaveToFile(mystr filename,int save_options)
1429 {
1430 	mystr el = "\n"; //end of line
1431 	mystr ob = "{";  //open bracket
1432 	mystr cb = "}";  //closing bracket
1433 	mystr ds = ": "; //double stop
1434 	mystr eq = "= "; //equal sign
1435 
1436 	ofstream of(filename.c_str());
1437 
1438 	//++++++++++++++++
1439 	//header:
1440 	char str[32];
1441 	/*sprintf(str, "%0.3f\n\n", HOTINT_version_info);*/
1442 
1443 	_SYSTEMTIME time;
1444 	GetSystemTime(&time);
1445 
1446 	// do not use HOTINT_data_file_version in header
1447 	mystr header = "";
1448 
1449 	header += mystr("%======================================================================\n");
1450 	header += mystr("%                      HOTINT model \n");
1451 	header += mystr("%\n");
1452 	header += mystr("% model name: ") + mystr(MBS_EDC_TreeGetString("GeneralOptions.ModelFile.internal_model_function_name")) + mystr("\n");
1453 	header += mystr("%\n");
1454 	header += mystr("% saved on: ")+mystr(time.wDay)+mystr(".")+mystr(time.wMonth)+mystr(".")+mystr(time.wYear)+mystr(" at ")+mystr(time.wHour)+mystr(":")+mystr(time.wMinute)+mystr("\n");
1455 	header += mystr("%======================================================================\n");
1456 	header +=mystr("HOTINT_data_file_version = \"")+mystr(GetHotintVersion().GetString())+mystr("\" % version of HOTINT, that has been used to generate this file \n\n");
1457 
1458 	of << header;
1459 
1460 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1461 	//		Check if the mbs can be saved at all
1462 	bool error = 0;
1463 
1464 	if(error)
1465 	{
1466 		UO() << "Writing of output file aborted due to the error(s) above! \n";
1467 		of << "% Writing of output file aborted, because nodes are not available for skript language.";
1468 		of.close();
1469 		return;
1470 	}
1471 
1472 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1473 	//materials:
1474 	for (int i=1; i<=NMaterials(); i++)
1475 	{
1476 		mystr otext = "";
1477 		ElementDataContainer edc;
1478 		Material& m = GetMaterial(i);
1479 		m.GetElementData(edc);
1480 
1481 		otext += "Material" + mystr(i);
1482 		otext += el + ob + el;			// open bracket
1483 
1484 		mystr str;
1485 		EDCParser().EDC2String(edc, str, "  ");
1486 		otext += str;								// element data
1487 		otext += cb + el;						// close bracket
1488 
1489 		if(m.GetType() & TMatBeam)
1490 		{
1491 			otext += "AddBeamProperties(Material" +mystr(i)+ ")" + el +el;
1492 		}
1493 		else
1494 		{
1495 			otext += "AddMaterial(Material" +mystr(i)+ ")" + el +el;
1496 		}
1497 
1498 		of << otext;	// write the string to file
1499 	}
1500 
1501 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1502 	// nodes:
1503 	for (int i=1; i<=NNodes(); i++)
1504 	{
1505 		mystr otext = "";
1506 		ElementDataContainer edc;
1507 		Node& m = GetNode(i);
1508 		m.GetElementData(edc);
1509 
1510 		otext += "Node" + mystr(i);
1511 		otext += el + ob + el;			// open bracket
1512 
1513 		mystr str;
1514 		EDCParser().EDC2String(edc, str, "  ");
1515 		otext += str;								// element data
1516 		otext += cb + el;						// close bracket
1517 		otext += "AddNode(Node" +mystr(i)+ ")" + el +el;
1518 
1519 		of << otext;	// write the string to file
1520 	}
1521 
1522 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1523 	//elements:
1524 	for (int i=1; i<=NE(); i++)
1525 	{
1526 		mystr otext = "";
1527 		ElementDataContainer edc;
1528 		Element& e = GetElement(i);
1529 		e.GetElementData(edc);
1530 
1531 		otext += "Element" + mystr(i);
1532 		otext += el + ob + el;			// open bracket
1533 
1534 		mystr str;
1535 		EDCParser().EDC2String(edc, str, "  ");
1536 		otext += str;								// element data
1537 		otext += cb + el;						// close bracket
1538 
1539 		if (e.IsType(TConstraint) && !e.IsType(TController))
1540 		{
1541 			otext += "AddConnector(Element" +mystr(i)+ ")" + el +el;	// add the element
1542 		}
1543 		else
1544 		{
1545 			otext += "AddElement(Element" +mystr(i)+ ")" + el +el;		// add the element
1546 		}
1547 		of << otext;	// write the string to file
1548 	}
1549 
1550 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1551 	//loads:
1552 	for (int i=1; i<=NLoads(); i++)
1553 	{
1554 		mystr otext = "";
1555 		ElementDataContainer edc;
1556 		MBSLoad& l = GetLoad(i);
1557 		l.GetElementData(edc);
1558 
1559 		otext += "Load" + mystr(i);
1560 		otext += el + ob + el;			// open bracket
1561 
1562 		mystr str;
1563 		EDCParser().EDC2String(edc, str, "  ");
1564 		otext += str;								// element data
1565 		otext += cb + el;						// close bracket
1566 		otext += "AddLoad(Load" +mystr(i)+ ")" + el +el;	// add the element
1567 		of << otext;	// write the string to file
1568 	}
1569 
1570 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1571 	//sensors:
1572 	for (int i=1; i<=NSensors(); i++)
1573 	{
1574 		mystr otext = "";
1575 		ElementDataContainer edc;
1576 		Sensor& s = GetSensor(i);
1577 		s.GetElementData(edc);
1578 
1579 		otext += "Sensor" + mystr(i);
1580 		otext += el + ob + el;			// open bracket
1581 
1582 		mystr str;
1583 		EDCParser().EDC2String(edc, str, "  ");
1584 		otext += str;								// element data
1585 		otext += cb + el;						// close bracket
1586 		otext += "AddSensor(Sensor" +mystr(i)+ ")" + el +el;	// add the element
1587 		of << otext;	// write the string to file
1588 	}
1589 
1590 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1591 	// GeomElements:
1592 	for (int i=1; i<=NDrawElements(); i++)
1593 	{
1594 		mystr otext = "";
1595 		ElementDataContainer edc;
1596 		GeomElement *e = GetDrawElement(i);
1597 		e->GetElementData(edc);
1598 
1599 		otext += "GeomElement" + mystr(i);
1600 		otext += el + ob + el;			// open bracket
1601 
1602 		mystr str;
1603 		EDCParser().EDC2String(edc, str, "  ");
1604 		otext += str;								// element data
1605 		otext += cb + el;						// close bracket
1606 
1607 		otext += "AddGeomElement(GeomElement" +mystr(i)+ ")" + el +el;		// add the element
1608 
1609 		of << otext;	// write the string to file
1610 	}
1611 
1612 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1613 	//options:
1614 	if(save_options)
1615 	{
1616 		ElementDataContainer edc;
1617 
1618 		//SolverOptions2EDC(edc); // save solver options only
1619 		//Options2EDC(edc); // save hotint options only
1620 
1621 		// entire edc - currently no dialog active for all options
1622 		SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options ==> this is because old dialogs modify the i/d/toptions //JG
1623 		edc.CopyFrom(*GetMBS_EDC_Options());
1624 
1625 		////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1626 		////set some default values, which should not be loaded:
1627 		//edc_configfile.TreeSetDouble("SolverOptions.start_time", 0.); //do not load any starttime except 0.
1628 		//edc_configfile.TreeSetBool("ViewingOptions.Animation.animate_deformation", 0); //animate at startup
1629 		//edc_configfile.TreeSetBool("ViewingOptions.Animation.RecordSingleFrames.record", 0); //do not record at beginning
1630 		////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1631 
1632 		edc.TreeDelete("GeneralOptions.ModelFile.hotint_input_data_filename");
1633 		edc.TreeDelete("GeneralOptions.ModelFile.internal_model_function_name");
1634 		edc.TreeDelete("GeneralOptions.ModelFile.recent_file1");
1635 		edc.TreeDelete("GeneralOptions.ModelFile.recent_file2");
1636 		edc.TreeDelete("GeneralOptions.ModelFile.recent_file3");
1637 		edc.TreeDelete("GeneralOptions.ModelFile.recent_file4");
1638 		edc.TreeDelete("GeneralOptions.ModelFile.recent_file5");
1639 
1640 		mystr opts;
1641 		EDCParser().EDC2String(edc, opts, "");
1642 		of << "%======================================================================\n";
1643 		of << "%                      Solver Options \n";
1644 		of << opts;	// write the string to file
1645 	}
1646 
1647 	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1648 	//the end
1649 	of.close();
1650 
1651 	UO(UO_LVL_all) << "\nMBS system saved as '" << filename << "'\n";
1652 }
1653 
LoadFromFile(mystr filename)1654 int MultiBodySystem::LoadFromFile(mystr filename)
1655 {
1656 	Destroy();
1657 	int rv = ReadModelData(filename);
1658 	if(rv)
1659 	{
1660 		SetModelData_Initialized(1);
1661 		//Assemble(); // this is done by ModelChanged() wich is called later anyway
1662 	}
1663 	else
1664 	{
1665 		UO() << "ERROR in LoadFromFile during reading '" << filename << "'\n";
1666 	}
1667 	return rv;
1668 }
1669 
1670 
1671 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1672 //these functions are called from WCDriver via WinCompInterface:
GetObjectFactory()1673 MBSObjectFactoryInterface * MultiBodySystem::GetObjectFactory()
1674 {
1675 	return EDCParser().GetObjectFactory();
1676 }
1677 
1678 
1679 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1680 //++++++++++++++++++               EDC_MBS_OPTIONS             ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1681 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1682 
GetMBS_EDC_Options()1683 ElementDataContainer* MultiBodySystem::GetMBS_EDC_Options()
1684 {
1685 	return mbs_edc_options;
1686 }
GetMBS_EDC_Options() const1687 const ElementDataContainer* MultiBodySystem::GetMBS_EDC_Options() const
1688 {
1689 	return mbs_edc_options;
1690 }
SetMBS_EDC_Options(const ElementDataContainer & edc)1691 void MultiBodySystem::SetMBS_EDC_Options(const ElementDataContainer& edc)
1692 {
1693 	if (mbs_edc_options != 0) delete mbs_edc_options;
1694 
1695 	mbs_edc_options = new ElementDataContainer;
1696 
1697 	mbs_edc_options->CopyFrom(edc);
1698 }
1699 
1700 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GetMBS_EDC_Variables()1701 ElementDataContainer* MultiBodySystem::GetMBS_EDC_Variables()
1702 {
1703 	return mbs_edc_global_variables;
1704 }
GetMBS_EDC_Variables() const1705 const ElementDataContainer* MultiBodySystem::GetMBS_EDC_Variables() const
1706 {
1707 	return mbs_edc_global_variables;
1708 }
SetMBS_EDC_Variables(const ElementDataContainer & edc)1709 void MultiBodySystem::SetMBS_EDC_Variables(const ElementDataContainer& edc)
1710 {
1711 	if (mbs_edc_global_variables != 0) delete mbs_edc_global_variables;
1712 
1713 	mbs_edc_global_variables = new ElementDataContainer;
1714 
1715 	mbs_edc_global_variables->CopyFrom(edc);
1716 }
1717 
1718 //get values in MBS_EDC:
MBS_EDC_TreeGetDouble(double & data,const char * name) const1719 void MultiBodySystem::MBS_EDC_TreeGetDouble(double& data, const char* name) const
1720 {
1721 	data = GetMBS_EDC_Options()->TreeGetDouble(name);
1722 }
MBS_EDC_TreeGetInt(int & data,const char * name) const1723 void MultiBodySystem::MBS_EDC_TreeGetInt(int& data, const char* name) const
1724 {
1725 	data = GetMBS_EDC_Options()->TreeGetInt(name); //(int == bool internally)
1726 }
MBS_EDC_TreeGetString(const char * name) const1727 const char* MultiBodySystem::MBS_EDC_TreeGetString(const char* name) const
1728 {
1729 	return GetMBS_EDC_Options()->TreeGetString(name);
1730 }
1731 
1732 //set values in MBS_EDC:
MBS_EDC_TreeSetDouble(double data,const char * name)1733 void MultiBodySystem::MBS_EDC_TreeSetDouble(double data, const char* name)
1734 {
1735 	GetMBS_EDC_Options()->TreeSetDouble(name, data);
1736 }
MBS_EDC_TreeSetInt(int data,const char * name)1737 void MultiBodySystem::MBS_EDC_TreeSetInt(int data, const char* name)
1738 {
1739 	GetMBS_EDC_Options()->TreeSetInt(name, data); //(int == bool internally)
1740 }
MBS_EDC_TreeSetString(const char * data,const char * name)1741 void MultiBodySystem::MBS_EDC_TreeSetString(const char* data, const char* name)
1742 {
1743 	GetMBS_EDC_Options()->TreeSetString(name, data);
1744 }
1745 
MBSParser() const1746 const CMBSParser& MultiBodySystem::MBSParser() const {return *mbs_parser;}
MBSParser()1747 CMBSParser& MultiBodySystem::MBSParser() {return *mbs_parser;}
1748 
EDCParser() const1749 const CEDCParser& MultiBodySystem::EDCParser() const {return *edc_parser;}
EDCParser()1750 CEDCParser& MultiBodySystem::EDCParser() {return *edc_parser;}
1751 
File2Str(const char * filename,mystr & str)1752 int MultiBodySystem::File2Str(const char* filename,	mystr& str)
1753 {
1754 	mystr filen = filename;
1755 	CMFile file(filename, TFMread);
1756 	UO()	<< "--------------------------------\n";
1757 
1758 	//read parameters from file
1759 	if (file.IsGood())
1760 	{
1761 		UO() << "read " << filename << "\n";
1762 
1763 		//read file
1764 		file.RWF(str);
1765 	}
1766 	else
1767 	{
1768 		UO()	<< "*****************\n";
1769 		UO()	<< "*****************\n";
1770 		UO()	<< "*****************\n";
1771 		UO()	<< "ERROR: failed to read model data from " << filename << "\n";
1772 		UO()	<< "*****************\n";
1773 		UO()	<< "*****************\n";
1774 		UO()	<< "*****************\n";
1775 
1776 		return 0;  // error
1777 	}
1778 	return 1;
1779 }
1780 
1781 //this function reads a file and stores it in an edc
File2EDC(const char * filename,ElementDataContainer * edc_file)1782 int MultiBodySystem::File2EDC(const char* filename, ElementDataContainer* edc_file)
1783 {
1784 	//$ DR 2013-01-14:[ added call for stl-files
1785 	mystr filen = filename;
1786 	if(filen.Find(".stl")>0)
1787 	{
1788 		return STLFile2EDC(filen, 0, edc_file);
1789 	}
1790 	//$ DR 2013-01-14:]
1791 
1792 	CMFile file(filename, TFMread);
1793 	UO()	<< "--------------------------------\n";
1794 
1795 	//read parameters from file
1796 	if (file.IsGood())
1797 	{
1798 		UO() << "read " << filename << "\n";
1799 
1800 		//read file
1801 		mystr str;
1802 		file.RWF(str);
1803 
1804 		// overwrite edc with contents from file
1805 //		EDCParser().String2TreeEDC(/*this, */str, *edc_file);
1806 
1807 		EDCParser().ParseAndExecuteString(str, *edc_file);
1808 	}
1809 	else
1810 	{
1811 		UO()	<< "*****************\n";
1812 		UO()	<< "*****************\n";
1813 		UO()	<< "*****************\n";
1814 		UO()	<< "ERROR: failed to read model data from " << filename << "\n";
1815 		UO()	<< "*****************\n";
1816 		UO()	<< "*****************\n";
1817 		UO()	<< "*****************\n";
1818 
1819 		return 0;  // error
1820 	}
1821 	return 1;
1822 }
1823 
1824 //DR 2013-01-14 this function reads a stl-file and writes the data in the edc
STLFile2EDC(char * file,int binary,ElementDataContainer * return_value)1825 int MultiBodySystem::STLFile2EDC(char* file, int binary, ElementDataContainer* return_value)
1826 {
1827 	int initsize = 10000;
1828 	TArray<Vector3D> newnormals(initsize);
1829 	TArray<Vector3D> newpoints(3*initsize);
1830 	double stl_tolerance=1e-4;								//tolerance for equal points when reading
1831 
1832 	if (!binary)
1833 	{
1834 		ifstream ist(file);
1835 
1836 		char buf[200];
1837 		Vector3D pts[3];
1838 		Vector3D normal;
1839 
1840 		int cntface = 0;
1841 		int vertex = 0;
1842 		int badnormals = 0;
1843 
1844 		while (ist.good())
1845 		{
1846 			ist >> buf;
1847 			if (strcmp (buf, "facet") == 0)
1848 			{
1849 				cntface++;
1850 			}
1851 
1852 			normal = 0;
1853 
1854 			if (strcmp (buf, "normal") == 0)
1855 			{
1856 				ist >> normal.X()
1857 					>> normal.Y()
1858 					>> normal.Z();
1859 				if (normal.Norm() > 0)
1860 					normal /= normal.Norm();
1861 			}
1862 
1863 
1864 			if (strcmp (buf, "vertex") == 0)
1865 			{
1866 				ist >> pts[vertex].X()
1867 					>> pts[vertex].Y()
1868 					>> pts[vertex].Z();
1869 
1870 
1871 				vertex++;
1872 				if (vertex == 3)
1873 				{
1874 					if (normal.Norm() <= 1e-5)
1875 					{
1876 						Vector3D v1 = pts[1]-pts[0];
1877 						Vector3D v2 = pts[2]-pts[0];
1878 						normal = v1.Cross(v2);
1879 						if (normal.Norm() != 0) normal *= 1./normal.Norm();
1880 					}
1881 
1882 					vertex = 0;
1883 
1884 					if ( (Dist (pts[0], pts[1]) < 1e-16) ||
1885 						(Dist (pts[0], pts[2]) < 1e-16) ||
1886 						(Dist (pts[1], pts[2]) < 1e-16) )
1887 					{
1888 						;
1889 					}
1890 					else
1891 					{
1892 						newnormals.Add(normal);
1893 						newpoints.Add(pts[0]);
1894 						newpoints.Add(pts[1]);
1895 						newpoints.Add(pts[2]);
1896 					}
1897 				}
1898 			}
1899 		}
1900 
1901 	}	//end read STL ASCII format
1902 	else
1903 	{
1904 		//read STL BINARY format
1905 
1906 		int binary_mode = 1;
1907 		CMFile infile(file, TFMread, binary_mode);
1908 
1909 		Vector3D pts[3];
1910 		Vector3D normal;
1911 
1912 		int nofacets = 0;
1913 		int vertex = 0;
1914 
1915 		if (sizeof(int) != 4 || sizeof(float) != 4)
1916 			UO() << "for stl-binary compatibility only use 32 bit compilation!!!";
1917 
1918 		//specific settings for stl-binary format
1919 		const int namelen = 80; //length of name of header in file
1920 		const int nospaces = 2; //number of spaces after a triangle
1921 
1922 		//read header: name
1923 		char buf[namelen+1];
1924 
1925 		mystr str;
1926 		//read leading 80 characters
1927 		infile.RWchars(namelen, str);
1928 		//global_uo << "STL-header=" << str << "\n";
1929 
1930 		//read 4-byte int number of facets
1931 		infile.RWbinaryInt(nofacets);
1932 		//global_uo << "No. facets=" << nofacets << "\n";
1933 
1934 		float f;
1935 		char spaces[nospaces];
1936 
1937 		//read triangles:
1938 		int cntface, j;
1939 		for (cntface = 1; cntface <= nofacets; cntface++)
1940 		{
1941 			//read 3 floats for triangle normal
1942 			infile.RWbinaryFloat(f); normal.X() = (double)f;
1943 			infile.RWbinaryFloat(f); normal.Y() = (double)f;
1944 			infile.RWbinaryFloat(f); normal.Z() = (double)f;
1945 
1946 			//read 3 x 3 floats for (x,y,z) coordinates of triangle points
1947 			for (j = 0; j < 3; j++)
1948 			{
1949 				infile.RWbinaryFloat(f); pts[j].X() = (double)f;
1950 				infile.RWbinaryFloat(f); pts[j].Y() = (double)f;
1951 				infile.RWbinaryFloat(f); pts[j].Z() = (double)f;
1952 			}
1953 
1954 			//read two bytes for attributes (usually unused)
1955 			infile.RWchar(spaces[0]);
1956 			infile.RWchar(spaces[1]);
1957 			//global_uo << "sp1=" << (int)spaces[0] << ", sp1=" << (int)spaces[1] << "\n";
1958 
1959 			newnormals.Add(normal);
1960 			newpoints.Add(pts[0]);
1961 			newpoints.Add(pts[1]);
1962 			newpoints.Add(pts[2]);
1963 		}
1964 
1965 	}
1966 
1967 	//now sort points and generate a consistent surface mesh (not necessary for graphical representation)
1968 	Box3D box;
1969 	for (int i=1; i <= newpoints.Length(); i++) box.Add(newpoints(i));
1970 
1971 	IVector pnums;
1972 	pnums.SetLen(newpoints.Length());
1973 	IVector items;
1974 
1975 	double boxeps = stl_tolerance+1e-12;
1976 	double eps2 = Sqr(stl_tolerance);
1977 
1978 	TArray<Vector3D> locpoints;
1979 
1980 	SearchTree st(20,20,20, box);
1981 	for (int i=1; i <= newpoints.Length(); i++)
1982 	{
1983 		Box3D b(newpoints(i), newpoints(i));
1984 		b.Increase(boxeps);
1985 		st.GetItemsInBox(b, items);
1986 
1987 		int found = 0;
1988 		for (int j=1; j <= items.Length(); j++)
1989 		{
1990 			if (Dist2(newpoints(i), locpoints(items(j))) <= eps2)
1991 			{
1992 				found = items(j);
1993 				break;
1994 			}
1995 		}
1996 		if (found)
1997 		{
1998 			pnums(i) = found;
1999 		}
2000 		else
2001 		{
2002 			pnums(i) = locpoints.Add(newpoints(i));
2003 			st.AddItem(Box3D(newpoints(i),newpoints(i)), pnums(i));
2004 		}
2005 	}
2006 
2007 	Matrix m(newnormals.Length(), 3);
2008 	Matrix n(newnormals.Length(), 3);
2009 	for (int i=1; i <= newnormals.Length(); i++)
2010 	{
2011 		m(i,1) = pnums(3*i-2);
2012 		m(i,2) = pnums(3*i-1);
2013 		m(i,3) = pnums(3*i);
2014 		n(i,1) = newnormals(i).X();
2015 		n(i,2) = newnormals(i).Y();
2016 		n(i,3) = newnormals(i).Z();
2017 	}
2018 
2019 	//ElementDataContainer edc;
2020 
2021 	ElementData ed;
2022 	ed.SetMatrix(m.GetMatPtr(),m.Getrows(),m.Getcols(),"triangles");
2023 	return_value->Add(ed);
2024 
2025 	ed.SetMatrix(n.GetMatPtr(),n.Getrows(),n.Getcols(),"normals");
2026 	return_value->Add(ed);
2027 
2028 	Matrix p(newnormals.Length(), 3);
2029 	for (int i=1; i <= locpoints.Length(); i++)
2030 	{
2031 		p(i,1) = locpoints(i).X();
2032 		p(i,2) = locpoints(i).Y();
2033 		p(i,3) = locpoints(i).Z();
2034 	}
2035 
2036 	ed.SetMatrix(p.GetMatPtr(),p.Getrows(),p.Getcols(),"points");
2037 	return_value->Add(ed);
2038 
2039 	//return_value.SetEDC(edc.GetCopy(),"MeshData");
2040 	return 1;
2041 }
2042 
2043 //this function computes mass, moment of inertia, volume and center of gravity based on the data about the geometry and the material
ComputeInertia(ElementDataContainer * data,ElementDataContainer * return_value)2044 int MultiBodySystem::ComputeInertia(ElementDataContainer* data, ElementDataContainer* return_value)
2045 {
2046 	int material_number = 0;
2047 	double rho = 0;
2048 
2049 	// set rho according to material_number or directly entered density, if there is no material_number
2050 	if(!data->Find("material_number"))	// if there is no material_number search for entry "density"
2051 	{
2052 		rho = data->TreeGetDouble("density",0);
2053 	}
2054 	else
2055 	{
2056 		material_number = data->TreeGetInt("material_number",0);
2057 		if(material_number <= NMaterials())
2058 		{
2059 			rho = GetMaterial(material_number).Density();
2060 		}
2061 		else
2062 		{
2063 			return 0;		// not a valid material_number
2064 		}
2065 	}
2066 
2067 	if(!rho) 	{	return 0; }// density == 0
2068 	// rho is now set
2069 
2070 	// start the computation of the inertia values
2071 	Matrix3D Iphi(0.);
2072 	double mass, volume;
2073 	Vector3D cog;
2074 
2075 	if(data->Find("MeshData"))
2076 	{
2077 		//see Maple file "maple/integration_triangle_volume.mws" and paper 'computing moments of piecewise polynomial surfaces'
2078 		double im11=0, im12=0, im13=0, im22=0, im23=0, im33=0;
2079 		double vol=0;
2080 		Vector3D center(0.,0.,0.);
2081 
2082 		int dummy = 0;
2083 		int Npoints, Ntrigs;
2084 
2085 		double * p;
2086 		double * t;
2087 		data->TreeGetMatrix("MeshData.points",&p,Npoints,dummy);
2088 		if(dummy!=3) {return 0;}	// error
2089 		data->TreeGetMatrix("MeshData.triangles",&t,Ntrigs,dummy);
2090 		if(dummy!=3) {return 0;}	// error
2091 
2092 		Matrix pts(Npoints,3,p);
2093 		Matrix trigs(Ntrigs,3,t);
2094 
2095 		for (int i=1; i <= Ntrigs; i++)
2096 		{
2097 			//const Vector3D& p1 = locpoints(trigs(i).Get(1));
2098 			//const Vector3D& p2 = locpoints(trigs(i).Get(2));
2099 			//const Vector3D& p3 = locpoints(trigs(i).Get(3));
2100 
2101 			const Vector3D& p1 = Vector3D(pts(trigs(i,1),1),pts(trigs(i,1),2),pts(trigs(i,1),3));
2102 			const Vector3D& p2 = Vector3D(pts(trigs(i,2),1),pts(trigs(i,2),2),pts(trigs(i,2),3));
2103 			const Vector3D& p3 = Vector3D(pts(trigs(i,3),1),pts(trigs(i,3),2),pts(trigs(i,3),3));
2104 
2105 			double v1x = p2.X()-p1.X();
2106 			double v1y = p2.Y()-p1.Y();
2107 			double v1z = p2.Z()-p1.Z();
2108 
2109 			double v2x = p3.X()-p1.X();
2110 			double v2y = p3.Y()-p1.Y();
2111 			double v2z = p3.Z()-p1.Z();
2112 			double px = p1.X();
2113 			double py = p1.Y();
2114 			double pz = p1.Z();
2115 
2116 			im11 += v1x*v1x*v1z*(v1x*v2y-v2x*v1y)/20.0+px*px*pz*(v1x*v2y-v2x*v1y)/2.0+(
2117 				2.0*px*v1x*v1z+v1x*v1x*pz)*(v1x*v2y-v2x*v1y)/12.0+(2.0*v2x*v1x*v1z+v1x*v1x*v2z)
2118 				*(v1x*v2y-v2x*v1y)/60.0+(2.0*px*v2x*v1z+2.0*px*v1x*v2z+2.0*v2x*v1x*pz)*(v1x*v2y
2119 				-v2x*v1y)/24.0+(v2x*v2x*v1z+2.0*v2x*v1x*v2z)*(v1x*v2y-v2x*v1y)/60.0+(px*px*v1z+
2120 				2.0*px*v1x*pz)*(v1x*v2y-v2x*v1y)/6.0+(px*px*v2z+2.0*px*v2x*pz)*(v1x*v2y-v2x*v1y
2121 				)/6.0+(2.0*px*v2x*v2z+v2x*v2x*pz)*(v1x*v2y-v2x*v1y)/12.0+v2x*v2x*v2z*(v1x*v2y-
2122 				v2x*v1y)/20.0;
2123 			double MapleGenVar1 = ((px*v1y+v1x*py)*v1z+v1x*v1y*pz)*(v1x*v2y-v2x*v1y)/12.0+((
2124 				v2x*v1y+v1x*v2y)*v1z+v1x*v1y*v2z)*(v1x*v2y-v2x*v1y)/60.0+((px*v2y+v2x*py)*v1z+(
2125 				px*v1y+v1x*py)*v2z+(v2x*v1y+v1x*v2y)*pz)*(v1x*v2y-v2x*v1y)/24.0+(v2x*v2y*v1z+(
2126 				v2x*v1y+v1x*v2y)*v2z)*(v1x*v2y-v2x*v1y)/60.0+(px*py*v2z+(px*v2y+v2x*py)*pz)*(
2127 				v1x*v2y-v2x*v1y)/6.0;
2128 			im12 += MapleGenVar1+((px*v2y+v2x*py)*v2z+v2x*v2y*pz)*(v1x*v2y-v2x*v1y)/12.0
2129 				+px*py*pz*(v1x*v2y-v2x*v1y)/2.0+(px*py*v1z+(px*v1y+v1x*py)*pz)*(v1x*v2y-v2x*v1y
2130 				)/6.0+v1x*v1y*v1z*(v1x*v2y-v2x*v1y)/20.0+v2x*v2y*v2z*(v1x*v2y-v2x*v1y)/20.0;
2131 			im13 += px*pz*pz*(v1x*v2y-v2x*v1y)/4.0+v1x*v1z*v1z*(v1x*v2y-v2x*v1y)/40.0+
2132 				v2x*v2z*v2z*(v1x*v2y-v2x*v1y)/40.0+(px*v1z*v1z+2.0*v1x*pz*v1z)*(v1x*v2y-v2x*v1y
2133 				)/24.0+(v2x*v1z*v1z+2.0*v1x*v2z*v1z)*(v1x*v2y-v2x*v1y)/120.0+(2.0*(px*v2z+v2x*
2134 				pz)*v1z+2.0*v1x*pz*v2z)*(v1x*v2y-v2x*v1y)/48.0+(2.0*v2x*v2z*v1z+v1x*v2z*v2z)*(
2135 				v1x*v2y-v2x*v1y)/120.0+(2.0*px*pz*v2z+v2x*pz*pz)*(v1x*v2y-v2x*v1y)/12.0+(px*v2z
2136 				*v2z+2.0*v2x*pz*v2z)*(v1x*v2y-v2x*v1y)/24.0+(2.0*px*pz*v1z+v1x*pz*pz)*(v1x*v2y-
2137 				v2x*v1y)/12.0;
2138 			im22 += py*py*pz*(v1x*v2y-v2x*v1y)/2.0+v2y*v2y*v2z*(v1x*v2y-v2x*v1y)/20.0+
2139 				v1y*v1y*v1z*(v1x*v2y-v2x*v1y)/20.0+(2.0*py*v1y*v1z+v1y*v1y*pz)*(v1x*v2y-v2x*v1y
2140 				)/12.0+(2.0*v2y*v1y*v1z+v1y*v1y*v2z)*(v1x*v2y-v2x*v1y)/60.0+(2.0*py*v2y*v1z+2.0
2141 				*py*v1y*v2z+2.0*v2y*v1y*pz)*(v1x*v2y-v2x*v1y)/24.0+(v2y*v2y*v1z+2.0*v2y*v1y*v2z
2142 				)*(v1x*v2y-v2x*v1y)/60.0+(py*py*v1z+2.0*py*v1y*pz)*(v1x*v2y-v2x*v1y)/6.0+(py*py
2143 				*v2z+2.0*py*v2y*pz)*(v1x*v2y-v2x*v1y)/6.0+(2.0*py*v2y*v2z+v2y*v2y*pz)*(v1x*v2y-
2144 				v2x*v1y)/12.0;
2145 			im23 += v2y*v2z*v2z*(v1x*v2y-v2x*v1y)/40.0+py*pz*pz*(v1x*v2y-v2x*v1y)/4.0+
2146 				v1y*v1z*v1z*(v1x*v2y-v2x*v1y)/40.0+(py*v1z*v1z+2.0*v1y*pz*v1z)*(v1x*v2y-v2x*v1y
2147 				)/24.0+(v2y*v1z*v1z+2.0*v1y*v2z*v1z)*(v1x*v2y-v2x*v1y)/120.0+(2.0*(py*v2z+v2y*
2148 				pz)*v1z+2.0*v1y*pz*v2z)*(v1x*v2y-v2x*v1y)/48.0+(2.0*v2y*v2z*v1z+v1y*v2z*v2z)*(
2149 				v1x*v2y-v2x*v1y)/120.0+(2.0*py*pz*v2z+v2y*pz*pz)*(v1x*v2y-v2x*v1y)/12.0+(py*v2z
2150 				*v2z+2.0*v2y*pz*v2z)*(v1x*v2y-v2x*v1y)/24.0+(2.0*py*pz*v1z+v1y*pz*pz)*(v1x*v2y-
2151 				v2x*v1y)/12.0;
2152 			im33 += v2z*v1z*v1z*(v1x*v2y-v2x*v1y)/60.0+v1z*v1z*v1z*(v1x*v2y-v2x*v1y)/
2153 				60.0+pz*v2z*v1z*(v1x*v2y-v2x*v1y)/12.0+pz*pz*v1z*(v1x*v2y-v2x*v1y)/6.0+v2z*v2z*
2154 				v1z*(v1x*v2y-v2x*v1y)/60.0+pz*pz*v2z*(v1x*v2y-v2x*v1y)/6.0+pz*v2z*v2z*(v1x*v2y-
2155 				v2x*v1y)/12.0+pz*pz*pz*(v1x*v2y-v2x*v1y)/6.0+v2z*v2z*v2z*(v1x*v2y-v2x*v1y)/60.0
2156 				+pz*v1z*v1z*(v1x*v2y-v2x*v1y)/12.0;
2157 
2158 			vol += 1./6.*v1z*(v1x*v2y-v2x*v1y)+1./6.*v2z*(v1x*v2y-v2x*v1y)+1./2.*pz*(v1x*v2y-v2x*v1y);
2159 
2160 			center.X() += v1x*v1z*(v1x*v2y-v2x*v1y)/12.0+(v2x*v1z+v1x*v2z)*(v1x*v2y-v2x*v1y)/24.0+v2x*v2z*(v1x*v2y-v2x*v1y)/12.0+(px*v1z+v1x*pz)*(v1x*v2y-v2x*v1y)/6.0+(px*v2z+v2x*pz)*(v1x*v2y-v2x*v1y)/6.0+px*pz*(v1x*v2y-v2x*v1y)/2.0;
2161 			center.Y() += v1y*v1z*(v1x*v2y-v2x*v1y)/12.0+(v2y*v1z+v1y*v2z)*(v1x*v2y-v2x*v1y)/24.0+v2y*v2z*(v1x*v2y-v2x*v1y)/12.0+(py*v1z+v1y*pz)*(v1x*v2y-v2x*v1y)/6.0+(py*v2z+v2y*pz)*(v1x*v2y-v2x*v1y)/6.0+py*pz*(v1x*v2y-v2x*v1y)/2.0;
2162 			center.Z() += v1z*v1z*(v1x*v2y-v2x*v1y)/24.0+v2z*v1z*(v1x*v2y-v2x*v1y)/24.0+v2z*v2z*(v1x*v2y-v2x*v1y)/24.0+pz*v1z*(v1x*v2y-v2x*v1y)/6.0+pz*v2z*(v1x*v2y-v2x*v1y)/6.0+pz*pz*(v1x*v2y-v2x*v1y)/4.0;
2163 		}
2164 		volume = vol;
2165 		mass = volume*rho;
2166 		Iphi = rho * Matrix3D(im22+im33,-im12,-im13, -im12, im11+im33, -im23, -im13, -im23, im11+im22);
2167 		if (vol != 0)
2168 		{
2169 			cog = center * (1./vol);
2170 		}
2171 	}
2172 	else if(data->Find("Cube"))
2173 	{
2174 		double x,y,z;
2175 		data->TreeGetVector3D("Cube.body_dimensions",x,y,z);
2176 
2177 		volume = x*y*z;
2178 		mass = volume*rho;
2179 		Iphi(1,1)= 1./12.*mass*(Sqr(y)+Sqr(z));
2180 		Iphi(2,2)= 1./12.*mass*(Sqr(x)+Sqr(z));
2181 		Iphi(3,3)= 1./12.*mass*(Sqr(x)+Sqr(y));
2182 		cog = Vector3D(0.);
2183 	}
2184 	else if(data->Find("Cylinder"))
2185 	{
2186 
2187 	}
2188 
2189 	// set the new edc
2190 	ElementData ed;
2191 	ed.SetDouble(volume,"volume"); return_value->Add(ed);
2192 	ed.SetDouble(mass,"mass"); return_value->Add(ed);
2193 	ed.SetVector3D(cog.X(),cog.Y(),cog.Z(),"center_of_mass"); return_value->Add(ed);
2194 	ed.SetMatrix(Iphi.GetMatPtr(),3,3,"moment_of_inertia"); return_value->Add(ed);
2195 
2196 	return 1;
2197 
2198 }
2199 
2200 //this function reads a column of a file and returns it as vector, rv = 1.. success, 0..file is not good
LoadVectorFromFile(const char * filename,int col,ElementDataContainer * return_value)2201 int MultiBodySystem::LoadVectorFromFile(const char* filename, int col, ElementDataContainer* return_value)
2202 {
2203 	CMatrixFile file( filename, TFMread );
2204 	if(file.IsGood())
2205 	{
2206 		file.ReadSingleColumn(col);
2207 		TArray<double>& coldata = file.Column(col);
2208 		Vector test;
2209 		test.SetVector(coldata);
2210 		// set the new edc
2211 		ElementData ed;
2212 		ed.SetVector(test.GetVecPtr(), test.Length(),"vector"); return_value->Add(ed);
2213 		return 1;
2214 	}
2215 	else
2216 	{
2217 		return 0;
2218 	}
2219 }
2220 
AddReplaceModelDataEDC(ElementDataContainer & edc)2221 void MultiBodySystem::AddReplaceModelDataEDC(/*const */ElementDataContainer& edc)
2222 {
2223 	//$ DR 2013-06-12:[ code that has been in AddModelData
2224 	// verbosity level is needed for further opertation
2225 	if (edc.TreeFind("LoggingOptions.output_level"))    // temporary solution - best would be to have an entry like "GeneralOptions.show_general_warnings" in edc_file     //$ PG 2012-2-3: substituted SolverOptions.Log.output_level by LoggingOptions.output_level
2226 	{
2227 		GetOptions()->LoggingOptions()->OutputLevel() = edc.TreeGetInt("LoggingOptions.output_level");       //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel() and SolverOptions.Log.output_level by LoggingOptions.output_level
2228 	}
2229 	//$ DR 2013-06-12:] code that has been in AddModelData
2230 
2231 	bool show_warnings = ( GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_dbg1 );    //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel()
2232 
2233 	ElementData* edmodel;
2234 
2235 	// loop over all default main branches
2236 	for (int i=1; i <= edc.Length(); i++)
2237 	{
2238 		// get i-th main branch
2239 		if(!GetMBS_EDC_Options()->TreeFind(edc.GetPtr(i)->GetDataName()))
2240 		{
2241 			ElementDataContainer edci;edci.TreeAdd("",edc.Get(i));
2242 			edc_modeldata->TreeReplaceEDCDataWith(&edci, show_warnings, mystr(edc.GetPtr(i)->GetDataName())+mystr("."));
2243 		}
2244 	}
2245 
2246 	//$ DR 2013-06-12:[ code that has been in AddModelData
2247 	// replace solveroptions & other settings
2248 	ElementData* eddef;
2249 	ElementData* edfile;
2250 
2251 	// loop over all default main branches
2252 	for (int i=1; i <= GetMBS_EDC_Options()->Length(); i++)
2253 	{
2254 		// get i-th main branch
2255 		//eddef = edc_default.GetPtr(i);
2256 		eddef = GetMBS_EDC_Options()->GetPtr(i);
2257 		edfile = edc.TreeFind(eddef->GetDataName());
2258 		// replace the default settings by the user's file settings
2259 		if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2260 		{
2261 			if(GetMBS_EDC_Options()->TreeFind(edfile->GetDataName()))
2262 			{
2263 				UO(UO_LVL_ext) << "replacing hotint option: " << edfile->GetDataName() << "\n";
2264 				// use file parameters (when existing) instead of default variables
2265 				eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2266 			}
2267 		}
2268 	}
2269 	// overwrite default options by user file data
2270 	EDC2SolverOptions(GetMBS_EDC_Options());
2271 	EDC2Options(GetMBS_EDC_Options());       // copy EDC to i/d/toptions
2272 
2273 	OpenLogFile(0);
2274 
2275 	UO() << "done.\n";
2276 	UO() << "--------------------------------\n";
2277 	//$ DR 2013-06-12:] code that has been in AddModelData
2278 }
2279 
2280 
ReadModelData(mystr filename)2281 int MultiBodySystem::ReadModelData(mystr filename)
2282 {
2283 	ElementDataContainer edc_file;
2284 
2285 	// read parameters from file and store it in ElementDataContainer of mbs (details: see forum)
2286 	CMFile file(filename, TFMread);
2287 	UO()	<< "--------------------------------\n";
2288 	int rv = 1;
2289 
2290 	//read parameters from file
2291 	if (file.IsGood())
2292 	{
2293 		UO(UO_LVL_0) << "read " << filename << "\n";
2294 
2295 		//read file
2296 		mystr str;
2297 		file.RWF(str);
2298 
2299 		//$ DR 2013-03-09:[
2300 		// Get the variables of the parameter variation
2301 		ElementDataContainer edc_tmp;
2302 		ElementData ed_tmp;
2303 		if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.ParameterVariation.activate"))
2304 		{
2305 			mystr varname = GetMBS_EDC_Options()->TreeGetString("SolverOptions.ParameterVariation.MBS_EDC_variable_name");
2306 			double val = edc_modeldata->TreeGetDouble(varname);
2307 			ed_tmp.SetDouble(val,varname);
2308 			edc_tmp.Add(ed_tmp);
2309 			if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.ParameterVariation.Var2.activate"))
2310 			{
2311 				varname = GetMBS_EDC_Options()->TreeGetString("SolverOptions.ParameterVariation.Var2.MBS_EDC_variable_name");
2312 				val = edc_modeldata->TreeGetDouble(varname);
2313 				ed_tmp.SetDouble(val,varname);
2314 				edc_tmp.Add(ed_tmp);
2315 			}
2316 		}
2317 		//$ DR 2013-03-09:]
2318 		//$ RE & MSax 2013-06-27:[
2319 		else if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.Optimization.activate") && edc_modeldata)
2320 		{
2321 			int number_of_params = GetMBS_EDC_Options()->TreeGetInt("SolverOptions.Optimization.Parameters.number_of_params");
2322 			for (int col=1; col <= number_of_params; col++)
2323 			{
2324 				mystr varname =	GetMBS_EDC_Options()->TreeGetString(mystr("SolverOptions.Optimization.Parameters.param_name")+mystr(col));
2325 				double val = edc_modeldata->TreeGetDouble(varname);
2326 				ed_tmp.SetDouble(val,varname);
2327 				edc_tmp.Add(ed_tmp);
2328 			}
2329 		}
2330 		//$ RE & MSax 2013-06-27:]
2331 
2332 
2333 
2334 //$!AD 26-09-2013: parse line by line directly into modeldata EDC [
2335 // NEW CODE:
2336 		edc_modeldata = 0;
2337 		if (edc_modeldata != 0)
2338 		{
2339 			delete edc_modeldata;
2340 			edc_modeldata = 0;
2341 		}
2342 		edc_modeldata = new ElementDataContainer;
2343 
2344 		// overwrite edc with contents from file
2345 		//edc_modeldata = &edc_file; //JG, this is just temporary in order to get variables, change to MBSParser->readedc_global/local!!!
2346 		ElementData ed;
2347 		ed.SetText(filename, "last_file_name");edc_modeldata->Add(ed); // path is stored e.g. for getting relative paths in include command
2348 
2349 		//$ DR 2013-03-09:[
2350 		// set the values for the parameter variation and save them with flagging them as readonly
2351 		for(int i=1; i<=edc_tmp.Length();i++)
2352 		{
2353 			edc_modeldata->Add(edc_tmp.Get(i));
2354 			edc_modeldata->Last().SetLocked(1);
2355 		}
2356 		edc_tmp.Reset();
2357 		//$ DR 2013-03-09:]
2358 
2359 		this->EDCParser().GetMBSParser()->SetLocalEDC2(edc_modeldata);
2360 		rv = this->EDCParser().ParseAndExecuteString(str, *edc_modeldata);
2361 		edc_file = *(edc_modeldata->GetCopy());	//$ DR+AD 2013-10-01 bugfix, copy is necessary for solver options
2362 
2363 // OLD CODE:
2364 		////////
2365 		//////////UO() << "WARNING:set read EDC==>modeldata!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
2366 		////////rv = EDCParser().String2TreeEDC(/*this, */str, edc_file);
2367 		//////////UO() << "delete read EDC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
2368 		//////////delete read EDC
2369 		////////edc_modeldata = 0;
2370 
2371 		////////SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions) at start of Generate - function
2372 		////////
2373 //$!AD ]
2374 	}
2375 	else // FileNotGood
2376 	{
2377 		UO()	<< "*****************\n";
2378 		UO()	<< "*****************\n";
2379 		UO()	<< "*****************\n";
2380 		UO()	<< "ERROR: failed to read model data from " << filename << "\n";
2381 		UO()	<< "*****************\n";
2382 		UO()	<< "*****************\n";
2383 		UO()	<< "*****************\n";
2384 		SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions) at start of Generate - function
2385 
2386 		return 0;  //$JG2012-02-21 changed from 2 to 0 in case of error
2387 	}
2388 
2389 	// verbosity level is needed for further opertation
2390 	if (edc_file.TreeFind("LoggingOptions.output_level"))    // temporary solution - best would be to have an entry like "GeneralOptions.show_general_warnings" in edc_file         //$ PG 2012-2-3: substituted SolverOptions.Log.output_level by LoggingOptions.output_level
2391 	{
2392 		GetOptions()->LoggingOptions()->OutputLevel() = edc_file.TreeGetInt("LoggingOptions.output_level");    //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel(), and SolverOptions.Log.output_level by LoggingOptions.output_level
2393 	}
2394 	bool show_warnings = ( GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_warn );     //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel()
2395 
2396 	// load default parameter settings
2397 	ElementDataContainer* edc_default = GetMBS_EDC_Options();
2398 
2399 	RemoveVariableFromEDCTree(*edc_default, mystr("SolverOptions.ComputationSteps"), 1);
2400 
2401 	ElementData* eddef;
2402 	ElementData* edfile;
2403 
2404 	//$ AD: 2011-11-08: special treatment for Computation Step entries in EDC
2405 	// as these entries would produce a popupwindow every time when using TreeReplace
2406 	// copy computation steps manually, assume that entry does NOT exist in default EDC
2407 	ElementData* edcsfile = edc_file.TreeFind("SolverOptions.ComputationSteps");
2408 	if(edcsfile != 0 && edcsfile->IsEDC())
2409 	{
2410 		ElementDataContainer* edc_solopt_default = edc_default->TreeFind("SolverOptions")->GetEDC();
2411 		edc_solopt_default->Add(*edcsfile);
2412 		UO(UO_LVL_ext) << "Added Computation Steps: (" << edcsfile->GetEDC()->Length() << ")\n";
2413 	// one could eliminate entries from FileEDC now...
2414 		RemoveVariableFromEDCTree(edc_file, mystr("SolverOptions.ComputationSteps"), 0);
2415 	}
2416 
2417 
2418 	// loop over all default main branches
2419 	for (int i=1; i <= edc_default->Length(); i++)
2420 	{
2421 
2422 		// get i-th main branch
2423 		eddef = edc_default->GetPtr(i);
2424 		edfile = edc_file.TreeFind(eddef->GetDataName());
2425 
2426 		// replace the default settings by the user's file settings
2427 		if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2428 		{
2429 			UO(UO_LVL_ext) << "replacing defaults: " << edfile->GetDataName() << "\n";
2430 
2431 			// use file parameters (when existing) instead of default variables
2432 			eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2433 		}
2434 	}
2435 
2436 	// overwrite default options by user file data
2437 	EDC2SolverOptions(edc_default);
2438 	EDC2Options(edc_default);       // copy EDC to i/d/toptions
2439 
2440 	UO() << "done.\n";
2441 	UO() << "--------------------------------\n";
2442 
2443 	return rv; //1==success, 0==error
2444 }
2445 
2446 // use add model data after command read model data; assumption: model data container is not empty!!!
2447 //$ DR 2013-07-25: assumption is not necessary anymore.
2448 //$ AD 2013-10-22: uses ParseAndExecuteString to instantly write to edc_modeldata
AddModelData(mystr filename)2449 int MultiBodySystem::AddModelData(mystr filename)
2450 {
2451 	UO(UO_LVL_0) << "read " << filename << "\n";
2452 
2453 	ElementDataContainer edc_file;
2454 
2455 	// store file name for include command with relative paths
2456 	ElementData ed;
2457 	ed.SetText(filename, "last_file_name");
2458 	if(edc_modeldata != 0)
2459 	{
2460 		edc_modeldata->TreeSet("",ed);
2461 	}
2462 	else
2463 	{
2464 		SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions)
2465 	}
2466 
2467 //$ AD 2013-10-22: read the string and parse it directly into the modeldatacontainer
2468 	mystr str;
2469 	int rv = File2Str(filename, str);
2470 	if(!rv)return rv;
2471 
2472 	EDCParser().ParseAndExecuteString(str, *edc_modeldata);
2473 
2474 	// replace solveroptions & other settings
2475 	bool show_warnings = GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_dbg1;
2476 	ElementData* eddef;
2477 	ElementData* edfile;
2478 
2479 	// loop over all default main branches
2480 	for (int i=1; i <= GetMBS_EDC_Options()->Length(); i++)
2481 	{
2482 		// get i-th main branch
2483 		//eddef = edc_default.GetPtr(i);
2484 		eddef = GetMBS_EDC_Options()->GetPtr(i);
2485 		edfile = edc_modeldata->TreeFind(eddef->GetDataName());
2486 		// replace the default settings by the user's file settings
2487 		if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2488 		{
2489 			if(GetMBS_EDC_Options()->TreeFind(edfile->GetDataName()))
2490 			{
2491 				UO(UO_LVL_ext) << "replacing hotint option: " << edfile->GetDataName() << "\n";
2492 				// use file parameters (when existing) instead of default variables
2493 				eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2494 			}
2495 		}
2496 	}
2497 	// overwrite default options by user file data
2498 	EDC2SolverOptions(GetMBS_EDC_Options());
2499 	EDC2Options(GetMBS_EDC_Options());       // copy EDC to i/d/toptions
2500 
2501 	OpenLogFile(0);
2502 
2503 	UO() << "done.\n";
2504 	UO() << "--------------------------------\n";
2505 
2506 	return 1; //success
2507 }
2508 
2509 // remove a variable or branch from the edc by name - this is used to prevent ComputationSteps to be written to file and to be remembered from a previous model
RemoveVariableFromEDCTree(ElementDataContainer & edc,mystr & varname,int warning)2510 int MultiBodySystem::RemoveVariableFromEDCTree(ElementDataContainer& edc, mystr& varname, int warning)
2511 {
2512 	mystr treename, elementname;
2513 	edc.SplitIntoTreeAndElementName(varname, treename, elementname);
2514 	ElementData* ed_branch = edc.TreeFind(varname);
2515 
2516 	if (ed_branch != 0) // variable exists
2517 	{
2518 		ElementDataContainer* edc_nesting;
2519 		if(treename.Length())
2520 		{
2521 			edc_nesting = edc.TreeFind(treename)->GetEDC();
2522 		}
2523 		else
2524 		{
2525 			edc_nesting = &edc;
2526 		}
2527 
2528 		if (warning)
2529 		{
2530 			if( ed_branch -> IsEDC() ) UO(UO_LVL_ext) << "removing sub-edc " + varname + " from edc\n";
2531 			else UO(UO_LVL_ext) << "removing entry " + varname + "from edc \n";
2532 		}
2533 
2534 		edc_nesting->Delete(edc_nesting->Find(elementname));
2535 		return 1;
2536 	}
2537 	return 0;
2538 }
2539 
AddFileSensor(const char * filename,const mystr sensor_name,const int ncolumns,const int colTime,const int colSignal,const int interpolation,const int nrOfHeaderLines)2540 int MultiBodySystem::AddFileSensor(const char* filename, const mystr sensor_name, const int ncolumns, const int colTime, const int colSignal, const int interpolation, const int nrOfHeaderLines)
2541 {
2542 	/*
2543 	MathFunction mf;
2544 	if(mf.SetPiecewiseFromFile(filename, ncolumns, colTime, colSignal, interpolation, nrOfHeaderLines)) // interpolation: 0...steps, 1...piecewise linear
2545 	{
2546 		InstantMessageText(mystr("Error1: File " + mystr(filename) + " not found!"));
2547 		return 1; // error
2548 	}
2549 	Vector2D posDraw(0.,0.); // drawing position
2550 	Vector3D drawDim = Vector3D(0.2,0.2,0.); // draw dimension of control element
2551 	IOTime lt_time(this);
2552 	lt_time.SetElementName(sensor_name+"-IOTime");
2553 	lt_time.SetRefPos2D(Vector2D(0.,3.0)+posDraw);//define reference position for drawing
2554 	lt_time.SetDrawDim(drawDim);     //define size of rectangle for drawing (B, H, dummy)
2555 	int nLt_time = AddElement(&lt_time);
2556 
2557 	IOMathFunction iom_ty(this);
2558 	iom_ty.SetIOMathFunction(mf);
2559 	iom_ty.SetRefPos2D(Vector2D(0.5,3.0)+posDraw);
2560 	iom_ty.SetDrawDim(drawDim);
2561 	iom_ty.SetElementName(sensor_name+"-IOMathFcn");						//Change name of element from default name
2562 	iom_ty.AddInput(nLt_time, IOInputTypeElement, 1);  // connection(nLt_time,  typ=io, output 1)
2563 	int nIo_ty = AddElement(&iom_ty);
2564 
2565 	MBSSensor sens_mes(this, TMBSSensor(TSOutputSensor), nIo_ty, 1); //measure output 1
2566 	sens_mes.SetSensorName(sensor_name);
2567 	AddSensor(&sens_mes);
2568 	*/
2569 	return 0; //success
2570 }
AddFileSensor2(const char * filename,const mystr sensor_name,const int colTime,const int colSignal,const int interpolation,mystr comment)2571 int MultiBodySystem::AddFileSensor2(const char* filename, const mystr sensor_name, const int colTime, const int colSignal, const int interpolation, mystr comment)
2572 {
2573 	/*
2574 	MBSSensor sens_mes(this, TMBSSensor(TSFile), colTime, colSignal); //measure output 1
2575 	if(sens_mes.SetTSFile(filename, colTime, colSignal, interpolation, comment)) // set file name
2576 	{
2577 		return 1; // error, don't add sensor
2578 	}
2579 	sens_mes.SetSensorName(sensor_name);
2580 	AddSensor(&sens_mes);
2581 	*/
2582 	return 0; //success
2583 }
2584 
2585 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2586 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SetOptions2EDCOptions()2587 void MultiBodySystem::SetOptions2EDCOptions()
2588 {
2589 	ElementDataContainer* edc = GetMBS_EDC_Options();
2590 	ElementDataContainer edcnew;
2591 	Options2EDC(&edcnew);                //copy options to edc:
2592 	edc->TreeReplaceEDCDataWith(&edcnew);//replace edcnew data in edc:
2593 }
2594 
SetEDCOptions2Options()2595 void MultiBodySystem::SetEDCOptions2Options()
2596 {
2597 	ElementDataContainer* edc = GetMBS_EDC_Options();
2598 	EDC2Options(edc);
2599 }
2600 
SetComputationSolverOptions()2601 void MultiBodySystem::SetComputationSolverOptions()
2602 {
2603 	ElementDataContainer* edc = GetMBS_EDC_Options();
2604 	EDC2SolverOptions(edc);
2605 }
2606 
SetSolverDialogOptions()2607 void MultiBodySystem::SetSolverDialogOptions()
2608 {
2609 	//update computation options with solver settings:
2610 
2611 	ElementDataContainer* edc = GetMBS_EDC_Options();
2612 	ElementDataContainer edcnew;
2613 
2614 	//copy mbssolset to edc:
2615 	SolverOptions2EDC(&edcnew);
2616 	//replace edcnew data in edc:
2617 	edc->TreeReplaceEDCDataWith(&edcnew);
2618 
2619 }
2620 
2621