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