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

Last change on this file since 302 was 288, checked in by barrand, 18 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.