source: trunk/source/persistency/ascii/src/G4tgbVolume.cc@ 1351

Last change on this file since 1351 was 1347, checked in by garnier, 15 years ago

geant4 tag 9.4

File size: 51.1 KB
Line 
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: G4tgbVolume.cc,v 1.23 2010/11/05 08:58:36 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-ref-00 $
29//
30//
31// class G4tgbVolume
32
33// History:
34// - Created. P.Arce, CIEMAT (November 2007)
35// -------------------------------------------------------------------------
36
37#include "G4tgbVolume.hh"
38#include "G4tgbVolumeMgr.hh"
39#include "G4tgbMaterialMgr.hh"
40#include "G4tgbRotationMatrixMgr.hh"
41#include "G4tgbPlaceParamLinear.hh"
42#include "G4tgbPlaceParamSquare.hh"
43#include "G4tgbPlaceParamCircle.hh"
44
45#include "G4tgrSolid.hh"
46#include "G4tgrSolidBoolean.hh"
47#include "G4tgrVolume.hh"
48#include "G4tgrVolumeDivision.hh"
49#include "G4tgrVolumeAssembly.hh"
50#include "G4tgrVolumeMgr.hh"
51#include "G4tgrPlace.hh"
52#include "G4tgrPlaceSimple.hh"
53#include "G4tgrPlaceDivRep.hh"
54#include "G4tgrPlaceParameterisation.hh"
55#include "G4tgrUtils.hh"
56
57#include "G4VSolid.hh"
58#include "G4UnionSolid.hh"
59#include "G4SubtractionSolid.hh"
60#include "G4IntersectionSolid.hh"
61#include "G4LogicalVolume.hh"
62#include "G4VPhysicalVolume.hh"
63#include "G4PVPlacement.hh"
64#include "G4PVDivision.hh"
65#include "G4PVReplica.hh"
66#include "G4PVParameterised.hh"
67#include "G4Box.hh"
68#include "G4Tubs.hh"
69#include "G4Cons.hh"
70#include "G4Trap.hh"
71#include "G4Sphere.hh"
72#include "G4Orb.hh"
73#include "G4Trd.hh"
74#include "G4Para.hh"
75#include "G4Torus.hh"
76#include "G4Hype.hh"
77#include "G4Polycone.hh"
78#include "G4Polyhedra.hh"
79#include "G4EllipticalTube.hh"
80#include "G4Ellipsoid.hh"
81#include "G4EllipticalCone.hh"
82#include "G4Hype.hh"
83#include "G4Tet.hh"
84#include "G4TwistedBox.hh"
85#include "G4TwistedTrap.hh"
86#include "G4TwistedTrd.hh"
87#include "G4TwistedTubs.hh"
88#include "G4AssemblyVolume.hh"
89#include "G4BREPSolidBox.hh"
90#include "G4BREPSolidCylinder.hh"
91#include "G4BREPSolidCone.hh"
92#include "G4BREPSolidSphere.hh"
93#include "G4BREPSolidTorus.hh"
94#include "G4BREPSolidPCone.hh"
95#include "G4BREPSolidPolyhedra.hh"
96#include "G4BREPSolidOpenPCone.hh"
97#include "G4TessellatedSolid.hh"
98#include "G4TriangularFacet.hh"
99#include "G4QuadrangularFacet.hh"
100#include "G4ExtrudedSolid.hh"
101
102#include "G4VisExtent.hh"
103#include "G4Material.hh"
104#include "G4RotationMatrix.hh"
105#include "G4ReflectionFactory.hh"
106
107#include "G4VisAttributes.hh"
108#include "G4RegionStore.hh"
109#include "G4tgrMessenger.hh"
110#include "G4UIcommand.hh"
111#include "G4GeometryTolerance.hh"
112
113//-------------------------------------------------------------------
114G4tgbVolume::G4tgbVolume()
115 : theTgrVolume(0), theG4AssemblyVolume(0)
116{
117}
118
119
120//-------------------------------------------------------------------
121G4tgbVolume::~G4tgbVolume()
122{
123}
124
125
126//-------------------------------------------------------------------
127G4tgbVolume::G4tgbVolume( G4tgrVolume* vol)
128{
129 theTgrVolume = vol;
130 theG4AssemblyVolume = 0;
131}
132
133
134//-------------------------------------------------------------------
135void G4tgbVolume::ConstructG4Volumes( const G4tgrPlace* place,
136 const G4LogicalVolume* parentLV )
137{
138#ifdef G4VERBOSE
139 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
140 {
141 G4cout << G4endl << "@@@ G4tgbVolume::ConstructG4Volumes - " << GetName() << G4endl;
142 if( place && parentLV ) G4cout << " place in LV " << parentLV->GetName() << G4endl;
143 }
144#endif
145 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr::GetInstance();
146 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( GetName() );
147 G4bool bFirstCopy = false;
148 if( (logvol == 0) )
149 {
150 bFirstCopy = true;
151 if( theTgrVolume->GetType() != "VOLDivision" )
152 {
153 //--- If first time build solid and LogVol
154 G4VSolid* solid = FindOrConstructG4Solid( theTgrVolume->GetSolid() );
155 if( solid != 0 ) // for G4AssemblyVolume it is 0
156 {
157 g4vmgr->RegisterMe( solid );
158 logvol = ConstructG4LogVol( solid );
159 g4vmgr->RegisterMe( logvol );
160 g4vmgr->RegisterChildParentLVs( logvol, parentLV );
161 }
162 else
163 {
164 return;
165 }
166 }
167 else
168 {
169 return;
170 }
171 }
172 //--- Construct PhysVol
173 G4VPhysicalVolume* physvol = ConstructG4PhysVol( place, logvol, parentLV );
174 if( physvol != 0 ) // 0 for G4AssemblyVolumes
175 {
176 g4vmgr->RegisterMe( physvol );
177
178 if( logvol == 0 ) // case of divisions
179 {
180 logvol = physvol->GetLogicalVolume();
181 }
182 }
183 else
184 {
185 return;
186 }
187
188 //--- If first copy build children placements in this LogVol
189 if(bFirstCopy)
190 {
191 std::pair<G4mmapspl::iterator, G4mmapspl::iterator> children
192 = G4tgrVolumeMgr::GetInstance()->GetChildren( GetName() );
193 G4mmapspl::iterator cite;
194 for( cite = children.first; cite != children.second; cite++ )
195 {
196 //----- Call G4tgrPlace ->constructG4Volumes
197 //---- find G4tgbVolume corresponding to the G4tgrVolume
198 // pointed by G4tgrPlace
199 G4tgrPlace* pl = const_cast<G4tgrPlace*>((*cite).second);
200 G4tgbVolume* svol = g4vmgr->FindVolume( pl->GetVolume()->GetName() );
201 //--- find copyNo
202#ifdef G4VERBOSE
203 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
204 {
205 G4cout << " G4tgbVolume::ConstructG4Volumes - construct daughter " << pl->GetVolume()->GetName() << " # " << pl->GetCopyNo() << G4endl;
206 }
207#endif
208 svol->ConstructG4Volumes( pl, logvol );
209 }
210 }
211
212}
213
214
215
216//-------------------------------------------------------------------
217G4VSolid* G4tgbVolume::FindOrConstructG4Solid( const G4tgrSolid* sol )
218{
219 G4double angularTolerance = G4GeometryTolerance::GetInstance()
220 ->GetAngularTolerance();
221
222 if( sol == 0 ) { return 0; }
223
224#ifdef G4VERBOSE
225 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
226 {
227 G4cout << " G4tgbVolume::FindOrConstructG4Solid():" << G4endl
228 << " SOLID = " << sol << G4endl
229 << " " << sol->GetName() << " of type " << sol->GetType()
230 << G4endl;
231 }
232#endif
233
234 //----- Check if solid exists already
235 G4VSolid* solid = G4tgbVolumeMgr::GetInstance()
236 ->FindG4Solid( sol->GetName() );
237 if( solid ) { return solid; }
238
239 // Give 'sol' as Boolean solids needs to call this method twice
240
241#ifdef G4VERBOSE
242 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
243 {
244 G4cout << " G4tgbVolume::FindOrConstructG4Solid() - "
245 << sol->GetSolidParams().size() << G4endl;
246 }
247#endif
248
249 std::vector<G4double> solParam;
250
251 // In case of BOOLEAN solids, solidParams are taken from components
252
253 if( sol->GetSolidParams().size() == 1)
254 {
255 solParam = * sol->GetSolidParams()[ 0 ];
256 }
257
258 //----------- instantiate the appropiate G4VSolid type
259 G4String stype = sol->GetType();
260 G4String sname = sol->GetName();
261
262 if( stype == "BOX" )
263 {
264 CheckNoSolidParams( stype, 3, solParam.size() );
265 solid = new G4Box( sname, solParam[0], solParam[1], solParam[2] );
266
267 }
268 else if( stype == "TUBE" )
269 {
270 CheckNoSolidParams( stype, 3, solParam.size() );
271 solid = new G4Tubs( sname, solParam[0], solParam[1], solParam[2],
272 0.*deg, 360.*deg );
273 }
274 else if( stype == "TUBS" )
275 {
276 CheckNoSolidParams( stype, 5, solParam.size() );
277 G4double phiDelta = solParam[4];
278 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
279 solid = new G4Tubs( sname, solParam[0], solParam[1], solParam[2],
280 solParam[3], phiDelta );
281 }
282 else if( stype == "TRAP" )
283 {
284 if( solParam.size() == 11 )
285 {
286 solid = new G4Trap( sname, solParam[0], solParam[1], solParam[2],
287 solParam[3], solParam[4], solParam[5], solParam[6],
288 solParam[7], solParam[8], solParam[9], solParam[10] );
289 }
290 else if( solParam.size() == 4 )
291 {
292 solid = new G4Trap( sname, solParam[0], solParam[1]/deg,
293 solParam[2]/deg, solParam[3]);
294 }
295 else
296 {
297 G4String ErrMessage1 = "Solid type " + stype;
298 G4String ErrMessage2 = " should have 11 or 4 parameters,\n";
299 G4String ErrMessage3 = "and it has "
300 + G4UIcommand::ConvertToString(G4int(solParam.size()));
301 G4String ErrMessage = ErrMessage1 + ErrMessage2 + ErrMessage3 + " !";
302 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
303 "InvalidSetup", FatalException, ErrMessage);
304 return 0;
305 }
306
307 }
308 else if( stype == "TRD" )
309 {
310 CheckNoSolidParams( stype, 5, solParam.size() );
311 solid = new G4Trd( sname, solParam[0], solParam[1], solParam[2],
312 solParam[3], solParam[4] );
313 }
314 else if( stype == "PARA" )
315 {
316 CheckNoSolidParams( stype, 6, solParam.size() );
317 solid = new G4Para( sname, solParam[0], solParam[1], solParam[2],
318 solParam[3], solParam[4], solParam[5] );
319 }
320 else if( stype == "CONE" )
321 {
322 CheckNoSolidParams( stype, 5, solParam.size() );
323 solid = new G4Cons( sname, solParam[0], solParam[1], solParam[2],
324 solParam[3], solParam[4], 0., 360.*deg);
325 }
326 else if( stype == "CONS" )
327 {
328 CheckNoSolidParams( stype, 7, solParam.size() );
329 G4double phiDelta = solParam[6];
330 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
331 solid = new G4Cons( sname, solParam[0], solParam[1], solParam[2],
332 solParam[3], solParam[4], solParam[5], phiDelta);
333 }
334 else if( stype == "SPHERE" )
335 {
336 CheckNoSolidParams( stype, 6, solParam.size() );
337 G4double phiDelta = solParam[3];
338 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
339 G4double thetaDelta = solParam[5];
340 if( std::fabs(thetaDelta - pi) < angularTolerance ) { thetaDelta = pi; }
341 solid = new G4Sphere( sname, solParam[0], solParam[1], solParam[2],
342 phiDelta, solParam[4], thetaDelta);
343 }
344 else if( stype == "ORB" )
345 {
346 CheckNoSolidParams( stype, 1, solParam.size() );
347 solid = new G4Orb( sname, solParam[0] );
348 }
349 else if( stype == "TORUS" )
350 {
351 CheckNoSolidParams( stype, 5, solParam.size() );
352 G4double phiDelta = solParam[4];
353 if( std::fabs(phiDelta - twopi) < angularTolerance ) { phiDelta = twopi; }
354 solid = new G4Torus( sname, solParam[0], solParam[1], solParam[2],
355 solParam[3], phiDelta );
356 }
357 else if( stype == "POLYCONE" )
358 {
359 size_t nplanes = size_t(solParam[2]);
360 G4bool genericPoly = false;
361 if( solParam.size() == 3+nplanes*3 )
362 {
363 genericPoly = true;
364 }
365 else if( solParam.size() == 3+nplanes*2 )
366 {
367 genericPoly = false;
368 }
369 else
370 {
371 G4String Err1 = "Solid type " + stype + " should have ";
372 G4String Err2 = G4UIcommand::ConvertToString(G4int(3+nplanes*3))
373 + " (Z,Rmin,Rmax)\n";
374 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(3+nplanes*2));
375 G4String Err4 = " (RZ corners) parameters,\n";
376 G4String Err5 = "and it has "
377 + G4UIcommand::ConvertToString(G4int(solParam.size()));
378 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !";
379 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
380 "InvalidSetup", FatalException, ErrMessage);
381 return 0;
382 }
383
384 if( genericPoly )
385 {
386 std::vector<G4double>* z_p = new std::vector<G4double>;
387 std::vector<G4double>* rmin_p = new std::vector<G4double>;
388 std::vector<G4double>* rmax_p = new std::vector<G4double>;
389 for( size_t ii = 0; ii < nplanes; ii++ )
390 {
391 (*z_p).push_back( solParam[3+3*ii] );
392 (*rmin_p).push_back( solParam[3+3*ii+1] );
393 (*rmax_p).push_back( solParam[3+3*ii+2] );
394 }
395 G4double phiTotal = solParam[1];
396 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
397 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi
398 nplanes, // sections
399 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
400 }
401 else
402 {
403 std::vector<G4double>* R_c = new std::vector<G4double>;
404 std::vector<G4double>* Z_c = new std::vector<G4double>;
405 for( size_t ii = 0; ii < nplanes; ii++ )
406 {
407 (*R_c).push_back( solParam[3+2*ii] );
408 (*Z_c).push_back( solParam[3+2*ii+1] );
409 }
410 G4double phiTotal = solParam[1];
411 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
412 solid = new G4Polycone( sname, solParam[0], phiTotal, // start,delta-phi
413 nplanes, // sections
414 &((*R_c)[0]), &((*Z_c)[0]));
415 }
416
417 }
418 else if( stype == "POLYHEDRA" )
419 {
420 size_t nplanes = size_t(solParam[3]);
421 G4bool genericPoly = false;
422 if( solParam.size() == 4+nplanes*3 )
423 {
424 genericPoly = true;
425 }
426 else if( solParam.size() == 4+nplanes*2 )
427 {
428 genericPoly = false;
429 }
430 else
431 {
432 G4String Err1 = "Solid type " + stype + " should have ";
433 G4String Err2 = G4UIcommand::ConvertToString(G4int(4+nplanes*3))
434 + " (Z,Rmin,Rmax)\n";
435 G4String Err3 = "or " + G4UIcommand::ConvertToString(G4int(4+nplanes*2));
436 G4String Err4 = " (RZ corners) parameters,\n";
437 G4String Err5 = "and it has "
438 + G4UIcommand::ConvertToString(G4int(solParam.size()));
439 G4String ErrMessage = Err1 + Err2 + Err3 + Err4 + Err5 + " !";
440 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
441 "InvalidSetup", FatalException, ErrMessage);
442 return 0;
443 }
444
445 if( genericPoly )
446 {
447 std::vector<G4double>* z_p = new std::vector<G4double>;
448 std::vector<G4double>* rmin_p = new std::vector<G4double>;
449 std::vector<G4double>* rmax_p = new std::vector<G4double>;
450 for( size_t ii = 0; ii < nplanes; ii++ )
451 {
452 (*z_p).push_back( solParam[4+3*ii] );
453 (*rmin_p).push_back( solParam[4+3*ii+1] );
454 (*rmax_p).push_back( solParam[4+3*ii+2] );
455 }
456 G4double phiTotal = solParam[1];
457 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
458 solid = new G4Polyhedra( sname, solParam[0], phiTotal,
459 G4int(solParam[2]), nplanes,
460 &((*z_p)[0]), &((*rmin_p)[0]), &((*rmax_p)[0]));
461 }
462 else
463 {
464 std::vector<G4double>* R_c = new std::vector<G4double>;
465 std::vector<G4double>* Z_c = new std::vector<G4double>;
466 for( size_t ii = 0; ii < nplanes; ii++ )
467 {
468 (*R_c).push_back( solParam[4+2*ii] );
469 (*Z_c).push_back( solParam[4+2*ii+1] );
470 }
471 G4double phiTotal = solParam[1];
472 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
473 solid = new G4Polyhedra( sname, solParam[0], phiTotal,
474 G4int(solParam[2]), nplanes,
475 &((*R_c)[0]), &((*Z_c)[0]));
476 }
477 }
478 else if( stype == "ELLIPTICALTUBE" )
479 {
480 CheckNoSolidParams( stype, 3, solParam.size() );
481 solid = new G4EllipticalTube( sname, solParam[0], solParam[1], solParam[2]);
482 }
483 else if( stype == "ELLIPSOID" )
484 {
485 CheckNoSolidParams( stype, 5, solParam.size() );
486 solid = new G4Ellipsoid( sname, solParam[0], solParam[1], solParam[2],
487 solParam[3], solParam[4] );
488 }
489 else if( stype == "ELLIPTICALCONE" )
490 {
491 CheckNoSolidParams( stype, 4, solParam.size() );
492 solid = new G4EllipticalCone( sname, solParam[0], solParam[1],
493 solParam[2], solParam[3] );
494 }
495 else if( stype == "HYPE" )
496 {
497 CheckNoSolidParams( stype, 5, solParam.size() );
498 solid = new G4Hype( sname, solParam[0], solParam[1], solParam[2],
499 solParam[3], solParam[4] );
500 }
501 else if( stype == "TET" )
502 {
503 CheckNoSolidParams( stype, 12, solParam.size() );
504 G4ThreeVector anchor(solParam[0], solParam[1], solParam[2]);
505 G4ThreeVector p2(solParam[3], solParam[4], solParam[5]);
506 G4ThreeVector p3(solParam[6], solParam[7], solParam[8]);
507 G4ThreeVector p4(solParam[9], solParam[10], solParam[11]);
508 solid = new G4Tet( sname, anchor, p2, p3, p4 );
509 }
510 else if( stype == "TWISTEDBOX" )
511 {
512 CheckNoSolidParams( stype, 4, solParam.size() );
513 solid = new G4TwistedBox( sname, solParam[0], solParam[1],
514 solParam[2], solParam[3]);
515 }
516 else if( stype == "TWISTEDTRAP" )
517 {
518 CheckNoSolidParams( stype, 11, solParam.size() );
519 solid = new G4TwistedTrap( sname, solParam[0], solParam[1], solParam[2],
520 solParam[3], solParam[4], solParam[5], solParam[6],
521 solParam[7], solParam[8], solParam[9], solParam[10] );
522 }
523 else if( stype == "TWISTEDTRD" )
524 {
525 CheckNoSolidParams( stype, 6, solParam.size() );
526 solid = new G4TwistedTrd( sname, solParam[0], solParam[1], solParam[2],
527 solParam[3], solParam[4], solParam[5]);
528 }
529 else if( stype == "TWISTEDTUBS" )
530 {
531 CheckNoSolidParams( stype, 5, solParam.size() );
532 G4double phiTotal = solParam[4];
533 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
534 solid = new G4TwistedTubs( sname, solParam[0], solParam[1], solParam[2],
535 solParam[3], phiTotal);
536 }
537 else if( stype == "BREPBOX" ) // EntityType is = "Closed_Shell"
538 {
539 CheckNoSolidParams( stype, 24, solParam.size() );
540 std::vector<G4Point3D> points;
541 for( size_t ii = 0; ii < 8; ii++ )
542 {
543 points.push_back( G4Point3D(solParam[ii*3+0],
544 solParam[ii*3+1],
545 solParam[ii*3+2]) );
546 }
547 solid = new G4BREPSolidBox( sname, points[0], points[1], points[2],
548 points[3], points[4], points[5], points[6],
549 points[7] );
550 }
551 else if( stype == "BREPCYLINDER" ) // EntityType is = "Closed_Shell"
552 {
553 CheckNoSolidParams( stype, 11, solParam.size() );
554 solid = new G4BREPSolidCylinder( sname,
555 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
556 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
557 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
558 solParam[9], solParam[10] );
559 }
560 else if( stype == "BREPCONE" ) // EntityType is = "Closed_Shell"
561 {
562 CheckNoSolidParams( stype, 12, solParam.size() );
563 solid = new G4BREPSolidCone( sname,
564 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
565 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
566 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
567 solParam[9], solParam[10], solParam[11] );
568 }
569 else if( stype == "BREPSPHERE" ) // EntityType is = "Closed_Shell"
570 {
571 CheckNoSolidParams( stype, 10, solParam.size() );
572 solid = new G4BREPSolidSphere( sname,
573 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
574 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
575 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
576 solParam[9] );
577
578 }
579 else if( stype == "BREPTORUS" ) // EntityType is = "Closed_Shell"
580 {
581 CheckNoSolidParams( stype, 11, solParam.size() );
582 solid = new G4BREPSolidTorus( sname,
583 G4ThreeVector( solParam[0], solParam[1], solParam[2] ),
584 G4ThreeVector( solParam[3], solParam[4], solParam[5] ),
585 G4ThreeVector( solParam[6], solParam[7], solParam[8] ),
586 solParam[9], solParam[10] );
587 }
588 else if( stype == "BREPPCONE" ) // EntityType is = "Closed_Shell"
589 {
590 size_t nplanes = size_t(solParam[2]);
591 CheckNoSolidParams( stype, 4+3*nplanes, solParam.size() );
592 std::vector<G4double>* z_p = new std::vector<G4double>;
593 std::vector<G4double>* rmin_p = new std::vector<G4double>;
594 std::vector<G4double>* rmax_p = new std::vector<G4double>;
595 for( size_t ii = 0; ii < nplanes; ii++ )
596 {
597 (*z_p).push_back( solParam[4+3*ii] );
598 (*rmin_p).push_back( solParam[4+3*ii+1] );
599 (*rmax_p).push_back( solParam[4+3*ii+2] );
600 }
601 G4double phiTotal = solParam[1];
602 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
603 CheckNoSolidParams( stype, 12, solParam.size() );
604 solid = new G4BREPSolidPCone( sname, solParam[0], phiTotal, // start,dph
605 nplanes, // sections
606 solParam[3], // z_start
607 &((*z_p)[0]), &((*rmin_p)[0]),
608 &((*rmax_p)[0]));
609 }
610 else if( stype == "BREPPOLYHEDRA" ) // EntityType is = "Closed_Shell"
611 {
612 size_t nplanes = size_t(solParam[3]);
613 CheckNoSolidParams( stype, 5+3*nplanes, solParam.size() );
614 std::vector<G4double>* z_p = new std::vector<G4double>;
615 std::vector<G4double>* rmin_p = new std::vector<G4double>;
616 std::vector<G4double>* rmax_p = new std::vector<G4double>;
617 for( size_t ii = 0; ii < nplanes; ii++ )
618 {
619 (*z_p).push_back( solParam[5+3*ii] );
620 (*rmin_p).push_back( solParam[5+3*ii+1] );
621 (*rmax_p).push_back( solParam[5+3*ii+2] );
622 }
623 G4double phiTotal = solParam[1];
624 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
625 CheckNoSolidParams( stype, 12, solParam.size() );
626 solid = new G4BREPSolidPolyhedra( sname, solParam[0], phiTotal, // start,dph
627 G4int(solParam[2]), // sides
628 nplanes, // sections
629 solParam[4], // z_start
630 &((*z_p)[0]), &((*rmin_p)[0]),
631 &((*rmax_p)[0]));
632 }
633 else if( stype == "BREPOPENPCONE" ) // EntityType is = "Closed_Shell"
634 {
635 size_t nplanes = size_t(solParam[2]);
636 std::vector<G4double>* z_p = new std::vector<G4double>;
637 std::vector<G4double>* rmin_p = new std::vector<G4double>;
638 std::vector<G4double>* rmax_p = new std::vector<G4double>;
639 for( size_t ii = 0; ii < nplanes; ii++ )
640 {
641 (*z_p).push_back( solParam[4+3*ii] );
642 (*rmin_p).push_back( solParam[4+3*ii+1] );
643 (*rmax_p).push_back( solParam[4+3*ii+2] );
644 }
645 G4double phiTotal = solParam[1];
646 if( std::fabs(phiTotal - twopi) < angularTolerance ) { phiTotal = twopi; }
647 CheckNoSolidParams( stype, 12, solParam.size() );
648 solid = new G4BREPSolidOpenPCone( sname, solParam[0], phiTotal, // start,dph
649 nplanes, // sections
650 solParam[3], // z_start
651 &((*z_p)[0]), &((*rmin_p)[0]),
652 &((*rmax_p)[0]));
653 }
654 else if( stype == "TESSELLATED" )
655 {
656 G4int nFacets = G4int(solParam[0]);
657 G4int jj = 0;
658 solid = new G4TessellatedSolid(sname);
659 G4TessellatedSolid* solidTS = (G4TessellatedSolid*)(solid);
660 G4VFacet* facet=0;
661
662 for( G4int ii = 0; ii < nFacets; ii++){
663 G4int nPoints = G4int(solParam[jj+1]);
664 if( G4int(solParam.size()) < jj + nPoints*3 + 2 ) {
665 G4String Err1 = "Too small number of parameters in tesselated solid, it should be at least " + G4UIcommand::ConvertToString(jj + nPoints*3 + 2 );
666 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(ii);
667 G4String Err3 = " number of parameters is " + G4UIcommand::ConvertToString(G4int(solParam.size()));
668 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
669 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
670 "InvalidSetup", FatalException, ErrMessage);
671 return 0;
672 }
673
674 if( nPoints == 3 )
675 {
676 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]);
677 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]);
678 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]);
679 G4FacetVertexType vertexType = ABSOLUTE;
680 if( solParam[jj+11] == 0 )
681 {
682 vertexType = ABSOLUTE;
683 }
684 else if( solParam[jj+11] == 0 )
685 {
686 vertexType = RELATIVE;
687 }
688 else
689 {
690 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
691 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
692 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+11]);
693 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
694 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
695 "InvalidSetup", FatalException, ErrMessage);
696 return 0;
697 }
698 facet = new G4TriangularFacet( pt0, vt1, vt2, vertexType );
699 }
700 else if( nPoints == 4 )
701 {
702 G4ThreeVector pt0(solParam[jj+2],solParam[jj+3],solParam[jj+4]);
703 G4ThreeVector vt1(solParam[jj+5],solParam[jj+6],solParam[jj+7]);
704 G4ThreeVector vt2(solParam[jj+8],solParam[jj+9],solParam[jj+10]);
705 G4ThreeVector vt3(solParam[jj+11],solParam[jj+12],solParam[jj+13]);
706 G4FacetVertexType vertexType = ABSOLUTE;
707 if( solParam[jj+14] == 0 )
708 {
709 vertexType = ABSOLUTE;
710 }
711 else if( solParam[jj+14] == 0 )
712 {
713 vertexType = RELATIVE;
714 }
715 else
716 {
717 G4String Err1 = "Wrong number of vertex type in tesselated solid, it should be 0 =ABSOLUTE) or 1 (=RELATIVE)";
718 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
719 G4String Err3 = " vertex type is " + G4UIcommand::ConvertToString(solParam[jj+14]);
720 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
721 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
722 "InvalidSetup", FatalException, ErrMessage);
723 return 0;
724 }
725 facet = new G4QuadrangularFacet( pt0, vt1, vt2, vt3, vertexType );
726 }
727 else
728 {
729 G4String Err1 = "Wrong number of points in tesselated solid, it should be 3 or 4";
730 G4String Err2 = " facet number " + G4UIcommand::ConvertToString(G4int(ii));
731 G4String Err3 = " number of points is " + G4UIcommand::ConvertToString(G4int(nPoints));
732 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
733 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
734 "InvalidSetup", FatalException, ErrMessage);
735 return 0;
736 }
737
738 solidTS->AddFacet( facet );
739 jj += nPoints*3 + 2;
740 }
741
742 }
743 else if( stype == "EXTRUDED" )
744 {
745 std::vector<G4TwoVector> polygonList;
746 std::vector<G4ExtrudedSolid::ZSection> zsectionList;
747 G4int nPolygons = G4int(solParam[0]);
748 G4int ii = 1;
749 G4int nMax = nPolygons*2+1;
750 for( ;ii < nMax; ii+=2 )
751 {
752 polygonList.push_back( G4TwoVector(solParam[ii],solParam[ii+1]) );
753 }
754 G4int nZSections = G4int(solParam[ii]);
755 nMax = nPolygons*2 + nZSections*4 + 2;
756 ii++;
757 for( ; ii < nMax; ii+=4 )
758 {
759 G4TwoVector offset(solParam[ii+1],solParam[ii+2]);
760 zsectionList.push_back( G4ExtrudedSolid::ZSection(solParam[ii],offset,solParam[ii+3]) );
761 }
762 solid = new G4ExtrudedSolid( sname, polygonList, zsectionList );
763
764 }
765 else if( stype.substr(0,7) == "Boolean" )
766 {
767 const G4tgrSolidBoolean* solb = dynamic_cast<const G4tgrSolidBoolean*>(sol);
768 if (!solb)
769 {
770 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
771 "InvalidSetup", FatalException, "Invalid Solid pointer");
772 return 0;
773 }
774 G4VSolid* sol1 = FindOrConstructG4Solid( solb->GetSolid(0));
775 G4VSolid* sol2 = FindOrConstructG4Solid( solb->GetSolid(1));
776 G4RotationMatrix* relRotMat = G4tgbRotationMatrixMgr::GetInstance()
777 ->FindOrBuildG4RotMatrix( sol->GetRelativeRotMatName() );
778 G4ThreeVector relPlace = solb->GetRelativePlace();
779
780 if( stype == "Boolean_UNION" )
781 {
782 solid = new G4UnionSolid( sname, sol1, sol2, relRotMat, relPlace );
783 }
784 else if( stype == "Boolean_SUBTRACTION" )
785 {
786 solid = new G4SubtractionSolid( sname, sol1, sol2, relRotMat, relPlace );
787 }
788 else if( stype == "Boolean_INTERSECTION" )
789 {
790 solid = new G4IntersectionSolid( sname, sol1, sol2, relRotMat, relPlace );
791 }
792 else
793 {
794 G4String ErrMessage = "Unknown Boolean type " + stype;
795 G4Exception("G4tgbVolume::FindOrConstructG4Solid()",
796 "InvalidSetup", FatalException, ErrMessage);
797 return 0;
798 }
799 }
800 else
801 {
802 G4String ErrMessage = "Solids of type " + stype
803 + " not implemented yet, sorry...";
804 G4Exception("G4tgbVolume::FindOrConstructG4Solid()", "NotImplemented",
805 FatalException, ErrMessage);
806 return 0;
807 }
808
809#ifdef G4VERBOSE
810 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
811 {
812 G4cout << " G4tgbVolume::FindOrConstructG4Solid()" << G4endl
813 << " Created solid " << sname
814 << " of type " << solid->GetEntityType() << G4endl;
815 }
816#endif
817
818#ifdef G4VERBOSE
819 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
820 {
821 G4cout << " Constructing new G4Solid: "
822 << *solid << G4endl;
823 }
824#endif
825
826 return solid;
827}
828
829//-------------------------------------------------------------------
830void G4tgbVolume::CheckNoSolidParams( const G4String& solidType,
831 const unsigned int NoParamExpected,
832 const unsigned int NoParam )
833{
834 if( NoParamExpected != NoParam )
835 {
836 G4String Err1 = "Solid type " + solidType + " should have ";
837 G4String Err2 = G4UIcommand::ConvertToString(G4int(NoParamExpected))
838 + " parameters,\n";
839 G4String Err3 = "and it has "
840 + G4UIcommand::ConvertToString(G4int(NoParam));
841 G4String ErrMessage = Err1 + Err2 + Err3 + " !";
842 G4Exception("G4tgbVolume::CheckNoSolidParams()", "InvalidSetup",
843 FatalException, ErrMessage);
844 }
845}
846
847
848//-------------------------------------------------------------------
849G4LogicalVolume* G4tgbVolume::ConstructG4LogVol( const G4VSolid* solid )
850{
851 G4LogicalVolume* logvol;
852
853#ifdef G4VERBOSE
854 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
855 {
856 G4cout << " G4tgbVolume::ConstructG4LogVol() - " << GetName() << G4endl;
857 }
858#endif
859
860 //----------- Get the material first
861 G4Material* mate = G4tgbMaterialMgr::GetInstance()
862 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() );
863 if( mate == 0 )
864 {
865 G4String ErrMessage = "Material not found "
866 + theTgrVolume->GetMaterialName()
867 + " for volume " + GetName() + ".";
868 G4Exception("G4tgbVolume::ConstructG4LogVol()", "InvalidSetup",
869 FatalException, ErrMessage);
870 }
871#ifdef G4VERBOSE
872 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
873 {
874 G4cout << " G4tgbVolume::ConstructG4LogVol() -"
875 << " Material constructed: " << mate->GetName() << G4endl;
876 }
877#endif
878
879 //---------- Construct the LV
880 logvol = new G4LogicalVolume( const_cast<G4VSolid*>(solid),
881 const_cast<G4Material*>(mate), GetName() );
882
883#ifdef G4VERBOSE
884 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
885 {
886 G4cout << " Constructing new G4LogicalVolume: "
887 << logvol->GetName() << " mate " << mate->GetName() << G4endl;
888 }
889#endif
890
891 //---------- Set visibility and colour
892 if( !GetVisibility() || GetColour()[0] != -1 )
893 {
894 G4VisAttributes* visAtt = new G4VisAttributes();
895#ifdef G4VERBOSE
896 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
897 {
898 G4cout << " Constructing new G4VisAttributes: "
899 << *visAtt << G4endl;
900 }
901#endif
902
903 if( !GetVisibility() )
904 {
905 visAtt->SetVisibility( GetVisibility() );
906 }
907 else if( GetColour()[0] != -1 )
908 {
909 // this else should not be necessary, because if the visibility
910 // is set to off, colour should have no effect. But it does not
911 // work: if you set colour and vis off, it is visualized!?!?!?
912
913 const G4double* col = GetColour();
914 if( col[3] == -1. )
915 {
916 visAtt->SetColour( G4Colour(col[0],col[1],col[2]));
917 }
918 else
919 {
920 visAtt->SetColour( G4Colour(col[0],col[1],col[2],col[3]));
921 }
922 }
923 logvol->SetVisAttributes(visAtt);
924 }
925
926#ifdef G4VERBOSE
927 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
928 {
929 G4cout << " G4tgbVolume::ConstructG4LogVol() -"
930 << " Created logical volume: " << GetName() << G4endl;
931 }
932#endif
933
934 return logvol;
935}
936
937
938//-------------------------------------------------------------------
939G4VPhysicalVolume*
940G4tgbVolume::ConstructG4PhysVol( const G4tgrPlace* place,
941 const G4LogicalVolume* currentLV,
942 const G4LogicalVolume* parentLV )
943{
944 G4VPhysicalVolume* physvol = 0;
945 G4int copyNo;
946
947 //----- Case of placement of top volume
948 if( place == 0 )
949 {
950#ifdef G4VERBOSE
951 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
952 {
953 G4cout << " G4tgbVolume::ConstructG4PhysVol() - World: "
954 << GetName() << G4endl;
955 }
956#endif
957 physvol = new G4PVPlacement(0, G4ThreeVector(),
958 const_cast<G4LogicalVolume*>(currentLV),
959 GetName(), 0, false, 0,
960 theTgrVolume->GetCheckOverlaps());
961#ifdef G4VERBOSE
962 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
963 {
964 G4cout << " Constructing new : G4PVPlacement "
965 << physvol->GetName() << G4endl;
966 }
967#endif
968 }
969 else
970 {
971 copyNo = place->GetCopyNo();
972
973#ifdef G4VERBOSE
974 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
975 {
976 G4cout << " G4tgbVolume::ConstructG4PhysVol() - " << GetName() << G4endl
977 << " inside " << parentLV->GetName() << " copy No: " << copyNo
978 << " of type= " << theTgrVolume->GetType() << G4endl
979 << " placement type= " << place->GetType() << G4endl;
980 }
981#endif
982
983 if( theTgrVolume->GetType() == "VOLSimple" )
984 {
985 //----- Get placement
986#ifdef G4VERBOSE
987 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
988 {
989 G4cout << " G4tgbVolume::ConstructG4PhysVol() - Placement type = "
990 << place->GetType() << G4endl;
991 }
992#endif
993
994 //--------------- If it is G4tgrPlaceSimple
995 if( place->GetType() == "PlaceSimple" )
996 {
997 //----- Get rotation matrix
998 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place;
999 G4String rmName = placeSimple->GetRotMatName();
1000
1001 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance()
1002 ->FindOrBuildG4RotMatrix( rmName );
1003 //----- Place volume in mother
1004 G4double check = (rotmat->colX().cross(rotmat->colY()))*rotmat->colZ();
1005 G4double tol = 1.0e-3;
1006 //---- Check that matrix is ortogonal
1007 if (1-std::abs(check)>tol)
1008 {
1009 G4cerr << " Matrix : " << rmName << " " << rotmat->colX()
1010 << " " << rotmat->colY() << " " << rotmat->colZ() << G4endl
1011 << " product x X y * z = " << check << " x X y "
1012 << rotmat->colX().cross(rotmat->colY()) << G4endl;
1013 G4String ErrMessage = "Rotation is not ortogonal " + rmName + " !";
1014 G4Exception("G4tgbVolume::ConstructG4PhysVol()",
1015 "InvalidSetup", FatalException, ErrMessage);
1016 //---- Check if it is reflection
1017 }
1018 else if (1+check<=tol)
1019 {
1020 G4Translate3D transl = place->GetPlacement();
1021 G4Transform3D trfrm = transl * G4Rotate3D(*rotmat);
1022 physvol = (G4ReflectionFactory::Instance()->Place(trfrm, GetName(),
1023 const_cast<G4LogicalVolume*>(currentLV),
1024 const_cast<G4LogicalVolume*>(parentLV),
1025 false, copyNo, false )).first;
1026 }
1027 else
1028 {
1029#ifdef G4VERBOSE
1030 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1031 {
1032 G4cout << "Construction new G4VPhysicalVolume"
1033 << " through G4ReflectionFactory " << GetName()
1034 << " in volume " << parentLV->GetName()
1035 << " copyNo " << copyNo
1036 << " position " << place->GetPlacement()
1037 << " ROT " << rotmat->colX()
1038 << " " << rotmat->colY()
1039 << " " << rotmat->colZ() << G4endl;
1040 }
1041#endif
1042 physvol = new G4PVPlacement( rotmat, place->GetPlacement(),
1043 const_cast<G4LogicalVolume*>(currentLV),
1044 GetName(),
1045 const_cast<G4LogicalVolume*>(parentLV),
1046 false, copyNo,
1047 theTgrVolume->GetCheckOverlaps());
1048 }
1049
1050 //--------------- If it is G4tgrPlaceParam
1051 }
1052 else if( place->GetType() == "PlaceParam" )
1053 {
1054 G4tgrPlaceParameterisation* dp = (G4tgrPlaceParameterisation*)(place);
1055
1056 //----- See what parameterisation type
1057#ifdef G4VERBOSE
1058 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
1059 {
1060 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1061 << " param: " << GetName() << " in " << parentLV->GetName()
1062 << " param type= " << dp->GetParamType() << G4endl;
1063 }
1064#endif
1065
1066 G4tgbPlaceParameterisation * param=0;
1067
1068 if( (dp->GetParamType() == "CIRCLE")
1069 || (dp->GetParamType() == "CIRCLE_XY")
1070 || (dp->GetParamType() == "CIRCLE_XZ")
1071 || (dp->GetParamType() == "CIRCLE_YZ") )
1072 {
1073 param = new G4tgbPlaceParamCircle(dp);
1074
1075 }
1076 else if( (dp->GetParamType() == "LINEAR")
1077 || (dp->GetParamType() == "LINEAR_X")
1078 || (dp->GetParamType() == "LINEAR_Y")
1079 || (dp->GetParamType() == "LINEAR_Z") )
1080 {
1081 param = new G4tgbPlaceParamLinear(dp);
1082
1083 }
1084 else if( (dp->GetParamType() == "SQUARE")
1085 || (dp->GetParamType() == "SQUARE_XY")
1086 || (dp->GetParamType() == "SQUARE_XZ")
1087 || (dp->GetParamType() == "SQUARE_YZ") )
1088 {
1089 param = new G4tgbPlaceParamSquare(dp);
1090 }
1091 else
1092 {
1093 G4String ErrMessage = "Parameterisation has wrong type, TYPE: "
1094 + G4String(dp->GetParamType()) + " !";
1095 G4Exception("G4tgbVolume::ConstructG4PhysVol", "WrongArgument",
1096 FatalException, ErrMessage);
1097 return 0;
1098 }
1099#ifdef G4VERBOSE
1100 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1101 {
1102 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1103 << " New G4PVParameterised: " << GetName() << " vol "
1104 << currentLV->GetName() << " in vol " << parentLV->GetName()
1105 << " axis " << param->GetAxis() << " nCopies "
1106 << param->GetNCopies() << G4endl;
1107 }
1108#endif
1109 physvol = new G4PVParameterised(GetName(),
1110 const_cast<G4LogicalVolume*>(currentLV),
1111 const_cast<G4LogicalVolume*>(parentLV),
1112 EAxis(param->GetAxis()),
1113 param->GetNCopies(), param);
1114#ifdef G4VERBOSE
1115 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1116 {
1117 G4cout << " Constructing new G4PVParameterised: "
1118 << physvol->GetName() << " in volume " << parentLV->GetName()
1119 << " N copies " << param->GetNCopies()
1120 << " axis " << param->GetAxis() << G4endl;
1121 }
1122#endif
1123
1124 }
1125 else if( place->GetType() == "PlaceReplica" )
1126 {
1127 //--------------- If it is PlaceReplica
1128 G4tgrPlaceDivRep* dpr = (G4tgrPlaceDivRep*)place;
1129
1130#ifdef G4VERBOSE
1131 if( G4tgrMessenger::GetVerboseLevel() >= 2 )
1132 {
1133 G4cout << " G4tgbVolume::ConstructG4PhysVol() -" << G4endl
1134 << " replica" << " " << currentLV->GetName()
1135 << " in " << parentLV->GetName()
1136 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth()
1137 << " offset " << dpr->GetOffset() << G4endl;
1138 }
1139#endif
1140 physvol = new G4PVReplica(GetName(),
1141 const_cast<G4LogicalVolume*>(currentLV),
1142 const_cast<G4LogicalVolume*>(parentLV),
1143 EAxis(dpr->GetAxis()), dpr->GetNDiv(),
1144 dpr->GetWidth(), dpr->GetOffset());
1145#ifdef G4VERBOSE
1146 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1147 {
1148 G4cout << " Constructing new G4PVReplica: "
1149 << currentLV->GetName()
1150 << " in " << parentLV->GetName()
1151 << " NDiv " << dpr->GetNDiv() << " Width " << dpr->GetWidth()
1152 << " offset " << dpr->GetOffset() << G4endl;
1153 }
1154#endif
1155 }
1156 }
1157 else if( theTgrVolume->GetType() == "VOLDivision" )
1158 {
1159 G4tgrVolumeDivision* volr = (G4tgrVolumeDivision*)theTgrVolume;
1160 G4tgrPlaceDivRep* placeDiv = volr->GetPlaceDivision() ;
1161 G4VSolid* solid = BuildSolidForDivision( parentLV->GetSolid(), placeDiv->GetAxis() );
1162 G4Material* mate = G4tgbMaterialMgr::GetInstance()
1163 ->FindOrBuildG4Material( theTgrVolume->GetMaterialName() );
1164 G4LogicalVolume* divLV = new G4LogicalVolume(solid,
1165 const_cast<G4Material*>(mate),
1166 GetName() );
1167#ifdef G4VERBOSE
1168 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1169 {
1170 G4cout << " Constructed new G4LogicalVolume for division: "
1171 << divLV->GetName() << " mate " << mate->GetName() << G4endl;
1172 }
1173#endif
1174
1175 G4DivType divType = placeDiv->GetDivType();
1176 switch (divType)
1177 {
1178 case DivByNdiv:
1179 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1180 const_cast<G4LogicalVolume*>(parentLV),
1181 placeDiv->GetAxis(), placeDiv->GetNDiv(),
1182 placeDiv->GetOffset());
1183#ifdef G4VERBOSE
1184 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1185 {
1186 G4cout << " Constructing new G4PVDivision by number of divisions: "
1187 << GetName() << " in " << parentLV->GetName()
1188 << " axis " << placeDiv->GetAxis()
1189 << " Ndiv " << placeDiv->GetNDiv()
1190 << " offset " << placeDiv->GetOffset() << G4endl;
1191 }
1192#endif
1193 break;
1194 case DivByWidth:
1195 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1196 const_cast<G4LogicalVolume*>(parentLV),
1197 placeDiv->GetAxis(), placeDiv->GetWidth(),
1198 placeDiv->GetOffset());
1199#ifdef G4VERBOSE
1200 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1201 {
1202 G4cout << " Constructing new G4PVDivision by width: "
1203 << GetName() << " in " << parentLV->GetName()
1204 << " axis " << placeDiv->GetAxis()
1205 << " width " << placeDiv->GetWidth()
1206 << " offset " << placeDiv->GetOffset() << G4endl;
1207 }
1208#endif
1209 break;
1210 case DivByNdivAndWidth:
1211 physvol = new G4PVDivision(GetName(), (G4LogicalVolume*)divLV,
1212 const_cast<G4LogicalVolume*>(parentLV),
1213 placeDiv->GetAxis(), placeDiv->GetNDiv(),
1214 placeDiv->GetWidth(),
1215 placeDiv->GetOffset());
1216#ifdef G4VERBOSE
1217 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1218 {
1219 G4cout << " Constructing new G4PVDivision by width"
1220 << " and number of divisions: "
1221 << GetName() << " in " << parentLV->GetName()
1222 << " axis " << placeDiv->GetAxis()
1223 << " Ndiv " << placeDiv->GetNDiv()
1224 << " width " << placeDiv->GetWidth()
1225 << " offset " << placeDiv->GetOffset() << G4endl;
1226 }
1227#endif
1228 break;
1229 }
1230 }
1231 else if( theTgrVolume->GetType() == "VOLAssembly" )
1232 {
1233 // Define one layer as one assembly volume
1234 G4tgrVolumeAssembly * tgrAssembly = (G4tgrVolumeAssembly *)theTgrVolume;
1235
1236 if( !theG4AssemblyVolume )
1237 {
1238 theG4AssemblyVolume = new G4AssemblyVolume;
1239#ifdef G4VERBOSE
1240 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1241 {
1242 G4cout << " Constructing new G4AssemblyVolume: "
1243 << " number of assembly components "
1244 << tgrAssembly->GetNoComponents() << G4endl;
1245 }
1246#endif
1247 G4tgbVolumeMgr* g4vmgr = G4tgbVolumeMgr::GetInstance();
1248 for( G4int ii = 0; ii < tgrAssembly->GetNoComponents(); ii++ )
1249 {
1250 // Rotation and translation of a plate inside the assembly
1251
1252 G4ThreeVector transl = tgrAssembly->GetComponentPos(ii);
1253 G4String rmName = tgrAssembly->GetComponentRM(ii);
1254 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance()
1255 ->FindOrBuildG4RotMatrix( rmName );
1256
1257 //----- Get G4LogicalVolume of component
1258 G4String lvname = tgrAssembly->GetComponentName(ii);
1259 G4LogicalVolume* logvol = g4vmgr->FindG4LogVol( lvname);
1260 if( logvol == 0 )
1261 {
1262 g4vmgr->FindVolume( lvname )->ConstructG4Volumes( 0, 0);
1263 logvol = g4vmgr->FindG4LogVol( lvname, true );
1264 }
1265 // Fill the assembly by the plates
1266 theG4AssemblyVolume->AddPlacedVolume( logvol, transl, rotmat );
1267#ifdef G4VERBOSE
1268 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1269 {
1270 G4cout << " G4AssemblyVolume->AddPlacedVolume " << ii
1271 << " " << logvol->GetName()
1272 << " translation " << transl
1273 << " rotmat " << rotmat->colX()
1274 << " " << rotmat->colY()
1275 << " " << rotmat->colZ() << G4endl;
1276 }
1277#endif
1278 }
1279 }
1280
1281 // Rotation and Translation of the assembly inside the world
1282
1283 G4tgrPlaceSimple* placeSimple = (G4tgrPlaceSimple*)place;
1284 G4String rmName = placeSimple->GetRotMatName();
1285 G4RotationMatrix* rotmat = G4tgbRotationMatrixMgr::GetInstance()
1286 ->FindOrBuildG4RotMatrix( rmName );
1287 G4ThreeVector transl = place->GetPlacement();
1288
1289 G4LogicalVolume* parentLV_nonconst =
1290 const_cast<G4LogicalVolume*>(parentLV);
1291 theG4AssemblyVolume->MakeImprint( parentLV_nonconst, transl, rotmat );
1292
1293 }
1294 else // If it is G4tgrVolumeAssembly
1295 {
1296 G4String ErrMessage = "Volume type not supported: "
1297 + theTgrVolume->GetType() + ", sorry...";
1298 G4Exception("G4tgbVolume::ConstructG4PhysVol()", "NotImplemented",
1299 FatalException, ErrMessage);
1300 }
1301 }
1302
1303 return physvol;
1304}
1305
1306
1307//-------------------------------------------------------------------
1308G4VSolid* G4tgbVolume::BuildSolidForDivision( G4VSolid* parentSolid, EAxis axis )
1309{
1310 G4VSolid* solid=0;
1311 G4double redf = (parentSolid->GetExtent().GetXmax()-parentSolid->GetExtent().GetXmin());
1312 redf = std::min(redf,parentSolid->GetExtent().GetYmax()-parentSolid->GetExtent().GetYmin());
1313 redf = std::min(redf,parentSolid->GetExtent().GetZmax()-parentSolid->GetExtent().GetZmin());
1314 redf *= 0.001; //make daugther much smaller, to fit in parent
1315
1316 if( parentSolid->GetEntityType() == "G4Box" )
1317 {
1318 G4Box* psolid = (G4Box*)(parentSolid);
1319 solid = new G4Box(GetName(), psolid->GetXHalfLength()*redf,
1320 psolid->GetZHalfLength()*redf,
1321 psolid->GetZHalfLength()*redf);
1322 }
1323 else if ( parentSolid->GetEntityType() == "G4Tubs" )
1324 {
1325 G4Tubs* psolid = (G4Tubs*)(parentSolid);
1326 solid = new G4Tubs( GetName(), psolid->GetInnerRadius()*redf,
1327 psolid->GetOuterRadius()*redf,
1328 psolid->GetZHalfLength()*redf,
1329 psolid->GetSPhi(), psolid->GetDPhi());
1330 }
1331 else if ( parentSolid->GetEntityType() == "G4Cons" )
1332 {
1333 G4Cons* psolid = (G4Cons*)(parentSolid);
1334 solid = new G4Cons( GetName(), psolid->GetInnerRadiusMinusZ()*redf,
1335 psolid->GetOuterRadiusMinusZ()*redf,
1336 psolid->GetInnerRadiusPlusZ()*redf,
1337 psolid->GetOuterRadiusPlusZ()*redf,
1338 psolid->GetZHalfLength()*redf,
1339 psolid->GetSPhi(), psolid->GetDPhi());
1340 }
1341 else if ( parentSolid->GetEntityType() == "G4Trd" )
1342 {
1343 G4Trd* psolid = (G4Trd*)(parentSolid);
1344 G4double mpDx1 = psolid->GetXHalfLength1();
1345 G4double mpDx2 = psolid->GetXHalfLength2();
1346
1347 if( axis == kXAxis && std::fabs(mpDx1 - mpDx2) > G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() )
1348 {
1349 solid = new G4Trap( GetName(), psolid->GetZHalfLength()*redf,
1350 psolid->GetYHalfLength1()*redf,
1351 psolid->GetXHalfLength2()*redf,
1352 psolid->GetXHalfLength1()*redf );
1353 }
1354 else
1355 {
1356 solid = new G4Trd( GetName(), psolid->GetXHalfLength1()*redf,
1357 psolid->GetXHalfLength2()*redf,
1358 psolid->GetYHalfLength1()*redf,
1359 psolid->GetYHalfLength2()*redf,
1360 psolid->GetZHalfLength()*redf);
1361 }
1362
1363 }
1364 else if ( parentSolid->GetEntityType() == "G4Para" )
1365 {
1366 G4Para* psolid = (G4Para*)(parentSolid);
1367 solid = new G4Para( GetName(), psolid->GetXHalfLength()*redf,
1368 psolid->GetYHalfLength()*redf,
1369 psolid->GetZHalfLength()*redf,
1370 std::atan(psolid->GetTanAlpha()),
1371 psolid->GetSymAxis().theta(),
1372 psolid->GetSymAxis().phi() );
1373 }
1374 else if ( parentSolid->GetEntityType() == "G4Polycone" )
1375 {
1376 G4Polycone* psolid = (G4Polycone*)(parentSolid);
1377 G4PolyconeHistorical origParam = *(psolid->GetOriginalParameters());
1378 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ )
1379 {
1380 origParam.Rmin[ii] = origParam.Rmin[ii]*redf;
1381 origParam.Rmax[ii] = origParam.Rmax[ii]*redf;
1382 }
1383 solid = new G4Polycone( GetName(), psolid->GetStartPhi(),
1384 psolid->GetEndPhi(),
1385 origParam.Num_z_planes, origParam.Z_values,
1386 origParam.Rmin, origParam.Rmax);
1387
1388 }
1389 else if ( parentSolid->GetEntityType() == "G4Polyhedra" )
1390 {
1391 G4Polyhedra* psolid = (G4Polyhedra*)(parentSolid);
1392 G4PolyhedraHistorical origParam = *(psolid->GetOriginalParameters());
1393 for( G4int ii = 0; ii < origParam.Num_z_planes; ii++ )
1394 {
1395 origParam.Rmin[ii] = origParam.Rmin[ii]*redf;
1396 origParam.Rmax[ii] = origParam.Rmax[ii]*redf;
1397 }
1398 solid = new G4Polyhedra( GetName(), psolid->GetStartPhi(),
1399 psolid->GetEndPhi(),
1400 psolid->GetNumSide(),
1401 origParam.Num_z_planes, origParam.Z_values,
1402 origParam.Rmin, origParam.Rmax);
1403 }
1404 else
1405 {
1406 G4String ErrMessage = "Solid type not supported. VOLUME= " + GetName()
1407 + " Solid type= " + parentSolid->GetEntityType() + "\n"
1408 + "Only supported types are: G4Box, G4Tubs, G4Cons,"
1409 + " G4Trd, G4Para, G4Polycone, G4Polyhedra.";
1410 G4Exception("G4tgbVolume::BuildSolidForDivision()", "NotImplemented",
1411 FatalException, ErrMessage);
1412 return 0;
1413 }
1414
1415#ifdef G4VERBOSE
1416 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
1417 {
1418 G4cout << " Constructing new G4Solid for division: "
1419 << *solid << G4endl;
1420 }
1421#endif
1422 return solid;
1423}
1424
Note: See TracBrowser for help on using the repository browser.