202{
205
206 if(sol == nullptr)
207 {
208 return nullptr;
209 }
210
211#ifdef G4VERBOSE
213 {
214 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid():" <<
G4endl
215 <<
" SOLID = " << sol <<
G4endl <<
" " << sol->GetName()
216 <<
" of type " << sol->GetType() <<
G4endl;
217 }
218#endif
219
220
222 if(solid != nullptr)
223 {
224 return solid;
225 }
226
227
228
229#ifdef G4VERBOSE
231 {
232 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid() - "
233 << sol->GetSolidParams().size() <<
G4endl;
234 }
235#endif
236
237 std::vector<G4double> solParam;
238
239
240
241 if(sol->GetSolidParams().size() == 1)
242 {
243 solParam = *sol->GetSolidParams()[0];
244 }
245
246
249
250 if(stype == "BOX")
251 {
253 solid =
new G4Box(sname, solParam[0], solParam[1], solParam[2]);
254 }
255 else if(stype == "TUBE")
256 {
258 solid =
new G4Tubs(sname, solParam[0], solParam[1], solParam[2], 0. * deg,
259 360. * deg);
260 }
261 else if(stype == "TUBS")
262 {
265 if(std::fabs(phiDelta - twopi) < angularTolerance)
266 {
267 phiDelta = twopi;
268 }
269 solid =
new G4Tubs(sname, solParam[0], solParam[1], solParam[2],
270 solParam[3], phiDelta);
271 }
272 else if(stype == "TRAP")
273 {
274 if(solParam.size() == 11)
275 {
276 solid =
new G4Trap(sname, solParam[0], solParam[1], solParam[2],
277 solParam[3], solParam[4], solParam[5], solParam[6],
278 solParam[7], solParam[8], solParam[9], solParam[10]);
279 }
280 else if(solParam.size() == 4)
281 {
282 solid =
new G4Trap(sname, solParam[0], solParam[1] / deg,
283 solParam[2] / deg, solParam[3]);
284 }
285 else
286 {
287 G4String ErrMessage1 =
"Solid type " + stype;
288 G4String ErrMessage2 =
" should have 11 or 4 parameters,\n";
291 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 +
" !";
292 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
294 return 0;
295 }
296 }
297 else if(stype == "TRD")
298 {
300 solid =
new G4Trd(sname, solParam[0], solParam[1], solParam[2], solParam[3],
301 solParam[4]);
302 }
303 else if(stype == "PARA")
304 {
306 solid =
new G4Para(sname, solParam[0], solParam[1], solParam[2],
307 solParam[3], solParam[4], solParam[5]);
308 }
309 else if(stype == "CONE")
310 {
312 solid =
new G4Cons(sname, solParam[0], solParam[1], solParam[2],
313 solParam[3], solParam[4], 0., 360. * deg);
314 }
315 else if(stype == "CONS")
316 {
319 if(std::fabs(phiDelta - twopi) < angularTolerance)
320 {
321 phiDelta = twopi;
322 }
323 solid =
new G4Cons(sname, solParam[0], solParam[1], solParam[2],
324 solParam[3], solParam[4], solParam[5], phiDelta);
325 }
326 else if(stype == "SPHERE")
327 {
330 if(std::fabs(phiDelta - twopi) < angularTolerance)
331 {
332 phiDelta = twopi;
333 }
335 if(std::fabs(thetaDelta - pi) < angularTolerance)
336 {
338 }
339 solid =
new G4Sphere(sname, solParam[0], solParam[1], solParam[2], phiDelta,
340 solParam[4], thetaDelta);
341 }
342 else if(stype == "ORB")
343 {
345 solid =
new G4Orb(sname, solParam[0]);
346 }
347 else if(stype == "TORUS")
348 {
351 if(std::fabs(phiDelta - twopi) < angularTolerance)
352 {
353 phiDelta = twopi;
354 }
355 solid =
new G4Torus(sname, solParam[0], solParam[1], solParam[2],
356 solParam[3], phiDelta);
357 }
358 else if(stype == "POLYCONE")
359 {
360 std::size_t nplanes = std::size_t(solParam[2]);
361 G4bool genericPoly =
false;
362 if(solParam.size() == 3 + nplanes * 3)
363 {
364 genericPoly = false;
365 }
366 else if(solParam.size() == 3 + nplanes * 2)
367 {
368 genericPoly = true;
369 }
370 else
371 {
372 G4String Err1 =
"Solid type " + stype +
" should have ";
374 " (Z,Rmin,Rmax)\n";
377 G4String Err4 =
" (RZ corners) parameters,\n";
380 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
381 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
383 return nullptr;
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(std::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)
399 {
400 phiTotal = twopi;
401 }
402 solid =
new G4Polycone(sname, solParam[0], phiTotal,
403 nplanes,
404 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
405 }
406 else
407 {
408 std::vector<G4double>* R_c = new std::vector<G4double>;
409 std::vector<G4double>* Z_c = new std::vector<G4double>;
410 for(size_t ii = 0; ii < nplanes; ii++)
411 {
412 (*R_c).push_back(solParam[3 + 2 * ii]);
413 (*Z_c).push_back(solParam[3 + 2 * ii + 1]);
414 }
416 if(std::fabs(phiTotal - twopi) < angularTolerance)
417 {
418 phiTotal = twopi;
419 }
420 solid =
422 nplanes,
423 &((*R_c)[0]), &((*Z_c)[0]));
424 }
425 }
426 else if(stype == "POLYHEDRA")
427 {
428 std::size_t nplanes = std::size_t(solParam[3]);
429 G4bool genericPoly =
false;
430 if(solParam.size() == 4 + nplanes * 3)
431 {
432 genericPoly = true;
433 }
434 else if(solParam.size() == 4 + nplanes * 2)
435 {
436 genericPoly = false;
437 }
438 else
439 {
440 G4String Err1 =
"Solid type " + stype +
" should have ";
442 " (Z,Rmin,Rmax)\n";
445 G4String Err4 =
" (RZ corners) parameters,\n";
448 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 +
" !";
449 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
451 return nullptr;
452 }
453
454 if(!genericPoly)
455 {
456 std::vector<G4double>* z_p = new std::vector<G4double>;
457 std::vector<G4double>* rmin_p = new std::vector<G4double>;
458 std::vector<G4double>* rmax_p = new std::vector<G4double>;
459 for(std::size_t ii = 0; ii < nplanes; ++ii)
460 {
461 (*z_p).push_back(solParam[4 + 3 * ii]);
462 (*rmin_p).push_back(solParam[4 + 3 * ii + 1]);
463 (*rmax_p).push_back(solParam[4 + 3 * ii + 2]);
464 }
466 if(std::fabs(phiTotal - twopi) < angularTolerance)
467 {
468 phiTotal = twopi;
469 }
471 nplanes, &((*z_p)[0]), &((*rmin_p)[0]),
472 &((*rmax_p)[0]));
473 }
474 else
475 {
476 std::vector<G4double>* R_c = new std::vector<G4double>;
477 std::vector<G4double>* Z_c = new std::vector<G4double>;
478 for(std::size_t ii = 0; ii < nplanes; ++ii)
479 {
480 (*R_c).push_back(solParam[4 + 2 * ii]);
481 (*Z_c).push_back(solParam[4 + 2 * ii + 1]);
482 }
484 if(std::fabs(phiTotal - twopi) < angularTolerance)
485 {
486 phiTotal = twopi;
487 }
489 nplanes, &((*R_c)[0]), &((*Z_c)[0]));
490 }
491 }
492 else if(stype == "ELLIPTICALTUBE")
493 {
496 }
497 else if(stype == "ELLIPSOID")
498 {
500 solid =
new G4Ellipsoid(sname, solParam[0], solParam[1], solParam[2],
501 solParam[3], solParam[4]);
502 }
503 else if(stype == "ELLIPTICALCONE")
504 {
507 solParam[3]);
508 }
509 else if(stype == "HYPE")
510 {
512 solid =
new G4Hype(sname, solParam[0], solParam[1], solParam[2],
513 solParam[3], solParam[4]);
514 }
515 else if(stype == "TET")
516 {
522 solid =
new G4Tet(sname, anchor, p2, p3, p4);
523 }
524 else if(stype == "TWISTEDBOX")
525 {
527 solid =
new G4TwistedBox(sname, solParam[0], solParam[1], solParam[2],
528 solParam[3]);
529 }
530 else if(stype == "TWISTEDTRAP")
531 {
533 solid =
534 new G4TwistedTrap(sname, solParam[0], solParam[1], solParam[2],
535 solParam[3], solParam[4], solParam[5], solParam[6],
536 solParam[7], solParam[8], solParam[9], solParam[10]);
537 }
538 else if(stype == "TWISTEDTRD")
539 {
541 solid =
new G4TwistedTrd(sname, solParam[0], solParam[1], solParam[2],
542 solParam[3], solParam[4], solParam[5]);
543 }
544 else if(stype == "TWISTEDTUBS")
545 {
548 if(std::fabs(phiTotal - twopi) < angularTolerance)
549 {
550 phiTotal = twopi;
551 }
552 solid =
new G4TwistedTubs(sname, solParam[0], solParam[1], solParam[2],
553 solParam[3], phiTotal);
554 }
555 else if(stype == "TESSELLATED")
556 {
562
563 for(
G4int ii = 0; ii < nFacets; ++ii)
564 {
566 if(
G4int(solParam.size()) < jj + nPoints * 3 + 2)
567 {
568 G4String Err1 =
"Too small number of parameters in tesselated solid, "
569 "it should be at least " +
572 G4String Err3 =
" number of parameters is " +
574 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
575 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
577 return nullptr;
578 }
579
580 if(nPoints == 3)
581 {
582 G4ThreeVector pt0(solParam[jj + 2], solParam[jj + 3], solParam[jj + 4]);
583 G4ThreeVector vt1(solParam[jj + 5], solParam[jj + 6], solParam[jj + 7]);
585 solParam[jj + 10]);
587 if(solParam[jj + 11] == 0)
588 {
590 }
591 else if(solParam[jj + 11] == 1)
592 {
594 }
595 else
596 {
597 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it "
598 "should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
601 G4String Err3 =
" vertex type is " +
603 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
604 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
606 return nullptr;
607 }
609 }
610 else if(nPoints == 4)
611 {
612 G4ThreeVector pt0(solParam[jj + 2], solParam[jj + 3], solParam[jj + 4]);
613 G4ThreeVector vt1(solParam[jj + 5], solParam[jj + 6], solParam[jj + 7]);
615 solParam[jj + 10]);
617 solParam[jj + 13]);
619 if(solParam[jj + 14] == 0)
620 {
622 }
623 else if(solParam[jj + 14] == 1)
624 {
626 }
627 else
628 {
629 G4String Err1 =
"Wrong number of vertex type in tesselated solid, it "
630 "should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
633 G4String Err3 =
" vertex type is " +
635 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
636 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
638 return nullptr;
639 }
641 }
642 else
643 {
645 "Wrong number of points in tesselated solid, it should be 3 or 4";
648 G4String Err3 =
" number of points is " +
650 G4String ErrMessage = Err1 + Err2 + Err3 +
" !";
651 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
653 return nullptr;
654 }
655
657 jj += nPoints * 3 + 2;
658 }
659 }
660 else if(stype == "EXTRUDED")
661 {
662 std::vector<G4TwoVector> polygonList;
663 std::vector<G4ExtrudedSolid::ZSection> zsectionList;
666 G4int nMax = nPolygons * 2 + 1;
667 for(; ii < nMax; ii += 2)
668 {
669 polygonList.push_back(
G4TwoVector(solParam[ii], solParam[ii + 1]));
670 }
672 nMax = nPolygons * 2 + nZSections * 4 + 2;
673 ++ii;
674 for(; ii < nMax; ii += 4)
675 {
676 G4TwoVector offset(solParam[ii + 1], solParam[ii + 2]);
677 zsectionList.push_back(
679 }
681 }
682 else if(stype.substr(0, 7) == "Boolean")
683 {
685 if(solb == nullptr)
686 {
687 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
689 return nullptr;
690 }
695 sol->GetRelativeRotMatName());
697
698 if(stype == "Boolean_UNION")
699 {
700 solid =
new G4UnionSolid(sname, sol1, sol2, relRotMat, relPlace);
701 }
702 else if(stype == "Boolean_SUBTRACTION")
703 {
705 }
706 else if(stype == "Boolean_INTERSECTION")
707 {
709 }
710 else
711 {
712 G4String ErrMessage =
"Unknown Boolean type " + stype;
713 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"InvalidSetup",
715 return nullptr;
716 }
717 }
718 else
719 {
721 "Solids of type " + stype + " not implemented yet, sorry...";
722 G4Exception(
"G4tgbVolume::FindOrConstructG4Solid()",
"NotImplemented",
724 return nullptr;
725 }
726
727#ifdef G4VERBOSE
729 {
730 G4cout <<
" G4tgbVolume::FindOrConstructG4Solid()" <<
G4endl
731 << " Created solid " << sname << " of type "
733 }
734#endif
735
736#ifdef G4VERBOSE
738 {
739 G4cout <<
" Constructing new G4Solid: " << *solid <<
G4endl;
740 }
741#endif
742
743 return solid;
744}
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