Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ViewParameters.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id$
28 //
29 //
30 // John Allison 19th July 1996
31 // View parameters and options.
32 
33 #include <sstream>
34 
35 #include "G4ViewParameters.hh"
36 
37 #include "G4VisManager.hh"
38 #include "G4UnitsTable.hh"
39 #include "G4SystemOfUnits.hh"
40 #include "G4ios.hh"
41 
43  fDrawingStyle (wireframe),
44  fAuxEdgeVisible (false),
45  fRepStyle (polyhedron),
46  fCulling (true),
47  fCullInvisible (true),
48  fDensityCulling (false),
49  fVisibleDensity (0.01 * g / cm3),
50  fCullCovered (false),
51  fSection (false),
52  fSectionPlane (),
53  fCutawayMode (cutawayUnion),
54  fCutawayPlanes (),
55  fExplodeFactor (1.),
56  fNoOfSides (24),
57  fViewpointDirection (G4Vector3D (0., 0., 1.)), // On z-axis.
58  fUpVector (G4Vector3D (0., 1., 0.)), // y-axis up.
59  fFieldHalfAngle (0.), // Orthogonal projection.
60  fZoomFactor (1.),
61  fScaleFactor (G4Vector3D (1., 1., 1.)),
62  fCurrentTargetPoint (),
63  fDolly (0.),
64  fLightsMoveWithCamera (false),
65  fRelativeLightpointDirection (G4Vector3D (1., 1., 1.)),
66  fActualLightpointDirection (G4Vector3D (1., 1., 1.)),
67  fDefaultVisAttributes (),
68  fDefaultTextVisAttributes (G4Colour (0., 0., 1.)),
69  fDefaultMarker (),
70  fGlobalMarkerScale (1.),
71  fGlobalLineWidthScale (1.),
72  fMarkerNotHidden (true),
73  fWindowSizeHintX (600),
74  fWindowSizeHintY (600),
75  fWindowLocationHintX(0),
76  fWindowLocationHintY(0),
77  fWindowLocationHintXNegative(true),
78  fWindowLocationHintYNegative(false),
79  fGeometryMask(0),
80  fAutoRefresh (false),
81  fBackgroundColour (G4Colour(0.,0.,0.)), // Black
82  fPicking (false),
83  fRotationStyle (constrainUpDirection)
84 {
85  fDefaultMarker.SetScreenSize (5.);
86  // Markers are 5 pixels "overall" size, i.e., diameter.
87 }
88 
90 
92 (const G4Vector3D& scaleFactorMultiplier) {
93  fScaleFactor.setX(fScaleFactor.x() * scaleFactorMultiplier.x());
94  fScaleFactor.setY(fScaleFactor.y() * scaleFactorMultiplier.y());
95  fScaleFactor.setZ(fScaleFactor.z() * scaleFactorMultiplier.z());
96 }
97 
99  SetViewAndLights (fViewpointDirection);
100  return fActualLightpointDirection;
101 }
102 
103 // Useful quantities - begin snippet.
104 // Here Follow functions to evaluate the above algorithms as a
105 // function of the radius of the Bounding Sphere of the object being
106 // viewed. Call them in the order given - for efficiency, later
107 // functions depend on the results of earlier ones (Store the
108 // results of earlier functions in your own temporary variables -
109 // see, for example, G4OpenGLView::SetView ().)
110 
112  G4double cameraDistance;
113  if (fFieldHalfAngle == 0.) {
114  cameraDistance = radius;
115  }
116  else {
117  cameraDistance = radius / std::sin (fFieldHalfAngle) - fDolly;
118  }
119  return cameraDistance;
120 }
121 
123  G4double radius) const {
124  const G4double small = 1.e-6 * radius;
125  G4double nearDistance = cameraDistance - radius;
126  if (nearDistance < small) nearDistance = small;
127  return nearDistance;
128 }
129 
131  G4double nearDistance,
132  G4double radius) const {
133  G4double farDistance = cameraDistance + radius;
134  if (farDistance < nearDistance) farDistance = nearDistance;
135  return farDistance;
136 }
137 
139  G4double radius) const {
140  G4double frontHalfHeight;
141  if (fFieldHalfAngle == 0.) {
142  frontHalfHeight = radius / fZoomFactor;
143  }
144  else {
145  frontHalfHeight = nearDistance * std::tan (fFieldHalfAngle) / fZoomFactor;
146  }
147  return frontHalfHeight;
148 }
149 // Useful quantities - end snippet.
150 
151 void G4ViewParameters::AddCutawayPlane (const G4Plane3D& cutawayPlane) {
152  if (fCutawayPlanes.size () < 3 ) {
153  fCutawayPlanes.push_back (cutawayPlane);
154  }
155  else {
156  G4cout <<
157  "ERROR: G4ViewParameters::AddCutawayPlane:"
158  "\n A maximum of 3 cutaway planes supported." << G4endl;
159  }
160 }
161 
163 (size_t index, const G4Plane3D& cutawayPlane) {
164  if (index >= fCutawayPlanes.size()) {
165  G4cout <<
166  "ERROR: G4ViewParameters::ChangeCutawayPlane:"
167  "\n Plane " << index << " does not exist." << G4endl;
168  } else {
169  fCutawayPlanes[index] = cutawayPlane;
170  }
171 }
172 
174  const G4double reasonableMaximum = 10.0 * g / cm3;
175  if (visibleDensity < 0) {
176  G4cout << "G4ViewParameters::SetVisibleDensity: attempt to set negative "
177  "density - ignored." << G4endl;
178  }
179  else {
180  if (visibleDensity > reasonableMaximum) {
181  G4cout << "G4ViewParameters::SetVisibleDensity: density > "
182  << G4BestUnit (reasonableMaximum, "Volumic Mass")
183  << " - did you mean this?"
184  << G4endl;
185  }
186  fVisibleDensity = visibleDensity;
187  }
188 }
189 
191  const G4int nSidesMin = 12;
192  if (nSides < nSidesMin) {
193  nSides = nSidesMin;
194  G4cout << "G4ViewParameters::SetNoOfSides: attempt to set the"
195  "\nnumber of sides per circle < " << nSidesMin
196  << "; forced to " << nSides << G4endl;
197  }
198  fNoOfSides = nSides;
199  return fNoOfSides;
200 }
201 
203 (const G4Vector3D& viewpointDirection) {
204 
205  fViewpointDirection = viewpointDirection;
206 
207  // If the requested viewpoint direction is parallel to the up
208  // vector, the orientation of the view is undefined...
209  if (fViewpointDirection.unit() * fUpVector.unit() > .9999) {
210  G4cout <<
211  "WARNING: Viewpoint direction is very close to the up vector direction."
212  "\n Consider setting the up vector to obtain definable behaviour."
213  << G4endl;
214  }
215 
216  // Move the lights too if requested...
217  if (fLightsMoveWithCamera) {
218  G4Vector3D zprime = fViewpointDirection.unit ();
219  G4Vector3D xprime = (fUpVector.cross (zprime)).unit ();
220  G4Vector3D yprime = zprime.cross (xprime);
221  fActualLightpointDirection =
222  fRelativeLightpointDirection.x () * xprime +
223  fRelativeLightpointDirection.y () * yprime +
224  fRelativeLightpointDirection.x () * zprime;
225  } else {
226  fActualLightpointDirection = fRelativeLightpointDirection;
227  }
228 }
229 
231 (const G4Vector3D& lightpointDirection) {
232  fRelativeLightpointDirection = lightpointDirection;
233  SetViewAndLights (fViewpointDirection);
234 }
235 
237  G4Vector3D unitRight = (fUpVector.cross (fViewpointDirection)).unit();
238  G4Vector3D unitUp = (fViewpointDirection.cross (unitRight)).unit();
239  fCurrentTargetPoint = right * unitRight + up * unitUp;
240 }
241 
243  IncrementPan (right,up, 0);
244 }
245 
247  G4Vector3D unitRight = (fUpVector.cross (fViewpointDirection)).unit();
248  G4Vector3D unitUp = (fViewpointDirection.cross (unitRight)).unit();
249  fCurrentTargetPoint += right * unitRight + up * unitUp + distance * fViewpointDirection;
250 }
251 
253 (const G4Point3D standardTargetPoint) const
254 {
255  std::ostringstream oss;
256 
257  oss << "#\n# Camera and lights commands";
258 
259  oss << "\n/vis/viewer/set/viewpointVector "
260  << fViewpointDirection.x()
261  << ' ' << fViewpointDirection.y()
262  << ' ' << fViewpointDirection.z();
263 
264  oss << "\n/vis/viewer/set/upVector "
265  << fUpVector.x()
266  << ' ' << fUpVector.y()
267  << ' ' << fUpVector.z();
268 
269  oss << "\n/vis/viewer/set/projection ";
270  if (fFieldHalfAngle == 0.) {
271  oss
272  << "orthogonal";
273  } else {
274  oss
275  << "perspective "
276  << fFieldHalfAngle/deg
277  << " deg";
278  }
279 
280  oss << "\n/vis/viewer/zoomTo "
281  << fZoomFactor;
282 
283  oss << "\n/vis/viewer/scaleTo "
284  << fScaleFactor.x()
285  << ' ' << fScaleFactor.y()
286  << ' ' << fScaleFactor.z();
287 
288  oss << "\n/vis/viewer/set/targetPoint "
289  << G4BestUnit(standardTargetPoint+fCurrentTargetPoint,"Length")
290  << "\n# Note that if you have not set a target point, the vis system sets"
291  << "\n# a target point based on the scene - plus any panning and dollying -"
292  << "\n# so don't be alarmed by strange coordinates here.";
293 
294  oss << "\n/vis/viewer/dollyTo "
295  << G4BestUnit(fDolly,"Length");
296 
297  oss << "\n/vis/viewer/set/lightsMove ";
298  if (fLightsMoveWithCamera) {
299  oss << "camera";
300  } else {
301  oss << "object";
302  }
303 
304  oss << "\n/vis/viewer/set/lightsVector "
305  << fRelativeLightpointDirection.x()
306  << ' ' << fRelativeLightpointDirection.y()
307  << ' ' << fRelativeLightpointDirection.z();
308 
309  oss << "\n/vis/viewer/set/rotationStyle ";
310  if (fRotationStyle == constrainUpDirection) {
311  oss << "constrainUpDirection";
312  } else {
313  oss << "freeRotation";
314  }
315 
316  G4Colour c = fBackgroundColour;
317  oss << "\n/vis/viewer/set/background "
318  << c.GetRed()
319  << ' ' << c.GetGreen()
320  << ' ' << c.GetBlue()
321  << ' ' << c.GetAlpha();
322 
323  c = fDefaultVisAttributes.GetColour();
324  oss << "\n/vis/viewer/set/defaultColour "
325  << c.GetRed()
326  << ' ' << c.GetGreen()
327  << ' ' << c.GetBlue()
328  << ' ' << c.GetAlpha();
329 
330  c = fDefaultTextVisAttributes.GetColour();
331  oss << "\n/vis/viewer/set/defaultTextColour "
332  << c.GetRed()
333  << ' ' << c.GetGreen()
334  << ' ' << c.GetBlue()
335  << ' ' << c.GetAlpha();
336 
337  oss << std::endl;
338 
339  return oss.str();
340 }
341 
343 {
344  std::ostringstream oss;
345 
346  oss << "#\n# Drawing style commands";
347 
348  oss << "\n/vis/viewer/set/style ";
349  if (fDrawingStyle == wireframe || fDrawingStyle == hlr) {
350  oss << "wireframe";
351  } else {
352  oss << "surface";
353  }
354 
355  oss << "\n/vis/viewer/set/hiddenEdge ";
356  if (fDrawingStyle == hlr || fDrawingStyle == hlhsr) {
357  oss << "true";
358  } else {
359  oss << "false";
360  }
361 
362  oss << "\n/vis/viewer/set/auxiliaryEdge ";
363  if (fAuxEdgeVisible) {
364  oss << "true";
365  } else {
366  oss << "false";
367  }
368 
369  oss << "\n/vis/viewer/set/hiddenMarker ";
370  if (fMarkerNotHidden) {
371  oss << "false";
372  } else {
373  oss << "true";
374  }
375 
376  oss << "\n/vis/viewer/set/globalLineWidthScale "
377  << fGlobalLineWidthScale;
378 
379  oss << "\n/vis/viewer/set/globalMarkerScale "
380  << fGlobalMarkerScale;
381 
382  oss << std::endl;
383 
384  return oss.str();
385 }
386 
388 {
389  std::ostringstream oss;
390 
391  oss << "#\n# Scene-modifying commands";
392 
393  oss << "\n/vis/viewer/set/culling global ";
394  if (fCulling) {
395  oss << "true";
396  } else {
397  oss << "false";
398  }
399 
400  oss << "\n/vis/viewer/set/culling invisible ";
401  if (fCullInvisible) {
402  oss << "true";
403  } else {
404  oss << "false";
405  }
406 
407  oss << "\n/vis/viewer/set/culling density ";
408  if (fDensityCulling) {
409  oss << "true " << fVisibleDensity/(g/cm3) << " g/cm3";
410  } else {
411  oss << "false";
412  }
413 
414  oss << "\n/vis/viewer/set/culling coveredDaughters ";
415  if (fCullCovered) {
416  oss << "true";
417  } else {
418  oss << "false";
419  }
420 
421  oss << "\n/vis/viewer/set/sectionPlane ";
422  if (fSection) {
423  oss << "on "
424  << G4BestUnit(fSectionPlane.point(),"Length")
425  << fSectionPlane.normal().x()
426  << ' ' << fSectionPlane.normal().y()
427  << ' ' << fSectionPlane.normal().z();
428  } else {
429  oss << "off";
430  }
431 
432  oss << "\n/vis/viewer/set/cutawayMode ";
433  if (fCutawayMode == cutawayUnion) {
434  oss << "union";
435  } else {
436  oss << "intersection";
437  }
438 
439  oss << "\n/vis/viewer/clearCutawayPlanes";
440  if (fCutawayPlanes.size()) {
441  for (size_t i = 0; i < fCutawayPlanes.size(); i++) {
442  oss << "\n/vis/viewer/addCutawayPlane "
443  << G4BestUnit(fCutawayPlanes[i].point(),"Length")
444  << fCutawayPlanes[i].normal().x()
445  << ' ' << fCutawayPlanes[i].normal().y()
446  << ' ' << fCutawayPlanes[i].normal().z();
447  }
448  } else {
449  oss << "\n# No cutaway planes defined.";
450  }
451 
452  oss << "\n/vis/viewer/set/explodeFactor "
453  << fExplodeFactor
454  << ' ' << G4BestUnit(fExplodeCentre,"Length");
455 
456  oss << "\n/vis/viewer/set/lineSegmentsPerCircle "
457  << fNoOfSides;
458 
459  oss << std::endl;
460 
461  return oss.str();
462 }
463 
465 {
466  std::ostringstream oss;
467 
468  oss << "#\n# Touchable commands";
469 
470  const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
471  fVisAttributesModifiers;
472 
473  if (vams.empty()) {
474  oss << "\n# None";
475  oss << std::endl;
476  return oss.str();
477  }
478 
479  std::vector<G4ModelingParameters::VisAttributesModifier>::const_iterator
480  iModifier;
481  for (iModifier = vams.begin();
482  iModifier != vams.end();
483  ++iModifier) {
484  oss << "\n/vis/set/touchable";
486  iModifier->GetPVNameCopyNoPath();
488  for (iVAM = vamPath.begin();
489  iVAM != vamPath.end();
490  ++iVAM) {
491  oss << ' ' << iVAM->GetName() << ' ' << iVAM->GetCopyNo();
492  }
493  const G4VisAttributes& vamVisAtts = iModifier->GetVisAttributes();
494  const G4Colour& c = vamVisAtts.GetColour();
495  switch (iModifier->GetVisAttributesSignifier()) {
497  oss << "\n/vis/touchable/set/visibility ";
498  if (vamVisAtts.IsVisible()) {
499  oss << "true";
500  } else {
501  oss << "false";
502  }
503  break;
505  oss << "\n/vis/touchable/set/daughtersInvisible ";
506  if (vamVisAtts.IsDaughtersInvisible()) {
507  oss << "true";
508  } else {
509  oss << "false";
510  }
511  break;
513  oss << "\n/vis/touchable/set/colour "
514  << c.GetRed()
515  << ' ' << c.GetGreen()
516  << ' ' << c.GetBlue()
517  << ' ' << c.GetAlpha();
518  break;
520  oss << "\n/vis/touchable/set/lineStyle ";
521  switch (vamVisAtts.GetLineStyle()) {
523  oss << "unbroken";
524  break;
526  oss << "dashed";
527  break;
529  oss << "dotted";
530  }
531  break;
533  oss << "\n/vis/touchable/set/lineWidth "
534  << vamVisAtts.GetLineWidth();
535  break;
538  oss << "\n/vis/touchable/set/forceWireframe ";
539  if (vamVisAtts.IsForceDrawingStyle()) {
540  oss << "true";
541  } else {
542  oss << "false";
543  }
544  }
545  break;
547  if (vamVisAtts.GetForcedDrawingStyle() == G4VisAttributes::solid) {
548  oss << "\n/vis/touchable/set/forceSolid ";
549  if (vamVisAtts.IsForceDrawingStyle()) {
550  oss << "true";
551  } else {
552  oss << "false";
553  }
554  }
555  break;
557  oss << "\n/vis/touchable/set/forceAuxEdgeVisible ";
558  if (vamVisAtts.IsForceAuxEdgeVisible()) {
559  oss << "true";
560  } else {
561  oss << "false";
562  }
563  break;
565  oss << "\n/vis/touchable/set/lineSegmentsPerCircle "
566  << vamVisAtts.GetForcedLineSegmentsPerCircle();
567  break;
568  }
569  }
570 
571  oss << std::endl;
572 
573  return oss.str();
574 }
575 
577 
578  // Put performance-sensitive parameters first.
579  if (
580  // This first to optimise spin, etc.
581  (fViewpointDirection != v.fViewpointDirection) ||
582 
583  // No particular order from here on.
584  (fDrawingStyle != v.fDrawingStyle) ||
585  (fAuxEdgeVisible != v.fAuxEdgeVisible) ||
586  (fRepStyle != v.fRepStyle) ||
587  (fCulling != v.fCulling) ||
588  (fCullInvisible != v.fCullInvisible) ||
589  (fDensityCulling != v.fDensityCulling) ||
590  (fVisibleDensity != v.fVisibleDensity) ||
591  (fCullCovered != v.fCullCovered) ||
592  (fSection != v.fSection) ||
593  (fNoOfSides != v.fNoOfSides) ||
594  (fUpVector != v.fUpVector) ||
595  (fFieldHalfAngle != v.fFieldHalfAngle) ||
596  (fZoomFactor != v.fZoomFactor) ||
597  (fScaleFactor != v.fScaleFactor) ||
598  (fCurrentTargetPoint != v.fCurrentTargetPoint) ||
599  (fDolly != v.fDolly) ||
600  (fRelativeLightpointDirection != v.fRelativeLightpointDirection) ||
601  (fLightsMoveWithCamera != v.fLightsMoveWithCamera) ||
602  (fDefaultVisAttributes != v.fDefaultVisAttributes) ||
603  (fDefaultTextVisAttributes != v.fDefaultTextVisAttributes) ||
604  (fDefaultMarker != v.fDefaultMarker) ||
605  (fGlobalMarkerScale != v.fGlobalMarkerScale) ||
606  (fGlobalLineWidthScale != v.fGlobalLineWidthScale) ||
607  (fMarkerNotHidden != v.fMarkerNotHidden) ||
608  (fWindowSizeHintX != v.fWindowSizeHintX) ||
609  (fWindowSizeHintY != v.fWindowSizeHintY) ||
610  (fXGeometryString != v.fXGeometryString) ||
611  (fGeometryMask != v.fGeometryMask) ||
612  (fAutoRefresh != v.fAutoRefresh) ||
613  (fBackgroundColour != v.fBackgroundColour) ||
614  (fPicking != v.fPicking) ||
615  (fRotationStyle != v.fRotationStyle)
616  )
617  G4cout << "Difference in 1st batch." << G4endl;
618 
619  if (fSection) {
620  if (!(fSectionPlane == v.fSectionPlane))
621  G4cout << "Difference in section planes batch." << G4endl;
622  }
623 
624  if (IsCutaway()) {
625  if (fCutawayPlanes.size () != v.fCutawayPlanes.size ()) {
626  G4cout << "Difference in no of cutaway planes." << G4endl;
627  }
628  else {
629  for (size_t i = 0; i < fCutawayPlanes.size (); i++) {
630  if (!(fCutawayPlanes[i] == v.fCutawayPlanes[i]))
631  G4cout << "Difference in cutaway plane no. " << i << G4endl;
632  }
633  }
634  }
635 
636  if (IsExplode()) {
637  if (fExplodeFactor != v.fExplodeFactor)
638  G4cout << "Difference in explode factor." << G4endl;
639  if (fExplodeCentre != v.fExplodeCentre)
640  G4cout << "Difference in explode centre." << G4endl;
641  }
642 }
643 
644 std::ostream& operator << (std::ostream& os,
645  const G4ViewParameters::DrawingStyle& style) {
646  switch (style) {
648  os << "wireframe"; break;
650  os << "hlr - hidden lines removed"; break;
652  os << "hsr - hidden surfaces removed"; break;
654  os << "hlhsr - hidden line, hidden surface removed"; break;
655  default: os << "unrecognised"; break;
656  }
657  return os;
658 }
659 
660 std::ostream& operator << (std::ostream& os, const G4ViewParameters& v) {
661  os << "View parameters and options:";
662 
663  os << "\n Drawing style: ";
664  switch (v.fDrawingStyle) {
666  os << "edges, wireframe"; break;
668  os << "edges, hidden line removal"; break;
670  os << "surfaces, hidden surface removal"; break;
672  os << "surfaces and edges, hidden line and surface removal"; break;
673  default: os << "unrecognised"; break;
674  }
675 
676  os << "\n Auxiliary edges: ";
677  if (!v.fAuxEdgeVisible) os << "in";
678  os << "visible";
679 
680  os << "\n Representation style: ";
681  switch (v.fRepStyle) {
683  os << "polyhedron"; break;
685  os << "nurbs"; break;
686  default: os << "unrecognised"; break;
687  }
688 
689  os << "\n Culling: ";
690  if (v.fCulling) os << "on";
691  else os << "off";
692 
693  os << "\n Culling invisible objects: ";
694  if (v.fCullInvisible) os << "on";
695  else os << "off";
696 
697  os << "\n Density culling: ";
698  if (v.fDensityCulling) {
699  os << "on - invisible if density less than "
700  << v.fVisibleDensity / (1. * g / cm3) << " g cm^-3";
701  }
702  else os << "off";
703 
704  os << "\n Culling daughters covered by opaque mothers: ";
705  if (v.fCullCovered) os << "on";
706  else os << "off";
707 
708  os << "\n Section flag: ";
709  if (v.fSection) os << "true, section/cut plane: " << v.fSectionPlane;
710  else os << "false";
711 
712  if (v.IsCutaway()) {
713  os << "\n Cutaway planes: ";
714  for (size_t i = 0; i < v.fCutawayPlanes.size (); i++) {
715  os << ' ' << v.fCutawayPlanes[i];
716  }
717  }
718  else {
719  os << "\n No cutaway planes";
720  }
721 
722  os << "\n Explode factor: " << v.fExplodeFactor
723  << " about centre: " << v.fExplodeCentre;
724 
725  os << "\n No. of sides used in circle polygon approximation: "
726  << v.fNoOfSides;
727 
728  os << "\n Viewpoint direction: " << v.fViewpointDirection;
729 
730  os << "\n Up vector: " << v.fUpVector;
731 
732  os << "\n Field half angle: " << v.fFieldHalfAngle;
733 
734  os << "\n Zoom factor: " << v.fZoomFactor;
735 
736  os << "\n Scale factor: " << v.fScaleFactor;
737 
738  os << "\n Current target point: " << v.fCurrentTargetPoint;
739 
740  os << "\n Dolly distance: " << v.fDolly;
741 
742  os << "\n Light ";
743  if (v.fLightsMoveWithCamera) os << "moves";
744  else os << "does not move";
745  os << " with camera";
746 
747  os << "\n Relative lightpoint direction: "
748  << v.fRelativeLightpointDirection;
749 
750  os << "\n Actual lightpoint direction: "
751  << v.fActualLightpointDirection;
752 
753  os << "\n Derived parameters for standard view of object of unit radius:";
754  G4ViewParameters tempVP = v;
755  tempVP.fDolly = 0.;
756  tempVP.fZoomFactor = 1.;
757  const G4double radius = 1.;
758  const G4double cameraDistance = tempVP.GetCameraDistance (radius);
759  const G4double nearDistance =
760  tempVP.GetNearDistance (cameraDistance, radius);
761  const G4double farDistance =
762  tempVP.GetFarDistance (cameraDistance, nearDistance, radius);
763  const G4double right = tempVP.GetFrontHalfHeight (nearDistance, radius);
764  os << "\n Camera distance: " << cameraDistance;
765  os << "\n Near distance: " << nearDistance;
766  os << "\n Far distance: " << farDistance;
767  os << "\n Front half height: " << right;
768 
769  os << "\n Default VisAttributes:\n " << v.fDefaultVisAttributes;
770 
771  os << "\n Default TextVisAttributes:\n " << v.fDefaultTextVisAttributes;
772 
773  os << "\n Default marker: " << v.fDefaultMarker;
774 
775  os << "\n Global marker scale: " << v.fGlobalMarkerScale;
776 
777  os << "\n Global lineWidth scale: " << v.fGlobalLineWidthScale;
778 
779  os << "\n Marker ";
780  if (v.fMarkerNotHidden) os << "not ";
781  os << "hidden by surfaces.";
782 
783  os << "\n Window size hint: "
784  << v.fWindowSizeHintX << 'x'<< v.fWindowSizeHintX;
785 
786  os << "\n X geometry string: " << v.fXGeometryString;
787  os << "\n X geometry mask: "
788  << std::showbase << std::hex << v.fGeometryMask
789  << std::noshowbase << std::dec;
790 
791  os << "\n Auto refresh: ";
792  if (v.fAutoRefresh) os << "true";
793  else os << "false";
794 
795  os << "\n Background colour: " << v.fBackgroundColour;
796 
797  os << "\n Picking requested: ";
798  if (v.fPicking) os << "true";
799  else os << "false";
800 
801  os << "\n Rotation style: ";
802  switch (v.fRotationStyle) {
804  os << "constrainUpDirection (conventional HEP view)"; break;
806  os << "freeRotation (Google-like rotation, using mouse-grab)"; break;
807  default: os << "unrecognised"; break;
808  }
809 
810  os << "\n Vis attributes modifiers: ";
811  const std::vector<G4ModelingParameters::VisAttributesModifier>& vams =
812  v.fVisAttributesModifiers;
813  if (vams.empty()) {
814  os << "None";
815  } else {
816  os << vams;
817  }
818 
819  return os;
820 }
821 
823 
824  // Put performance-sensitive parameters first.
825  if (
826  // This first to optimise spin, etc.
827  (fViewpointDirection != v.fViewpointDirection) ||
828 
829  // No particular order from here on.
830  (fDrawingStyle != v.fDrawingStyle) ||
831  (fAuxEdgeVisible != v.fAuxEdgeVisible) ||
832  (fRepStyle != v.fRepStyle) ||
833  (fCulling != v.fCulling) ||
834  (fCullInvisible != v.fCullInvisible) ||
835  (fDensityCulling != v.fDensityCulling) ||
836  (fCullCovered != v.fCullCovered) ||
837  (fSection != v.fSection) ||
838  (IsCutaway() != v.IsCutaway()) ||
839  (IsExplode() != v.IsExplode()) ||
840  (fNoOfSides != v.fNoOfSides) ||
841  (fUpVector != v.fUpVector) ||
842  (fFieldHalfAngle != v.fFieldHalfAngle) ||
843  (fZoomFactor != v.fZoomFactor) ||
844  (fScaleFactor != v.fScaleFactor) ||
845  (fCurrentTargetPoint != v.fCurrentTargetPoint) ||
846  (fDolly != v.fDolly) ||
847  (fRelativeLightpointDirection != v.fRelativeLightpointDirection) ||
848  (fLightsMoveWithCamera != v.fLightsMoveWithCamera) ||
849  (fDefaultVisAttributes != v.fDefaultVisAttributes) ||
850  (fDefaultTextVisAttributes != v.fDefaultTextVisAttributes) ||
851  (fDefaultMarker != v.fDefaultMarker) ||
852  (fGlobalMarkerScale != v.fGlobalMarkerScale) ||
853  (fGlobalLineWidthScale != v.fGlobalLineWidthScale) ||
854  (fMarkerNotHidden != v.fMarkerNotHidden) ||
855  (fWindowSizeHintX != v.fWindowSizeHintX) ||
856  (fWindowSizeHintY != v.fWindowSizeHintY) ||
857  (fXGeometryString != v.fXGeometryString) ||
858  (fGeometryMask != v.fGeometryMask) ||
859  (fAutoRefresh != v.fAutoRefresh) ||
860  (fBackgroundColour != v.fBackgroundColour) ||
861  (fPicking != v.fPicking) ||
862  (fRotationStyle != v.fRotationStyle)
863  )
864  return true;
865 
866  if (fDensityCulling &&
867  (fVisibleDensity != v.fVisibleDensity)) return true;
868 
869  if (fSection &&
870  (!(fSectionPlane == v.fSectionPlane))) return true;
871 
872  if (IsCutaway()) {
873  if (fCutawayPlanes.size () != v.fCutawayPlanes.size ())
874  return true;
875  else {
876  for (size_t i = 0; i < fCutawayPlanes.size (); i++) {
877  if (!(fCutawayPlanes[i] == v.fCutawayPlanes[i])) return true;
878  }
879  }
880  }
881 
882  if (IsExplode() &&
883  ((fExplodeFactor != v.fExplodeFactor) ||
884  (fExplodeCentre != v.fExplodeCentre))) return true;
885 
887  (fVisAttributesModifiers, v.fVisAttributesModifiers))
888  return true;
889 
890  return false;
891 }
892 
893 
894 void G4ViewParameters::SetXGeometryString (const G4String& geomStringArg) {
895 
896 
897  G4int x,y = 0;
898  unsigned int w,h = 0;
899  G4String geomString = geomStringArg;
900  // Parse windowSizeHintString for backwards compatibility...
901  const G4String delimiters("xX+-");
902  G4String::size_type i = geomString.find_first_of(delimiters);
903  if (i == G4String::npos) { // Does not contain "xX+-". Assume single number
904  std::istringstream iss(geomString);
905  G4int size;
906  iss >> size;
907  if (!iss) {
908  size = 600;
909  G4cout << "Unrecognised windowSizeHint string: \""
910  << geomString
911  << "\". Asuuming " << size << G4endl;
912  }
913  std::ostringstream oss;
914  oss << size << 'x' << size;
915  geomString = oss.str();
916  }
917 
918  fGeometryMask = ParseGeometry( geomString, &x, &y, &w, &h );
919 
920  // Handle special case :
921  if ((fGeometryMask & fYValue) == 0)
922  { // Using default
923  y = fWindowLocationHintY;
924  }
925  if ((fGeometryMask & fXValue) == 0)
926  { // Using default
927  x = fWindowLocationHintX;
928  }
929 
930  // Check errors
931  // if there is no Width and Height
932  if ( ((fGeometryMask & fHeightValue) == 0 ) &&
933  ((fGeometryMask & fWidthValue) == 0 )) {
934  h = fWindowSizeHintY;
935  w = fWindowSizeHintX;
936  } else if ((fGeometryMask & fHeightValue) == 0 ) {
937 
938  // if there is only Width. Special case to be backward compatible
939  // We set Width and Height the same to obtain a square windows.
940 
941  G4cout << "Unrecognised geometry string \""
942  << geomString
943  << "\". No Height found. Using Width value instead"
944  << G4endl;
945  h = w;
946  }
947  if ( ((fGeometryMask & fXValue) == 0 ) ||
948  ((fGeometryMask & fYValue) == 0 )) {
949  //Using defaults
950  x = fWindowLocationHintX;
951  y = fWindowLocationHintY;
952  }
953  // Set the string
954  fXGeometryString = geomString;
955 
956  // Set values
957  fWindowSizeHintX = w;
958  fWindowSizeHintY = h;
959  fWindowLocationHintX = x;
960  fWindowLocationHintY = y;
961 
962  if ( ((fGeometryMask & fXValue)) &&
963  ((fGeometryMask & fYValue))) {
964 
965  if ( (fGeometryMask & fXNegative) ) {
966  fWindowLocationHintXNegative = true;
967  } else {
968  fWindowLocationHintXNegative = false;
969  }
970  if ( (fGeometryMask & fYNegative) ) {
971  fWindowLocationHintYNegative = true;
972  } else {
973  fWindowLocationHintYNegative = false;
974  }
975  }
976 }
977 
979  if ( fWindowLocationHintXNegative ) {
980  return sizeX + fWindowLocationHintX - fWindowSizeHintX;
981  }
982  return fWindowLocationHintX;
983 }
984 
986  if ( fWindowLocationHintYNegative ) {
987  return sizeY + fWindowLocationHintY - fWindowSizeHintY;
988  }
989  return fWindowLocationHintY;
990 }
991 
992 /* Keep from :
993  * 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
994  *
995  * ParseGeometry parses strings of the form
996  * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
997  * width, height, xoffset, and yoffset are unsigned integers.
998  * Example: "=80x24+300-49"
999  * The equal sign is optional.
1000  * It returns a bitmask that indicates which of the four values
1001  * were actually found in the string. For each value found,
1002  * the corresponding argument is updated; for each value
1003  * not found, the corresponding argument is left unchanged.
1004  */
1005 
1006 int G4ViewParameters::ParseGeometry (
1007  const char *string,
1008  G4int *x,
1009  G4int *y,
1010  unsigned int *width,
1011  unsigned int *height)
1012 {
1013 
1014  G4int mask = fNoValue;
1015  register char *strind;
1016  unsigned int tempWidth = 0;
1017  unsigned int tempHeight = 0;
1018  G4int tempX = 0;
1019  G4int tempY = 0;
1020  char *nextCharacter;
1021  if ( (string == NULL) || (*string == '\0')) {
1022  return(mask);
1023  }
1024  if (*string == '=')
1025  string++; /* ignore possible '=' at beg of geometry spec */
1026  strind = (char *)string;
1027  if (*strind != '+' && *strind != '-' && *strind != 'x') {
1028  tempWidth = ReadInteger(strind, &nextCharacter);
1029  if (strind == nextCharacter)
1030  return (0);
1031  strind = nextCharacter;
1032  mask |= fWidthValue;
1033  }
1034  if (*strind == 'x' || *strind == 'X') {
1035  strind++;
1036  tempHeight = ReadInteger(strind, &nextCharacter);
1037  if (strind == nextCharacter)
1038  return (0);
1039  strind = nextCharacter;
1040  mask |= fHeightValue;
1041  }
1042 
1043  if ((*strind == '+') || (*strind == '-')) {
1044  if (*strind == '-') {
1045  strind++;
1046  tempX = -ReadInteger(strind, &nextCharacter);
1047  if (strind == nextCharacter)
1048  return (0);
1049  strind = nextCharacter;
1050  mask |= fXNegative;
1051 
1052  }
1053  else
1054  { strind++;
1055  tempX = ReadInteger(strind, &nextCharacter);
1056  if (strind == nextCharacter)
1057  return(0);
1058  strind = nextCharacter;
1059  }
1060  mask |= fXValue;
1061  if ((*strind == '+') || (*strind == '-')) {
1062  if (*strind == '-') {
1063  strind++;
1064  tempY = -ReadInteger(strind, &nextCharacter);
1065  if (strind == nextCharacter)
1066  return(0);
1067  strind = nextCharacter;
1068  mask |= fYNegative;
1069  }
1070  else
1071  {
1072  strind++;
1073  tempY = ReadInteger(strind, &nextCharacter);
1074  if (strind == nextCharacter)
1075  return(0);
1076  strind = nextCharacter;
1077  }
1078  mask |= fYValue;
1079  }
1080  }
1081  /* If strind isn't at the end of the string the it's an invalid
1082  geometry specification. */
1083  if (*strind != '\0') return (0);
1084  if (mask & fXValue)
1085  *x = tempX;
1086  if (mask & fYValue)
1087  *y = tempY;
1088  if (mask & fWidthValue)
1089  *width = tempWidth;
1090  if (mask & fHeightValue)
1091  *height = tempHeight;
1092  return (mask);
1093 }
1094 
1095 /* Keep from :
1096  * 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
1097  *
1098  */
1099 G4int G4ViewParameters::ReadInteger(char *string, char **NextString)
1100 {
1101  register G4int Result = 0;
1102  G4int Sign = 1;
1103 
1104  if (*string == '+')
1105  string++;
1106  else if (*string == '-')
1107  {
1108  string++;
1109  Sign = -1;
1110  }
1111  for (; (*string >= '0') && (*string <= '9'); string++)
1112  {
1113  Result = (Result * 10) + (*string - '0');
1114  }
1115  *NextString = string;
1116  if (Sign >= 0)
1117  return (Result);
1118  else
1119  return (-Result);
1120 }