206{
209
210 if(sol == nullptr)
211 {
212 return nullptr;
213 }
214
215#ifdef G4VERBOSE
217 {
218 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid():" <<
G4endl
219 <<
" SOLID = " << sol <<
G4endl <<
" " << sol->GetName()
220 <<
" of type " << sol->GetType() <<
G4endl;
221 }
222#endif
223
224
226 if(solid != nullptr)
227 {
228 return solid;
229 }
230
231
232
233#ifdef G4VERBOSE
235 {
236 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid() - "
237 << sol->GetSolidParams().size() <<
G4endl;
238 }
239#endif
240
241 std::vector<G4double> solParam;
242
243
244
245 if(sol->GetSolidParams().size() == 1)
246 {
247 solParam = *sol->GetSolidParams()[0];
248 }
249
250
253
254 if(stype == "BOX")
255 {
257 solid =
new G4Box(sname, solParam[0], solParam[1], solParam[2]);
258 }
259 else if(stype == "TUBE")
260 {
262 solid =
new G4Tubs(sname, solParam[0], solParam[1], solParam[2], 0. * deg,
263 360. * deg);
264 }
265 else if(stype == "TUBS")
266 {
269 if(std::fabs(phiDelta - twopi) < angularTolerance)
270 {
271 phiDelta = twopi;
272 }
273 solid =
new G4Tubs(sname, solParam[0], solParam[1], solParam[2],
274 solParam[3], phiDelta);
275 }
276 else if(stype == "TRAP")
277 {
278 if(solParam.size() == 11)
279 {
280 solid =
new G4Trap(sname, solParam[0], solParam[1], solParam[2],
281 solParam[3], solParam[4], solParam[5], solParam[6],
282 solParam[7], solParam[8], solParam[9], solParam[10]);
283 }
284 else if(solParam.size() == 4)
285 {
286 solid =
new G4Trap(sname, solParam[0], solParam[1] / deg,
287 solParam[2] / deg, solParam[3]);
288 }
289 else
290 {
291 G4String ErrMessage1 =
"Solid type " + stype;
292 G4String ErrMessage2 =
" should have 11 or 4 parameters,\n";
295 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 +
" !";
296 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
298 return 0;
299 }
300 }
301 else if(stype == "TRD")
302 {
304 solid =
new G4Trd(sname, solParam[0], solParam[1], solParam[2], solParam[3],
305 solParam[4]);
306 }
307 else if(stype == "PARA")
308 {
310 solid =
new G4Para(sname, solParam[0], solParam[1], solParam[2],
311 solParam[3], solParam[4], solParam[5]);
312 }
313 else if(stype == "CONE")
314 {
316 solid =
new G4Cons(sname, solParam[0], solParam[1], solParam[2],
317 solParam[3], solParam[4], 0., 360. * deg);
318 }
319 else if(stype == "CONS")
320 {
323 if(std::fabs(phiDelta - twopi) < angularTolerance)
324 {
325 phiDelta = twopi;
326 }
327 solid =
new G4Cons(sname, solParam[0], solParam[1], solParam[2],
328 solParam[3], solParam[4], solParam[5], phiDelta);
329 }
330 else if(stype == "SPHERE")
331 {
334 if(std::fabs(phiDelta - twopi) < angularTolerance)
335 {
336 phiDelta = twopi;
337 }
339 if(std::fabs(thetaDelta - pi) < angularTolerance)
340 {
342 }
343 solid =
new G4Sphere(sname, solParam[0], solParam[1], solParam[2], phiDelta,
344 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)
356 {
357 phiDelta = twopi;
358 }
359 solid =
new G4Torus(sname, solParam[0], solParam[1], solParam[2],
360 solParam[3], phiDelta);
361 }
362 else if(stype == "POLYCONE"
363 || stype == "GENERICPOLYCONE")
364 {
365 std::size_t nplanes = std::size_t(solParam[2]);
366 G4bool genericPoly =
false;
367 if(solParam.size() == 3 + nplanes * 3)
368 {
369 genericPoly = false;
370 }
371 else if(solParam.size() == 3 + nplanes * 2)
372 {
373 genericPoly = true;
374 }
375 else
376 {
377 G4String Err1 =
"Solid type " + stype +
" should have ";
379 " (Z,Rmin,Rmax)\n";
382 G4String Err4 =
" (RZ corners) parameters,\n";
385 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
386 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
388 return nullptr;
389 }
390
391 if(!genericPoly)
392 {
393 std::vector<G4double>* z_p = new std::vector<G4double>;
394 std::vector<G4double>* rmin_p = new std::vector<G4double>;
395 std::vector<G4double>* rmax_p = new std::vector<G4double>;
396 for(std::size_t ii = 0; ii < nplanes; ++ii)
397 {
398 (*z_p).push_back(solParam[3 + 3 * ii]);
399 (*rmin_p).push_back(solParam[3 + 3 * ii + 1]);
400 (*rmax_p).push_back(solParam[3 + 3 * ii + 2]);
401 }
403 if(std::fabs(phiTotal - twopi) < angularTolerance)
404 {
405 phiTotal = twopi;
406 }
407 solid =
new G4Polycone(sname, solParam[0], phiTotal,
409 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
410 }
411 else
412 {
413 std::vector<G4double>* R_c = new std::vector<G4double>;
414 std::vector<G4double>* Z_c = new std::vector<G4double>;
415 for(size_t ii = 0; ii < nplanes; ii++)
416 {
417 (*R_c).push_back(solParam[3 + 2 * ii]);
418 (*Z_c).push_back(solParam[3 + 2 * ii + 1]);
419 }
421 if(std::fabs(phiTotal - twopi) < angularTolerance)
422 {
423 phiTotal = twopi;
424 }
425 solid =
428 &((*R_c)[0]), &((*Z_c)[0]));
429 }
430 }
431 else if(stype == "POLYHEDRA")
432 {
433 std::size_t nplanes = std::size_t(solParam[3]);
434 G4bool genericPoly =
false;
435 if(solParam.size() == 4 + nplanes * 3)
436 {
437 genericPoly = false;
438 }
439 else if(solParam.size() == 4 + nplanes * 2)
440 {
441 genericPoly = true;
442 }
443 else
444 {
445 G4String Err1 =
"Solid type " + stype +
" should have ";
447 " (Z,Rmin,Rmax)\n";
450 G4String Err4 =
" (RZ corners) parameters,\n";
453 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
454 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
456 return nullptr;
457 }
458
459 if(!genericPoly)
460 {
461 std::vector<G4double>* z_p = new std::vector<G4double>;
462 std::vector<G4double>* rmin_p = new std::vector<G4double>;
463 std::vector<G4double>* rmax_p = new std::vector<G4double>;
464 for(std::size_t ii = 0; ii < nplanes; ++ii)
465 {
466 (*z_p).push_back(solParam[4 + 3 * ii]);
467 (*rmin_p).push_back(solParam[4 + 3 * ii + 1]);
468 (*rmax_p).push_back(solParam[4 + 3 * ii + 2]);
469 }
471 if(std::fabs(phiTotal - twopi) < angularTolerance)
472 {
473 phiTotal = twopi;
474 }
476 (
G4int)nplanes, &((*z_p)[0]), &((*rmin_p)[0]),
477 &((*rmax_p)[0]));
478 }
479 else
480 {
481 std::vector<G4double>* R_c = new std::vector<G4double>;
482 std::vector<G4double>* Z_c = new std::vector<G4double>;
483 for(std::size_t ii = 0; ii < nplanes; ++ii)
484 {
485 (*R_c).push_back(solParam[4 + 2 * ii]);
486 (*Z_c).push_back(solParam[4 + 2 * ii + 1]);
487 }
489 if(std::fabs(phiTotal - twopi) < angularTolerance)
490 {
491 phiTotal = twopi;
492 }
494 (
G4int)nplanes, &((*R_c)[0]), &((*Z_c)[0]));
495 }
496 }
497 else if(stype == "ELLIPTICALTUBE")
498 {
501 }
502 else if(stype == "ELLIPSOID")
503 {
505 solid =
new G4Ellipsoid(sname, solParam[0], solParam[1], solParam[2],
506 solParam[3], solParam[4]);
507 }
508 else if(stype == "ELLIPTICALCONE")
509 {
512 solParam[3]);
513 }
514 else if(stype == "HYPE")
515 {
517 solid =
new G4Hype(sname, solParam[0], solParam[1], solParam[2],
518 solParam[3], solParam[4]);
519 }
520 else if(stype == "TET")
521 {
527 solid =
new G4Tet(sname, anchor, p2, p3, p4);
528 }
529 else if(stype == "TWISTEDBOX")
530 {
532 solid =
new G4TwistedBox(sname, solParam[0], solParam[1], solParam[2],
533 solParam[3]);
534 }
535 else if(stype == "TWISTEDTRAP")
536 {
538 solid =
539 new G4TwistedTrap(sname, solParam[0], solParam[1], solParam[2],
540 solParam[3], solParam[4], solParam[5], solParam[6],
541 solParam[7], solParam[8], solParam[9], solParam[10]);
542 }
543 else if(stype == "TWISTEDTRD")
544 {
546 solid =
new G4TwistedTrd(sname, solParam[0], solParam[1], solParam[2],
547 solParam[3], solParam[4], solParam[5]);
548 }
549 else if(stype == "SCALED")
550 {
552 if(tgrSol == nullptr)
553 {
554 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
556 return nullptr;
557 }
561 }
562 else if(stype == "TWISTEDTUBS")
563 {
566 if(std::fabs(phiTotal - twopi) < angularTolerance)
567 {
568 phiTotal = twopi;
569 }
570 solid =
new G4TwistedTubs(sname, solParam[0], solParam[1], solParam[2],
571 solParam[3], phiTotal);
572 }
573 else if(stype == "TESSELLATED")
574 {
580
581 for(
G4int ii = 0; ii < nFacets; ++ii)
582 {
584 if(
G4int(solParam.size()) < jj + nPoints * 3 + 2)
585 {
586 G4String Err1 =
"Too small number of parameters in tesselated solid, "
587 "it should be at least " +
590 G4String Err3 =
" number of parameters is " +
592 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
593 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
595 return nullptr;
596 }
597
598 if(nPoints == 3)
599 {
600 G4ThreeVector pt0(solParam[jj + 2], solParam[jj + 3], solParam[jj + 4]);
601 G4ThreeVector vt1(solParam[jj + 5], solParam[jj + 6], solParam[jj + 7]);
603 solParam[jj + 10]);
605 if(solParam[jj + 11] == 0)
606 {
608 }
609 else if(solParam[jj + 11] == 1)
610 {
612 }
613 else
614 {
615 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it "
616 "should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
619 G4String Err3 =
" vertex type is " +
621 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
622 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
624 return nullptr;
625 }
627 }
628 else if(nPoints == 4)
629 {
630 G4ThreeVector pt0(solParam[jj + 2], solParam[jj + 3], solParam[jj + 4]);
631 G4ThreeVector vt1(solParam[jj + 5], solParam[jj + 6], solParam[jj + 7]);
633 solParam[jj + 10]);
635 solParam[jj + 13]);
637 if(solParam[jj + 14] == 0)
638 {
640 }
641 else if(solParam[jj + 14] == 1)
642 {
644 }
645 else
646 {
647 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it "
648 "should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
651 G4String Err3 =
" vertex type is " +
653 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
654 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
656 return nullptr;
657 }
659 }
660 else
661 {
663 "Wrong number of points in tesselated solid, it should be 3 or 4";
666 G4String Err3 =
" number of points is " +
668 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
669 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
671 return nullptr;
672 }
673
675 jj += nPoints * 3 + 2;
676 }
677 }
678 else if(stype == "EXTRUDED")
679 {
680 std::vector<G4TwoVector> polygonList;
681 std::vector<G4ExtrudedSolid::ZSection> zsectionList;
684 G4int nMax = nPolygons * 2 + 1;
685 for(; ii < nMax; ii += 2)
686 {
687 polygonList.push_back(
G4TwoVector(solParam[ii], solParam[ii + 1]));
688 }
690 nMax = nPolygons * 2 + nZSections * 4 + 2;
691 ++ii;
692 for(; ii < nMax; ii += 4)
693 {
694 G4TwoVector offset(solParam[ii + 1], solParam[ii + 2]);
695 zsectionList.push_back(
697 }
699 }
700 else if(stype.substr(0, 7) == "Boolean")
701 {
703 if(solb == nullptr)
704 {
705 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
707 return nullptr;
708 }
713 sol->GetRelativeRotMatName());
715
716 if(stype == "Boolean_UNION")
717 {
718 solid =
new G4UnionSolid(sname, sol1, sol2, relRotMat, relPlace);
719 }
720 else if(stype == "Boolean_SUBTRACTION")
721 {
723 }
724 else if(stype == "Boolean_INTERSECTION")
725 {
727 }
728 else
729 {
730 G4String ErrMessage =
"Unknown Boolean type " + stype;
731 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
733 return nullptr;
734 }
735 }
736 else if(stype == "MULTIUNION")
737 {
739 if(tgrSol == nullptr)
740 {
741 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
743 return nullptr;
744 }
745
750
751 for (
G4int i=0; i<nsol; ++i)
752 {
756 }
758 solid =
dynamic_cast<G4VSolid*
>(solidu);
759 }
760 else
761 {
763 "Solids of type " + stype + " not implemented yet, sorry...";
764 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"NotImplemented",
766 return nullptr;
767 }
768
769#ifdef G4VERBOSE
771 {
772 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid()" <<
G4endl
773 << " Created solid " << sname << " of type "
775 }
776#endif
777
778#ifdef G4VERBOSE
780 {
781 G4cout <<
" Constructing new G4Solid: " << *solid <<
G4endl;
782 }
783#endif
784
785 return solid;
786}
CLHEP::Hep2Vector G4TwoVector
G4double GetAngularTolerance() const
void AddNode(G4VSolid &solid, const G4Transform3D &trans)
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
const G4tgrSolid * GetSolid(G4int ii) const
const G4Transform3D GetTransformation(G4int ii) const
const G4Scale3D GetScale3d() const
const G4tgrSolid * GetOrigSolid() const