00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "G4AssemblyVolume.hh"
00035 #include "G4PVPlacement.hh"
00036 #include "G4RotationMatrix.hh"
00037 #include "G4AffineTransform.hh"
00038 #include "G4LogicalVolume.hh"
00039 #include "G4VPhysicalVolume.hh"
00040 #include "G4ReflectionFactory.hh"
00041
00042 #include <sstream>
00043
00044 unsigned int G4AssemblyVolume::fsInstanceCounter = 0;
00045
00046
00047
00048 G4AssemblyVolume::G4AssemblyVolume()
00049 : fAssemblyID( 0 )
00050 {
00051 InstanceCountPlus();
00052 SetAssemblyID( GetInstanceCount() );
00053 SetImprintsCount( 0 );
00054 }
00055
00056
00057
00058 G4AssemblyVolume::G4AssemblyVolume( G4LogicalVolume* volume,
00059 G4ThreeVector& translation,
00060 G4RotationMatrix* rotation )
00061 : fAssemblyID( 0 )
00062 {
00063 InstanceCountPlus();
00064 SetAssemblyID( GetInstanceCount() );
00065 SetImprintsCount( 0 );
00066 AddPlacedVolume(volume, translation, rotation);
00067 }
00068
00069
00070
00071 G4AssemblyVolume::~G4AssemblyVolume()
00072 {
00073 unsigned int howmany = fTriplets.size();
00074 if( howmany != 0 )
00075 {
00076 for( unsigned int i = 0; i < howmany; i++ )
00077 {
00078 G4RotationMatrix* pRotToClean = fTriplets[i].GetRotation();
00079 if( pRotToClean != 0 )
00080 {
00081 delete pRotToClean;
00082 }
00083 }
00084 }
00085 fTriplets.clear();
00086
00087 howmany = fPVStore.size();
00088 if( howmany != 0 )
00089 {
00090 for( unsigned int j = 0; j < howmany; j++ )
00091 {
00092 delete fPVStore[j];
00093 }
00094 }
00095 fPVStore.clear();
00096 InstanceCountMinus();
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void G4AssemblyVolume::AddPlacedVolume( G4LogicalVolume* pVolume,
00110 G4ThreeVector& translation,
00111 G4RotationMatrix* pRotation )
00112 {
00113 G4RotationMatrix* toStore = new G4RotationMatrix;
00114
00115 if( pRotation != 0 ) { *toStore = *pRotation; }
00116
00117 G4AssemblyTriplet toAdd( pVolume, translation, toStore );
00118 fTriplets.push_back( toAdd );
00119 }
00120
00121
00122
00123 void G4AssemblyVolume::AddPlacedVolume( G4LogicalVolume* pVolume,
00124 G4Transform3D& transformation )
00125 {
00126
00127 G4Scale3D scale;
00128 G4Rotate3D rotation;
00129 G4Translate3D translation;
00130 transformation.getDecomposition(scale, rotation, translation);
00131
00132 G4ThreeVector v = translation.getTranslation();
00133 G4RotationMatrix* r = new G4RotationMatrix;
00134 *r = rotation.getRotation();
00135
00136 G4bool isReflection = false;
00137 if (scale(0,0)*scale(1,1)*scale(2,2) < 0.) { isReflection = true; }
00138
00139 G4AssemblyTriplet toAdd( pVolume, v, r, isReflection );
00140 fTriplets.push_back( toAdd );
00141 }
00142
00143
00144
00145
00146 void G4AssemblyVolume::AddPlacedAssembly( G4AssemblyVolume* pAssembly,
00147 G4ThreeVector& translation,
00148 G4RotationMatrix* pRotation )
00149 {
00150 G4RotationMatrix* toStore = new G4RotationMatrix;
00151
00152 if( pRotation != 0 ) { *toStore = *pRotation; }
00153
00154 G4AssemblyTriplet toAdd( pAssembly, translation, toStore );
00155 fTriplets.push_back( toAdd );
00156 }
00157
00158
00159
00160
00161 void G4AssemblyVolume::AddPlacedAssembly( G4AssemblyVolume* pAssembly,
00162 G4Transform3D& transformation )
00163 {
00164
00165
00166 G4Scale3D scale;
00167 G4Rotate3D rotation;
00168 G4Translate3D translation;
00169 transformation.getDecomposition(scale, rotation, translation);
00170
00171 G4ThreeVector v = translation.getTranslation();
00172 G4RotationMatrix* r = new G4RotationMatrix;
00173 *r = rotation.getRotation();
00174
00175 G4bool isReflection = false;
00176 if (scale(0,0)*scale(1,1)*scale(2,2) < 0.) { isReflection = true; }
00177
00178 G4AssemblyTriplet toAdd( pAssembly, v, r, isReflection );
00179 fTriplets.push_back( toAdd );
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void G4AssemblyVolume::MakeImprint( G4AssemblyVolume* pAssembly,
00221 G4LogicalVolume* pMotherLV,
00222 G4Transform3D& transformation,
00223 G4int copyNumBase,
00224 G4bool surfCheck )
00225 {
00226 unsigned int numberOfDaughters;
00227
00228 if( copyNumBase == 0 )
00229 {
00230 numberOfDaughters = pMotherLV->GetNoDaughters();
00231 }
00232 else
00233 {
00234 numberOfDaughters = copyNumBase;
00235 }
00236
00237
00238
00239 numberOfDaughters++;
00240
00241 ImprintsCountPlus();
00242
00243 std::vector<G4AssemblyTriplet> triplets = pAssembly->fTriplets;
00244
00245 for( unsigned int i = 0; i < triplets.size(); i++ )
00246 {
00247 G4Transform3D Ta( *(triplets[i].GetRotation()),
00248 triplets[i].GetTranslation() );
00249 if ( triplets[i].IsReflection() ) { Ta = Ta * G4ReflectZ3D(); }
00250
00251 G4Transform3D Tfinal = transformation * Ta;
00252
00253 if ( triplets[i].GetVolume() )
00254 {
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 std::stringstream pvName;
00266 pvName << "av_"
00267 << GetAssemblyID()
00268 << "_impr_"
00269 << GetImprintsCount()
00270 << "_"
00271 << triplets[i].GetVolume()->GetName().c_str()
00272 << "_pv_"
00273 << i
00274 << std::ends;
00275
00276
00277
00278
00279
00280 G4PhysicalVolumesPair pvPlaced
00281 = G4ReflectionFactory::Instance()->Place( Tfinal,
00282 pvName.str().c_str(),
00283 triplets[i].GetVolume(),
00284 pMotherLV,
00285 false,
00286 numberOfDaughters + i,
00287 surfCheck );
00288
00289
00290
00291 fPVStore.push_back( pvPlaced.first );
00292 if ( pvPlaced.second ) { fPVStore.push_back( pvPlaced.second ); }
00293 }
00294 else if ( triplets[i].GetAssembly() )
00295 {
00296
00297
00298 MakeImprint( triplets[i].GetAssembly(), pMotherLV,
00299 Tfinal, i*100+copyNumBase, surfCheck );
00300 }
00301 else
00302 {
00303 G4Exception("G4AssemblyVolume::MakeImprint(..)",
00304 "GeomVol0003", FatalException,
00305 "Triplet has no volume and no assembly");
00306 }
00307 }
00308 }
00309
00310 void G4AssemblyVolume::MakeImprint( G4LogicalVolume* pMotherLV,
00311 G4ThreeVector& translationInMother,
00312 G4RotationMatrix* pRotationInMother,
00313 G4int copyNumBase,
00314 G4bool surfCheck )
00315 {
00316
00317
00318
00319
00320
00321
00322
00323
00324 if( pRotationInMother == 0 )
00325 {
00326
00327
00328 pRotationInMother =
00329 const_cast<G4RotationMatrix*>( &G4RotationMatrix::IDENTITY );
00330 }
00331
00332 G4Transform3D transform( *pRotationInMother,
00333 translationInMother );
00334 MakeImprint(this, pMotherLV, transform, copyNumBase, surfCheck);
00335 }
00336
00337 void G4AssemblyVolume::MakeImprint( G4LogicalVolume* pMotherLV,
00338 G4Transform3D& transformation,
00339 G4int copyNumBase,
00340 G4bool surfCheck )
00341 {
00342
00343
00344
00345
00346
00347
00348 MakeImprint(this, pMotherLV, transformation, copyNumBase, surfCheck);
00349 }
00350
00351 unsigned int G4AssemblyVolume::GetInstanceCount() const
00352 {
00353 return G4AssemblyVolume::fsInstanceCounter;
00354 }
00355
00356 void G4AssemblyVolume::SetInstanceCount( unsigned int value )
00357 {
00358 G4AssemblyVolume::fsInstanceCounter = value;
00359 }
00360
00361 void G4AssemblyVolume::InstanceCountPlus()
00362 {
00363 G4AssemblyVolume::fsInstanceCounter++;
00364 }
00365
00366 void G4AssemblyVolume::InstanceCountMinus()
00367 {
00368 G4AssemblyVolume::fsInstanceCounter--;
00369 }