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

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