Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TheRayTracer.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 //
31 
32 
33 #include "G4TheRayTracer.hh"
34 #include "G4SystemOfUnits.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"
54 #include "G4RegionStore.hh"
55 #include "G4ProductionCutsTable.hh"
56 
58  G4VRTScanner* scanner)
59 {
60  theFigMaker = figMaker;
62  theScanner = scanner;
71 
72  nColumn = 640;
73  nRow = 640;
74 
75  eyePosition = G4ThreeVector(1.*m,1.*m,1.*m);
76  targetPosition = G4ThreeVector(0.,0.,0.);
77  lightDirection = G4ThreeVector(-0.1,-0.2,-0.3).unit();
78  up = G4ThreeVector(0,1,0);
79  viewSpan = 5.0*deg;
80  headAngle = 0.;
81  attenuationLength = 1.0*m;
82 
83  distortionOn = false;
84  antialiasingOn = false;
85 
86  backgroundColour = G4Colour(1.,1.,1.);
87 }
88 
90 {
91  delete theRayShooter;
94  delete theMessenger;
95  delete theScanner;
96  delete theFigMaker;
97 }
98 
100 {
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 
116  G4int storeTrajectory = UI->GetCurrentIntValue("/tracking/storeTrajectory");
117  if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 1");
118 
119 
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 
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; }
134 
135  if(storeTrajectory==0) UI->ApplyCommand("/tracking/storeTrajectory 0");
136 
137  delete [] colorR;
138  delete [] colorG;
139  delete [] colorB;
140 }
141 
143 {
148 
151 
156 
158  if(theSDMan)
159  { theSDMan->Activate("/",false); }
160 
162  theGeomMan->OpenGeometry();
163  theGeomMan->CloseGeometry(true);
164 }
165 
167 {
172 
174  if(theSDMan)
175  { theSDMan->Activate("/",true); }
176 }
177 
178 #include "G4ProcessManager.hh"
179 #include "G4ProcessVector.hh"
180 #include "G4Geantino.hh"
181 
183 {
184  G4int iEvent = 0;
185  G4double stepAngle = viewSpan/100.;
186  G4double viewSpanX = stepAngle*nColumn;
187  G4double viewSpanY = stepAngle*nRow;
188  G4bool succeeded;
189 
190 // Confirm process(es) of Geantino is initialized
191  G4VPhysicalVolume* pWorld =
193  GetNavigatorForTracking()->GetWorldVolume();
196  G4ProcessVector* pVector
198  for (G4int j=0; j < pVector->size(); ++j) {
199  (*pVector)[j]->BuildPhysicsTable(*(G4Geantino::GeantinoDefinition()));
200  }
201 
202 // Close geometry and set the application state
204  geomManager->OpenGeometry();
205  geomManager->CloseGeometry(1,0);
206 
207  G4ThreeVector center(0,0,0);
210  navigator->LocateGlobalPointAndSetup(center,0,false);
211 
213  theStateMan->SetNewState(G4State_GeomClosed);
214 
215 // Event loop
216  theScanner->Initialize(nRow,nColumn);
217  G4int iRow, iColumn;
218  while (theScanner->Coords(iRow,iColumn)) {
219  G4int iCoord = iRow * nColumn + iColumn;
220  G4double dRow = 0, dColumn = 0; // Antialiasing increments.
221  G4Event* anEvent = new G4Event(iEvent++);
222  G4double angleX = -(viewSpanX/2. - (iColumn+dColumn)*stepAngle);
223  G4double angleY = viewSpanY/2. - (iRow+dRow)*stepAngle;
224  G4ThreeVector rayDirection;
225  if(distortionOn)
226  {
227  rayDirection = G4ThreeVector(-std::tan(angleX)/std::cos(angleY),std::tan(angleY)/std::cos(angleX),1.0);
228  }
229  else
230  {
231  rayDirection = G4ThreeVector(-std::tan(angleX),std::tan(angleY),1.0);
232  }
233  G4double cp = std::cos(eyeDirection.phi());
234  G4double sp = std::sqrt(1.-cp*cp);
235  G4double ct = std::cos(eyeDirection.theta());
236  G4double st = std::sqrt(1.-ct*ct);
237  G4double gamma = std::atan2(ct*cp*up.x()+ct*sp*up.y()-st*up.z(), -sp*up.x()+cp*up.y());
238  rayDirection.rotateZ(-gamma);
239  rayDirection.rotateZ(headAngle);
240  rayDirection.rotateUz(eyeDirection);
241  G4ThreeVector rayPosition(eyePosition);
242  G4bool interceptable = true;
243  // Check if rayPosition is in the world.
244  EInside whereisit =
245  pWorld->GetLogicalVolume()->GetSolid()->Inside(rayPosition);
246  if (whereisit != kInside) {
247  // It's outside the world, so move it inside.
248  G4double outsideDistance =
249  pWorld->GetLogicalVolume()->GetSolid()->
250  DistanceToIn(rayPosition,rayDirection);
251  if (outsideDistance != kInfinity) {
252  // Borrowing from geometry, where 1e-8 < epsilon < 1e-3, in
253  // absolute/internal length units, is used for ensuring good
254  // behaviour, choose to add 0.001 to ensure rayPosition is
255  // definitely inside the world volume (JA 16/9/2005)...
256  rayPosition = rayPosition+(outsideDistance+0.001)*rayDirection;
257  }
258  else {
259  interceptable = false;
260  }
261  }
262  if (interceptable) {
263  theRayShooter->Shoot(anEvent,rayPosition,rayDirection.unit());
265  succeeded = GenerateColour(anEvent);
266  colorR[iCoord] = (unsigned char)(int(255*rayColour.GetRed()));
267  colorG[iCoord] = (unsigned char)(int(255*rayColour.GetGreen()));
268  colorB[iCoord] = (unsigned char)(int(255*rayColour.GetBlue()));
269  } else { // Ray does not intercept world at all.
270  // Store background colour...
271  colorR[iCoord] = (unsigned char)(int(255*backgroundColour.GetRed()));
272  colorG[iCoord] = (unsigned char)(int(255*backgroundColour.GetGreen()));
273  colorB[iCoord] = (unsigned char)(int(255*backgroundColour.GetBlue()));
274  succeeded = true;
275  }
276 
277  theScanner->Draw(colorR[iCoord],colorG[iCoord],colorB[iCoord]);
278 
279  delete anEvent;
280  if(!succeeded) return false;
281  }
282 
283  theStateMan->SetNewState(G4State_Idle);
284  return true;
285 }
286 
288 {
289  //G4cout << nColumn << " " << nRow << G4endl;
291 }
292 
294 {
295  G4TrajectoryContainer * trajectoryContainer = anEvent->GetTrajectoryContainer();
296 
297  G4RayTrajectory* trajectory = (G4RayTrajectory*)( (*trajectoryContainer)[0] );
298  if(!trajectory) return false;
299 
300  G4int nPoint = trajectory->GetPointEntries();
301  if(nPoint==0) return false;
302 
303  G4Colour initialColour(backgroundColour);
304  if( trajectory->GetPointC(nPoint-1)->GetPostStepAtt() )
305  { initialColour = GetSurfaceColour(trajectory->GetPointC(nPoint-1)); }
306  rayColour = Attenuate(trajectory->GetPointC(nPoint-1),initialColour);
307 
308  for(int i=nPoint-2;i>=0;i--)
309  {
310  G4Colour surfaceColour = GetSurfaceColour(trajectory->GetPointC(i));
311  G4double weight = 1.0 - surfaceColour.GetAlpha();
312  G4Colour mixedColour = GetMixedColour(rayColour,surfaceColour,weight);
313  rayColour = Attenuate(trajectory->GetPointC(i),mixedColour);
314  }
315 
316  return true;
317 }
318 
320 {
321  G4double red = weight*surfCol.GetRed() + (1.-weight)*transCol.GetRed();
322  G4double green = weight*surfCol.GetGreen() + (1.-weight)*transCol.GetGreen();
323  G4double blue = weight*surfCol.GetBlue() + (1.-weight)*transCol.GetBlue();
324  G4double alpha = weight*surfCol.GetAlpha() + (1.-weight)*transCol.GetAlpha();
325  return G4Colour(red,green,blue,alpha);
326 }
327 
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 red = preAtt->GetColour().GetRed();
349  G4double green = preAtt->GetColour().GetGreen();
350  G4double blue = preAtt->GetColour().GetBlue();
351  preCol = G4Colour
352  (red*brill,green*brill,blue*brill,preAtt->GetColour().GetAlpha());
353  }
354  else
355  { preCol = transparent; }
356 
357  if(postVis)
358  {
359  G4double brill = (1.0-(-lightDirection).dot(-normal))/2.0;
360  G4double red = postAtt->GetColour().GetRed();
361  G4double green = postAtt->GetColour().GetGreen();
362  G4double blue = postAtt->GetColour().GetBlue();
363  postCol = G4Colour
364  (red*brill,green*brill,blue*brill,postAtt->GetColour().GetAlpha());
365  }
366  else
367  { postCol = transparent; }
368 
369  if(!preVis) return postCol;
370  if(!postVis) return preCol;
371 
372  G4double weight = 0.5;
373  return GetMixedColour(preCol,postCol,weight);
374 }
375 
377 {
378  const G4VisAttributes* preAtt = point->GetPreStepAtt();
379 
380  G4bool visible = ValidColour(preAtt);
381  if(!visible) return sourceCol;
382 
383  G4Colour objCol = preAtt->GetColour();
384  G4double stepRed = objCol.GetRed();
385  G4double stepGreen = objCol.GetGreen();
386  G4double stepBlue = objCol.GetBlue();
387  G4double stepAlpha = objCol.GetAlpha();
388  G4double stepLength = point->GetStepLength();
389 
390  G4double attenuationFuctor;
391  if(stepAlpha > 0.9999999){ stepAlpha = 0.9999999; } // patch to the next line
392  attenuationFuctor = -stepAlpha/(1.0-stepAlpha)*stepLength/attenuationLength;
393 
394  G4double KtRed = std::exp((1.0-stepRed)*attenuationFuctor);
395  G4double KtGreen = std::exp((1.0-stepGreen)*attenuationFuctor);
396  G4double KtBlue = std::exp((1.0-stepBlue)*attenuationFuctor);
397  if(KtRed>1.0){KtRed=1.0;}
398  if(KtGreen>1.0){KtGreen=1.0;}
399  if(KtBlue>1.0){KtBlue=1.0;}
400  return G4Colour(sourceCol.GetRed()*KtRed,
401  sourceCol.GetGreen()*KtGreen,sourceCol.GetBlue()*KtBlue);
402 }
403 
405 {
406  G4bool val = true;
407  if(!visAtt)
408  { val = false; }
409  else if(!(visAtt->IsVisible()))
410  { val = false; }
411  else if(visAtt->IsForceDrawingStyle()
413  { val = false; }
414  return val;
415 }
416