Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/management/src/G4VViewer.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/management/src/G4VViewer.cc (Version 11.3.0) and /visualization/management/src/G4VViewer.cc (Version 10.6)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 //                                                 27 //
 28 //                                             <<  28 // 
 29 // John Allison  27th March 1996                   29 // John Allison  27th March 1996
 30 // Abstract interface class for graphics views     30 // Abstract interface class for graphics views.
 31                                                    31 
 32 #include "G4VViewer.hh"                            32 #include "G4VViewer.hh"
 33                                                    33 
 34 #include "G4PhysicalVolumeStore.hh"            <<  34 #include "G4ios.hh"
                                                   >>  35 #include <sstream>
                                                   >>  36 
                                                   >>  37 #include "G4VisManager.hh"
                                                   >>  38 #include "G4VGraphicsSystem.hh"
                                                   >>  39 #include "G4VSceneHandler.hh"
 35 #include "G4Scene.hh"                              40 #include "G4Scene.hh"
 36 #include "G4Timer.hh"                          <<  41 #include "G4VPhysicalVolume.hh"
 37 #include "G4Transform3D.hh"                        42 #include "G4Transform3D.hh"
 38 #include "G4UImanager.hh"                          43 #include "G4UImanager.hh"
 39 #include "G4UIsession.hh"                      << 
 40 #include "G4VGraphicsSystem.hh"                << 
 41 #include "G4VInteractiveSession.hh"            << 
 42 #include "G4VPhysicalVolume.hh"                << 
 43 #include "G4VSceneHandler.hh"                  << 
 44 #include "G4VisManager.hh"                     << 
 45 #include "G4ios.hh"                            << 
 46                                                    44 
 47 #include <sstream>                             <<  45 G4VViewer::G4VViewer (G4VSceneHandler& sceneHandler,
 48                                                <<  46           G4int id, const G4String& name):
 49 G4VViewer::G4VViewer(G4VSceneHandler& sceneHan <<  47 fSceneHandler (sceneHandler),
 50   : fSceneHandler(sceneHandler), fViewId(id),  <<  48 fViewId (id),
                                                   >>  49 //fModified (true),
                                                   >>  50 fNeedKernelVisit (true)
 51 {                                                  51 {
 52   if (name == "") {                                52   if (name == "") {
 53     std::ostringstream ost;                        53     std::ostringstream ost;
 54     ost << fSceneHandler.GetName() << '-' << f <<  54     ost << fSceneHandler.GetName () << '-' << fViewId;
 55     fName = ost.str();                             55     fName = ost.str();
 56   }                                                56   }
 57   else {                                           57   else {
 58     fName = name;                                  58     fName = name;
 59   }                                                59   }
 60   fShortName = fName.substr(0, fName.find(' ') <<  60   fShortName = fName (0, fName.find (' '));
 61   G4StrUtil::strip(fShortName);                <<  61   fShortName.strip ();
 62                                                    62 
 63   fVP = G4VisManager::GetInstance()->GetDefaul     63   fVP = G4VisManager::GetInstance()->GetDefaultViewParameters();
 64   fDefaultVP = fVP;                                64   fDefaultVP = fVP;
 65                                                << 
 66   fSceneTree.SetType(G4SceneTreeItem::root);   << 
 67   fSceneTree.SetDescription(fName);            << 
 68 }                                                  65 }
 69                                                    66 
 70 G4VViewer::~G4VViewer()                        <<  67 G4VViewer::~G4VViewer () {
 71 {                                              << 
 72   fSceneHandler.RemoveViewerFromList(this);        68   fSceneHandler.RemoveViewerFromList(this);
 73 }                                                  69 }
 74                                                    70 
 75 void G4VViewer::SetName(const G4String& name)  <<  71 void G4VViewer::SetName (const G4String& name) {
 76 {                                              << 
 77   fName = name;                                    72   fName = name;
 78   fShortName = fName.substr(0, fName.find(' ') <<  73   fShortName = fName (0, fName.find (' '));
 79   G4StrUtil::strip(fShortName);                <<  74   fShortName.strip ();
 80 }                                                  75 }
 81                                                    76 
 82 void G4VViewer::NeedKernelVisit()              <<  77 void G4VViewer::NeedKernelVisit () {
 83 {                                              <<  78 
 84   fNeedKernelVisit = true;                         79   fNeedKernelVisit = true;
 85                                                    80 
 86   // At one time I thought we'd better notify      81   // At one time I thought we'd better notify all viewers.  But I guess
 87   // each viewer can take care of itself, so t     82   // each viewer can take care of itself, so the following code is
 88   // redundant (but keep it commented out for      83   // redundant (but keep it commented out for now).   (John Allison)
 89   // Notify all viewers that a kernel visit is     84   // Notify all viewers that a kernel visit is required.
 90   // const G4ViewerList& viewerList = fSceneHa     85   // const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
 91   // G4ViewerListConstIterator i;                  86   // G4ViewerListConstIterator i;
 92   // for (i = viewerList.begin(); i != viewerL     87   // for (i = viewerList.begin(); i != viewerList.end(); i++) {
 93   //   (*i) -> SetNeedKernelVisit ();              88   //   (*i) -> SetNeedKernelVisit ();
 94   // }                                             89   // }
 95   // ??...but, there's a problem in OpenGL Sto     90   // ??...but, there's a problem in OpenGL Stored which seems to
 96   // require *all* viewers to revisit the kern     91   // require *all* viewers to revisit the kernel, so...
 97   //  const G4ViewerList& viewerList = fSceneH     92   //  const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
 98   //  G4ViewerListConstIterator i;                 93   //  G4ViewerListConstIterator i;
 99   //  for (i = viewerList.begin(); i != viewer     94   //  for (i = viewerList.begin(); i != viewerList.end(); i++) {
100   //    (*i) -> SetNeedKernelVisit (true);         95   //    (*i) -> SetNeedKernelVisit (true);
101   //  }                                            96   //  }
102   // Feb 2005 - commented out.  Let's fix Open     97   // Feb 2005 - commented out.  Let's fix OpenGL if necessary.
103 }                                                  98 }
104                                                    99 
105 void G4VViewer::FinishView() {}                << 100 void G4VViewer::FinishView () {}
106                                                   101 
107 void G4VViewer::ShowView() {}                  << 102 void G4VViewer::ShowView () {}
108                                                   103 
109 void G4VViewer::ProcessView()                  << 104 void G4VViewer::ProcessView ()
110 {                                                 105 {
111   // If the scene has changed, or if the concr    106   // If the scene has changed, or if the concrete viewer has decided
112   // that it necessary to visit the kernel, pe    107   // that it necessary to visit the kernel, perhaps because the view
113   // parameters have changed significantly (th    108   // parameters have changed significantly (this should be done in the
114   // concrete viewer's DrawView)...               109   // concrete viewer's DrawView)...
115   if (fNeedKernelVisit) {                         110   if (fNeedKernelVisit) {
116     // Reset flag.  This must be done before P    111     // Reset flag.  This must be done before ProcessScene to prevent
117     // recursive calls when recomputing transi    112     // recursive calls when recomputing transients...
118     G4Timer timer;                             << 
119     timer.Start();                             << 
120     fNeedKernelVisit = false;                     113     fNeedKernelVisit = false;
121     fSceneHandler.ClearStore();                << 114     fSceneHandler.ClearStore ();
122     fSceneHandler.ProcessScene();              << 115     fSceneHandler.ProcessScene ();
123     UpdateGUISceneTree();                      << 
124     timer.Stop();                              << 
125     fKernelVisitElapsedTimeSeconds = timer.Get << 
126   }                                               116   }
127 }                                                 117 }
128                                                   118 
129 void G4VViewer::SetViewParameters(const G4View << 119 void G4VViewer::SetViewParameters (const G4ViewParameters& vp) {
130 {                                              << 
131   fVP = vp;                                       120   fVP = vp;
132 }                                                 121 }
133                                                   122 
134 void G4VViewer::SetTouchable(                  << 123 void G4VViewer::SetTouchable
135   const std::vector<G4PhysicalVolumeModel::G4P << 124 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath)
136 {                                                 125 {
137   // Set the touchable for /vis/touchable/set/    126   // Set the touchable for /vis/touchable/set/... commands.
138   std::ostringstream oss;                         127   std::ostringstream oss;
139   const auto& pvStore = G4PhysicalVolumeStore: << 128   for (const auto& pvNodeId: fullPath) {
140   for (const auto& pvNodeId : fullPath) {      << 129     oss
141     const auto& pv = pvNodeId.GetPhysicalVolum << 130     << ' ' << pvNodeId.GetPhysicalVolume()->GetName()
142     auto iterator = find(pvStore->cbegin(), pv << 131     << ' ' << pvNodeId.GetCopyNo();
143     if (iterator == pvStore->cend()) {         << 
144       G4ExceptionDescription ed;               << 
145       ed << "Volume no longer in physical volu << 
146       G4Exception("G4VViewer::SetTouchable", " << 
147     }                                          << 
148     else {                                     << 
149       oss << ' ' << pvNodeId.GetPhysicalVolume << 
150     }                                          << 
151   }                                               132   }
152   G4UImanager::GetUIpointer()->ApplyCommand("/    133   G4UImanager::GetUIpointer()->ApplyCommand("/vis/set/touchable" + oss.str());
153 }                                                 134 }
154                                                   135 
155 void G4VViewer::TouchableSetVisibility(        << 136 void G4VViewer::TouchableSetVisibility
156   const std::vector<G4PhysicalVolumeModel::G4P << 137 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
                                                   >> 138  G4bool visibiity)
157 {                                                 139 {
158   // Changes the Vis Attribute Modifiers and s << 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";
159                                                   145 
160   // The following is equivalent to               146   // The following is equivalent to
161   //  G4UImanager::GetUIpointer()->ApplyComman << 147   //  G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
162   // (assuming the touchable has already been     148   // (assuming the touchable has already been set), but avoids view rebuild.
163                                                   149 
164   // Instantiate a working copy of a G4VisAttr    150   // Instantiate a working copy of a G4VisAttributes object...
165   G4VisAttributes workingVisAtts;                 151   G4VisAttributes workingVisAtts;
166   // and set the visibility.                      152   // and set the visibility.
167   workingVisAtts.SetVisibility(visibiity);        153   workingVisAtts.SetVisibility(visibiity);
168                                                   154 
169   fVP.AddVisAttributesModifier(G4ModelingParam << 155   fVP.AddVisAttributesModifier
170     workingVisAtts, G4ModelingParameters::VASV << 156   (G4ModelingParameters::VisAttributesModifier
                                                   >> 157    (workingVisAtts,
                                                   >> 158     G4ModelingParameters::VASVisibility,
171     G4PhysicalVolumeModel::GetPVNameCopyNoPath    159     G4PhysicalVolumeModel::GetPVNameCopyNoPath(fullPath)));
172   // G4ModelingParameters::VASVisibility (VAS     160   // G4ModelingParameters::VASVisibility (VAS = Vis Attribute Signifier)
173   // signifies that it is the visibility that     161   // signifies that it is the visibility that should be picked out
174   // and merged with the touchable's normal vi    162   // and merged with the touchable's normal vis attributes.
175                                                   163 
176   // Find scene tree item and set visibility   << 164   // Record on G4cout (with #) for information.
177   // The scene tree works with strings         << 165   if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
178   G4String fullPathString = G4PhysicalVolumeMo << 166     G4cout << "# " << oss.str() << G4endl;
179   std::list<G4SceneTreeItem>::iterator foundIt << 
180   if (fSceneTree.FindTouchableFromRoot(fullPat << 
181     foundIter->AccessVisAttributes().SetVisibi << 
182     UpdateGUISceneTree();                      << 
183   }                                            << 
184   else {                                       << 
185     G4ExceptionDescription ed;                 << 
186     ed << "Touchable \"" << fullPath << "\" no << 
187     G4Exception("G4VViewer::TouchableSetVisibi << 
188   }                                               167   }
189 }                                                 168 }
190                                                   169 
191 void G4VViewer::TouchableSetColour(            << 170 void G4VViewer::TouchableSetColour
192   const std::vector<G4PhysicalVolumeModel::G4P << 171 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
193   const G4Colour& colour)                      << 172  const G4Colour& colour)
194 {                                                 173 {
195   // Changes the Vis Attribute Modifiers and s << 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();
196                                                   180 
197   // The following is equivalent to               181   // The following is equivalent to
198   //  G4UImanager::GetUIpointer()->ApplyComman << 182   //  G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
199   // (assuming the touchable has already been     183   // (assuming the touchable has already been set), but avoids view rebuild.
200                                                   184 
201   // Instantiate a working copy of a G4VisAttr    185   // Instantiate a working copy of a G4VisAttributes object...
202   G4VisAttributes workingVisAtts;                 186   G4VisAttributes workingVisAtts;
203   // and set the colour.                          187   // and set the colour.
204   workingVisAtts.SetColour(colour);               188   workingVisAtts.SetColour(colour);
205                                                   189 
206   fVP.AddVisAttributesModifier(G4ModelingParam << 190   fVP.AddVisAttributesModifier
207     workingVisAtts, G4ModelingParameters::VASC << 191   (G4ModelingParameters::VisAttributesModifier
                                                   >> 192    (workingVisAtts,
                                                   >> 193     G4ModelingParameters::VASColour,
208     G4PhysicalVolumeModel::GetPVNameCopyNoPath    194     G4PhysicalVolumeModel::GetPVNameCopyNoPath(fullPath)));
209   // G4ModelingParameters::VASColour (VAS = Vi    195   // G4ModelingParameters::VASColour (VAS = Vis Attribute Signifier)
210   // signifies that it is the colour that shou    196   // signifies that it is the colour that should be picked out
211   // and merged with the touchable's normal vi    197   // and merged with the touchable's normal vis attributes.
212                                                   198 
213   // Find scene tree item and set colour       << 199   // Record on G4cout (with #) for information.
214   // The scene tree works with strings         << 200   if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
215   G4String fullPathString = G4PhysicalVolumeMo << 201     G4cout << "# " << oss.str() << G4endl;
216   std::list<G4SceneTreeItem>::iterator foundIt << 202   }
217   if (fSceneTree.FindTouchableFromRoot(fullPat << 203 }
218     foundIter->AccessVisAttributes().SetColour << 204 
219     UpdateGUISceneTree();                      << 205 std::vector <G4ThreeVector> G4VViewer::ComputeFlyThrough(G4Vector3D* /*aVect*/)
220   }                                            << 206 {
221   else {                                       << 207     enum CurveType {
222     G4ExceptionDescription ed;                 << 208         Bezier,
223     ed << "Touchable \"" << fullPath << "\" no << 209         G4SplineTest};
224     G4Exception("G4VViewer::TouchableSetColour << 210     
225   }                                            << 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;
226 }                                                 375 }
227                                                   376 
228 void G4VViewer::UpdateGUISceneTree()           << 377 void G4VViewer::SwitchToMasterThread () {
229 {                                              << 378   // G4cout << "G4VViewer::SwitchToMasterThread" << G4endl;
230   G4UImanager* UI = G4UImanager::GetUIpointer( << 379 }
231   auto uiWindow = dynamic_cast<G4VInteractiveS << 
232   if (uiWindow) uiWindow->UpdateSceneTree(fSce << 
233 }                                              << 
234                                                << 
235 void G4VViewer::InsertModelInSceneTree(G4VMode << 
236 {                                              << 
237   const auto& modelType = model->GetType();    << 
238   const auto& modelDescription = model->GetGlo << 
239                                                << 
240   auto type = G4SceneTreeItem::model;          << 
241   auto pvModel = dynamic_cast<G4PhysicalVolume << 
242   if (pvModel) type = G4SceneTreeItem::pvmodel << 
243                                                << 
244   fCurtailDescent = false;  // This is used la << 
245   G4String furtherInfo;                        << 
246   if (pvModel) {                               << 
247     struct : public G4PseudoScene {            << 
248       void ProcessVolume(const G4VSolid&) {++f << 
249       G4int fNTotalTouchables = 0;             << 
250     } counter;                                 << 
251     pvModel->DescribeYourselfTo(counter);  //  << 
252     if (counter.fNTotalTouchables > fMaxNTouch << 
253       std::ostringstream oss;                  << 
254       oss << counter.fNTotalTouchables << " to << 
255       furtherInfo = oss.str();                 << 
256       if (G4VisManager::GetInstance()->GetVerb << 
257         G4ExceptionDescription ed;             << 
258         ed << pvModel->GetGlobalDescription()  << 
259         ":\n  Too many touchables (" << counte << 
260         << ") for scene tree. Scene tree for t << 
261         G4Exception("G4VViewer::InsertModelInS << 
262       }                                        << 
263       fCurtailDescent = true;  // This is used << 
264     }                                          << 
265   }                                            << 
266                                                   380 
267   // Find appropriate model                    << 381 #endif
268   auto& modelItems = fSceneTree.AccessChildren << 
269   auto modelIter = modelItems.begin();         << 
270   auto pvModelIter = modelItems.end();         << 
271   for (; modelIter != modelItems.end(); ++mode << 
272     if (modelIter->GetType() == G4SceneTreeIte << 
273       pvModelIter = modelIter;  // Last pre-ex << 
274     }                                          << 
275     if (modelIter->GetModelDescription() == mo << 
276   }                                            << 
277                                                   382 
278   if (modelIter == modelItems.end()) {  // Mod << 383 std::ostream& operator << (std::ostream& os, const G4VViewer& v) {
279     G4SceneTreeItem modelItem(type);           << 384   os << "View " << v.fName << ":\n";
280     modelItem.SetDescription("model");         << 385   os << v.fVP;
281     modelItem.SetModelType(modelType);         << 386   return os;
282     modelItem.SetModelDescription(modelDescrip << 
283     modelItem.SetFurtherInfo(furtherInfo);     << 
284     if (pvModelIter != modelItems.end() &&  // << 
285         type == G4SceneTreeItem::pvmodel) {    << 
286       fSceneTree.InsertChild(++pvModelIter, mo << 
287     } else {                                   << 
288       fSceneTree.InsertChild(modelIter, modelI << 
289     }                                          << 
290   } else {  // Existing model - mark visible = << 
291     modelIter->AccessVisAttributes().SetVisibi << 
292   }                                            << 
293 }                                                 387 }
294                                                   388 
295 G4VViewer::SceneTreeScene::SceneTreeScene(G4VV << 
296 : fpViewer (pViewer)                           << 
297 , fpPVModel(pPVModel)                          << 
298 {                                              << 
299   if (fpPVModel == nullptr) {                  << 
300     G4Exception("G4VViewer::SceneTreeScene::Sc << 
301                 "G4PhysicalVolumeModel pointer << 
302     return;  // To keep Coverity happy         << 
303   }                                            << 
304                                                << 
305   // Describe the model to an empty scene simp << 
306   struct : public G4PseudoScene {              << 
307     void ProcessVolume(const G4VSolid&) {}     << 
308   } counter;                                   << 
309   fpPVModel->DescribeYourselfTo(counter);  //  << 
310                                                << 
311   // Limit the expanded depth to limit the num << 
312   G4int expanded = 0;                          << 
313   for (const auto& dn : fpPVModel->GetNumberOf << 
314     expanded += dn.second;                     << 
315     if (fMaximumExpandedDepth < dn.first) fMax << 
316     if (expanded > fMaximumExpanded) break;    << 
317   }                                            << 
318                                                   389 
319   // Find appropriate model and its iterator   << 390 // ===== G4Spline class =====
320   const auto& modelID = fpPVModel->GetGlobalDe << 
321   auto& modelItems = fpViewer->fSceneTree.Acce << 
322   fModelIter = modelItems.begin();             << 
323   for (; fModelIter != modelItems.end(); ++fMo << 
324     if (fModelIter->GetModelDescription() == m << 
325   }                                            << 
326   if (fModelIter == modelItems.end()) {        << 
327     G4Exception("G4VViewer::SceneTreeScene::Sc << 
328                 "Model not found");            << 
329   }                                            << 
330 }                                              << 
331                                                   391 
332 void G4VViewer::SceneTreeScene::ProcessVolume( << 392 G4VViewer::G4Spline::G4Spline()
                                                   >> 393 : vp(), delta_t(0)
333 {                                                 394 {
334   if (fpViewer->fCurtailDescent) {             << 395 }
335     fpPVModel->CurtailDescent();               << 
336     return;                                    << 
337   }                                            << 
338                                                   396 
339   const auto& modelID = fpPVModel->GetGlobalDe << 
340                                                   397 
341   std::ostringstream oss;                      << 398 G4VViewer::G4Spline::~G4Spline()
342   oss << fpPVModel->GetFullPVPath();  // of th << 399 {}
343   G4String fullPathString(oss.str());  // Has  << 
344                                                   400 
345   // Navigate scene tree and find or insert to << 401 // Solve the Catmull-Rom parametric equation for a given time(t) and vector quadruple (p1,p2,p3,p4)
346   // Work down the path - "name id", then "nam << 402 G4Vector3D G4VViewer::G4Spline::CatmullRom_Eq(float t, const G4Vector3D& p1, const G4Vector3D& p2, const G4Vector3D& p3, const G4Vector3D& p4)
347   const auto& nodeIDs = fpPVModel->GetFullPVPa << 403 {
348   G4String partialPathString;                  << 404     float t2 = t * t;
349   auto currentIter = fModelIter;               << 405     float t3 = t2 * t;
350   G4int depth = 0;                             << 406     
351   for (const auto& nodeID : nodeIDs) {         << 407     float b1 = .5 * (  -t3 + 2*t2 - t);
352     std::ostringstream oss1;                   << 408     float b2 = .5 * ( 3*t3 - 5*t2 + 2);
353     oss1 << nodeID;                            << 409     float b3 = .5 * (-3*t3 + 4*t2 + t);
354     partialPathString += ' ' + oss1.str();     << 410     float b4 = .5 * (   t3 -   t2    );
355     currentIter =                              << 411     
356     FindOrInsertTouchable(modelID, *currentIte << 412     return (p1*b1 + p2*b2 + p3*b3 + p4*b4);
357   }                                            << 
358 }                                                 413 }
359                                                   414 
360 // clang-format off                            << 415 void G4VViewer::G4Spline::AddSplinePoint(const G4Vector3D& v)
361 std::list<G4SceneTreeItem>::iterator G4VViewer << 416 {
362  (const G4String& modelID, G4SceneTreeItem& mo << 417     vp.push_back(v);
363   G4int depth, const G4String& partialPathStri << 418     delta_t = (float)1 / (float)vp.size();
364 {                                              << 419 }
365   auto& children = mother.AccessChildren();    << 
366   auto childIter = children.begin();           << 
367   for (; childIter != children.end(); ++childI << 
368     if (childIter->GetPVPath() == partialPathS << 
369   }                                            << 
370   if (childIter != children.end()) {           << 
371                                                << 
372     // Item already exists                     << 
373                                                << 
374     if (childIter->GetType() == G4SceneTreeIte << 
375                                                   420 
376       // Previously it was a ghost - but maybe << 
377                                                   421 
378       if (partialPathString == fullPathString) << 422 G4Vector3D G4VViewer::G4Spline::GetPoint(int a)
379         // Partial path string refers to the a << 423 {
380         childIter->SetType(G4SceneTreeItem::to << 424     return vp[a];
381         // Populate with information           << 425 }
382         childIter->SetDescription(fpPVModel->G << 
383         childIter->SetModelType(fpPVModel->Get << 
384         childIter->SetModelDescription(modelID << 
385         childIter->SetPVPath(partialPathString << 
386         if (fpVisAttributes) childIter->SetVis << 
387         childIter->SetAttDefs(fpPVModel->GetAt << 
388         childIter->SetAttValues(fpPVModel->Cre << 
389       }  // Partial path string refers to an a << 
390                                                << 
391     } else {                                   << 
392                                                << 
393       // Already a pre-existing full touchable << 
394                                                << 
395       if (partialPathString == fullPathString) << 
396         // Partial path string refers to the a << 
397         // Replace vis attributes (if any) - t << 
398         if (fpVisAttributes) childIter->SetVis << 
399       }  // Partial path string refers to an a << 
400                                                << 
401     }                                          << 
402                                                << 
403   } else {                                     << 
404                                                << 
405     // Item does not yet exist                 << 
406                                                << 
407     if (partialPathString == fullPathString) { << 
408                                                << 
409       // Partial path string refers to the act << 
410       // Insert new touchable item             << 
411       G4SceneTreeItem touchable(G4SceneTreeIte << 
412       touchable.SetExpanded(depth > fMaximumEx << 
413       touchable.SetDescription(fpPVModel->GetC << 
414       touchable.SetModelType(fpPVModel->GetTyp << 
415       touchable.SetModelDescription(modelID);  << 
416       touchable.SetPVPath(partialPathString);  << 
417       if (fpVisAttributes) touchable.SetVisAtt << 
418       touchable.SetAttDefs(fpPVModel->GetAttDe << 
419       touchable.SetAttValues(fpPVModel->Create << 
420       childIter = mother.InsertChild(childIter << 
421                                                << 
422     } else {                                   << 
423                                                << 
424       // Partial path string refers to an ance << 
425       G4SceneTreeItem ghost(G4SceneTreeItem::g << 
426       ghost.SetExpanded(depth > fMaximumExpand << 
427       // Create a tag from the partial path    << 
428       std::istringstream iss(partialPathString << 
429       G4String name, copyNo;                   << 
430       while (iss >> name >> copyNo);           << 
431       std::ostringstream oss;                  << 
432       oss << name << ':' << copyNo;            << 
433       ghost.SetDescription(oss.str());         << 
434       ghost.SetModelType(fpPVModel->GetType()) << 
435       ghost.SetModelDescription(modelID);      << 
436       ghost.SetPVPath(partialPathString);      << 
437       ghost.AccessVisAttributes().SetVisibilit << 
438       childIter = mother.InsertChild(childIter << 
439     }                                          << 
440   }                                            << 
441                                                   426 
442   return childIter;                            << 427 int G4VViewer::G4Spline::GetNumPoints()
                                                   >> 428 {
                                                   >> 429     return vp.size();
443 }                                                 430 }
444 // clang-format on                             << 
445                                                   431 
446 std::ostream& operator<<(std::ostream& os, con << 432 G4Vector3D G4VViewer::G4Spline::GetInterpolatedSplinePoint(float t)
447 {                                                 433 {
448   os << "View " << v.fName << ":\n";           << 434     // Find out in which interval we are on the spline
449   os << v.fVP;                                 << 435     int p = (int)(t / delta_t);
450   return os;                                   << 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]);
451 }                                                 446 }
452                                                   447