Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VSceneHandler.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// Abstract interface class for graphics scenes.
31
32#include "G4VSceneHandler.hh"
33
34#include "G4ios.hh"
35#include <sstream>
36
37#include "G4VisManager.hh"
38#include "G4VGraphicsSystem.hh"
39#include "G4VViewer.hh"
40#include "G4VSolid.hh"
41#include "G4RotationMatrix.hh"
42#include "G4ThreeVector.hh"
43#include "G4VPhysicalVolume.hh"
44#include "G4Material.hh"
45#include "G4Polyline.hh"
46#include "G4Text.hh"
47#include "G4Circle.hh"
48#include "G4Square.hh"
49#include "G4Polymarker.hh"
50#include "G4Polyhedron.hh"
51#include "G4Visible.hh"
52#include "G4VisAttributes.hh"
53#include "G4VModel.hh"
55#include "G4Box.hh"
56#include "G4Cons.hh"
57#include "G4Orb.hh"
58#include "G4Para.hh"
59#include "G4Sphere.hh"
60#include "G4Torus.hh"
61#include "G4Trap.hh"
62#include "G4Trd.hh"
63#include "G4Tubs.hh"
64#include "G4Ellipsoid.hh"
65#include "G4Polycone.hh"
66#include "G4Polyhedra.hh"
67#include "G4Tet.hh"
68#include "G4DisplacedSolid.hh"
69#include "G4UnionSolid.hh"
71#include "G4SubtractionSolid.hh"
72#include "G4LogicalVolume.hh"
75#include "G4VTrajectory.hh"
76#include "G4VTrajectoryPoint.hh"
77#include "G4HitsModel.hh"
78#include "G4VHit.hh"
79#include "G4VDigi.hh"
80#include "G4ScoringManager.hh"
81#include "G4VScoringMesh.hh"
82#include "G4Mesh.hh"
84#include "G4QuickRand.hh"
85#include "G4StateManager.hh"
86#include "G4RunManager.hh"
88#include "G4Run.hh"
89#include "G4Transform3D.hh"
90#include "G4AttHolder.hh"
91#include "G4AttDef.hh"
92#include "G4SceneTreeItem.hh"
93#include "G4VVisCommand.hh"
95#include "G4SystemOfUnits.hh"
96
97#include <set>
98
99#define G4warn G4cout
102 fSystem (system),
103 fSceneHandlerId (id),
104 fViewCount (0),
105 fpViewer (0),
106 fpScene (0),
107 fMarkForClearingTransientStore (true), // Ready for first
108 // ClearTransientStoreIfMarked(),
109 // e.g., at end of run (see
110 // G4VisManager.cc).
111 fReadyForTransients (true), // Only false while processing scene.
112 fProcessingSolid (false),
113 fProcessing2D (false),
114 fpModel (0),
115 fNestingDepth (0),
116 fpVisAttribs (0)
117{
119 fpScene = pVMan -> GetCurrentScene ();
120 if (name == "") {
121 std::ostringstream ost;
122 ost << fSystem.GetName () << '-' << fSceneHandlerId;
123 fName = ost.str();
124 }
125 else {
126 fName = name;
127 }
128 fTransientsDrawnThisEvent = pVMan->GetTransientsDrawnThisEvent();
129 fTransientsDrawnThisRun = pVMan->GetTransientsDrawnThisRun();
134 while( ! fViewerList.empty() ) {
135 last = fViewerList.back();
136 fViewerList.pop_back();
137 delete last;
138 }
139}
140
142{
143 if (fpScene) {
144 return fpScene->GetExtent();
145 } else {
146 static const G4VisExtent defaultExtent = G4VisExtent();
147 return defaultExtent;
148 }
149}
150
151void G4VSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation,
152 const G4VisAttributes& visAttribs) {
153 fObjectTransformation = objectTransformation;
154 fpVisAttribs = &visAttribs;
155 fProcessingSolid = true;
156}
157
166
168(const G4Transform3D& objectTransformation) {
169 //static G4int count = 0;
170 //G4cout << "G4VSceneHandler::BeginPrimitives: " << count++ << G4endl;
172 if (fNestingDepth > 1)
174 ("G4VSceneHandler::BeginPrimitives",
175 "visman0101", FatalException,
176 "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
177 fObjectTransformation = objectTransformation;
178}
179
181 if (fNestingDepth <= 0)
182 G4Exception("G4VSceneHandler::EndPrimitives",
183 "visman0102", FatalException, "Nesting error.");
188 }
189}
190
192(const G4Transform3D& objectTransformation) {
194 if (fNestingDepth > 1)
196 ("G4VSceneHandler::BeginPrimitives2D",
197 "visman0103", FatalException,
198 "Nesting detected. It is illegal to nest Begin/EndPrimitives.");
199 fObjectTransformation = objectTransformation;
200 fProcessing2D = true;
201}
202
204 if (fNestingDepth <= 0)
205 G4Exception("G4VSceneHandler::EndPrimitives2D",
206 "visman0104", FatalException, "Nesting error.");
211 }
212 fProcessing2D = false;
213}
214
217
219{
220 fpModel = 0;
221}
222
224
226
227template <class T> void G4VSceneHandler::AddSolidT
228(const T& solid)
229{
230 // Get and check applicable vis attributes.
232 RequestPrimitives (solid);
233}
234
236(const T& solid)
237{
238 // Get and check applicable vis attributes.
240 // Draw with auxiliary edges unless otherwise specified.
242 // Create a vis atts object for the modified vis atts.
243 // It is static so that we may return a reliable pointer to it.
244 static G4VisAttributes visAttsWithAuxEdges;
245 // Initialise it with the current vis atts and reset the pointer.
246 visAttsWithAuxEdges = *fpVisAttribs;
247 // Force auxiliary edges visible.
248 visAttsWithAuxEdges.SetForceAuxEdgeVisible();
249 fpVisAttribs = &visAttsWithAuxEdges;
250 }
251 RequestPrimitives (solid);
252}
253
255 AddSolidT (box);
256 // If your graphics system is sophisticated enough to handle a
257 // particular solid shape as a primitive, in your derived class write a
258 // function to override this.
259 // Your function might look like this...
260 // void G4MySceneHandler::AddSolid (const G4Box& box) {
261 // Get and check applicable vis attributes.
262 // fpVisAttribs = fpViewer->GetApplicableVisAttributes(fpVisAttribs);
263 // Do not draw if not visible.
264 // if (fpVisAttribs->IsVisible()) {
265 // Get parameters of appropriate object, e.g.:
266 // G4double dx = box.GetXHalfLength ();
267 // G4double dy = box.GetYHalfLength ();
268 // G4double dz = box.GetZHalfLength ();
269 // ...
270 // and Draw or Store in your display List.
271}
272
274 AddSolidT (cons);
275}
276
280
282 AddSolidT (para);
283}
284
287}
288
291}
292
294 AddSolidT (trap);
295}
296
298 AddSolidT (trd);
299}
300
302 AddSolidT (tubs);
303}
304
305void G4VSceneHandler::AddSolid (const G4Ellipsoid& ellipsoid) {
306 AddSolidWithAuxiliaryEdges (ellipsoid);
307}
308
309void G4VSceneHandler::AddSolid (const G4Polycone& polycone) {
310 AddSolidT (polycone);
311}
312
313void G4VSceneHandler::AddSolid (const G4Polyhedra& polyhedra) {
314 AddSolidT (polyhedra);
315}
316
318 AddSolidT (tess);
319}
320
322 AddSolidT (solid);
323}
324
326 G4TrajectoriesModel* trajectoriesModel =
327 dynamic_cast<G4TrajectoriesModel*>(fpModel);
328 if (trajectoriesModel)
329 traj.DrawTrajectory();
330 else {
332 ("G4VSceneHandler::AddCompound(const G4VTrajectory&)",
333 "visman0105", FatalException, "Not a G4TrajectoriesModel.");
334 }
335}
336
338 // Cast away const because Draw is non-const!!!!
339 const_cast<G4VHit&>(hit).Draw();
340}
341
343 // Cast away const because Draw is non-const!!!!
344 const_cast<G4VDigi&>(digi).Draw();
345}
346
348 using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
349 //G4cout << "AddCompound: hits: " << &hits << G4endl;
350 G4bool scoreMapHits = false;
352 if (scoringManager) {
353 std::size_t nMeshes = scoringManager->GetNumberOfMesh();
354 for (std::size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
355 G4VScoringMesh* mesh = scoringManager->GetMesh((G4int)iMesh);
356 if (mesh && mesh->IsActive()) {
357 MeshScoreMap scoreMap = mesh->GetScoreMap();
358 const G4String& mapNam = const_cast<G4THitsMap<G4double>&>(hits).GetName();
359 for(MeshScoreMap::const_iterator i = scoreMap.cbegin();
360 i != scoreMap.cend(); ++i) {
361 const G4String& scoreMapName = i->first;
362 if (scoreMapName == mapNam) {
363 G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
364 scoreMapHits = true;
365 mesh->DrawMesh(scoreMapName, &colorMap);
366 }
367 }
368 }
369 }
370 }
371 if (scoreMapHits) {
372 static G4bool first = true;
373 if (first) {
374 first = false;
375 G4cout <<
376 "Scoring map drawn with default parameters."
377 "\n To get gMocren file for gMocren browser:"
378 "\n /vis/open gMocrenFile"
379 "\n /vis/viewer/flush"
380 "\n Many other options available with /score/draw... commands."
381 "\n You might want to \"/vis/viewer/set/autoRefresh false\"."
382 << G4endl;
383 }
384 } else { // Not score map hits. Just call DrawAllHits.
385 // Cast away const because DrawAllHits is non-const!!!!
386 const_cast<G4THitsMap<G4double>&>(hits).DrawAllHits();
387 }
388}
389
391 using MeshScoreMap = G4VScoringMesh::MeshScoreMap;
392 //G4cout << "AddCompound: hits: " << &hits << G4endl;
393 G4bool scoreMapHits = false;
395 if (scoringManager) {
396 std::size_t nMeshes = scoringManager->GetNumberOfMesh();
397 for (std::size_t iMesh = 0; iMesh < nMeshes; ++iMesh) {
398 G4VScoringMesh* mesh = scoringManager->GetMesh((G4int)iMesh);
399 if (mesh && mesh->IsActive()) {
400 MeshScoreMap scoreMap = mesh->GetScoreMap();
401 for(MeshScoreMap::const_iterator i = scoreMap.cbegin();
402 i != scoreMap.cend(); ++i) {
403 const G4String& scoreMapName = i->first;
404 const G4THitsMap<G4StatDouble>* foundHits = i->second;
405 if (foundHits == &hits) {
406 G4DefaultLinearColorMap colorMap("G4VSceneHandlerColorMap");
407 scoreMapHits = true;
408 mesh->DrawMesh(scoreMapName, &colorMap);
409 }
410 }
411 }
412 }
413 }
414 if (scoreMapHits) {
415 static G4bool first = true;
416 if (first) {
417 first = false;
418 G4cout <<
419 "Scoring map drawn with default parameters."
420 "\n To get gMocren file for gMocren browser:"
421 "\n /vis/open gMocrenFile"
422 "\n /vis/viewer/flush"
423 "\n Many other options available with /score/draw... commands."
424 "\n You might want to \"/vis/viewer/set/autoRefresh false\"."
425 << G4endl;
426 }
427 } else { // Not score map hits. Just call DrawAllHits.
428 // Cast away const because DrawAllHits is non-const!!!!
429 const_cast<G4THitsMap<G4StatDouble>&>(hits).DrawAllHits();
430 }
431}
432
434{
435 G4warn <<
436 "There has been an attempt to draw a mesh with option \""
438 << "\":\n" << mesh
439 << "but it is not of a recognised type or is not implemented"
440 "\nby the current graphics driver. Instead we draw its"
441 "\ncontainer \"" << mesh.GetContainerVolume()->GetName() << "\"."
442 << G4endl;
443 const auto& pv = mesh.GetContainerVolume();
444 const auto& lv = pv->GetLogicalVolume();
445 const auto& solid = lv->GetSolid();
446 const auto& transform = mesh.GetTransform();
447 // Make sure container is visible
448 G4VisAttributes tmpVisAtts; // Visible, white, not forced.
449 const auto& saveVisAtts = lv->GetVisAttributes();
450 if (saveVisAtts) {
451 tmpVisAtts = *saveVisAtts;
452 tmpVisAtts.SetVisibility(true);
453 auto colour = saveVisAtts->GetColour();
454 colour.SetAlpha(1.);
455 tmpVisAtts.SetColour(colour);
456 }
457 // Draw container
458 PreAddSolid(transform,tmpVisAtts);
459 solid->DescribeYourselfTo(*this);
460 PostAddSolid();
461 // Restore vis attributes
462 lv->SetVisAttributes(saveVisAtts);
463}
464
466 fViewerList.push_back (pViewer);
467}
468
470 switch (polymarker.GetMarkerType()) {
471 default:
473 {
474 G4Circle dot (polymarker);
475 dot.SetWorldSize (0.);
476 dot.SetScreenSize (0.1); // Very small circle.
477 for (std::size_t iPoint = 0; iPoint < polymarker.size (); ++iPoint) {
478 dot.SetPosition (polymarker[iPoint]);
479 AddPrimitive (dot);
480 }
481 }
482 break;
484 {
485 G4Circle circle (polymarker); // Default circle
486 for (std::size_t iPoint = 0; iPoint < polymarker.size (); ++iPoint) {
487 circle.SetPosition (polymarker[iPoint]);
488 AddPrimitive (circle);
489 }
490 }
491 break;
493 {
494 G4Square square (polymarker); // Default square
495 for (std::size_t iPoint = 0; iPoint < polymarker.size (); ++iPoint) {
496 square.SetPosition (polymarker[iPoint]);
497 AddPrimitive (square);
498 }
499 }
500 break;
501 }
502}
503
505 fViewerList.remove(pViewer); // Does nothing if already removed
506 // And reset current viewer
507 auto visManager = G4VisManager::GetInstance();
508 visManager->SetCurrentViewer(nullptr);
509}
510
511
513 G4warn << "WARNING: Plotter not implemented for " << fSystem.GetName() << G4endl;
514 G4warn << " Open a plotter-aware graphics system or remove plotter with" << G4endl;
515 G4warn << " /vis/scene/removeModel Plotter" << G4endl;
516}
517
519 fpScene = pScene;
520 // Notify all viewers that a kernel visit is required.
522 for (i = fViewerList.begin(); i != fViewerList.end(); i++) {
523 (*i) -> SetNeedKernelVisit (true);
524 }
525}
526
528{
529 // Sometimes solids that have no substance get requested. They may
530 // be part of the geometry tree but have been "spirited away", for
531 // example by a Boolean subtraction in which the original volume
532 // is entirely inside the subtractor or an intersection in which
533 // the original volume is entirely outside the intersector.
534 // The problem is that the Boolean Processor still returns a
535 // polyhedron in these cases (IMHO it should not), so the
536 // workaround is to return before the damage is done.
537 // Algorithm by Evgueni Tcherniaev
538 auto pSolid = &solid;
539 auto pBooleanSolid = dynamic_cast<const G4BooleanSolid*>(pSolid);
540 if (pBooleanSolid) {
541 G4ThreeVector bmin, bmax;
542 pBooleanSolid->BoundingLimits(bmin, bmax);
543 G4bool isGood = false;
544 if (dynamic_cast<const G4SubtractionSolid*>(pBooleanSolid)) {
545 auto ptrB = pBooleanSolid->GetConstituentSolid(1);
546 for (G4int i=0; i<10; ++i) {
547 G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
548 G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
549 G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
550 if (ptrB->Inside(G4ThreeVector(x,y,bmin.z())) != kInside) { isGood = true; break; }
551 if (ptrB->Inside(G4ThreeVector(x,y,bmax.z())) != kInside) { isGood = true; break; }
552 if (ptrB->Inside(G4ThreeVector(x,bmin.y(),z)) != kInside) { isGood = true; break; }
553 if (ptrB->Inside(G4ThreeVector(x,bmax.y(),z)) != kInside) { isGood = true; break; }
554 if (ptrB->Inside(G4ThreeVector(bmin.x(),y,z)) != kInside) { isGood = true; break; }
555 if (ptrB->Inside(G4ThreeVector(bmax.x(),y,z)) != kInside) { isGood = true; break; }
556 }
557 } else if (dynamic_cast<const G4IntersectionSolid*>(pBooleanSolid)) {
558 auto ptrB = pBooleanSolid->GetConstituentSolid(1);
559 for (G4int i=0; i<10; ++i) {
560 G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
561 G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
562 G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
563 if (ptrB->Inside(G4ThreeVector(x,y,bmin.z())) == kInside) { isGood = true; break; }
564 if (ptrB->Inside(G4ThreeVector(x,y,bmax.z())) == kInside) { isGood = true; break; }
565 if (ptrB->Inside(G4ThreeVector(x,bmin.y(),z)) == kInside) { isGood = true; break; }
566 if (ptrB->Inside(G4ThreeVector(x,bmax.y(),z)) == kInside) { isGood = true; break; }
567 if (ptrB->Inside(G4ThreeVector(bmin.x(),y,z)) == kInside) { isGood = true; break; }
568 if (ptrB->Inside(G4ThreeVector(bmax.x(),y,z)) == kInside) { isGood = true; break; }
569 }
570 }
571 if (!isGood)
572 {
573 for (G4int i=0; i<10000; ++i) {
574 G4double x = bmin.x() + (bmax.x() - bmin.x())*G4QuickRand();
575 G4double y = bmin.y() + (bmax.y() - bmin.y())*G4QuickRand();
576 G4double z = bmin.z() + (bmax.z() - bmin.z())*G4QuickRand();
577 if (pBooleanSolid->Inside(G4ThreeVector(x,y,z)) == kInside) { isGood = true; break; }
578 }
579 }
580 if (!isGood) return;
581 }
582
585
586 switch (style) {
587 default:
592 {
593 // Use polyhedral representation
595 G4Polyhedron* pPolyhedron = solid.GetPolyhedron ();
597 if (pPolyhedron) {
598 pPolyhedron -> SetVisAttributes (fpVisAttribs);
600 AddPrimitive (*pPolyhedron);
601 EndPrimitives ();
602 break;
603 } else { // Print warnings and drop through to cloud
605 static std::set<const G4VSolid*> problematicSolids;
606 if (verbosity >= G4VisManager::errors &&
607 problematicSolids.find(&solid) == problematicSolids.end()) {
608 problematicSolids.insert(&solid);
609 G4warn <<
610 "ERROR: G4VSceneHandler::RequestPrimitives"
611 "\n Polyhedron not available for " << solid.GetName ();
612 G4PhysicalVolumeModel* pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
613 if (pPVModel) {
614 G4warn << "\n Touchable path: " << pPVModel->GetFullPVPath();
615 }
616 static G4bool explanation = false;
617 if (!explanation) {
618 explanation = true;
619 G4warn <<
620 "\n This means it cannot be visualized in the usual way on most systems."
621 "\n 1) The solid may not have implemented the CreatePolyhedron method."
622 "\n 2) For Boolean solids, the BooleanProcessor, which attempts to create"
623 "\n the resultant polyhedron, may have failed."
624 "\n Try RayTracer. It uses Geant4's tracking algorithms instead.";
625 }
626 G4warn << "\n Drawing solid with cloud of points.";
627 G4warn << G4endl;
628 }
629 }
630 }
631 [[fallthrough]];
632
634 {
635 // Form solid out of cloud of dots on surface of solid
636 G4Polymarker dots;
637 // Note: OpenGL has a fast implementation of polymarker so it's better
638 // to build a polymarker rather than add a succession of circles.
639 // And anyway, in Qt, in the latter case each circle would be a scene-tree
640 // entry, something we would want to avoid.
643 dots.SetSize(G4VMarker::screen,1.);
644 G4int numberOfCloudPoints = GetNumberOfCloudPoints(fpVisAttribs);
645 if (numberOfCloudPoints <= 0) numberOfCloudPoints = vp.GetNumberOfCloudPoints();
646 for (G4int i = 0; i < numberOfCloudPoints; ++i) {
648 dots.push_back(p);
649 }
651 AddPrimitive(dots);
652 EndPrimitives ();
653 break;
654 }
655 }
656}
657
658//namespace {
659// void DrawExtent(const G4VModel* pModel)
660// {
661// // Show extent boxes - debug only, OGLSX only (OGLSQt problem?)
662// if (pModel->GetExtent() != G4VisExtent::GetNullExtent()) {
663// const auto& extent = pModel->GetExtent();
664// const auto& centre = extent.GetExtentCenter();
665// const auto& position = G4Translate3D(centre);
666// const auto& dx = (extent.GetXmax()-extent.GetXmin())/2.;
667// const auto& dy = (extent.GetYmax()-extent.GetYmin())/2.;
668// const auto& dz = (extent.GetZmax()-extent.GetZmin())/2.;
669// auto visAtts = G4VisAttributes();
670// visAtts.SetForceWireframe();
671// G4Box extentBox("Extent",dx,dy,dz);
672// G4VisManager::GetInstance()->Draw(extentBox,visAtts,position);
673// }
674// }
675//}
676
678{
679 // Assumes graphics database store has already been cleared if
680 // relevant for the particular scene handler.
681
682 if(!fpScene)
683 return;
684
686 {
687 G4Exception("G4VSceneHandler::ProcessScene", "visman0106", JustWarning,
688 "The scene has no extent.");
689 }
690
692
693 if(!visManager->GetConcreteInstance())
694 return;
695
696 G4VisManager::Verbosity verbosity = visManager->GetVerbosity();
697
698 fReadyForTransients = false;
699
700 // Reset fMarkForClearingTransientStore. (Leaving
701 // fMarkForClearingTransientStore true causes problems with
702 // recomputing transients below.) Restore it again at end...
703 G4bool tmpMarkForClearingTransientStore = fMarkForClearingTransientStore;
705
706 // Traverse geometry tree and send drawing primitives to window(s).
707
708 const std::vector<G4Scene::Model>& runDurationModelList =
710
711 if(runDurationModelList.size())
712 {
713 if(verbosity >= G4VisManager::confirmations)
714 {
715 G4cout << "Traversing scene data..." << G4endl;
716 }
717
718 // Reset visibility of all objects to false - visible objects will then set to true
720
722
723 // Create modeling parameters from view parameters...
725
726 for(std::size_t i = 0; i < runDurationModelList.size(); ++i)
727 {
728 if(runDurationModelList[i].fActive)
729 {
730 fpModel = runDurationModelList[i].fpModel;
732
733 // Describe to the current scene handler
735
736 // To see the extents of each model represented as wireframe boxes,
737 // uncomment the next line and DrawExtent in namespace above.
738 // DrawExtent(fpModel);
739
740 // Enter models in the scene tree, and for PV models, describe
741 // the model to the scene tree, i.e., enter all the touchables.
742 auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
743 sceneTreeScene.SetViewer(fpViewer);
744 sceneTreeScene.SetModel(fpModel);
745 if (dynamic_cast<G4PhysicalVolumeModel*>(fpModel)) {
746 fpModel->DescribeYourselfTo(sceneTreeScene);
747 }
748
749 // Reset modeling parameters pointer
751 }
752 }
753
754 fpModel = 0;
755 delete pMP;
756
757 EndModeling();
758 }
759
760 fReadyForTransients = true;
761
762 // Refresh event from end-of-event model list.
763 // Allow only in Idle or GeomClosed state...
765 G4ApplicationState state = stateManager->GetCurrentState();
766 if(state == G4State_Idle || state == G4State_GeomClosed)
767 {
768 visManager->SetEventRefreshing(true);
769
770 if(visManager->GetRequestedEvent())
771 {
772 DrawEvent(visManager->GetRequestedEvent());
773 }
774 else
775 {
777 if(runManager)
778 {
779 const G4Run* run = runManager->GetCurrentRun();
780 // Draw a null event in order to pick up models for the scene tree even before a run
781 if (run == nullptr) DrawEvent(0);
782 const std::vector<const G4Event*>* events =
783 run ? run->GetEventVector() : 0;
784 std::size_t nKeptEvents = 0;
785 if(events)
786 nKeptEvents = events->size();
787 if(nKeptEvents)
788 {
790 {
791 if(verbosity >= G4VisManager::confirmations)
792 {
793 G4cout << "Refreshing event..." << G4endl;
794 }
795 const G4Event* event = 0;
796 if(events && events->size())
797 event = events->back();
798 if(event)
799 DrawEvent(event);
800 }
801 else
802 { // Accumulating events.
803
804 if(verbosity >= G4VisManager::confirmations)
805 {
806 G4cout << "Refreshing events in run..." << G4endl;
807 }
808 for(const auto& event : *events)
809 {
810 if(event)
811 DrawEvent(event);
812 }
813
815 {
816 if(verbosity >= G4VisManager::warnings)
817 {
818 G4warn << "WARNING: Cannot refresh events accumulated over more"
819 "\n than one runs. Refreshed just the last run."
820 << G4endl;
821 }
822 }
823 }
824 }
825 }
826 }
827 visManager->SetEventRefreshing(false);
828 }
829
830 // Refresh end-of-run model list.
831 // Allow only in Idle or GeomClosed state...
832 if(state == G4State_Idle || state == G4State_GeomClosed)
833 {
835 }
836
837 fMarkForClearingTransientStore = tmpMarkForClearingTransientStore;
838}
839
841{
842 const std::vector<G4Scene::Model>& EOEModelList =
843 fpScene -> GetEndOfEventModelList ();
844 std::size_t nModels = EOEModelList.size();
845 if (nModels) {
847 pMP->SetEvent(event);
848 for (std::size_t i = 0; i < nModels; ++i) {
849 if (EOEModelList[i].fActive) {
850 fpModel = EOEModelList[i].fpModel;
851 fpModel -> SetModelingParameters(pMP);
852
853 // Describe to the current scene handler
854 fpModel -> DescribeYourselfTo (*this);
855
856 // Enter models in the scene tree
857 auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
858 sceneTreeScene.SetViewer(fpViewer);
859 sceneTreeScene.SetModel(fpModel);
860
861 // Reset modeling parameters pointer
862 fpModel -> SetModelingParameters(0);
863 }
864 }
865 fpModel = 0;
866 delete pMP;
867 }
868}
869
871{
872 const std::vector<G4Scene::Model>& EORModelList =
873 fpScene -> GetEndOfRunModelList ();
874 std::size_t nModels = EORModelList.size();
875 if (nModels) {
877 pMP->SetEvent(0);
878 for (std::size_t i = 0; i < nModels; ++i) {
879 if (EORModelList[i].fActive) {
880 fpModel = EORModelList[i].fpModel;
881 fpModel -> SetModelingParameters(pMP);
882
883 // Describe to the current scene handler
884 fpModel -> DescribeYourselfTo (*this);
885
886 // Enter models in the scene tree
887 auto& sceneTreeScene = fpViewer->AccessSceneTreeScene();
888 sceneTreeScene.SetViewer(fpViewer);
889 sceneTreeScene.SetModel(fpModel);
890
891 // Reset modeling parameters pointer
892 fpModel -> SetModelingParameters(0);
893 }
894 }
895 fpModel = 0;
896 delete pMP;
897 }
898}
899
901{
902 // Create modeling parameters from View Parameters...
903 if (!fpViewer) return NULL;
904
905 const G4ViewParameters& vp = fpViewer -> GetViewParameters ();
906
907 // Convert drawing styles...
908 G4ModelingParameters::DrawingStyle modelDrawingStyle =
910 switch (vp.GetDrawingStyle ()) {
911 default:
913 modelDrawingStyle = G4ModelingParameters::wf;
914 break;
916 modelDrawingStyle = G4ModelingParameters::hlr;
917 break;
919 modelDrawingStyle = G4ModelingParameters::hsr;
920 break;
922 modelDrawingStyle = G4ModelingParameters::hlhsr;
923 break;
925 modelDrawingStyle = G4ModelingParameters::cloud;
926 break;
927 }
928
929 // Decide if covered daughters are really to be culled...
930 G4bool reallyCullCovered =
931 vp.IsCullingCovered() // Culling daughters depends also on...
932 && !vp.IsSection () // Sections (DCUT) not requested.
933 && !vp.IsCutaway () // Cutaways not requested.
934 ;
935
936 G4ModelingParameters* pModelingParams = new G4ModelingParameters
938 modelDrawingStyle,
939 vp.IsCulling (),
940 vp.IsCullingInvisible (),
941 vp.IsDensityCulling (),
942 vp.GetVisibleDensity (),
943 reallyCullCovered,
944 vp.GetNoOfSides ()
945 );
946
947 pModelingParams->SetNumberOfCloudPoints(vp.GetNumberOfCloudPoints());
948 pModelingParams->SetWarning
950
951 pModelingParams->SetCBDAlgorithmNumber(vp.GetCBDAlgorithmNumber());
952 pModelingParams->SetCBDParameters(vp.GetCBDParameters());
953
954 pModelingParams->SetExplodeFactor(vp.GetExplodeFactor());
955 pModelingParams->SetExplodeCentre(vp.GetExplodeCentre());
956
957 pModelingParams->SetSectionSolid(CreateSectionSolid());
958
963 }
964
965 pModelingParams->SetCutawaySolid(CreateCutawaySolid());
966 // The polyhedron objects are deleted in the modeling parameters destructor.
967
969
970 pModelingParams->SetSpecialMeshRendering(vp.IsSpecialMeshRendering());
971 pModelingParams->SetSpecialMeshVolumes(vp.GetSpecialMeshVolumes());
972
973 return pModelingParams;
974}
975
977{
978 G4DisplacedSolid* sectioner = 0;
979
981 if (vp.IsSection () ) {
982
984 G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
985 G4VSolid* sectionBox =
986 new G4Box("_sectioner", safe, safe, 1.e-5 * radius); // Thin in z-plane...
987
988 const G4Plane3D& sp = vp.GetSectionPlane ();
989 G4ThreeVector normal = sp.normal();
990 G4Transform3D requiredTransform = G4Translate3D(normal*(-sp.d())) *
991 G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
992
993 sectioner = new G4DisplacedSolid
994 ("_displaced_sectioning_box", sectionBox, requiredTransform);
995 }
996
997 return sectioner;
998}
999
1001{
1002 const auto& vp = fpViewer->GetViewParameters();
1003 const auto& nPlanes = vp.GetCutawayPlanes().size();
1004
1005 if (nPlanes == 0) return nullptr;
1006
1007 std::vector<G4DisplacedSolid*> cutaway_solids;
1008
1010 G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag();
1011 auto cutawayBox = new G4Box("_cutaway_box", safe, safe, safe);
1012
1013 // if (vp.GetCutawayMode() == G4ViewParameters::cutawayUnion) we need a subtractor that is
1014 // the intersection of displaced cutaway boxes, displaced so that a subtraction keeps the
1015 // positive values a*x+b*y+c*z+d>0, so we have to invert the normal. This may appear
1016 // "back to front". The parameter "cutawayUnion" means "the union of volumes
1017 // that remain *after* cutaway", because we base the concept on OpenGL cutaway planes and make
1018 // a "union" of what remains by superimposing up to 3 passes - see G4OpenGLViewer::SetView
1019 // and G4OpenGLImmediate/StoredViewer::ProcessView. So we have to create a subtractor
1020 // that is the intersection of inverted cutaway planes.
1021
1022 // Conversely, if (vp.GetCutawayMode() == G4ViewParameters::cutawayIntersection) we have to
1023 // create an intersector that is the intersector of intersected non-inverted cutaway planes.
1024
1025 for (size_t plane_no = 0; plane_no < nPlanes; plane_no++)
1026 {
1027 const G4Plane3D& sp = vp.GetCutawayPlanes()[plane_no];
1028 G4Transform3D requiredTransform;
1029 G4ThreeVector normal;
1030 switch (vp.GetCutawayMode()) {
1032 normal = -sp.normal(); // Invert normal - we want a subtractor
1033 requiredTransform = G4Translate3D(normal*(safe + sp.d())) *
1034 G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
1035 break;
1037 normal = sp.normal();
1038 requiredTransform = G4Translate3D(normal*(safe - sp.d())) *
1039 G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeVector(0,1,0), normal, normal.orthogonal());
1040 break;
1041 }
1042 cutaway_solids.push_back
1043 (new G4DisplacedSolid("_displaced_cutaway_box", cutawayBox, requiredTransform));
1044 }
1045
1046 if (nPlanes == 1) return (G4DisplacedSolid*) cutaway_solids[0];
1047
1048 G4IntersectionSolid *union2 = nullptr, *union3 = nullptr;
1049 G4IntersectionSolid *intersection2 = nullptr, *intersection3 = nullptr;
1050 switch (vp.GetCutawayMode()) {
1051
1053 // Here we make a subtractor of intersections of inverted cutaway planes.
1054 union2 = new G4IntersectionSolid("_union_2", cutaway_solids[0], cutaway_solids[1]);
1055 if (nPlanes == 2) return (G4DisplacedSolid*)union2;
1056 else if (nPlanes == 3) {
1057 union3 = new G4IntersectionSolid("_union_3", union2, cutaway_solids[2]);
1058 return (G4DisplacedSolid*)union3;
1059 }
1060 break;
1061
1063 // And here we make an intersector of intersections of non-inverted cutaway planes.
1064 intersection2
1065 = new G4IntersectionSolid("_intersection_2", cutaway_solids[0], cutaway_solids[1]);
1066 if (nPlanes == 2) return (G4DisplacedSolid*)intersection2;
1067 else if (nPlanes == 3) {
1068 intersection3
1069 = new G4IntersectionSolid("_intersection_3", intersection2, cutaway_solids[2]);
1070 return (G4DisplacedSolid*)intersection3;
1071 }
1072 break;
1073 }
1074
1075 G4Exception("G4VSceneHandler::CreateCutawaySolid", "visman107", JustWarning,
1076 "Not programmed for more than 3 cutaway planes");
1077 return nullptr;
1078}
1079
1081{
1082 // Load G4Atts from G4VisAttributes, if any...
1083 const G4VisAttributes* va = visible.GetVisAttributes();
1084 if (va) {
1085 const std::map<G4String,G4AttDef>* vaDefs =
1086 va->GetAttDefs();
1087 if (vaDefs) {
1088 holder->AddAtts(visible.GetVisAttributes()->CreateAttValues(), vaDefs);
1089 }
1090 }
1091
1092 G4PhysicalVolumeModel* pPVModel =
1093 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1094 if (pPVModel) {
1095 // Load G4Atts from G4PhysicalVolumeModel...
1096 const std::map<G4String,G4AttDef>* pvDefs = pPVModel->GetAttDefs();
1097 if (pvDefs) {
1098 holder->AddAtts(pPVModel->CreateCurrentAttValues(), pvDefs);
1099 }
1100 }
1101
1102 G4TrajectoriesModel* trajModel = dynamic_cast<G4TrajectoriesModel*>(fpModel);
1103 if (trajModel) {
1104 // Load G4Atts from trajectory model...
1105 const std::map<G4String,G4AttDef>* trajModelDefs = trajModel->GetAttDefs();
1106 if (trajModelDefs) {
1107 holder->AddAtts(trajModel->CreateCurrentAttValues(), trajModelDefs);
1108 }
1109 // Load G4Atts from trajectory...
1110 const G4VTrajectory* traj = trajModel->GetCurrentTrajectory();
1111 if (traj) {
1112 const std::map<G4String,G4AttDef>* trajDefs = traj->GetAttDefs();
1113 if (trajDefs) {
1114 holder->AddAtts(traj->CreateAttValues(), trajDefs);
1115 }
1116 G4int nPoints = traj->GetPointEntries();
1117 for (G4int i = 0; i < nPoints; ++i) {
1118 G4VTrajectoryPoint* trajPoint = traj->GetPoint(i);
1119 if (trajPoint) {
1120 const std::map<G4String,G4AttDef>* pointDefs = trajPoint->GetAttDefs();
1121 if (pointDefs) {
1122 holder->AddAtts(trajPoint->CreateAttValues(), pointDefs);
1123 }
1124 }
1125 }
1126 }
1127 }
1128
1129 G4HitsModel* hitsModel = dynamic_cast<G4HitsModel*>(fpModel);
1130 if (hitsModel) {
1131 // Load G4Atts from hit...
1132 const G4VHit* hit = hitsModel->GetCurrentHit();
1133 const std::map<G4String,G4AttDef>* hitsDefs = hit->GetAttDefs();
1134 if (hitsDefs) {
1135 holder->AddAtts(hit->CreateAttValues(), hitsDefs);
1136 }
1137 }
1138}
1139
1142 const G4Colour& colour = fpVisAttribs -> GetColour ();
1143 return colour;
1144}
1145
1147 auto pVA = visible.GetVisAttributes();
1149 return pVA->GetColour();
1150}
1151
1153 auto pVA = text.GetVisAttributes();
1155 return pVA->GetColour();
1156}
1157
1159{
1160 G4double lineWidth = pVisAttribs->GetLineWidth();
1161 if (lineWidth < 1.) lineWidth = 1.;
1162 lineWidth *= fpViewer -> GetViewParameters().GetGlobalLineWidthScale();
1163 if (lineWidth < 1.) lineWidth = 1.;
1164 return lineWidth;
1165}
1166
1168(const G4VisAttributes* pVisAttribs) {
1169 // Drawing style is normally determined by the view parameters, but
1170 // it can be overriddden by the ForceDrawingStyle flag in the vis
1171 // attributes.
1173 const G4ViewParameters::DrawingStyle viewerStyle = vp.GetDrawingStyle();
1174 G4ViewParameters::DrawingStyle resultantStyle = viewerStyle;
1175 if (pVisAttribs -> IsForceDrawingStyle ()) {
1177 pVisAttribs -> GetForcedDrawingStyle ();
1178 // This is complicated because if hidden line and surface removal
1179 // has been requested we wish to preserve this sometimes.
1180 switch (forcedStyle) {
1182 switch (viewerStyle) {
1183 case (G4ViewParameters::hlr):
1184 resultantStyle = G4ViewParameters::hlhsr;
1185 break;
1187 resultantStyle = G4ViewParameters::hsr;
1188 break;
1190 resultantStyle = G4ViewParameters::hsr;
1191 break;
1193 case (G4ViewParameters::hsr):
1194 break;
1195 }
1196 break;
1198 resultantStyle = G4ViewParameters::cloud;
1199 break;
1201 default:
1202 // But if forced style is wireframe, do it, because one of its
1203 // main uses is in displaying the consituent solids of a Boolean
1204 // solid and their surfaces overlap with the resulting Booean
1205 // solid, making a mess if hlr is specified.
1206 resultantStyle = G4ViewParameters::wireframe;
1207 break;
1208 }
1209 }
1210 return resultantStyle;
1211}
1212
1214(const G4VisAttributes* pVisAttribs) const {
1215 // Returns no of cloud points from current view parameters, unless the user
1216 // has forced through the vis attributes, thereby over-riding the
1217 // current view parameter.
1218 G4int numberOfCloudPoints = fpViewer->GetViewParameters().GetNumberOfCloudPoints();
1219 if (pVisAttribs -> IsForceDrawingStyle() &&
1220 pVisAttribs -> GetForcedDrawingStyle() == G4VisAttributes::cloud &&
1221 pVisAttribs -> GetForcedNumberOfCloudPoints() > 0) {
1222 numberOfCloudPoints = pVisAttribs -> GetForcedNumberOfCloudPoints();
1223 }
1224 return numberOfCloudPoints;
1225}
1226
1228 G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible ();
1229 if (pVisAttribs -> IsForceAuxEdgeVisible()) {
1230 isAuxEdgeVisible = pVisAttribs->IsForcedAuxEdgeVisible();
1231 }
1232 return isAuxEdgeVisible;
1233}
1234
1236(const G4VMarker& marker,
1237 G4VSceneHandler::MarkerSizeType& markerSizeType)
1238{
1239 G4bool userSpecified = marker.GetWorldSize() || marker.GetScreenSize();
1240 const G4VMarker& defaultMarker =
1241 fpViewer -> GetViewParameters().GetDefaultMarker();
1242 G4double size = userSpecified ?
1243 marker.GetWorldSize() : defaultMarker.GetWorldSize();
1244 if (size) {
1245 // Draw in world coordinates.
1246 markerSizeType = world;
1247 }
1248 else {
1249 size = userSpecified ?
1250 marker.GetScreenSize() : defaultMarker.GetScreenSize();
1251 // Draw in screen coordinates.
1252 markerSizeType = screen;
1253 }
1254 size *= fpViewer -> GetViewParameters().GetGlobalMarkerScale();
1255 if (markerSizeType == screen && size < 1.) size = 1.;
1256 return size;
1257}
1258
1260{
1261 // No. of sides (lines segments per circle) is normally determined
1262 // by the view parameters, but it can be overriddden by the
1263 // ForceLineSegmentsPerCircle in the vis attributes.
1264 G4int lineSegmentsPerCircle = fpViewer->GetViewParameters().GetNoOfSides();
1265 if (pVisAttribs) {
1266 if (pVisAttribs->IsForceLineSegmentsPerCircle())
1267 lineSegmentsPerCircle = pVisAttribs->GetForcedLineSegmentsPerCircle();
1268 if (lineSegmentsPerCircle < pVisAttribs->GetMinLineSegmentsPerCircle()) {
1269 lineSegmentsPerCircle = pVisAttribs->GetMinLineSegmentsPerCircle();
1270 G4warn <<
1271 "G4VSceneHandler::GetNoOfSides: attempt to set the"
1272 "\nnumber of line segments per circle < " << lineSegmentsPerCircle
1273 << "; forced to " << pVisAttribs->GetMinLineSegmentsPerCircle() << G4endl;
1274 }
1275 }
1276 return lineSegmentsPerCircle;
1277}
1278
1279std::ostream& operator << (std::ostream& os, const G4VSceneHandler& sh) {
1280
1281 os << "Scene handler " << sh.fName << " has "
1282 << sh.fViewerList.size () << " viewer(s):";
1283 for (std::size_t i = 0; i < sh.fViewerList.size (); ++i) {
1284 os << "\n " << *(sh.fViewerList [i]);
1285 }
1286
1287 if (sh.fpScene) {
1288 os << "\n " << *sh.fpScene;
1289 }
1290 else {
1291 os << "\n This scene handler currently has no scene.";
1292 }
1293
1294 return os;
1295}
1296
1297void G4VSceneHandler::PseudoSceneFor3DRectMeshPositions::AddSolid(const G4Box&) {
1298 if (fpPVModel->GetCurrentDepth() == fpMesh->GetMeshDepth()) { // Leaf-level cells only
1299 const auto& material = fpPVModel->GetCurrentLV()->GetMaterial();
1300 const auto& name = material? material->GetName(): fpMesh->GetContainerVolume()->GetName();
1301 const auto& pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
1302 // Get position in world coordinates
1303 // As a parameterisation the box is transformed by the current transformation
1304 // and its centre, originally by definition at (0,0,0), is now translated.
1306 fPositionByMaterial.insert(std::make_pair(material,position));
1307 if (fNameAndVisAttsByMaterial.find(material) == fNameAndVisAttsByMaterial.end())
1308 // Store name and vis attributes of first encounter with this material
1309 fNameAndVisAttsByMaterial[material] = NameAndVisAtts(name,*pVisAtts);
1310 }
1311}
1312
1313void G4VSceneHandler::PseudoSceneForTetVertices::AddSolid(const G4VSolid& solid) {
1314 if (fpPVModel->GetCurrentDepth() == fpMesh->GetMeshDepth()) { // Leaf-level cells only
1315 // Need to know it's a tet !!!! or implement G4VSceneHandler::AddSolid (const G4Tet&) !!!!
1316 try {
1317 const auto& tet = dynamic_cast<const G4Tet&>(solid);
1318 const auto& material = fpPVModel->GetCurrentLV()->GetMaterial();
1319 const auto& name = material? material->GetName(): fpMesh->GetContainerVolume()->GetName();
1320 const auto& pVisAtts = fpPVModel->GetCurrentLV()->GetVisAttributes();
1321 // Transform into world coordinates if necessary
1322 if (fpCurrentObjectTransformation->xx() == 1. &&
1323 fpCurrentObjectTransformation->yy() == 1. &&
1324 fpCurrentObjectTransformation->zz() == 1.) { // No transformation necessary
1325 const auto& vertices = tet.GetVertices();
1326 fVerticesByMaterial.insert(std::make_pair(material,vertices));
1327 } else {
1328 auto vertices = tet.GetVertices();
1329 for (auto&& vertex: vertices) {
1330 vertex = G4Point3D(vertex).transform(*fpCurrentObjectTransformation);
1331 }
1332 fVerticesByMaterial.insert(std::make_pair(material,vertices));
1333 }
1334 if (fNameAndVisAttsByMaterial.find(material) == fNameAndVisAttsByMaterial.end())
1335 // Store name and vis attributes of first encounter with this material
1336 fNameAndVisAttsByMaterial[material] = NameAndVisAtts(name,*pVisAtts);
1337 }
1338 catch (const std::bad_cast&) {
1340 ed << "Called for a mesh that is not a tetrahedron mesh: " << solid.GetName();
1341 G4Exception("PseudoSceneForTetVertices","visman0108",JustWarning,ed);
1342 }
1343 }
1344}
1345
1347// Standard way of special mesh rendering.
1348// MySceneHandler::AddCompound(const G4Mesh& mesh) may use this if
1349// appropriate or implement its own special mesh rendereing.
1350{
1351 G4bool implemented = false;
1352 switch (mesh.GetMeshType()) {
1353 case G4Mesh::rectangle: [[fallthrough]];
1357 [[fallthrough]];
1359 Draw3DRectMeshAsDots(mesh); // Rectangular 3-deep mesh as dots
1360 implemented = true;
1361 break;
1363 Draw3DRectMeshAsSurfaces(mesh); // Rectangular 3-deep mesh as surfaces
1364 implemented = true;
1365 break;
1366 }
1367 break;
1371 [[fallthrough]];
1373 DrawTetMeshAsDots(mesh); // Tetrahedron mesh as dots
1374 implemented = true;
1375 break;
1377 DrawTetMeshAsSurfaces(mesh); // Tetrahedron mesh as surfaces
1378 implemented = true;
1379 break;
1380 }
1381 break;
1382 case G4Mesh::cylinder: [[fallthrough]];
1383 case G4Mesh::sphere: [[fallthrough]];
1384 case G4Mesh::invalid: break;
1385 }
1386 if (implemented) {
1387 // Draw container if not marked invisible...
1388 auto container = mesh.GetContainerVolume();
1389 auto containerLogical = container->GetLogicalVolume();
1390 auto containerVisAtts = containerLogical->GetVisAttributes();
1391 if (containerVisAtts == nullptr || containerVisAtts->IsVisible()) {
1392 auto solid = containerLogical->GetSolid();
1393 auto polyhedron = solid->GetPolyhedron();
1394 // Always draw as wireframe
1395 G4VisAttributes tmpVisAtts;
1396 if (containerVisAtts != nullptr) tmpVisAtts = *containerVisAtts;
1397 tmpVisAtts.SetForceWireframe();
1398 polyhedron->SetVisAttributes(tmpVisAtts);
1400 AddPrimitive(*polyhedron);
1401 EndPrimitives();
1402 }
1403 } else {
1404 // Invoke base class function
1406 }
1407 return;
1408}
1409
1411// For a rectangular 3-D mesh, draw as coloured dots by colour and material,
1412// one dot randomly placed in each visible mesh cell.
1413{
1414 // Check
1415 if (mesh.GetMeshType() != G4Mesh::rectangle &&
1418 ed << "Called with a mesh that is not rectangular:" << mesh;
1419 G4Exception("G4VSceneHandler::Draw3DRectMeshAsDots","visman0108",JustWarning,ed);
1420 return;
1421 }
1422
1423 static G4bool firstPrint = true;
1424 const auto& verbosity = G4VisManager::GetVerbosity();
1425 G4bool print = firstPrint && verbosity >= G4VisManager::errors;
1426 if (print) {
1427 G4cout
1428 << "Special case drawing of 3D rectangular G4VNestedParameterisation as dots:"
1429 << '\n' << mesh
1430 << G4endl;
1431 }
1432
1433 const auto& container = mesh.GetContainerVolume();
1434
1435 // This map is static so that once filled it stays filled.
1436 static std::map<G4String,std::map<const G4Material*,G4Polymarker>> dotsByMaterialAndMesh;
1437 auto& dotsByMaterial = dotsByMaterialAndMesh[mesh.GetContainerVolume()->GetName()];
1438
1439 // Fill map if not already filled
1440 if (dotsByMaterial.empty()) {
1441
1442 // Get positions and material one cell at a time (using PseudoSceneFor3DRectMeshPositions).
1443 // The pseudo scene allows a "private" descent into the parameterisation.
1444 // Instantiate a temporary G4PhysicalVolumeModel
1446 tmpMP.SetCulling(true); // This avoids drawing transparent...
1447 tmpMP.SetCullingInvisible(true); // ... or invisble volumes.
1448 const G4bool useFullExtent = true; // To avoid calculating the extent
1449 G4PhysicalVolumeModel tmpPVModel
1450 (container,
1452 G4Transform3D(), // so that positions are in local coordinates
1453 &tmpMP,
1454 useFullExtent);
1455 // Accumulate information in temporary maps by material
1456 std::multimap<const G4Material*,const G4ThreeVector> positionByMaterial;
1457 std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
1458 // Instantiate the pseudo scene
1460 (&tmpPVModel,&mesh,positionByMaterial,nameAndVisAttsByMaterial);
1461 // Make private descent into the parameterisation
1462 tmpPVModel.DescribeYourselfTo(pseudoScene);
1463 // Now we have a map of positions by material.
1464 // Also a map of name and colour by material.
1465
1466 const auto& prms = mesh.GetThreeDRectParameters();
1467 const auto& halfX = prms.fHalfX;
1468 const auto& halfY = prms.fHalfY;
1469 const auto& halfZ = prms.fHalfZ;
1470
1471 // Fill the permanent (static) map of dots by material
1472 G4int nDotsTotal = 0;
1473 for (const auto& entry: nameAndVisAttsByMaterial) {
1474 G4int nDots = 0;
1475 const auto& material = entry.first;
1476 const auto& nameAndVisAtts = nameAndVisAttsByMaterial[material];
1477 const auto& name = nameAndVisAtts.fName;
1478 const auto& visAtts = nameAndVisAtts.fVisAtts;
1479 G4Polymarker dots;
1480 dots.SetInfo(name);
1481 dots.SetVisAttributes(visAtts);
1483 dots.SetSize(G4VMarker::screen,1.);
1484 // Enter empty polymarker into the map
1485 dotsByMaterial[material] = dots;
1486 // Now fill it in situ
1487 auto& dotsInMap = dotsByMaterial[material];
1488 const auto& range = positionByMaterial.equal_range(material);
1489 for (auto posByMat = range.first; posByMat != range.second; ++posByMat) {
1490 dotsInMap.push_back(GetPointInBox(posByMat->second, halfX, halfY, halfZ));
1491 ++nDots;
1492 }
1493
1494 if (print) {
1495 G4cout
1496 << std::setw(30) << std::left << name.substr(0,30) << std::right
1497 << ": " << std::setw(7) << nDots << " dots"
1498 << ": colour " << std::fixed << std::setprecision(2)
1499 << visAtts.GetColour() << std::defaultfloat
1500 << G4endl;
1501 }
1502
1503 nDotsTotal += nDots;
1504 }
1505
1506 if (print) {
1507 G4cout << "Total number of dots: " << nDotsTotal << G4endl;
1508 }
1509 }
1510
1511 // Some subsequent expressions apply only to G4PhysicalVolumeModel
1512 auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1513
1514 G4String parameterisationName;
1515 if (pPVModel) {
1516 parameterisationName = pPVModel->GetFullPVPath().back().GetPhysicalVolume()->GetName();
1517 }
1518
1519 // Draw the dots by material
1520 // Ensure they are "hidden", i.e., use the z-buffer as non-marker primitives do
1521 auto keepVP = fpViewer->GetViewParameters();
1522 auto vp = fpViewer->GetViewParameters();
1523 vp.SetMarkerHidden();
1525 // Now we transform to world coordinates
1527 for (const auto& entry: dotsByMaterial) {
1528 const auto& dots = entry.second;
1529 // The current "leaf" node in the PVPath is the parameterisation. Here it has
1530 // been converted into polymarkers by material. So...temporarily...change
1531 // its name to that of the material (whose name has been stored in Info)
1532 // so that its appearance in the scene tree of, e.g., G4OpenGLQtViewer, has
1533 // an appropriate name and its visibility and colour may be changed.
1534 if (pPVModel) {
1535 const auto& fullPVPath = pPVModel->GetFullPVPath();
1536 auto leafPV = fullPVPath.back().GetPhysicalVolume();
1537 leafPV->SetName(dots.GetInfo());
1538 }
1539 // Add dots to the scene
1540 AddPrimitive(dots);
1541 }
1542 EndPrimitives ();
1543 // Restore view parameters
1544 fpViewer->SetViewParameters(keepVP);
1545 // Restore parameterisation name
1546 if (pPVModel) {
1547 pPVModel->GetFullPVPath().back().GetPhysicalVolume()->SetName(parameterisationName);
1548 }
1549
1550 firstPrint = false;
1551 return;
1552}
1553
1555// For a rectangular 3-D mesh, draw as surfaces by colour and material
1556// with inner shared faces removed.
1557{
1558 // Check
1559 if (mesh.GetMeshType() != G4Mesh::rectangle &&
1562 ed << "Called with a mesh that is not rectangular:" << mesh;
1563 G4Exception("G4VSceneHandler::Draw3DRectMeshAsSurfaces","visman0108",JustWarning,ed);
1564 return;
1565 }
1566
1567 static G4bool firstPrint = true;
1568 const auto& verbosity = G4VisManager::GetVerbosity();
1569 G4bool print = firstPrint && verbosity >= G4VisManager::errors;
1570 if (print) {
1571 G4cout
1572 << "Special case drawing of 3D rectangular G4VNestedParameterisation as surfaces:"
1573 << '\n' << mesh
1574 << G4endl;
1575 }
1576
1577 const auto& container = mesh.GetContainerVolume();
1578
1579 // This map is static so that once filled it stays filled.
1580 static std::map<G4String,std::map<const G4Material*,G4Polyhedron>> boxesByMaterialAndMesh;
1581 auto& boxesByMaterial = boxesByMaterialAndMesh[mesh.GetContainerVolume()->GetName()];
1582
1583 // Fill map if not already filled
1584 if (boxesByMaterial.empty()) {
1585
1586 // Get positions and material one cell at a time (using PseudoSceneFor3DRectMeshPositions).
1587 // The pseudo scene allows a "private" descent into the parameterisation.
1588 // Instantiate a temporary G4PhysicalVolumeModel
1590 tmpMP.SetCulling(true); // This avoids drawing transparent...
1591 tmpMP.SetCullingInvisible(true); // ... or invisble volumes.
1592 const G4bool useFullExtent = true; // To avoid calculating the extent
1593 G4PhysicalVolumeModel tmpPVModel
1594 (container,
1596 G4Transform3D(), // so that positions are in local coordinates
1597 &tmpMP,
1598 useFullExtent);
1599 // Accumulate information in temporary maps by material
1600 std::multimap<const G4Material*,const G4ThreeVector> positionByMaterial;
1601 std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
1602 // Instantiate the pseudo scene
1604 (&tmpPVModel,&mesh,positionByMaterial,nameAndVisAttsByMaterial);
1605 // Make private descent into the parameterisation
1606 tmpPVModel.DescribeYourselfTo(pseudoScene);
1607 // Now we have a map of positions by material.
1608 // Also a map of name and colour by material.
1609
1610 const auto& prms = mesh.GetThreeDRectParameters();
1611 const auto& sizeX = 2.*prms.fHalfX;
1612 const auto& sizeY = 2.*prms.fHalfY;
1613 const auto& sizeZ = 2.*prms.fHalfZ;
1614
1615 // Fill the permanent (static) map of boxes by material
1616 G4int nBoxesTotal = 0, nFacetsTotal = 0;
1617 for (const auto& entry: nameAndVisAttsByMaterial) {
1618 G4int nBoxes = 0;
1619 const auto& material = entry.first;
1620 const auto& nameAndVisAtts = nameAndVisAttsByMaterial[material];
1621 const auto& name = nameAndVisAtts.fName;
1622 const auto& visAtts = nameAndVisAtts.fVisAtts;
1623 // Transfer positions into a vector ready for creating polyhedral surface
1624 std::vector<G4ThreeVector> positionsForPolyhedron;
1625 const auto& range = positionByMaterial.equal_range(material);
1626 for (auto posByMat = range.first; posByMat != range.second; ++posByMat) {
1627 const auto& position = posByMat->second;
1628 positionsForPolyhedron.push_back(position);
1629 ++nBoxes;
1630 }
1631 // The polyhedron will be in local coordinates
1632 // Add an empty place-holder to the map and get a reference to it
1633 auto& polyhedron = boxesByMaterial[material];
1634 // Replace with the desired polyhedron (uses efficient "move assignment")
1635 polyhedron = G4PolyhedronBoxMesh(sizeX,sizeY,sizeZ,positionsForPolyhedron);
1636 polyhedron.SetVisAttributes(visAtts);
1637 polyhedron.SetInfo(name);
1638
1639 if (print) {
1640 G4cout
1641 << std::setw(30) << std::left << name.substr(0,30) << std::right
1642 << ": " << std::setw(7) << nBoxes << " boxes"
1643 << " (" << std::setw(7) << 6*nBoxes << " faces)"
1644 << ": reduced to " << std::setw(7) << polyhedron.GetNoFacets() << " facets ("
1645 << std::setw(2) << std::fixed << std::setprecision(2) << 100*polyhedron.GetNoFacets()/(6*nBoxes)
1646 << "%): colour " << std::fixed << std::setprecision(2)
1647 << visAtts.GetColour() << std::defaultfloat
1648 << G4endl;
1649 }
1650
1651 nBoxesTotal += nBoxes;
1652 nFacetsTotal += polyhedron.GetNoFacets();
1653 }
1654
1655 if (print) {
1656 G4cout << "Total number of boxes: " << nBoxesTotal << " (" << 6*nBoxesTotal << " faces)"
1657 << ": reduced to " << nFacetsTotal << " facets ("
1658 << std::setw(2) << std::fixed << std::setprecision(2) << 100*nFacetsTotal/(6*nBoxesTotal) << "%)"
1659 << G4endl;
1660 }
1661 }
1662
1663 // Some subsequent expressions apply only to G4PhysicalVolumeModel
1664 auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1665
1666 G4String parameterisationName;
1667 if (pPVModel) {
1668 parameterisationName = pPVModel->GetFullPVPath().back().GetPhysicalVolume()->GetName();
1669 }
1670
1671 // Draw the boxes by material
1672 // Now we transform to world coordinates
1674 for (const auto& entry: boxesByMaterial) {
1675 const auto& poly = entry.second;
1676 // The current "leaf" node in the PVPath is the parameterisation. Here it has
1677 // been converted into polyhedra by material. So...temporarily...change
1678 // its name to that of the material (whose name has been stored in Info)
1679 // so that its appearance in the scene tree of, e.g., G4OpenGLQtViewer, has
1680 // an appropriate name and its visibility and colour may be changed.
1681 if (pPVModel) {
1682 const auto& fullPVPath = pPVModel->GetFullPVPath();
1683 auto leafPV = fullPVPath.back().GetPhysicalVolume();
1684 leafPV->SetName(poly.GetInfo());
1685 }
1686 AddPrimitive(poly);
1687 }
1688 EndPrimitives ();
1689 // Restore parameterisation name
1690 if (pPVModel) {
1691 pPVModel->GetFullPVPath().back().GetPhysicalVolume()->SetName(parameterisationName);
1692 }
1693
1694 firstPrint = false;
1695 return;
1696}
1697
1699// For a tetrahedron mesh, draw as coloured dots by colour and material,
1700// one dot randomly placed in each visible mesh cell.
1701{
1702 // Check
1703 if (mesh.GetMeshType() != G4Mesh::tetrahedron) {
1705 ed << "Called with mesh that is not a tetrahedron mesh:" << mesh;
1706 G4Exception("G4VSceneHandler::DrawTetMeshAsDots","visman0108",JustWarning,ed);
1707 return;
1708 }
1709
1710 static G4bool firstPrint = true;
1711 const auto& verbosity = G4VisManager::GetVerbosity();
1712 G4bool print = firstPrint && verbosity >= G4VisManager::errors;
1713
1714 if (print) {
1715 G4cout
1716 << "Special case drawing of tetrahedron mesh as dots"
1717 << '\n' << mesh
1718 << G4endl;
1719 }
1720
1721 const auto& container = mesh.GetContainerVolume();
1722
1723 // This map is static so that once filled it stays filled.
1724 static std::map<G4String,std::map<const G4Material*,G4Polymarker>> dotsByMaterialAndMesh;
1725 auto& dotsByMaterial = dotsByMaterialAndMesh[mesh.GetContainerVolume()->GetName()];
1726
1727 // Fill map if not already filled
1728 if (dotsByMaterial.empty()) {
1729
1730 // Get vertices and colour one cell at a time (using PseudoSceneForTetVertices).
1731 // The pseudo scene allows a "private" descent into the parameterisation.
1732 // Instantiate a temporary G4PhysicalVolumeModel
1734 tmpMP.SetCulling(true); // This avoids drawing transparent...
1735 tmpMP.SetCullingInvisible(true); // ... or invisble volumes.
1736 const G4bool useFullExtent = true; // To avoid calculating the extent
1737 G4PhysicalVolumeModel tmpPVModel
1738 (container,
1740 G4Transform3D(), // so that positions are in local coordinates
1741 &tmpMP,
1742 useFullExtent);
1743 // Accumulate information in temporary maps by material
1744 std::multimap<const G4Material*,std::vector<G4ThreeVector>> verticesByMaterial;
1745 std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
1746 // Instantiate a pseudo scene
1747 PseudoSceneForTetVertices pseudoScene
1748 (&tmpPVModel,&mesh,verticesByMaterial,nameAndVisAttsByMaterial);
1749 // Make private descent into the parameterisation
1750 tmpPVModel.DescribeYourselfTo(pseudoScene);
1751 // Now we have a map of vertices by material.
1752 // Also a map of name and colour by material.
1753
1754 // Fill the permanent (static) map of dots by material
1755 G4int nDotsTotal = 0;
1756 for (const auto& entry: nameAndVisAttsByMaterial) {
1757 G4int nDots = 0;
1758 const auto& material = entry.first;
1759 const auto& nameAndVisAtts = nameAndVisAttsByMaterial[material];
1760 const auto& name = nameAndVisAtts.fName;
1761 const auto& visAtts = nameAndVisAtts.fVisAtts;
1762 G4Polymarker dots;
1763 dots.SetVisAttributes(visAtts);
1765 dots.SetSize(G4VMarker::screen,1.);
1766 dots.SetInfo(name);
1767 // Enter empty polymarker into the map
1768 dotsByMaterial[material] = dots;
1769 // Now fill it in situ
1770 auto& dotsInMap = dotsByMaterial[material];
1771 const auto& range = verticesByMaterial.equal_range(material);
1772 for (auto vByMat = range.first; vByMat != range.second; ++vByMat) {
1773 dotsInMap.push_back(GetPointInTet(vByMat->second));
1774 ++nDots;
1775 }
1776
1777 if (print) {
1778 G4cout
1779 << std::setw(30) << std::left << name.substr(0,30) << std::right
1780 << ": " << std::setw(7) << nDots << " dots"
1781 << ": colour " << std::fixed << std::setprecision(2)
1782 << visAtts.GetColour() << std::defaultfloat
1783 << G4endl;
1784 }
1785
1786 nDotsTotal += nDots;
1787 }
1788
1789 if (print) {
1790 G4cout << "Total number of dots: " << nDotsTotal << G4endl;
1791 }
1792 }
1793
1794 // Some subsequent expressions apply only to G4PhysicalVolumeModel
1795 auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1796
1797 G4String parameterisationName;
1798 if (pPVModel) {
1799 parameterisationName = pPVModel->GetFullPVPath().back().GetPhysicalVolume()->GetName();
1800 }
1801
1802 // Draw the dots by material
1803 // Ensure they are "hidden", i.e., use the z-buffer as non-marker primitives do
1804 auto keepVP = fpViewer->GetViewParameters();
1805 auto vp = fpViewer->GetViewParameters();
1806 vp.SetMarkerHidden();
1808
1809 // Now we transform to world coordinates
1811 for (const auto& entry: dotsByMaterial) {
1812 const auto& dots = entry.second;
1813 // The current "leaf" node in the PVPath is the parameterisation. Here it has
1814 // been converted into polymarkers by material. So...temporarily...change
1815 // its name to that of the material (whose name has been stored in Info)
1816 // so that its appearance in the scene tree of, e.g., G4OpenGLQtViewer, has
1817 // an appropriate name and its visibility and colour may be changed.
1818 if (pPVModel) {
1819 const auto& fullPVPath = pPVModel->GetFullPVPath();
1820 auto leafPV = fullPVPath.back().GetPhysicalVolume();
1821 leafPV->SetName(dots.GetInfo());
1822 }
1823 AddPrimitive(dots);
1824 }
1825 EndPrimitives ();
1826
1827 // Restore view parameters
1828 fpViewer->SetViewParameters(keepVP);
1829 // Restore parameterisation name
1830 if (pPVModel) {
1831 pPVModel->GetFullPVPath().back().GetPhysicalVolume()->SetName(parameterisationName);
1832 }
1833
1834 firstPrint = false;
1835 return;
1836}
1837
1839// For a tetrahedron mesh, draw as surfaces by colour and material
1840// with inner shared faces removed.
1841{
1842 // Check
1843 if (mesh.GetMeshType() != G4Mesh::tetrahedron) {
1845 ed << "Called with mesh that is not a tetrahedron mesh:" << mesh;
1846 G4Exception("G4VSceneHandler::DrawTetMeshAsSurfaces","visman0108",JustWarning,ed);
1847 return;
1848 }
1849
1850 static G4bool firstPrint = true;
1851 const auto& verbosity = G4VisManager::GetVerbosity();
1852 G4bool print = firstPrint && verbosity >= G4VisManager::errors;
1853
1854 if (print) {
1855 G4cout
1856 << "Special case drawing of tetrahedron mesh as surfaces"
1857 << '\n' << mesh
1858 << G4endl;
1859 }
1860
1861 // This map is static so that once filled it stays filled.
1862 static std::map<G4String,std::map<const G4Material*,G4Polyhedron>> surfacesByMaterialAndMesh;
1863 auto& surfacesByMaterial = surfacesByMaterialAndMesh[mesh.GetContainerVolume()->GetName()];
1864
1865 // Fill map if not already filled
1866 if (surfacesByMaterial.empty()) {
1867
1868 // Get vertices and colour one cell at a time (using PseudoSceneForTetVertices).
1869 // The pseudo scene allows a "private" descent into the parameterisation.
1870 // Instantiate a temporary G4PhysicalVolumeModel
1872 tmpMP.SetCulling(true); // This avoids drawing transparent...
1873 tmpMP.SetCullingInvisible(true); // ... or invisble volumes.
1874 const G4bool useFullExtent = true; // To avoid calculating the extent
1875 G4PhysicalVolumeModel tmpPVModel
1876 (mesh.GetContainerVolume(),
1878 G4Transform3D(), // so that positions are in local coordinates
1879 &tmpMP,
1880 useFullExtent);
1881 // Accumulate information in temporary maps by material
1882 std::multimap<const G4Material*,std::vector<G4ThreeVector>> verticesByMaterial;
1883 std::map<const G4Material*,G4VSceneHandler::NameAndVisAtts> nameAndVisAttsByMaterial;
1884 // Instantiate a pseudo scene
1885 PseudoSceneForTetVertices pseudoScene
1886 (&tmpPVModel,&mesh,verticesByMaterial,nameAndVisAttsByMaterial);
1887 // Make private descent into the parameterisation
1888 tmpPVModel.DescribeYourselfTo(pseudoScene);
1889 // Now we have a map of vertices by material.
1890 // Also a map of name and colour by material.
1891
1892 // Fill the permanent (static) map of surfaces by material
1893 G4int nTetsTotal = 0, nFacetsTotal = 0;
1894 for (const auto& entry: nameAndVisAttsByMaterial) {
1895 G4int nTets = 0;
1896 const auto& material = entry.first;
1897 const auto& nameAndVisAtts = nameAndVisAttsByMaterial[material];
1898 const auto& name = nameAndVisAtts.fName;
1899 const auto& visAtts = nameAndVisAtts.fVisAtts;
1900 // Transfer vertices into a vector ready for creating polyhedral surface
1901 std::vector<G4ThreeVector> verticesForPolyhedron;
1902 const auto& range = verticesByMaterial.equal_range(material);
1903 for (auto vByMat = range.first; vByMat != range.second; ++vByMat) {
1904 const std::vector<G4ThreeVector>& vertices = vByMat->second;
1905 for (const auto& vertex: vertices)
1906 verticesForPolyhedron.push_back(vertex);
1907 ++nTets;
1908 }
1909 // The polyhedron will be in local coordinates
1910 // Add an empty place-holder to the map and get a reference to it
1911 auto& polyhedron = surfacesByMaterial[material];
1912 // Replace with the desired polyhedron (uses efficient "move assignment")
1913 polyhedron = G4PolyhedronTetMesh(verticesForPolyhedron);
1914 polyhedron.SetVisAttributes(visAtts);
1915 polyhedron.SetInfo(name);
1916
1917 if (print) {
1918 G4cout
1919 << std::setw(30) << std::left << name.substr(0,30) << std::right
1920 << ": " << std::setw(7) << nTets << " tetrahedra"
1921 << " (" << std::setw(7) << 4*nTets << " faces)"
1922 << ": reduced to " << std::setw(7) << polyhedron.GetNoFacets() << " facets ("
1923 << std::setw(2) << std::fixed << std::setprecision(2) << 100*polyhedron.GetNoFacets()/(4*nTets)
1924 << "%): colour " << std::fixed << std::setprecision(2)
1925 << visAtts.GetColour() << std::defaultfloat
1926 << G4endl;
1927 }
1928
1929 nTetsTotal += nTets;
1930 nFacetsTotal += polyhedron.GetNoFacets();
1931 }
1932
1933 if (print) {
1934 G4cout << "Total number of tetrahedra: " << nTetsTotal << " (" << 4*nTetsTotal << " faces)"
1935 << ": reduced to " << nFacetsTotal << " facets ("
1936 << std::setw(2) << std::fixed << std::setprecision(2) << 100*nFacetsTotal/(4*nTetsTotal) << "%)"
1937 << G4endl;
1938 }
1939 }
1940
1941 // Some subsequent expressions apply only to G4PhysicalVolumeModel
1942 auto pPVModel = dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
1943
1944 G4String parameterisationName;
1945 if (pPVModel) {
1946 parameterisationName = pPVModel->GetFullPVPath().back().GetPhysicalVolume()->GetName();
1947 }
1948
1949 // Draw the surfaces by material
1950 // Now we transform to world coordinates
1952 for (const auto& entry: surfacesByMaterial) {
1953 const auto& poly = entry.second;
1954 // The current "leaf" node in the PVPath is the parameterisation. Here it has
1955 // been converted into polyhedra by material. So...temporarily...change
1956 // its name to that of the material (whose name has been stored in Info)
1957 // so that its appearance in the scene tree of, e.g., G4OpenGLQtViewer, has
1958 // an appropriate name and its visibility and colour may be changed.
1959 if (pPVModel) {
1960 const auto& fullPVPath = pPVModel->GetFullPVPath();
1961 auto leafPV = fullPVPath.back().GetPhysicalVolume();
1962 leafPV->SetName(poly.GetInfo());
1963 }
1964 AddPrimitive(poly);
1965 }
1966 EndPrimitives ();
1967
1968 // Restore parameterisation name
1969 if (pPVModel) {
1970 pPVModel->GetFullPVPath().back().GetPhysicalVolume()->SetName(parameterisationName);
1971 }
1972
1973 firstPrint = false;
1974 return;
1975}
1976
1979 G4double halfX,
1980 G4double halfY,
1981 G4double halfZ) const
1982{
1983 G4double x = pos.getX() + (2.*G4QuickRand() - 1.)*halfX;
1984 G4double y = pos.getY() + (2.*G4QuickRand() - 1.)*halfY;
1985 G4double z = pos.getZ() + (2.*G4QuickRand() - 1.)*halfZ;
1986 return G4ThreeVector(x, y, z);
1987}
1988
1990G4VSceneHandler::GetPointInTet(const std::vector<G4ThreeVector>& vertices) const
1991{
1992 G4double p = G4QuickRand();
1993 G4double q = G4QuickRand();
1994 G4double r = G4QuickRand();
1995 if (p + q > 1.)
1996 {
1997 p = 1. - p;
1998 q = 1. - q;
1999 }
2000 if (q + r > 1.)
2001 {
2002 G4double tmp = r;
2003 r = 1. - p - q;
2004 q = 1. - tmp;
2005 }
2006 else if (p + q + r > 1.)
2007 {
2008 G4double tmp = r;
2009 r = p + q + r - 1.;
2010 p = 1. - q - tmp;
2011 }
2012 G4double a = 1. - p - q - r;
2013 return vertices[0]*a + vertices[1]*p + vertices[2]*q + vertices[3]*r;
2014}
G4ApplicationState
@ G4State_Idle
@ G4State_GeomClosed
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
HepGeom::Point3D< G4double > G4Point3D
Definition G4Point3D.hh:34
G4double G4QuickRand()
#define G4warn
Definition G4Scene.cc:41
CLHEP::Hep3Vector G4ThreeVector
HepGeom::Transform3D G4Transform3D
HepGeom::Translate3D G4Translate3D
HepGeom::Rotate3D G4Rotate3D
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
std::ostream & operator<<(std::ostream &os, const G4VSceneHandler &sh)
std::vector< G4VViewer * >::iterator G4ViewerListIterator
void print(G4double elem)
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double z() const
Hep3Vector orthogonal() const
double x() const
double y() const
void AddAtts(const std::vector< G4AttValue > *values, const std::map< G4String, G4AttDef > *defs)
Definition G4Box.hh:56
const G4VHit * GetCurrentHit() const
G4VSolid * GetSolid() const
const G4VisAttributes * GetVisAttributes() const
G4Material * GetMaterial() const
MeshType GetMeshType() const
Definition G4Mesh.hh:75
G4VPhysicalVolume * GetContainerVolume() const
Definition G4Mesh.hh:73
const G4Transform3D & GetTransform() const
Definition G4Mesh.hh:77
@ invalid
Definition G4Mesh.hh:52
@ rectangle
Definition G4Mesh.hh:53
@ nested3DRectangular
Definition G4Mesh.hh:54
@ sphere
Definition G4Mesh.hh:56
@ cylinder
Definition G4Mesh.hh:55
@ tetrahedron
Definition G4Mesh.hh:57
const ThreeDRectangleParameters & GetThreeDRectParameters() const
Definition G4Mesh.hh:78
G4int GetMeshDepth() const
Definition G4Mesh.hh:76
void SetCBDParameters(const std::vector< G4double > &)
void SetWarning(G4bool)
void SetNumberOfCloudPoints(G4int)
void SetCBDAlgorithmNumber(G4int)
void SetExplodeFactor(G4double explodeFactor)
void SetVisAttributesModifiers(const std::vector< VisAttributesModifier > &)
void SetExplodeCentre(const G4Point3D &explodeCentre)
void SetCutawayMode(CutawayMode)
void SetCutawaySolid(G4DisplacedSolid *pCutawaySolid)
void SetCulling(G4bool)
void SetSectionSolid(G4DisplacedSolid *pSectionSolid)
void SetEvent(const G4Event *pEvent)
void SetCullingInvisible(G4bool)
void SetSpecialMeshVolumes(const std::vector< PVNameCopyNo > &)
void SetSpecialMeshRendering(G4bool)
Definition G4Orb.hh:56
std::vector< G4AttValue > * CreateCurrentAttValues() const
void DescribeYourselfTo(G4VGraphicsScene &)
G4LogicalVolume * GetCurrentLV() const
const std::vector< G4PhysicalVolumeNodeID > & GetFullPVPath() const
const std::map< G4String, G4AttDef > * GetAttDefs() const
void SetMarkerType(MarkerType)
MarkerType GetMarkerType() const
const G4Transform3D * fpCurrentObjectTransformation
static G4RunManager * GetMasterRunManager()
const G4Run * GetCurrentRun() const
Definition G4Run.hh:49
std::vector< const G4Event * > * GetEventVector() const
Definition G4Run.hh:104
const std::vector< Model > & GetRunDurationModelList() const
G4bool GetRefreshAtEndOfEvent() const
const G4VisExtent & GetExtent() const
G4bool GetRefreshAtEndOfRun() const
G4VScoringMesh * GetMesh(G4int i) const
size_t GetNumberOfMesh() const
static G4ScoringManager * GetScoringManagerIfExist()
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
Definition G4Tet.hh:56
const G4VTrajectory * GetCurrentTrajectory() const
std::vector< G4AttValue > * CreateCurrentAttValues() const
const std::map< G4String, G4AttDef > * GetAttDefs() const
Definition G4Trd.hh:63
const G4String & GetName() const
virtual std::vector< G4AttValue > * CreateAttValues() const
Definition G4VHit.hh:69
virtual const std::map< G4String, G4AttDef > * GetAttDefs() const
Definition G4VHit.hh:62
G4double GetScreenSize() const
void SetSize(SizeType, G4double)
Definition G4VMarker.cc:86
void SetScreenSize(G4double)
void SetWorldSize(G4double)
void SetPosition(const G4Point3D &)
G4double GetWorldSize() const
void SetModelingParameters(const G4ModelingParameters *)
virtual void DescribeYourselfTo(G4VGraphicsScene &)=0
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
virtual void BeginModeling()
G4int GetNumberOfCloudPoints(const G4VisAttributes *) const
G4int GetNoOfSides(const G4VisAttributes *)
void DrawTetMeshAsSurfaces(const G4Mesh &)
virtual void ClearTransientStore()
void LoadAtts(const G4Visible &, G4AttHolder *)
void DrawEvent(const G4Event *)
G4ModelingParameters * CreateModelingParameters()
const G4Colour & GetTextColour(const G4Text &)
const G4Colour & GetColour()
void Draw3DRectMeshAsDots(const G4Mesh &)
void AddSolidT(const T &solid)
G4Transform3D fObjectTransformation
virtual void EndPrimitives()
G4bool fTransientsDrawnThisEvent
void AddSolidWithAuxiliaryEdges(const T &solid)
virtual G4DisplacedSolid * CreateSectionSolid()
virtual void EndModeling()
virtual const G4VisExtent & GetExtent() const
G4ViewerList fViewerList
virtual void ProcessScene()
G4double GetMarkerSize(const G4VMarker &, MarkerSizeType &)
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &)
G4VSceneHandler(G4VGraphicsSystem &system, G4int id, const G4String &name="")
virtual void PostAddSolid()
const G4String & GetName() const
void AddViewerToList(G4VViewer *pView)
virtual void EndPrimitives2D()
virtual void SetScene(G4Scene *)
G4bool fMarkForClearingTransientStore
const G4VisAttributes * fpVisAttribs
virtual void BeginPrimitives2D(const G4Transform3D &objectTransformation=G4Transform3D())
G4ThreeVector GetPointInBox(const G4ThreeVector &pos, G4double halfX, G4double halfY, G4double halfZ) const
virtual void RequestPrimitives(const G4VSolid &solid)
G4ViewParameters::DrawingStyle GetDrawingStyle(const G4VisAttributes *)
void RemoveViewerFromList(G4VViewer *pView)
virtual G4DisplacedSolid * CreateCutawaySolid()
void DrawTetMeshAsDots(const G4Mesh &)
virtual void BeginPrimitives(const G4Transform3D &objectTransformation=G4Transform3D())
G4double GetLineWidth(const G4VisAttributes *)
G4ThreeVector GetPointInTet(const std::vector< G4ThreeVector > &vertices) const
G4VGraphicsSystem & fSystem
virtual void AddSolid(const G4Box &)
virtual void ClearStore()
void Draw3DRectMeshAsSurfaces(const G4Mesh &)
virtual void AddCompound(const G4VTrajectory &)
virtual ~G4VSceneHandler()
virtual void AddPrimitive(const G4Polyline &)=0
G4bool GetAuxEdgeVisible(const G4VisAttributes *)
void StandardSpecialMeshRendering(const G4Mesh &)
G4bool IsActive() const
std::map< G4String, RunScore * > MeshScoreMap
void DrawMesh(const G4String &psName, G4VScoreColorMap *colorMap, G4int axflg=111)
MeshScoreMap GetScoreMap() const
G4String GetName() const
virtual G4ThreeVector GetPointOnSurface() const
Definition G4VSolid.cc:152
virtual G4Polyhedron * GetPolyhedron() const
Definition G4VSolid.cc:705
virtual std::vector< G4AttValue > * CreateAttValues() const
virtual const std::map< G4String, G4AttDef > * GetAttDefs() const
virtual G4VTrajectoryPoint * GetPoint(G4int i) const =0
virtual G4int GetPointEntries() const =0
virtual std::vector< G4AttValue > * CreateAttValues() const
virtual void DrawTrajectory() const
virtual const std::map< G4String, G4AttDef > * GetAttDefs() const
void SetViewer(G4VViewer *pViewer)
Definition G4VViewer.hh:176
const G4VisAttributes * GetApplicableVisAttributes(const G4VisAttributes *) const
const G4ViewParameters & GetViewParameters() const
G4SceneTreeItem & AccessSceneTree()
Definition G4VViewer.hh:191
void SetViewParameters(const G4ViewParameters &vp)
Definition G4VViewer.cc:128
SceneTreeScene & AccessSceneTreeScene()
Definition G4VViewer.hh:190
static G4VVisManager * GetConcreteInstance()
const std::vector< G4ModelingParameters::VisAttributesModifier > & GetVisAttributesModifiers() const
G4int GetNoOfSides() const
G4bool IsSpecialMeshRendering() const
CutawayMode GetCutawayMode() const
G4double GetExplodeFactor() const
G4int GetNumberOfCloudPoints() const
G4bool IsCutaway() const
G4bool IsSection() const
G4bool IsCulling() const
void SetMarkerHidden()
const G4VisAttributes * GetDefaultTextVisAttributes() const
const std::vector< G4double > & GetCBDParameters() const
G4int GetCBDAlgorithmNumber() const
const std::vector< G4ModelingParameters::PVNameCopyNo > & GetSpecialMeshVolumes() const
G4bool IsCullingInvisible() const
const G4VisAttributes * GetDefaultVisAttributes() const
const G4Planes & GetCutawayPlanes() const
G4bool IsDensityCulling() const
G4double GetVisibleDensity() const
SMROption GetSpecialMeshRenderingOption() const
const G4Point3D & GetExplodeCentre() const
G4bool IsCullingCovered() const
const G4Plane3D & GetSectionPlane() const
DrawingStyle GetDrawingStyle() const
G4bool IsAuxEdgeVisible() const
void remove(G4VViewer *)
const std::map< G4String, G4AttDef > * GetAttDefs() const
G4bool IsForceLineSegmentsPerCircle() const
G4double GetLineWidth() const
void SetColour(const G4Colour &)
void SetVisibility(G4bool=true)
void SetForceAuxEdgeVisible(G4bool=true)
G4int GetForcedLineSegmentsPerCircle() const
void SetForceWireframe(G4bool=true)
const std::vector< G4AttValue > * CreateAttValues() const
const G4Colour & GetColour() const
G4bool IsForceAuxEdgeVisible() const
G4bool IsForcedAuxEdgeVisible() const
static G4int GetMinLineSegmentsPerCircle()
static const G4VisExtent & GetNullExtent()
G4double GetExtentRadius() const
const G4Point3D & GetExtentCentre() const
void SetEventRefreshing(G4bool)
G4bool GetTransientsDrawnThisEvent() const
G4bool GetTransientsDrawnThisRun() const
static Verbosity GetVerbosity()
const G4Event * GetRequestedEvent() const
static G4VisManager * GetInstance()
void SetVisAttributes(const G4VisAttributes *)
Definition G4Visible.cc:98
const G4VisAttributes * GetVisAttributes() const
virtual void SetInfo(const G4String &info)
CLHEP::Hep3Vector getTranslation() const
static void SetNumberOfRotationSteps(G4int n)
static void ResetNumberOfRotationSteps()
@ kInside
Definition geomdefs.hh:70
const char * name(G4int ptype)