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.1)


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