Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // 23 // >> 24 // $Id: G4RayTracer.cc,v 1.13 2003/09/18 11:14:04 johna Exp $ >> 25 // GEANT4 tag $Name: geant4-06-00-patch-01 $ >> 26 // >> 27 // >> 28 // >> 29 27 30 28 #include "G4RayTracer.hh" 31 #include "G4RayTracer.hh" 29 #include "G4RayTracerFeatures.hh" 32 #include "G4RayTracerFeatures.hh" 30 #include "G4RayTracerSceneHandler.hh" 33 #include "G4RayTracerSceneHandler.hh" 31 #include "G4RayTracerViewer.hh" 34 #include "G4RayTracerViewer.hh" >> 35 #include "G4EventManager.hh" >> 36 #include "G4RTMessenger.hh" >> 37 #include "G4RayShooter.hh" >> 38 #include "G4VFigureFileMaker.hh" >> 39 #include "G4RTTrackingAction.hh" >> 40 #include "G4RTSteppingAction.hh" >> 41 #include "G4RayTrajectory.hh" >> 42 #include "G4RayTrajectoryPoint.hh" >> 43 #include "G4RTJpegMaker.hh" >> 44 #include "G4RTSimpleScanner.hh" >> 45 #include "G4GeometryManager.hh" >> 46 #include "G4SDManager.hh" >> 47 #include "G4StateManager.hh" >> 48 #include "G4Event.hh" >> 49 #include "G4TrajectoryContainer.hh" >> 50 #include "G4Colour.hh" >> 51 #include "G4VisAttributes.hh" >> 52 #include "G4UImanager.hh" >> 53 #include "G4TransportationManager.hh" >> 54 #include "G4RegionStore.hh" >> 55 #include "G4ProductionCutsTable.hh" 32 56 33 #define G4warn G4cout << 57 G4RayTracer::G4RayTracer(G4VFigureFileMaker* figMaker, 34 << 58 G4VRTScanner* scanner) 35 G4RayTracer::G4RayTracer(): << 59 :G4VGraphicsSystem("RayTracer","RayTracer",RAYTRACER_FEATURES, 36 G4VGraphicsSystem("RayTracer", << 60 G4VGraphicsSystem::threeD) 37 "RayTracer", << 38 RAYTRACER_FEATURES, << 39 G4VGraphicsSystem::threeD) << 40 , theRayTracer(nullptr) << 41 { 61 { >> 62 theFigMaker = figMaker; >> 63 if(!theFigMaker) theFigMaker = new G4RTJpegMaker(); >> 64 theScanner = scanner; >> 65 if(!theScanner) theScanner = new G4RTSimpleScanner; >> 66 theRayShooter = new G4RayShooter(); >> 67 theRayTracerEventAction = 0; >> 68 theRayTracerStackingAction = 0; >> 69 theRayTracerTrackingAction = new G4RTTrackingAction(); >> 70 theRayTracerSteppingAction = new G4RTSteppingAction(); >> 71 theMessenger = new G4RTMessenger(this,theRayTracerSteppingAction); >> 72 theEventManager = G4EventManager::GetEventManager(); >> 73 >> 74 nColumn = 640; >> 75 nRow = 640; >> 76 >> 77 eyePosition = G4ThreeVector(1.*m,1.*m,1.*m); >> 78 targetPosition = G4ThreeVector(0.,0.,0.); >> 79 lightDirection = G4ThreeVector(-0.1,-0.2,-0.3).unit(); >> 80 viewSpan = 5.0*deg; >> 81 headAngle = 270.*deg; >> 82 attenuationLength = 1.0*m; >> 83 >> 84 distortionOn = false; >> 85 >> 86 backgroundColour = G4Colour(1.,1.,1.); 42 } 87 } 43 88 44 G4RayTracer::~G4RayTracer() 89 G4RayTracer::~G4RayTracer() 45 {} << 90 { >> 91 delete theRayShooter; >> 92 delete theRayTracerTrackingAction; >> 93 delete theRayTracerSteppingAction; >> 94 delete theMessenger; >> 95 delete theScanner; >> 96 delete theFigMaker; >> 97 } >> 98 >> 99 void G4RayTracer::Trace(G4String fileName) >> 100 { >> 101 G4StateManager* theStateMan = G4StateManager::GetStateManager(); >> 102 G4ApplicationState currentState = theStateMan->GetCurrentState(); >> 103 if(currentState!=G4State_Idle) >> 104 { >> 105 G4cerr << "Illegal application state - Trace() ignored." << G4endl; >> 106 return; >> 107 } >> 108 >> 109 if(!theFigMaker) >> 110 { >> 111 G4cerr << "Figure file maker class is not specified - Trace() ignored." << G4endl; >> 112 return; >> 113 } >> 114 >> 115 G4UImanager* UI = G4UImanager::GetUIpointer(); >> 116 G4int storeTrajectory = UI->GetCurrentIntValue("/tracking/storeTrajectory"); >> 117 if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 1"); >> 118 >> 119 >> 120 G4ThreeVector tmpVec = targetPosition - eyePosition; >> 121 eyeDirection = tmpVec.unit(); >> 122 colorR = new unsigned char[nColumn*nRow]; >> 123 colorG = new unsigned char[nColumn*nRow]; >> 124 colorB = new unsigned char[nColumn*nRow]; >> 125 >> 126 StoreUserActions(); >> 127 G4bool succeeded = CreateBitMap(); >> 128 if(succeeded) >> 129 { CreateFigureFile(fileName); } >> 130 else >> 131 { G4cerr << "Could not create figure file" << G4endl; >> 132 G4cerr << "You might set the eye position outside of the world volume" << G4endl; } >> 133 RestoreUserActions(); >> 134 >> 135 if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 0"); >> 136 >> 137 delete [] colorR; >> 138 delete [] colorG; >> 139 delete [] colorB; >> 140 } 46 141 47 G4VSceneHandler* G4RayTracer::CreateSceneHandl 142 G4VSceneHandler* G4RayTracer::CreateSceneHandler (const G4String& name) { 48 G4VSceneHandler* pScene = new G4RayTracerSce 143 G4VSceneHandler* pScene = new G4RayTracerSceneHandler (*this, name); >> 144 G4cout << G4RayTracerSceneHandler::GetSceneCount () >> 145 << ' ' << fName << " scene handlers extanct." << G4endl; 49 return pScene; 146 return pScene; 50 } 147 } 51 148 52 G4VViewer* G4RayTracer::CreateViewer (G4VScene 149 G4VViewer* G4RayTracer::CreateViewer (G4VSceneHandler& sceneHandler, 53 const G4String& name) { 150 const G4String& name) { 54 G4VViewer* pViewer = new G4RayTracerViewer << 151 G4VViewer* pView = new G4RayTracerViewer (sceneHandler, name); 55 (sceneHandler, name, theRayTracer); << 152 return pView; 56 if (pViewer) { << 153 } 57 if (pViewer->GetViewId() < 0) { << 154 58 G4warn << << 155 void G4RayTracer::StoreUserActions() 59 "G4RayTracer::CreateViewer: ERROR flag << 156 { 60 " view id in G4RayTracerViewer creatio << 157 theUserEventAction = theEventManager->GetUserEventAction(); 61 "\n Destroying view and returning null << 158 theUserStackingAction = theEventManager->GetUserStackingAction(); 62 << G4endl; << 159 theUserTrackingAction = theEventManager->GetUserTrackingAction(); 63 delete pViewer; << 160 theUserSteppingAction = theEventManager->GetUserSteppingAction(); 64 pViewer = 0; << 161 65 } << 162 theEventManager->SetUserAction(theRayTracerEventAction); 66 } << 163 theEventManager->SetUserAction(theRayTracerStackingAction); 67 else { << 164 theEventManager->SetUserAction(theRayTracerTrackingAction); 68 G4warn << << 165 theEventManager->SetUserAction(theRayTracerSteppingAction); 69 "G4RayTracer::CreateViewer: ERROR: null << 166 70 << G4endl; << 167 G4SDManager* theSDMan = G4SDManager::GetSDMpointerIfExist(); >> 168 if(theSDMan) >> 169 { theSDMan->Activate("/",false); } >> 170 >> 171 G4GeometryManager* theGeomMan = G4GeometryManager::GetInstance(); >> 172 theGeomMan->OpenGeometry(); >> 173 theGeomMan->CloseGeometry(true); >> 174 } >> 175 >> 176 void G4RayTracer::RestoreUserActions() >> 177 { >> 178 theEventManager->SetUserAction(theUserEventAction); >> 179 theEventManager->SetUserAction(theUserStackingAction); >> 180 theEventManager->SetUserAction(theUserTrackingAction); >> 181 theEventManager->SetUserAction(theUserSteppingAction); >> 182 >> 183 G4SDManager* theSDMan = G4SDManager::GetSDMpointerIfExist(); >> 184 if(theSDMan) >> 185 { theSDMan->Activate("/",true); } >> 186 } >> 187 >> 188 #include "G4ProcessManager.hh" >> 189 #include "G4ProcessVector.hh" >> 190 #include "G4Geantino.hh" >> 191 >> 192 G4bool G4RayTracer::CreateBitMap() >> 193 { >> 194 G4int iEvent = 0; >> 195 G4double stepAngle = viewSpan/100.; >> 196 G4double viewSpanX = stepAngle*nColumn; >> 197 G4double viewSpanY = stepAngle*nRow; >> 198 G4bool succeeded; >> 199 >> 200 // Confirm process(es) of Geantino is initialized >> 201 G4RegionStore::GetInstance()->UpdateMaterialList(); >> 202 G4ProductionCutsTable::GetProductionCutsTable()->UpdateCoupleTable(); >> 203 G4ProcessVector* pVector >> 204 = G4Geantino::GeantinoDefinition()->GetProcessManager()->GetProcessList(); >> 205 for (G4int j=0; j < pVector->size(); ++j) { >> 206 (*pVector)[j]->BuildPhysicsTable(*(G4Geantino::GeantinoDefinition())); >> 207 } >> 208 >> 209 // Close geometry and set the application state >> 210 G4GeometryManager* geomManager = G4GeometryManager::GetInstance(); >> 211 geomManager->OpenGeometry(); >> 212 geomManager->CloseGeometry(1,0); >> 213 >> 214 G4ThreeVector center(0,0,0); >> 215 G4Navigator* navigator = >> 216 G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking(); >> 217 navigator->LocateGlobalPointAndSetup(center,0,false); >> 218 >> 219 G4StateManager* theStateMan = G4StateManager::GetStateManager(); >> 220 theStateMan->SetNewState(G4State_GeomClosed); >> 221 >> 222 // Event loop >> 223 theScanner->Initialize(nRow,nColumn); >> 224 G4int iRow, iColumn; >> 225 while (theScanner->Coords(iRow,iColumn)) { >> 226 G4int iCoord = iRow * nColumn + iColumn; >> 227 G4Event* anEvent = new G4Event(iEvent++); >> 228 >> 229 G4double angleX = -(viewSpanX/2. - iColumn*stepAngle); >> 230 G4double angleY = viewSpanY/2. - iRow*stepAngle; >> 231 G4ThreeVector rayDirection; >> 232 if(distortionOn) >> 233 { >> 234 rayDirection = G4ThreeVector(tan(angleX)/cos(angleY),-tan(angleY)/cos(angleX),1.0); >> 235 } >> 236 else >> 237 { >> 238 rayDirection = G4ThreeVector(tan(angleX),-tan(angleY),1.0); >> 239 } >> 240 rayDirection.rotateZ(headAngle); >> 241 rayDirection.rotateUz(eyeDirection); >> 242 G4ThreeVector rayPosition(eyePosition); >> 243 G4bool interceptable = true; >> 244 // Check if rayPosition is in the world. >> 245 G4VPhysicalVolume* pWorld = >> 246 G4TransportationManager::GetTransportationManager()-> >> 247 GetNavigatorForTracking()->GetWorldVolume (); >> 248 EInside whereisit = >> 249 pWorld->GetLogicalVolume()->GetSolid()->Inside(rayPosition); >> 250 if (whereisit != kInside) { >> 251 // It's outside the world, so move it inside. >> 252 G4double outsideDistance = >> 253 pWorld->GetLogicalVolume()->GetSolid()-> >> 254 DistanceToIn(rayPosition,rayDirection); >> 255 if (outsideDistance != kInfinity) { >> 256 rayPosition = rayPosition+outsideDistance*rayDirection; >> 257 } >> 258 else { >> 259 interceptable = false; >> 260 } >> 261 } >> 262 if (interceptable) { >> 263 theRayShooter->Shoot(anEvent,rayPosition,rayDirection); >> 264 theEventManager->ProcessOneEvent(anEvent); >> 265 succeeded = GenerateColour(anEvent,iCoord); >> 266 //G4cout << iColumn << " " << iRow << " " << anEvent->GetEventID() << G4endl; >> 267 } >> 268 else { // Ray does not intercept world at all. >> 269 // Store background colour... >> 270 colorR[iCoord] = (unsigned char)(int(255*backgroundColour.GetRed())); >> 271 colorG[iCoord] = (unsigned char)(int(255*backgroundColour.GetGreen())); >> 272 colorB[iCoord] = (unsigned char)(int(255*backgroundColour.GetBlue())); >> 273 succeeded = true; >> 274 } >> 275 delete anEvent; >> 276 if(!succeeded) return false; >> 277 } >> 278 >> 279 theStateMan->SetNewState(G4State_Idle); >> 280 return true; >> 281 } >> 282 >> 283 void G4RayTracer::CreateFigureFile(G4String fileName) >> 284 { >> 285 //G4cout << nColumn << " " << nRow << G4endl; >> 286 theFigMaker->CreateFigureFile(fileName,nColumn,nRow,colorR,colorG,colorB); >> 287 } >> 288 >> 289 G4bool G4RayTracer::GenerateColour(G4Event* anEvent, G4int iCoord) >> 290 { >> 291 G4TrajectoryContainer * trajectoryContainer = anEvent->GetTrajectoryContainer(); >> 292 >> 293 G4RayTrajectory* trajectory = (G4RayTrajectory*)( (*trajectoryContainer)[0] ); >> 294 if(!trajectory) return false; >> 295 >> 296 G4int nPoint = trajectory->GetPointEntries(); >> 297 if(nPoint==0) return false; >> 298 >> 299 G4Colour rayColour; >> 300 G4Colour initialColour(backgroundColour); >> 301 if( trajectory->GetPointC(nPoint-1)->GetPostStepAtt() ) >> 302 { initialColour = GetSurfaceColour(trajectory->GetPointC(nPoint-1)); } >> 303 rayColour = Attenuate(trajectory->GetPointC(nPoint-1),initialColour); >> 304 >> 305 for(int i=nPoint-2;i>=0;i--) >> 306 { >> 307 G4Colour surfaceColour = GetSurfaceColour(trajectory->GetPointC(i)); >> 308 G4double weight = 1.0 - surfaceColour.GetAlpha(); >> 309 G4Colour mixedColour = GetMixedColour(rayColour,surfaceColour,weight); >> 310 rayColour = Attenuate(trajectory->GetPointC(i),mixedColour); 71 } 311 } 72 return pViewer; << 312 >> 313 colorR[iCoord] = (unsigned char)(int(255*rayColour.GetRed())); >> 314 colorG[iCoord] = (unsigned char)(int(255*rayColour.GetGreen())); >> 315 colorB[iCoord] = (unsigned char)(int(255*rayColour.GetBlue())); >> 316 return true; >> 317 } >> 318 >> 319 G4Colour G4RayTracer::GetMixedColour(G4Colour surfCol,G4Colour transCol,G4double weight) >> 320 { >> 321 G4double r = weight*surfCol.GetRed() + (1.-weight)*transCol.GetRed(); >> 322 G4double g = weight*surfCol.GetGreen() + (1.-weight)*transCol.GetGreen(); >> 323 G4double b = weight*surfCol.GetBlue() + (1.-weight)*transCol.GetBlue(); >> 324 G4double a = weight*surfCol.GetAlpha() + (1.-weight)*transCol.GetAlpha(); >> 325 return G4Colour(r,g,b,a); 73 } 326 } >> 327 >> 328 G4Colour G4RayTracer::GetSurfaceColour(G4RayTrajectoryPoint* point) >> 329 { >> 330 const G4VisAttributes* preAtt = point->GetPreStepAtt(); >> 331 const G4VisAttributes* postAtt = point->GetPostStepAtt(); >> 332 >> 333 G4bool preVis = ValidColour(preAtt); >> 334 G4bool postVis = ValidColour(postAtt); >> 335 >> 336 G4Colour transparent(1.,1.,1.,0.); >> 337 >> 338 if(!preVis&&!postVis) return transparent; >> 339 >> 340 G4ThreeVector normal = point->GetSurfaceNormal(); >> 341 >> 342 G4Colour preCol(1.,1.,1.); >> 343 G4Colour postCol(1.,1.,1.); >> 344 >> 345 if(preVis) >> 346 { >> 347 G4double brill = (1.0-(-lightDirection).dot(normal))/2.0; >> 348 G4double r = preAtt->GetColour().GetRed(); >> 349 G4double g = preAtt->GetColour().GetGreen(); >> 350 G4double b = preAtt->GetColour().GetBlue(); >> 351 preCol = G4Colour(r*brill,g*brill,b*brill,preAtt->GetColour().GetAlpha()); >> 352 } >> 353 else >> 354 { preCol = transparent; } >> 355 >> 356 if(postVis) >> 357 { >> 358 G4double brill = (1.0-(-lightDirection).dot(-normal))/2.0; >> 359 G4double r = postAtt->GetColour().GetRed(); >> 360 G4double g = postAtt->GetColour().GetGreen(); >> 361 G4double b = postAtt->GetColour().GetBlue(); >> 362 postCol = G4Colour(r*brill,g*brill,b*brill,postAtt->GetColour().GetAlpha()); >> 363 } >> 364 else >> 365 { postCol = transparent; } >> 366 >> 367 if(!preVis) return postCol; >> 368 if(!postVis) return preCol; >> 369 >> 370 G4double weight = 0.5; >> 371 return GetMixedColour(preCol,postCol,weight); >> 372 } >> 373 >> 374 G4Colour G4RayTracer::Attenuate(G4RayTrajectoryPoint* point, G4Colour sourceCol) >> 375 { >> 376 const G4VisAttributes* preAtt = point->GetPreStepAtt(); >> 377 >> 378 G4bool visible = ValidColour(preAtt); >> 379 if(!visible) return sourceCol; >> 380 >> 381 G4Colour objCol = preAtt->GetColour(); >> 382 G4double stepRed = objCol.GetRed(); >> 383 G4double stepGreen = objCol.GetGreen(); >> 384 G4double stepBlue = objCol.GetBlue(); >> 385 G4double stepAlpha = objCol.GetAlpha(); >> 386 G4double stepLength = point->GetStepLength(); >> 387 >> 388 G4double attenuationFuctor; >> 389 if(stepAlpha > 0.9999999){ stepAlpha = 0.9999999; } // patch to the next line >> 390 attenuationFuctor = -stepAlpha/(1.0-stepAlpha)*stepLength/attenuationLength; >> 391 >> 392 G4double KtRed = exp((1.0-stepRed)*attenuationFuctor); >> 393 G4double KtGreen = exp((1.0-stepGreen)*attenuationFuctor); >> 394 G4double KtBlue = exp((1.0-stepBlue)*attenuationFuctor); >> 395 if(KtRed>1.0){KtRed=1.0;} >> 396 if(KtGreen>1.0){KtGreen=1.0;} >> 397 if(KtBlue>1.0){KtBlue=1.0;} >> 398 return G4Colour(sourceCol.GetRed()*KtRed, >> 399 sourceCol.GetGreen()*KtGreen,sourceCol.GetBlue()*KtBlue); >> 400 } >> 401 >> 402 G4bool G4RayTracer::ValidColour(const G4VisAttributes* visAtt) >> 403 { >> 404 G4bool val = true; >> 405 if(!visAtt) >> 406 { val = false; } >> 407 else if(!(visAtt->IsVisible())) >> 408 { val = false; } >> 409 else if(visAtt->IsForceDrawingStyle() >> 410 &&(visAtt->GetForcedDrawingStyle()==G4VisAttributes::wireframe)) >> 411 { val = false; } >> 412 return val; >> 413 } >> 414 74 415