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.11 2002/12/11 16:00:00 johna Exp $ >> 25 // GEANT4 tag $Name: geant4-05-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 "G4GeometryManager.hh" >> 45 #include "G4SDManager.hh" >> 46 #include "G4StateManager.hh" >> 47 #include "G4Event.hh" >> 48 #include "G4TrajectoryContainer.hh" >> 49 #include "G4Colour.hh" >> 50 #include "G4VisAttributes.hh" >> 51 #include "G4UImanager.hh" >> 52 #include "G4TransportationManager.hh" 32 53 33 #define G4warn G4cout << 54 G4RayTracer::G4RayTracer(G4VFigureFileMaker* figMaker) 34 << 55 :G4VGraphicsSystem("RayTracer","RayTracer",RAYTRACER_FEATURES, 35 G4RayTracer::G4RayTracer(): << 56 G4VGraphicsSystem::threeD) 36 G4VGraphicsSystem("RayTracer", << 37 "RayTracer", << 38 RAYTRACER_FEATURES, << 39 G4VGraphicsSystem::threeD) << 40 , theRayTracer(nullptr) << 41 { 57 { >> 58 theFigMaker = figMaker; >> 59 if(!theFigMaker) theFigMaker = new G4RTJpegMaker(); >> 60 theRayShooter = new G4RayShooter(); >> 61 theRayTracerEventAction = 0; >> 62 theRayTracerStackingAction = 0; >> 63 theRayTracerTrackingAction = new G4RTTrackingAction(); >> 64 theRayTracerSteppingAction = new G4RTSteppingAction(); >> 65 theMessenger = new G4RTMessenger(this,theRayTracerSteppingAction); >> 66 theEventManager = G4EventManager::GetEventManager(); >> 67 >> 68 nColumn = 640; >> 69 nRow = 640; >> 70 >> 71 eyePosition = G4ThreeVector(1.*m,1.*m,1.*m); >> 72 targetPosition = G4ThreeVector(0.,0.,0.); >> 73 lightDirection = G4ThreeVector(-0.1,-0.2,-0.3).unit(); >> 74 viewSpan = 5.0*deg; >> 75 headAngle = 270.*deg; >> 76 attenuationLength = 1.0*m; >> 77 >> 78 distortionOn = false; 42 } 79 } 43 80 44 G4RayTracer::~G4RayTracer() 81 G4RayTracer::~G4RayTracer() 45 {} << 82 { >> 83 delete theRayShooter; >> 84 delete theRayTracerTrackingAction; >> 85 delete theRayTracerSteppingAction; >> 86 delete theMessenger; >> 87 delete theFigMaker; >> 88 } >> 89 >> 90 void G4RayTracer::Trace(G4String fileName) >> 91 { >> 92 G4StateManager* theStateMan = G4StateManager::GetStateManager(); >> 93 G4ApplicationState currentState = theStateMan->GetCurrentState(); >> 94 if(currentState!=G4State_Idle) >> 95 { >> 96 G4cerr << "Illegal application state - Trace() ignored." << G4endl; >> 97 return; >> 98 } >> 99 >> 100 if(!theFigMaker) >> 101 { >> 102 G4cerr << "Figure file maker class is not specified - Trace() ignored." << G4endl; >> 103 return; >> 104 } >> 105 >> 106 G4UImanager* UI = G4UImanager::GetUIpointer(); >> 107 G4int storeTrajectory = UI->GetCurrentIntValue("/tracking/storeTrajectory"); >> 108 if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 1"); >> 109 >> 110 >> 111 G4ThreeVector tmpVec = targetPosition - eyePosition; >> 112 eyeDirection = tmpVec.unit(); >> 113 colorR = new unsigned char[nColumn*nRow]; >> 114 colorG = new unsigned char[nColumn*nRow]; >> 115 colorB = new unsigned char[nColumn*nRow]; >> 116 >> 117 StoreUserActions(); >> 118 G4bool succeeded = CreateBitMap(); >> 119 if(succeeded) >> 120 { CreateFigureFile(fileName); } >> 121 else >> 122 { G4cerr << "Could not create figure file" << G4endl; >> 123 G4cerr << "You might set the eye position outside of the world volume" << G4endl; } >> 124 RestoreUserActions(); >> 125 >> 126 if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 0"); >> 127 >> 128 delete [] colorR; >> 129 delete [] colorG; >> 130 delete [] colorB; >> 131 } 46 132 47 G4VSceneHandler* G4RayTracer::CreateSceneHandl 133 G4VSceneHandler* G4RayTracer::CreateSceneHandler (const G4String& name) { 48 G4VSceneHandler* pScene = new G4RayTracerSce 134 G4VSceneHandler* pScene = new G4RayTracerSceneHandler (*this, name); >> 135 G4cout << G4RayTracerSceneHandler::GetSceneCount () >> 136 << ' ' << fName << " scene handlers extanct." << G4endl; 49 return pScene; 137 return pScene; 50 } 138 } 51 139 52 G4VViewer* G4RayTracer::CreateViewer (G4VScene 140 G4VViewer* G4RayTracer::CreateViewer (G4VSceneHandler& sceneHandler, 53 const G4String& name) { 141 const G4String& name) { 54 G4VViewer* pViewer = new G4RayTracerViewer << 142 G4VViewer* pView = new G4RayTracerViewer (sceneHandler, name); 55 (sceneHandler, name, theRayTracer); << 143 return pView; 56 if (pViewer) { << 144 } 57 if (pViewer->GetViewId() < 0) { << 145 58 G4warn << << 146 void G4RayTracer::StoreUserActions() 59 "G4RayTracer::CreateViewer: ERROR flag << 147 { 60 " view id in G4RayTracerViewer creatio << 148 theUserEventAction = theEventManager->GetUserEventAction(); 61 "\n Destroying view and returning null << 149 theUserStackingAction = theEventManager->GetUserStackingAction(); 62 << G4endl; << 150 theUserTrackingAction = theEventManager->GetUserTrackingAction(); 63 delete pViewer; << 151 theUserSteppingAction = theEventManager->GetUserSteppingAction(); 64 pViewer = 0; << 152 >> 153 theEventManager->SetUserAction(theRayTracerEventAction); >> 154 theEventManager->SetUserAction(theRayTracerStackingAction); >> 155 theEventManager->SetUserAction(theRayTracerTrackingAction); >> 156 theEventManager->SetUserAction(theRayTracerSteppingAction); >> 157 >> 158 G4SDManager* theSDMan = G4SDManager::GetSDMpointerIfExist(); >> 159 if(theSDMan) >> 160 { theSDMan->Activate("/",false); } >> 161 >> 162 G4GeometryManager* theGeomMan = G4GeometryManager::GetInstance(); >> 163 theGeomMan->OpenGeometry(); >> 164 theGeomMan->CloseGeometry(true); >> 165 } >> 166 >> 167 void G4RayTracer::RestoreUserActions() >> 168 { >> 169 theEventManager->SetUserAction(theUserEventAction); >> 170 theEventManager->SetUserAction(theUserStackingAction); >> 171 theEventManager->SetUserAction(theUserTrackingAction); >> 172 theEventManager->SetUserAction(theUserSteppingAction); >> 173 >> 174 G4SDManager* theSDMan = G4SDManager::GetSDMpointerIfExist(); >> 175 if(theSDMan) >> 176 { theSDMan->Activate("/",true); } >> 177 } >> 178 >> 179 G4bool G4RayTracer::CreateBitMap() >> 180 { >> 181 G4int iEvent = 0; >> 182 G4double stepAngle = viewSpan/100.; >> 183 G4double viewSpanX = stepAngle*nColumn; >> 184 G4double viewSpanY = stepAngle*nRow; >> 185 G4bool succeeded; >> 186 for(int iRow=0;iRow<nRow;iRow++) >> 187 { >> 188 for(int iColumn=0;iColumn<nColumn;iColumn++) >> 189 { >> 190 G4Event* anEvent = new G4Event(iEvent++); >> 191 >> 192 G4double angleX = -(viewSpanX/2. - iColumn*stepAngle); >> 193 G4double angleY = viewSpanY/2. - iRow*stepAngle; >> 194 G4ThreeVector rayDirection; >> 195 if(distortionOn) >> 196 { >> 197 rayDirection = G4ThreeVector(tan(angleX)/cos(angleY),-tan(angleY)/cos(angleX),1.0); >> 198 } >> 199 else >> 200 { >> 201 rayDirection = G4ThreeVector(tan(angleX),-tan(angleY),1.0); >> 202 } >> 203 rayDirection.rotateZ(headAngle); >> 204 rayDirection.rotateUz(eyeDirection); >> 205 G4ThreeVector rayPosition(eyePosition); >> 206 G4bool interceptable = true; >> 207 // Check if rayPosition is in the world. >> 208 G4VPhysicalVolume* pWorld = >> 209 G4TransportationManager::GetTransportationManager()-> >> 210 GetNavigatorForTracking()->GetWorldVolume (); >> 211 EInside whereisit = >> 212 pWorld->GetLogicalVolume()->GetSolid()->Inside(rayPosition); >> 213 if (whereisit != kInside) { >> 214 // It's outside the world, so move it inside. >> 215 G4double outsideDistance = >> 216 pWorld->GetLogicalVolume()->GetSolid()-> >> 217 DistanceToIn(rayPosition,rayDirection); >> 218 if (outsideDistance != kInfinity) { >> 219 rayPosition = rayPosition+outsideDistance*rayDirection; >> 220 } >> 221 else { >> 222 interceptable = false; >> 223 } >> 224 } >> 225 if (interceptable) { >> 226 theRayShooter->Shoot(anEvent,rayPosition,rayDirection); >> 227 theEventManager->ProcessOneEvent(anEvent); >> 228 succeeded = GenerateColour(anEvent); >> 229 //G4cout << iColumn << " " << iRow << " " << anEvent->GetEventID() << G4endl; >> 230 } >> 231 else { // Ray does not intercept world at all. >> 232 // Generate background colour... >> 233 G4int iEvent = anEvent->GetEventID(); >> 234 colorR[iEvent] = 0; >> 235 colorG[iEvent] = 0; >> 236 colorB[iEvent] = 0; >> 237 succeeded = true; >> 238 } >> 239 delete anEvent; >> 240 if(!succeeded) return false; 65 } 241 } 66 } 242 } 67 else { << 243 return true; 68 G4warn << << 244 } 69 "G4RayTracer::CreateViewer: ERROR: null << 245 70 << G4endl; << 246 void G4RayTracer::CreateFigureFile(G4String fileName) >> 247 { >> 248 //G4cout << nColumn << " " << nRow << G4endl; >> 249 theFigMaker->CreateFigureFile(fileName,nColumn,nRow,colorR,colorG,colorB); >> 250 } >> 251 >> 252 G4bool G4RayTracer::GenerateColour(G4Event* anEvent) >> 253 { >> 254 G4TrajectoryContainer * trajectoryContainer = anEvent->GetTrajectoryContainer(); >> 255 >> 256 G4RayTrajectory* trajectory = (G4RayTrajectory*)( (*trajectoryContainer)[0] ); >> 257 if(!trajectory) return false; >> 258 >> 259 G4int nPoint = trajectory->GetPointEntries(); >> 260 if(nPoint==0) return false; >> 261 >> 262 G4Colour rayColour; >> 263 G4Colour initialColour(1.,1.,1.); >> 264 if( trajectory->GetPointC(nPoint-1)->GetPostStepAtt() ) >> 265 { initialColour = GetSurfaceColour(trajectory->GetPointC(nPoint-1)); } >> 266 rayColour = Attenuate(trajectory->GetPointC(nPoint-1),initialColour); >> 267 >> 268 for(int i=nPoint-2;i>=0;i--) >> 269 { >> 270 G4Colour surfaceColour = GetSurfaceColour(trajectory->GetPointC(i)); >> 271 G4double weight = 1.0 - surfaceColour.GetAlpha(); >> 272 G4Colour mixedColour = GetMixedColour(rayColour,surfaceColour,weight); >> 273 rayColour = Attenuate(trajectory->GetPointC(i),mixedColour); >> 274 } >> 275 >> 276 G4int iEvent = anEvent->GetEventID(); >> 277 colorR[iEvent] = (unsigned char)(int(255*rayColour.GetRed())); >> 278 colorG[iEvent] = (unsigned char)(int(255*rayColour.GetGreen())); >> 279 colorB[iEvent] = (unsigned char)(int(255*rayColour.GetBlue())); >> 280 return true; >> 281 } >> 282 >> 283 G4Colour G4RayTracer::GetMixedColour(G4Colour surfCol,G4Colour transCol,G4double weight) >> 284 { >> 285 G4double r = weight*surfCol.GetRed() + (1.-weight)*transCol.GetRed(); >> 286 G4double g = weight*surfCol.GetGreen() + (1.-weight)*transCol.GetGreen(); >> 287 G4double b = weight*surfCol.GetBlue() + (1.-weight)*transCol.GetBlue(); >> 288 G4double a = weight*surfCol.GetAlpha() + (1.-weight)*transCol.GetAlpha(); >> 289 return G4Colour(r,g,b,a); >> 290 } >> 291 >> 292 G4Colour G4RayTracer::GetSurfaceColour(G4RayTrajectoryPoint* point) >> 293 { >> 294 const G4VisAttributes* preAtt = point->GetPreStepAtt(); >> 295 const G4VisAttributes* postAtt = point->GetPostStepAtt(); >> 296 >> 297 G4bool preVis = ValidColour(preAtt); >> 298 G4bool postVis = ValidColour(postAtt); >> 299 >> 300 G4Colour transparent(1.,1.,1.,0.); >> 301 >> 302 if(!preVis&&!postVis) return transparent; >> 303 >> 304 G4ThreeVector normal = point->GetSurfaceNormal(); >> 305 >> 306 G4Colour preCol(1.,1.,1.); >> 307 G4Colour postCol(1.,1.,1.); >> 308 >> 309 if(preVis) >> 310 { >> 311 G4double brill = (1.0-(-lightDirection).dot(normal))/2.0; >> 312 G4double r = preAtt->GetColour().GetRed(); >> 313 G4double g = preAtt->GetColour().GetGreen(); >> 314 G4double b = preAtt->GetColour().GetBlue(); >> 315 preCol = G4Colour(r*brill,g*brill,b*brill,preAtt->GetColour().GetAlpha()); 71 } 316 } 72 return pViewer; << 317 else >> 318 { preCol = transparent; } >> 319 >> 320 if(postVis) >> 321 { >> 322 G4double brill = (1.0-(-lightDirection).dot(-normal))/2.0; >> 323 G4double r = postAtt->GetColour().GetRed(); >> 324 G4double g = postAtt->GetColour().GetGreen(); >> 325 G4double b = postAtt->GetColour().GetBlue(); >> 326 postCol = G4Colour(r*brill,g*brill,b*brill,postAtt->GetColour().GetAlpha()); >> 327 } >> 328 else >> 329 { postCol = transparent; } >> 330 >> 331 if(!preVis) return postCol; >> 332 if(!postVis) return preCol; >> 333 >> 334 G4double weight = 0.5; >> 335 return GetMixedColour(preCol,postCol,weight); 73 } 336 } >> 337 >> 338 G4Colour G4RayTracer::Attenuate(G4RayTrajectoryPoint* point, G4Colour sourceCol) >> 339 { >> 340 const G4VisAttributes* preAtt = point->GetPreStepAtt(); >> 341 >> 342 G4bool visible = ValidColour(preAtt); >> 343 if(!visible) return sourceCol; >> 344 >> 345 G4Colour objCol = preAtt->GetColour(); >> 346 G4double stepRed = objCol.GetRed(); >> 347 G4double stepGreen = objCol.GetGreen(); >> 348 G4double stepBlue = objCol.GetBlue(); >> 349 G4double stepAlpha = objCol.GetAlpha(); >> 350 G4double stepLength = point->GetStepLength(); >> 351 >> 352 G4double attenuationFuctor; >> 353 if(stepAlpha > 0.9999999){ stepAlpha = 0.9999999; } // patch to the next line >> 354 attenuationFuctor = -stepAlpha/(1.0-stepAlpha)*stepLength/attenuationLength; >> 355 >> 356 G4double KtRed = exp((1.0-stepRed)*attenuationFuctor); >> 357 G4double KtGreen = exp((1.0-stepGreen)*attenuationFuctor); >> 358 G4double KtBlue = exp((1.0-stepBlue)*attenuationFuctor); >> 359 if(KtRed>1.0){KtRed=1.0;} >> 360 if(KtGreen>1.0){KtGreen=1.0;} >> 361 if(KtBlue>1.0){KtBlue=1.0;} >> 362 return G4Colour(sourceCol.GetRed()*KtRed, >> 363 sourceCol.GetGreen()*KtGreen,sourceCol.GetBlue()*KtBlue); >> 364 } >> 365 >> 366 G4bool G4RayTracer::ValidColour(const G4VisAttributes* visAtt) >> 367 { >> 368 G4bool val = true; >> 369 if(!visAtt) >> 370 { val = false; } >> 371 else if(!(visAtt->IsVisible())) >> 372 { val = false; } >> 373 else if(visAtt->IsForceDrawingStyle() >> 374 &&(visAtt->GetForcedDrawingStyle()==G4VisAttributes::wireframe)) >> 375 { val = false; } >> 376 return val; >> 377 } >> 378 74 379