Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/csg/csgparser.cpp
3206 views
1
#include <mystdlib.h>
2
#include <myadt.hpp>
3
4
#include <linalg.hpp>
5
#include <csg.hpp>
6
7
8
namespace netgen
9
{
10
//using namespace netgen;
11
12
13
static kwstruct defkw[] =
14
{
15
{ TOK_RECO, "algebraic3d" },
16
{ TOK_SOLID, "solid" },
17
{ TOK_TLO, "tlo" },
18
{ TOK_CURVE2D, "curve2d" },
19
{ TOK_CURVE3D, "curve3d" },
20
{ TOK_BOUNDINGBOX, "boundingbox" },
21
{ TOK_OR, "or" },
22
{ TOK_AND, "and" },
23
{ TOK_NOT, "not" },
24
{ TOK_SINGULAR, "singular" },
25
{ TOK_EDGE, "edge" },
26
{ TOK_FACE, "face" },
27
{ TOK_POINT, "point" },
28
{ TOK_IDENTIFY, "identify" },
29
{ TOK_CLOSESURFACES, "closesurfaces" },
30
{ TOK_CLOSEEDGES, "closeedges" },
31
{ TOK_PERIODIC, "periodic" },
32
{ TOK_BOUNDARYCONDITION, "boundarycondition" },
33
{ TOK_BOUNDARYCONDITIONNAME, "boundaryconditionname" },
34
{ TOK_DEFINE, "define" },
35
{ TOK_CONSTANT, "constant" },
36
{ TOKEN_TYPE(0) }
37
};
38
39
static primstruct defprim[] =
40
{
41
{ TOK_PLANE, "plane" },
42
{ TOK_SPHERE, "sphere" },
43
{ TOK_CYLINDER, "cylinder" },
44
{ TOK_CONE, "cone" },
45
{ TOK_ELLIPTICCYLINDER, "ellipticcylinder" },
46
{ TOK_ELLIPSOID, "ellipsoid" },
47
{ TOK_ORTHOBRICK, "orthobrick" },
48
{ TOK_POLYHEDRON, "polyhedron" },
49
{ TOK_TORUS, "torus" },
50
51
{ TOK_TUBE, "tube" },
52
{ TOK_GENCYL, "gencyl" },
53
{ TOK_EXTRUSION, "extrusion" },
54
{ TOK_REVOLUTION, "revolution" },
55
56
{ TOK_TRANSLATE, "translate" },
57
{ TOK_MULTITRANSLATE, "multitranslate" },
58
{ TOK_ROTATE, "rotate" },
59
{ TOK_MULTIROTATE, "multirotate" },
60
{ PRIMITIVE_TYPE(0) }
61
};
62
63
static CSGeometry * geom;
64
65
66
CSGScanner :: CSGScanner (istream & ascanin)
67
{
68
scanin = &ascanin;
69
token = TOK_END;
70
num_value = 0;
71
linenum = 1;
72
}
73
74
75
void CSGScanner :: ReadNext ()
76
{
77
char ch;
78
79
80
// scan whitespaces
81
do
82
{
83
scanin->get(ch);
84
85
//if (ch == '\n')
86
// linenum++;
87
88
// end of file reached
89
if (scanin->eof())
90
{
91
token = TOK_END;
92
return;
93
}
94
if (ch == '\n')
95
linenum++;
96
97
98
// skip comment line
99
if (ch == '#')
100
{
101
while (ch != '\n')
102
{
103
scanin->get(ch);
104
if (scanin->eof())
105
{
106
token = TOK_END;
107
return;
108
}
109
}
110
linenum++;
111
}
112
}
113
while (isspace(ch));
114
115
switch (ch)
116
{
117
case '(': case ')':
118
case '[': case ']':
119
case '-':
120
case '=': case ',': case ';':
121
{
122
token = TOKEN_TYPE (ch);
123
break;
124
}
125
126
default:
127
{
128
if (isdigit (ch) || ch == '.')
129
{
130
scanin->putback (ch);
131
(*scanin) >> num_value;
132
token = TOK_NUM;
133
return;
134
}
135
136
if (isalpha (ch))
137
{
138
string_value = string (1, ch);
139
scanin->get(ch);
140
while (isalnum(ch) || ch == '_')
141
{
142
string_value += ch;
143
scanin->get(ch);
144
}
145
scanin->putback (ch);
146
}
147
148
int nr = 0;
149
while (defkw[nr].kw)
150
{
151
if (string_value == defkw[nr].name)
152
{
153
token = defkw[nr].kw;
154
return;
155
}
156
nr++;
157
}
158
159
nr = 0;
160
while (defprim[nr].kw)
161
{
162
if (string_value == defprim[nr].name)
163
{
164
token = TOK_PRIMITIVE;
165
prim_token = defprim[nr].kw;
166
return;
167
}
168
nr++;
169
}
170
171
token = TOK_STRING;
172
}
173
}
174
}
175
176
void CSGScanner :: Error (const string & err)
177
{
178
stringstream errstr;
179
errstr << "Parsing error in line " << linenum << ": " << endl << err << endl;
180
throw string(errstr.str());
181
}
182
183
184
/*
185
Solid = Term { OR Term }
186
Term = Primary { AND Primary }
187
Primary = PRIM | IDENT | ( Solid ) | NOT Primary
188
*/
189
190
void ParseChar (CSGScanner & scan, char ch)
191
{
192
if (scan.GetToken() != TOKEN_TYPE(ch))
193
scan.Error (string ("token '") + string(1, ch) + string("' expected"));
194
scan.ReadNext();
195
}
196
197
double ParseNumber(CSGScanner & scan)
198
{
199
if (scan.GetToken() == '-')
200
{
201
scan.ReadNext();
202
return -ParseNumber (scan);
203
}
204
if (scan.GetToken() != TOK_NUM) scan.Error ("number expected");
205
double val = scan.GetNumValue();
206
scan.ReadNext();
207
return val;
208
}
209
210
Vec<3> ParseVector (CSGScanner & scan)
211
{
212
Vec<3> v;
213
v(0) = ParseNumber (scan);
214
ParseChar (scan, ',');
215
v(1) = ParseNumber (scan);
216
ParseChar (scan, ',');
217
v(2) = ParseNumber (scan);
218
return v;
219
}
220
221
222
CSGScanner & operator>> (CSGScanner & scan, char ch)
223
{
224
if (scan.GetToken() != TOKEN_TYPE(ch))
225
scan.Error (string ("token '") + string(1, ch) + string("' expected"));
226
scan.ReadNext();
227
return scan;
228
}
229
230
CSGScanner & operator>> (CSGScanner & scan, double & d)
231
{
232
d = ParseNumber (scan);
233
return scan;
234
}
235
236
CSGScanner & operator>> (CSGScanner & scan, int & i)
237
{
238
i = int (ParseNumber (scan));
239
return scan;
240
}
241
242
CSGScanner & operator>> (CSGScanner & scan, Point<3> & p)
243
{
244
scan >> p(0) >> ',' >> p(1) >> ',' >> p(2);
245
return scan;
246
}
247
248
CSGScanner & operator>> (CSGScanner & scan, Vec<3> & v)
249
{
250
scan >> v(0) >> ',' >> v(1) >> ',' >> v(2);
251
return scan;
252
}
253
254
255
Solid * ParseSolid (CSGScanner & scan);
256
Solid * ParseTerm (CSGScanner & scan);
257
Solid * ParsePrimary (CSGScanner & scan);
258
259
260
Solid * ParsePrimary (CSGScanner & scan)
261
{
262
if (scan.GetToken() == TOK_PRIMITIVE)
263
{
264
switch (scan.GetPrimitiveToken())
265
{
266
case TOK_PLANE:
267
{
268
Point<3> p;
269
Vec<3> v;
270
271
scan.ReadNext();
272
scan >> '(' >> p >> ';' >> v >> ')';
273
274
OneSurfacePrimitive * surf = new Plane ( p, v );
275
geom->AddSurfaces (surf);
276
return new Solid (surf);
277
}
278
279
case TOK_CYLINDER:
280
{
281
Point<3> pa, pb;
282
double r;
283
284
scan.ReadNext();
285
scan >> '(' >> pa >> ';' >> pb >> ';' >> r >> ')';
286
287
OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r );
288
geom->AddSurfaces (surf);
289
return new Solid (surf);
290
}
291
292
case TOK_ELLIPTICCYLINDER:
293
{
294
Point<3> pa;
295
Vec<3> vl, vs;
296
297
scan.ReadNext();
298
scan >> '(' >> pa >> ';' >> vl >> ';' >> vs >> ')';
299
300
OneSurfacePrimitive * surf = new EllipticCylinder ( pa, vl, vs);
301
geom->AddSurfaces (surf);
302
return new Solid (surf);
303
}
304
305
306
case TOK_ELLIPSOID:
307
{
308
Point<3> pa;
309
Vec<3> v1, v2, v3;
310
311
scan.ReadNext();
312
scan >> '(' >> pa >> ';' >> v1 >> ';' >> v2 >> ';' >> v3 >> ')';
313
314
OneSurfacePrimitive * surf = new Ellipsoid ( pa, v1, v2, v3);
315
geom->AddSurfaces (surf);
316
return new Solid (surf);
317
}
318
319
320
case TOK_CONE:
321
{
322
Point<3> pa, pb;
323
double ra, rb;
324
325
scan.ReadNext();
326
scan >> '(' >> pa >> ';' >> ra >> ';' >> pb >> ';' >> rb >> ')';
327
328
OneSurfacePrimitive * surf = new Cone ( pa, pb, ra, rb );
329
geom->AddSurfaces (surf);
330
return new Solid (surf);
331
}
332
333
334
335
case TOK_SPHERE:
336
{
337
Point<3> p;
338
double r;
339
340
scan.ReadNext();
341
scan >> '(' >> p >> ';' >> r >> ')';
342
343
OneSurfacePrimitive * surf = new Sphere ( p, r );
344
geom->AddSurfaces (surf);
345
return new Solid (surf);
346
}
347
348
case TOK_ORTHOBRICK:
349
{
350
Point<3> pa, pb;
351
352
scan.ReadNext();
353
scan >> '(' >> pa >> ';' >> pb >> ')';
354
355
356
Primitive * nprim = new OrthoBrick (pa, pb);
357
geom->AddSurfaces (nprim);
358
return new Solid (nprim);
359
}
360
361
case TOK_POLYHEDRON:
362
{
363
// Added by Dalibor Lukas, October 15, 2003
364
365
Point<3> p;
366
//int pi1, pi2, pi3, pi4;
367
368
scan.ReadNext();
369
ParseChar (scan, '(');
370
371
Polyhedra * polyhedron = new Polyhedra;
372
373
// scanning the points
374
while (1)
375
{
376
p = Point<3> (ParseVector (scan));
377
ParseChar (scan, ';');
378
379
polyhedron->AddPoint(p);
380
381
if (scan.GetToken() == ';')
382
{
383
scan.ReadNext();
384
break;
385
}
386
}
387
388
// scanning the faces
389
int inputface = 0;
390
while (1)
391
{
392
ARRAY<int> pnums,cleaned_pnums;
393
for(int i=0; i<3; i++)
394
{
395
pnums.Append((int) (ParseNumber (scan)));
396
if(i<2)
397
ParseChar (scan, ',');
398
}
399
400
if (scan.GetToken() == TOK_COMMA)
401
{
402
ParseChar (scan, ',');
403
pnums.Append((int) (ParseNumber (scan)));
404
}
405
406
for(int i=0; i<pnums.Size(); i++)
407
if(!cleaned_pnums.Contains(pnums[i]))
408
cleaned_pnums.Append(pnums[i]);
409
410
if(cleaned_pnums.Size() == 3)
411
{
412
polyhedron->AddFace(cleaned_pnums[0]-1,
413
cleaned_pnums[1]-1,
414
cleaned_pnums[2]-1,
415
inputface);
416
}
417
else if(cleaned_pnums.Size() == 4)
418
{
419
polyhedron->AddFace(cleaned_pnums[0]-1,
420
cleaned_pnums[1]-1,
421
cleaned_pnums[2]-1,
422
inputface);
423
polyhedron->AddFace(cleaned_pnums[0]-1,
424
cleaned_pnums[2]-1,
425
cleaned_pnums[3]-1,
426
inputface);
427
}
428
else
429
{
430
ostringstream msg;
431
msg << "Something wrong with polyhedron face:";
432
for(int i=0; i<pnums.Size(); i++)
433
msg << " " << pnums[i];
434
throw NgException(msg.str());
435
}
436
437
438
439
if (scan.GetToken() == ')')
440
{
441
scan.ReadNext();
442
break;
443
}
444
scan.ReadNext();
445
inputface++;
446
}
447
448
geom->AddSurfaces (polyhedron);
449
return new Solid (polyhedron);
450
}
451
452
453
case TOK_REVOLUTION:
454
{
455
Point<3> p0,p1;
456
457
scan.ReadNext();
458
scan >> '(' >> p0 >> ';' >> p1 >> ';';
459
460
string spline = scan.GetStringValue();
461
462
scan.ReadNext();
463
scan >> ')';
464
465
if(!geom->GetSplineCurve2d(spline))
466
{
467
scan.Error ( string("2D Spline curve not found: ") + spline );
468
break;
469
}
470
471
Primitive * nprim = new Revolution(p0,p1,
472
*(geom->GetSplineCurve2d(spline)));
473
474
geom->AddSurfaces (nprim);
475
return new Solid(nprim);
476
}
477
478
479
case TOK_EXTRUSION:
480
{
481
scan.ReadNext();
482
scan >> '(';
483
string epath = scan.GetStringValue();
484
scan.ReadNext();
485
scan >> ';';
486
string profile = scan.GetStringValue();
487
488
489
scan.ReadNext();
490
Vec<3> z_dir;
491
scan >> ';' >> z_dir(0) >> ',' >> z_dir(1) >> ',' >> z_dir(2) >> ')';
492
493
if(!geom->GetSplineCurve2d(profile))
494
{
495
scan.Error ( string("2D Spline curve not found: ") + profile );
496
break;
497
}
498
if(!geom->GetSplineCurve3d(epath))
499
{
500
scan.Error ( string("2D Spline curve not found: ") + epath );
501
break;
502
}
503
504
Primitive * nprim = new Extrusion(*(geom->GetSplineCurve3d(epath)),
505
*(geom->GetSplineCurve2d(profile)),
506
z_dir);
507
geom->AddSurfaces (nprim);
508
return new Solid(nprim);
509
}
510
511
512
/// Torus
513
/// Lorenzo Codecasa ([email protected])
514
/// April 27th, 2005
515
///
516
/// begin...
517
case TOK_TORUS:
518
{
519
Point<3> pc;
520
Vec<3> vn;
521
double R, r;
522
523
scan.ReadNext();
524
scan >> '(' >> pc >> ';' >> vn >> ';' >> R >> ';' >> r >> ')';
525
526
OneSurfacePrimitive * surf = new Torus ( pc, vn, R, r );
527
geom->AddSurfaces (surf);
528
return new Solid (surf);
529
}
530
/// ..end
531
532
533
534
535
case TOK_TRANSLATE:
536
{
537
Vec<3> v;
538
scan.ReadNext();
539
540
ParseChar (scan, '(');
541
v = ParseVector (scan);
542
ParseChar (scan, ';');
543
544
Solid * sol1 = ParseSolid (scan);
545
546
ParseChar (scan, ')');
547
548
Solid * nsol = sol1 -> Copy(*geom);
549
Transformation<3> trans(v);
550
nsol -> Transform (trans);
551
return nsol;
552
}
553
554
555
case TOK_ROTATE:
556
{
557
Point<3> c;
558
Vec<3> v;
559
scan.ReadNext();
560
561
scan >> '(' >> c >> ';' >> v >> ';';
562
563
Solid * sol1 = ParseSolid (scan);
564
565
ParseChar (scan, ')');
566
567
Solid * nsol = sol1 -> Copy(*geom);
568
Transformation<3> trans(c,v(0),v(1),v(2));
569
nsol -> Transform (trans);
570
return nsol;
571
}
572
573
574
case TOK_MULTITRANSLATE:
575
{
576
Vec<3> v;
577
int n;
578
579
scan.ReadNext();
580
581
scan >> '(' >> v >> ';' >> n >> ';';
582
583
Solid * sol1 = ParseSolid (scan);
584
585
scan >> ')';
586
587
Solid * hsol = sol1;
588
for (int i = 1; i <= n; i++)
589
{
590
Solid * nsol = sol1 -> Copy(*geom);
591
Transformation<3> trans(double(i) * v);
592
593
nsol -> Transform (trans);
594
hsol = new Solid (Solid::UNION, hsol, nsol);
595
}
596
return hsol;
597
}
598
599
600
case TOK_MULTIROTATE:
601
{
602
Point<3> c;
603
Vec<3> v;
604
int n;
605
606
scan.ReadNext();
607
608
scan >> '(' >> c >> ';' >> v >> ';' >> n >> ';';
609
Solid * sol1 = ParseSolid (scan);
610
scan >> ')';
611
612
Transformation<3> trans(c, v(0), v(1), v(2));
613
Transformation<3> multi(Vec<3>(0,0,0));
614
Transformation<3> ht;
615
616
Solid * hsol = sol1;
617
for (int i = 1; i <= n; i++)
618
{
619
Solid * nsol = sol1 -> Copy(*geom);
620
621
nsol -> Transform (multi);
622
hsol = new Solid (Solid::UNION, hsol, nsol);
623
624
ht=multi;
625
multi.Combine (trans, ht);
626
}
627
return hsol;
628
}
629
630
631
default:
632
{
633
scan.Error (string ("unknown primary ") + scan.GetStringValue());
634
}
635
636
}
637
}
638
639
else if (scan.GetToken() == TOK_STRING &&
640
geom->GetSolid(scan.GetStringValue()))
641
642
{
643
Solid * sol = const_cast<Solid*> (geom->GetSolid(scan.GetStringValue()));
644
scan.ReadNext();
645
return sol;
646
}
647
648
else if (scan.GetToken() == TOK_NOT)
649
650
{
651
scan.ReadNext();
652
Solid * sol1 = ParsePrimary (scan);
653
return new Solid (Solid::SUB, sol1);
654
}
655
656
else if (scan.GetToken() == '(')
657
658
{
659
scan.ReadNext();
660
Solid * sol1 = ParseSolid (scan);
661
scan.ReadNext();
662
return sol1;
663
}
664
665
scan.Error (string ("not a primary, name = ")+
666
scan.GetStringValue());
667
return 0;
668
}
669
670
671
672
Solid * ParseTerm (CSGScanner & scan)
673
{
674
Solid * sol = ParsePrimary(scan);
675
while (scan.GetToken() == TOK_AND)
676
{
677
scan.ReadNext();
678
Solid * sol2 = ParsePrimary(scan);
679
sol = new Solid (Solid::SECTION, sol, sol2);
680
}
681
return sol;
682
}
683
684
685
Solid * ParseSolid (CSGScanner & scan)
686
{
687
Solid * sol = ParseTerm(scan);
688
while (scan.GetToken() == TOK_OR)
689
{
690
scan.ReadNext();
691
Solid * sol2 = ParseTerm(scan);
692
sol = new Solid (Solid::UNION, sol, sol2);
693
}
694
return sol;
695
}
696
697
698
699
void ParseFlags (CSGScanner & scan, Flags & flags)
700
{
701
while (scan.GetToken() == '-')
702
{
703
scan.ReadNext();
704
string name = scan.GetStringValue();
705
scan.ReadNext();
706
if (scan.GetToken() == '=')
707
{
708
scan.ReadNext();
709
if (scan.GetToken() == TOK_STRING)
710
{
711
flags.SetFlag (name.c_str(), scan.GetStringValue().c_str());
712
scan.ReadNext();
713
}
714
else if (scan.GetToken() == '[')
715
{
716
scan.ReadNext();
717
718
if(scan.GetToken() == '-' || scan.GetToken() == TOK_NUM)
719
{
720
ARRAY<double> vals;
721
vals.Append (ParseNumber(scan));
722
while (scan.GetToken() == ',')
723
{
724
scan.ReadNext();
725
vals.Append (ParseNumber(scan));
726
}
727
ParseChar (scan, ']');
728
flags.SetFlag (name.c_str(), vals);
729
}
730
else
731
{ // string list
732
ARRAY<char*> vals;
733
string val = scan.GetStringValue();
734
vals.Append(new char[val.size()+1]);
735
strcpy(vals.Last(),val.c_str());
736
scan.ReadNext();
737
738
while (scan.GetToken() == ',')
739
{
740
scan.ReadNext();
741
val = scan.GetStringValue();
742
vals.Append(new char[val.size()+1]);
743
strcpy(vals.Last(),val.c_str());
744
scan.ReadNext();
745
}
746
ParseChar (scan, ']');
747
flags.SetFlag (name.c_str(), vals);
748
for(int i=0; i<vals.Size(); i++)
749
delete [] vals[i];
750
}
751
}
752
else if (scan.GetToken() == TOK_NUM)
753
{
754
flags.SetFlag (name.c_str(), scan.GetNumValue());
755
scan.ReadNext();
756
}
757
}
758
else
759
{
760
flags.SetFlag (name.c_str());
761
}
762
}
763
}
764
765
766
/*
767
Main parsing function for CSG geometry
768
*/
769
CSGeometry * ParseCSG (istream & istr)
770
{
771
CSGScanner scan(istr);
772
773
geom = new CSGeometry;
774
775
scan.ReadNext();
776
if (scan.GetToken() != TOK_RECO) // keyword 'algebraic3d'
777
return 0;
778
779
scan.ReadNext();
780
781
try
782
{
783
while (1)
784
{
785
if (scan.GetToken() == TOK_END) break;
786
787
if (scan.GetToken() == TOK_SOLID)
788
{
789
scan.ReadNext();
790
if (scan.GetToken() != TOK_STRING)
791
scan.Error ("name identifier expected");
792
string solidname = scan.GetStringValue();
793
794
scan.ReadNext();
795
796
ParseChar (scan, '=');
797
Solid * solid = ParseSolid (scan);
798
799
Flags flags;
800
ParseFlags (scan, flags);
801
802
geom->SetSolid (solidname.c_str(), new Solid (Solid::ROOT, solid));
803
geom->SetFlags (solidname.c_str(), flags);
804
805
ParseChar (scan, ';');
806
807
PrintMessage (4, "define solid ", solidname);
808
}
809
810
else if (scan.GetToken() == TOK_TLO)
811
812
{ // a TopLevelObject definition
813
814
scan.ReadNext();
815
816
string name = scan.GetStringValue();
817
scan.ReadNext();
818
819
if (scan.GetToken() != TOK_STRING)
820
821
{ // a solid TLO
822
823
Flags flags;
824
ParseFlags (scan, flags);
825
826
ParseChar (scan, ';');
827
if (!geom->GetSolid (name))
828
scan.Error ("Top-Level-Object "+name+" not defined");
829
830
int tlonr =
831
geom->SetTopLevelObject ((Solid*)geom->GetSolid(name));
832
TopLevelObject * tlo = geom->GetTopLevelObject (tlonr);
833
834
if (flags.NumListFlagDefined ("col"))
835
{
836
const ARRAY<double> & col =
837
flags.GetNumListFlag ("col");
838
tlo->SetRGB (col[0], col[1], col[2]);
839
}
840
841
if (flags.GetDefineFlag ("transparent"))
842
tlo->SetTransparent (1);
843
844
tlo->SetMaterial (flags.GetStringFlag ("material", ""));
845
tlo->SetLayer (int(flags.GetNumFlag ("layer", 1)));
846
if (flags.NumFlagDefined ("maxh"))
847
tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10));
848
}
849
850
else
851
852
{ // a surface TLO
853
854
string surfname = scan.GetStringValue();
855
scan.ReadNext();
856
857
Flags flags;
858
ParseFlags (scan, flags);
859
860
ParseChar (scan, ';');
861
862
ARRAY<int> si;
863
geom->GetSolid(surfname)->GetSurfaceIndices(si);
864
int tlonr =
865
geom->SetTopLevelObject ((Solid*)geom->GetSolid(name),
866
(Surface*)geom->GetSurface(si.Get(1)));
867
TopLevelObject * tlo = geom->GetTopLevelObject (tlonr);
868
if (flags.NumListFlagDefined ("col"))
869
{
870
const ARRAY<double> & col = flags.GetNumListFlag ("col");
871
tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3));
872
}
873
if (flags.GetDefineFlag ("transparent"))
874
tlo->SetTransparent (1);
875
876
if (flags.NumFlagDefined ("maxh"))
877
tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10));
878
tlo->SetLayer (int(flags.GetNumFlag ("layer", 1)));
879
tlo->SetBCProp (int(flags.GetNumFlag ("bc", -1)));
880
if ( flags.StringFlagDefined("bcname") )
881
tlo->SetBCName ( flags.GetStringFlag ("bcname", "default") );
882
}
883
}
884
885
else if (scan.GetToken() == TOK_IDENTIFY)
886
887
{
888
889
scan.ReadNext();
890
switch (scan.GetToken())
891
{
892
case TOK_CLOSESURFACES:
893
{
894
scan.ReadNext();
895
896
string name1 = scan.GetStringValue();
897
scan.ReadNext();
898
899
string name2 = scan.GetStringValue();
900
scan.ReadNext();
901
902
Flags flags;
903
ParseFlags (scan, flags);
904
905
ParseChar (scan, ';');
906
907
908
ARRAY<int> si1, si2;
909
geom->GetSolid(name1)->GetSurfaceIndices(si1);
910
geom->GetSolid(name2)->GetSurfaceIndices(si2);
911
912
const TopLevelObject * domain = 0;
913
if (flags.StringFlagDefined ("tlo"))
914
{
915
domain =
916
geom->GetTopLevelObject (geom->GetSolid(flags.GetStringFlag ("tlo","")));
917
if (!domain)
918
scan.Error ("identification needs undefined tlo");
919
}
920
921
geom->AddIdentification
922
(new CloseSurfaceIdentification
923
(geom->GetNIdentifications()+1, *geom,
924
geom->GetSurface (si1[0]), geom->GetSurface (si2[0]),
925
domain,
926
flags));
927
928
break;
929
}
930
931
case TOK_PERIODIC:
932
{
933
scan.ReadNext();
934
935
string name1 = scan.GetStringValue();
936
scan.ReadNext();
937
938
string name2 = scan.GetStringValue();
939
scan.ReadNext();
940
941
ParseChar (scan, ';');
942
943
944
ARRAY<int> si1, si2;
945
geom->GetSolid(name1)->GetSurfaceIndices(si1);
946
geom->GetSolid(name2)->GetSurfaceIndices(si2);
947
948
geom->AddIdentification
949
(new PeriodicIdentification
950
(geom->GetNIdentifications()+1,
951
*geom,
952
geom->GetSurface (si1.Get(1)),
953
geom->GetSurface (si2.Get(1))));
954
break;
955
}
956
957
default:
958
scan.Error ("keyword 'closesurfaces' or 'periodic' expected");
959
}
960
961
}
962
963
else if (scan.GetToken() == TOK_SINGULAR)
964
965
{
966
967
scan.ReadNext();
968
switch (scan.GetToken())
969
{
970
case TOK_FACE:
971
{
972
scan.ReadNext();
973
974
string name1 = scan.GetStringValue(); // tlo
975
scan.ReadNext();
976
977
string name2 = scan.GetStringValue();
978
scan.ReadNext();
979
980
Flags flags;
981
ParseFlags (scan, flags);
982
int factor = int(flags.GetNumFlag("factor",1));
983
// cout << "Singular Face with factor " << factor << endl;
984
PrintMessageCR (3, "Singular Face with factor ", factor);
985
986
ParseChar (scan, ';');
987
988
const Solid * sol = geom->GetSolid(name2);
989
990
if(!sol)
991
scan.Error ("unknown solid in singular face definition");
992
else
993
for (int i = 0; i < geom->GetNTopLevelObjects(); i++)
994
if (name1 == geom->GetTopLevelObject (i)->GetSolid()->Name())
995
geom->singfaces.Append (new SingularFace (i+1, sol,factor));
996
997
break;
998
}
999
1000
case TOK_EDGE:
1001
{
1002
scan.ReadNext();
1003
1004
string name1 = scan.GetStringValue();
1005
scan.ReadNext();
1006
1007
string name2 = scan.GetStringValue();
1008
scan.ReadNext();
1009
1010
Flags flags;
1011
ParseFlags (scan, flags);
1012
int factor = int(flags.GetNumFlag("factor",1));
1013
double maxhinit = flags.GetNumFlag("maxh",-1);
1014
ParseChar (scan, ';');
1015
1016
const Solid * s1 = geom->GetSolid(name1);
1017
const Solid * s2 = geom->GetSolid(name2);
1018
PrintMessageCR (3, "Singular Edge with factor ", factor);
1019
1020
int domnr = -1;
1021
if (flags.StringFlagDefined ("tlo"))
1022
{
1023
const Solid * sol =
1024
geom->GetSolid(flags.GetStringFlag ("tlo",""));
1025
1026
for (int i = 0; i < geom->GetNTopLevelObjects(); i++)
1027
if (geom->GetTopLevelObject(i)->GetSolid() == sol)
1028
domnr = i;
1029
1030
// cout << "domnr = " << domnr;
1031
}
1032
1033
if(!s1 || !s2)
1034
scan.Error ("unknown solid ins singular edge definition");
1035
else
1036
geom->singedges.Append (new SingularEdge (1, domnr,
1037
*geom, s1, s2, factor,
1038
maxhinit));
1039
break;
1040
}
1041
1042
case TOK_POINT:
1043
{
1044
scan.ReadNext();
1045
1046
string name1 = scan.GetStringValue();
1047
scan.ReadNext();
1048
string name2 = scan.GetStringValue();
1049
scan.ReadNext();
1050
string name3 = scan.GetStringValue();
1051
scan.ReadNext();
1052
1053
Flags flags;
1054
ParseFlags (scan, flags);
1055
int factor = int(flags.GetNumFlag("factor",1));
1056
ParseChar (scan, ';');
1057
1058
const Solid * s1 = geom->GetSolid(name1);
1059
const Solid * s2 = geom->GetSolid(name2);
1060
const Solid * s3 = geom->GetSolid(name3);
1061
// cout << "Singular Point with factor " << factor << endl;
1062
PrintMessageCR (3, "Singular Point with factor ", factor);
1063
geom->singpoints.Append (new SingularPoint (1, s1, s2, s3, factor));
1064
break;
1065
}
1066
default:
1067
scan.Error ("keyword 'face' or 'edge' or 'point' expected");
1068
}
1069
}
1070
1071
1072
else if (scan.GetToken() == TOK_POINT)
1073
{
1074
Point<3> p;
1075
1076
scan.ReadNext();
1077
ParseChar (scan, '(');
1078
p = Point<3> (ParseVector (scan));
1079
ParseChar (scan, ')');
1080
1081
1082
Flags flags;
1083
ParseFlags (scan, flags);
1084
int factor = int(flags.GetNumFlag("factor",0));
1085
1086
ParseChar (scan, ';');
1087
1088
geom->AddUserPoint (p, factor);
1089
}
1090
1091
else if (scan.GetToken() == TOK_BOUNDINGBOX)
1092
{
1093
Point<3> p1, p2;
1094
1095
scan.ReadNext();
1096
ParseChar (scan, '(');
1097
p1 = Point<3> (ParseVector (scan));
1098
ParseChar (scan, ';');
1099
p2 = Point<3> (ParseVector (scan));
1100
ParseChar (scan, ')');
1101
ParseChar (scan, ';');
1102
1103
geom->SetBoundingBox (Box<3> (p1, p2));
1104
}
1105
1106
else if (scan.GetToken() == TOK_CURVE2D)
1107
{
1108
scan.ReadNext();
1109
1110
1111
if (scan.GetToken() != TOK_STRING)
1112
scan.Error ("name identifier expected");
1113
string curvename = scan.GetStringValue();
1114
1115
scan.ReadNext();
1116
1117
ParseChar (scan, '=');
1118
ParseChar (scan, '(');
1119
1120
SplineGeometry<2> * newspline = new SplineGeometry<2>;
1121
newspline->CSGLoad(scan);
1122
1123
ParseChar (scan, ')');
1124
ParseChar (scan, ';');
1125
1126
geom->SetSplineCurve(curvename.c_str(),newspline);
1127
1128
PrintMessage (4, "define 2d curve ", curvename);
1129
}
1130
1131
else if (scan.GetToken() == TOK_CURVE3D)
1132
{
1133
scan.ReadNext();
1134
1135
1136
if (scan.GetToken() != TOK_STRING)
1137
scan.Error ("name identifier expected");
1138
string curvename = scan.GetStringValue();
1139
1140
scan.ReadNext();
1141
1142
ParseChar (scan, '=');
1143
ParseChar (scan, '(');
1144
1145
SplineGeometry<3> * newspline = new SplineGeometry<3>;
1146
newspline->CSGLoad(scan);
1147
1148
ParseChar (scan, ')');
1149
ParseChar (scan, ';');
1150
1151
geom->SetSplineCurve(curvename.c_str(),newspline);
1152
1153
PrintMessage (4, "define 3d curve ", curvename);
1154
}
1155
1156
else if (scan.GetToken() == TOK_BOUNDARYCONDITION)
1157
{
1158
scan.ReadNext();
1159
1160
string name1 = scan.GetStringValue();
1161
scan.ReadNext();
1162
1163
string name2 = scan.GetStringValue();
1164
scan.ReadNext();
1165
1166
int num = int (ParseNumber (scan));
1167
ParseChar (scan, ';');
1168
1169
1170
CSGeometry::BCModification bcm;
1171
bcm.bcname = NULL;
1172
ARRAY<int> si;
1173
1174
geom->GetSolid(name1)->GetSurfaceIndices(si);
1175
if(si.Size() == 0)
1176
{
1177
string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces";
1178
scan.Error (errstring);
1179
}
1180
1181
bcm.tlonr = -1;
1182
int i;
1183
for (i = 0; i < geom->GetNTopLevelObjects(); i++)
1184
if (string (geom->GetTopLevelObject(i)->GetSolid()->Name())
1185
== name2)
1186
{
1187
bcm.tlonr = i;
1188
break;
1189
}
1190
if(bcm.tlonr == -1)
1191
{
1192
string errstring = "tlo \""; errstring += name2; errstring += "\" not found";
1193
scan.Error(errstring);
1194
}
1195
1196
1197
bcm.bcnr = num;
1198
for (i = 0; i < si.Size(); i++)
1199
{
1200
bcm.si = si[i];
1201
geom->bcmodifications.Append (bcm);
1202
}
1203
}
1204
1205
else if (scan.GetToken() == TOK_BOUNDARYCONDITIONNAME)
1206
{
1207
scan.ReadNext();
1208
1209
string name1 = scan.GetStringValue();
1210
scan.ReadNext();
1211
1212
string name2 = scan.GetStringValue();
1213
scan.ReadNext();
1214
1215
string bcname = scan.GetStringValue();
1216
scan.ReadNext();
1217
ParseChar(scan, ';');
1218
1219
1220
CSGeometry::BCModification bcm;
1221
bcm.bcname = NULL;
1222
1223
1224
ARRAY<int> si;
1225
1226
geom->GetSolid(name1)->GetSurfaceIndices(si);
1227
if(si.Size() == 0)
1228
{
1229
string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces";
1230
scan.Error (errstring);
1231
}
1232
1233
bcm.tlonr = -1;
1234
int i;
1235
for (i = 0; i < geom->GetNTopLevelObjects(); i++)
1236
if (string (geom->GetTopLevelObject(i)->GetSolid()->Name())
1237
== name2)
1238
{
1239
bcm.tlonr = i;
1240
break;
1241
}
1242
if(bcm.tlonr == -1)
1243
{
1244
string errstring = "tlo \""; errstring += name2; errstring += "\" not found";
1245
scan.Error(errstring);
1246
}
1247
1248
1249
bcm.bcnr = -1;
1250
for (i = 0; i < si.Size(); i++)
1251
{
1252
bcm.si = si[i];
1253
geom->bcmodifications.Append (bcm);
1254
geom->bcmodifications.Last().bcname = new string(bcname);
1255
}
1256
}
1257
1258
else if (scan.GetToken() == TOK_DEFINE)
1259
{
1260
scan.ReadNext();
1261
string name;
1262
double val;
1263
1264
switch (scan.GetToken())
1265
{
1266
case TOK_CONSTANT:
1267
scan.ReadNext();
1268
1269
name = scan.GetStringValue();
1270
scan.ReadNext();
1271
1272
ParseChar(scan, '=');
1273
val = ParseNumber(scan);
1274
1275
if(name == "identprec")
1276
geom->SetIdEps(val);
1277
1278
1279
1280
break;
1281
default:
1282
scan.Error ("keyword 'constant' expected");
1283
}
1284
}
1285
1286
1287
else
1288
{
1289
cout << "read unidentified token " << scan.GetToken()
1290
<< " (as char: \"" << char(scan.GetToken()) << "\")"
1291
<< " string = " << scan.GetStringValue() << endl;
1292
scan.ReadNext();
1293
}
1294
}
1295
}
1296
catch (string errstr)
1297
{
1298
cout << "caught error " << errstr << endl;
1299
throw NgException (errstr);
1300
}
1301
1302
1303
1304
(*testout) << geom->GetNTopLevelObjects() << " TLOs:" << endl;
1305
for (int i = 0; i < geom->GetNTopLevelObjects(); i++)
1306
{
1307
const TopLevelObject * tlo = geom->GetTopLevelObject(i);
1308
if (tlo->GetSolid())
1309
(*testout) << i << ": " << *tlo->GetSolid() << endl;
1310
}
1311
1312
(*testout) << geom->GetNSurf() << " Surfaces" << endl;
1313
for (int i = 0; i < geom->GetNSurf(); i++)
1314
(*testout) << i << ": " << *geom->GetSurface(i) << endl;
1315
1316
return geom;
1317
/*
1318
do
1319
{
1320
scan.ReadNext();
1321
if (scan.GetToken() == TOK_STRING)
1322
cout << "found string " << scan.GetStringValue() << endl;
1323
else
1324
cout << "token = " << int(scan.GetToken()) << endl;
1325
}
1326
while (scan.GetToken() != TOK_END);
1327
*/
1328
}
1329
1330
1331
};
1332
1333
1334