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 11.0.p2)


  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 "G4PhysicalVolumeStore.hh"
                                                   >>  42 #include "G4VPhysicalVolume.hh"
 37 #include "G4Transform3D.hh"                        43 #include "G4Transform3D.hh"
 38 #include "G4UImanager.hh"                          44 #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                                                << 
 47 #include <sstream>                             << 
 48                                                    45 
 49 G4VViewer::G4VViewer(G4VSceneHandler& sceneHan <<  46 G4VViewer::G4VViewer (G4VSceneHandler& sceneHandler,
 50   : fSceneHandler(sceneHandler), fViewId(id),  <<  47           G4int id, const G4String& name):
                                                   >>  48 fSceneHandler (sceneHandler),
                                                   >>  49 fViewId (id),
                                                   >>  50 //fModified (true),
                                                   >>  51 fNeedKernelVisit (true)
 51 {                                                  52 {
 52   if (name == "") {                                53   if (name == "") {
 53     std::ostringstream ost;                        54     std::ostringstream ost;
 54     ost << fSceneHandler.GetName() << '-' << f <<  55     ost << fSceneHandler.GetName () << '-' << fViewId;
 55     fName = ost.str();                             56     fName = ost.str();
 56   }                                                57   }
 57   else {                                           58   else {
 58     fName = name;                                  59     fName = name;
 59   }                                                60   }
 60   fShortName = fName.substr(0, fName.find(' ') <<  61   fShortName = fName.substr(0, fName.find (' '));
 61   G4StrUtil::strip(fShortName);                    62   G4StrUtil::strip(fShortName);
 62                                                    63 
 63   fVP = G4VisManager::GetInstance()->GetDefaul     64   fVP = G4VisManager::GetInstance()->GetDefaultViewParameters();
 64   fDefaultVP = fVP;                                65   fDefaultVP = fVP;
 65                                                << 
 66   fSceneTree.SetType(G4SceneTreeItem::root);   << 
 67   fSceneTree.SetDescription(fName);            << 
 68 }                                                  66 }
 69                                                    67 
 70 G4VViewer::~G4VViewer()                        <<  68 G4VViewer::~G4VViewer () {
 71 {                                              << 
 72   fSceneHandler.RemoveViewerFromList(this);        69   fSceneHandler.RemoveViewerFromList(this);
 73 }                                                  70 }
 74                                                    71 
 75 void G4VViewer::SetName(const G4String& name)  <<  72 void G4VViewer::SetName (const G4String& name) {
 76 {                                              << 
 77   fName = name;                                    73   fName = name;
 78   fShortName = fName.substr(0, fName.find(' ') <<  74   fShortName = fName.substr(0, fName.find (' '));
 79   G4StrUtil::strip(fShortName);                    75   G4StrUtil::strip(fShortName);
 80 }                                                  76 }
 81                                                    77 
 82 void G4VViewer::NeedKernelVisit()              <<  78 void G4VViewer::NeedKernelVisit () {
 83 {                                              <<  79 
 84   fNeedKernelVisit = true;                         80   fNeedKernelVisit = true;
 85                                                    81 
 86   // At one time I thought we'd better notify      82   // At one time I thought we'd better notify all viewers.  But I guess
 87   // each viewer can take care of itself, so t     83   // each viewer can take care of itself, so the following code is
 88   // redundant (but keep it commented out for      84   // redundant (but keep it commented out for now).   (John Allison)
 89   // Notify all viewers that a kernel visit is     85   // Notify all viewers that a kernel visit is required.
 90   // const G4ViewerList& viewerList = fSceneHa     86   // const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
 91   // G4ViewerListConstIterator i;                  87   // G4ViewerListConstIterator i;
 92   // for (i = viewerList.begin(); i != viewerL     88   // for (i = viewerList.begin(); i != viewerList.end(); i++) {
 93   //   (*i) -> SetNeedKernelVisit ();              89   //   (*i) -> SetNeedKernelVisit ();
 94   // }                                             90   // }
 95   // ??...but, there's a problem in OpenGL Sto     91   // ??...but, there's a problem in OpenGL Stored which seems to
 96   // require *all* viewers to revisit the kern     92   // require *all* viewers to revisit the kernel, so...
 97   //  const G4ViewerList& viewerList = fSceneH     93   //  const G4ViewerList& viewerList = fSceneHandler.GetViewerList ();
 98   //  G4ViewerListConstIterator i;                 94   //  G4ViewerListConstIterator i;
 99   //  for (i = viewerList.begin(); i != viewer     95   //  for (i = viewerList.begin(); i != viewerList.end(); i++) {
100   //    (*i) -> SetNeedKernelVisit (true);         96   //    (*i) -> SetNeedKernelVisit (true);
101   //  }                                            97   //  }
102   // Feb 2005 - commented out.  Let's fix Open     98   // Feb 2005 - commented out.  Let's fix OpenGL if necessary.
103 }                                                  99 }
104                                                   100 
105 void G4VViewer::FinishView() {}                << 101 void G4VViewer::FinishView () {}
106                                                   102 
107 void G4VViewer::ShowView() {}                  << 103 void G4VViewer::ShowView () {}
108                                                   104 
109 void G4VViewer::ProcessView()                  << 105 void G4VViewer::ProcessView ()
110 {                                                 106 {
111   // If the scene has changed, or if the concr    107   // If the scene has changed, or if the concrete viewer has decided
112   // that it necessary to visit the kernel, pe    108   // that it necessary to visit the kernel, perhaps because the view
113   // parameters have changed significantly (th    109   // parameters have changed significantly (this should be done in the
114   // concrete viewer's DrawView)...               110   // concrete viewer's DrawView)...
115   if (fNeedKernelVisit) {                         111   if (fNeedKernelVisit) {
116     // Reset flag.  This must be done before P    112     // Reset flag.  This must be done before ProcessScene to prevent
117     // recursive calls when recomputing transi    113     // recursive calls when recomputing transients...
118     G4Timer timer;                             << 
119     timer.Start();                             << 
120     fNeedKernelVisit = false;                     114     fNeedKernelVisit = false;
121     fSceneHandler.ClearStore();                << 115     fSceneHandler.ClearStore ();
122     fSceneHandler.ProcessScene();              << 116     fSceneHandler.ProcessScene ();
123     UpdateGUISceneTree();                      << 
124     timer.Stop();                              << 
125     fKernelVisitElapsedTimeSeconds = timer.Get << 
126   }                                               117   }
127 }                                                 118 }
128                                                   119 
129 void G4VViewer::SetViewParameters(const G4View << 120 void G4VViewer::SetViewParameters (const G4ViewParameters& vp) {
130 {                                              << 
131   fVP = vp;                                       121   fVP = vp;
132 }                                                 122 }
133                                                   123 
134 void G4VViewer::SetTouchable(                  << 124 void G4VViewer::SetTouchable
135   const std::vector<G4PhysicalVolumeModel::G4P << 125 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath)
136 {                                                 126 {
137   // Set the touchable for /vis/touchable/set/    127   // Set the touchable for /vis/touchable/set/... commands.
138   std::ostringstream oss;                         128   std::ostringstream oss;
139   const auto& pvStore = G4PhysicalVolumeStore:    129   const auto& pvStore = G4PhysicalVolumeStore::GetInstance();
140   for (const auto& pvNodeId : fullPath) {      << 130   for (const auto& pvNodeId: fullPath) {
141     const auto& pv = pvNodeId.GetPhysicalVolum    131     const auto& pv = pvNodeId.GetPhysicalVolume();
142     auto iterator = find(pvStore->cbegin(), pv << 132     auto iterator = find(pvStore->begin(),pvStore->end(),pv);
143     if (iterator == pvStore->cend()) {         << 133     if (iterator == pvStore->end()) {
144       G4ExceptionDescription ed;                  134       G4ExceptionDescription ed;
145       ed << "Volume no longer in physical volu    135       ed << "Volume no longer in physical volume store.";
146       G4Exception("G4VViewer::SetTouchable", " << 136       G4Exception("G4VViewer::SetTouchable", "visman0501", JustWarning, ed);
147     }                                          << 137     } else {
148     else {                                     << 138       oss
149       oss << ' ' << pvNodeId.GetPhysicalVolume << 139       << ' ' << pvNodeId.GetPhysicalVolume()->GetName()
                                                   >> 140       << ' ' << pvNodeId.GetCopyNo();
150     }                                             141     }
151   }                                               142   }
152   G4UImanager::GetUIpointer()->ApplyCommand("/    143   G4UImanager::GetUIpointer()->ApplyCommand("/vis/set/touchable" + oss.str());
153 }                                                 144 }
154                                                   145 
155 void G4VViewer::TouchableSetVisibility(        << 146 void G4VViewer::TouchableSetVisibility
156   const std::vector<G4PhysicalVolumeModel::G4P << 147 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
                                                   >> 148  G4bool visibiity)
157 {                                                 149 {
158   // Changes the Vis Attribute Modifiers and s << 150   // Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
                                                   >> 151 
                                                   >> 152   std::ostringstream oss;
                                                   >> 153   oss << "/vis/touchable/set/visibility ";
                                                   >> 154   if (visibiity) oss << "true"; else oss << "false";
159                                                   155 
160   // The following is equivalent to               156   // The following is equivalent to
161   //  G4UImanager::GetUIpointer()->ApplyComman << 157   //  G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
162   // (assuming the touchable has already been     158   // (assuming the touchable has already been set), but avoids view rebuild.
163                                                   159 
164   // Instantiate a working copy of a G4VisAttr    160   // Instantiate a working copy of a G4VisAttributes object...
165   G4VisAttributes workingVisAtts;                 161   G4VisAttributes workingVisAtts;
166   // and set the visibility.                      162   // and set the visibility.
167   workingVisAtts.SetVisibility(visibiity);        163   workingVisAtts.SetVisibility(visibiity);
168                                                   164 
169   fVP.AddVisAttributesModifier(G4ModelingParam << 165   fVP.AddVisAttributesModifier
170     workingVisAtts, G4ModelingParameters::VASV << 166   (G4ModelingParameters::VisAttributesModifier
                                                   >> 167    (workingVisAtts,
                                                   >> 168     G4ModelingParameters::VASVisibility,
171     G4PhysicalVolumeModel::GetPVNameCopyNoPath    169     G4PhysicalVolumeModel::GetPVNameCopyNoPath(fullPath)));
172   // G4ModelingParameters::VASVisibility (VAS     170   // G4ModelingParameters::VASVisibility (VAS = Vis Attribute Signifier)
173   // signifies that it is the visibility that     171   // signifies that it is the visibility that should be picked out
174   // and merged with the touchable's normal vi    172   // and merged with the touchable's normal vis attributes.
175                                                   173 
176   // Find scene tree item and set visibility   << 174   // Record on G4cout (with #) for information.
177   // The scene tree works with strings         << 175   if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
178   G4String fullPathString = G4PhysicalVolumeMo << 176     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   }                                               177   }
189 }                                                 178 }
190                                                   179 
191 void G4VViewer::TouchableSetColour(            << 180 void G4VViewer::TouchableSetColour
192   const std::vector<G4PhysicalVolumeModel::G4P << 181 (const std::vector<G4PhysicalVolumeModel::G4PhysicalVolumeNodeID>& fullPath,
193   const G4Colour& colour)                      << 182  const G4Colour& colour)
194 {                                                 183 {
195   // Changes the Vis Attribute Modifiers and s << 184   // Changes the Vis Attribute Modifiers WITHOUT triggering a rebuild.
                                                   >> 185 
                                                   >> 186   std::ostringstream oss;
                                                   >> 187   oss << "/vis/touchable/set/colour "
                                                   >> 188   << colour.GetRed() << ' ' << colour.GetGreen()
                                                   >> 189   << ' ' << colour.GetBlue() << ' ' << colour.GetAlpha();
196                                                   190 
197   // The following is equivalent to               191   // The following is equivalent to
198   //  G4UImanager::GetUIpointer()->ApplyComman << 192   //  G4UImanager::GetUIpointer()->ApplyCommand(oss.str());
199   // (assuming the touchable has already been     193   // (assuming the touchable has already been set), but avoids view rebuild.
200                                                   194 
201   // Instantiate a working copy of a G4VisAttr    195   // Instantiate a working copy of a G4VisAttributes object...
202   G4VisAttributes workingVisAtts;                 196   G4VisAttributes workingVisAtts;
203   // and set the colour.                          197   // and set the colour.
204   workingVisAtts.SetColour(colour);               198   workingVisAtts.SetColour(colour);
205                                                   199 
206   fVP.AddVisAttributesModifier(G4ModelingParam << 200   fVP.AddVisAttributesModifier
207     workingVisAtts, G4ModelingParameters::VASC << 201   (G4ModelingParameters::VisAttributesModifier
                                                   >> 202    (workingVisAtts,
                                                   >> 203     G4ModelingParameters::VASColour,
208     G4PhysicalVolumeModel::GetPVNameCopyNoPath    204     G4PhysicalVolumeModel::GetPVNameCopyNoPath(fullPath)));
209   // G4ModelingParameters::VASColour (VAS = Vi    205   // G4ModelingParameters::VASColour (VAS = Vis Attribute Signifier)
210   // signifies that it is the colour that shou    206   // signifies that it is the colour that should be picked out
211   // and merged with the touchable's normal vi    207   // and merged with the touchable's normal vis attributes.
212                                                   208 
213   // Find scene tree item and set colour       << 209   // Record on G4cout (with #) for information.
214   // The scene tree works with strings         << 210   if (G4UImanager::GetUIpointer()->GetVerboseLevel() >= 2) {
215   G4String fullPathString = G4PhysicalVolumeMo << 211     G4cout << "# " << oss.str() << G4endl;
216   std::list<G4SceneTreeItem>::iterator foundIt << 212   }
217   if (fSceneTree.FindTouchableFromRoot(fullPat << 213 }
218     foundIter->AccessVisAttributes().SetColour << 214 
219     UpdateGUISceneTree();                      << 215 std::vector <G4ThreeVector> G4VViewer::ComputeFlyThrough(G4Vector3D* /*aVect*/)
220   }                                            << 216 {
221   else {                                       << 217     enum CurveType {
222     G4ExceptionDescription ed;                 << 218         Bezier,
223     ed << "Touchable \"" << fullPath << "\" no << 219         G4SplineTest};
224     G4Exception("G4VViewer::TouchableSetColour << 220     
225   }                                            << 221     // Choose a curve type (for testing)
                                                   >> 222 //    int myCurveType = Bezier;
                                                   >> 223 
                                                   >> 224     // number if step points
                                                   >> 225     int stepPoints = 500;
                                                   >> 226 
                                                   >> 227     
                                                   >> 228     G4Spline spline;
                                                   >> 229 
                                                   >> 230     
                                                   >> 231     // At the moment we don't use the aVect parameters, but build it here :
                                                   >> 232     // Good step points for exampleB5
                                                   >> 233     spline.AddSplinePoint(G4Vector3D(0,1000,-14000));
                                                   >> 234     spline.AddSplinePoint(G4Vector3D(0,1000,0));
                                                   >> 235     spline.AddSplinePoint(G4Vector3D(-4000,1000,4000));
                                                   >> 236 
                                                   >> 237     
                                                   >> 238     std::vector <G4ThreeVector> viewVect;
                                                   >> 239 
                                                   >> 240 //    if(myCurveType == Bezier) {
                                                   >> 241 
                                                   >> 242         
                                                   >> 243         // Draw the spline
                                                   >> 244         
                                                   >> 245         for (int i = 0; i < stepPoints; i++) {
                                                   >> 246             float t = (float)i / (float)stepPoints;
                                                   >> 247             G4Vector3D cameraPosition = spline.GetInterpolatedSplinePoint(t);
                                                   >> 248             //        G4Vector3D targetPoint = spline.GetInterpolatedSplinePoint(t);
                                                   >> 249             
                                                   >> 250             //        viewParam->SetViewAndLights(G4ThreeVector (cameraPosition.x(), cameraPosition.y(), cameraPosition.z()));
                                                   >> 251             //        viewParam->SetCurrentTargetPoint(targetPoint);
                                                   >> 252             G4cout << "FLY CR("<< i << "):" << cameraPosition << G4endl;
                                                   >> 253             viewVect.push_back(G4ThreeVector (cameraPosition.x(), cameraPosition.y(), cameraPosition.z()));
                                                   >> 254         }
                                                   >> 255         
                                                   >> 256 //    } else if (myCurveType == G4SplineTest) {
                                                   >> 257         /*
                                                   >> 258          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.
                                                   >> 259          This method add "stay straight" parameter which could be between 0 and 1 where the pass will follow exactly the line between the waypoints
                                                   >> 260          Ex : stay straight = 50%
                                                   >> 261          m1 = 3*(P1+P0)/2
                                                   >> 262          
                                                   >> 263          Ex : stay straight = 0%
                                                   >> 264          m1 = (P1+P0)/2
                                                   >> 265          
                                                   >> 266          P1
                                                   >> 267          /  \
                                                   >> 268          /    \
                                                   >> 269          a--x--b
                                                   >> 270          /  °  °  \
                                                   >> 271          / °      ° \
                                                   >> 272          m1           m2
                                                   >> 273          /              \
                                                   >> 274          /                \
                                                   >> 275          /                  \
                                                   >> 276          /                    \
                                                   >> 277          P0                     P2
                                                   >> 278          
                                                   >> 279          */
                                                   >> 280 //        G4Vector3D a;
                                                   >> 281 //        G4Vector3D b;
                                                   >> 282 //        G4Vector3D m1;
                                                   >> 283 //        G4Vector3D m2;
                                                   >> 284 //        G4Vector3D P0;
                                                   >> 285 //        G4Vector3D P1;
                                                   >> 286 //        G4Vector3D P2;
                                                   >> 287 //        G4double stayStraight = 0;
                                                   >> 288 //        G4double bezierSpeed = 0.4; // Spend 40% time in bezier curve (time between m1-m2 is 40% of time between P0-P1)
                                                   >> 289 //        
                                                   >> 290 //        G4Vector3D firstPoint;
                                                   >> 291 //        G4Vector3D lastPoint;
                                                   >> 292 //        
                                                   >> 293 //        float nbBezierSteps = (stepPoints * bezierSpeed*(1-stayStraight)) * (2./spline.GetNumPoints());
                                                   >> 294 //        float nbFirstSteps = ((stepPoints/2-nbBezierSteps/2) /(1+stayStraight)) * (2./spline.GetNumPoints());
                                                   >> 295 //        
                                                   >> 296 //        // First points
                                                   >> 297 //        firstPoint = spline.GetPoint(0);
                                                   >> 298 //        lastPoint = (firstPoint + spline.GetPoint(1))/2;
                                                   >> 299 //        
                                                   >> 300 //        for( float j=0; j<1; j+= 1/nbFirstSteps) {
                                                   >> 301 //            G4ThreeVector pt = firstPoint + (lastPoint - firstPoint) * j;
                                                   >> 302 //            viewVect.push_back(pt);
                                                   >> 303 //            G4cout << "FLY Bezier A1("<< viewVect.size()<< "):" << pt << G4endl;
                                                   >> 304 //        }
                                                   >> 305 //        
                                                   >> 306 //        for (int i = 0; i < spline.GetNumPoints()-2; i++) {
                                                   >> 307 //            P0 = spline.GetPoint(i);
                                                   >> 308 //            P1 = spline.GetPoint(i+1);
                                                   >> 309 //            P2 = spline.GetPoint(i+2);
                                                   >> 310 //            
                                                   >> 311 //            m1 = P1 - (P1-P0)*(1-stayStraight)/2;
                                                   >> 312 //            m2 = P1 + (P2-P1)*(1-stayStraight)/2;
                                                   >> 313 //            
                                                   >> 314 //            // We have to get straight path from (middile of P0-P1) to (middile of P0-P1 + (dist P0-P1) * stayStraight/2)
                                                   >> 315 //            if (stayStraight >0) {
                                                   >> 316 //                
                                                   >> 317 //                firstPoint = (P0 + P1)/2;
                                                   >> 318 //                lastPoint = (P0 + P1)/2 + (P1-P0)*stayStraight/2;
                                                   >> 319 //                
                                                   >> 320 //                for( float j=0; j<1; j+= 1/(nbFirstSteps*stayStraight)) {
                                                   >> 321 //                    G4ThreeVector pt = firstPoint + (lastPoint - firstPoint)* j;
                                                   >> 322 //                    viewVect.push_back(pt);
                                                   >> 323 //                    G4cout << "FLY Bezier A2("<< viewVect.size()<< "):" << pt << G4endl;
                                                   >> 324 //                }
                                                   >> 325 //            }
                                                   >> 326 //            // Compute Bezier curve
                                                   >> 327 //            for( float delta = 0 ; delta < 1 ; delta += 1/nbBezierSteps)
                                                   >> 328 //            {
                                                   >> 329 //                // The Green Line
                                                   >> 330 //                a = m1 + ( (P1 - m1) * delta );
                                                   >> 331 //                b = P1 + ( (m2 - P1) * delta );
                                                   >> 332 //                
                                                   >> 333 //                // Final point
                                                   >> 334 //                G4ThreeVector pt = a + ((b-a) * delta );
                                                   >> 335 //                viewVect.push_back(pt);
                                                   >> 336 //                G4cout << "FLY Bezier("<< viewVect.size()<< "):" << pt << G4endl;
                                                   >> 337 //            }
                                                   >> 338 //            
                                                   >> 339 //            // We have to get straight path
                                                   >> 340 //            if (stayStraight >0) {
                                                   >> 341 //                firstPoint = (P1 + P2)/2 - (P2-P1)*stayStraight/2;
                                                   >> 342 //                lastPoint = (P1 + P2)/2;
                                                   >> 343 //                
                                                   >> 344 //                for( float j=0; j<1; j+= 1/(nbFirstSteps*stayStraight)) {
                                                   >> 345 //                    G4ThreeVector pt = firstPoint + (lastPoint - firstPoint)* j;
                                                   >> 346 //                    viewVect.push_back(pt);
                                                   >> 347 //                    G4cout << "FLY Bezier B1("<< viewVect.size()<< "):" << pt << G4endl;
                                                   >> 348 //                }
                                                   >> 349 //            }
                                                   >> 350 //        }
                                                   >> 351 //        
                                                   >> 352 //        // last points
                                                   >> 353 //        firstPoint = spline.GetPoint(spline.GetNumPoints()-2);
                                                   >> 354 //        lastPoint = spline.GetPoint(spline.GetNumPoints()-1);
                                                   >> 355 //        for( float j=1; j>0; j-= 1/nbFirstSteps) {
                                                   >> 356 //            G4ThreeVector pt = lastPoint - ((lastPoint-firstPoint)*((1-stayStraight)/2) * j );
                                                   >> 357 //            viewVect.push_back(pt);
                                                   >> 358 //            G4cout << "FLY Bezier B2("<< viewVect.size()<< "):" << pt << G4endl;
                                                   >> 359 //        }
                                                   >> 360 //    }
                                                   >> 361     return viewVect;
                                                   >> 362 }
                                                   >> 363 
                                                   >> 364 
                                                   >> 365 #ifdef G4MULTITHREADED
                                                   >> 366 
                                                   >> 367 void G4VViewer::DoneWithMasterThread () {
                                                   >> 368   // G4cout << "G4VViewer::DoneWithMasterThread" << G4endl;
                                                   >> 369 }
                                                   >> 370 
                                                   >> 371 void G4VViewer::MovingToMasterThread () {
                                                   >> 372   // G4cout << "G4VViewer::MovingToMasterThread" << G4endl;
                                                   >> 373 }
                                                   >> 374 
                                                   >> 375 void G4VViewer::SwitchToVisSubThread () {
                                                   >> 376   // G4cout << "G4VViewer::SwitchToVisSubThread" << G4endl;
                                                   >> 377 }
                                                   >> 378 
                                                   >> 379 void G4VViewer::DoneWithVisSubThread () {
                                                   >> 380   // G4cout << "G4VViewer::DoneWithVisSubThread" << G4endl;
                                                   >> 381 }
                                                   >> 382 
                                                   >> 383 void G4VViewer::MovingToVisSubThread () {
                                                   >> 384   // G4cout << "G4VViewer::MovingToVisSubThread" << G4endl;
226 }                                                 385 }
227                                                   386 
228 void G4VViewer::UpdateGUISceneTree()           << 387 void G4VViewer::SwitchToMasterThread () {
229 {                                              << 388   // G4cout << "G4VViewer::SwitchToMasterThread" << G4endl;
230   G4UImanager* UI = G4UImanager::GetUIpointer( << 
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                                                << 
267   // Find appropriate model                    << 
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                                                << 
278   if (modelIter == modelItems.end()) {  // Mod << 
279     G4SceneTreeItem modelItem(type);           << 
280     modelItem.SetDescription("model");         << 
281     modelItem.SetModelType(modelType);         << 
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 }                                                 389 }
294                                                   390 
295 G4VViewer::SceneTreeScene::SceneTreeScene(G4VV << 391 #endif
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                                                   392 
319   // Find appropriate model and its iterator   << 393 std::ostream& operator << (std::ostream& os, const G4VViewer& v) {
320   const auto& modelID = fpPVModel->GetGlobalDe << 394   os << "View " << v.fName << ":\n";
321   auto& modelItems = fpViewer->fSceneTree.Acce << 395   os << v.fVP;
322   fModelIter = modelItems.begin();             << 396   return os;
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 }                                                 397 }
331                                                   398 
332 void G4VViewer::SceneTreeScene::ProcessVolume( << 
333 {                                              << 
334   if (fpViewer->fCurtailDescent) {             << 
335     fpPVModel->CurtailDescent();               << 
336     return;                                    << 
337   }                                            << 
338                                                << 
339   const auto& modelID = fpPVModel->GetGlobalDe << 
340                                                   399 
341   std::ostringstream oss;                      << 400 // ===== G4Spline class =====
342   oss << fpPVModel->GetFullPVPath();  // of th << 
343   G4String fullPathString(oss.str());  // Has  << 
344                                                   401 
345   // Navigate scene tree and find or insert to << 402 G4VViewer::G4Spline::G4Spline()
346   // Work down the path - "name id", then "nam << 403 : vp(), delta_t(0)
347   const auto& nodeIDs = fpPVModel->GetFullPVPa << 404 {
348   G4String partialPathString;                  << 
349   auto currentIter = fModelIter;               << 
350   G4int depth = 0;                             << 
351   for (const auto& nodeID : nodeIDs) {         << 
352     std::ostringstream oss1;                   << 
353     oss1 << nodeID;                            << 
354     partialPathString += ' ' + oss1.str();     << 
355     currentIter =                              << 
356     FindOrInsertTouchable(modelID, *currentIte << 
357   }                                            << 
358 }                                                 405 }
359                                                   406 
360 // clang-format off                            << 
361 std::list<G4SceneTreeItem>::iterator G4VViewer << 
362  (const G4String& modelID, G4SceneTreeItem& mo << 
363   G4int depth, const G4String& partialPathStri << 
364 {                                              << 
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                                                << 
376       // Previously it was a ghost - but maybe << 
377                                                << 
378       if (partialPathString == fullPathString) << 
379         // Partial path string refers to the a << 
380         childIter->SetType(G4SceneTreeItem::to << 
381         // Populate with information           << 
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                                                   407 
391     } else {                                   << 408 G4VViewer::G4Spline::~G4Spline()
392                                                << 409 {}
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                                                   410 
403   } else {                                     << 411 // Solve the Catmull-Rom parametric equation for a given time(t) and vector quadruple (p1,p2,p3,p4)
404                                                << 412 G4Vector3D G4VViewer::G4Spline::CatmullRom_Eq(float t, const G4Vector3D& p1, const G4Vector3D& p2, const G4Vector3D& p3, const G4Vector3D& p4)
405     // Item does not yet exist                 << 413 {
406                                                << 414     float t2 = t * t;
407     if (partialPathString == fullPathString) { << 415     float t3 = t2 * t;
                                                   >> 416     
                                                   >> 417     float b1 = .5 * (  -t3 + 2*t2 - t);
                                                   >> 418     float b2 = .5 * ( 3*t3 - 5*t2 + 2);
                                                   >> 419     float b3 = .5 * (-3*t3 + 4*t2 + t);
                                                   >> 420     float b4 = .5 * (   t3 -   t2    );
                                                   >> 421     
                                                   >> 422     return (p1*b1 + p2*b2 + p3*b3 + p4*b4);
                                                   >> 423 }
408                                                   424 
409       // Partial path string refers to the act << 425 void G4VViewer::G4Spline::AddSplinePoint(const G4Vector3D& v)
410       // Insert new touchable item             << 426 {
411       G4SceneTreeItem touchable(G4SceneTreeIte << 427     vp.push_back(v);
412       touchable.SetExpanded(depth > fMaximumEx << 428     delta_t = (float)1 / (float)vp.size();
413       touchable.SetDescription(fpPVModel->GetC << 429 }
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                                                   430 
422     } else {                                   << 
423                                                   431 
424       // Partial path string refers to an ance << 432 G4Vector3D G4VViewer::G4Spline::GetPoint(int a)
425       G4SceneTreeItem ghost(G4SceneTreeItem::g << 433 {
426       ghost.SetExpanded(depth > fMaximumExpand << 434     return vp[a];
427       // Create a tag from the partial path    << 435 }
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                                                   436 
442   return childIter;                            << 437 int G4VViewer::G4Spline::GetNumPoints()
                                                   >> 438 {
                                                   >> 439     return vp.size();
443 }                                                 440 }
444 // clang-format on                             << 
445                                                   441 
446 std::ostream& operator<<(std::ostream& os, con << 442 G4Vector3D G4VViewer::G4Spline::GetInterpolatedSplinePoint(float t)
447 {                                                 443 {
448   os << "View " << v.fName << ":\n";           << 444     // Find out in which interval we are on the spline
449   os << v.fVP;                                 << 445     int p = (int)(t / delta_t);
450   return os;                                   << 446     // Compute local control point indices
                                                   >> 447 #define BOUNDS(pp) { if (pp < 0) pp = 0; else if (pp >= (int)vp.size()-1) pp = vp.size() - 1; }
                                                   >> 448     int p0 = p - 1;     BOUNDS(p0);
                                                   >> 449     int p1 = p;         BOUNDS(p1);
                                                   >> 450     int p2 = p + 1;     BOUNDS(p2);
                                                   >> 451     int p3 = p + 2;     BOUNDS(p3);
                                                   >> 452     // Relative (local) time
                                                   >> 453     float lt = (t - delta_t*(float)p) / delta_t;
                                                   >> 454     // Interpolate
                                                   >> 455     return CatmullRom_Eq(lt, vp[p0], vp[p1], vp[p2], vp[p3]);
451 }                                                 456 }
452                                                   457