Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/management/src/G4ViewParameters.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/G4ViewParameters.cc (Version 11.3.0) and /visualization/management/src/G4ViewParameters.cc (Version 10.7.p3)


  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  19th July 1996                    29 // John Allison  19th July 1996
 30 // View parameters and options.                    30 // View parameters and options.
 31                                                    31 
 32 #include "G4ViewParameters.hh"                     32 #include "G4ViewParameters.hh"
 33                                                    33 
 34 #include "G4VisManager.hh"                         34 #include "G4VisManager.hh"
 35 #include "G4VPhysicalVolume.hh"                    35 #include "G4VPhysicalVolume.hh"
 36 #include "G4UnitsTable.hh"                         36 #include "G4UnitsTable.hh"
 37 #include "G4SystemOfUnits.hh"                      37 #include "G4SystemOfUnits.hh"
 38 #include "G4Polyhedron.hh"                         38 #include "G4Polyhedron.hh"
 39                                                    39 
 40 #include <sstream>                                 40 #include <sstream>
 41 #include <cmath>                                   41 #include <cmath>
 42                                                    42 
 43 #define G4warn G4cout                          << 
 44                                                << 
 45 G4ViewParameters::G4ViewParameters ():             43 G4ViewParameters::G4ViewParameters ():
 46   fDrawingStyle (wireframe),                       44   fDrawingStyle (wireframe),
 47   fNumberOfCloudPoints(10000),                     45   fNumberOfCloudPoints(10000),
 48   fAuxEdgeVisible (false),                         46   fAuxEdgeVisible (false),
 49   fCulling (true),                                 47   fCulling (true),
 50   fCullInvisible (true),                           48   fCullInvisible (true),
 51   fDensityCulling (false),                         49   fDensityCulling (false),
 52   fVisibleDensity (0.01 * g / cm3),                50   fVisibleDensity (0.01 * g / cm3),
 53   fCullCovered (false),                            51   fCullCovered (false),
 54   fCBDAlgorithmNumber (0),                         52   fCBDAlgorithmNumber (0),
 55   fSection (false),                                53   fSection (false),
 56   fSectionPlane (),                                54   fSectionPlane (),
 57   fCutawayMode (cutawayUnion),                     55   fCutawayMode (cutawayUnion),
 58   fCutawayPlanes (),                               56   fCutawayPlanes (),
 59   fExplodeFactor (1.),                             57   fExplodeFactor (1.),
 60   fNoOfSides (),                                   58   fNoOfSides (),
 61   fViewpointDirection (G4Vector3D (0., 0., 1.)     59   fViewpointDirection (G4Vector3D (0., 0., 1.)),  // On z-axis.
 62   fUpVector (G4Vector3D (0., 1., 0.)),             60   fUpVector (G4Vector3D (0., 1., 0.)),            // y-axis up.
 63   fFieldHalfAngle (0.),                            61   fFieldHalfAngle (0.),                           // Orthogonal projection.
 64   fZoomFactor (1.),                                62   fZoomFactor (1.),
 65   fScaleFactor (G4Vector3D (1., 1., 1.)),          63   fScaleFactor (G4Vector3D (1., 1., 1.)),
 66   fCurrentTargetPoint (),                          64   fCurrentTargetPoint (),
 67   fDolly (0.),                                     65   fDolly (0.),
 68   fLightsMoveWithCamera (false),                   66   fLightsMoveWithCamera (false),
 69   fRelativeLightpointDirection (G4Vector3D (1.     67   fRelativeLightpointDirection (G4Vector3D (1., 1., 1.)),
 70   fActualLightpointDirection (G4Vector3D (1.,      68   fActualLightpointDirection (G4Vector3D (1., 1., 1.)),
 71   fDefaultVisAttributes (),                        69   fDefaultVisAttributes (),
 72   fDefaultTextVisAttributes (G4Colour (0., 0.,     70   fDefaultTextVisAttributes (G4Colour (0., 0., 1.)),
 73   fDefaultMarker (),                               71   fDefaultMarker (),
 74   fGlobalMarkerScale (1.),                         72   fGlobalMarkerScale (1.),
 75   fGlobalLineWidthScale (1.),                      73   fGlobalLineWidthScale (1.),
 76   fMarkerNotHidden (true),                         74   fMarkerNotHidden (true),
 77   fWindowSizeHintX (600),                          75   fWindowSizeHintX (600),
 78   fWindowSizeHintY (600),                          76   fWindowSizeHintY (600),
 79   fWindowLocationHintX(0),                         77   fWindowLocationHintX(0),
 80   fWindowLocationHintY(0),                         78   fWindowLocationHintY(0),
 81   fWindowLocationHintXNegative(true),              79   fWindowLocationHintXNegative(true),
 82   fWindowLocationHintYNegative(false),             80   fWindowLocationHintYNegative(false),
 83   fGeometryMask(0),                                81   fGeometryMask(0),
 84   fAutoRefresh (false),                            82   fAutoRefresh (false),
 85   fBackgroundColour (G4Colour(0.,0.,0.)),          83   fBackgroundColour (G4Colour(0.,0.,0.)),         // Black
 86   fPicking (false),                                84   fPicking (false),
 87   fRotationStyle (constrainUpDirection),           85   fRotationStyle (constrainUpDirection),
 88   fStartTime(-G4VisAttributes::fVeryLongTime),     86   fStartTime(-G4VisAttributes::fVeryLongTime),
 89   fEndTime(G4VisAttributes::fVeryLongTime),        87   fEndTime(G4VisAttributes::fVeryLongTime),
 90   fFadeFactor(0.),                                 88   fFadeFactor(0.),
 91   fDisplayHeadTime(false),                         89   fDisplayHeadTime(false),
 92   fDisplayHeadTimeX(-0.9),                         90   fDisplayHeadTimeX(-0.9),
 93   fDisplayHeadTimeY(-0.9),                         91   fDisplayHeadTimeY(-0.9),
 94   fDisplayHeadTimeSize(24.),                       92   fDisplayHeadTimeSize(24.),
 95   fDisplayHeadTimeRed(0.),                         93   fDisplayHeadTimeRed(0.),
 96   fDisplayHeadTimeGreen(1.),                       94   fDisplayHeadTimeGreen(1.),
 97   fDisplayHeadTimeBlue(1.),                        95   fDisplayHeadTimeBlue(1.),
 98   fDisplayLightFront(false),                       96   fDisplayLightFront(false),
 99   fDisplayLightFrontX(0.),                         97   fDisplayLightFrontX(0.),
100   fDisplayLightFrontY(0.),                         98   fDisplayLightFrontY(0.),
101   fDisplayLightFrontZ(0.),                         99   fDisplayLightFrontZ(0.),
102   fDisplayLightFrontT(0.),                        100   fDisplayLightFrontT(0.),
103   fDisplayLightFrontRed(0.),                      101   fDisplayLightFrontRed(0.),
104   fDisplayLightFrontGreen(1.),                    102   fDisplayLightFrontGreen(1.),
105   fDisplayLightFrontBlue(0.),                  << 103   fDisplayLightFrontBlue(0.)
106   fSpecialMeshRendering(false),                << 
107   fSpecialMeshRenderingOption(meshAsDefault)   << 
108 {                                                 104 {
109   // Pick up default no of sides from G4Polyhe    105   // Pick up default no of sides from G4Polyhedron.
110   // Note that this parameter is variously cal    106   // Note that this parameter is variously called:
111   //   No of sides                                107   //   No of sides
112   //   NumberOfRotationSteps                      108   //   NumberOfRotationSteps
113   //   Line segments per circle                   109   //   Line segments per circle
114   // It refers to the approximation of a circl    110   // It refers to the approximation of a circle by a polygon of
115   // stated number of sides.                      111   // stated number of sides.
116   fNoOfSides = G4Polyhedron::GetNumberOfRotati    112   fNoOfSides = G4Polyhedron::GetNumberOfRotationSteps();
117                                                   113   
118   fDefaultMarker.SetScreenSize (5.);              114   fDefaultMarker.SetScreenSize (5.);
119   // Markers are 5 pixels "overall" size, i.e.    115   // Markers are 5 pixels "overall" size, i.e., diameter.
120 }                                                 116 }
121                                                   117 
122 G4ViewParameters::~G4ViewParameters () {}         118 G4ViewParameters::~G4ViewParameters () {}
123                                                   119 
124 void G4ViewParameters::MultiplyScaleFactor        120 void G4ViewParameters::MultiplyScaleFactor
125 (const G4Vector3D& scaleFactorMultiplier) {       121 (const G4Vector3D& scaleFactorMultiplier) {
126   fScaleFactor.setX(fScaleFactor.x() * scaleFa    122   fScaleFactor.setX(fScaleFactor.x() * scaleFactorMultiplier.x());
127   fScaleFactor.setY(fScaleFactor.y() * scaleFa    123   fScaleFactor.setY(fScaleFactor.y() * scaleFactorMultiplier.y());
128   fScaleFactor.setZ(fScaleFactor.z() * scaleFa    124   fScaleFactor.setZ(fScaleFactor.z() * scaleFactorMultiplier.z());
129 }                                                 125 }
130                                                   126 
131 G4Vector3D& G4ViewParameters::GetActualLightpo    127 G4Vector3D& G4ViewParameters::GetActualLightpointDirection () {
132   SetViewAndLights (fViewpointDirection);         128   SetViewAndLights (fViewpointDirection);
133   return fActualLightpointDirection;              129   return fActualLightpointDirection;
134 }                                                 130 }
135                                                   131 
136 // Useful quantities - begin snippet.             132 // Useful quantities - begin snippet.
137 // Here Follow functions to evaluate the above    133 // Here Follow functions to evaluate the above algorithms as a
138 // function of the radius of the Bounding Sphe    134 // function of the radius of the Bounding Sphere of the object being
139 // viewed.  Call them in the order given - for    135 // viewed.  Call them in the order given - for efficiency, later
140 // functions depend on the results of earlier     136 // functions depend on the results of earlier ones (Store the
141 // results of earlier functions in your own te    137 // results of earlier functions in your own temporary variables -
142 // see, for example, G4OpenGLView::SetView ().    138 // see, for example, G4OpenGLView::SetView ().)
143                                                   139 
144 G4double G4ViewParameters::GetCameraDistance (    140 G4double G4ViewParameters::GetCameraDistance (G4double radius) const {
145   G4double cameraDistance;                        141   G4double cameraDistance;
146   if (fFieldHalfAngle == 0.) {                    142   if (fFieldHalfAngle == 0.) {
147     cameraDistance = radius;                      143     cameraDistance = radius;
148   }                                               144   }
149   else {                                          145   else {
150     cameraDistance = radius / std::sin (fField    146     cameraDistance = radius / std::sin (fFieldHalfAngle) - fDolly;
151   }                                               147   }
152   return cameraDistance;                          148   return cameraDistance;
153 }                                                 149 }
154                                                   150 
155 G4double G4ViewParameters::GetNearDistance (G4    151 G4double G4ViewParameters::GetNearDistance (G4double cameraDistance,
156               G4double radius) const {            152               G4double radius) const {
157   const G4double small = 1.e-6 * radius;          153   const G4double small = 1.e-6 * radius;
158   G4double nearDistance = cameraDistance - rad    154   G4double nearDistance = cameraDistance - radius;
159   if (nearDistance < small) nearDistance = sma    155   if (nearDistance < small) nearDistance = small;
160   return nearDistance;                            156   return nearDistance;
161 }                                                 157 }
162                                                   158 
163 G4double G4ViewParameters::GetFarDistance (G4d    159 G4double G4ViewParameters::GetFarDistance (G4double cameraDistance,
164              G4double nearDistance,               160              G4double nearDistance,
165              G4double radius) const {             161              G4double radius) const {
166   G4double farDistance = cameraDistance + radi    162   G4double farDistance = cameraDistance + radius;
167   if (farDistance < nearDistance) farDistance     163   if (farDistance < nearDistance) farDistance = nearDistance;
168   return farDistance;                             164   return farDistance;
169 }                                                 165 }
170                                                   166 
171 G4double G4ViewParameters::GetFrontHalfHeight     167 G4double G4ViewParameters::GetFrontHalfHeight (G4double nearDistance,
172                  G4double radius) const {         168                  G4double radius) const {
173   G4double frontHalfHeight;                       169   G4double frontHalfHeight;
174   if (fFieldHalfAngle == 0.) {                    170   if (fFieldHalfAngle == 0.) {
175     frontHalfHeight = radius / fZoomFactor;       171     frontHalfHeight = radius / fZoomFactor;
176   }                                               172   }
177   else {                                          173   else {
178     frontHalfHeight = nearDistance * std::tan     174     frontHalfHeight = nearDistance * std::tan (fFieldHalfAngle) / fZoomFactor;
179   }                                               175   }
180   return frontHalfHeight;                         176   return frontHalfHeight;
181 }                                                 177 }
182 // Useful quantities - end snippet.               178 // Useful quantities - end snippet.
183                                                   179 
184 void G4ViewParameters::AddCutawayPlane (const     180 void G4ViewParameters::AddCutawayPlane (const G4Plane3D& cutawayPlane) {
185   if (fCutawayPlanes.size () < 3 ) {              181   if (fCutawayPlanes.size () < 3 ) {
186     fCutawayPlanes.push_back (cutawayPlane);      182     fCutawayPlanes.push_back (cutawayPlane);
187   }                                               183   }
188   else {                                          184   else {
189     G4warn <<                                  << 185     G4cerr <<
190       "ERROR: G4ViewParameters::AddCutawayPlan    186       "ERROR: G4ViewParameters::AddCutawayPlane:"
191       "\n  A maximum of 3 cutaway planes suppo    187       "\n  A maximum of 3 cutaway planes supported." << G4endl;
192   }                                               188   }
193 }                                                 189 }
194                                                   190 
195 void G4ViewParameters::ChangeCutawayPlane         191 void G4ViewParameters::ChangeCutawayPlane
196 (size_t index, const G4Plane3D& cutawayPlane)     192 (size_t index, const G4Plane3D& cutawayPlane) {
197   if (index >= fCutawayPlanes.size()) {           193   if (index >= fCutawayPlanes.size()) {
198     G4warn <<                                  << 194     G4cerr <<
199       "ERROR: G4ViewParameters::ChangeCutawayP    195       "ERROR: G4ViewParameters::ChangeCutawayPlane:"
200       "\n  Plane " << index << " does not exis    196       "\n  Plane " << index << " does not exist." << G4endl;
201   } else {                                        197   } else {
202     fCutawayPlanes[index] = cutawayPlane;         198     fCutawayPlanes[index] = cutawayPlane;
203   }                                               199   }
204 }                                                 200 }
205                                                   201 
206 void G4ViewParameters::SetVisibleDensity (G4do    202 void G4ViewParameters::SetVisibleDensity (G4double visibleDensity) {
207   const G4double reasonableMaximum = 10.0 * g     203   const G4double reasonableMaximum = 10.0 * g / cm3;
208   if (visibleDensity < 0) {                       204   if (visibleDensity < 0) {
209     G4warn << "G4ViewParameters::SetVisibleDen << 205     G4cout << "G4ViewParameters::SetVisibleDensity: attempt to set negative "
210       "density - ignored." << G4endl;             206       "density - ignored." << G4endl;
211   }                                               207   }
212   else {                                          208   else {
213     if (visibleDensity > reasonableMaximum) {     209     if (visibleDensity > reasonableMaximum) {
214       G4warn << "G4ViewParameters::SetVisibleD << 210       G4cout << "G4ViewParameters::SetVisibleDensity: density > "
215        << G4BestUnit (reasonableMaximum, "Volu    211        << G4BestUnit (reasonableMaximum, "Volumic Mass")
216        << " - did you mean this?"                 212        << " - did you mean this?"
217        << G4endl;                                 213        << G4endl;
218     }                                             214     }
219     fVisibleDensity = visibleDensity;             215     fVisibleDensity = visibleDensity;
220   }                                               216   }
221 }                                                 217 }
222                                                   218 
223 G4int G4ViewParameters::SetNoOfSides (G4int nS    219 G4int G4ViewParameters::SetNoOfSides (G4int nSides) {
224   const G4int nSidesMin = fDefaultVisAttribute    220   const G4int nSidesMin = fDefaultVisAttributes.GetMinLineSegmentsPerCircle();
225   if (nSides < nSidesMin) {                       221   if (nSides < nSidesMin) {
226     nSides = nSidesMin;                           222     nSides = nSidesMin;
227     G4warn << "G4ViewParameters::SetNoOfSides: << 223     G4cout << "G4ViewParameters::SetNoOfSides: attempt to set the"
228     "\nnumber of sides per circle < " << nSide    224     "\nnumber of sides per circle < " << nSidesMin
229     << "; forced to " << nSides << G4endl;        225     << "; forced to " << nSides << G4endl;
230   }                                               226   }
231   fNoOfSides = nSides;                            227   fNoOfSides = nSides;
232   return fNoOfSides;                              228   return fNoOfSides;
233 }                                                 229 }
234                                                   230 
235 G4int G4ViewParameters::SetNumberOfCloudPoints    231 G4int G4ViewParameters::SetNumberOfCloudPoints(G4int nPoints) {
236   const G4int nPointsMin = 100;                   232   const G4int nPointsMin = 100;
237   if (nPoints < nPointsMin) {                     233   if (nPoints < nPointsMin) {
238     nPoints = nPointsMin;                         234     nPoints = nPointsMin;
239     G4warn << "G4ViewParameters::SetNumberOfCl << 235     G4cout << "G4ViewParameters::SetNumberOfCloudPoints:"
240     "\nnumber of points per cloud set to minim    236     "\nnumber of points per cloud set to minimum " << nPoints
241     << G4endl;                                    237     << G4endl;
242   }                                               238   }
243   fNumberOfCloudPoints = nPoints;                 239   fNumberOfCloudPoints = nPoints;
244   return fNumberOfCloudPoints;                    240   return fNumberOfCloudPoints;
245 }                                                 241 }
246                                                   242 
247 void G4ViewParameters::SetViewAndLights           243 void G4ViewParameters::SetViewAndLights
248 (const G4Vector3D& viewpointDirection) {          244 (const G4Vector3D& viewpointDirection) {
249                                                   245 
250   fViewpointDirection = viewpointDirection;       246   fViewpointDirection = viewpointDirection;
251                                                   247 
252   // If the requested viewpoint direction is p    248   // If the requested viewpoint direction is parallel to the up
253   // vector, the orientation of the view is un    249   // vector, the orientation of the view is undefined...
254   if (fViewpointDirection.unit() * fUpVector.u    250   if (fViewpointDirection.unit() * fUpVector.unit() > .9999) {
255     static G4bool firstTime = true;               251     static G4bool firstTime = true;
256     if (firstTime) {                              252     if (firstTime) {
257       firstTime = false;                          253       firstTime = false;
258       G4warn <<                                << 254       G4cout <<
259       "WARNING: Viewpoint direction is very cl    255       "WARNING: Viewpoint direction is very close to the up vector direction."
260       "\n  Change the up vector or \"/vis/view    256       "\n  Change the up vector or \"/vis/viewer/set/rotationStyle freeRotation\"."
261       << G4endl;                                  257       << G4endl;
262     }                                             258     }
263   }                                               259   }
264                                                   260 
265   // Move the lights too if requested...          261   // Move the lights too if requested...
266   if (fLightsMoveWithCamera) {                    262   if (fLightsMoveWithCamera) {
267     G4Vector3D zprime = fViewpointDirection.un    263     G4Vector3D zprime = fViewpointDirection.unit ();
268     G4Vector3D xprime = (fUpVector.cross (zpri    264     G4Vector3D xprime = (fUpVector.cross (zprime)).unit ();
269     G4Vector3D yprime = zprime.cross (xprime);    265     G4Vector3D yprime = zprime.cross (xprime);
270     fActualLightpointDirection =                  266     fActualLightpointDirection =
271       fRelativeLightpointDirection.x () * xpri    267       fRelativeLightpointDirection.x () * xprime +
272       fRelativeLightpointDirection.y () * ypri    268       fRelativeLightpointDirection.y () * yprime +
273       fRelativeLightpointDirection.x () * zpri    269       fRelativeLightpointDirection.x () * zprime;     
274   } else {                                        270   } else {
275     fActualLightpointDirection = fRelativeLigh    271     fActualLightpointDirection = fRelativeLightpointDirection;
276   }                                               272   }
277 }                                                 273 }
278                                                   274 
279 void G4ViewParameters::SetLightpointDirection     275 void G4ViewParameters::SetLightpointDirection
280 (const G4Vector3D& lightpointDirection) {         276 (const G4Vector3D& lightpointDirection) {
281   fRelativeLightpointDirection = lightpointDir    277   fRelativeLightpointDirection = lightpointDirection;
282   SetViewAndLights (fViewpointDirection);         278   SetViewAndLights (fViewpointDirection);
283 }                                                 279 }
284                                                   280 
285 void G4ViewParameters::SetPan (G4double right,    281 void G4ViewParameters::SetPan (G4double right, G4double up) {
286   G4Vector3D unitRight = (fUpVector.cross (fVi    282   G4Vector3D unitRight = (fUpVector.cross (fViewpointDirection)).unit();
287   G4Vector3D unitUp    = (fViewpointDirection.    283   G4Vector3D unitUp    = (fViewpointDirection.cross (unitRight)).unit();
288   fCurrentTargetPoint  = right * unitRight + u    284   fCurrentTargetPoint  = right * unitRight + up * unitUp;
289 }                                                 285 }
290                                                   286 
291 void G4ViewParameters::IncrementPan (G4double     287 void G4ViewParameters::IncrementPan (G4double right, G4double up) {
292   IncrementPan (right,up, 0);                     288   IncrementPan (right,up, 0);
293 }                                                 289 }
294                                                   290 
295 void G4ViewParameters::IncrementPan (G4double     291 void G4ViewParameters::IncrementPan (G4double right, G4double up, G4double distance) {
296   G4Vector3D unitRight = (fUpVector.cross (fVi    292   G4Vector3D unitRight = (fUpVector.cross (fViewpointDirection)).unit();
297   G4Vector3D unitUp    = (fViewpointDirection.    293   G4Vector3D unitUp    = (fViewpointDirection.cross (unitRight)).unit();
298   fCurrentTargetPoint += right * unitRight + u    294   fCurrentTargetPoint += right * unitRight + up * unitUp + distance * fViewpointDirection;
299 }                                                 295 }
300                                                   296 
301 void G4ViewParameters::AddVisAttributesModifie    297 void G4ViewParameters::AddVisAttributesModifier
302 (const G4ModelingParameters::VisAttributesModi    298 (const G4ModelingParameters::VisAttributesModifier& vam) {
303   // If target exists with same signifier just    299   // If target exists with same signifier just change vis attributes.
304   G4bool duplicateTarget = false;                 300   G4bool duplicateTarget = false;
305   auto i = fVisAttributesModifiers.begin();       301   auto i = fVisAttributesModifiers.begin();
306   for (; i < fVisAttributesModifiers.end(); ++    302   for (; i < fVisAttributesModifiers.end(); ++i) {
307     if (vam.GetPVNameCopyNoPath() == (*i).GetP    303     if (vam.GetPVNameCopyNoPath() == (*i).GetPVNameCopyNoPath() &&
308         vam.GetVisAttributesSignifier() == (*i    304         vam.GetVisAttributesSignifier() == (*i).GetVisAttributesSignifier()) {
309       duplicateTarget = true;                     305       duplicateTarget = true;
310       break;                                      306       break;
311     }                                             307     }
312   }                                               308   }
313   if (duplicateTarget) (*i).SetVisAttributes(v    309   if (duplicateTarget) (*i).SetVisAttributes(vam.GetVisAttributes());
314   else fVisAttributesModifiers.push_back(vam);    310   else fVisAttributesModifiers.push_back(vam);
315 }                                                 311 }
316                                                   312 
317 G4String G4ViewParameters::CameraAndLightingCo    313 G4String G4ViewParameters::CameraAndLightingCommands
318 (const G4Point3D standardTargetPoint) const       314 (const G4Point3D standardTargetPoint) const
319 {                                                 315 {
320   std::ostringstream oss;                         316   std::ostringstream oss;
321                                                   317 
322   oss << "#\n# Camera and lights commands";       318   oss << "#\n# Camera and lights commands";
323                                                   319   
324   oss << "\n/vis/viewer/set/viewpointVector "     320   oss << "\n/vis/viewer/set/viewpointVector "
325   << fViewpointDirection.x()                      321   << fViewpointDirection.x()
326   << ' ' << fViewpointDirection.y()               322   << ' ' << fViewpointDirection.y()
327   << ' ' << fViewpointDirection.z();              323   << ' ' << fViewpointDirection.z();
328                                                   324   
329   oss << "\n/vis/viewer/set/upVector "            325   oss << "\n/vis/viewer/set/upVector "
330   << fUpVector.x()                                326   << fUpVector.x()
331   << ' ' << fUpVector.y()                         327   << ' ' << fUpVector.y()
332   << ' ' << fUpVector.z();                        328   << ' ' << fUpVector.z();
333                                                   329   
334   oss << "\n/vis/viewer/set/projection ";         330   oss << "\n/vis/viewer/set/projection ";
335     if (fFieldHalfAngle == 0.) {                  331     if (fFieldHalfAngle == 0.) {
336     oss                                           332     oss
337     << "orthogonal";                              333     << "orthogonal";
338   } else {                                        334   } else {
339     oss                                           335     oss
340     << "perspective "                             336     << "perspective "
341     << fFieldHalfAngle/deg                        337     << fFieldHalfAngle/deg
342     << " deg";                                    338     << " deg";
343   }                                               339   }
344                                                   340   
345   oss << "\n/vis/viewer/zoomTo "                  341   oss << "\n/vis/viewer/zoomTo "
346   << fZoomFactor;                                 342   << fZoomFactor;
347                                                   343   
348   oss << "\n/vis/viewer/scaleTo "                 344   oss << "\n/vis/viewer/scaleTo "
349   << fScaleFactor.x()                             345   << fScaleFactor.x()
350   << ' ' << fScaleFactor.y()                      346   << ' ' << fScaleFactor.y()
351   << ' ' << fScaleFactor.z();                     347   << ' ' << fScaleFactor.z();
352                                                   348   
353   oss << "\n/vis/viewer/set/targetPoint "         349   oss << "\n/vis/viewer/set/targetPoint "
354   << G4BestUnit(standardTargetPoint+fCurrentTa    350   << G4BestUnit(standardTargetPoint+fCurrentTargetPoint,"Length")
355   << "\n# Note that if you have not set a targ    351   << "\n# Note that if you have not set a target point, the vis system sets"
356   << "\n# a target point based on the scene -     352   << "\n# a target point based on the scene - plus any panning and dollying -"
357   << "\n# so don't be alarmed by strange coord    353   << "\n# so don't be alarmed by strange coordinates here.";
358                                                   354   
359   oss << "\n/vis/viewer/dollyTo "                 355   oss << "\n/vis/viewer/dollyTo "
360   << G4BestUnit(fDolly,"Length");                 356   << G4BestUnit(fDolly,"Length");
361                                                   357   
362   oss << "\n/vis/viewer/set/lightsMove ";         358   oss << "\n/vis/viewer/set/lightsMove ";
363   if (fLightsMoveWithCamera) {                    359   if (fLightsMoveWithCamera) {
364     oss << "camera";                              360     oss << "camera";
365   } else {                                        361   } else {
366     oss << "object";                              362     oss << "object";
367   }                                               363   }
368                                                   364   
369   oss << "\n/vis/viewer/set/lightsVector "        365   oss << "\n/vis/viewer/set/lightsVector "
370   << fRelativeLightpointDirection.x()             366   << fRelativeLightpointDirection.x()
371   << ' ' << fRelativeLightpointDirection.y()      367   << ' ' << fRelativeLightpointDirection.y()
372   << ' ' << fRelativeLightpointDirection.z();     368   << ' ' << fRelativeLightpointDirection.z();
373                                                   369   
374   oss << "\n/vis/viewer/set/rotationStyle ";      370   oss << "\n/vis/viewer/set/rotationStyle ";
375   if (fRotationStyle == constrainUpDirection)     371   if (fRotationStyle == constrainUpDirection) {
376     oss << "constrainUpDirection";                372     oss << "constrainUpDirection";
377   } else {                                        373   } else {
378     oss << "freeRotation";                        374     oss << "freeRotation";
379   }                                               375   }
380                                                   376   
381   G4Colour c = fBackgroundColour;                 377   G4Colour c = fBackgroundColour;
382   oss << "\n/vis/viewer/set/background "          378   oss << "\n/vis/viewer/set/background "
383   << c.GetRed()                                   379   << c.GetRed()
384   << ' ' << c.GetGreen()                          380   << ' ' << c.GetGreen()
385   << ' ' << c.GetBlue()                           381   << ' ' << c.GetBlue()
386   << ' ' << c.GetAlpha();                         382   << ' ' << c.GetAlpha();
387                                                   383   
388   c = fDefaultVisAttributes.GetColour();          384   c = fDefaultVisAttributes.GetColour();
389   oss << "\n/vis/viewer/set/defaultColour "       385   oss << "\n/vis/viewer/set/defaultColour "
390   << c.GetRed()                                   386   << c.GetRed()
391   << ' ' << c.GetGreen()                          387   << ' ' << c.GetGreen()
392   << ' ' << c.GetBlue()                           388   << ' ' << c.GetBlue()
393   << ' ' << c.GetAlpha();                         389   << ' ' << c.GetAlpha();
394                                                   390   
395   c = fDefaultTextVisAttributes.GetColour();      391   c = fDefaultTextVisAttributes.GetColour();
396   oss << "\n/vis/viewer/set/defaultTextColour     392   oss << "\n/vis/viewer/set/defaultTextColour "
397   << c.GetRed()                                   393   << c.GetRed()
398   << ' ' << c.GetGreen()                          394   << ' ' << c.GetGreen()
399   << ' ' << c.GetBlue()                           395   << ' ' << c.GetBlue()
400   << ' ' << c.GetAlpha();                         396   << ' ' << c.GetAlpha();
401                                                   397   
402   oss << std::endl;                               398   oss << std::endl;
403                                                   399   
404   return oss.str();                               400   return oss.str();
405 }                                                 401 }
406                                                   402 
407 G4String G4ViewParameters::DrawingStyleCommand    403 G4String G4ViewParameters::DrawingStyleCommands() const
408 {                                                 404 {
409   std::ostringstream oss;                         405   std::ostringstream oss;
410                                                   406   
411   oss << "#\n# Drawing style commands";           407   oss << "#\n# Drawing style commands";
412                                                   408   
413   oss << "\n/vis/viewer/set/style ";              409   oss << "\n/vis/viewer/set/style ";
414   switch (fDrawingStyle) {                        410   switch (fDrawingStyle) {
415     case wireframe:                               411     case wireframe:
416     case hlr:                                     412     case hlr:
417       oss << "wireframe";                         413       oss << "wireframe";
418       break;                                      414       break;
419     case hsr:                                     415     case hsr:
420     case hlhsr:                                   416     case hlhsr:
421       oss << "surface";                           417       oss << "surface";
422       break;                                      418       break;
423     case cloud:                                   419     case cloud:
424       oss << "cloud";                             420       oss << "cloud";
425       break;                                      421       break;
426   }                                               422   }
427                                                   423 
428   oss << "\n/vis/viewer/set/hiddenEdge ";         424   oss << "\n/vis/viewer/set/hiddenEdge ";
429   if (fDrawingStyle == hlr || fDrawingStyle ==    425   if (fDrawingStyle == hlr || fDrawingStyle == hlhsr) {
430     oss << "true";                                426     oss << "true";
431   } else {                                        427   } else {
432     oss << "false";                               428     oss << "false";
433   }                                               429   }
434                                                   430   
435   oss << "\n/vis/viewer/set/auxiliaryEdge ";      431   oss << "\n/vis/viewer/set/auxiliaryEdge ";
436   if (fAuxEdgeVisible) {                          432   if (fAuxEdgeVisible) {
437     oss << "true";                                433     oss << "true";
438   } else {                                        434   } else {
439     oss << "false";                               435     oss << "false";
440   }                                               436   }
441                                                   437   
442   oss << "\n/vis/viewer/set/hiddenMarker ";       438   oss << "\n/vis/viewer/set/hiddenMarker ";
443   if (fMarkerNotHidden) {                         439   if (fMarkerNotHidden) {
444     oss << "false";                               440     oss << "false";
445   } else {                                        441   } else {
446     oss << "true";                                442     oss << "true";
447   }                                               443   }
448                                                   444   
449   oss << "\n/vis/viewer/set/globalLineWidthSca    445   oss << "\n/vis/viewer/set/globalLineWidthScale "
450   << fGlobalLineWidthScale;                       446   << fGlobalLineWidthScale;
451                                                   447   
452   oss << "\n/vis/viewer/set/globalMarkerScale     448   oss << "\n/vis/viewer/set/globalMarkerScale "
453   << fGlobalMarkerScale;                          449   << fGlobalMarkerScale;
454                                                   450 
455   oss << "\n/vis/viewer/set/numberOfCloudPoint    451   oss << "\n/vis/viewer/set/numberOfCloudPoints "
456   << fNumberOfCloudPoints;                        452   << fNumberOfCloudPoints;
457                                                   453 
458   oss << "\n/vis/viewer/set/specialMeshRenderi << 
459   if (fSpecialMeshRendering) {                 << 
460     oss << "true";                             << 
461   } else {                                     << 
462     oss << "false";                            << 
463   }                                            << 
464                                                << 
465   oss << "\n/vis/viewer/set/specialMeshRenderi << 
466   << fSpecialMeshRenderingOption;              << 
467                                                << 
468   oss << "\n/vis/viewer/set/specialMeshVolumes << 
469   for (const auto& volume : fSpecialMeshVolume << 
470     oss << ' ' << volume.GetName() << ' ' << v << 
471   }                                            << 
472                                                << 
473   oss << std::endl;                               454   oss << std::endl;
474                                                   455   
475   return oss.str();                               456   return oss.str();
476 }                                                 457 }
477                                                   458 
478 G4String G4ViewParameters::SceneModifyingComma    459 G4String G4ViewParameters::SceneModifyingCommands() const
479 {                                                 460 {
480   std::ostringstream oss;                         461   std::ostringstream oss;
481                                                   462   
482   oss << "#\n# Scene-modifying commands";         463   oss << "#\n# Scene-modifying commands";
483                                                   464   
484   oss << "\n/vis/viewer/set/culling global ";     465   oss << "\n/vis/viewer/set/culling global ";
485   if (fCulling) {                                 466   if (fCulling) {
486     oss << "true";                                467     oss << "true";
487   } else {                                        468   } else {
488     oss << "false";                               469     oss << "false";
489   }                                               470   }
490                                                   471 
491   oss << "\n/vis/viewer/set/culling invisible     472   oss << "\n/vis/viewer/set/culling invisible ";
492   if (fCullInvisible) {                           473   if (fCullInvisible) {
493     oss << "true";                                474     oss << "true";
494   } else {                                        475   } else {
495     oss << "false";                               476     oss << "false";
496   }                                               477   }
497                                                   478   
498   oss << "\n/vis/viewer/set/culling density ";    479   oss << "\n/vis/viewer/set/culling density ";
499   if (fDensityCulling) {                          480   if (fDensityCulling) {
500     oss << "true " << fVisibleDensity/(g/cm3)     481     oss << "true " << fVisibleDensity/(g/cm3) << " g/cm3";
501   } else {                                        482   } else {
502     oss << "false";                               483     oss << "false";
503   }                                               484   }
504                                                   485   
505   oss << "\n/vis/viewer/set/culling coveredDau    486   oss << "\n/vis/viewer/set/culling coveredDaughters ";
506   if (fCullCovered) {                             487   if (fCullCovered) {
507     oss << "true";                                488     oss << "true";
508   } else {                                        489   } else {
509     oss << "false";                               490     oss << "false";
510   }                                               491   }
511                                                   492 
512   oss << "\n/vis/viewer/colourByDensity "         493   oss << "\n/vis/viewer/colourByDensity "
513   << fCBDAlgorithmNumber << " g/cm3";             494   << fCBDAlgorithmNumber << " g/cm3";
514   for (auto p: fCBDParameters) {                  495   for (auto p: fCBDParameters) {
515     oss << ' ' << p/(g/cm3);                      496     oss << ' ' << p/(g/cm3);
516   }                                               497   }
517                                                   498 
518   oss << "\n/vis/viewer/set/sectionPlane ";       499   oss << "\n/vis/viewer/set/sectionPlane ";
519   if (fSection) {                                 500   if (fSection) {
520     oss << "on "                                  501     oss << "on "
521     << G4BestUnit(fSectionPlane.point(),"Lengt    502     << G4BestUnit(fSectionPlane.point(),"Length")
522     << fSectionPlane.normal().x()                 503     << fSectionPlane.normal().x()
523     << ' ' << fSectionPlane.normal().y()          504     << ' ' << fSectionPlane.normal().y()
524     << ' ' << fSectionPlane.normal().z();         505     << ' ' << fSectionPlane.normal().z();
525   } else {                                        506   } else {
526     oss << "off";                                 507     oss << "off";
527   }                                               508   }
528                                                   509   
529   oss << "\n/vis/viewer/set/cutawayMode ";        510   oss << "\n/vis/viewer/set/cutawayMode ";
530   if (fCutawayMode == cutawayUnion) {             511   if (fCutawayMode == cutawayUnion) {
531     oss << "union";                               512     oss << "union";
532   } else {                                        513   } else {
533     oss << "intersection";                        514     oss << "intersection";
534   }                                               515   }
535                                                   516   
536   oss << "\n/vis/viewer/clearCutawayPlanes";      517   oss << "\n/vis/viewer/clearCutawayPlanes";
537   if (fCutawayPlanes.size()) {                    518   if (fCutawayPlanes.size()) {
538     for (size_t i = 0; i < fCutawayPlanes.size    519     for (size_t i = 0; i < fCutawayPlanes.size(); i++) {
539       oss << "\n/vis/viewer/addCutawayPlane "     520       oss << "\n/vis/viewer/addCutawayPlane "
540       << G4BestUnit(fCutawayPlanes[i].point(),    521       << G4BestUnit(fCutawayPlanes[i].point(),"Length")
541       << fCutawayPlanes[i].normal().x()           522       << fCutawayPlanes[i].normal().x()
542       << ' ' << fCutawayPlanes[i].normal().y()    523       << ' ' << fCutawayPlanes[i].normal().y()
543       << ' ' << fCutawayPlanes[i].normal().z()    524       << ' ' << fCutawayPlanes[i].normal().z();
544     }                                             525     }
545   } else {                                        526   } else {
546     oss << "\n# No cutaway planes defined.";      527     oss << "\n# No cutaway planes defined.";
547   }                                               528   }
548                                                   529   
549   oss << "\n/vis/viewer/set/explodeFactor "       530   oss << "\n/vis/viewer/set/explodeFactor "
550   << fExplodeFactor                               531   << fExplodeFactor
551   << ' ' << G4BestUnit(fExplodeCentre,"Length"    532   << ' ' << G4BestUnit(fExplodeCentre,"Length");
552                                                   533   
553   oss << "\n/vis/viewer/set/lineSegmentsPerCir    534   oss << "\n/vis/viewer/set/lineSegmentsPerCircle "
554   << fNoOfSides;                                  535   << fNoOfSides;
555                                                   536   
556   oss << std::endl;                               537   oss << std::endl;
557                                                   538   
558   return oss.str();                               539   return oss.str();
559 }                                                 540 }
560                                                   541 
561 G4String G4ViewParameters::TouchableCommands()    542 G4String G4ViewParameters::TouchableCommands() const
562 {                                                 543 {
563   std::ostringstream oss;                         544   std::ostringstream oss;
564                                                   545   
565   oss << "#\n# Touchable commands";               546   oss << "#\n# Touchable commands";
566                                                   547 
567   const std::vector<G4ModelingParameters::VisA    548   const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
568     fVisAttributesModifiers;                      549     fVisAttributesModifiers;
569                                                   550 
570   if (vams.empty()) {                             551   if (vams.empty()) {
571     oss                                           552     oss
572     << "\n# None"                                 553     << "\n# None"
573     << "\n/vis/viewer/clearVisAttributesModifi    554     << "\n/vis/viewer/clearVisAttributesModifiers";
574     oss << std::endl;                             555     oss << std::endl;
575     return oss.str();                             556     return oss.str();
576   }                                               557   }
577                                                   558 
578   oss                                             559   oss
579   << "\n/vis/viewer/clearVisAttributesModifier    560   << "\n/vis/viewer/clearVisAttributesModifiers";
580                                                   561 
581   G4ModelingParameters::PVNameCopyNoPath lastP    562   G4ModelingParameters::PVNameCopyNoPath lastPath;
582   std::vector<G4ModelingParameters::VisAttribu    563   std::vector<G4ModelingParameters::VisAttributesModifier>::const_iterator
583     iModifier;                                    564     iModifier;
584   for (iModifier = vams.begin();                  565   for (iModifier = vams.begin();
585        iModifier != vams.end();                   566        iModifier != vams.end();
586        ++iModifier) {                             567        ++iModifier) {
587     const G4ModelingParameters::PVNameCopyNoPa    568     const G4ModelingParameters::PVNameCopyNoPath& vamPath =
588       iModifier->GetPVNameCopyNoPath();           569       iModifier->GetPVNameCopyNoPath();
589     if (vamPath != lastPath) {                    570     if (vamPath != lastPath) {
590       lastPath = vamPath;                         571       lastPath = vamPath;
591       oss << "\n/vis/set/touchable";              572       oss << "\n/vis/set/touchable";
592       G4ModelingParameters::PVNameCopyNoPathCo    573       G4ModelingParameters::PVNameCopyNoPathConstIterator iVAM;
593       for (iVAM = vamPath.begin();                574       for (iVAM = vamPath.begin();
594            iVAM != vamPath.end();                 575            iVAM != vamPath.end();
595            ++iVAM) {                              576            ++iVAM) {
596         oss << ' ' << iVAM->GetName() << ' ' <    577         oss << ' ' << iVAM->GetName() << ' ' << iVAM->GetCopyNo();
597       }                                           578       }
598     }                                             579     }
599     const G4VisAttributes& vamVisAtts = iModif    580     const G4VisAttributes& vamVisAtts = iModifier->GetVisAttributes();
600     const G4Colour& c = vamVisAtts.GetColour()    581     const G4Colour& c = vamVisAtts.GetColour();
601     switch (iModifier->GetVisAttributesSignifi    582     switch (iModifier->GetVisAttributesSignifier()) {
602       case G4ModelingParameters::VASVisibility    583       case G4ModelingParameters::VASVisibility:
603         oss << "\n/vis/touchable/set/visibilit    584         oss << "\n/vis/touchable/set/visibility ";
604         if (vamVisAtts.IsVisible()) {             585         if (vamVisAtts.IsVisible()) {
605           oss << "true";                          586           oss << "true";
606         } else {                                  587         } else {
607           oss << "false";                         588           oss << "false";
608         }                                         589         }
609         break;                                    590         break;
610       case G4ModelingParameters::VASDaughtersI    591       case G4ModelingParameters::VASDaughtersInvisible:
611         oss << "\n/vis/touchable/set/daughters    592         oss << "\n/vis/touchable/set/daughtersInvisible ";
612         if (vamVisAtts.IsDaughtersInvisible())    593         if (vamVisAtts.IsDaughtersInvisible()) {
613           oss << "true";                          594           oss << "true";
614         } else {                                  595         } else {
615           oss << "false";                         596           oss << "false";
616         }                                         597         }
617         break;                                    598         break;
618       case G4ModelingParameters::VASColour:       599       case G4ModelingParameters::VASColour:
619         oss << "\n/vis/touchable/set/colour "     600         oss << "\n/vis/touchable/set/colour "
620         << c.GetRed()                             601         << c.GetRed()
621         << ' ' << c.GetGreen()                    602         << ' ' << c.GetGreen()
622         << ' ' << c.GetBlue()                     603         << ' ' << c.GetBlue()
623         << ' ' << c.GetAlpha();                   604         << ' ' << c.GetAlpha();
624         break;                                    605         break;
625       case G4ModelingParameters::VASLineStyle:    606       case G4ModelingParameters::VASLineStyle:
626         oss << "\n/vis/touchable/set/lineStyle    607         oss << "\n/vis/touchable/set/lineStyle ";
627         switch (vamVisAtts.GetLineStyle()) {      608         switch (vamVisAtts.GetLineStyle()) {
628           case G4VisAttributes::unbroken:         609           case G4VisAttributes::unbroken:
629             oss << "unbroken";                    610             oss << "unbroken";
630             break;                                611             break;
631           case G4VisAttributes::dashed:           612           case G4VisAttributes::dashed:
632             oss << "dashed";                      613             oss << "dashed";
633             break;                                614             break;
634           case G4VisAttributes::dotted:           615           case G4VisAttributes::dotted:
635           oss << "dotted";                        616           oss << "dotted";
636         }                                         617         }
637         break;                                    618         break;
638       case G4ModelingParameters::VASLineWidth:    619       case G4ModelingParameters::VASLineWidth:
639         oss << "\n/vis/touchable/set/lineWidth    620         oss << "\n/vis/touchable/set/lineWidth "
640         << vamVisAtts.GetLineWidth();             621         << vamVisAtts.GetLineWidth();
641         break;                                    622         break;
642       case G4ModelingParameters::VASForceWiref    623       case G4ModelingParameters::VASForceWireframe:
643         if (vamVisAtts.IsForceDrawingStyle())     624         if (vamVisAtts.IsForceDrawingStyle()) {
644           if (vamVisAtts.GetForcedDrawingStyle    625           if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::wireframe) {
645             oss << "\n/vis/touchable/set/force    626             oss << "\n/vis/touchable/set/forceWireframe ";
646             if (vamVisAtts.IsForceDrawingStyle    627             if (vamVisAtts.IsForceDrawingStyle()) {
647               oss << "true";                      628               oss << "true";
648             } else {                              629             } else {
649               oss << "false";                     630               oss << "false";
650             }                                     631             }
651           }                                       632           }
652         }                                         633         }
653         break;                                    634         break;
654       case G4ModelingParameters::VASForceSolid    635       case G4ModelingParameters::VASForceSolid:
655         if (vamVisAtts.IsForceDrawingStyle())     636         if (vamVisAtts.IsForceDrawingStyle()) {
656           if (vamVisAtts.GetForcedDrawingStyle    637           if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::solid) {
657             oss << "\n/vis/touchable/set/force    638             oss << "\n/vis/touchable/set/forceSolid ";
658             if (vamVisAtts.IsForceDrawingStyle    639             if (vamVisAtts.IsForceDrawingStyle()) {
659               oss << "true";                      640               oss << "true";
660             } else {                              641             } else {
661               oss << "false";                     642               oss << "false";
662             }                                     643             }
663           }                                       644           }
664         }                                         645         }
665         break;                                    646         break;
666       case G4ModelingParameters::VASForceCloud    647       case G4ModelingParameters::VASForceCloud:
667         if (vamVisAtts.IsForceDrawingStyle())     648         if (vamVisAtts.IsForceDrawingStyle()) {
668           if (vamVisAtts.GetForcedDrawingStyle    649           if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::cloud) {
669             oss << "\n/vis/touchable/set/force    650             oss << "\n/vis/touchable/set/forceCloud ";
670             if (vamVisAtts.IsForceDrawingStyle    651             if (vamVisAtts.IsForceDrawingStyle()) {
671               oss << "true";                      652               oss << "true";
672             } else {                              653             } else {
673               oss << "false";                     654               oss << "false";
674             }                                     655             }
675           }                                       656           }
676         }                                         657         }
677         break;                                    658         break;
678       case G4ModelingParameters::VASForceAuxEd    659       case G4ModelingParameters::VASForceAuxEdgeVisible:
679         if (vamVisAtts.IsForceAuxEdgeVisible()    660         if (vamVisAtts.IsForceAuxEdgeVisible()) {
680           oss << "\n/vis/touchable/set/forceAu    661           oss << "\n/vis/touchable/set/forceAuxEdgeVisible ";
681           if (vamVisAtts.IsForcedAuxEdgeVisibl    662           if (vamVisAtts.IsForcedAuxEdgeVisible()) {
682             oss << "true";                        663             oss << "true";
683           } else {                                664           } else {
684             oss << "false";                       665             oss << "false";
685           }                                       666           }
686         }                                         667         }
687         break;                                    668         break;
688       case G4ModelingParameters::VASForceLineS    669       case G4ModelingParameters::VASForceLineSegmentsPerCircle:
689         oss << "\n/vis/touchable/set/lineSegme    670         oss << "\n/vis/touchable/set/lineSegmentsPerCircle "
690         << vamVisAtts.GetForcedLineSegmentsPer    671         << vamVisAtts.GetForcedLineSegmentsPerCircle();
691         break;                                    672         break;
692       case G4ModelingParameters::VASForceNumbe    673       case G4ModelingParameters::VASForceNumberOfCloudPoints:
693         oss << "\n/vis/touchable/set/numberOfC    674         oss << "\n/vis/touchable/set/numberOfCloudPoints "
694         << vamVisAtts.GetForcedNumberOfCloudPo    675         << vamVisAtts.GetForcedNumberOfCloudPoints();
695         break;                                    676         break;
696     }                                             677     }
697   }                                               678   }
698                                                   679   
699   oss << std::endl;                               680   oss << std::endl;
700                                                   681   
701   return oss.str();                               682   return oss.str();
702 }                                                 683 }
703                                                   684 
704 G4String G4ViewParameters::TimeWindowCommands(    685 G4String G4ViewParameters::TimeWindowCommands() const
705 {                                                 686 {
706   std::ostringstream oss;                         687   std::ostringstream oss;
707                                                   688 
708   oss <<  "#\n# Time window commands";            689   oss <<  "#\n# Time window commands";
709                                                   690 
710   oss                                             691   oss
711   << "\n/vis/viewer/set/timeWindow/startTime "    692   << "\n/vis/viewer/set/timeWindow/startTime "
712   << fStartTime/ns << " ns ";                     693   << fStartTime/ns << " ns ";
713                                                   694 
714   oss                                             695   oss
715   << "\n/vis/viewer/set/timeWindow/endTime "      696   << "\n/vis/viewer/set/timeWindow/endTime "
716   << fEndTime/ns << " ns ";                       697   << fEndTime/ns << " ns ";
717                                                   698 
718   oss << "\n/vis/viewer/set/timeWindow/fadeFac    699   oss << "\n/vis/viewer/set/timeWindow/fadeFactor "
719   << fFadeFactor;                                 700   << fFadeFactor;
720                                                   701 
721   oss                                             702   oss
722   << "\n/vis/viewer/set/timeWindow/displayHead    703   << "\n/vis/viewer/set/timeWindow/displayHeadTime ";
723   if (!fDisplayHeadTime) {                        704   if (!fDisplayHeadTime) {
724     oss << "false";                               705     oss << "false";
725   } else {                                        706   } else {
726     oss                                           707     oss
727     << "true"                                     708     << "true"
728     << ' ' << fDisplayHeadTimeX                   709     << ' ' << fDisplayHeadTimeX
729     << ' ' << fDisplayHeadTimeY                   710     << ' ' << fDisplayHeadTimeY
730     << ' ' << fDisplayHeadTimeSize                711     << ' ' << fDisplayHeadTimeSize
731     << ' ' << fDisplayHeadTimeRed                 712     << ' ' << fDisplayHeadTimeRed
732     << ' ' << fDisplayHeadTimeGreen               713     << ' ' << fDisplayHeadTimeGreen
733     << ' ' << fDisplayHeadTimeBlue;               714     << ' ' << fDisplayHeadTimeBlue;
734   }                                               715   }
735                                                   716 
736   oss                                             717   oss
737   << "\n/vis/viewer/set/timeWindow/displayLigh    718   << "\n/vis/viewer/set/timeWindow/displayLightFront ";
738   if (!fDisplayLightFront) {                      719   if (!fDisplayLightFront) {
739     oss << "false";                               720     oss << "false";
740   } else {                                        721   } else {
741     oss                                           722     oss
742     << "true"                                     723     << "true"
743     << ' ' << fDisplayLightFrontX/mm              724     << ' ' << fDisplayLightFrontX/mm
744     << ' ' << fDisplayLightFrontY/mm              725     << ' ' << fDisplayLightFrontY/mm
745     << ' ' << fDisplayLightFrontZ/mm              726     << ' ' << fDisplayLightFrontZ/mm
746     << " mm"                                      727     << " mm"
747     << ' ' << fDisplayLightFrontT/ns              728     << ' ' << fDisplayLightFrontT/ns
748     << " ns"                                      729     << " ns"
749     << ' ' << fDisplayLightFrontRed               730     << ' ' << fDisplayLightFrontRed
750     << ' ' << fDisplayLightFrontGreen             731     << ' ' << fDisplayLightFrontGreen
751     << ' ' << fDisplayLightFrontBlue;             732     << ' ' << fDisplayLightFrontBlue;
752   }                                               733   }
753                                                   734 
754   oss << std::endl;                               735   oss << std::endl;
755                                                   736 
756   return oss.str();                               737   return oss.str();
757 }                                                 738 }
758                                                   739 
759 void G4ViewParameters::PrintDifferences (const    740 void G4ViewParameters::PrintDifferences (const G4ViewParameters& v) const {
760                                                   741 
761   // Put performance-sensitive parameters firs    742   // Put performance-sensitive parameters first.
762   if (                                            743   if (
763       // This first to optimise spin, etc.        744       // This first to optimise spin, etc.
764       (fViewpointDirection   != v.fViewpointDi    745       (fViewpointDirection   != v.fViewpointDirection)   ||
765                                                   746 
766       // No particular order from here on.        747       // No particular order from here on.
767       (fDrawingStyle         != v.fDrawingStyl    748       (fDrawingStyle         != v.fDrawingStyle)         ||
768       (fNumberOfCloudPoints  != v.fNumberOfClo    749       (fNumberOfCloudPoints  != v.fNumberOfCloudPoints)  ||
769       (fAuxEdgeVisible       != v.fAuxEdgeVisi    750       (fAuxEdgeVisible       != v.fAuxEdgeVisible)       ||
770       (fCulling              != v.fCulling)       751       (fCulling              != v.fCulling)              ||
771       (fCullInvisible        != v.fCullInvisib    752       (fCullInvisible        != v.fCullInvisible)        ||
772       (fDensityCulling       != v.fDensityCull    753       (fDensityCulling       != v.fDensityCulling)       ||
773       (fVisibleDensity       != v.fVisibleDens    754       (fVisibleDensity       != v.fVisibleDensity)       ||
774       (fCullCovered          != v.fCullCovered    755       (fCullCovered          != v.fCullCovered)          ||
775       (fCBDAlgorithmNumber   != v.fCBDAlgorith    756       (fCBDAlgorithmNumber   != v.fCBDAlgorithmNumber)   ||
776       (fSection              != v.fSection)       757       (fSection              != v.fSection)              ||
777       (fNoOfSides            != v.fNoOfSides)     758       (fNoOfSides            != v.fNoOfSides)            ||
778       (fUpVector             != v.fUpVector)      759       (fUpVector             != v.fUpVector)             ||
779       (fFieldHalfAngle       != v.fFieldHalfAn    760       (fFieldHalfAngle       != v.fFieldHalfAngle)       ||
780       (fZoomFactor           != v.fZoomFactor)    761       (fZoomFactor           != v.fZoomFactor)           ||
781       (fScaleFactor          != v.fScaleFactor    762       (fScaleFactor          != v.fScaleFactor)          ||
782       (fCurrentTargetPoint   != v.fCurrentTarg    763       (fCurrentTargetPoint   != v.fCurrentTargetPoint)   ||
783       (fDolly                != v.fDolly)         764       (fDolly                != v.fDolly)                ||
784       (fRelativeLightpointDirection != v.fRela    765       (fRelativeLightpointDirection != v.fRelativeLightpointDirection)  ||
785       (fLightsMoveWithCamera != v.fLightsMoveW    766       (fLightsMoveWithCamera != v.fLightsMoveWithCamera) ||
786       (fDefaultVisAttributes != v.fDefaultVisA    767       (fDefaultVisAttributes != v.fDefaultVisAttributes) ||
787       (fDefaultTextVisAttributes != v.fDefault    768       (fDefaultTextVisAttributes != v.fDefaultTextVisAttributes) ||
788       (fDefaultMarker        != v.fDefaultMark    769       (fDefaultMarker        != v.fDefaultMarker)        ||
789       (fGlobalMarkerScale    != v.fGlobalMarke    770       (fGlobalMarkerScale    != v.fGlobalMarkerScale)    ||
790       (fGlobalLineWidthScale != v.fGlobalLineW    771       (fGlobalLineWidthScale != v.fGlobalLineWidthScale) ||
791       (fMarkerNotHidden      != v.fMarkerNotHi    772       (fMarkerNotHidden      != v.fMarkerNotHidden)      ||
792       (fWindowSizeHintX      != v.fWindowSizeH    773       (fWindowSizeHintX      != v.fWindowSizeHintX)      ||
793       (fWindowSizeHintY      != v.fWindowSizeH    774       (fWindowSizeHintY      != v.fWindowSizeHintY)      ||
794       (fXGeometryString      != v.fXGeometrySt    775       (fXGeometryString      != v.fXGeometryString)      ||
795       (fGeometryMask         != v.fGeometryMas    776       (fGeometryMask         != v.fGeometryMask)         ||
796       (fAutoRefresh          != v.fAutoRefresh    777       (fAutoRefresh          != v.fAutoRefresh)          ||
797       (fBackgroundColour     != v.fBackgroundC    778       (fBackgroundColour     != v.fBackgroundColour)     || 
798       (fPicking              != v.fPicking)       779       (fPicking              != v.fPicking)              ||
799       (fRotationStyle        != v.fRotationSty    780       (fRotationStyle        != v.fRotationStyle)
800       )                                           781       )
801     G4cout << "Difference in 1st batch." << G4    782     G4cout << "Difference in 1st batch." << G4endl;
802                                                   783 
803   if (fCBDAlgorithmNumber > 0) {                  784   if (fCBDAlgorithmNumber > 0) {
804     if (fCBDParameters.size() != v.fCBDParamet    785     if (fCBDParameters.size() != v.fCBDParameters.size()) {
805       G4cout << "Difference in number of colou    786       G4cout << "Difference in number of colour by density parameters." << G4endl;
806     } else if (fCBDParameters != v.fCBDParamet    787     } else if (fCBDParameters != v.fCBDParameters) {
807       G4cout << "Difference in values of colou    788       G4cout << "Difference in values of colour by density parameters." << G4endl;
808     }                                             789     }
809   }                                               790   }
810                                                   791 
811   if (fSection) {                                 792   if (fSection) {
812     if (!(fSectionPlane == v.fSectionPlane))      793     if (!(fSectionPlane == v.fSectionPlane))
813       G4cout << "Difference in section planes     794       G4cout << "Difference in section planes batch." << G4endl;
814   }                                               795   }
815                                                   796 
816   if (IsCutaway()) {                              797   if (IsCutaway()) {
817     if (fCutawayPlanes.size () != v.fCutawayPl    798     if (fCutawayPlanes.size () != v.fCutawayPlanes.size ()) {
818       G4cout << "Difference in no of cutaway p    799       G4cout << "Difference in no of cutaway planes." << G4endl;
819     }                                             800     }
820     else {                                        801     else {
821       for (size_t i = 0; i < fCutawayPlanes.si    802       for (size_t i = 0; i < fCutawayPlanes.size (); i++) {
822   if (!(fCutawayPlanes[i] == v.fCutawayPlanes[    803   if (!(fCutawayPlanes[i] == v.fCutawayPlanes[i]))
823     G4cout << "Difference in cutaway plane no.    804     G4cout << "Difference in cutaway plane no. " << i << G4endl;
824       }                                           805       }
825     }                                             806     }
826   }                                               807   }
827                                                   808 
828   if (IsExplode()) {                              809   if (IsExplode()) {
829     if (fExplodeFactor != v.fExplodeFactor)       810     if (fExplodeFactor != v.fExplodeFactor)
830       G4cout << "Difference in explode factor.    811       G4cout << "Difference in explode factor." << G4endl;
831     if (fExplodeCentre != v.fExplodeCentre)       812     if (fExplodeCentre != v.fExplodeCentre)
832       G4cout << "Difference in explode centre.    813       G4cout << "Difference in explode centre." << G4endl;
833   }                                               814   }
834                                                   815 
835   if (fVisAttributesModifiers != v.fVisAttribu    816   if (fVisAttributesModifiers != v.fVisAttributesModifiers) {
836     G4cout << "Difference in vis attributes mo    817     G4cout << "Difference in vis attributes modifiers." << G4endl;
837   }                                               818   }
838                                                   819 
839   if (fStartTime != v.fStartTime ||               820   if (fStartTime != v.fStartTime ||
840       fEndTime   != v.fEndTime)  {                821       fEndTime   != v.fEndTime)  {
841     G4cout << "Difference in time window." <<     822     G4cout << "Difference in time window." << G4endl;
842   }                                               823   }
843                                                   824 
844   if (fFadeFactor != v.fFadeFactor) {             825   if (fFadeFactor != v.fFadeFactor) {
845     G4cout << "Difference in time window fade     826     G4cout << "Difference in time window fade factor." << G4endl;
846   }                                               827   }
847                                                   828 
848   if (fDisplayHeadTime != v.fDisplayHeadTime)     829   if (fDisplayHeadTime != v.fDisplayHeadTime) {
849     G4cout << "Difference in display head time    830     G4cout << "Difference in display head time flag." << G4endl;
850   } else {                                        831   } else {
851     if (fDisplayHeadTimeX     != v.fDisplayHea    832     if (fDisplayHeadTimeX     != v.fDisplayHeadTimeX     ||
852         fDisplayHeadTimeY     != v.fDisplayHea    833         fDisplayHeadTimeY     != v.fDisplayHeadTimeY     ||
853         fDisplayHeadTimeSize  != v.fDisplayHea    834         fDisplayHeadTimeSize  != v.fDisplayHeadTimeSize  ||
854         fDisplayHeadTimeRed   != v.fDisplayHea    835         fDisplayHeadTimeRed   != v.fDisplayHeadTimeRed   ||
855         fDisplayHeadTimeGreen != v.fDisplayHea    836         fDisplayHeadTimeGreen != v.fDisplayHeadTimeGreen ||
856         fDisplayHeadTimeBlue  != v.fDisplayHea    837         fDisplayHeadTimeBlue  != v.fDisplayHeadTimeBlue) {
857       G4cout << "Difference in display head ti    838       G4cout << "Difference in display head time parameters." << G4endl;
858     }                                             839     }
859   }                                               840   }
860                                                   841 
861   if (fDisplayLightFront != v.fDisplayLightFro    842   if (fDisplayLightFront != v.fDisplayLightFront) {
862     G4cout << "Difference in display light fro    843     G4cout << "Difference in display light front flag." << G4endl;
863   } else {                                        844   } else {
864     if (fDisplayLightFrontX     != v.fDisplayL    845     if (fDisplayLightFrontX     != v.fDisplayLightFrontX     ||
865         fDisplayLightFrontY     != v.fDisplayL    846         fDisplayLightFrontY     != v.fDisplayLightFrontY     ||
866         fDisplayLightFrontZ     != v.fDisplayL    847         fDisplayLightFrontZ     != v.fDisplayLightFrontZ     ||
867         fDisplayLightFrontT     != v.fDisplayL    848         fDisplayLightFrontT     != v.fDisplayLightFrontT     ||
868         fDisplayLightFrontRed   != v.fDisplayL    849         fDisplayLightFrontRed   != v.fDisplayLightFrontRed   ||
869         fDisplayLightFrontGreen != v.fDisplayL    850         fDisplayLightFrontGreen != v.fDisplayLightFrontGreen ||
870         fDisplayLightFrontBlue  != v.fDisplayL    851         fDisplayLightFrontBlue  != v.fDisplayLightFrontBlue) {
871       G4cout << "Difference in display light f    852       G4cout << "Difference in display light front parameters." << G4endl;
872     }                                             853     }
873   }                                               854   }
874 }                                                 855 }
875                                                   856 
876 std::ostream& operator <<                         857 std::ostream& operator <<
877  (std::ostream& os, G4ViewParameters::DrawingS << 858 (std::ostream& os, const G4ViewParameters::DrawingStyle& style)
878 {                                                 859 {
879   switch (style) {                                860   switch (style) {
880     case G4ViewParameters::wireframe:          << 861   case G4ViewParameters::wireframe:
881       os << "wireframe"; break;                << 862     os << "wireframe"; break;
882     case G4ViewParameters::hlr:                << 863   case G4ViewParameters::hlr:
883       os << "hlr - hidden lines removed"; brea << 864     os << "hlr - hidden lines removed"; break;
884     case G4ViewParameters::hsr:                << 865   case G4ViewParameters::hsr:
885       os << "hsr - hidden surfaces removed"; b << 866     os << "hsr - hidden surfaces removed"; break;
886     case G4ViewParameters::hlhsr:              << 867   case G4ViewParameters::hlhsr:
887       os << "hlhsr - hidden line, hidden surfa << 868     os << "hlhsr - hidden line, hidden surface removed"; break;
888     case G4ViewParameters::cloud:              << 869   case G4ViewParameters::cloud:
889       os << "cloud - draw volume as a cloud of << 870     os << "cloud - draw volume as a cloud of dots"; break;
890     default: os << "unrecognised"; break;      << 871   default: os << "unrecognised"; break;
891   }                                            << 
892   return os;                                   << 
893 }                                              << 
894                                                << 
895 std::ostream& operator <<                      << 
896 (std::ostream& os, G4ViewParameters::SMROption << 
897 {                                              << 
898   switch (option) {                            << 
899     case G4ViewParameters::meshAsDefault:      << 
900       os << "default"; break;                  << 
901     case G4ViewParameters::meshAsDots:         << 
902       os << "dots"; break;                     << 
903     case G4ViewParameters::meshAsSurfaces:     << 
904       os << "surfaces"; break;                 << 
905   }                                               872   }
906   return os;                                      873   return os;
907 }                                                 874 }
908                                                   875 
909 std::ostream& operator << (std::ostream& os, c    876 std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
910   os << "View parameters and options:";           877   os << "View parameters and options:";
911                                                   878 
912   os << "\n  Drawing style: " << v.fDrawingSty    879   os << "\n  Drawing style: " << v.fDrawingStyle;
913                                                   880 
914   os << "\n  Number of cloud points: " << v.fN    881   os << "\n  Number of cloud points: " << v.fNumberOfCloudPoints;
915                                                   882 
916   os << "\n  Auxiliary edges: ";                  883   os << "\n  Auxiliary edges: ";
917   if (!v.fAuxEdgeVisible) os << "in";             884   if (!v.fAuxEdgeVisible) os << "in";
918   os << "visible";                                885   os << "visible";
919                                                   886 
920   os << "\n  Culling: ";                          887   os << "\n  Culling: ";
921   if (v.fCulling) os << "on";                     888   if (v.fCulling) os << "on";
922   else            os << "off";                    889   else            os << "off";
923                                                   890 
924   os << "\n  Culling invisible objects: ";        891   os << "\n  Culling invisible objects: ";
925   if (v.fCullInvisible) os << "on";               892   if (v.fCullInvisible) os << "on";
926   else                  os << "off";              893   else                  os << "off";
927                                                   894 
928   os << "\n  Density culling: ";                  895   os << "\n  Density culling: ";
929   if (v.fDensityCulling) {                        896   if (v.fDensityCulling) {
930     os << "on - invisible if density less than    897     os << "on - invisible if density less than "
931        << v.fVisibleDensity / (1. * g / cm3) <    898        << v.fVisibleDensity / (1. * g / cm3) << " g cm^-3";
932   }                                               899   }
933   else os << "off";                               900   else os << "off";
934                                                   901 
935   os << "\n  Culling daughters covered by opaq    902   os << "\n  Culling daughters covered by opaque mothers: ";
936   if (v.fCullCovered) os << "on";                 903   if (v.fCullCovered) os << "on";
937   else                os << "off";                904   else                os << "off";
938                                                   905 
939   os << "\n  Colour by density: ";                906   os << "\n  Colour by density: ";
940   if (v.fCBDAlgorithmNumber <= 0) {               907   if (v.fCBDAlgorithmNumber <= 0) {
941     os << "inactive";                             908     os << "inactive";
942   } else {                                        909   } else {
943     os << "Algorithm " << v.fCBDAlgorithmNumbe    910     os << "Algorithm " << v.fCBDAlgorithmNumber << ", Parameters:";
944     for (auto p: v.fCBDParameters) {              911     for (auto p: v.fCBDParameters) {
945       os << ' ' << G4BestUnit(p,"Volumic Mass"    912       os << ' ' << G4BestUnit(p,"Volumic Mass");
946     }                                             913     }
947   }                                               914   }
948                                                   915 
949   os << "\n  Section flag: ";                     916   os << "\n  Section flag: ";
950   if (v.fSection) os << "true, section/cut pla    917   if (v.fSection) os << "true, section/cut plane: " << v.fSectionPlane;
951   else            os << "false";                  918   else            os << "false";
952                                                   919 
953   if (v.IsCutaway()) {                            920   if (v.IsCutaway()) {
954     os << "\n  Cutaway planes: ";                 921     os << "\n  Cutaway planes: ";
955     for (size_t i = 0; i < v.fCutawayPlanes.si    922     for (size_t i = 0; i < v.fCutawayPlanes.size (); i++) {
956       os << ' ' << v.fCutawayPlanes[i];           923       os << ' ' << v.fCutawayPlanes[i];
957     }                                             924     }
958   }                                               925   }
959   else {                                          926   else {
960     os << "\n  No cutaway planes";                927     os << "\n  No cutaway planes";
961   }                                               928   }
962                                                   929 
963   os << "\n  Explode factor: " << v.fExplodeFa    930   os << "\n  Explode factor: " << v.fExplodeFactor
964      << " about centre: " << v.fExplodeCentre;    931      << " about centre: " << v.fExplodeCentre;
965                                                   932 
966   os << "\n  No. of sides used in circle polyg    933   os << "\n  No. of sides used in circle polygon approximation: "
967      << v.fNoOfSides;                             934      << v.fNoOfSides;
968                                                   935 
969   os << "\n  Viewpoint direction:  " << v.fVie    936   os << "\n  Viewpoint direction:  " << v.fViewpointDirection;
970                                                   937 
971   os << "\n  Up vector:            " << v.fUpV    938   os << "\n  Up vector:            " << v.fUpVector;
972                                                   939 
973   os << "\n  Field half angle:     " << v.fFie    940   os << "\n  Field half angle:     " << v.fFieldHalfAngle;
974                                                   941 
975   os << "\n  Zoom factor:          " << v.fZoo    942   os << "\n  Zoom factor:          " << v.fZoomFactor;
976                                                   943 
977   os << "\n  Scale factor:         " << v.fSca    944   os << "\n  Scale factor:         " << v.fScaleFactor;
978                                                   945 
979   os << "\n  Current target point: " << v.fCur    946   os << "\n  Current target point: " << v.fCurrentTargetPoint;
980                                                   947 
981   os << "\n  Dolly distance:       " << v.fDol    948   os << "\n  Dolly distance:       " << v.fDolly;
982                                                   949 
983   os << "\n  Light ";                             950   os << "\n  Light ";
984   if (v.fLightsMoveWithCamera) os << "moves";     951   if (v.fLightsMoveWithCamera) os << "moves";
985   else                         os << "does not    952   else                         os << "does not move";
986   os << " with camera";                           953   os << " with camera";
987                                                   954 
988   os << "\n  Relative lightpoint direction: "     955   os << "\n  Relative lightpoint direction: "
989      << v.fRelativeLightpointDirection;           956      << v.fRelativeLightpointDirection;
990                                                   957 
991   os << "\n  Actual lightpoint direction: "       958   os << "\n  Actual lightpoint direction: "
992      << v.fActualLightpointDirection;             959      << v.fActualLightpointDirection;
993                                                   960 
994   os << "\n  Derived parameters for standard v    961   os << "\n  Derived parameters for standard view of object of unit radius:";
995   G4ViewParameters tempVP = v;                    962   G4ViewParameters tempVP = v;
996   tempVP.fDolly = 0.;                             963   tempVP.fDolly = 0.;
997   tempVP.fZoomFactor = 1.;                        964   tempVP.fZoomFactor = 1.;
998   const G4double radius = 1.;                     965   const G4double radius = 1.;
999   const G4double cameraDistance = tempVP.GetCa    966   const G4double cameraDistance = tempVP.GetCameraDistance (radius);
1000   const G4double nearDistance =                  967   const G4double nearDistance =
1001     tempVP.GetNearDistance (cameraDistance, r    968     tempVP.GetNearDistance (cameraDistance, radius);
1002   const G4double farDistance =                   969   const G4double farDistance =
1003     tempVP.GetFarDistance  (cameraDistance, n    970     tempVP.GetFarDistance  (cameraDistance, nearDistance, radius);
1004   const G4double right  = tempVP.GetFrontHalf    971   const G4double right  = tempVP.GetFrontHalfHeight (nearDistance, radius);
1005   os << "\n    Camera distance:   " << camera    972   os << "\n    Camera distance:   " << cameraDistance;
1006   os << "\n    Near distance:     " << nearDi    973   os << "\n    Near distance:     " << nearDistance;
1007   os << "\n    Far distance:      " << farDis    974   os << "\n    Far distance:      " << farDistance;
1008   os << "\n    Front half height: " << right;    975   os << "\n    Front half height: " << right;
1009                                                  976 
1010   os << "\n  Default VisAttributes:\n  " << v    977   os << "\n  Default VisAttributes:\n  " << v.fDefaultVisAttributes;
1011                                                  978 
1012   os << "\n  Default TextVisAttributes:\n  "     979   os << "\n  Default TextVisAttributes:\n  " << v.fDefaultTextVisAttributes;
1013                                                  980 
1014   os << "\n  Default marker:\n    " << v.fDef << 981   os << "\n  Default marker: " << v.fDefaultMarker;
1015                                                  982 
1016   os << "\n  Global marker scale: " << v.fGlo    983   os << "\n  Global marker scale: " << v.fGlobalMarkerScale;
1017                                                  984 
1018   os << "\n  Global lineWidth scale: " << v.f    985   os << "\n  Global lineWidth scale: " << v.fGlobalLineWidthScale;
1019                                                  986 
1020   os << "\n  Marker ";                           987   os << "\n  Marker ";
1021   if (v.fMarkerNotHidden) os << "not ";          988   if (v.fMarkerNotHidden) os << "not ";
1022   os << "hidden by surfaces.";                   989   os << "hidden by surfaces.";
1023                                                  990 
1024   os << "\n  Window size hint: "                 991   os << "\n  Window size hint: "
1025      << v.fWindowSizeHintX << 'x'<< v.fWindow    992      << v.fWindowSizeHintX << 'x'<< v.fWindowSizeHintX;
1026                                                  993 
1027   os << "\n  X geometry string: " << v.fXGeom    994   os << "\n  X geometry string: " << v.fXGeometryString;
1028   os << "\n  X geometry mask: "                  995   os << "\n  X geometry mask: "
1029      << std::showbase << std::hex << v.fGeome    996      << std::showbase << std::hex << v.fGeometryMask
1030      << std::noshowbase << std::dec;             997      << std::noshowbase << std::dec;
1031                                                  998 
1032   os << "\n  Auto refresh: ";                    999   os << "\n  Auto refresh: ";
1033   if (v.fAutoRefresh) os << "true";              1000   if (v.fAutoRefresh) os << "true";
1034   else os << "false";                            1001   else os << "false";
1035                                                  1002 
1036   os << "\n  Background colour: " << v.fBackg    1003   os << "\n  Background colour: " << v.fBackgroundColour;
1037                                                  1004 
1038   os << "\n  Picking requested: ";               1005   os << "\n  Picking requested: ";
1039   if (v.fPicking) os << "true";                  1006   if (v.fPicking) os << "true";
1040   else os << "false";                            1007   else os << "false";
1041                                                  1008 
1042   os << "\n  Rotation style: ";                  1009   os << "\n  Rotation style: ";
1043   switch (v.fRotationStyle) {                    1010   switch (v.fRotationStyle) {
1044   case G4ViewParameters::constrainUpDirection    1011   case G4ViewParameters::constrainUpDirection:
1045     os << "constrainUpDirection (conventional    1012     os << "constrainUpDirection (conventional HEP view)"; break;
1046   case G4ViewParameters::freeRotation:           1013   case G4ViewParameters::freeRotation:
1047     os << "freeRotation (Google-like rotation    1014     os << "freeRotation (Google-like rotation, using mouse-grab)"; break;
1048   default: os << "unrecognised"; break;          1015   default: os << "unrecognised"; break;
1049   }                                              1016   }
1050                                                  1017 
1051   os << "\nVis attributes modifiers: ";       << 1018   os << "\n  Vis attributes modifiers: ";
1052   const std::vector<G4ModelingParameters::Vis    1019   const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
1053     v.fVisAttributesModifiers;                   1020     v.fVisAttributesModifiers;
1054   if (vams.empty()) {                            1021   if (vams.empty()) {
1055     os << "None";                                1022     os << "None";
1056   } else {                                       1023   } else {
1057     os << vams;                                  1024     os << vams;
1058   }                                              1025   }
1059                                                  1026 
1060   os << "\nTime window parameters:"           << 1027   os << "\n  Time window parameters:"
1061   << "\n  Start time:  " << v.fStartTime/ns <    1028   << "\n  Start time:  " << v.fStartTime/ns << " ns"
1062   << "\n  End time:    " << v.fEndTime/ns <<     1029   << "\n  End time:    " << v.fEndTime/ns << " ns"
1063   << "\n  Fade factor: " << v.fFadeFactor;       1030   << "\n  Fade factor: " << v.fFadeFactor;
1064   if (!v.fDisplayHeadTime) {                     1031   if (!v.fDisplayHeadTime) {
1065     os << "\n  Head time display not requeste    1032     os << "\n  Head time display not requested.";
1066   } else {                                       1033   } else {
1067     os                                           1034     os
1068     << "\n  Head time position: "                1035     << "\n  Head time position: "
1069     << v.fDisplayHeadTimeX << ' ' << v.fDispl    1036     << v.fDisplayHeadTimeX << ' ' << v.fDisplayHeadTimeY
1070     << "\n  Head time size:     " << v.fDispl    1037     << "\n  Head time size:     " << v.fDisplayHeadTimeSize
1071     << "\n  Head time colour:   " << v.fDispl    1038     << "\n  Head time colour:   " << v.fDisplayHeadTimeRed
1072     << ' ' << v.fDisplayHeadTimeGreen << ' '     1039     << ' ' << v.fDisplayHeadTimeGreen << ' ' << v.fDisplayHeadTimeBlue;
1073   }                                              1040   }
1074   if (!v.fDisplayLightFront) {                   1041   if (!v.fDisplayLightFront) {
1075     os << "\n  Light front display not reques    1042     os << "\n  Light front display not requested.";
1076   } else {                                       1043   } else {
1077     os                                           1044     os
1078     << "\n  Light front position: "              1045     << "\n  Light front position: "
1079     << v.fDisplayLightFrontX/mm << ' ' << v.f    1046     << v.fDisplayLightFrontX/mm << ' ' << v.fDisplayLightFrontY/mm
1080     << ' ' << v.fDisplayLightFrontZ/mm << " m    1047     << ' ' << v.fDisplayLightFrontZ/mm << " mm"
1081     << "\n  Light front time:     " << v.fDis    1048     << "\n  Light front time:     " << v.fDisplayLightFrontT/ns << " ns"
1082     << "\n  Light front colour:   " << v.fDis    1049     << "\n  Light front colour:   " << v.fDisplayLightFrontRed
1083     << ' ' << v.fDisplayLightFrontGreen << '     1050     << ' ' << v.fDisplayLightFrontGreen << ' ' << v.fDisplayLightFrontBlue;
1084   }                                              1051   }
1085                                                  1052 
1086   os << "\nSpecial Mesh Rendering";           << 
1087   if (v.fSpecialMeshRendering) {              << 
1088     os << " requested with option \"" << v.fS << 
1089     os << "\" for ";                          << 
1090     if (v.fSpecialMeshVolumes.empty()) {      << 
1091       os << "any mesh";                       << 
1092     } else {                                  << 
1093       os << "selected meshes";                << 
1094       for (const auto& vol: v.fSpecialMeshVol << 
1095   os << "\n    " << vol.GetName() << ':' << v << 
1096       }                                       << 
1097     }                                         << 
1098   } else os << ": off";                       << 
1099   return os;                                     1053   return os;
1100 }                                                1054 }
1101                                                  1055 
1102 G4bool G4ViewParameters::operator != (const G    1056 G4bool G4ViewParameters::operator != (const G4ViewParameters& v) const {
1103                                                  1057 
1104   // Put performance-sensitive parameters fir    1058   // Put performance-sensitive parameters first.
1105   if (                                           1059   if (
1106       // This first to optimise spin, etc.       1060       // This first to optimise spin, etc.
1107       (fViewpointDirection   != v.fViewpointD    1061       (fViewpointDirection   != v.fViewpointDirection)   ||
1108                                                  1062 
1109       // No particular order from here on.       1063       // No particular order from here on.
1110       (fDrawingStyle         != v.fDrawingSty    1064       (fDrawingStyle         != v.fDrawingStyle)         ||
1111       (fNumberOfCloudPoints  != v.fNumberOfCl    1065       (fNumberOfCloudPoints  != v.fNumberOfCloudPoints)  ||
1112       (fAuxEdgeVisible       != v.fAuxEdgeVis    1066       (fAuxEdgeVisible       != v.fAuxEdgeVisible)       ||
1113       (fCulling              != v.fCulling)      1067       (fCulling              != v.fCulling)              ||
1114       (fCullInvisible        != v.fCullInvisi    1068       (fCullInvisible        != v.fCullInvisible)        ||
1115       (fDensityCulling       != v.fDensityCul    1069       (fDensityCulling       != v.fDensityCulling)       ||
1116       (fCullCovered          != v.fCullCovere    1070       (fCullCovered          != v.fCullCovered)          ||
1117       (fCBDAlgorithmNumber   != v.fCBDAlgorit    1071       (fCBDAlgorithmNumber   != v.fCBDAlgorithmNumber)   ||
1118       (fSection              != v.fSection)      1072       (fSection              != v.fSection)              ||
1119       (IsCutaway()           != v.IsCutaway()    1073       (IsCutaway()           != v.IsCutaway())           ||
1120       (IsExplode()           != v.IsExplode()    1074       (IsExplode()           != v.IsExplode())           ||
1121       (fNoOfSides            != v.fNoOfSides)    1075       (fNoOfSides            != v.fNoOfSides)            ||
1122       (fUpVector             != v.fUpVector)     1076       (fUpVector             != v.fUpVector)             ||
1123       (fFieldHalfAngle       != v.fFieldHalfA    1077       (fFieldHalfAngle       != v.fFieldHalfAngle)       ||
1124       (fZoomFactor           != v.fZoomFactor    1078       (fZoomFactor           != v.fZoomFactor)           ||
1125       (fScaleFactor          != v.fScaleFacto    1079       (fScaleFactor          != v.fScaleFactor)          ||
1126       (fCurrentTargetPoint   != v.fCurrentTar    1080       (fCurrentTargetPoint   != v.fCurrentTargetPoint)   ||
1127       (fDolly                != v.fDolly)        1081       (fDolly                != v.fDolly)                ||
1128       (fRelativeLightpointDirection != v.fRel    1082       (fRelativeLightpointDirection != v.fRelativeLightpointDirection)  ||
1129       (fLightsMoveWithCamera != v.fLightsMove    1083       (fLightsMoveWithCamera != v.fLightsMoveWithCamera) ||
1130       (fDefaultVisAttributes != v.fDefaultVis    1084       (fDefaultVisAttributes != v.fDefaultVisAttributes) ||
1131       (fDefaultTextVisAttributes != v.fDefaul    1085       (fDefaultTextVisAttributes != v.fDefaultTextVisAttributes) ||
1132       (fDefaultMarker        != v.fDefaultMar    1086       (fDefaultMarker        != v.fDefaultMarker)        ||
1133       (fGlobalMarkerScale    != v.fGlobalMark    1087       (fGlobalMarkerScale    != v.fGlobalMarkerScale)    ||
1134       (fGlobalLineWidthScale != v.fGlobalLine    1088       (fGlobalLineWidthScale != v.fGlobalLineWidthScale) ||
1135       (fMarkerNotHidden      != v.fMarkerNotH    1089       (fMarkerNotHidden      != v.fMarkerNotHidden)      ||
1136       (fWindowSizeHintX      != v.fWindowSize    1090       (fWindowSizeHintX      != v.fWindowSizeHintX)      ||
1137       (fWindowSizeHintY      != v.fWindowSize    1091       (fWindowSizeHintY      != v.fWindowSizeHintY)      ||
1138       (fXGeometryString      != v.fXGeometryS    1092       (fXGeometryString      != v.fXGeometryString)      ||
1139       (fGeometryMask         != v.fGeometryMa    1093       (fGeometryMask         != v.fGeometryMask)         ||
1140       (fAutoRefresh          != v.fAutoRefres    1094       (fAutoRefresh          != v.fAutoRefresh)          ||
1141       (fBackgroundColour     != v.fBackground    1095       (fBackgroundColour     != v.fBackgroundColour)     ||
1142       (fPicking              != v.fPicking)      1096       (fPicking              != v.fPicking)              ||
1143       (fRotationStyle        != v.fRotationSt << 1097       (fRotationStyle        != v.fRotationStyle)
1144       (fSpecialMeshRendering != v.fSpecialMes << 
1145       (fSpecialMeshRenderingOption != v.fSpec << 
1146       )                                          1098       )
1147     return true;                                 1099     return true;
1148                                                  1100 
1149   if (fDensityCulling &&                         1101   if (fDensityCulling &&
1150       (fVisibleDensity != v.fVisibleDensity))    1102       (fVisibleDensity != v.fVisibleDensity)) return true;
1151                                                  1103 
1152   if (fCBDAlgorithmNumber > 0) {                 1104   if (fCBDAlgorithmNumber > 0) {
1153     if (fCBDParameters.size() != v.fCBDParame    1105     if (fCBDParameters.size() != v.fCBDParameters.size()) return true;
1154     else if (fCBDParameters != v.fCBDParamete    1106     else if (fCBDParameters != v.fCBDParameters) return true;
1155   }                                              1107   }
1156                                                  1108 
1157   if (fSection &&                                1109   if (fSection &&
1158       (!(fSectionPlane == v.fSectionPlane)))     1110       (!(fSectionPlane == v.fSectionPlane))) return true;
1159                                                  1111 
1160   if (IsCutaway()) {                             1112   if (IsCutaway()) {
1161     if (fCutawayPlanes.size () != v.fCutawayP    1113     if (fCutawayPlanes.size () != v.fCutawayPlanes.size ())
1162       return true;                               1114       return true;
1163     else {                                       1115     else {
1164       for (size_t i = 0; i < fCutawayPlanes.s    1116       for (size_t i = 0; i < fCutawayPlanes.size (); i++) {
1165   if (!(fCutawayPlanes[i] == v.fCutawayPlanes    1117   if (!(fCutawayPlanes[i] == v.fCutawayPlanes[i])) return true;
1166       }                                          1118       }
1167     }                                            1119     }
1168   }                                              1120   }
1169                                                  1121 
1170   if (IsExplode() &&                             1122   if (IsExplode() &&
1171       ((fExplodeFactor != v.fExplodeFactor) |    1123       ((fExplodeFactor != v.fExplodeFactor) ||
1172        (fExplodeCentre != v.fExplodeCentre)))    1124        (fExplodeCentre != v.fExplodeCentre))) return true;
1173                                                  1125 
1174   if (fVisAttributesModifiers != v.fVisAttrib    1126   if (fVisAttributesModifiers != v.fVisAttributesModifiers) return true;
1175                                                  1127 
1176   if (fStartTime  != v.fStartTime ||             1128   if (fStartTime  != v.fStartTime ||
1177       fEndTime    != v.fEndTime   ||             1129       fEndTime    != v.fEndTime   ||
1178       fFadeFactor != v.fFadeFactor) return tr    1130       fFadeFactor != v.fFadeFactor) return true;
1179                                                  1131 
1180   if (fDisplayHeadTime != v.fDisplayHeadTime)    1132   if (fDisplayHeadTime != v.fDisplayHeadTime) return true;
1181   if (fDisplayHeadTime) {                        1133   if (fDisplayHeadTime) {
1182     if (fDisplayHeadTimeX     != v.fDisplayHe    1134     if (fDisplayHeadTimeX     != v.fDisplayHeadTimeX     ||
1183         fDisplayHeadTimeY     != v.fDisplayHe    1135         fDisplayHeadTimeY     != v.fDisplayHeadTimeY     ||
1184         fDisplayHeadTimeSize  != v.fDisplayHe    1136         fDisplayHeadTimeSize  != v.fDisplayHeadTimeSize  ||
1185         fDisplayHeadTimeRed   != v.fDisplayHe    1137         fDisplayHeadTimeRed   != v.fDisplayHeadTimeRed   ||
1186         fDisplayHeadTimeGreen != v.fDisplayHe    1138         fDisplayHeadTimeGreen != v.fDisplayHeadTimeGreen ||
1187         fDisplayHeadTimeBlue  != v.fDisplayHe    1139         fDisplayHeadTimeBlue  != v.fDisplayHeadTimeBlue) {
1188       return true;                               1140       return true;
1189     }                                            1141     }
1190   }                                              1142   }
1191                                                  1143 
1192   if (fDisplayLightFront != v.fDisplayLightFr    1144   if (fDisplayLightFront != v.fDisplayLightFront) return true;
1193   if (fDisplayLightFront) {                      1145   if (fDisplayLightFront) {
1194     if (fDisplayLightFrontX     != v.fDisplay    1146     if (fDisplayLightFrontX     != v.fDisplayLightFrontX     ||
1195         fDisplayLightFrontY     != v.fDisplay    1147         fDisplayLightFrontY     != v.fDisplayLightFrontY     ||
1196         fDisplayLightFrontZ     != v.fDisplay    1148         fDisplayLightFrontZ     != v.fDisplayLightFrontZ     ||
1197         fDisplayLightFrontT     != v.fDisplay    1149         fDisplayLightFrontT     != v.fDisplayLightFrontT     ||
1198         fDisplayLightFrontRed   != v.fDisplay    1150         fDisplayLightFrontRed   != v.fDisplayLightFrontRed   ||
1199         fDisplayLightFrontGreen != v.fDisplay    1151         fDisplayLightFrontGreen != v.fDisplayLightFrontGreen ||
1200         fDisplayLightFrontBlue  != v.fDisplay    1152         fDisplayLightFrontBlue  != v.fDisplayLightFrontBlue) {
1201       return true;                               1153       return true;
1202     }                                            1154     }
1203   }                                              1155   }
1204                                                  1156 
1205   if (fSpecialMeshRendering) {                << 
1206     if (fSpecialMeshVolumes != v.fSpecialMesh << 
1207       return true;;                           << 
1208   }                                           << 
1209                                               << 
1210   return false;                                  1157   return false;
1211 }                                                1158 }
1212                                                  1159 
1213 void G4ViewParameters::SetXGeometryString (co << 1160 void G4ViewParameters::SetXGeometryString (const G4String& geomStringArg)
1214 {                                                1161 {
                                                   >> 1162   G4int x = 0, y = 0;
                                                   >> 1163   unsigned int w = 0, h = 0;
                                                   >> 1164   G4String geomString = geomStringArg;
                                                   >> 1165   // Parse windowSizeHintString for backwards compatibility...
1215   const G4String delimiters("xX+-");             1166   const G4String delimiters("xX+-");
1216   G4String::size_type i = geomString.find_fir    1167   G4String::size_type i = geomString.find_first_of(delimiters);
1217   if (i == G4String::npos) {                  << 1168   if (i == G4String::npos) {  // Does not contain "xX+-".  Assume single number
1218     // Does not contain "xX+-".               << 
1219     // Is it a single number?                 << 
1220     std::istringstream iss(geomString);          1169     std::istringstream iss(geomString);
1221     G4int size;                                  1170     G4int size;
1222     iss >> size;                                 1171     iss >> size;
1223     if (iss) {                                << 1172     if (!iss) {
1224       // It is a number                       << 1173       size = 600;
1225       fWindowSizeHintX = size;                << 1174       G4cout << "Unrecognised windowSizeHint string: \""
1226       fWindowSizeHintY = size;                << 1175        << geomString
                                                   >> 1176        << "\".  Asuuming " << size << G4endl;
1227     }                                            1177     }
1228     // Accept other or all defaults (in G4Vie << 
1229     // Reconstruct a geometry string coherent << 
1230     char signX, signY;                        << 
1231     if (fWindowLocationHintXNegative) signX = << 
1232     if (fWindowLocationHintYNegative) signY = << 
1233     std::ostringstream oss;                      1178     std::ostringstream oss;
1234     oss << fWindowSizeHintX << 'x' << fWindow << 1179     oss << size << 'x' << size;
1235     << signX << fWindowLocationHintX << signY << 1180     geomString = oss.str();
1236     fXGeometryString = oss.str();             << 
1237     return;                                   << 
1238   }                                              1181   }
1239                                               << 1182  
1240   // Assume it's a parseable X geometry strin << 
1241   G4int x = 0, y = 0;                         << 
1242   unsigned int w = 0, h = 0;                  << 
1243   fGeometryMask = ParseGeometry( geomString,     1183   fGeometryMask = ParseGeometry( geomString, &x, &y, &w, &h );
1244                                                  1184 
1245   // Handle special case :                       1185   // Handle special case :
1246   if ((fGeometryMask & fYValue) == 0)            1186   if ((fGeometryMask & fYValue) == 0)
1247     {  // Using default                          1187     {  // Using default
1248       y =  fWindowLocationHintY;                 1188       y =  fWindowLocationHintY;
1249     }                                            1189     }
1250   if ((fGeometryMask & fXValue) == 0)            1190   if ((fGeometryMask & fXValue) == 0)
1251     {  // Using default                          1191     {  // Using default
1252       x =  fWindowLocationHintX;                 1192       x =  fWindowLocationHintX;
1253     }                                            1193     }
1254                                                  1194 
1255   // Check errors                                1195   // Check errors
1256   // if there is no Width and Height             1196   // if there is no Width and Height
1257   if ( ((fGeometryMask & fHeightValue) == 0 )    1197   if ( ((fGeometryMask & fHeightValue) == 0 ) &&
1258        ((fGeometryMask & fWidthValue)  == 0 )    1198        ((fGeometryMask & fWidthValue)  == 0 )) {
1259     h = fWindowSizeHintY;                        1199     h = fWindowSizeHintY;
1260     w = fWindowSizeHintX;                        1200     w = fWindowSizeHintX;
1261   } else  if ((fGeometryMask & fHeightValue)     1201   } else  if ((fGeometryMask & fHeightValue) == 0 ) {
1262                                                  1202 
1263     // if there is only Width. Special case t    1203     // if there is only Width. Special case to be backward compatible
1264     // We set Width and Height the same to ob    1204     // We set Width and Height the same to obtain a square windows.
1265                                                  1205     
1266     G4warn << "Unrecognised geometry string \ << 1206     G4cout << "Unrecognised geometry string \""
1267            << geomString                         1207            << geomString
1268            << "\".  No Height found. Using Wi    1208            << "\".  No Height found. Using Width value instead"
1269            << G4endl;                            1209            << G4endl;
1270     h = w;                                       1210     h = w;
1271   }                                              1211   }
1272   if ( ((fGeometryMask & fXValue) == 0 ) ||      1212   if ( ((fGeometryMask & fXValue) == 0 ) ||
1273        ((fGeometryMask & fYValue)  == 0 )) {     1213        ((fGeometryMask & fYValue)  == 0 )) {
1274     //Using defaults                             1214     //Using defaults
1275     x = fWindowLocationHintX;                    1215     x = fWindowLocationHintX;
1276     y = fWindowLocationHintY;                    1216     y = fWindowLocationHintY;
1277   }                                              1217   }
1278   // Set the string                              1218   // Set the string
1279   fXGeometryString = geomString;                 1219   fXGeometryString = geomString;
1280                                                  1220   
1281   // Set values                                  1221   // Set values
1282   fWindowSizeHintX = w;                          1222   fWindowSizeHintX = w;
1283   fWindowSizeHintY = h;                          1223   fWindowSizeHintY = h;
1284   fWindowLocationHintX = x;                      1224   fWindowLocationHintX = x;
1285   fWindowLocationHintY = y;                      1225   fWindowLocationHintY = y;
1286                                                  1226 
1287   if ( ((fGeometryMask & fXValue)) &&            1227   if ( ((fGeometryMask & fXValue)) &&
1288        ((fGeometryMask & fYValue))) {            1228        ((fGeometryMask & fYValue))) {
1289                                                  1229 
1290     if ( (fGeometryMask & fXNegative) ) {        1230     if ( (fGeometryMask & fXNegative) ) {
1291       fWindowLocationHintXNegative = true;       1231       fWindowLocationHintXNegative = true;
1292     } else {                                     1232     } else {
1293       fWindowLocationHintXNegative = false;      1233       fWindowLocationHintXNegative = false;
1294     }                                            1234     }
1295     if ( (fGeometryMask & fYNegative) ) {        1235     if ( (fGeometryMask & fYNegative) ) {
1296     fWindowLocationHintYNegative = true;         1236     fWindowLocationHintYNegative = true;
1297     } else {                                     1237     } else {
1298       fWindowLocationHintYNegative = false;      1238       fWindowLocationHintYNegative = false;
1299     }                                            1239     }
1300   }                                              1240   }
1301 }                                                1241 }
1302                                                  1242 
1303 G4int G4ViewParameters::GetWindowAbsoluteLoca    1243 G4int G4ViewParameters::GetWindowAbsoluteLocationHintX (G4int sizeX ) const {
1304   if ( fWindowLocationHintXNegative ) {          1244   if ( fWindowLocationHintXNegative ) {
1305     return  sizeX  + fWindowLocationHintX - f    1245     return  sizeX  + fWindowLocationHintX - fWindowSizeHintX;
1306   }                                              1246   }
1307   return fWindowLocationHintX;                   1247   return fWindowLocationHintX;
1308 }                                                1248 }
1309                                                  1249 
1310 G4int G4ViewParameters::GetWindowAbsoluteLoca    1250 G4int G4ViewParameters::GetWindowAbsoluteLocationHintY (G4int sizeY ) const {
1311   if (  fWindowLocationHintYNegative ) {         1251   if (  fWindowLocationHintYNegative ) {
1312     return  sizeY  + fWindowLocationHintY - f    1252     return  sizeY  + fWindowLocationHintY - fWindowSizeHintY;
1313   }                                              1253   }
1314   return fWindowLocationHintY;                   1254   return fWindowLocationHintY;
1315 }                                                1255 }
1316                                                  1256 
1317 /* Keep from :                                   1257 /* Keep from :
1318  * ftp://ftp.trolltech.com/qt/source/qt-embed    1258  * ftp://ftp.trolltech.com/qt/source/qt-embedded-free-3.0.6.tar.gz/qt-embedded-free-3.0.6/src/kernel/qapplication_qws.cpp
1319  *                                               1259  *
1320  *    ParseGeometry parses strings of the for    1260  *    ParseGeometry parses strings of the form
1321  *   "=<width>x<height>{+-}<xoffset>{+-}<yoff    1261  *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
1322  *   width, height, xoffset, and yoffset are     1262  *   width, height, xoffset, and yoffset are unsigned integers.
1323  *   Example:  "=80x24+300-49"                   1263  *   Example:  "=80x24+300-49"
1324  *   The equal sign is optional.                 1264  *   The equal sign is optional.
1325  *   It returns a bitmask that indicates whic    1265  *   It returns a bitmask that indicates which of the four values
1326  *   were actually found in the string. For e    1266  *   were actually found in the string. For each value found,
1327  *   the corresponding argument is updated;      1267  *   the corresponding argument is updated;  for each value
1328  *   not found, the corresponding argument is    1268  *   not found, the corresponding argument is left unchanged.
1329  */                                              1269  */
1330                                                  1270 
1331 int G4ViewParameters::ParseGeometry (            1271 int G4ViewParameters::ParseGeometry (
1332  const char *string,                             1272  const char *string,
1333  G4int *x,                                       1273  G4int *x,
1334  G4int *y,                                       1274  G4int *y,
1335  unsigned int *width,                            1275  unsigned int *width,
1336  unsigned int *height)                           1276  unsigned int *height)
1337 {                                                1277 {
1338                                                  1278 
1339   G4int mask = fNoValue;                         1279   G4int mask = fNoValue;
1340   char *strind;                                  1280   char *strind;
1341   unsigned int tempWidth  = 0;                   1281   unsigned int tempWidth  = 0;
1342   unsigned int tempHeight = 0;                   1282   unsigned int tempHeight = 0;
1343   G4int tempX = 0;                               1283   G4int tempX = 0;
1344   G4int tempY = 0;                               1284   G4int tempY = 0;
1345   char *nextCharacter;                           1285   char *nextCharacter;
1346   if ( (string == NULL) || (*string == '\0'))    1286   if ( (string == NULL) || (*string == '\0')) {
1347     return(mask);                                1287     return(mask);
1348   }                                              1288   }
1349   if (*string == '=')                            1289   if (*string == '=')
1350     string++;  /* ignore possible '=' at beg     1290     string++;  /* ignore possible '=' at beg of geometry spec */
1351   strind = (char *)string;                       1291   strind = (char *)string;
1352   if (*strind != '+' && *strind != '-' && *st    1292   if (*strind != '+' && *strind != '-' && *strind != 'x') {
1353     tempWidth = ReadInteger(strind, &nextChar    1293     tempWidth = ReadInteger(strind, &nextCharacter);
1354     if (strind == nextCharacter)                 1294     if (strind == nextCharacter)
1355       return (0);                                1295       return (0);
1356     strind = nextCharacter;                      1296     strind = nextCharacter;
1357     mask |= fWidthValue;                         1297     mask |= fWidthValue;
1358   }                                              1298   }
1359   if (*strind == 'x' || *strind == 'X') {        1299   if (*strind == 'x' || *strind == 'X') {
1360     strind++;                                    1300     strind++;
1361     tempHeight = ReadInteger(strind, &nextCha    1301     tempHeight = ReadInteger(strind, &nextCharacter);
1362     if (strind == nextCharacter)                 1302     if (strind == nextCharacter)
1363       return (0);                                1303       return (0);
1364     strind = nextCharacter;                      1304     strind = nextCharacter;
1365     mask |= fHeightValue;                        1305     mask |= fHeightValue;
1366   }                                              1306   }
1367                                                  1307 
1368   if ((*strind == '+') || (*strind == '-')) {    1308   if ((*strind == '+') || (*strind == '-')) {
1369     if (*strind == '-') {                        1309     if (*strind == '-') {
1370       strind++;                                  1310       strind++;
1371       tempX = -ReadInteger(strind, &nextChara    1311       tempX = -ReadInteger(strind, &nextCharacter);
1372       if (strind == nextCharacter)               1312       if (strind == nextCharacter)
1373         return (0);                              1313         return (0);
1374       strind = nextCharacter;                    1314       strind = nextCharacter;
1375       mask |= fXNegative;                        1315       mask |= fXNegative;
1376                                                  1316 
1377     }                                            1317     }
1378     else                                         1318     else
1379       { strind++;                                1319       { strind++;
1380         tempX = ReadInteger(strind, &nextChar    1320         tempX = ReadInteger(strind, &nextCharacter);
1381         if (strind == nextCharacter)             1321         if (strind == nextCharacter)
1382           return(0);                             1322           return(0);
1383         strind = nextCharacter;                  1323         strind = nextCharacter;
1384       }                                          1324       }
1385     mask |= fXValue;                             1325     mask |= fXValue;
1386     if ((*strind == '+') || (*strind == '-'))    1326     if ((*strind == '+') || (*strind == '-')) {
1387       if (*strind == '-') {                      1327       if (*strind == '-') {
1388         strind++;                                1328         strind++;
1389         tempY = -ReadInteger(strind, &nextCha    1329         tempY = -ReadInteger(strind, &nextCharacter);
1390         if (strind == nextCharacter)             1330         if (strind == nextCharacter)
1391           return(0);                             1331           return(0);
1392         strind = nextCharacter;                  1332         strind = nextCharacter;
1393         mask |= fYNegative;                      1333         mask |= fYNegative;
1394       }                                          1334       }
1395       else                                       1335       else
1396         {                                        1336         {
1397           strind++;                              1337           strind++;
1398           tempY = ReadInteger(strind, &nextCh    1338           tempY = ReadInteger(strind, &nextCharacter);
1399           if (strind == nextCharacter)           1339           if (strind == nextCharacter)
1400             return(0);                           1340             return(0);
1401           strind = nextCharacter;                1341           strind = nextCharacter;
1402         }                                        1342         }
1403       mask |= fYValue;                           1343       mask |= fYValue;
1404     }                                            1344     }
1405   }                                              1345   }
1406   /* If strind isn't at the end of the string    1346   /* If strind isn't at the end of the string the it's an invalid
1407      geometry specification. */                  1347      geometry specification. */
1408   if (*strind != '\0') return (0);               1348   if (*strind != '\0') return (0);
1409   if (mask & fXValue)                            1349   if (mask & fXValue)
1410     *x = tempX;                                  1350     *x = tempX;
1411   if (mask & fYValue)                            1351   if (mask & fYValue)
1412     *y = tempY;                                  1352     *y = tempY;
1413   if (mask & fWidthValue)                        1353   if (mask & fWidthValue)
1414     *width = tempWidth;                          1354     *width = tempWidth;
1415   if (mask & fHeightValue)                       1355   if (mask & fHeightValue)
1416     *height = tempHeight;                        1356     *height = tempHeight;
1417   return (mask);                                 1357   return (mask);
1418 }                                                1358 }
1419                                                  1359 
1420 /* Keep from :                                   1360 /* Keep from :
1421  * ftp://ftp.trolltech.com/qt/source/qt-embed    1361  * ftp://ftp.trolltech.com/qt/source/qt-embedded-free-3.0.6.tar.gz/qt-embedded-free-3.0.6/src/kernel/qapplication_qws.cpp
1422  *                                               1362  *
1423  */                                              1363  */
1424 G4int G4ViewParameters::ReadInteger(char *str    1364 G4int G4ViewParameters::ReadInteger(char *string, char **NextString)
1425 {                                                1365 {
1426     G4int Result = 0;                            1366     G4int Result = 0;
1427     G4int Sign = 1;                              1367     G4int Sign = 1;
1428                                                  1368 
1429     if (*string == '+')                          1369     if (*string == '+')
1430   string++;                                      1370   string++;
1431     else if (*string == '-')                     1371     else if (*string == '-')
1432     {                                            1372     {
1433   string++;                                      1373   string++;
1434   Sign = -1;                                     1374   Sign = -1;
1435     }                                            1375     }
1436     for (; (*string >= '0') && (*string <= '9    1376     for (; (*string >= '0') && (*string <= '9'); string++)
1437     {                                            1377     {
1438   Result = (Result * 10) + (*string - '0');      1378   Result = (Result * 10) + (*string - '0');
1439     }                                            1379     }
1440     *NextString = string;                        1380     *NextString = string;
1441     if (Sign >= 0)                               1381     if (Sign >= 0)
1442   return (Result);                               1382   return (Result);
1443     else                                         1383     else
1444   return (-Result);                              1384   return (-Result);
1445 }                                                1385 }
1446                                                  1386 
1447 G4ViewParameters* G4ViewParameters::CatmullRo    1387 G4ViewParameters* G4ViewParameters::CatmullRomCubicSplineInterpolation
1448 (const std::vector<G4ViewParameters>& views,     1388 (const std::vector<G4ViewParameters>& views,
1449  G4int nInterpolationPoints)  // No of interp    1389  G4int nInterpolationPoints)  // No of interpolations points per interval
1450 {                                                1390 {
1451   // Returns a null pointer when no more to b    1391   // Returns a null pointer when no more to be done.  For example:
1452   // do {                                        1392   // do {
1453   //   G4ViewParameters* vp =                    1393   //   G4ViewParameters* vp =
1454   //   G4ViewParameters::CatmullRomCubicSplin    1394   //   G4ViewParameters::CatmullRomCubicSplineInterpolation(viewVector,nInterpolationPoints);
1455   //   if (!vp) break;                           1395   //   if (!vp) break;
1456   //     ...                                     1396   //     ...
1457   // } while (true);                             1397   // } while (true);
1458                                                  1398 
1459   // See https://en.wikipedia.org/wiki/Cubic_    1399   // See https://en.wikipedia.org/wiki/Cubic_Hermite_spline
1460                                                  1400 
1461   // Assumes equal intervals                     1401   // Assumes equal intervals
1462                                                  1402 
1463   if (views.size() < 2) {                        1403   if (views.size() < 2) {
1464     G4Exception                                  1404     G4Exception
1465     ("G4ViewParameters::CatmullRomCubicSpline    1405     ("G4ViewParameters::CatmullRomCubicSplineInterpolation",
1466      "visman0301", JustWarning,                  1406      "visman0301", JustWarning,
1467      "There must be at least two views.");       1407      "There must be at least two views.");
1468     return 0;                                    1408     return 0;
1469   }                                              1409   }
1470                                                  1410 
1471   if (nInterpolationPoints < 1) {                1411   if (nInterpolationPoints < 1) {
1472     G4Exception                                  1412     G4Exception
1473     ("G4ViewParameters::CatmullRomCubicSpline    1413     ("G4ViewParameters::CatmullRomCubicSplineInterpolation",
1474      "visman0302", JustWarning,                  1414      "visman0302", JustWarning,
1475      "Number of interpolation points cannot b    1415      "Number of interpolation points cannot be zero or negative.");
1476     return 0;                                    1416     return 0;
1477   }                                              1417   }
1478                                                  1418 
1479   const size_t nIntervals = views.size() - 1;    1419   const size_t nIntervals = views.size() - 1;
1480   const G4double dt = 1./nInterpolationPoints    1420   const G4double dt = 1./nInterpolationPoints;
1481                                                  1421 
1482   static G4ViewParameters holdingValues;         1422   static G4ViewParameters holdingValues;
1483   static G4double t = 0.;  // 0. <= t <= 1.      1423   static G4double t = 0.;  // 0. <= t <= 1.
1484   static G4int iInterpolationPoint = 0;          1424   static G4int iInterpolationPoint = 0;
1485   static size_t iInterval = 0;                   1425   static size_t iInterval = 0;
1486                                                  1426 
1487 //  G4cout << "Interval " << iInterval << ",     1427 //  G4cout << "Interval " << iInterval << ", t = " << t << G4endl;
1488                                                  1428 
1489   // Hermite polynomials.                        1429   // Hermite polynomials.
1490   const G4double h00 = 2.*t*t*t - 3.*t*t +1;     1430   const G4double h00 = 2.*t*t*t - 3.*t*t +1;
1491   const G4double h10 = t*t*t -2.*t*t + t;        1431   const G4double h10 = t*t*t -2.*t*t + t;
1492   const G4double h01 = -2.*t*t*t + 3.*t*t;       1432   const G4double h01 = -2.*t*t*t + 3.*t*t;
1493   const G4double h11 = t*t*t - t*t;              1433   const G4double h11 = t*t*t - t*t;
1494                                                  1434 
1495   // Aliases (to simplify code)                  1435   // Aliases (to simplify code)
1496   const size_t& n = nIntervals;                  1436   const size_t& n = nIntervals;
1497   size_t& i = iInterval;                         1437   size_t& i = iInterval;
1498   const std::vector<G4ViewParameters>& v = vi    1438   const std::vector<G4ViewParameters>& v = views;
1499                                                  1439 
1500   // The Catmull-Rom cubic spline prescriptio    1440   // The Catmull-Rom cubic spline prescription is as follows:
1501   // Slope at first way point is v[1] - v[0].    1441   // Slope at first way point is v[1] - v[0].
1502   // Slope at last way point is v[n] - v[n-1]    1442   // Slope at last way point is v[n] - v[n-1].
1503   // Otherwise slope at way point i is 0.5*(v    1443   // Otherwise slope at way point i is 0.5*(v[i+1] - v[i-1]).
1504   // Result = h00*v[i] + h10*m[i] + h01*v[i+1    1444   // Result = h00*v[i] + h10*m[i] + h01*v[i+1] + h11*m[i+1],
1505   // where m[i] amd m[i+1] are the slopes at     1445   // where m[i] amd m[i+1] are the slopes at the start and end
1506   // of the interval for the particular value    1446   // of the interval for the particular value.
1507   // If (n == 1), linear interpolation result    1447   // If (n == 1), linear interpolation results.
1508   // If (n == 2), quadratic interpolation res    1448   // If (n == 2), quadratic interpolation results.
1509                                                  1449 
1510   // Working variables                           1450   // Working variables
1511   G4double mi, mi1, real, x, y, z;               1451   G4double mi, mi1, real, x, y, z;
1512                                                  1452   
1513   // First, a crude interpolation of all para    1453   // First, a crude interpolation of all parameters.  Then, below, a
1514   // smooth interpolation of those for which     1454   // smooth interpolation of those for which it makes sense.
1515   holdingValues = t < 0.5? v[i]: v[i+1];         1455   holdingValues = t < 0.5? v[i]: v[i+1];
1516                                                  1456 
1517   // Catmull-Rom cubic spline interpolation      1457   // Catmull-Rom cubic spline interpolation
1518 #define INTERPOLATE(param) \                     1458 #define INTERPOLATE(param) \
1519 /* This works out the interpolated param in i    1459 /* This works out the interpolated param in i'th interval */ \
1520 /* Assumes n >= 1 */ \                           1460 /* Assumes n >= 1 */ \
1521 if (i == 0) { \                                  1461 if (i == 0) { \
1522 /* First interval */ \                           1462 /* First interval */ \
1523 mi = v[1].param - v[0].param; \                  1463 mi = v[1].param - v[0].param; \
1524 /* If there is only one interval, make start     1464 /* If there is only one interval, make start and end slopes equal */ \
1525 /* (This results in a linear interpolation) *    1465 /* (This results in a linear interpolation) */ \
1526 if (n == 1) mi1 = mi; \                          1466 if (n == 1) mi1 = mi; \
1527 /* else the end slope of the interval takes a    1467 /* else the end slope of the interval takes account of the next waypoint along */ \
1528 else mi1 = 0.5 * (v[2].param - v[0].param); \    1468 else mi1 = 0.5 * (v[2].param - v[0].param); \
1529 } else if (i >= n - 1) { \                       1469 } else if (i >= n - 1) { \
1530 /* Similarly for last interval */ \              1470 /* Similarly for last interval */ \
1531 mi1 = v[i+1].param - v[i].param; \               1471 mi1 = v[i+1].param - v[i].param; \
1532 /* If there is only one interval, make start     1472 /* If there is only one interval, make start and end slopes equal */ \
1533 if (n == 1) mi = mi1; \                          1473 if (n == 1) mi = mi1; \
1534 /* else the start slope of the interval takes    1474 /* else the start slope of the interval takes account of the previous waypoint */ \
1535 else mi = 0.5 * (v[i+1].param - v[i-1].param)    1475 else mi = 0.5 * (v[i+1].param - v[i-1].param); \
1536 } else { \                                       1476 } else { \
1537 /* Full Catmull-Rom slopes use previous AND n    1477 /* Full Catmull-Rom slopes use previous AND next waypoints */ \
1538 mi  = 0.5 * (v[i+1].param - v[i-1].param); \     1478 mi  = 0.5 * (v[i+1].param - v[i-1].param); \
1539 mi1 = 0.5 * (v[i+2].param - v[i  ].param); \     1479 mi1 = 0.5 * (v[i+2].param - v[i  ].param); \
1540 } \                                              1480 } \
1541 real = h00 * v[i].param + h10 * mi + h01 * v[    1481 real = h00 * v[i].param + h10 * mi + h01 * v[i+1].param + h11 * mi1;
1542                                                  1482 
1543 #define INTERPOLATELOG(param) \                  1483 #define INTERPOLATELOG(param) \
1544 if (i == 0) { \                                  1484 if (i == 0) { \
1545 mi = std::log(v[1].param) - std::log(v[0].par    1485 mi = std::log(v[1].param) - std::log(v[0].param); \
1546 if (n == 1) mi1 = mi; \                          1486 if (n == 1) mi1 = mi; \
1547 else mi1 = 0.5 * (std::log(v[2].param) - std:    1487 else mi1 = 0.5 * (std::log(v[2].param) - std::log(v[0].param)); \
1548 } else if (i >= n - 1) { \                       1488 } else if (i >= n - 1) { \
1549 mi1 = std::log(v[i+1].param) - std::log(v[i].    1489 mi1 = std::log(v[i+1].param) - std::log(v[i].param); \
1550 if (n == 1) mi = mi1; \                          1490 if (n == 1) mi = mi1; \
1551 else mi = 0.5 * (std::log(v[i+1].param) - std    1491 else mi = 0.5 * (std::log(v[i+1].param) - std::log(v[i-1].param)); \
1552 } else { \                                       1492 } else { \
1553 mi  = 0.5 * (std::log(v[i+1].param) - std::lo    1493 mi  = 0.5 * (std::log(v[i+1].param) - std::log(v[i-1].param)); \
1554 mi1 = 0.5 * (std::log(v[i+2].param) - std::lo    1494 mi1 = 0.5 * (std::log(v[i+2].param) - std::log(v[i  ].param)); \
1555 } \                                              1495 } \
1556 real = std::exp(h00 * std::log(v[i].param) +     1496 real = std::exp(h00 * std::log(v[i].param) + h10 * mi + h01 * std::log(v[i+1].param) + h11 * mi1);
1557                                                  1497 
1558   // Real parameters                             1498   // Real parameters
1559   INTERPOLATE(fVisibleDensity);                  1499   INTERPOLATE(fVisibleDensity);
1560   if (real < 0.) real = 0.;                      1500   if (real < 0.) real = 0.;
1561   holdingValues.fVisibleDensity = real;          1501   holdingValues.fVisibleDensity = real;
1562   INTERPOLATELOG(fExplodeFactor);                1502   INTERPOLATELOG(fExplodeFactor);
1563   holdingValues.fExplodeFactor = real;           1503   holdingValues.fExplodeFactor = real;
1564   INTERPOLATE(fFieldHalfAngle);                  1504   INTERPOLATE(fFieldHalfAngle);
1565   if (real < 0.) real = 0.;                      1505   if (real < 0.) real = 0.;
1566   holdingValues.fFieldHalfAngle = real;          1506   holdingValues.fFieldHalfAngle = real;
1567   INTERPOLATELOG(fZoomFactor);                   1507   INTERPOLATELOG(fZoomFactor);
1568   holdingValues.fZoomFactor = real;              1508   holdingValues.fZoomFactor = real;
1569   INTERPOLATE(fDolly);                           1509   INTERPOLATE(fDolly);
1570   holdingValues.fDolly = real;                   1510   holdingValues.fDolly = real;
1571   INTERPOLATE(fGlobalMarkerScale);               1511   INTERPOLATE(fGlobalMarkerScale);
1572   if (real < 0.) real = 0.;                      1512   if (real < 0.) real = 0.;
1573   holdingValues.fGlobalMarkerScale = real;       1513   holdingValues.fGlobalMarkerScale = real;
1574   INTERPOLATE(fGlobalLineWidthScale);            1514   INTERPOLATE(fGlobalLineWidthScale);
1575   if (real < 0.) real = 0.;                      1515   if (real < 0.) real = 0.;
1576   holdingValues.fGlobalLineWidthScale = real;    1516   holdingValues.fGlobalLineWidthScale = real;
1577                                                  1517 
1578   // Unit vectors                                1518   // Unit vectors
1579 #define INTERPOLATEUNITVECTOR(vector) \          1519 #define INTERPOLATEUNITVECTOR(vector) \
1580 INTERPOLATE(vector.x()); x = real; \             1520 INTERPOLATE(vector.x()); x = real; \
1581 INTERPOLATE(vector.y()); y = real; \             1521 INTERPOLATE(vector.y()); y = real; \
1582 INTERPOLATE(vector.z()); z = real;               1522 INTERPOLATE(vector.z()); z = real;
1583   INTERPOLATEUNITVECTOR(fViewpointDirection);    1523   INTERPOLATEUNITVECTOR(fViewpointDirection);
1584   holdingValues.fViewpointDirection              1524   holdingValues.fViewpointDirection          = G4Vector3D(x,y,z).unit();
1585   INTERPOLATEUNITVECTOR(fUpVector);              1525   INTERPOLATEUNITVECTOR(fUpVector);
1586   holdingValues.fUpVector                        1526   holdingValues.fUpVector                    = G4Vector3D(x,y,z).unit();
1587   INTERPOLATEUNITVECTOR(fRelativeLightpointDi    1527   INTERPOLATEUNITVECTOR(fRelativeLightpointDirection);
1588   holdingValues.fRelativeLightpointDirection     1528   holdingValues.fRelativeLightpointDirection = G4Vector3D(x,y,z).unit();
1589   INTERPOLATEUNITVECTOR(fActualLightpointDire    1529   INTERPOLATEUNITVECTOR(fActualLightpointDirection);
1590   holdingValues.fActualLightpointDirection       1530   holdingValues.fActualLightpointDirection   = G4Vector3D(x,y,z).unit();
1591                                                  1531 
1592   // Un-normalised vectors                       1532   // Un-normalised vectors
1593 #define INTERPOLATEVECTOR(vector) \              1533 #define INTERPOLATEVECTOR(vector) \
1594 INTERPOLATE(vector.x()); x = real; \             1534 INTERPOLATE(vector.x()); x = real; \
1595 INTERPOLATE(vector.y()); y = real; \             1535 INTERPOLATE(vector.y()); y = real; \
1596 INTERPOLATE(vector.z()); z = real;               1536 INTERPOLATE(vector.z()); z = real;
1597   INTERPOLATEVECTOR(fScaleFactor);               1537   INTERPOLATEVECTOR(fScaleFactor);
1598   holdingValues.fScaleFactor = G4Vector3D(x,y    1538   holdingValues.fScaleFactor = G4Vector3D(x,y,z);
1599                                                  1539 
1600   // Points                                      1540   // Points
1601 #define INTERPOLATEPOINT(point) \                1541 #define INTERPOLATEPOINT(point) \
1602 INTERPOLATE(point.x()); x = real; \              1542 INTERPOLATE(point.x()); x = real; \
1603 INTERPOLATE(point.y()); y = real; \              1543 INTERPOLATE(point.y()); y = real; \
1604 INTERPOLATE(point.z()); z = real;                1544 INTERPOLATE(point.z()); z = real;
1605   INTERPOLATEPOINT(fExplodeCentre);              1545   INTERPOLATEPOINT(fExplodeCentre);
1606   holdingValues.fExplodeCentre      = G4Point    1546   holdingValues.fExplodeCentre      = G4Point3D(x,y,z);
1607   INTERPOLATEPOINT(fCurrentTargetPoint);         1547   INTERPOLATEPOINT(fCurrentTargetPoint);
1608   holdingValues.fCurrentTargetPoint = G4Point    1548   holdingValues.fCurrentTargetPoint = G4Point3D(x,y,z);
1609                                                  1549 
1610   // Colour                                      1550   // Colour
1611   G4double red, green, blue, alpha;              1551   G4double red, green, blue, alpha;
1612 #define INTERPOLATECOLOUR(colour) \              1552 #define INTERPOLATECOLOUR(colour) \
1613 INTERPOLATE(colour.GetRed());   red   = real;    1553 INTERPOLATE(colour.GetRed());   red   = real; \
1614 INTERPOLATE(colour.GetGreen()); green = real;    1554 INTERPOLATE(colour.GetGreen()); green = real; \
1615 INTERPOLATE(colour.GetBlue());  blue  = real;    1555 INTERPOLATE(colour.GetBlue());  blue  = real; \
1616 INTERPOLATE(colour.GetAlpha()); alpha = real;    1556 INTERPOLATE(colour.GetAlpha()); alpha = real;
1617   INTERPOLATECOLOUR(fBackgroundColour);          1557   INTERPOLATECOLOUR(fBackgroundColour);
1618   // Components are clamped to 0. <= componen    1558   // Components are clamped to 0. <= component <= 1.
1619   holdingValues.fBackgroundColour = G4Colour(    1559   holdingValues.fBackgroundColour = G4Colour(red,green,blue,alpha);
1620                                                  1560 
1621   // For some parameters we need to check som    1561   // For some parameters we need to check some continuity
1622   G4bool continuous;                             1562   G4bool continuous;
1623 #define CONTINUITY(quantity) \                   1563 #define CONTINUITY(quantity) \
1624   continuous = false; \                          1564   continuous = false; \
1625   /* This follows the logic of the INTERPOLAT    1565   /* This follows the logic of the INTERPOLATE macro above; see comments therein */ \
1626   if (i == 0) { \                                1566   if (i == 0) { \
1627     if (v[1].quantity == v[0].quantity) { \      1567     if (v[1].quantity == v[0].quantity) { \
1628        if (n == 1) continuous = true; \          1568        if (n == 1) continuous = true; \
1629        else if (v[2].quantity == v[0].quantit    1569        else if (v[2].quantity == v[0].quantity) \
1630        continuous = true; \                      1570        continuous = true; \
1631     } \                                          1571     } \
1632   } else if (i >= n - 1) { \                     1572   } else if (i >= n - 1) { \
1633     if (v[i+1].quantity == v[i].quantity) { \    1573     if (v[i+1].quantity == v[i].quantity) { \
1634       if (n == 1) continuous = true; \           1574       if (n == 1) continuous = true; \
1635       else if (v[i+1].quantity == v[i-1].quan    1575       else if (v[i+1].quantity == v[i-1].quantity) \
1636       continuous = true; \                       1576       continuous = true; \
1637     } \                                          1577     } \
1638   } else { \                                     1578   } else { \
1639     if (v[i-1].quantity == v[i].quantity && \    1579     if (v[i-1].quantity == v[i].quantity && \
1640         v[i+1].quantity == v[i].quantity && \    1580         v[i+1].quantity == v[i].quantity && \
1641         v[i+2].quantity == v[i].quantity) \      1581         v[i+2].quantity == v[i].quantity) \
1642     continuous = true; \                         1582     continuous = true; \
1643   }                                              1583   }
1644                                                  1584 
1645   G4double a, b, c, d;                           1585   G4double a, b, c, d;
1646 #define INTERPOLATEPLANE(plane) \                1586 #define INTERPOLATEPLANE(plane) \
1647 INTERPOLATE(plane.a()); a = real; \              1587 INTERPOLATE(plane.a()); a = real; \
1648 INTERPOLATE(plane.b()); b = real; \              1588 INTERPOLATE(plane.b()); b = real; \
1649 INTERPOLATE(plane.c()); c = real; \              1589 INTERPOLATE(plane.c()); c = real; \
1650 INTERPOLATE(plane.d()); d = real;                1590 INTERPOLATE(plane.d()); d = real;
1651                                                  1591 
1652   // Section plane                               1592   // Section plane
1653   CONTINUITY(fSection);                          1593   CONTINUITY(fSection);
1654   if (continuous) {                              1594   if (continuous) {
1655     INTERPOLATEPLANE(fSectionPlane);             1595     INTERPOLATEPLANE(fSectionPlane);
1656     holdingValues.fSectionPlane = G4Plane3D(a    1596     holdingValues.fSectionPlane = G4Plane3D(a,b,c,d);
1657   }                                              1597   }
1658                                                  1598 
1659   // Cutaway planes                              1599   // Cutaway planes
1660   if (v[i].fCutawayPlanes.size()) {              1600   if (v[i].fCutawayPlanes.size()) {
1661     CONTINUITY(fCutawayPlanes.size());           1601     CONTINUITY(fCutawayPlanes.size());
1662     if (continuous) {                            1602     if (continuous) {
1663       for (size_t j = 0; j < v[i].fCutawayPla    1603       for (size_t j = 0; j < v[i].fCutawayPlanes.size(); ++j) {
1664         INTERPOLATEPLANE(fCutawayPlanes[j]);     1604         INTERPOLATEPLANE(fCutawayPlanes[j]);
1665         holdingValues.fCutawayPlanes[j] = G4P    1605         holdingValues.fCutawayPlanes[j] = G4Plane3D(a,b,c,d);
1666       }                                          1606       }
1667     }                                            1607     }
1668   }                                              1608   }
1669                                                  1609 
1670   // Vis attributes modifiers                    1610   // Vis attributes modifiers
1671   // Really, we are only interested in colour    1611   // Really, we are only interested in colour - other attributes can follow
1672   // the "crude" interpolation that is guaran    1612   // the "crude" interpolation that is guaranteed above.
1673   static G4VisAttributes workingVA;              1613   static G4VisAttributes workingVA;
1674   if  (v[i].fVisAttributesModifiers.size()) {    1614   if  (v[i].fVisAttributesModifiers.size()) {
1675     CONTINUITY(fVisAttributesModifiers.size()    1615     CONTINUITY(fVisAttributesModifiers.size());
1676     if (continuous) {                            1616     if (continuous) {
1677       for (size_t j = 0; j < v[i].fVisAttribu    1617       for (size_t j = 0; j < v[i].fVisAttributesModifiers.size(); ++j) {
1678         CONTINUITY(fVisAttributesModifiers[j]    1618         CONTINUITY(fVisAttributesModifiers[j].GetPVNameCopyNoPath());
1679         if (continuous) {                        1619         if (continuous) {
1680           CONTINUITY(fVisAttributesModifiers[    1620           CONTINUITY(fVisAttributesModifiers[j].GetVisAttributesSignifier());
1681           if (continuous) {                      1621           if (continuous) {
1682             if (v[i].fVisAttributesModifiers[    1622             if (v[i].fVisAttributesModifiers[j].GetVisAttributesSignifier() ==
1683                 G4ModelingParameters::VASColo    1623                 G4ModelingParameters::VASColour) {
1684               INTERPOLATECOLOUR(fVisAttribute    1624               INTERPOLATECOLOUR(fVisAttributesModifiers[j].GetVisAttributes().GetColour());
1685               workingVA = v[i].fVisAttributes    1625               workingVA = v[i].fVisAttributesModifiers[j].GetVisAttributes();
1686               workingVA.SetColour(G4Colour(re    1626               workingVA.SetColour(G4Colour(red,green,blue,alpha));
1687               holdingValues.fVisAttributesMod    1627               holdingValues.fVisAttributesModifiers[j].SetVisAttributes(workingVA);
1688             }                                    1628             }
1689           }                                      1629           }
1690         }                                        1630         }
1691       }                                          1631       }
1692     }                                            1632     }
1693   }                                              1633   }
1694                                                  1634 
1695   // Time window parameters (for showing part    1635   // Time window parameters (for showing particles in flight)
1696   // Only two parameters are interpolated. Th    1636   // Only two parameters are interpolated. The others are usually chosen
1697   // once and for all by the user for a given    1637   // once and for all by the user for a given series of views - or at least,
1698   // if not, they will be interpolated by the    1638   // if not, they will be interpolated by the default "crude" method above.
1699   INTERPOLATE(fStartTime)                        1639   INTERPOLATE(fStartTime)
1700   holdingValues.fStartTime = real;               1640   holdingValues.fStartTime = real;
1701   INTERPOLATE(fEndTime)                          1641   INTERPOLATE(fEndTime)
1702   holdingValues.fEndTime = real;                 1642   holdingValues.fEndTime = real;
1703                                                  1643 
1704   // Increment counters                          1644   // Increment counters
1705   iInterpolationPoint++;                         1645   iInterpolationPoint++;
1706   t += dt;                                       1646   t += dt;
1707   if (iInterpolationPoint > nInterpolationPoi    1647   if (iInterpolationPoint > nInterpolationPoints) {
1708     iInterpolationPoint = 1;  // Ready for ne    1648     iInterpolationPoint = 1;  // Ready for next interval.
1709     t = dt;                                      1649     t = dt;
1710     iInterval++;                                 1650     iInterval++;
1711   }                                              1651   }
1712   if (iInterval >= nIntervals) {                 1652   if (iInterval >= nIntervals) {
1713     iInterpolationPoint = 0;  // Ready for a     1653     iInterpolationPoint = 0;  // Ready for a complete restart.
1714     t = 0.;                                      1654     t = 0.;
1715     iInterval = 0;                               1655     iInterval = 0;
1716     return 0;                                    1656     return 0;
1717   }                                              1657   }
1718                                                  1658 
1719   return &holdingValues;                         1659   return &holdingValues;
1720 }                                                1660 }
1721                                                  1661