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