220{
223
224 if( sol == 0 ) { return 0; }
225
226#ifdef G4VERBOSE
228 {
229 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid():" <<
G4endl
230 <<
" SOLID = " << sol <<
G4endl
231 << " " << sol->GetName() << " of type " << sol->GetType()
233 }
234#endif
235
236
239 if( solid ) { return solid; }
240
241
242
243#ifdef G4VERBOSE
245 {
246 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid() - "
247 << sol->GetSolidParams().size() <<
G4endl;
248 }
249#endif
250
251 std::vector<G4double> solParam;
252
253
254
255 if( sol->GetSolidParams().size() == 1)
256 {
257 solParam = * sol->GetSolidParams()[ 0 ];
258 }
259
260
263
264 if( stype == "BOX" )
265 {
267 solid =
new G4Box( sname, solParam[0], solParam[1], solParam[2] );
268
269 }
270 else if( stype == "TUBE" )
271 {
273 solid =
new G4Tubs( sname, solParam[0], solParam[1], solParam[2],
274 0.*deg, 360.*deg );
275 }
276 else if( stype == "TUBS" )
277 {
280 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
281 solid =
new G4Tubs( sname, solParam[0], solParam[1], solParam[2],
282 solParam[3], phiDelta );
283 }
284 else if( stype == "TRAP" )
285 {
286 if( solParam.size() == 11 )
287 {
288 solid =
new G4Trap( sname, solParam[0], solParam[1], solParam[2],
289 solParam[3], solParam[4], solParam[5], solParam[6],
290 solParam[7], solParam[8], solParam[9], solParam[10] );
291 }
292 else if( solParam.size() == 4 )
293 {
294 solid =
new G4Trap( sname, solParam[0], solParam[1]/deg,
295 solParam[2]/deg, solParam[3]);
296 }
297 else
298 {
299 G4String ErrMessage1 =
"Solid type " + stype;
300 G4String ErrMessage2 =
" should have 11 or 4 parameters,\n";
301 G4String ErrMessage3 =
"and it has "
303 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 +
" !";
304 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
306 return 0;
307 }
308
309 }
310 else if( stype == "TRD" )
311 {
313 solid =
new G4Trd( sname, solParam[0], solParam[1], solParam[2],
314 solParam[3], solParam[4] );
315 }
316 else if( stype == "PARA" )
317 {
319 solid =
new G4Para( sname, solParam[0], solParam[1], solParam[2],
320 solParam[3], solParam[4], solParam[5] );
321 }
322 else if( stype == "CONE" )
323 {
325 solid =
new G4Cons( sname, solParam[0], solParam[1], solParam[2],
326 solParam[3], solParam[4], 0., 360.*deg);
327 }
328 else if( stype == "CONS" )
329 {
332 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
333 solid =
new G4Cons( sname, solParam[0], solParam[1], solParam[2],
334 solParam[3], solParam[4], solParam[5], phiDelta);
335 }
336 else if( stype == "SPHERE" )
337 {
340 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
342 if( std::fabs(thetaDelta - pi) < angularTolerance ) { thetaDelta =
pi; }
343 solid =
new G4Sphere( sname, solParam[0], solParam[1], solParam[2],
344 phiDelta, solParam[4], thetaDelta);
345 }
346 else if( stype == "ORB" )
347 {
349 solid =
new G4Orb( sname, solParam[0] );
350 }
351 else if( stype == "TORUS" )
352 {
355 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
356 solid =
new G4Torus( sname, solParam[0], solParam[1], solParam[2],
357 solParam[3], phiDelta );
358 }
359 else if( stype == "POLYCONE" )
360 {
361 size_t nplanes = size_t(solParam[2]);
362 G4bool genericPoly =
false;
363 if( solParam.size() == 3+nplanes*3 )
364 {
365 genericPoly = true;
366 }
367 else if( solParam.size() == 3+nplanes*2 )
368 {
369 genericPoly = false;
370 }
371 else
372 {
373 G4String Err1 =
"Solid type " + stype +
" should have ";
375 + " (Z,Rmin,Rmax)\n";
377 G4String Err4 =
" (RZ corners) parameters,\n";
380 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
381 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
383 return 0;
384 }
385
386 if( genericPoly )
387 {
388 std::vector<G4double>* z_p = new std::vector<G4double>;
389 std::vector<G4double>* rmin_p = new std::vector<G4double>;
390 std::vector<G4double>* rmax_p = new std::vector<G4double>;
391 for( size_t ii = 0; ii < nplanes; ii++ )
392 {
393 (*z_p).push_back( solParam[3+3*ii] );
394 (*rmin_p).push_back( solParam[3+3*ii+1] );
395 (*rmax_p).push_back( solParam[3+3*ii+2] );
396 }
398 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
399 solid =
new G4Polycone( sname, solParam[0], phiTotal,
400 nplanes,
401 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
402 }
403 else
404 {
405 std::vector<G4double>* R_c = new std::vector<G4double>;
406 std::vector<G4double>* Z_c = new std::vector<G4double>;
407 for( size_t ii = 0; ii < nplanes; ii++ )
408 {
409 (*R_c).push_back( solParam[3+2*ii] );
410 (*Z_c).push_back( solParam[3+2*ii+1] );
411 }
413 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
414 solid =
new G4Polycone( sname, solParam[0], phiTotal,
415 nplanes,
416 &((*R_c)[0]), &((*Z_c)[0]));
417 }
418
419 }
420 else if( stype == "POLYHEDRA" )
421 {
422 size_t nplanes = size_t(solParam[3]);
423 G4bool genericPoly =
false;
424 if( solParam.size() == 4+nplanes*3 )
425 {
426 genericPoly = true;
427 }
428 else if( solParam.size() == 4+nplanes*2 )
429 {
430 genericPoly = false;
431 }
432 else
433 {
434 G4String Err1 =
"Solid type " + stype +
" should have ";
436 + " (Z,Rmin,Rmax)\n";
438 G4String Err4 =
" (RZ corners) parameters,\n";
441 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
442 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
444 return 0;
445 }
446
447 if( genericPoly )
448 {
449 std::vector<G4double>* z_p = new std::vector<G4double>;
450 std::vector<G4double>* rmin_p = new std::vector<G4double>;
451 std::vector<G4double>* rmax_p = new std::vector<G4double>;
452 for( size_t ii = 0; ii < nplanes; ii++ )
453 {
454 (*z_p).push_back( solParam[4+3*ii] );
455 (*rmin_p).push_back( solParam[4+3*ii+1] );
456 (*rmax_p).push_back( solParam[4+3*ii+2] );
457 }
459 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
460 solid =
new G4Polyhedra( sname, solParam[0], phiTotal,
461 G4int(solParam[2]), nplanes,
462 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
463 }
464 else
465 {
466 std::vector<G4double>* R_c = new std::vector<G4double>;
467 std::vector<G4double>* Z_c = new std::vector<G4double>;
468 for( size_t ii = 0; ii < nplanes; ii++ )
469 {
470 (*R_c).push_back( solParam[4+2*ii] );
471 (*Z_c).push_back( solParam[4+2*ii+1] );
472 }
474 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
475 solid =
new G4Polyhedra( sname, solParam[0], phiTotal,
476 G4int(solParam[2]), nplanes,
477 &((*R_c)[0]), &((*Z_c)[0]));
478 }
479 }
480 else if( stype == "ELLIPTICALTUBE" )
481 {
483 solid =
new G4EllipticalTube( sname, solParam[0], solParam[1], solParam[2]);
484 }
485 else if( stype == "ELLIPSOID" )
486 {
488 solid =
new G4Ellipsoid( sname, solParam[0], solParam[1], solParam[2],
489 solParam[3], solParam[4] );
490 }
491 else if( stype == "ELLIPTICALCONE" )
492 {
495 solParam[2], solParam[3] );
496 }
497 else if( stype == "HYPE" )
498 {
500 solid =
new G4Hype( sname, solParam[0], solParam[1], solParam[2],
501 solParam[3], solParam[4] );
502 }
503 else if( stype == "TET" )
504 {
510 solid =
new G4Tet( sname, anchor, p2, p3, p4 );
511 }
512 else if( stype == "TWISTEDBOX" )
513 {
515 solid =
new G4TwistedBox( sname, solParam[0], solParam[1],
516 solParam[2], solParam[3]);
517 }
518 else if( stype == "TWISTEDTRAP" )
519 {
521 solid =
new G4TwistedTrap( sname, solParam[0], solParam[1], solParam[2],
522 solParam[3], solParam[4], solParam[5], solParam[6],
523 solParam[7], solParam[8], solParam[9], solParam[10] );
524 }
525 else if( stype == "TWISTEDTRD" )
526 {
528 solid =
new G4TwistedTrd( sname, solParam[0], solParam[1], solParam[2],
529 solParam[3], solParam[4], solParam[5]);
530 }
531 else if( stype == "TWISTEDTUBS" )
532 {
535 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
536 solid =
new G4TwistedTubs( sname, solParam[0], solParam[1], solParam[2],
537 solParam[3], phiTotal);
538 }
539 else if( stype == "BREPBOX" )
540 {
542 std::vector<G4Point3D> points;
543 for( size_t ii = 0; ii < 8; ii++ )
544 {
545 points.push_back(
G4Point3D(solParam[ii*3+0],
546 solParam[ii*3+1],
547 solParam[ii*3+2]) );
548 }
549 solid =
new G4BREPSolidBox( sname, points[0], points[1], points[2],
550 points[3], points[4], points[5], points[6],
551 points[7] );
552 }
553 else if( stype == "BREPCYLINDER" )
554 {
560 solParam[9], solParam[10] );
561 }
562 else if( stype == "BREPCONE" )
563 {
569 solParam[9], solParam[10], solParam[11] );
570 }
571 else if( stype == "BREPSPHERE" )
572 {
578 solParam[9] );
579
580 }
581 else if( stype == "BREPTORUS" )
582 {
588 solParam[9], solParam[10] );
589 }
590 else if( stype == "BREPPCONE" )
591 {
592 size_t nplanes = size_t(solParam[2]);
594 std::vector<G4double>* z_p = new std::vector<G4double>;
595 std::vector<G4double>* rmin_p = new std::vector<G4double>;
596 std::vector<G4double>* rmax_p = new std::vector<G4double>;
597 for( size_t ii = 0; ii < nplanes; ii++ )
598 {
599 (*z_p).push_back( solParam[4+3*ii] );
600 (*rmin_p).push_back( solParam[4+3*ii+1] );
601 (*rmax_p).push_back( solParam[4+3*ii+2] );
602 }
604 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
607 nplanes,
608 solParam[3],
609 &((*z_p)[0]), &((*rmin_p)[0]),
610 &((*rmax_p)[0]));
611 }
612 else if( stype == "BREPPOLYHEDRA" )
613 {
614 size_t nplanes = size_t(solParam[3]);
616 std::vector<G4double>* z_p = new std::vector<G4double>;
617 std::vector<G4double>* rmin_p = new std::vector<G4double>;
618 std::vector<G4double>* rmax_p = new std::vector<G4double>;
619 for( size_t ii = 0; ii < nplanes; ii++ )
620 {
621 (*z_p).push_back( solParam[5+3*ii] );
622 (*rmin_p).push_back( solParam[5+3*ii+1] );
623 (*rmax_p).push_back( solParam[5+3*ii+2] );
624 }
626 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
630 nplanes,
631 solParam[4],
632 &((*z_p)[0]), &((*rmin_p)[0]),
633 &((*rmax_p)[0]));
634 }
635 else if( stype == "BREPOPENPCONE" )
636 {
637 size_t nplanes = size_t(solParam[2]);
638 std::vector<G4double>* z_p = new std::vector<G4double>;
639 std::vector<G4double>* rmin_p = new std::vector<G4double>;
640 std::vector<G4double>* rmax_p = new std::vector<G4double>;
641 for( size_t ii = 0; ii < nplanes; ii++ )
642 {
643 (*z_p).push_back( solParam[4+3*ii] );
644 (*rmin_p).push_back( solParam[4+3*ii+1] );
645 (*rmax_p).push_back( solParam[4+3*ii+2] );
646 }
648 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
651 nplanes,
652 solParam[3],
653 &((*z_p)[0]), &((*rmin_p)[0]),
654 &((*rmax_p)[0]));
655 }
656 else if( stype == "TESSELLATED" )
657 {
663
664 for(
G4int ii = 0; ii < nFacets; ii++){
666 if(
G4int(solParam.size()) < jj + nPoints*3 + 2 ) {
670 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
671 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
673 return 0;
674 }
675
676 if( nPoints == 3 )
677 {
678 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]);
679 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]);
680 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]);
682 if( solParam[jj+11] == 0 )
683 {
685 }
686 else if( solParam[jj+11] == 1 )
687 {
689 }
690 else
691 {
692 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
695 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
696 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
698 return 0;
699 }
701 }
702 else if( nPoints == 4 )
703 {
704 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]);
705 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]);
706 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]);
707 G4ThreeVector vt3(solParam[jj+11],solParam[jj+12],solParam[jj+13]);
709 if( solParam[jj+14] == 0 )
710 {
712 }
713 else if( solParam[jj+14] == 1 )
714 {
716 }
717 else
718 {
719 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
722 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
723 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
725 return 0;
726 }
728 }
729 else
730 {
731 G4String Err1 =
"Wrong number of points in tesselated solid, it should be 3 or 4";
734 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
735 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
737 return 0;
738 }
739
741 jj += nPoints*3 + 2;
742 }
743
744 }
745 else if( stype == "EXTRUDED" )
746 {
747 std::vector<G4TwoVector> polygonList;
748 std::vector<G4ExtrudedSolid::ZSection> zsectionList;
751 G4int nMax = nPolygons*2+1;
752 for( ;ii < nMax; ii+=2 )
753 {
754 polygonList.push_back(
G4TwoVector(solParam[ii],solParam[ii+1]) );
755 }
757 nMax = nPolygons*2 + nZSections*4 + 2;
758 ii++;
759 for( ; ii < nMax; ii+=4 )
760 {
763 }
765
766 }
767 else if( stype.substr(0,7) == "Boolean" )
768 {
770 if (!solb)
771 {
772 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
774 return 0;
775 }
781
782 if( stype == "Boolean_UNION" )
783 {
784 solid =
new G4UnionSolid( sname, sol1, sol2, relRotMat, relPlace );
785 }
786 else if( stype == "Boolean_SUBTRACTION" )
787 {
789 }
790 else if( stype == "Boolean_INTERSECTION" )
791 {
793 }
794 else
795 {
796 G4String ErrMessage =
"Unknown Boolean type " + stype;
797 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
799 return 0;
800 }
801 }
802 else
803 {
804 G4String ErrMessage =
"Solids of type " + stype
805 + " not implemented yet, sorry...";
806 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"NotImplemented",
808 return 0;
809 }
810
811#ifdef G4VERBOSE
813 {
814 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid()" <<
G4endl
815 << " Created solid " << sname
817 }
818#endif
819
820#ifdef G4VERBOSE
822 {
823 G4cout <<
" Constructing new G4Solid: "
825 }
826#endif
827
828 return solid;
829}
HepGeom::Point3D< G4double > G4Point3D
CLHEP::Hep2Vector G4TwoVector
G4double GetAngularTolerance() const
G4bool AddFacet(G4VFacet *aFacet)
G4VSolid * FindG4Solid(const G4String &name)
void CheckNoSolidParams(const G4String &solidType, const unsigned int NoParamExpected, const unsigned int NoParam)
const G4tgrSolid * GetSolid(G4int ii) const
G4ThreeVector GetRelativePlace() const