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