Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4tgbVolume.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29//
30// class G4tgbVolume
31
32// History:
33// - Created. P.Arce, CIEMAT (November 2007)
34// -------------------------------------------------------------------------
35
36#include "G4tgbVolume.hh"
37
39#include "G4SystemOfUnits.hh"
40#include "G4tgbVolumeMgr.hh"
41#include "G4tgbMaterialMgr.hh"
46
47#include "G4tgrSolid.hh"
48#include "G4tgrSolidBoolean.hh"
49#include "G4tgrVolume.hh"
52#include "G4tgrVolumeMgr.hh"
53#include "G4tgrPlace.hh"
54#include "G4tgrPlaceSimple.hh"
55#include "G4tgrPlaceDivRep.hh"
57#include "G4tgrUtils.hh"
58
59#include "G4VSolid.hh"
60#include "G4UnionSolid.hh"
61#include "G4SubtractionSolid.hh"
63#include "G4LogicalVolume.hh"
64#include "G4VPhysicalVolume.hh"
65#include "G4PVPlacement.hh"
66#include "G4PVDivision.hh"
67#include "G4PVReplica.hh"
68#include "G4PVParameterised.hh"
69#include "G4Box.hh"
70#include "G4Tubs.hh"
71#include "G4Cons.hh"
72#include "G4Trap.hh"
73#include "G4Sphere.hh"
74#include "G4Orb.hh"
75#include "G4Trd.hh"
76#include "G4Para.hh"
77#include "G4Torus.hh"
78#include "G4Hype.hh"
79#include "G4Polycone.hh"
80#include "G4Polyhedra.hh"
81#include "G4EllipticalTube.hh"
82#include "G4Ellipsoid.hh"
83#include "G4EllipticalCone.hh"
84#include "G4Hype.hh"
85#include "G4Tet.hh"
86#include "G4TwistedBox.hh"
87#include "G4TwistedTrap.hh"
88#include "G4TwistedTrd.hh"
89#include "G4TwistedTubs.hh"
90#include "G4AssemblyVolume.hh"
91#include "G4BREPSolidBox.hh"
93#include "G4BREPSolidCone.hh"
94#include "G4BREPSolidSphere.hh"
95#include "G4BREPSolidTorus.hh"
96#include "G4BREPSolidPCone.hh"
99#include "G4TessellatedSolid.hh"
100#include "G4TriangularFacet.hh"
101#include "G4QuadrangularFacet.hh"
102#include "G4ExtrudedSolid.hh"
103
104#include "G4VisExtent.hh"
105#include "G4Material.hh"
106#include "G4RotationMatrix.hh"
107#include "G4ReflectionFactory.hh"
108
109#include "G4VisAttributes.hh"
110#include "G4RegionStore.hh"
111#include "G4tgrMessenger.hh"
112#include "G4UIcommand.hh"
113#include "G4GeometryTolerance.hh"
114
115//-------------------------------------------------------------------
117 : theTgrVolume(0), theG4AssemblyVolume(0)
118{
119}
120
121
122//-------------------------------------------------------------------
124{
125}
126
127
128//-------------------------------------------------------------------
130{
131 theTgrVolume = vol;
132 theG4AssemblyVolume = 0;
133}
134
135
136//-------------------------------------------------------------------
138 const G4LogicalVolume* parentLV )
139{
140#ifdef G4VERBOSE
142 {
143 G4cout << G4endl << "@@@ G4tgbVolume::ConstructG4Volumes - " << GetName() << G4endl;
144 if( place && parentLV ) G4cout << " place in LV " << parentLV->GetName() << G4endl;
145 }
146#endif
148 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( GetName() );
149 G4bool bFirstCopy = false;
150 if( logvol == 0 )
151 {
152 bFirstCopy = true;
153 if( theTgrVolume->GetType() != "VOLDivision" )
154 {
155 //--- If first time build solid and LogVol
156 G4VSolid* solid = FindOrConstructG4Solid( theTgrVolume->GetSolid() );
157 if( solid != 0 ) // for G4AssemblyVolume it is 0
158 {
159 g4vmgr->RegisterMe( solid );
160 logvol = ConstructG4LogVol( solid );
161 g4vmgr->RegisterMe( logvol );
162 g4vmgr->RegisterChildParentLVs( logvol, parentLV );
163 }
164 else
165 {
166 return;
167 }
168 }
169 else
170 {
171 return;
172 }
173 }
174 //--- Construct PhysVol
175 G4VPhysicalVolume* physvol = ConstructG4PhysVol( place, logvol, parentLV );
176 if( physvol != 0 ) // 0 for G4AssemblyVolumes
177 {
178 g4vmgr->RegisterMe( physvol );
179
180 if( logvol == 0 ) // case of divisions
181 {
182 logvol = physvol->GetLogicalVolume();
183 }
184 }
185 else
186 {
187 return;
188 }
189
190 //--- If first copy build children placements in this LogVol
191 if(bFirstCopy)
192 {
193 std::pair<G4mmapspl::iterator, G4mmapspl::iterator> children
195 G4mmapspl::iterator cite;
196 for( cite = children.first; cite != children.second; cite++ )
197 {
198 //----- Call G4tgrPlace ->constructG4Volumes
199 //---- find G4tgbVolume corresponding to the G4tgrVolume
200 // pointed by G4tgrPlace
201 G4tgrPlace* pl = const_cast<G4tgrPlace*>((*cite).second);
202 G4tgbVolume* svol = g4vmgr->FindVolume( pl->GetVolume()->GetName() );
203 //--- find copyNo
204#ifdef G4VERBOSE
206 {
207 G4cout << " G4tgbVolume::ConstructG4Volumes - construct daughter " << pl->GetVolume()->GetName() << " # " << pl->GetCopyNo() << G4endl;
208 }
209#endif
210 svol->ConstructG4Volumes( pl, logvol );
211 }
212 }
213
214}
215
216
217
218//-------------------------------------------------------------------
220{
221 G4double angularTolerance = G4GeometryTolerance::GetInstance()
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()
232 << G4endl;
233 }
234#endif
235
236 //----- Check if solid exists already
238 ->FindG4Solid( sol->GetName() );
239 if( solid ) { return solid; }
240
241 // Give 'sol' as Boolean solids needs to call this method twice
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 // In case of BOOLEAN solids, solidParams are taken from components
254
255 if( sol->GetSolidParams().size() == 1)
256 {
257 solParam = * sol->GetSolidParams()[ 0 ];
258 }
259
260 //----------- instantiate the appropiate G4VSolid type
261 G4String stype = sol->GetType();
262 G4String sname = sol->GetName();
263
264 if( stype == "BOX" )
265 {
266 CheckNoSolidParams( stype, 3, solParam.size() );
267 solid = new G4Box( sname, solParam[0], solParam[1], solParam[2] );
268
269 }
270 else if( stype == "TUBE" )
271 {
272 CheckNoSolidParams( stype, 3, solParam.size() );
273 solid = new G4Tubs( sname, solParam[0], solParam[1], solParam[2],
274 0.*deg, 360.*deg );
275 }
276 else if( stype == "TUBS" )
277 {
278 CheckNoSolidParams( stype, 5, solParam.size() );
279 G4double phiDelta = solParam[4];
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 "
302 + G4UIcommand::ConvertToString(G4int(solParam.size()));
303 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 + " !";
304 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
305 "InvalidSetup", FatalException, ErrMessage);
306 return 0;
307 }
308
309 }
310 else if( stype == "TRD" )
311 {
312 CheckNoSolidParams( stype, 5, solParam.size() );
313 solid = new G4Trd( sname, solParam[0], solParam[1], solParam[2],
314 solParam[3], solParam[4] );
315 }
316 else if( stype == "PARA" )
317 {
318 CheckNoSolidParams( stype, 6, solParam.size() );
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 {
324 CheckNoSolidParams( stype, 5, solParam.size() );
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 {
330 CheckNoSolidParams( stype, 7, solParam.size() );
331 G4double phiDelta = solParam[6];
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 {
338 CheckNoSolidParams( stype, 6, solParam.size() );
339 G4double phiDelta = solParam[3];
340 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
341 G4double thetaDelta = solParam[5];
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 {
348 CheckNoSolidParams( stype, 1, solParam.size() );
349 solid = new G4Orb( sname, solParam[0] );
350 }
351 else if( stype == "TORUS" )
352 {
353 CheckNoSolidParams( stype, 5, solParam.size() );
354 G4double phiDelta = solParam[4];
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 ";
374 G4String Err2 = G4UIcommand::ConvertToString(G4int(3+nplanes*3))
375 + " (Z,Rmin,Rmax)\n";
376 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(3+nplanes*2));
377 G4String Err4 = " (RZ corners) parameters,\n";
378 G4String Err5 = "and it has "
379 + G4UIcommand::ConvertToString(G4int(solParam.size()));
380 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !";
381 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
382 "InvalidSetup", FatalException, ErrMessage);
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 }
397 G4double phiTotal = solParam[1];
398 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
399 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi
400 nplanes, // sections
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 }
412 G4double phiTotal = solParam[1];
413 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
414 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi
415 nplanes, // sections
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 ";
435 G4String Err2 = G4UIcommand::ConvertToString(G4int(4+nplanes*3))
436 + " (Z,Rmin,Rmax)\n";
437 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(4+nplanes*2));
438 G4String Err4 = " (RZ corners) parameters,\n";
439 G4String Err5 = "and it has "
440 + G4UIcommand::ConvertToString(G4int(solParam.size()));
441 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !";
442 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
443 "InvalidSetup", FatalException, ErrMessage);
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 }
458 G4double phiTotal = solParam[1];
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 }
473 G4double phiTotal = solParam[1];
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 {
482 CheckNoSolidParams( stype, 3, solParam.size() );
483 solid = new G4EllipticalTube( sname, solParam[0], solParam[1], solParam[2]);
484 }
485 else if( stype == "ELLIPSOID" )
486 {
487 CheckNoSolidParams( stype, 5, solParam.size() );
488 solid = new G4Ellipsoid( sname, solParam[0], solParam[1], solParam[2],
489 solParam[3], solParam[4] );
490 }
491 else if( stype == "ELLIPTICALCONE" )
492 {
493 CheckNoSolidParams( stype, 4, solParam.size() );
494 solid = new G4EllipticalCone( sname, solParam[0], solParam[1],
495 solParam[2], solParam[3] );
496 }
497 else if( stype == "HYPE" )
498 {
499 CheckNoSolidParams( stype, 5, solParam.size() );
500 solid = new G4Hype( sname, solParam[0], solParam[1], solParam[2],
501 solParam[3], solParam[4] );
502 }
503 else if( stype == "TET" )
504 {
505 CheckNoSolidParams( stype, 12, solParam.size() );
506 G4ThreeVector anchor(solParam[0], solParam[1], solParam[2]);
507 G4ThreeVector p2(solParam[3], solParam[4], solParam[5]);
508 G4ThreeVector p3(solParam[6], solParam[7], solParam[8]);
509 G4ThreeVector p4(solParam[9], solParam[10], solParam[11]);
510 solid = new G4Tet( sname, anchor, p2, p3, p4 );
511 }
512 else if( stype == "TWISTEDBOX" )
513 {
514 CheckNoSolidParams( stype, 4, solParam.size() );
515 solid = new G4TwistedBox( sname, solParam[0], solParam[1],
516 solParam[2], solParam[3]);
517 }
518 else if( stype == "TWISTEDTRAP" )
519 {
520 CheckNoSolidParams( stype, 11, solParam.size() );
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 {
527 CheckNoSolidParams( stype, 6, solParam.size() );
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 {
533 CheckNoSolidParams( stype, 5, solParam.size() );
534 G4double phiTotal = solParam[4];
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" ) // EntityType is = "Closed_Shell"
540 {
541 CheckNoSolidParams( stype, 24, solParam.size() );
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" ) // EntityType is = "Closed_Shell"
554 {
555 CheckNoSolidParams( stype, 11, solParam.size() );
556 solid = new G4BREPSolidCylinder( sname,
557 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
558 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
559 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
560 solParam[9], solParam[10] );
561 }
562 else if( stype == "BREPCONE" ) // EntityType is = "Closed_Shell"
563 {
564 CheckNoSolidParams( stype, 12, solParam.size() );
565 solid = new G4BREPSolidCone( sname,
566 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
567 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
568 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
569 solParam[9], solParam[10], solParam[11] );
570 }
571 else if( stype == "BREPSPHERE" ) // EntityType is = "Closed_Shell"
572 {
573 CheckNoSolidParams( stype, 10, solParam.size() );
574 solid = new G4BREPSolidSphere( sname,
575 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
576 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
577 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
578 solParam[9] );
579
580 }
581 else if( stype == "BREPTORUS" ) // EntityType is = "Closed_Shell"
582 {
583 CheckNoSolidParams( stype, 11, solParam.size() );
584 solid = new G4BREPSolidTorus( sname,
585 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
586 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
587 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
588 solParam[9], solParam[10] );
589 }
590 else if( stype == "BREPPCONE" ) // EntityType is = "Closed_Shell"
591 {
592 size_t nplanes = size_t(solParam[2]);
593 CheckNoSolidParams( stype, 4+3*nplanes, solParam.size() );
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 }
603 G4double phiTotal = solParam[1];
604 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
605 CheckNoSolidParams( stype, 12, solParam.size() );
606 solid = new G4BREPSolidPCone( sname, solParam[0], phiTotal, // start,dph
607 nplanes, // sections
608 solParam[3], // z_start
609 &((*z_p)[0]), &((*rmin_p)[0]),
610 &((*rmax_p)[0]));
611 }
612 else if( stype == "BREPPOLYHEDRA" ) // EntityType is = "Closed_Shell"
613 {
614 size_t nplanes = size_t(solParam[3]);
615 CheckNoSolidParams( stype, 5+3*nplanes, solParam.size() );
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 }
625 G4double phiTotal = solParam[1];
626 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
627 CheckNoSolidParams( stype, 12, solParam.size() );
628 solid = new G4BREPSolidPolyhedra( sname, solParam[0], phiTotal, // start,dph
629 G4int(solParam[2]), // sides
630 nplanes, // sections
631 solParam[4], // z_start
632 &((*z_p)[0]), &((*rmin_p)[0]),
633 &((*rmax_p)[0]));
634 }
635 else if( stype == "BREPOPENPCONE" ) // EntityType is = "Closed_Shell"
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 }
647 G4double phiTotal = solParam[1];
648 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
649 CheckNoSolidParams( stype, 12, solParam.size() );
650 solid = new G4BREPSolidOpenPCone( sname, solParam[0], phiTotal, // start,dph
651 nplanes, // sections
652 solParam[3], // z_start
653 &((*z_p)[0]), &((*rmin_p)[0]),
654 &((*rmax_p)[0]));
655 }
656 else if( stype == "TESSELLATED" )
657 {
658 G4int nFacets = G4int(solParam[0]);
659 G4int jj = 0;
660 solid = new G4TessellatedSolid(sname);
661 G4TessellatedSolid* solidTS = (G4TessellatedSolid*)(solid);
662 G4VFacet* facet=0;
663
664 for( G4int ii = 0; ii < nFacets; ii++){
665 G4int nPoints = G4int(solParam[jj+1]);
666 if( G4int(solParam.size()) < jj + nPoints*3 + 2 ) {
667 G4String Err1 = "Too small number of parameters in tesselated solid, it should be at least " + G4UIcommand::ConvertToString(jj + nPoints*3 + 2 );
668 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(ii);
669 G4String Err3 = " number of parameters is " + G4UIcommand::ConvertToString(G4int(solParam.size()));
670 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
671 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
672 "InvalidSetup", FatalException, ErrMessage);
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]);
681 G4FacetVertexType vertexType = ABSOLUTE;
682 if( solParam[jj+11] == 0 )
683 {
684 vertexType = ABSOLUTE;
685 }
686 else if( solParam[jj+11] == 1 )
687 {
688 vertexType = RELATIVE;
689 }
690 else
691 {
692 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
693 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
694 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+11]);
695 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
696 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
697 "InvalidSetup", FatalException, ErrMessage);
698 return 0;
699 }
700 facet = new G4TriangularFacet( pt0, vt1, vt2, vertexType );
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]);
708 G4FacetVertexType vertexType = ABSOLUTE;
709 if( solParam[jj+14] == 0 )
710 {
711 vertexType = ABSOLUTE;
712 }
713 else if( solParam[jj+14] == 1 )
714 {
715 vertexType = RELATIVE;
716 }
717 else
718 {
719 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
720 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
721 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+14]);
722 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
723 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
724 "InvalidSetup", FatalException, ErrMessage);
725 return 0;
726 }
727 facet = new G4QuadrangularFacet( pt0, vt1, vt2, vt3, vertexType );
728 }
729 else
730 {
731 G4String Err1 = "Wrong number of points in tesselated solid, it should be 3 or 4";
732 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
733 G4String Err3 = " number of points is " + G4UIcommand::ConvertToString(G4int(nPoints));
734 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
735 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
736 "InvalidSetup", FatalException, ErrMessage);
737 return 0;
738 }
739
740 solidTS->AddFacet( facet );
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;
749 G4int nPolygons = G4int(solParam[0]);
750 G4int ii = 1;
751 G4int nMax = nPolygons*2+1;
752 for( ;ii < nMax; ii+=2 )
753 {
754 polygonList.push_back( G4TwoVector(solParam[ii],solParam[ii+1]) );
755 }
756 G4int nZSections = G4int(solParam[ii]);
757 nMax = nPolygons*2 + nZSections*4 + 2;
758 ii++;
759 for( ; ii < nMax; ii+=4 )
760 {
761 G4TwoVector offset(solParam[ii+1],solParam[ii+2]);
762 zsectionList.push_back( G4ExtrudedSolid::ZSection(solParam[ii],offset,solParam[ii+3]) );
763 }
764 solid = new G4ExtrudedSolid( sname, polygonList, zsectionList );
765
766 }
767 else if( stype.substr(0,7) == "Boolean" )
768 {
769 const G4tgrSolidBoolean* solb = dynamic_cast<const G4tgrSolidBoolean*>(sol);
770 if (!solb)
771 {
772 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
773 "InvalidSetup", FatalException, "Invalid Solid pointer");
774 return 0;
775 }
776 G4VSolid* sol1 = FindOrConstructG4Solid( solb->GetSolid(0));
777 G4VSolid* sol2 = FindOrConstructG4Solid( solb->GetSolid(1));
780 G4ThreeVector relPlace = solb->GetRelativePlace();
781
782 if( stype == "Boolean_UNION" )
783 {
784 solid = new G4UnionSolid( sname, sol1, sol2, relRotMat, relPlace );
785 }
786 else if( stype == "Boolean_SUBTRACTION" )
787 {
788 solid = new G4SubtractionSolid( sname, sol1, sol2, relRotMat, relPlace );
789 }
790 else if( stype == "Boolean_INTERSECTION" )
791 {
792 solid = new G4IntersectionSolid( sname, sol1, sol2, relRotMat, relPlace );
793 }
794 else
795 {
796 G4String ErrMessage = "Unknown Boolean type " + stype;
797 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
798 "InvalidSetup", FatalException, ErrMessage);
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",
807 FatalException, ErrMessage);
808 return 0;
809 }
810
811#ifdef G4VERBOSE
813 {
814 G4cout << " G4tgbVolume::FindOrConstructG4Solid()" << G4endl
815 << " Created solid " << sname
816 << " of type " << solid->GetEntityType() << G4endl;
817 }
818#endif
819
820#ifdef G4VERBOSE
822 {
823 G4cout << " Constructing new G4Solid: "
824 << *solid << G4endl;
825 }
826#endif
827
828 return solid;
829}
830
831//-------------------------------------------------------------------
833 const unsigned int NoParamExpected,
834 const unsigned int NoParam )
835{
836 if( NoParamExpected != NoParam )
837 {
838 G4String Err1 = "Solid type " + solidType + " should have ";
839 G4String Err2 = G4UIcommand::ConvertToString(G4int(NoParamExpected))
840 + " parameters,\n";
841 G4String Err3 = "and it has "
843 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
844 G4Exception("G4tgbVolume::CheckNoSolidParams()", "InvalidSetup",
845 FatalException, ErrMessage);
846 }
847}
848
849
850//-------------------------------------------------------------------
852{
853 G4LogicalVolume* logvol;
854
855#ifdef G4VERBOSE
857 {
858 G4cout << " G4tgbVolume::ConstructG4LogVol() - " << GetName() << G4endl;
859 }
860#endif
861
862 //----------- Get the material first
864 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() );
865 if( mate == 0 )
866 {
867 G4String ErrMessage = "Material not found "
868 + theTgrVolume->GetMaterialName()
869 + " for volume " + GetName() + ".";
870 G4Exception("G4tgbVolume::ConstructG4LogVol()", "InvalidSetup",
871 FatalException, ErrMessage);
872 }
873#ifdef G4VERBOSE
875 {
876 G4cout << " G4tgbVolume::ConstructG4LogVol() -"
877 << " Material constructed: " << mate->GetName() << G4endl;
878 }
879#endif
880
881 //---------- Construct the LV
882 logvol = new G4LogicalVolume( const_cast<G4VSolid*>(solid),
883 const_cast<G4Material*>(mate), GetName() );
884
885#ifdef G4VERBOSE
887 {
888 G4cout << " Constructing new G4LogicalVolume: "
889 << logvol->GetName() << " mate " << mate->GetName() << G4endl;
890 }
891#endif
892
893 //---------- Set visibility and colour
894 if( !GetVisibility() || GetColour()[0] != -1 )
895 {
896 G4VisAttributes* visAtt = new G4VisAttributes();
897#ifdef G4VERBOSE
899 {
900 G4cout << " Constructing new G4VisAttributes: "
901 << *visAtt << G4endl;
902 }
903#endif
904
905 if( !GetVisibility() )
906 {
907 visAtt->SetVisibility( GetVisibility() );
908 }
909 else if( GetColour()[0] != -1 )
910 {
911 // this else should not be necessary, because if the visibility
912 // is set to off, colour should have no effect. But it does not
913 // work: if you set colour and vis off, it is visualized!?!?!?
914
915 const G4double* col = GetColour();
916 if( col[3] == -1. )
917 {
918 visAtt->SetColour( G4Colour(col[0],col[1],col[2]));
919 }
920 else
921 {
922 visAtt->SetColour( G4Colour(col[0],col[1],col[2],col[3]));
923 }
924 }
925 logvol->SetVisAttributes(visAtt);
926 }
927
928#ifdef G4VERBOSE
930 {
931 G4cout << " G4tgbVolume::ConstructG4LogVol() -"
932 << " Created logical volume: " << GetName() << G4endl;
933 }
934#endif
935
936 return logvol;
937}
938
939
940//-------------------------------------------------------------------
943 const G4LogicalVolume* currentLV,
944 const G4LogicalVolume* parentLV )
945{
946 G4VPhysicalVolume* physvol = 0;
947 G4int copyNo;
948
949 //----- Case of placement of top volume
950 if( place == 0 )
951 {
952#ifdef G4VERBOSE
954 {
955 G4cout << " G4tgbVolume::ConstructG4PhysVol() - World: "
956 << GetName() << G4endl;
957 }
958#endif
959 physvol = new G4PVPlacement(0, G4ThreeVector(),
960 const_cast<G4LogicalVolume*>(currentLV),
961 GetName(), 0, false, 0,
962 theTgrVolume->GetCheckOverlaps());
963#ifdef G4VERBOSE
965 {
966 G4cout << " Constructing new : G4PVPlacement "
967 << physvol->GetName() << G4endl;
968 }
969#endif
970 }
971 else
972 {
973 copyNo = place->GetCopyNo();
974
975#ifdef G4VERBOSE
977 {
978 G4cout << " G4tgbVolume::ConstructG4PhysVol() - " << GetName() << G4endl
979 << " inside " << parentLV->GetName() << " copy No: " << copyNo
980 << " of type= " << theTgrVolume->GetType() << G4endl
981 << " placement type= " << place->GetType() << G4endl;
982 }
983#endif
984
985 if( theTgrVolume->GetType() == "VOLSimple" )
986 {
987 //----- Get placement
988#ifdef G4VERBOSE
990 {
991 G4cout << " G4tgbVolume::ConstructG4PhysVol() - Placement type = "
992 << place->GetType() << G4endl;
993 }
994#endif
995
996 //--------------- If it is G4tgrPlaceSimple
997 if( place->GetType() == "PlaceSimple" )
998 {
999 //----- Get rotation matrix
1000 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place;
1001 G4String rmName = placeSimple->GetRotMatName();
1002
1004 ->FindOrBuildG4RotMatrix( rmName );
1005 //----- Place volume in mother
1006 G4double check = (rotmat->colX().cross(rotmat->colY()))*rotmat->colZ();
1007 G4double tol = 1.0e-3;
1008 //---- Check that matrix is ortogonal
1009 if (1-std::abs(check)>tol)
1010 {
1011 G4cerr << " Matrix : " << rmName << " " << rotmat->colX()
1012 << " " << rotmat->colY() << " " << rotmat->colZ() << G4endl
1013 << " product x X y * z = " << check << " x X y "
1014 << rotmat->colX().cross(rotmat->colY()) << G4endl;
1015 G4String ErrMessage = "Rotation is not ortogonal " + rmName + " !";
1016 G4Exception("G4tgbVolume::ConstructG4PhysVol()",
1017 "InvalidSetup", FatalException, ErrMessage);
1018 //---- Check if it is reflection
1019 }
1020 else if (1+check<=tol)
1021 {
1022 G4Translate3D transl = place->GetPlacement();
1023 G4Transform3D trfrm = transl * G4Rotate3D(*rotmat);
1024 physvol = (G4ReflectionFactory::Instance()->Place(trfrm, GetName(),
1025 const_cast<G4LogicalVolume*>(currentLV),
1026 const_cast<G4LogicalVolume*>(parentLV),
1027 false, copyNo, false )).first;
1028 }
1029 else
1030 {
1031#ifdef G4VERBOSE
1033 {
1034 G4cout << "Construction new G4VPhysicalVolume"
1035 << " through G4ReflectionFactory " << GetName()
1036 << " in volume " << parentLV->GetName()
1037 << " copyNo " << copyNo
1038 << " position " << place->GetPlacement()
1039 << " ROT " << rotmat->colX()
1040 << " " << rotmat->colY()
1041 << " " << rotmat->colZ() << G4endl;
1042 }
1043#endif
1044 physvol = new G4PVPlacement( rotmat, place->GetPlacement(),
1045 const_cast<G4LogicalVolume*>(currentLV),
1046 GetName(),
1047 const_cast<G4LogicalVolume*>(parentLV),
1048 false, copyNo,
1049 theTgrVolume->GetCheckOverlaps());
1050 }
1051
1052 //--------------- If it is G4tgrPlaceParam
1053 }
1054 else if( place->GetType() == "PlaceParam" )
1055 {
1057
1058 //----- See what parameterisation type
1059#ifdef G4VERBOSE
1061 {
1062 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1063 << " param: " << GetName() << " in " << parentLV->GetName()
1064 << " param type= " << dp->GetParamType() << G4endl;
1065 }
1066#endif
1067
1069
1070 if( (dp->GetParamType() == "CIRCLE")
1071 || (dp->GetParamType() == "CIRCLE_XY")
1072 || (dp->GetParamType() == "CIRCLE_XZ")
1073 || (dp->GetParamType() == "CIRCLE_YZ") )
1074 {
1075 param = new G4tgbPlaceParamCircle(dp);
1076
1077 }
1078 else if( (dp->GetParamType() == "LINEAR")
1079 || (dp->GetParamType() == "LINEAR_X")
1080 || (dp->GetParamType() == "LINEAR_Y")
1081 || (dp->GetParamType() == "LINEAR_Z") )
1082 {
1083 param = new G4tgbPlaceParamLinear(dp);
1084
1085 }
1086 else if( (dp->GetParamType() == "SQUARE")
1087 || (dp->GetParamType() == "SQUARE_XY")
1088 || (dp->GetParamType() == "SQUARE_XZ")
1089 || (dp->GetParamType() == "SQUARE_YZ") )
1090 {
1091 param = new G4tgbPlaceParamSquare(dp);
1092 }
1093 else
1094 {
1095 G4String ErrMessage = "Parameterisation has wrong type, TYPE: "
1096 + G4String(dp->GetParamType()) + " !";
1097 G4Exception("G4tgbVolume::ConstructG4PhysVol", "WrongArgument",
1098 FatalException, ErrMessage);
1099 return 0;
1100 }
1101#ifdef G4VERBOSE
1103 {
1104 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1105 << " New G4PVParameterised: " << GetName() << " vol "
1106 << currentLV->GetName() << " in vol " << parentLV->GetName()
1107 << " axis " << param->GetAxis() << " nCopies "
1108 << param->GetNCopies() << G4endl;
1109 }
1110#endif
1111 physvol = new G4PVParameterised(GetName(),
1112 const_cast<G4LogicalVolume*>(currentLV),
1113 const_cast<G4LogicalVolume*>(parentLV),
1114 EAxis(param->GetAxis()),
1115 param->GetNCopies(), param);
1116#ifdef G4VERBOSE
1118 {
1119 G4cout << " Constructing new G4PVParameterised: "
1120 << physvol->GetName() << " in volume " << parentLV->GetName()
1121 << " N copies " << param->GetNCopies()
1122 << " axis " << param->GetAxis() << G4endl;
1123 }
1124#endif
1125
1126 }
1127 else if( place->GetType() == "PlaceReplica" )
1128 {
1129 //--------------- If it is PlaceReplica
1130 G4tgrPlaceDivRep* dpr = (G4tgrPlaceDivRep*)place;
1131
1132#ifdef G4VERBOSE
1134 {
1135 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1136 << " replica" << " " << currentLV->GetName()
1137 << " in " << parentLV->GetName()
1138 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth()
1139 << " offset " << dpr->GetOffset() << G4endl;
1140 }
1141#endif
1142 physvol = new G4PVReplica(GetName(),
1143 const_cast<G4LogicalVolume*>(currentLV),
1144 const_cast<G4LogicalVolume*>(parentLV),
1145 EAxis(dpr->GetAxis()), dpr->GetNDiv(),
1146 dpr->GetWidth(), dpr->GetOffset());
1147#ifdef G4VERBOSE
1149 {
1150 G4cout << " Constructing new G4PVReplica: "
1151 << currentLV->GetName()
1152 << " in " << parentLV->GetName()
1153 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth()
1154 << " offset " << dpr->GetOffset() << G4endl;
1155 }
1156#endif
1157 }
1158 }
1159 else if( theTgrVolume->GetType() == "VOLDivision" )
1160 {
1161 G4tgrVolumeDivision* volr = (G4tgrVolumeDivision*)theTgrVolume;
1162 G4tgrPlaceDivRep* placeDiv = volr->GetPlaceDivision() ;
1163 G4VSolid* solid = BuildSolidForDivision( parentLV->GetSolid(), placeDiv->GetAxis() );
1165 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() );
1166 G4LogicalVolume* divLV = new G4LogicalVolume(solid,
1167 const_cast<G4Material*>(mate),
1168 GetName() );
1169#ifdef G4VERBOSE
1171 {
1172 G4cout << " Constructed new G4LogicalVolume for division: "
1173 << divLV->GetName() << " mate " << mate->GetName() << G4endl;
1174 }
1175#endif
1176
1177 G4DivType divType = placeDiv->GetDivType();
1178 switch (divType)
1179 {
1180 case DivByNdiv:
1181 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1182 const_cast<G4LogicalVolume*>(parentLV),
1183 placeDiv->GetAxis(), placeDiv->GetNDiv(),
1184 placeDiv->GetOffset());
1185#ifdef G4VERBOSE
1187 {
1188 G4cout << " Constructing new G4PVDivision by number of divisions: "
1189 << GetName() << " in " << parentLV->GetName()
1190 << " axis " << placeDiv->GetAxis()
1191 << " Ndiv " << placeDiv->GetNDiv()
1192 << " offset " << placeDiv->GetOffset() << G4endl;
1193 }
1194#endif
1195 break;
1196 case DivByWidth:
1197 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1198 const_cast<G4LogicalVolume*>(parentLV),
1199 placeDiv->GetAxis(), placeDiv->GetWidth(),
1200 placeDiv->GetOffset());
1201#ifdef G4VERBOSE
1203 {
1204 G4cout << " Constructing new G4PVDivision by width: "
1205 << GetName() << " in " << parentLV->GetName()
1206 << " axis " << placeDiv->GetAxis()
1207 << " width " << placeDiv->GetWidth()
1208 << " offset " << placeDiv->GetOffset() << G4endl;
1209 }
1210#endif
1211 break;
1212 case DivByNdivAndWidth:
1213 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1214 const_cast<G4LogicalVolume*>(parentLV),
1215 placeDiv->GetAxis(), placeDiv->GetNDiv(),
1216 placeDiv->GetWidth(),
1217 placeDiv->GetOffset());
1218#ifdef G4VERBOSE
1220 {
1221 G4cout << " Constructing new G4PVDivision by width"
1222 << " and number of divisions: "
1223 << GetName() << " in " << parentLV->GetName()
1224 << " axis " << placeDiv->GetAxis()
1225 << " Ndiv " << placeDiv->GetNDiv()
1226 << " width " << placeDiv->GetWidth()
1227 << " offset " << placeDiv->GetOffset() << G4endl;
1228 }
1229#endif
1230 break;
1231 }
1232 }
1233 else if( theTgrVolume->GetType() == "VOLAssembly" )
1234 {
1235 // Define one layer as one assembly volume
1236 G4tgrVolumeAssembly * tgrAssembly = (G4tgrVolumeAssembly *)theTgrVolume;
1237
1238 if( !theG4AssemblyVolume )
1239 {
1240 theG4AssemblyVolume = new G4AssemblyVolume;
1241#ifdef G4VERBOSE
1243 {
1244 G4cout << " Constructing new G4AssemblyVolume: "
1245 << " number of assembly components "
1246 << tgrAssembly->GetNoComponents() << G4endl;
1247 }
1248#endif
1250 for( G4int ii = 0; ii < tgrAssembly->GetNoComponents(); ii++ )
1251 {
1252 // Rotation and translation of a plate inside the assembly
1253
1254 G4ThreeVector transl = tgrAssembly->GetComponentPos(ii);
1255 G4String rmName = tgrAssembly->GetComponentRM(ii);
1257 ->FindOrBuildG4RotMatrix( rmName );
1258
1259 //----- Get G4LogicalVolume of component
1260 G4String lvname = tgrAssembly->GetComponentName(ii);
1261 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( lvname);
1262 if( logvol == 0 )
1263 {
1264 g4vmgr->FindVolume( lvname )->ConstructG4Volumes( 0, 0);
1265 logvol = g4vmgr->FindG4LogVol( lvname, true );
1266 }
1267 // Fill the assembly by the plates
1268 theG4AssemblyVolume->AddPlacedVolume( logvol, transl, rotmat );
1269#ifdef G4VERBOSE
1271 {
1272 G4cout << " G4AssemblyVolume->AddPlacedVolume " << ii
1273 << " " << logvol->GetName()
1274 << " translation " << transl
1275 << " rotmat " << rotmat->colX()
1276 << " " << rotmat->colY()
1277 << " " << rotmat->colZ() << G4endl;
1278 }
1279#endif
1280 }
1281 }
1282
1283 // Rotation and Translation of the assembly inside the world
1284
1285 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place;
1286 G4String rmName = placeSimple->GetRotMatName();
1288 ->FindOrBuildG4RotMatrix( rmName );
1289 G4ThreeVector transl = place->GetPlacement();
1290
1291 G4LogicalVolume* parentLV_nonconst =
1292 const_cast<G4LogicalVolume*>(parentLV);
1293 theG4AssemblyVolume->MakeImprint( parentLV_nonconst, transl, rotmat );
1294
1295 }
1296 else // If it is G4tgrVolumeAssembly
1297 {
1298 G4String ErrMessage = "Volume type not supported: "
1299 + theTgrVolume->GetType() + ", sorry...";
1300 G4Exception("G4tgbVolume::ConstructG4PhysVol()", "NotImplemented",
1301 FatalException, ErrMessage);
1302 }
1303 }
1304
1305 return physvol;
1306}
1307
1308
1309//-------------------------------------------------------------------
1311{
1312 G4VSolid* solid=0;
1313 G4double redf = (parentSolid->GetExtent().GetXmax()-parentSolid->GetExtent().GetXmin());
1314 redf = std::min(redf,parentSolid->GetExtent().GetYmax()-parentSolid->GetExtent().GetYmin());
1315 redf = std::min(redf,parentSolid->GetExtent().GetZmax()-parentSolid->GetExtent().GetZmin());
1316 redf *= 0.001; //make daugther much smaller, to fit in parent
1317
1318 if( parentSolid->GetEntityType() == "G4Box" )
1319 {
1320 G4Box* psolid = (G4Box*)(parentSolid);
1321 solid = new G4Box(GetName(), psolid->GetXHalfLength()*redf,
1322 psolid->GetZHalfLength()*redf,
1323 psolid->GetZHalfLength()*redf);
1324 }
1325 else if ( parentSolid->GetEntityType() == "G4Tubs" )
1326 {
1327 G4Tubs* psolid = (G4Tubs*)(parentSolid);
1328 solid = new G4Tubs( GetName(), psolid->GetInnerRadius()*redf,
1329 psolid->GetOuterRadius()*redf,
1330 psolid->GetZHalfLength()*redf,
1331 psolid->GetSPhi(), psolid->GetDPhi());
1332 }
1333 else if ( parentSolid->GetEntityType() == "G4Cons" )
1334 {
1335 G4Cons* psolid = (G4Cons*)(parentSolid);
1336 solid = new G4Cons( GetName(), psolid->GetInnerRadiusMinusZ()*redf,
1337 psolid->GetOuterRadiusMinusZ()*redf,
1338 psolid->GetInnerRadiusPlusZ()*redf,
1339 psolid->GetOuterRadiusPlusZ()*redf,
1340 psolid->GetZHalfLength()*redf,
1341 psolid->GetSPhi(), psolid->GetDPhi());
1342 }
1343 else if ( parentSolid->GetEntityType() == "G4Trd" )
1344 {
1345 G4Trd* psolid = (G4Trd*)(parentSolid);
1346 G4double mpDx1 = psolid->GetXHalfLength1();
1347 G4double mpDx2 = psolid->GetXHalfLength2();
1348
1349 if( axis == kXAxis && std::fabs(mpDx1 - mpDx2) > G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() )
1350 {
1351 solid = new G4Trap( GetName(), psolid->GetZHalfLength()*redf,
1352 psolid->GetYHalfLength1()*redf,
1353 psolid->GetXHalfLength2()*redf,
1354 psolid->GetXHalfLength1()*redf );
1355 }
1356 else
1357 {
1358 solid = new G4Trd( GetName(), psolid->GetXHalfLength1()*redf,
1359 psolid->GetXHalfLength2()*redf,
1360 psolid->GetYHalfLength1()*redf,
1361 psolid->GetYHalfLength2()*redf,
1362 psolid->GetZHalfLength()*redf);
1363 }
1364
1365 }
1366 else if ( parentSolid->GetEntityType() == "G4Para" )
1367 {
1368 G4Para* psolid = (G4Para*)(parentSolid);
1369 solid = new G4Para( GetName(), psolid->GetXHalfLength()*redf,
1370 psolid->GetYHalfLength()*redf,
1371 psolid->GetZHalfLength()*redf,
1372 std::atan(psolid->GetTanAlpha()),
1373 psolid->GetSymAxis().theta(),
1374 psolid->GetSymAxis().phi() );
1375 }
1376 else if ( parentSolid->GetEntityType() == "G4Polycone" )
1377 {
1378 G4Polycone* psolid = (G4Polycone*)(parentSolid);
1379 G4PolyconeHistorical origParam = *(psolid->GetOriginalParameters());
1380 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ )
1381 {
1382 origParam.Rmin[ii] = origParam.Rmin[ii]*redf;
1383 origParam.Rmax[ii] = origParam.Rmax[ii]*redf;
1384 }
1385 solid = new G4Polycone( GetName(), psolid->GetStartPhi(),
1386 psolid->GetEndPhi(),
1387 origParam.Num_z_planes, origParam.Z_values,
1388 origParam.Rmin, origParam.Rmax);
1389
1390 }
1391 else if ( parentSolid->GetEntityType() == "G4Polyhedra" )
1392 {
1393 G4Polyhedra* psolid = (G4Polyhedra*)(parentSolid);
1394 G4PolyhedraHistorical origParam = *(psolid->GetOriginalParameters());
1395 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ )
1396 {
1397 origParam.Rmin[ii] = origParam.Rmin[ii]*redf;
1398 origParam.Rmax[ii] = origParam.Rmax[ii]*redf;
1399 }
1400 solid = new G4Polyhedra( GetName(), psolid->GetStartPhi(),
1401 psolid->GetEndPhi(),
1402 psolid->GetNumSide(),
1403 origParam.Num_z_planes, origParam.Z_values,
1404 origParam.Rmin, origParam.Rmax);
1405 }
1406 else
1407 {
1408 G4String ErrMessage = "Solid type not supported. VOLUME= " + GetName()
1409 + " Solid type= " + parentSolid->GetEntityType() + "\n"
1410 + "Only supported types are: G4Box, G4Tubs, G4Cons,"
1411 + " G4Trd, G4Para, G4Polycone, G4Polyhedra.";
1412 G4Exception("G4tgbVolume::BuildSolidForDivision()", "NotImplemented",
1413 FatalException, ErrMessage);
1414 return 0;
1415 }
1416
1417#ifdef G4VERBOSE
1419 {
1420 G4cout << " Constructing new G4Solid for division: "
1421 << *solid << G4endl;
1422 }
1423#endif
1424 return solid;
1425}
1426
@ FatalException
HepGeom::Point3D< G4double > G4Point3D
Definition: G4Point3D.hh:35
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Rotate3D G4Rotate3D
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
G4FacetVertexType
Definition: G4VFacet.hh:56
@ ABSOLUTE
Definition: G4VFacet.hh:56
@ RELATIVE
Definition: G4VFacet.hh:56
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
G4DivType
@ DivByNdiv
@ DivByWidth
@ DivByNdivAndWidth
double phi() const
double theta() const
Hep3Vector cross(const Hep3Vector &) const
Hep3Vector colX() const
Hep3Vector colY() const
Hep3Vector colZ() const
void MakeImprint(G4LogicalVolume *pMotherLV, G4ThreeVector &translationInMother, G4RotationMatrix *pRotationInMother, G4int copyNumBase=0, G4bool surfCheck=false)
void AddPlacedVolume(G4LogicalVolume *pPlacedVolume, G4ThreeVector &translation, G4RotationMatrix *rotation)
Definition: G4Box.hh:55
G4double GetZHalfLength() const
G4double GetXHalfLength() const
Definition: G4Cons.hh:75
G4double GetOuterRadiusPlusZ() const
G4double GetInnerRadiusMinusZ() const
G4double GetInnerRadiusPlusZ() const
G4double GetSPhi() const
G4double GetOuterRadiusMinusZ() const
G4double GetZHalfLength() const
G4double GetDPhi() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
Definition: G4Hype.hh:67
G4VSolid * GetSolid() const
G4String GetName() const
void SetVisAttributes(const G4VisAttributes *pVA)
const G4String & GetName() const
Definition: G4Material.hh:177
Definition: G4Orb.hh:52
Definition: G4Para.hh:77
G4double GetTanAlpha() const
G4ThreeVector GetSymAxis() const
G4double GetYHalfLength() const
G4double GetZHalfLength() const
G4double GetXHalfLength() const
G4double * Z_values
Definition: G4Polycone.hh:80
G4double GetEndPhi() const
G4double GetStartPhi() const
G4PolyconeHistorical * GetOriginalParameters() const
G4double GetEndPhi() const
G4int GetNumSide() const
G4PolyhedraHistorical * GetOriginalParameters() const
G4double GetStartPhi() const
static G4ReflectionFactory * Instance()
G4PhysicalVolumesPair Place(const G4Transform3D &transform3D, const G4String &name, G4LogicalVolume *LV, G4LogicalVolume *motherLV, G4bool isMany, G4int copyNo, G4bool surfCheck=false)
G4bool AddFacet(G4VFacet *aFacet)
Definition: G4Tet.hh:57
Definition: G4Trd.hh:63
G4double GetXHalfLength2() const
G4double GetYHalfLength2() const
G4double GetXHalfLength1() const
G4double GetYHalfLength1() const
G4double GetZHalfLength() const
Definition: G4Tubs.hh:77
G4double GetZHalfLength() const
G4double GetSPhi() const
G4double GetInnerRadius() const
G4double GetOuterRadius() const
G4double GetDPhi() const
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:349
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
virtual G4VisExtent GetExtent() const
Definition: G4VSolid.cc:619
virtual G4GeometryType GetEntityType() const =0
void SetVisibility(G4bool)
void SetColour(const G4Colour &)
G4double GetYmin() const
Definition: G4VisExtent.hh:91
G4double GetXmax() const
Definition: G4VisExtent.hh:90
G4double GetYmax() const
Definition: G4VisExtent.hh:92
G4double GetZmax() const
Definition: G4VisExtent.hh:94
G4double GetZmin() const
Definition: G4VisExtent.hh:93
G4double GetXmin() const
Definition: G4VisExtent.hh:89
G4Material * FindOrBuildG4Material(const G4String &name, G4bool bMustExist=1)
static G4tgbMaterialMgr * GetInstance()
static G4tgbRotationMatrixMgr * GetInstance()
G4RotationMatrix * FindOrBuildG4RotMatrix(const G4String &name)
G4tgbVolume * FindVolume(const G4String &volname)
G4LogicalVolume * FindG4LogVol(const G4String &theName, const G4bool bExists=0)
G4VSolid * FindG4Solid(const G4String &name)
void RegisterMe(const G4tgbVolume *vol)
static G4tgbVolumeMgr * GetInstance()
void RegisterChildParentLVs(const G4LogicalVolume *logvol, const G4LogicalVolume *parentLV)
G4VPhysicalVolume * ConstructG4PhysVol(const G4tgrPlace *place, const G4LogicalVolume *currentLV, const G4LogicalVolume *parentLV)
Definition: G4tgbVolume.cc:942
const G4String & GetName() const
Definition: G4tgbVolume.hh:108
G4VSolid * FindOrConstructG4Solid(const G4tgrSolid *vol)
Definition: G4tgbVolume.cc:219
void CheckNoSolidParams(const G4String &solidType, const unsigned int NoParamExpected, const unsigned int NoParam)
Definition: G4tgbVolume.cc:832
G4VSolid * BuildSolidForDivision(G4VSolid *parentSolid, EAxis axis)
G4LogicalVolume * ConstructG4LogVol(const G4VSolid *solid)
Definition: G4tgbVolume.cc:851
const G4double * GetColour() const
Definition: G4tgbVolume.hh:110
void ConstructG4Volumes(const G4tgrPlace *place, const G4LogicalVolume *parentLV)
Definition: G4tgbVolume.cc:137
G4bool GetVisibility() const
Definition: G4tgbVolume.hh:109
static G4int GetVerboseLevel()
G4double GetOffset() const
G4double GetWidth() const
EAxis GetAxis() const
G4DivType GetDivType() const
G4int GetNDiv() const
const G4String & GetParamType() const
const G4String & GetRotMatName() const
virtual G4ThreeVector GetPlacement() const
Definition: G4tgrPlace.cc:52
const G4String & GetType() const
Definition: G4tgrPlace.hh:61
unsigned int GetCopyNo() const
Definition: G4tgrPlace.hh:60
G4tgrVolume * GetVolume() const
Definition: G4tgrPlace.hh:59
const G4tgrSolid * GetSolid(G4int ii) const
G4ThreeVector GetRelativePlace() const
const G4String & GetType() const
Definition: G4tgrSolid.hh:62
const G4String & GetName() const
Definition: G4tgrSolid.hh:61
virtual const G4String & GetRelativeRotMatName() const
Definition: G4tgrSolid.cc:91
const std::vector< std::vector< G4double > * > GetSolidParams() const
Definition: G4tgrSolid.cc:84
G4ThreeVector GetComponentPos(G4int ii) const
const G4String & GetComponentRM(G4int ii) const
G4int GetNoComponents() const
const G4String & GetComponentName(G4int ii) const
G4tgrPlaceDivRep * GetPlaceDivision()
static G4tgrVolumeMgr * GetInstance()
std::pair< G4mmapspl::iterator, G4mmapspl::iterator > GetChildren(const G4String &name)
G4bool GetCheckOverlaps() const
Definition: G4tgrVolume.hh:100
const G4String & GetName() const
Definition: G4tgrVolume.hh:89
G4tgrSolid * GetSolid() const
Definition: G4tgrVolume.hh:92
const G4String & GetType() const
Definition: G4tgrVolume.hh:91
const G4String & GetMaterialName() const
Definition: G4tgrVolume.hh:93
EAxis
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41