1 //#**************************************************************
2 //#
3 //# filename: elementdata.cpp
4 //#
5 //# author: Gerstmayr Johannes
6 //#
7 //# generated: March 2010
8 //# description: Utilities for general data structure ElementData and ElementDataContainer
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 "tarray.h"
26 #include "mystring.h"
27 #include "elementdata.h"
28
ElementData()29 ElementData::ElementData()
30 {
31 dataname = 0;
32 vdata = 0;
33 vdatalen = 0;
34 tdata = 0;
35 locked = 0;
36 hastooltip = 0;
37 tooltiptext = 0;
38 idata = 0;
39 idata2 = 0;
40 idata3 = 0;
41 groupnum = 0;
42 minval = 1;
43 maxval = 0;
44 oneLimit = 0;
45 edc = 0;
46 type = 0;
47 };
48
ElementData(const ElementData & e)49 ElementData::ElementData(const ElementData& e)
50 {
51 dataname = 0;
52 vdata = 0;
53 vdatalen = 0;
54 tdata = 0;
55 idata = 0;
56 idata2 = 0;
57 idata3 = 0;
58 groupnum = 0;
59 minval = 1;
60 maxval = 0;
61 oneLimit = 0;
62 locked = 0;
63 hastooltip = 0;
64 tooltiptext = 0;
65 edc = 0;
66 type = 0;
67
68 CopyFrom(e);
69 };
70
71
CopyFrom(const ElementData & e)72 void ElementData::CopyFrom(const ElementData& e)
73 {
74 Reset(); //free data
75
76 vdatalen = e.vdatalen;
77 type = e.type;
78 idata = e.idata;
79 idata2 = e.idata2;
80 idata3 = e.idata3;
81 groupnum = e.groupnum;
82 locked = e.locked;
83 minval = e.minval;
84 maxval = e.maxval;
85 oneLimit = e.oneLimit;
86 hastooltip = e.hastooltip;
87
88 if (e.edc != 0)
89 {
90 edc = e.edc->GetCopy();
91 }
92 else
93 {
94 edc = 0;
95 }
96 if (e.dataname != 0)
97 {
98 int length = strlen(e.dataname);
99 dataname = new char[length + 1];
100 strcpy(dataname, e.dataname);
101 } else
102 {
103 dataname = 0;
104 }
105 if (e.vdata != 0)
106 {
107 vdata = new double[vdatalen];
108 for (int i=0; i < vdatalen; i++)
109 {
110 vdata[i] = e.vdata[i];
111 }
112 } else
113 {
114 vdata = 0;
115 }
116 if (e.tdata != 0)
117 {
118 int length = strlen(e.tdata);
119 tdata = new char[length + 1];
120 strcpy(tdata, e.tdata);
121 }
122 else
123 {
124 tdata = 0;
125 }
126 if (e.tooltiptext != 0)
127 {
128 int length = strlen(e.tooltiptext);
129 tooltiptext = new char[length + 1];
130 strcpy(tooltiptext, e.tooltiptext);
131 }
132 else
133 {
134 tooltiptext = 0;
135 }
136 }
137
Reset()138 void ElementData::Reset()
139 {
140 locked = 0;
141 minval = 1;
142 maxval = 0;
143 hastooltip = 0;
144
145 if (vdatalen != 0 && vdata != 0)
146 {
147 delete[] vdata;
148 vdata = 0;
149 }
150 if (dataname != 0)
151 {
152 delete[] dataname;
153 dataname = 0;
154 }
155 if (tdata != 0)
156 {
157 delete[] tdata;
158 tdata = 0;
159 }
160 if (tooltiptext != 0)
161 {
162 delete[] tooltiptext;
163 tooltiptext = 0;
164 }
165 if (edc != 0)
166 {
167 delete edc;
168 edc = 0;
169 }
170 }
171
172
SetVector2D(double vx,double vy,const char * name,double minvalI,double maxvalI,bool onlyLowerBorder,bool onlyUpperBorder)173 void ElementData::SetVector2D(double vx, double vy, const char* name,double minvalI, double maxvalI, bool onlyLowerBorder, bool onlyUpperBorder)
174 {
175 Reset();
176 SetDataName(name);
177 type = 4+32;
178 vdatalen = 2;
179 vdata = new double[vdatalen];
180 vdata[0] = vx;
181 vdata[1] = vy;
182 SetMinMaxVal(minvalI, maxvalI, onlyLowerBorder, onlyUpperBorder);
183 }
SetVector3D(double vx,double vy,double vz,const char * name,double minvalI,double maxvalI,bool onlyLowerBorder,bool onlyUpperBorder)184 void ElementData::SetVector3D(double vx, double vy, double vz, const char* name, double minvalI, double maxvalI, bool onlyLowerBorder, bool onlyUpperBorder)
185 {
186 Reset();
187 SetDataName(name);
188 type = 4+32;
189 vdatalen = 3;
190 vdata = new double[vdatalen];
191 vdata[0] = vx;
192 vdata[1] = vy;
193 vdata[2] = vz;
194 SetMinMaxVal(minvalI, maxvalI, onlyLowerBorder, onlyUpperBorder);
195 }
196
SetVector(double * v,int len,const char * name,double minvalI,double maxvalI,bool onlyLowerBorder,bool onlyUpperBorder)197 void ElementData::SetVector(double* v, int len, const char* name, double minvalI, double maxvalI, bool onlyLowerBorder, bool onlyUpperBorder)
198 {
199 Reset();
200 SetDataName(name);
201 type = 4;
202 vdatalen = len;
203
204 if (len > 0)
205 {
206 vdata = new double[vdatalen];
207 for (int i = 0; i < vdatalen; i++)
208 {
209 vdata[i] = v[i];
210 }
211 }
212 SetMinMaxVal(minvalI, maxvalI, onlyLowerBorder, onlyUpperBorder);
213 }
214
SetMatrix(double * v,int rows,int cols,const char * name)215 void ElementData::SetMatrix(double* v, int rows, int cols, const char* name)
216 {
217 Reset();
218
219 SetDataName(name);
220 type = 1024;
221 vdatalen = rows*cols;
222
223 idata = rows;
224 idata2 = cols;
225
226 if (vdatalen > 0)
227 {
228 vdata = new double[vdatalen];
229 for (int i = 0; i < vdatalen; i++)
230 {
231 vdata[i] = v[i];
232 }
233 }
234 }
235
SetVector2DList(double * v,int n,const char * name)236 void ElementData::SetVector2DList(double* v, int n, const char* name) // $ MSax 2013-07-09 : added
237 {
238 Reset();
239
240 SetDataName(name);
241 type = 1024+4096+16384; //matrix & variable length & fixed number of columns
242 vdatalen = 2*n;
243
244 idata = n;
245 idata2 = 2; //number of columns = 2
246
247 if (vdatalen > 0)
248 {
249 vdata = new double[vdatalen];
250 for (int i = 0; i < vdatalen; i++)
251 {
252 vdata[i] = v[i];
253 }
254 }
255 }
256
SetMinMaxVal(double minvalI,double maxvalI,bool onlyLowerBorder,bool onlyUpperBorder)257 void ElementData::SetMinMaxVal(double minvalI, double maxvalI, bool onlyLowerBorder, bool onlyUpperBorder)
258 {
259 // 4 cases for boundaries are possible:
260 // oneLimit = 0:
261 // minval<=maxval upper and lower boundary are active: [...]
262 // minval >maxval no boundary is active: ...
263 // onLimit = 1:
264 // minval<=maxval only upper boundary is active: ...]
265 // minval >maxval only lower boundary is active: [...
266
267 if(onlyLowerBorder)
268 {
269 minval = minvalI;
270 maxval = minval-1;
271 }
272 else if(onlyUpperBorder)
273 {
274 maxval = maxvalI;
275 minval = maxval-1;
276 }
277 else
278 {
279 maxval = maxvalI;
280 minval = minvalI;
281 }
282
283 oneLimit = onlyUpperBorder || onlyLowerBorder;
284 }
285
SetInt(int num,const char * name,int minvalI,int maxvalI,bool onlyLowerBorder,bool onlyUpperBorder)286 void ElementData::SetInt(int num, const char* name, int minvalI, int maxvalI, bool onlyLowerBorder, bool onlyUpperBorder)
287 {
288 Reset();
289 SetDataName(name);
290 type = 1;
291 idata = num;
292 double min = (double)minvalI;
293 double max = (double)maxvalI;
294 SetMinMaxVal(min, max, onlyLowerBorder, onlyUpperBorder);
295 }
296
297
SetEDC(ElementDataContainer * edcI,const char * name)298 void ElementData::SetEDC(ElementDataContainer* edcI, const char* name)
299 {
300 Reset();
301 SetDataName(name);
302 type = 8192;
303
304 edc = edcI->GetCopy();
305 }
306
SetEDCno_copy(ElementDataContainer * edcI,const char * name)307 void ElementData::SetEDCno_copy(ElementDataContainer* edcI, const char* name)
308 {
309 Reset();
310 SetDataName(name);
311 type = 8192;
312
313 edc = edcI;
314 }
315
GetEDC()316 ElementDataContainer* ElementData::GetEDC()
317 {
318 return edc;
319 }
320
GetEDC() const321 const ElementDataContainer* ElementData::GetEDC() const
322 {
323 return edc;
324 }
325
Find(const char * name) const326 int ElementDataContainer::Find(const char* name) const
327 {
328 for (int i=1; i <= elemdata.Length(); i++)
329 {
330 if (_stricmp(name, elemdata(i)->GetDataName()) == 0) return i; //stricmp ignores case!!!!
331 }
332 return 0;
333 }
334 //$ RL 2011-6-23:[find all indices in an EDC of entries with same name.
FindAll(const char * name,TArray<int> & indices) const335 void ElementDataContainer::FindAll(const char* name, TArray<int>& indices) const
336 {
337 indices.SetLen(0);
338 for (int i=1; i <= elemdata.Length(); i++)
339 {
340 if (_stricmp(name, elemdata(i)->GetDataName()) == 0)
341 {
342 indices.Add(i); //stricmp ignores case!!!!
343 }
344 }
345 }
346 //$ RL 2011-6-23:]find all indices in an EDC of entries with same name.
347
348
TreeFind(const char * name) const349 const ElementData* ElementDataContainer::TreeFind(const char* name) const
350 {
351 mystr str(name);
352 if (str.Find('.') != -1)
353 {
354 int pos = 0;
355 mystr dataname;
356 str.GetUntil(pos, '.', dataname);
357 mystr str_rest = str.SubString(pos+1, str.Length()-1);
358
359 int i = Find(dataname);
360 if (i && Get(i).IsEDC())
361 {
362 return Get(i).GetEDC()->TreeFind(str_rest.c_str());
363 }
364 return 0;
365
366 }
367 else //no tree structure searched for
368 {
369 int i = Find(name);
370 if (i) return GetPtr(i);
371 return 0;
372 }
373 }
374
TreeFind(const char * name)375 ElementData* ElementDataContainer::TreeFind(const char* name)
376 {
377 mystr str(name);
378 if (str.Find('.') != -1)
379 {
380 int pos = 0;
381 mystr dataname;
382 str.GetUntil(pos, '.', dataname);
383 mystr str_rest = str.SubString(pos+1, str.Length()-1);
384
385 int i = Find(dataname);
386 if (i && Get(i).IsEDC())
387 {
388 return Get(i).GetEDC()->TreeFind(str_rest.c_str());
389 }
390 return 0;
391
392 }
393 else //no tree structure searched for
394 {
395 int i = Find(name);
396 if (i) return GetPtr(i);
397 return 0;
398 }
399 }
400
401 //delete an element in tree, name is e.g. "root.child1.child2.leave"; the name of the deleted object is "leave"
TreeDelete(const char * name)402 void ElementDataContainer::TreeDelete(const char* name)
403 {
404 mystr str(name);
405 if (str.Find('.') != -1)
406 {
407 int pos = 0;
408 mystr dataname;
409 str.GetUntil(pos, '.', dataname);
410 mystr str_rest = str.SubString(pos+1, str.Length()-1);
411
412 int i = Find(dataname);
413 if (i && Get(i).IsEDC())
414 {
415 Get(i).GetEDC()->TreeDelete(str_rest.c_str());
416 if(Get(i).GetEDC()->Length()==0) {Delete(i);} // if it was the last leave, delete the child
417 }
418 }
419 else
420 {
421 int i = Find(name);
422 if(i) { Delete(i);} // delete the leave
423 }
424 }
425
426 extern void TIMBSWarningHandle(const char* warn, int use_instant_message_text);
427
428 //find element, assume that it is double; if not exists use default value
429 //accepts integer and double!
TreeGetDouble(const char * name,double default_val) const430 double ElementDataContainer::TreeGetDouble(const char* name, double default_val) const
431 {
432 const ElementData* ed = TreeFind(name);
433 if (ed)
434 {
435 if (ed->IsBool()) return (double)ed->GetInt();
436 if (ed->IsInt()) return (double)ed->GetInt();
437 if (ed->IsDouble()) return ed->GetDouble();
438 }
439
440 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetDouble"),EDCWarningLevel());
441
442 return default_val;
443 }
444
445 //find element, assume that it is int; if not exists use default value
446 //accepts integer and double!
TreeGetInt(const char * name,int default_val) const447 int ElementDataContainer::TreeGetInt(const char* name, int default_val) const
448 {
449 const ElementData* ed = TreeFind(name);
450 if (ed)
451 {
452 if (ed->IsBool()) return ed->GetInt();
453 if (ed->IsInt()) return ed->GetInt();
454 if (ed->IsDouble()) return (int)ed->GetDouble();
455 }
456
457 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetInt"),EDCWarningLevel());
458
459 return default_val;
460 }
461
462 //find element, assume that it is int; if not exists use default value
463 //accepts integer and double!
TreeGetBool(const char * name,int default_val) const464 int ElementDataContainer::TreeGetBool(const char* name, int default_val) const
465 {
466 const ElementData* ed = TreeFind(name);
467 if (ed)
468 {
469 if (ed->IsInt()) return ed->GetInt();
470 if (ed->IsBool()) return ed->GetInt();
471 if (ed->IsDouble()) return (int)ed->GetDouble();
472 }
473
474 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetBool"),EDCWarningLevel());
475
476 return default_val;
477 }
478
479 //find element, assume that it is char*; if not exists use default value
TreeGetString(const char * name,char * default_val) const480 const char* ElementDataContainer::TreeGetString(const char* name, char* default_val) const
481 {
482 const ElementData* ed = TreeFind(name);
483 if (ed)
484 {
485 if(ed->GetText())
486 {
487 return ed->GetText();
488 }
489 }
490
491 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetString"),EDCWarningLevel());
492
493 return default_val;
494 }
495
496
TreeGetVector3D(const char * name,double & vx,double & vy,double & vz) const497 int ElementDataContainer::TreeGetVector3D(const char* name, double& vx, double& vy, double& vz) const
498 {
499 const ElementData* ed = TreeFind(name);
500 if (ed)
501 {
502 if (ed->IsVector() && ed->GetVectorLen() == 3)
503 {
504 ed->GetVector(vx, vy, vz);
505 return 1;
506 }
507 }
508
509 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetVector3D"),EDCWarningLevel());
510
511 return 0;
512 }
513
TreeGetVector2D(const char * name,double & vx,double & vy) const514 int ElementDataContainer::TreeGetVector2D(const char* name, double& vx, double& vy) const
515 {
516 const ElementData* ed = TreeFind(name);
517 if (ed)
518 {
519 if (ed->IsVector() && ed->GetVectorLen() == 2)
520 {
521 ed->GetVector(vx, vy);
522 return 1;
523 }
524 }
525
526 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetVector2D"),EDCWarningLevel());
527
528 return 0;
529 }
530
531 //find element, assume that it is Vector; if not exists use default value
TreeGetVector(const char * name,double ** v,int & len) const532 int ElementDataContainer::TreeGetVector(const char* name, double** v, int& len) const
533 {
534 len = 0;
535 *v = 0;
536 const ElementData* ed = TreeFind(name);
537 if (ed)
538 {
539 if (ed->IsVector())
540 {
541 *v = ed->GetVector();
542 len = ed->GetVectorLen();
543 return 1;
544 }
545 }
546
547 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetVector"),EDCWarningLevel());
548
549 return 0;
550 }
551
552 //find element, assume that it is MAtrix; if not exists use default value
TreeGetMatrix(const char * name,double ** v,int & rows,int & cols) const553 int ElementDataContainer::TreeGetMatrix(const char* name, double** v, int& rows, int& cols) const
554 {
555 rows = 0;
556 cols = 0;
557 *v = 0;
558 const ElementData* ed = TreeFind(name);
559 if (ed)
560 {
561 if (ed->IsMatrix())
562 {
563 *v = ed->GetMatrix();
564 rows = ed->GetMatrixRows();
565 cols = ed->GetMatrixCols();
566 return 1;
567 }
568 }
569
570 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetMatrix"),EDCWarningLevel());
571
572 return 0;
573 }
574
575 //find element, assume that it is MAtrix; if not exists use default value
TreeGetVector2DList(const char * name,double ** v,int & n) const576 int ElementDataContainer::TreeGetVector2DList(const char* name, double** v, int& n) const // $ MSax 2013-07-09 : added
577 {
578 n = 0;
579 *v = 0;
580 const ElementData* ed = TreeFind(name);
581 if (ed)
582 {
583 if (ed->IsMatrix())
584 {
585 //if(ed->GetMatrixCols() != 2)
586 //{
587 // ed->SetMatrixSize(n, 2);
588 // for (int i=1; i<=n; i++)
589 // {
590 // ed->SetMatrixVal(i,1,0);
591 // ed->SetMatrixVal(i,2,0);
592 // }
593 //}
594
595 if(ed->GetMatrixCols() != 2 && ed->GetMatrixCols() !=0)
596 {
597 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' has wrong dimensions"),EDCWarningLevel());
598 return 0;
599 }
600
601 *v = ed->GetMatrix();
602 n = ed->GetMatrixRows();
603
604 return 1;
605 }
606 }
607
608 TIMBSWarningHandle(mystr("'")+mystr(name)+mystr("' not found in TreeGetVector2DList"),EDCWarningLevel());
609
610 return 0;
611 }
612
613
Add(const ElementData & ed)614 int ElementDataContainer::Add(const ElementData& ed)
615 {
616 return elemdata.Add(ed.GetCopy());
617 }
618
619
SplitIntoTreeAndElementName(const char * name,mystr & tree,mystr & elementname)620 void ElementDataContainer::SplitIntoTreeAndElementName(const char* name, mystr& tree, mystr& elementname)
621 {
622 mystr str(name);
623 int pos = 0;
624 int posold;
625
626 //either finds '.' and gets position of last '.', or returns -1
627 while (pos != -1)
628 {
629 posold = pos;
630 pos = str.Find(pos+1, '.');
631 }
632
633 //in case of 0, the '.' is either at first position (invalid), or the '.' has not been found
634 if (posold > 0) //split tree string into tree and elementname: str="part1.part2.part3" ==> tree = "part1.part2", elementname="part3"
635 {
636 tree = str.SubString(0, posold-1);
637 elementname = str.SubString(posold+1, str.Length()-1);
638 }
639 else
640 {
641 tree = "";
642 elementname = str;
643 }
644 }
645
646 //add or replace element in EDC: double; e.g. name="tree1.leave2.data"
TreeSetDouble(const char * name,double val)647 void ElementDataContainer::TreeSetDouble(const char* name, double val)
648 {
649 mystr tree, elementname;
650 SplitIntoTreeAndElementName(name, tree, elementname);
651
652 ElementData ed;
653 ed.SetDouble(val, elementname);
654 TreeSet(tree, ed);
655 }
656
657 //add or replace element in EDC: int; e.g. name="tree1.leave2.data"
TreeSetInt(const char * name,int val)658 void ElementDataContainer::TreeSetInt(const char* name, int val)
659 {
660 mystr tree, elementname;
661 SplitIntoTreeAndElementName(name, tree, elementname);
662
663 ElementData ed;
664 ed.SetInt(val, elementname);
665 TreeSet(tree, ed);
666 }
667
668 //add or replace element in EDC: bool; e.g. name="tree1.leave2.data"
TreeSetBool(const char * name,int val)669 void ElementDataContainer::TreeSetBool(const char* name, int val)
670 {
671 mystr tree, elementname;
672 SplitIntoTreeAndElementName(name, tree, elementname);
673
674 ElementData ed;
675 ed.SetBool(val, elementname);
676 TreeSet(tree, ed);
677 }
678
679 //add or replace element in EDC: string; e.g. name="tree1.leave2.data"
TreeSetString(const char * name,const char * val)680 void ElementDataContainer::TreeSetString(const char* name, const char* val)
681 {
682 mystr tree, elementname;
683 SplitIntoTreeAndElementName(name, tree, elementname);
684
685 ElementData ed;
686 ed.SetText(val, elementname);
687 TreeSet(tree, ed);
688 }
689
690
691 //add or replace element in EDC with COMMENT: double; e.g. name="tree1.leave2.data"
TreeSetDoubleC(const char * name,double val,const char * comment)692 void ElementDataContainer::TreeSetDoubleC(const char* name, double val, const char* comment)
693 {
694 mystr tree, elementname;
695 SplitIntoTreeAndElementName(name, tree, elementname);
696
697 ElementData ed;
698 ed.SetDouble(val, elementname);
699 ed.SetToolTipText(comment);
700 TreeSet(tree, ed);
701 }
702
703 //add or replace element in EDC with COMMENT: int; e.g. name="tree1.leave2.data"
TreeSetIntC(const char * name,int val,const char * comment)704 void ElementDataContainer::TreeSetIntC(const char* name, int val, const char* comment)
705 {
706 mystr tree, elementname;
707 SplitIntoTreeAndElementName(name, tree, elementname);
708
709 ElementData ed;
710 ed.SetInt(val, elementname);
711 ed.SetToolTipText(comment);
712 TreeSet(tree, ed);
713 }
714
715 //add or replace element in EDC with COMMENT: bool; e.g. name="tree1.leave2.data"
TreeSetBoolC(const char * name,int val,const char * comment)716 void ElementDataContainer::TreeSetBoolC(const char* name, int val, const char* comment)
717 {
718 mystr tree, elementname;
719 SplitIntoTreeAndElementName(name, tree, elementname);
720
721 ElementData ed;
722 ed.SetBool(val, elementname);
723 ed.SetToolTipText(comment);
724 TreeSet(tree, ed);
725 }
726
727 //add or replace element in EDC with COMMENT: string; e.g. name="tree1.leave2.data"
TreeSetStringC(const char * name,const char * val,const char * comment)728 void ElementDataContainer::TreeSetStringC(const char* name, const char* val, const char* comment)
729 {
730 mystr tree, elementname;
731 SplitIntoTreeAndElementName(name, tree, elementname);
732
733 ElementData ed;
734 ed.SetText(val, elementname);
735 ed.SetToolTipText(comment);
736 TreeSet(tree, ed);
737 }
738
739 //find element, assume that it is Vector; if not exists use default value
TreeSetVectorC(const char * name,double * v,int len,const char * comment)740 void ElementDataContainer::TreeSetVectorC(const char* name, double* v, int len, const char* comment)
741 {
742 mystr tree, elementname;
743 SplitIntoTreeAndElementName(name, tree, elementname);
744
745 ElementData ed;
746 ed.SetVector(v,len,elementname);
747 ed.SetToolTipText(comment);
748 TreeSet(tree, ed);
749 }
750
TreeAdd(const char * tree,const ElementData & ed)751 void ElementDataContainer::TreeAdd(const char* tree, const ElementData& ed)
752 //void ElementDataContainer::TreeAdd(mystr tree, const ElementData& ed)
753 {
754 mystr str(tree);
755 if (str.Length() != 0)
756 {
757 int pos = 0;
758 mystr str_rest;
759 if (str.Find('.') != -1) //split tree string into part1 and rest: str="part1.part2.part3" ==> str_new = "part1", str_rest="part2.part3"
760 {
761 mystr str_new;
762 str.GetUntil(pos, '.', str_new);
763 str_rest = str.SubString(pos+1, str.Length()-1);
764 str = str_new;
765 }
766
767 //search if node exists
768 int i = Find(str);
769 if (i && Get(i).IsEDC())
770 {
771 Get(i).GetEDC()->TreeAdd(str_rest.c_str(), ed);
772 }
773 else
774 {
775 //create a new element data container at node
776 ElementData ed_edc;
777 ElementDataContainer edc_new;
778
779 edc_new.TreeAdd(str_rest.c_str(), ed);
780 ed_edc.SetEDC(&edc_new, str);
781
782 Add(ed_edc);
783 }
784
785 }
786 else //no tree structure searched for
787 {
788 Add(ed);
789 }
790 }
791 //
792 //void ElementDataContainer::TreeAdd1(mystr tree, const ElementData& ed)
793 //{
794 // mystr str(tree);
795 // if (str.Length() != 0)
796 // {
797 // int pos = 0;
798 // mystr str_rest;
799 // if (str.Find('.') != -1) //split tree string into part1 and rest: str="part1.part2.part3" ==> str_new = "part1", str_rest="part2.part3"
800 // {
801 // mystr str_new;
802 // str.GetUntil(pos, '.', str_new);
803 // str_rest = str.SubString(pos+1, str.Length()-1);
804 // str = str_new;
805 // }
806 //
807 // //search if node exists
808 // int i = Find(str);
809 // if (i && Get(i).IsEDC())
810 // {
811 // Get(i).GetEDC()->TreeAdd2(str_rest.c_str(), ed);
812 // }
813 // else
814 // {
815 // //create a new element data container at node
816 // ElementData ed_edc;
817 // ElementDataContainer edc_new;
818 //
819 // edc_new.TreeAdd2(str_rest.c_str(), ed);
820 // ed_edc.SetEDC(&edc_new, str);
821 //
822 // Add(ed_edc);
823 // }
824 //
825 // }
826 // else //no tree structure searched for
827 // {
828 // Add(ed);
829 // }
830 //}
831 //
832 //void ElementDataContainer::TreeAdd2(mystr tree, const ElementData& ed)
833 //{
834 // mystr str(tree);
835 // if (str.Length() != 0)
836 // {
837 // int pos = 0;
838 // mystr str_rest;
839 // if (str.Find('.') != -1) //split tree string into part1 and rest: str="part1.part2.part3" ==> str_new = "part1", str_rest="part2.part3"
840 // {
841 // mystr str_new;
842 // str.GetUntil(pos, '.', str_new);
843 // str_rest = str.SubString(pos+1, str.Length()-1);
844 // str = str_new;
845 // }
846 //
847 // //search if node exists
848 // int i = Find(str);
849 // if (i && Get(i).IsEDC())
850 // {
851 // Get(i).GetEDC()->TreeAdd3(str_rest.c_str(), ed);
852 // }
853 // else
854 // {
855 // //create a new element data container at node
856 // ElementData ed_edc;
857 // ElementDataContainer edc_new;
858 //
859 // edc_new.TreeAdd3(str_rest.c_str(), ed);
860 // ed_edc.SetEDC(&edc_new, str);
861 //
862 // Add(ed_edc);
863 // }
864 //
865 // }
866 // else //no tree structure searched for
867 // {
868 // Add(ed);
869 // }
870 //}
871 //
872 //void ElementDataContainer::TreeAdd3(mystr tree, const ElementData& ed)
873 //{
874 // mystr str(tree);
875 // if (str.Length() != 0)
876 // {
877 // int pos = 0;
878 // mystr str_rest;
879 // if (str.Find('.') != -1) //split tree string into part1 and rest: str="part1.part2.part3" ==> str_new = "part1", str_rest="part2.part3"
880 // {
881 // mystr str_new;
882 // str.GetUntil(pos, '.', str_new);
883 // str_rest = str.SubString(pos+1, str.Length()-1);
884 // str = str_new;
885 // }
886 //
887 // //search if node exists
888 // int i = Find(str);
889 // if (i && Get(i).IsEDC())
890 // {
891 // Get(i).GetEDC()->TreeAdd3(str_rest.c_str(), ed);
892 // }
893 // else
894 // {
895 // //create a new element data container at node
896 // ElementData ed_edc;
897 // ElementDataContainer edc_new;
898 //
899 // edc_new.TreeAdd3(str_rest.c_str(), ed);
900 // ed_edc.SetEDC(&edc_new, str);
901 //
902 // Add(ed_edc);
903 // }
904 //
905 // }
906 // else //no tree structure searched for
907 // {
908 // Add(ed);
909 // }
910 //}
911
912
913
914 //set an element in the tree of edc; if the tree does not exist, build the tree and insert data; if the data exists: replace the data
TreeSet(const char * tree,const ElementData & ed,int warn_if_items_dont_exist,int copy_ToolTipText)915 void ElementDataContainer::TreeSet(const char* tree, const ElementData& ed, int warn_if_items_dont_exist, int copy_ToolTipText)
916 {
917 mystr str = mystr(tree);
918 if (str.Length() != 0) {str += ".";}
919
920 str += ed.GetDataName();
921
922 ElementData* edfound = TreeFind(str);
923 if (edfound != 0)
924 {
925 if(edfound->IsLocked()) //$ DR 2013-04-09
926 {
927 TIMBSWarningHandle(mystr("The entry '") + local_warn_tree + str + mystr("' is marked as readonly in the original ElementDataContainer. The value is therefore not changed! If the entry is the variable of the parameter variation, ignore this warning.\n"),0);
928 }
929 else // replace the data
930 {
931 if (edfound->GetType() == ed.GetType())
932 {
933 //copy data, but keep tooltip text
934 mystr old_tooltip("");
935 if (edfound->HasToolTip()) old_tooltip = edfound->GetToolTipText();
936 edfound->CopyFrom(ed);
937 if(!copy_ToolTipText)
938 {
939 edfound->SetToolTipText(old_tooltip);
940 }
941 }
942 //treat int/bool/double the same; this means that the type of the old edfound is kept:
943 else if ( (edfound->IsInt() && ed.IsBool()) || (edfound->IsInt() && ed.IsDouble()) || (edfound->IsBool() && ed.IsInt()) || (edfound->IsBool() && ed.IsDouble())
944 || (edfound->IsDouble() && ed.IsInt()) || (edfound->IsDouble() && ed.IsBool()) )
945 {
946 double val;
947 if (ed.IsBool()) val = ed.GetBool();
948 if (ed.IsInt()) val = ed.GetInt();
949 if (ed.IsDouble()) val = ed.GetDouble();
950
951
952 if (edfound->IsBool()) {edfound->SetBool((int)val);} //JG, do not replace data name because of case sensitivity
953 if (edfound->IsInt()) {edfound->SetInt((int)val);} //JG, do not replace data name because of case sensitivity
954 if (edfound->IsDouble()) {edfound->SetDouble(val);} //JG, do not replace data name because of case sensitivity
955 //if (edfound->IsBool()) {edfound->SetBool(val, ed.GetDataName());}
956 //if (edfound->IsInt()) {edfound->SetInt(val, ed.GetDataName());}
957 //if (edfound->IsDouble()) {edfound->SetDouble(val, ed.GetDataName());}
958
959 }
960 // write vector2d/3d into vector-ed
961 else if ( edfound->IsVector() && ed.IsVectorXYZ() )
962 {
963 if (ed.GetVectorLen() == 2)
964 {
965 edfound->SetVector2D(ed.GetVectorVal(1), ed.GetVectorVal(2), ed.GetDataName());
966 }
967 if (ed.GetVectorLen() == 3)
968 {
969 edfound->SetVector3D(ed.GetVectorVal(1), ed.GetVectorVal(2), ed.GetVectorVal(3), ed.GetDataName());
970 }
971 }
972 // write first 2 or 3 values of vector into vector2d/3d-ed
973 else if ( edfound->IsVectorXYZ() && ed.IsVector() )
974 {
975 double* dummy = ed.GetVector();
976 if (edfound->GetVectorLen() == 2 && ed.GetVectorLen() >= 2 )
977 {
978 edfound->SetVector2D(dummy[0], dummy[1], ed.GetDataName());
979 }
980 if (edfound->GetVectorLen() == 3 && ed.GetVectorLen() >= 3 )
981 {
982 edfound->SetVector3D(dummy[0], dummy[1], dummy[2], ed.GetDataName());
983 }
984 if (edfound->GetVectorLen() == 3 && ed.GetVectorLen() == 2 )
985 {
986 edfound->SetVector3D(dummy[0], dummy[1], 0., ed.GetDataName());
987 }
988 }
989 //different types of vectors; length must be same, if vector does not have variable length
990 else if ( edfound->IsVector() && ed.IsVector() )
991 {
992 //independently of exact types (intvalues, etc.), replace vector
993 double* dummy = ed.GetVector();
994 if ((edfound->GetVectorLen() == ed.GetVectorLen())||(edfound->IsVariableLength())) //$ DR 2012-1: variable length added
995 {
996 int oldtype = edfound->GetType();
997 edfound->SetVector(dummy, ed.GetVectorLen(), ed.GetDataName());
998 edfound->SetType(oldtype);
999 }
1000 else
1001 {
1002 TIMBSWarningHandle(mystr("'") + local_warn_tree+mystr(ed.GetDataName())+mystr("': incompatible vector '")+mystr(edfound->GetDataName())+mystr("', check length and type of default entry!!"),EDCWarningLevel());
1003 }
1004 }
1005 else if(edfound->IsMatrix() && ed.IsVector() && (edfound->IsVariableLength() || edfound->GetMatrixCols() == ed.GetVectorLen() && edfound->GetMatrixRows() == 1))
1006 {
1007 //$ SW 2013-11-5: added the case that the matrix has fixed column size and the vector is empty.
1008 // matrix = vector & matrix has fixed column size => vector = [] or length(vector) == columns(matrix)
1009 if (edfound->IsVariableLength() && edfound->IsColumnNumberFixed() && ed.GetVectorLen() != 0 && ed.GetVectorLen() != edfound->GetMatrixCols())
1010 {
1011 TIMBSWarningHandle(mystr("'") + local_warn_tree + mystr(ed.GetDataName()) + mystr("': incompatible vector '") + mystr(edfound->GetDataName()) + mystr("', check dimensions!"),EDCWarningLevel());
1012 }
1013 //matrix = vector & matrix has fixed column size && vector = []
1014 else if (edfound->IsVariableLength() && edfound->IsColumnNumberFixed() && ed.GetVectorLen() == 0)
1015 {
1016 double* dummy = ed.GetVector();
1017 int oldtype = edfound->GetType();
1018 edfound->SetMatrix(dummy, 0, edfound->GetMatrixCols(), ed.GetDataName());
1019 edfound->SetType(oldtype);
1020 }
1021 else
1022 {
1023 double* dummy = ed.GetVector();
1024 int oldtype = edfound->GetType();
1025 edfound->SetMatrix(dummy, 1, ed.GetVectorLen(), ed.GetDataName());
1026 edfound->SetType(oldtype);
1027 }
1028 }
1029 else if(edfound->IsMatrix() && ed.IsMatrix() && (edfound->IsVariableLength() || (edfound->GetMatrixCols() == ed.GetMatrixCols() && edfound->GetMatrixRows() == ed.GetMatrixRows())))
1030 {
1031 double* dummy = ed.GetMatrix();
1032 int oldtype = edfound->GetType();
1033 edfound->SetMatrix(dummy, ed.GetMatrixRows(), ed.GetMatrixCols(), ed.GetDataName());
1034 edfound->SetType(oldtype);
1035 }
1036 else if(edfound->IsMatrix() && ed.IsVector() && ed.GetVectorLen() == 0)
1037 {
1038 // $ MSax 2013-07-11: do nothing, because ed is an empty matrix
1039 }
1040 else if(edfound->IsVector() && edfound->GetVectorLen() == 1 && (ed.IsDouble() || ed.IsInt()) )
1041 {
1042 //$ AD 2013-10-10: write a double in a length 1 vector
1043 double dummy;
1044 if(ed.IsDouble()) dummy = ed.GetDouble();
1045 else if(ed.IsInt()) dummy = (double) ed.GetInt();
1046 int oldtype = edfound->GetType();
1047 edfound->SetVector(&dummy, 1, ed.GetDataName());
1048 edfound->SetType(oldtype);
1049 }
1050 else if(edfound->IsMatrix() && edfound->GetMatrixRows() == 1 && edfound->GetMatrixCols() == 1 && (ed.IsDouble() || ed.IsInt()) )
1051 {
1052 //$ AD 2013-10-10: write a double in a length 1 vector
1053 double dummy;
1054 if(ed.IsDouble()) dummy = ed.GetDouble();
1055 else if(ed.IsInt()) dummy = (double) ed.GetInt();
1056 int oldtype = edfound->GetType();
1057 edfound->SetMatrix(&dummy, 1, 1, ed.GetDataName());
1058 edfound->SetType(oldtype);
1059 }
1060
1061 else
1062 {
1063 //here we should put a warning, because user could set a string options to a number value
1064 //TIMBSWarningHandle(mystr("'")+mystr(ed.GetDataName())+mystr("' is incompatible with data type of '")+mystr(edfound->GetDataName())+mystr("'!!"),EDCWarningLevel());
1065 TIMBSWarningHandle(mystr("'")+local_warn_tree+mystr("' is incompatible with data type of '")+mystr(edfound->GetDataName())+mystr("'!!"),EDCWarningLevel());
1066 //assert(0);
1067 }
1068 }
1069 }
1070 else
1071 {
1072 if (warn_if_items_dont_exist)
1073 {
1074 //TIMBSWarningHandle(mystr("'") + local_warn_tree + str + mystr("' added (check spelling)."), EDCWarningLevel());
1075 TIMBSWarningHandle(mystr(" The entry '") + local_warn_tree + str + mystr("' does not exist in the original ElementDataContainer (check spelling)."), EDCWarningLevel()); //$ DR 2013-02-20 new warning, also used for skript language
1076 }
1077 TreeAdd(tree, ed);
1078 }
1079 }
1080
TreeReplaceEDCDataWith(const ElementDataContainer * edc_new,int warn_if_items_dont_exist,mystr warn_str)1081 void ElementDataContainer::TreeReplaceEDCDataWith(const ElementDataContainer* edc_new, int warn_if_items_dont_exist, mystr warn_str)
1082 {
1083 //SetLocalWarnTree(warn_str);
1084 TreeReplaceEDCDataWithRecursive(edc_new, warn_if_items_dont_exist);
1085 }
1086
TreeReplaceEDCDataWithRecursive(const ElementDataContainer * edc_new,int warn_if_items_dont_exist)1087 void ElementDataContainer::TreeReplaceEDCDataWithRecursive(const ElementDataContainer* edc_new, int warn_if_items_dont_exist)
1088 {
1089 for(int i = 1; i<=edc_new->Length(); i++)
1090 {
1091 ElementData ed_new = edc_new->Get(i);
1092 mystr name = ed_new.GetDataName();
1093 int j = Find(name);
1094 if(j && Get(j).IsEDC()) // same variable names exist
1095 {
1096 Get(j).GetEDC()->TreeReplaceEDCDataWithRecursive(ed_new.GetEDC(), warn_if_items_dont_exist);// replace sub-tree
1097 }
1098 else
1099 {
1100 TreeSet("",ed_new,warn_if_items_dont_exist, 0);
1101 }
1102 }
1103 }
1104
1105 //$ DR 2012-06-27
1106 //void ElementDataContainer::PrintEDCRecursive(mystr filename)
PrintEDCRecursive(ofstream & edcout)1107 void ElementDataContainer::PrintEDCRecursive(ofstream &edcout)
1108 {
1109 //ofstream edcout(filename);
1110 for(int i = 1; i<=Length(); i++)
1111 {
1112 ElementData ed_tmp = Get(i);
1113 if(Get(i).IsEDC())
1114 {
1115 ElementDataContainer *edcp = Get(i).GetEDC();
1116 edcout << "================== \n";
1117 edcout << ed_tmp.GetDataName() << ":\n";
1118 edcp->PrintEDCRecursive(edcout);
1119 }
1120 else
1121 {
1122 edcout << "------------------- \n";
1123 edcout << ed_tmp.GetDataName() << ":\n";
1124 if(ed_tmp.GetType() ==1)
1125 {
1126 edcout << "int = " << ed_tmp.GetInt() << "\n";
1127 }
1128 if(ed_tmp.GetType() ==2)
1129 {
1130 edcout << "double = " << ed_tmp.GetDouble() << "\n";
1131 }
1132 if(ed_tmp.GetType() ==4)
1133 {
1134 edcout << "vec = " << ed_tmp.GetVector() << "\n";
1135 }
1136 if(ed_tmp.GetType() == 8)
1137 {
1138 edcout << "txt = " << ed_tmp.GetText() << "\n";
1139 }
1140 if(ed_tmp.GetType() == 16)
1141 {
1142 edcout << "bool = " << ed_tmp.GetBool() << "\n";
1143 }
1144 }
1145 }
1146 }
1147
1148
1149
1150
1151