ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VViewer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VViewer.cc
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 //
28 //
29 // John Allison 27th March 1996
30 // Abstract interface class for graphics views.
31 
32 #include "G4VViewer.hh"
33 
34 #include "G4ios.hh"
35 #include <sstream>
36 
37 #include "G4VisManager.hh"
38 #include "G4VGraphicsSystem.hh"
39 #include "G4VSceneHandler.hh"
40 #include "G4Scene.hh"
41 #include "G4VPhysicalVolume.hh"
42 #include "G4Transform3D.hh"
43 #include "G4UImanager.hh"
44 
46  G4int id, const G4String& name):
47 fSceneHandler (sceneHandler),
48 fViewId (id),
49 //fModified (true),
50 fNeedKernelVisit (true)
51 {
52  if (name == "") {
53  std::ostringstream ost;
54  ost << fSceneHandler.GetName () << '-' << fViewId;
55  fName = ost.str();
56  }
57  else {
58  fName = name;
59  }
60  fShortName = fName (0, fName.find (' '));
61  fShortName.strip ();
62 
64  fDefaultVP = fVP;
65 }
66 
69 }
70 
72  fName = name;
73  fShortName = fName (0, fName.find (' '));
74  fShortName.strip ();
75 }
76 
78 
79  fNeedKernelVisit = true;
80 
81  // At one time I thought we'd better notify all viewers. But I guess
82  // each viewer can take care of itself, so the following code is
83  // redundant (but keep it commented out for now). (John Allison)
84  // Notify all viewers that a kernel visit is required.
85  // const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
86  // G4ViewerListConstIterator i;
87  // for (i = viewerList.begin(); i != viewerList.end(); i++) {
88  // (*i) -> SetNeedKernelVisit ();
89  // }
90  // ??...but, there's a problem in OpenGL Stored which seems to
91  // require *all* viewers to revisit the kernel, so...
92  // const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
93  // G4ViewerListConstIterator i;
94  // for (i = viewerList.begin(); i != viewerList.end(); i++) {
95  // (*i) -> SetNeedKernelVisit (true);
96  // }
97  // Feb 2005 - commented out. Let's fix OpenGL if necessary.
98 }
99 
101 
103 
105 {
106  // If the scene has changed, or if the concrete viewer has decided
107  // that it necessary to visit the kernel, perhaps because the view
108  // parameters have changed significantly (this should be done in the
109  // concrete viewer's DrawView)...
110  if (fNeedKernelVisit) {
111  // Reset flag. This must be done before ProcessScene to prevent
112  // recursive calls when recomputing transients...
113  fNeedKernelVisit = false;
116  }
117 }
118 
120  fVP = vp;
121 }
122 
124 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath)
125 {
126  // Set the touchable for /vis/touchable/set/... commands.
127  std::ostringstream oss;
128  for (const auto& pvNodeId: fullPath) {
129  oss
130  << ' ' << pvNodeId.GetPhysicalVolume()->GetName()
131  << ' ' << pvNodeId.GetCopyNo();
132  }
133  G4UImanager::GetUIpointer()->ApplyCommand("/vis/set/touchable" + oss.str());
134 }
135 
137 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
138  G4bool visibiity)
139 {
140  // Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
141 
142  std::ostringstream oss;
143  oss << "/vis/touchable/set/visibility ";
144  if (visibiity) oss << "true"; else oss << "false";
145 
146  // The following is equivalent to
147  // G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
148  // (assuming the touchable has already been set), but avoids view rebuild.
149 
150  // Instantiate a working copy of a G4VisAttributes object...
151  G4VisAttributes workingVisAtts;
152  // and set the visibility.
153  workingVisAtts.SetVisibility(visibiity);
154 
155  fVP.AddVisAttributesModifier
157  (workingVisAtts,
160  // G4ModelingParameters::VASVisibility (VAS = Vis Attribute Signifier)
161  // signifies that it is the visibility that should be picked out
162  // and merged with the touchable's normal vis attributes.
163 
164  // Record on G4cout (with #) for information.
165  if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
166  G4cout << "# " << oss.str() << G4endl;
167  }
168 }
169 
171 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
172  const G4Colour& colour)
173 {
174  // Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
175 
176  std::ostringstream oss;
177  oss << "/vis/touchable/set/colour "
178  << colour.GetRed() << ' ' << colour.GetGreen()
179  << ' ' << colour.GetBlue() << ' ' << colour.GetAlpha();
180 
181  // The following is equivalent to
182  // G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
183  // (assuming the touchable has already been set), but avoids view rebuild.
184 
185  // Instantiate a working copy of a G4VisAttributes object...
186  G4VisAttributes workingVisAtts;
187  // and set the colour.
188  workingVisAtts.SetColour(colour);
189 
190  fVP.AddVisAttributesModifier
192  (workingVisAtts,
195  // G4ModelingParameters::VASColour (VAS = Vis Attribute Signifier)
196  // signifies that it is the colour that should be picked out
197  // and merged with the touchable's normal vis attributes.
198 
199  // Record on G4cout (with #) for information.
200  if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
201  G4cout << "# " << oss.str() << G4endl;
202  }
203 }
204 
205 std::vector <G4ThreeVector> G4VViewer::ComputeFlyThrough(G4Vector3D* /*aVect*/)
206 {
207  enum CurveType {
208  Bezier,
209  G4SplineTest};
210 
211  // Choose a curve type (for testing)
212 // int myCurveType = Bezier;
213 
214  // number if step points
215  int stepPoints = 500;
216 
217 
218  G4Spline spline;
219 
220 
221  // At the moment we don't use the aVect parameters, but build it here :
222  // Good step points for exampleB5
223  spline.AddSplinePoint(G4Vector3D(0,1000,-14000));
224  spline.AddSplinePoint(G4Vector3D(0,1000,0));
225  spline.AddSplinePoint(G4Vector3D(-4000,1000,4000));
226 
227 
228  std::vector <G4ThreeVector> viewVect;
229 
230 // if(myCurveType == Bezier) {
231 
232 
233  // Draw the spline
234 
235  for (int i = 0; i < stepPoints; i++) {
236  float t = (float)i / (float)stepPoints;
237  G4Vector3D cameraPosition = spline.GetInterpolatedSplinePoint(t);
238  // G4Vector3D targetPoint = spline.GetInterpolatedSplinePoint(t);
239 
240  // viewParam->SetViewAndLights(G4ThreeVector (cameraPosition.x(), cameraPosition.y(), cameraPosition.z()));
241  // viewParam->SetCurrentTargetPoint(targetPoint);
242  G4cout << "FLY CR("<< i << "):" << cameraPosition << G4endl;
243  viewVect.push_back(G4ThreeVector (cameraPosition.x(), cameraPosition.y(), cameraPosition.z()));
244  }
245 
246 // } else if (myCurveType == G4SplineTest) {
247  /*
248  This method is a inspire from a Bezier curve. The problem of the Bezier curve is that the path does not go straight between two waypoints.
249  This method add "stay straight" parameter which could be between 0 and 1 where the pass will follow exactly the line between the waypoints
250  Ex : stay straight = 50%
251  m1 = 3*(P1+P0)/2
252 
253  Ex : stay straight = 0%
254  m1 = (P1+P0)/2
255 
256  P1
257  / \
258  / \
259  a--x--b
260  / ° ° \
261  / ° ° \
262  m1 m2
263  / \
264  / \
265  / \
266  / \
267  P0 P2
268 
269  */
270 // G4Vector3D a;
271 // G4Vector3D b;
272 // G4Vector3D m1;
273 // G4Vector3D m2;
274 // G4Vector3D P0;
275 // G4Vector3D P1;
276 // G4Vector3D P2;
277 // G4double stayStraight = 0;
278 // G4double bezierSpeed = 0.4; // Spend 40% time in bezier curve (time between m1-m2 is 40% of time between P0-P1)
279 //
280 // G4Vector3D firstPoint;
281 // G4Vector3D lastPoint;
282 //
283 // float nbBezierSteps = (stepPoints * bezierSpeed*(1-stayStraight)) * (2./spline.GetNumPoints());
284 // float nbFirstSteps = ((stepPoints/2-nbBezierSteps/2) /(1+stayStraight)) * (2./spline.GetNumPoints());
285 //
286 // // First points
287 // firstPoint = spline.GetPoint(0);
288 // lastPoint = (firstPoint + spline.GetPoint(1))/2;
289 //
290 // for( float j=0; j<1; j+= 1/nbFirstSteps) {
291 // G4ThreeVector pt = firstPoint + (lastPoint - firstPoint) * j;
292 // viewVect.push_back(pt);
293 // G4cout << "FLY Bezier A1("<< viewVect.size()<< "):" << pt << G4endl;
294 // }
295 //
296 // for (int i = 0; i < spline.GetNumPoints()-2; i++) {
297 // P0 = spline.GetPoint(i);
298 // P1 = spline.GetPoint(i+1);
299 // P2 = spline.GetPoint(i+2);
300 //
301 // m1 = P1 - (P1-P0)*(1-stayStraight)/2;
302 // m2 = P1 + (P2-P1)*(1-stayStraight)/2;
303 //
304 // // We have to get straight path from (middile of P0-P1) to (middile of P0-P1 + (dist P0-P1) * stayStraight/2)
305 // if (stayStraight >0) {
306 //
307 // firstPoint = (P0 + P1)/2;
308 // lastPoint = (P0 + P1)/2 + (P1-P0)*stayStraight/2;
309 //
310 // for( float j=0; j<1; j+= 1/(nbFirstSteps*stayStraight)) {
311 // G4ThreeVector pt = firstPoint + (lastPoint - firstPoint)* j;
312 // viewVect.push_back(pt);
313 // G4cout << "FLY Bezier A2("<< viewVect.size()<< "):" << pt << G4endl;
314 // }
315 // }
316 // // Compute Bezier curve
317 // for( float delta = 0 ; delta < 1 ; delta += 1/nbBezierSteps)
318 // {
319 // // The Green Line
320 // a = m1 + ( (P1 - m1) * delta );
321 // b = P1 + ( (m2 - P1) * delta );
322 //
323 // // Final point
324 // G4ThreeVector pt = a + ((b-a) * delta );
325 // viewVect.push_back(pt);
326 // G4cout << "FLY Bezier("<< viewVect.size()<< "):" << pt << G4endl;
327 // }
328 //
329 // // We have to get straight path
330 // if (stayStraight >0) {
331 // firstPoint = (P1 + P2)/2 - (P2-P1)*stayStraight/2;
332 // lastPoint = (P1 + P2)/2;
333 //
334 // for( float j=0; j<1; j+= 1/(nbFirstSteps*stayStraight)) {
335 // G4ThreeVector pt = firstPoint + (lastPoint - firstPoint)* j;
336 // viewVect.push_back(pt);
337 // G4cout << "FLY Bezier B1("<< viewVect.size()<< "):" << pt << G4endl;
338 // }
339 // }
340 // }
341 //
342 // // last points
343 // firstPoint = spline.GetPoint(spline.GetNumPoints()-2);
344 // lastPoint = spline.GetPoint(spline.GetNumPoints()-1);
345 // for( float j=1; j>0; j-= 1/nbFirstSteps) {
346 // G4ThreeVector pt = lastPoint - ((lastPoint-firstPoint)*((1-stayStraight)/2) * j );
347 // viewVect.push_back(pt);
348 // G4cout << "FLY Bezier B2("<< viewVect.size()<< "):" << pt << G4endl;
349 // }
350 // }
351  return viewVect;
352 }
353 
354 
355 #ifdef G4MULTITHREADED
356 
357 void G4VViewer::DoneWithMasterThread () {
358  // G4cout << "G4VViewer::DoneWithMasterThread" << G4endl;
359 }
360 
361 void G4VViewer::MovingToMasterThread () {
362  // G4cout << "G4VViewer::MovingToMasterThread" << G4endl;
363 }
364 
365 void G4VViewer::SwitchToVisSubThread () {
366  // G4cout << "G4VViewer::SwitchToVisSubThread" << G4endl;
367 }
368 
369 void G4VViewer::DoneWithVisSubThread () {
370  // G4cout << "G4VViewer::DoneWithVisSubThread" << G4endl;
371 }
372 
373 void G4VViewer::MovingToVisSubThread () {
374  // G4cout << "G4VViewer::MovingToVisSubThread" << G4endl;
375 }
376 
377 void G4VViewer::SwitchToMasterThread () {
378  // G4cout << "G4VViewer::SwitchToMasterThread" << G4endl;
379 }
380 
381 #endif
382 
383 std::ostream& operator << (std::ostream& os, const G4VViewer& v) {
384  os << "View " << v.fName << ":\n";
385  os << v.fVP;
386  return os;
387 }
388 
389 
390 // ===== G4Spline class =====
391 
393 : vp(), delta_t(0)
394 {
395 }
396 
397 
399 {}
400 
401 // Solve the Catmull-Rom parametric equation for a given time(t) and vector quadruple (p1,p2,p3,p4)
403 {
404  float t2 = t * t;
405  float t3 = t2 * t;
406 
407  float b1 = .5 * ( -t3 + 2*t2 - t);
408  float b2 = .5 * ( 3*t3 - 5*t2 + 2);
409  float b3 = .5 * (-3*t3 + 4*t2 + t);
410  float b4 = .5 * ( t3 - t2 );
411 
412  return (p1*b1 + p2*b2 + p3*b3 + p4*b4);
413 }
414 
416 {
417  vp.push_back(v);
418  delta_t = (float)1 / (float)vp.size();
419 }
420 
421 
423 {
424  return vp[a];
425 }
426 
428 {
429  return vp.size();
430 }
431 
433 {
434  // Find out in which interval we are on the spline
435  int p = (int)(t / delta_t);
436  // Compute local control point indices
437 #define BOUNDS(pp) { if (pp < 0) pp = 0; else if (pp >= (int)vp.size()-1) pp = vp.size() - 1; }
438  int p0 = p - 1; BOUNDS(p0);
439  int p1 = p; BOUNDS(p1);
440  int p2 = p + 1; BOUNDS(p2);
441  int p3 = p + 2; BOUNDS(p3);
442  // Relative (local) time
443  float lt = (t - delta_t*(float)p) / delta_t;
444  // Interpolate
445  return CatmullRom_Eq(lt, vp[p0], vp[p1], vp[p2], vp[p3]);
446 }