source: snovis/trunk/source/G4Lab/cxx/SoG4Trajectories.cxx @ 233

Last change on this file since 233 was 233, checked in by barrand, 17 years ago
  • Property svn:eol-style set to native
File size: 18.9 KB
Line 
1
2// this :
3#include <G4Lab/SoG4Trajectories.h>
4
5// Inventor :
6#include <Inventor/SoPickedPoint.h>
7#include <Inventor/errors/SoDebugError.h>
8#include <Inventor/actions/SoGLRenderAction.h>
9#include <Inventor/actions/SoRayPickAction.h>
10#include <Inventor/actions/SoCallbackAction.h>
11#include <Inventor/actions/SoCallbackAction.h>
12#include <Inventor/sensors/SoFieldSensor.h>
13#include <Inventor/elements/SoLazyElement.h>
14#include <Inventor/bundles/SoMaterialBundle.h>
15
16// HEPVis :
17#include <HEPVis/actions/SoAlternateRepAction.h>
18
19#ifdef WIN32
20#undef pascal // Clash between windef.h and Geant4/SystemOfnits.hh
21#endif
22
23// Geant4 :
24#include <G4RunManager.hh>
25#include <G4Trajectory.hh>
26
27// G4Lab :
28#include <G4Lab/Trajectory.h>
29
30//WIN32 : have HEPVis/SbGL.h after G4SteppingManager.h.
31// Else the windows.h will clash with std::max.
32#include <HEPVis/SbGL.h> 
33
34#define MINIMUM(a,b) ((a)<(b)?a:b)
35#define MAXIMUM(a,b) ((a)>(b)?a:b)
36
37SO_NODE_SOURCE(SoG4Trajectories)
38//////////////////////////////////////////////////////////////////////////////
39void SoG4Trajectories::initClass(
40)
41//////////////////////////////////////////////////////////////////////////////
42//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
43{
44  SO_NODE_INIT_CLASS(SoG4Trajectories,SoShape,"Shape");
45}
46//////////////////////////////////////////////////////////////////////////////
47SoG4Trajectories::SoG4Trajectories(
48)
49:fContainer(0)
50,fSensor(0)
51//////////////////////////////////////////////////////////////////////////////
52//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
53{
54  SO_NODE_CONSTRUCTOR(SoG4Trajectories);
55  SO_NODE_ADD_FIELD(model,(ALL));
56  SO_NODE_ADD_FIELD(timeStart,(0));
57  SO_NODE_ADD_FIELD(timeInterval,(0.05F));
58  SO_NODE_ADD_FIELD(timeSteps,(100));
59  SO_NODE_ADD_FIELD(timeIndex,(0));
60
61  SO_NODE_ADD_FIELD(timeMin,(0));
62  SO_NODE_ADD_FIELD(timeMax,(0));
63  SO_NODE_ADD_FIELD(verbose,(FALSE));
64 
65  SO_NODE_ADD_FIELD(alternateRep,(NULL));
66
67  SO_NODE_DEFINE_ENUM_VALUE(Model,ALL);
68  SO_NODE_DEFINE_ENUM_VALUE(Model,TIMED);
69 
70  SO_NODE_SET_SF_ENUM_TYPE(model,Model);
71
72  fSensor = new SoFieldSensor(sensorCB,this);
73  fSensor->attach(&timeInterval);
74
75  timeSteps.addAuditor(&timeInterval,SoNotRec::FIELD);
76  timeStart.addAuditor(&timeInterval,SoNotRec::FIELD);
77
78}
79//////////////////////////////////////////////////////////////////////////////
80SoG4Trajectories::~SoG4Trajectories(
81)
82//////////////////////////////////////////////////////////////////////////////
83//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
84{
85  fSensor->detach();
86  timeSteps.removeAuditor(&timeInterval,SoNotRec::FIELD);
87  timeStart.removeAuditor(&timeInterval,SoNotRec::FIELD);
88}
89//////////////////////////////////////////////////////////////////////////////
90void SoG4Trajectories::GLRender (
91 SoGLRenderAction* aAction
92)
93//////////////////////////////////////////////////////////////////////////////
94//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
95{
96  G4RunManager* runManager = G4RunManager::GetRunManager();
97  if(!runManager) return;
98  const G4Event* event = runManager->GetCurrentEvent();
99  if(!event) return;
100  G4TrajectoryContainer* trajectoryContainer = event->GetTrajectoryContainer();
101  if(!trajectoryContainer) return;
102
103  SoState* state = aAction->getState();
104  state->push();
105
106  SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
107
108  glPushAttrib(GL_ENABLE_BIT);
109  glPushAttrib(GL_CURRENT_BIT);
110
111  SoMaterialBundle mb(aAction);
112  mb.sendFirst();
113
114  const SbColor& color = SoLazyElement::getDiffuse(aAction->getState(),0);
115  float red,green,blue;
116  color.getValue(red,green,blue);
117  glDisable(GL_LIGHTING);
118  glColor3f(red,green,blue);
119
120  if((SoG4Trajectories::Model)model.getValue()==SoG4Trajectories::TIMED) {
121
122    if(fContainer!=trajectoryContainer) { // Event had changed.
123      timeOrder(trajectoryContainer);
124      fContainer = trajectoryContainer;
125    }
126
127    int timen = fTimeOrderedPoints.size();
128    int ti = timeIndex.getValue();
129    if((ti>=0)&&(ti<timen)) {
130
131      const std::vector<PointIdentifier>& ids = fTimeOrderedPoints[ti];
132      int idn = ids.size();
133      if(verbose.getValue()==TRUE)
134        SoDebugError::postInfo("SoG4RunManager::GLRender",
135                               "debug : render slice %d with %d points.",
136                               ti,idn);
137
138      for(int t=0;t<=ti;t++) {
139        const std::vector<PointIdentifier>& ids = fTimeOrderedPoints[t];
140        int idn = ids.size();
141           
142        // First pass to draw points :
143        glBegin(GL_POINTS);
144        int i;
145        for(i=0;i<idn;i++) {
146          int itraj = ids[i].fTrajectory;
147          int ipoint = ids[i].fPoint;
148          G4Trajectory* trajectory = 
149            (G4Trajectory*)(*trajectoryContainer)[(size_t)itraj];
150          int pointn = trajectory->GetPointEntries();
151          if( (pointn==1) || (ipoint==pointn-1) ) {
152            G4TrajectoryPoint* tp = 
153              (G4TrajectoryPoint*)(trajectory->GetPoint(ipoint));
154            G4ThreeVector pos = tp->GetPosition();
155            glVertex3d(pos.x(),pos.y(),pos.z());
156          }
157        }
158        glEnd();
159       
160        // Draw segments :
161        glBegin(GL_LINES);
162        for(i=0;i<idn;i++) {
163          int itraj = ids[i].fTrajectory;
164          int ipoint = ids[i].fPoint;
165          G4Trajectory* trajectory = 
166            (G4Trajectory*)(*trajectoryContainer)[(size_t)itraj];
167          int pointn = trajectory->GetPointEntries();
168          if( (pointn==1) || (ipoint==pointn-1) ) {
169          } else {
170            G4TrajectoryPoint* tp = 
171              (G4TrajectoryPoint*)(trajectory->GetPoint(ipoint));
172            G4ThreeVector pos = tp->GetPosition();
173            glVertex3d(pos.x(),pos.y(),pos.z());
174            tp = (G4TrajectoryPoint*)(trajectory->GetPoint(ipoint+1));
175            pos = tp->GetPosition();
176            glVertex3d(pos.x(),pos.y(),pos.z());
177          }
178        }
179        glEnd();
180      }
181    }
182
183  } else {
184
185    int number = trajectoryContainer->entries();
186    for(int index=0;index<number;index++) {
187      G4Trajectory* trajectory = 
188        (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
189      int pointn = trajectory->GetPointEntries();
190      if(pointn==1) {
191        glBegin(GL_POINTS);
192        G4TrajectoryPoint* tp = (G4TrajectoryPoint*)(trajectory->GetPoint(0));
193        G4ThreeVector pos = tp->GetPosition();
194        glVertex3d(pos.x(),pos.y(),pos.z());
195        glEnd();
196      } else {
197        glBegin(GL_LINE_STRIP);
198        for (int i = 0; i < pointn ; i++) {
199          G4TrajectoryPoint* tp = 
200            (G4TrajectoryPoint*)(trajectory->GetPoint(i));
201          G4ThreeVector pos = tp->GetPosition();
202          glVertex3d(pos.x(),pos.y(),pos.z());
203        }
204        glEnd();
205      }
206    }
207
208  }
209
210  glPopAttrib(); //GL_CURRENT_BIT
211  glPopAttrib(); //GL_ENABLE_BIT
212
213  state->pop();
214}
215//////////////////////////////////////////////////////////////////////////////
216void SoG4Trajectories::rayPick (
217 SoRayPickAction* aAction
218)
219//////////////////////////////////////////////////////////////////////////////
220//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
221{
222  if(!shouldRayPick(aAction)) return;
223
224  aAction->setObjectSpace();
225
226  G4RunManager* runManager = G4RunManager::GetRunManager();
227  if(runManager) {
228    const G4Event* event = runManager->GetCurrentEvent();
229    if(event) {
230      G4TrajectoryContainer* trajectoryContainer = 
231        event->GetTrajectoryContainer();
232      if(trajectoryContainer) {
233        int number = trajectoryContainer->entries();
234        for(int index=0;index<number;index++) {
235          G4Trajectory* trajectory = 
236            (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
237          int pointn = trajectory->GetPointEntries();
238          if(!pointn) continue;
239          G4TrajectoryPoint* tp = 
240            (G4TrajectoryPoint*)(trajectory->GetPoint(0));
241          G4ThreeVector pos = tp->GetPosition();
242          SbVec3f v0;
243          v0.setValue((float)pos.x(),(float)pos.y(),(float)pos.z());
244          for (int i = 1; i < pointn ; i++) {
245            tp = (G4TrajectoryPoint*)(trajectory->GetPoint(i));
246            pos = tp->GetPosition();
247            SbVec3f v1((float)pos.x(),(float)pos.y(),(float)pos.z());
248            SbVec3f isect;
249            SbBool hit = aAction->intersect(v0, v1, isect);
250            if(hit && aAction->isBetweenPlanes(isect)) {
251              SoPickedPoint* pp = aAction->addIntersection(isect);
252              if(pp) {
253                pp->setMaterialIndex(0);
254                pp->setObjectNormal(SbVec3f(0.0f, 0.0f, 1.0f));
255              }
256            }
257            v0 = v1;
258          }
259        }
260      }
261    }
262  }
263}
264//////////////////////////////////////////////////////////////////////////////
265void SoG4Trajectories::computeBBox (
266 SoAction* //aAction
267,SbBox3f& aBox
268,SbVec3f& aCenter
269)
270//////////////////////////////////////////////////////////////////////////////
271//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
272{
273  G4RunManager* runManager = G4RunManager::GetRunManager();
274  if(runManager) {
275    const G4Event* event = runManager->GetCurrentEvent();
276    if(event) {
277      G4TrajectoryContainer* trajectoryContainer = 
278        event->GetTrajectoryContainer();
279      if(trajectoryContainer) {
280        int number = trajectoryContainer->entries();
281        double xmin = 0;
282        double ymin = 0;
283        double zmin = 0;
284        double xmax = 0;
285        double ymax = 0;
286        double zmax = 0;
287        bool first = true;
288        for(int index=0;index<number;index++) {
289          G4Trajectory* trajectory = 
290            (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
291          int pointn = trajectory->GetPointEntries();
292          for (int i = 0; i < pointn ; i++) {
293            G4TrajectoryPoint* tp = 
294              (G4TrajectoryPoint*)(trajectory->GetPoint(i));
295            G4ThreeVector pos = tp->GetPosition();
296            if(first) {
297              xmax = xmin = pos.x();
298              ymax = ymin = pos.y();
299              zmax = zmin = pos.z();
300              first = false;
301            } else {
302              xmin = MINIMUM(xmin,pos.x());
303              ymin = MINIMUM(ymin,pos.y());
304              zmin = MINIMUM(zmin,pos.z());
305              xmax = MAXIMUM(xmax,pos.x());
306              ymax = MAXIMUM(ymax,pos.y());
307              zmax = MAXIMUM(zmax,pos.z());
308            }
309          }
310        }
311        if(!first) {
312          aBox.setBounds(SbVec3f((float)xmin,(float)ymin,(float)zmin),
313                         SbVec3f((float)xmax,(float)ymax,(float)zmax));
314        }
315      }
316    }
317  }
318  aCenter = aBox.getCenter();
319}
320//////////////////////////////////////////////////////////////////////////////
321void SoG4Trajectories::generatePrimitives(
322 SoAction* //aAction
323) 
324//////////////////////////////////////////////////////////////////////////////
325//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
326{
327}
328//////////////////////////////////////////////////////////////////////////////
329void SoG4Trajectories::flush(
330)
331//////////////////////////////////////////////////////////////////////////////
332//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
333{
334  glFlush();
335  glFinish();
336}
337//////////////////////////////////////////////////////////////////////////////
338bool SoG4Trajectories::isG4LabTrajectories(
339 G4TrajectoryContainer* aContainer
340) 
341//////////////////////////////////////////////////////////////////////////////
342//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
343{
344  if(!aContainer) return false;
345
346  int number = aContainer->entries();
347  if(number<=0) return false;
348
349  // Check if G4Trajectory is a G4Lab::Trajectory :
350  G4Lab::Trajectory* trajectory = 
351    dynamic_cast<G4Lab::Trajectory*>((G4Trajectory*)(*aContainer)[(size_t)0]);
352
353  return (trajectory ? true : false);
354}
355//////////////////////////////////////////////////////////////////////////////
356void SoG4Trajectories::timeOrder(
357 G4TrajectoryContainer* aContainer
358) 
359//////////////////////////////////////////////////////////////////////////////
360//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
361{
362  fTimeOrderedPoints.clear();
363
364  if((SoG4Trajectories::Model)model.getValue()
365     !=SoG4Trajectories::TIMED) return;
366
367  if(!aContainer) return;
368
369  if(!isG4LabTrajectories(aContainer)) return;
370
371  int number = aContainer->entries();
372  if(number<=0) return;
373
374  // Compute min, max time :
375  double minTime = 0;
376  double maxTime = 0;
377  int numberOfPoints = 0;
378  for(int index=0;index<number;index++) {
379    G4Lab::Trajectory* trajectory = 
380      (G4Lab::Trajectory*)(*aContainer)[(size_t)index];
381    int pointn = trajectory->GetPointEntries();
382    for (int i = 0; i < pointn ; i++) {
383      double globalTime = trajectory->GetPointGlobalTime(i);
384      if(numberOfPoints==0) {
385        minTime = globalTime;
386        maxTime = globalTime;
387      } else {
388        minTime = MINIMUM(minTime,globalTime);
389        maxTime = MAXIMUM(maxTime,globalTime);
390      }
391      numberOfPoints++;
392    }
393  }   
394  SbBool flag = enableNotify(FALSE);
395  timeMin.setValue((float)minTime);
396  timeMax.setValue((float)maxTime);
397  enableNotify(flag);
398
399  // Construct the time ordered point list :
400  int timen = timeSteps.getValue();
401  if(timen>0) {
402    //double deltaTime = (maxTime - minTime)/timen;
403    double deltaTime = timeInterval.getValue();
404    int count = 0;
405    for(int t=0;t<=timen;t++) {
406      fTimeOrderedPoints.push_back(std::vector<PointIdentifier>());
407      std::vector<PointIdentifier>& ids = fTimeOrderedPoints[t];
408      double tmin = timeStart.getValue() + t * deltaTime;
409      double tmax = tmin + deltaTime;
410      for(int index=0;index<number;index++) {
411        G4Lab::Trajectory* trajectory = 
412          (G4Lab::Trajectory*)(*aContainer)[(size_t)index];
413        int pointn = trajectory->GetPointEntries();
414        for (int i = 0; i < pointn ; i++) {
415          double globalTime = trajectory->GetPointGlobalTime(i);
416          if((tmin<=globalTime) && (globalTime<tmax)) {
417            ids.push_back(PointIdentifier(index,i));
418            count++;
419          }
420        }
421      }
422    }
423
424    /*   
425    if(count!=numberOfPoints) {
426      SoDebugError::postWarning("SoG4RunManager::GLRender",
427        "point count problem ; %d points, but %d ordered.",
428        numberOfPoints,count);
429    }
430    */
431  }
432
433  if(verbose.getValue()==TRUE)
434    SoDebugError::postInfo("SoG4RunManager::GLRender",
435    "points : %d, minTime : %g, maxTime : %g, timeStart : %g, timeInterval : %g, timeSteps : %d.",
436    numberOfPoints,minTime,maxTime,
437    timeStart.getValue(),timeInterval.getValue(),timeSteps.getValue());
438
439}
440//////////////////////////////////////////////////////////////////////////////
441void SoG4Trajectories::sensorCB (
442 void* aData
443,SoSensor* //aSensor
444) 
445//////////////////////////////////////////////////////////////////////////////
446//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
447{
448  G4RunManager* runManager = G4RunManager::GetRunManager();
449  if(!runManager) return;
450  const G4Event* event = runManager->GetCurrentEvent();
451  if(!event) return;
452  G4TrajectoryContainer* trajectoryContainer = 
453    event->GetTrajectoryContainer();
454  if(!trajectoryContainer) return;
455
456  SoG4Trajectories* This = (SoG4Trajectories*)aData;
457
458  This->timeOrder(trajectoryContainer);
459
460}
461
462#include <Inventor/nodes/SoSeparator.h>
463#include <Inventor/nodes/SoCoordinate3.h>
464//#include <Inventor/nodes/SoLineSet.h>
465#include <Inventor/nodes/SoIndexedLineSet.h>
466//////////////////////////////////////////////////////////////////////////////
467void SoG4Trajectories::generateAlternateRep(
468) 
469//////////////////////////////////////////////////////////////////////////////
470//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
471{
472  G4RunManager* runManager = G4RunManager::GetRunManager();
473  if(!runManager) return;
474  const G4Event* event = runManager->GetCurrentEvent();
475  if(!event) return;
476  G4TrajectoryContainer* trajectoryContainer = event->GetTrajectoryContainer();
477  if(!trajectoryContainer) return;
478
479  /* With SoLineSets :
480  int number = trajectoryContainer->entries();
481  for(int index=0;index<number;index++) {
482    G4Trajectory* trajectory =
483      (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
484    int pointn = trajectory->GetPointEntries();
485    if(pointn>=1) {
486      SbVec3f* points = new SbVec3f[pointn];
487      for (int i = 0; i < pointn ; i++) {
488        G4TrajectoryPoint* tp =
489          (G4TrajectoryPoint*)(trajectory->GetPoint(i));
490        G4ThreeVector pos = tp->GetPosition();
491        points[i].setValue((float)pos.x(),(float)pos.y(),(float)pos.z());
492      }
493
494      // Scene graph :
495      SoSeparator* separator = new SoSeparator;
496
497      SoCoordinate3* coordinate3 = new SoCoordinate3;
498      coordinate3->point.setValues(0,pointn,points);
499      delete [] points;
500      separator->addChild(coordinate3);
501
502      SoLineSet* lineSet = new SoLineSet;
503      lineSet->numVertices.setValues(0,1,&pointn);
504      separator->addChild(lineSet);
505
506      alternateRep.setValue(separator);
507    }
508  } */
509
510  // With one SoIndexedLineSet :
511  int npoint = 0;
512  int ncoord = 0;
513 {int number = trajectoryContainer->entries();
514  for(int index=0;index<number;index++) {
515    G4Trajectory* trajectory = 
516      (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
517    int pointn = trajectory->GetPointEntries();
518    if(pointn>=1) {
519      npoint += pointn;
520      ncoord += pointn + 1;
521    }
522  }}
523  if(npoint<=0) return;
524
525  SbVec3f* points = new SbVec3f[npoint];
526  int32_t* coords = new int32_t[ncoord];
527
528  int ipoint = 0;
529  int icoord = 0;
530
531  int number = trajectoryContainer->entries();
532  for(int index=0;index<number;index++) {
533    G4Trajectory* trajectory = 
534      (G4Trajectory*)(*trajectoryContainer)[(size_t)index];
535    int pointn = trajectory->GetPointEntries();
536    if(pointn>=1) {
537      for (int i = 0; i < pointn ; i++) {
538        G4TrajectoryPoint* tp = 
539          (G4TrajectoryPoint*)(trajectory->GetPoint(i));
540        G4ThreeVector pos = tp->GetPosition();
541        points[ipoint].setValue((float)pos.x(),(float)pos.y(),(float)pos.z());
542        coords[icoord] = ipoint;
543        ipoint++;
544        icoord++;
545      }
546      coords[icoord] = SO_END_LINE_INDEX;
547      icoord++;
548    }
549  }
550
551  SoSeparator* separator = new SoSeparator;
552
553  SoCoordinate3* coordinate3 = new SoCoordinate3;
554  coordinate3->point.setValues(0,ipoint,points);
555  delete [] points;
556  separator->addChild(coordinate3);
557
558  SoIndexedLineSet* indexedLineSet = new SoIndexedLineSet;
559  indexedLineSet->coordIndex.setValues(0,icoord,coords);
560  delete [] coords;
561  separator->addChild(indexedLineSet);
562
563  alternateRep.setValue(separator);
564}
565//////////////////////////////////////////////////////////////////////////////
566void SoG4Trajectories::clearAlternateRep(
567) 
568//////////////////////////////////////////////////////////////////////////////
569//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
570{
571  alternateRep.setValue(NULL);
572}
573//////////////////////////////////////////////////////////////////////////////
574void SoG4Trajectories::doAction(
575 SoAction* aAction
576)
577//////////////////////////////////////////////////////////////////////////////
578//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
579{
580  SO_ALTERNATEREP_DO_ACTION(aAction)
581  SoShape::doAction(aAction);
582}
Note: See TracBrowser for help on using the repository browser.