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

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