Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // >> 27 // $Id: G4VSceneHandler.cc,v 1.82 2007/05/16 15:47:44 allison Exp $ >> 28 // GEANT4 tag $Name: geant4-09-00-patch-01 $ 27 // 29 // 28 // 30 // 29 // John Allison 19th July 1996 31 // John Allison 19th July 1996 30 // Abstract interface class for graphics scene 32 // Abstract interface class for graphics scenes. 31 33 32 #include "G4VSceneHandler.hh" 34 #include "G4VSceneHandler.hh" 33 35 34 #include "G4ios.hh" 36 #include "G4ios.hh" 35 #include <sstream> 37 #include <sstream> 36 38 37 #include "G4VisManager.hh" 39 #include "G4VisManager.hh" 38 #include "G4VGraphicsSystem.hh" 40 #include "G4VGraphicsSystem.hh" 39 #include "G4VViewer.hh" 41 #include "G4VViewer.hh" 40 #include "G4VSolid.hh" 42 #include "G4VSolid.hh" 41 #include "G4RotationMatrix.hh" 43 #include "G4RotationMatrix.hh" 42 #include "G4ThreeVector.hh" 44 #include "G4ThreeVector.hh" 43 #include "G4VPhysicalVolume.hh" 45 #include "G4VPhysicalVolume.hh" 44 #include "G4Material.hh" 46 #include "G4Material.hh" 45 #include "G4Polyline.hh" 47 #include "G4Polyline.hh" >> 48 #include "G4Scale.hh" 46 #include "G4Text.hh" 49 #include "G4Text.hh" 47 #include "G4Circle.hh" 50 #include "G4Circle.hh" 48 #include "G4Square.hh" 51 #include "G4Square.hh" 49 #include "G4Polymarker.hh" 52 #include "G4Polymarker.hh" 50 #include "G4Polyhedron.hh" 53 #include "G4Polyhedron.hh" >> 54 #include "G4NURBS.hh" 51 #include "G4Visible.hh" 55 #include "G4Visible.hh" 52 #include "G4VisAttributes.hh" 56 #include "G4VisAttributes.hh" 53 #include "G4VModel.hh" 57 #include "G4VModel.hh" 54 #include "G4TrajectoriesModel.hh" 58 #include "G4TrajectoriesModel.hh" 55 #include "G4Box.hh" 59 #include "G4Box.hh" 56 #include "G4Cons.hh" 60 #include "G4Cons.hh" 57 #include "G4Orb.hh" << 61 #include "G4Tubs.hh" 58 #include "G4Para.hh" << 62 #include "G4Trd.hh" >> 63 #include "G4Trap.hh" 59 #include "G4Sphere.hh" 64 #include "G4Sphere.hh" >> 65 #include "G4Para.hh" 60 #include "G4Torus.hh" 66 #include "G4Torus.hh" 61 #include "G4Trap.hh" << 62 #include "G4Trd.hh" << 63 #include "G4Tubs.hh" << 64 #include "G4Ellipsoid.hh" << 65 #include "G4Polycone.hh" 67 #include "G4Polycone.hh" 66 #include "G4Polyhedra.hh" 68 #include "G4Polyhedra.hh" 67 #include "G4Tet.hh" << 68 #include "G4DisplacedSolid.hh" << 69 #include "G4UnionSolid.hh" << 70 #include "G4IntersectionSolid.hh" << 71 #include "G4SubtractionSolid.hh" << 72 #include "G4LogicalVolume.hh" 69 #include "G4LogicalVolume.hh" 73 #include "G4PhysicalVolumeModel.hh" 70 #include "G4PhysicalVolumeModel.hh" 74 #include "G4ModelingParameters.hh" 71 #include "G4ModelingParameters.hh" 75 #include "G4VTrajectory.hh" 72 #include "G4VTrajectory.hh" 76 #include "G4VTrajectoryPoint.hh" 73 #include "G4VTrajectoryPoint.hh" 77 #include "G4HitsModel.hh" 74 #include "G4HitsModel.hh" 78 #include "G4VHit.hh" 75 #include "G4VHit.hh" 79 #include "G4VDigi.hh" << 76 #include "Randomize.hh" 80 #include "G4ScoringManager.hh" << 81 #include "G4VScoringMesh.hh" << 82 #include "G4Mesh.hh" << 83 #include "G4DefaultLinearColorMap.hh" << 84 #include "G4QuickRand.hh" << 85 #include "G4StateManager.hh" 77 #include "G4StateManager.hh" 86 #include "G4RunManager.hh" 78 #include "G4RunManager.hh" 87 #include "G4RunManagerFactory.hh" << 88 #include "G4Run.hh" 79 #include "G4Run.hh" 89 #include "G4Transform3D.hh" 80 #include "G4Transform3D.hh" 90 #include "G4AttHolder.hh" 81 #include "G4AttHolder.hh" 91 #include "G4AttDef.hh" 82 #include "G4AttDef.hh" 92 #include "G4SceneTreeItem.hh" << 93 #include "G4VVisCommand.hh" << 94 #include "G4PhysicalConstants.hh" << 95 #include "G4SystemOfUnits.hh" << 96 << 97 #define G4warn G4cout << 98 83 99 G4VSceneHandler::G4VSceneHandler (G4VGraphicsS 84 G4VSceneHandler::G4VSceneHandler (G4VGraphicsSystem& system, G4int id, const G4String& name): 100 fSystem (system), 85 fSystem (system), 101 fSceneHandlerId (id), 86 fSceneHandlerId (id), 102 fViewCount (0), 87 fViewCount (0), 103 fpViewer (0), 88 fpViewer (0), 104 fpScene (0), 89 fpScene (0), 105 fMarkForClearingTransientStore (true), // R 90 fMarkForClearingTransientStore (true), // Ready for first 106 // ClearTransientStoreIfMarked(), 91 // ClearTransientStoreIfMarked(), 107 // e.g., at end of run (see 92 // e.g., at end of run (see 108 // G4VisManager.cc). 93 // G4VisManager.cc). 109 fReadyForTransients (true), // Only fals 94 fReadyForTransients (true), // Only false while processing scene. 110 fProcessingSolid (false), 95 fProcessingSolid (false), 111 fProcessing2D (false), << 96 fSecondPassRequested (false), >> 97 fSecondPass (false), 112 fpModel (0), 98 fpModel (0), >> 99 fpObjectTransformation (0), 113 fNestingDepth (0), 100 fNestingDepth (0), 114 fpVisAttribs (0) 101 fpVisAttribs (0) 115 { 102 { 116 G4VisManager* pVMan = G4VisManager::GetInsta 103 G4VisManager* pVMan = G4VisManager::GetInstance (); 117 fpScene = pVMan -> GetCurrentScene (); 104 fpScene = pVMan -> GetCurrentScene (); 118 if (name == "") { 105 if (name == "") { 119 std::ostringstream ost; 106 std::ostringstream ost; 120 ost << fSystem.GetName () << '-' << fScene 107 ost << fSystem.GetName () << '-' << fSceneHandlerId; 121 fName = ost.str(); 108 fName = ost.str(); 122 } 109 } 123 else { 110 else { 124 fName = name; 111 fName = name; 125 } 112 } 126 fTransientsDrawnThisEvent = pVMan->GetTransi 113 fTransientsDrawnThisEvent = pVMan->GetTransientsDrawnThisEvent(); 127 fTransientsDrawnThisRun = pVMan->GetTransien 114 fTransientsDrawnThisRun = pVMan->GetTransientsDrawnThisRun(); 128 } 115 } 129 116 130 G4VSceneHandler::~G4VSceneHandler () { 117 G4VSceneHandler::~G4VSceneHandler () { 131 G4VViewer* last; << 118 G4ViewerListIterator i; 132 while( ! fViewerList.empty() ) { << 119 for (i = fViewerList.begin(); i != fViewerList.end(); ++i) { 133 last = fViewerList.back(); << 120 delete *i; 134 fViewerList.pop_back(); << 135 delete last; << 136 } << 137 } << 138 << 139 const G4VisExtent& G4VSceneHandler::GetExtent( << 140 { << 141 if (fpScene) { << 142 return fpScene->GetExtent(); << 143 } else { << 144 static const G4VisExtent defaultExtent = G << 145 return defaultExtent; << 146 } 121 } 147 } 122 } 148 123 149 void G4VSceneHandler::PreAddSolid (const G4Tra 124 void G4VSceneHandler::PreAddSolid (const G4Transform3D& objectTransformation, 150 const G4VisAttributes& visAttribs) << 125 const G4VisAttributes& visAttribs) { 151 fObjectTransformation = objectTransformation << 126 fpObjectTransformation = &objectTransformation; 152 fpVisAttribs = &visAttribs; 127 fpVisAttribs = &visAttribs; 153 fProcessingSolid = true; 128 fProcessingSolid = true; 154 } 129 } 155 130 156 void G4VSceneHandler::PostAddSolid () { 131 void G4VSceneHandler::PostAddSolid () { >> 132 fpObjectTransformation = 0; 157 fpVisAttribs = 0; 133 fpVisAttribs = 0; 158 fProcessingSolid = false; 134 fProcessingSolid = false; 159 if (fReadyForTransients) { 135 if (fReadyForTransients) { 160 fTransientsDrawnThisEvent = true; 136 fTransientsDrawnThisEvent = true; 161 fTransientsDrawnThisRun = true; 137 fTransientsDrawnThisRun = true; 162 } 138 } 163 } 139 } 164 140 165 void G4VSceneHandler::BeginPrimitives 141 void G4VSceneHandler::BeginPrimitives 166 (const G4Transform3D& objectTransformation) { 142 (const G4Transform3D& objectTransformation) { 167 //static G4int count = 0; << 168 //G4cout << "G4VSceneHandler::BeginPrimitive << 169 fNestingDepth++; 143 fNestingDepth++; 170 if (fNestingDepth > 1) 144 if (fNestingDepth > 1) 171 G4Exception << 145 G4Exception("G4VSceneHandler::BeginPrimitives: Nesting detected." 172 ("G4VSceneHandler::BeginPrimitives", << 146 "\n It is illegal to nest Begin/EndPrimitives."); 173 "visman0101", FatalException, << 147 fpObjectTransformation = &objectTransformation; 174 "Nesting detected. It is illegal to nes << 175 fObjectTransformation = objectTransformation << 176 } 148 } 177 149 178 void G4VSceneHandler::EndPrimitives () { 150 void G4VSceneHandler::EndPrimitives () { 179 if (fNestingDepth <= 0) 151 if (fNestingDepth <= 0) 180 G4Exception("G4VSceneHandler::EndPrimitive << 152 G4Exception("G4VSceneHandler::EndPrimitives: Nesting error"); 181 "visman0102", FatalException, "Nesting err << 182 fNestingDepth--; 153 fNestingDepth--; >> 154 fpObjectTransformation = 0; 183 if (fReadyForTransients) { 155 if (fReadyForTransients) { 184 fTransientsDrawnThisEvent = true; 156 fTransientsDrawnThisEvent = true; 185 fTransientsDrawnThisRun = true; 157 fTransientsDrawnThisRun = true; 186 } 158 } 187 } 159 } 188 160 189 void G4VSceneHandler::BeginPrimitives2D << 161 void G4VSceneHandler::BeginPrimitives2D () { 190 (const G4Transform3D& objectTransformation) { << 191 fNestingDepth++; 162 fNestingDepth++; 192 if (fNestingDepth > 1) 163 if (fNestingDepth > 1) 193 G4Exception << 164 G4Exception("G4VSceneHandler::BeginPrimitives2D: Nesting detected." 194 ("G4VSceneHandler::BeginPrimitives2D", << 165 "\n It is illegal to nest Begin/EndPrimitives."); 195 "visman0103", FatalException, << 166 // Not actually required for 2D operations but some drivers do an 196 "Nesting detected. It is illegal to nes << 167 // initial transformation... 197 fObjectTransformation = objectTransformation << 168 fpObjectTransformation = &fIdentityTransformation; 198 fProcessing2D = true; << 199 } 169 } 200 170 201 void G4VSceneHandler::EndPrimitives2D () { 171 void G4VSceneHandler::EndPrimitives2D () { 202 if (fNestingDepth <= 0) 172 if (fNestingDepth <= 0) 203 G4Exception("G4VSceneHandler::EndPrimitive << 173 G4Exception("G4VSceneHandler::EndPrimitives2D: Nesting error"); 204 "visman0104", FatalException, "Nesting err << 205 fNestingDepth--; 174 fNestingDepth--; >> 175 fpObjectTransformation = 0; 206 if (fReadyForTransients) { 176 if (fReadyForTransients) { 207 fTransientsDrawnThisEvent = true; 177 fTransientsDrawnThisEvent = true; 208 fTransientsDrawnThisRun = true; 178 fTransientsDrawnThisRun = true; 209 } 179 } 210 fProcessing2D = false; << 211 } 180 } 212 181 213 void G4VSceneHandler::BeginModeling () { 182 void G4VSceneHandler::BeginModeling () { 214 } 183 } 215 184 216 void G4VSceneHandler::EndModeling () 185 void G4VSceneHandler::EndModeling () 217 { 186 { 218 fpModel = 0; 187 fpModel = 0; 219 } 188 } 220 189 221 void G4VSceneHandler::ClearStore () {} << 190 void G4VSceneHandler::ClearStore () { 222 << 191 // if (fpViewer) fpViewer -> NeedKernelVisit (true); 223 void G4VSceneHandler::ClearTransientStore () { << 192 // ?? Viewer is supposed to be smart enough to know when to visit 224 << 193 // kernel, but a problem in OpenGL Stored seems to require a forced 225 template <class T> void G4VSceneHandler::AddSo << 194 // kernel visit triggered by the above code. John Allison Aug 2001 226 (const T& solid) << 195 // Feb 2005 - commented out. Let's fix OpenGL if necessary. 227 { << 228 // Get and check applicable vis attributes. << 229 fpVisAttribs = fpViewer->GetApplicableVisAtt << 230 RequestPrimitives (solid); << 231 } 196 } 232 197 233 template <class T> void G4VSceneHandler::AddSo << 198 void G4VSceneHandler::ClearTransientStore () { 234 (const T& solid) << 235 { << 236 // Get and check applicable vis attributes. << 237 fpVisAttribs = fpViewer->GetApplicableVisAtt << 238 // Draw with auxiliary edges unless otherwis << 239 if (!fpVisAttribs->IsForceAuxEdgeVisible()) << 240 // Create a vis atts object for the modifi << 241 // It is static so that we may return a re << 242 static G4VisAttributes visAttsWithAuxEdges << 243 // Initialise it with the current vis atts << 244 visAttsWithAuxEdges = *fpVisAttribs; << 245 // Force auxiliary edges visible. << 246 visAttsWithAuxEdges.SetForceAuxEdgeVisible << 247 fpVisAttribs = &visAttsWithAuxEdges; << 248 } << 249 RequestPrimitives (solid); << 250 } 199 } 251 200 252 void G4VSceneHandler::AddSolid (const G4Box& b 201 void G4VSceneHandler::AddSolid (const G4Box& box) { 253 AddSolidT (box); << 202 RequestPrimitives (box); 254 // If your graphics system is sophisticated << 203 // If your graphics system is sophisticated enough to handle a 255 // particular solid shape as a primitive, i << 204 // particular solid shape as a primitive, in your derived class write a 256 // function to override this. << 205 // function to override this. (Note: some compilers warn that your 257 // Your function might look like this... << 206 // function "hides" this one. That's OK.) 258 // void G4MySceneHandler::AddSolid (const G4 << 207 // Your function might look like this... 259 // Get and check applicable vis attributes. << 208 // void G4MyScene::AddSolid (const G4Box& box) { 260 // fpVisAttribs = fpViewer->GetApplicableV << 209 // Get parameters of appropriate object, e.g.: 261 // Do not draw if not visible. << 210 // G4double dx = box.GetXHalfLength (); 262 // if (fpVisAttribs->IsVisible()) { << 211 // G4double dy = box.GetYHalfLength (); 263 // Get parameters of appropriate object, e << 212 // G4double dz = box.GetZHalfLength (); 264 // G4double dx = box.GetXHalfLength (); << 213 // and Draw or Store in your display List. 265 // G4double dy = box.GetYHalfLength (); << 266 // G4double dz = box.GetZHalfLength (); << 267 // ... << 268 // and Draw or Store in your display Lis << 269 } << 270 << 271 void G4VSceneHandler::AddSolid (const G4Cons& << 272 AddSolidT (cons); << 273 } << 274 << 275 void G4VSceneHandler::AddSolid (const G4Orb& o << 276 AddSolidWithAuxiliaryEdges (orb); << 277 } 214 } 278 215 279 void G4VSceneHandler::AddSolid (const G4Para& << 216 void G4VSceneHandler::AddSolid (const G4Tubs& tubs) { 280 AddSolidT (para); << 217 RequestPrimitives (tubs); 281 } 218 } 282 219 283 void G4VSceneHandler::AddSolid (const G4Sphere << 220 void G4VSceneHandler::AddSolid (const G4Cons& cons) { 284 AddSolidWithAuxiliaryEdges (sphere); << 221 RequestPrimitives (cons); 285 } 222 } 286 223 287 void G4VSceneHandler::AddSolid (const G4Torus& << 224 void G4VSceneHandler::AddSolid (const G4Trd& trd) { 288 AddSolidWithAuxiliaryEdges (torus); << 225 RequestPrimitives (trd); 289 } 226 } 290 227 291 void G4VSceneHandler::AddSolid (const G4Trap& 228 void G4VSceneHandler::AddSolid (const G4Trap& trap) { 292 AddSolidT (trap); << 229 RequestPrimitives (trap); 293 } 230 } 294 231 295 void G4VSceneHandler::AddSolid (const G4Trd& t << 232 void G4VSceneHandler::AddSolid (const G4Sphere& sphere) { 296 AddSolidT (trd); << 233 RequestPrimitives (sphere ); 297 } 234 } 298 235 299 void G4VSceneHandler::AddSolid (const G4Tubs& << 236 void G4VSceneHandler::AddSolid (const G4Para& para) { 300 AddSolidT (tubs); << 237 RequestPrimitives (para); 301 } 238 } 302 239 303 void G4VSceneHandler::AddSolid (const G4Ellips << 240 void G4VSceneHandler::AddSolid (const G4Torus& torus) { 304 AddSolidWithAuxiliaryEdges (ellipsoid); << 241 RequestPrimitives (torus); 305 } 242 } 306 243 307 void G4VSceneHandler::AddSolid (const G4Polyco 244 void G4VSceneHandler::AddSolid (const G4Polycone& polycone) { 308 AddSolidT (polycone); << 245 RequestPrimitives (polycone); 309 } 246 } 310 247 311 void G4VSceneHandler::AddSolid (const G4Polyhe 248 void G4VSceneHandler::AddSolid (const G4Polyhedra& polyhedra) { 312 AddSolidT (polyhedra); << 249 RequestPrimitives (polyhedra); 313 } << 314 << 315 void G4VSceneHandler::AddSolid (const G4Tessel << 316 AddSolidT (tess); << 317 } 250 } 318 251 319 void G4VSceneHandler::AddSolid (const G4VSolid 252 void G4VSceneHandler::AddSolid (const G4VSolid& solid) { 320 AddSolidT (solid); << 253 RequestPrimitives (solid); 321 } 254 } 322 255 323 void G4VSceneHandler::AddCompound (const G4VTr 256 void G4VSceneHandler::AddCompound (const G4VTrajectory& traj) { 324 G4TrajectoriesModel* trajectoriesModel = << 257 G4TrajectoriesModel* pTrModel = 325 dynamic_cast<G4TrajectoriesModel*>(fpModel 258 dynamic_cast<G4TrajectoriesModel*>(fpModel); 326 if (trajectoriesModel) << 259 if (!pTrModel) G4Exception 327 traj.DrawTrajectory(); << 260 ("G4VSceneHandler::AddCompound(const G4VTrajectory&): Not a G4TrajectoriesModel."); 328 else { << 261 traj.DrawTrajectory(pTrModel->GetDrawingMode()); 329 G4Exception << 330 ("G4VSceneHandler::AddCompound(const G4VTr << 331 "visman0105", FatalException, "Not a G4Tr << 332 } << 333 } 262 } 334 263 335 void G4VSceneHandler::AddCompound (const G4VHi 264 void G4VSceneHandler::AddCompound (const G4VHit& hit) { 336 // Cast away const because Draw is non-const << 265 ((G4VHit&)hit).Draw(); // Cast to non-const because Draw is non-const!!!! 337 const_cast<G4VHit&>(hit).Draw(); << 338 } 266 } 339 267 340 void G4VSceneHandler::AddCompound (const G4VDi << 268 void G4VSceneHandler::AddViewerToList (G4VViewer* pViewer) { 341 // Cast away const because Draw is non-const << 269 fViewerList.push_back (pViewer); 342 const_cast<G4VDigi&>(digi).Draw(); << 343 } << 344 << 345 void G4VSceneHandler::AddCompound (const G4THi << 346 using MeshScoreMap = G4VScoringMesh::MeshSco << 347 //G4cout << "AddCompound: hits: " << &hits < << 348 G4bool scoreMapHits = false; << 349 G4ScoringManager* scoringManager = G4Scoring << 350 if (scoringManager) { << 351 std::size_t nMeshes = scoringManager->GetN << 352 for (std::size_t iMesh = 0; iMesh < nMeshe << 353 G4VScoringMesh* mesh = scoringManager->G << 354 if (mesh && mesh->IsActive()) { << 355 MeshScoreMap scoreMap = mesh->GetScoreMap(); << 356 const G4String& mapNam = const_cast<G4 << 357 for(MeshScoreMap::const_iterator i = scoreMa << 358 i != scoreMap.cend(); ++i) { << 359 const G4String& scoreMapName = i->first; << 360 if (scoreMapName == mapNam) { << 361 G4DefaultLinearColorMap colorMap("G4VSce << 362 scoreMapHits = true; << 363 mesh->DrawMesh(scoreMapName, &colorMap); << 364 } << 365 } << 366 } << 367 } << 368 } << 369 if (scoreMapHits) { << 370 static G4bool first = true; << 371 if (first) { << 372 first = false; << 373 G4cout << << 374 "Scoring map drawn with default parameters." << 375 "\n To get gMocren file for gMocren browser << 376 "\n /vis/open gMocrenFile" << 377 "\n /vis/viewer/flush" << 378 "\n Many other options available with /scor << 379 "\n You might want to \"/vis/viewer/set/aut << 380 << G4endl; << 381 } << 382 } else { // Not score map hits. Just call << 383 // Cast away const because DrawAllHits is << 384 const_cast<G4THitsMap<G4double>&>(hits).Dr << 385 } << 386 } 270 } 387 271 388 void G4VSceneHandler::AddCompound (const G4THi << 272 void G4VSceneHandler::AddPrimitive (const G4Scale& scale) { 389 using MeshScoreMap = G4VScoringMesh::MeshSco << 273 390 //G4cout << "AddCompound: hits: " << &hits < << 274 const G4double margin(0.01); 391 G4bool scoreMapHits = false; << 275 // Fractional margin - ensures scale is comfortably inside viewing 392 G4ScoringManager* scoringManager = G4Scoring << 276 // volume. 393 if (scoringManager) { << 277 const G4double oneMinusMargin (1. - margin); 394 std::size_t nMeshes = scoringManager->GetN << 278 395 for (std::size_t iMesh = 0; iMesh < nMeshe << 279 const G4VisExtent& sceneExtent = fpScene->GetExtent(); 396 G4VScoringMesh* mesh = scoringManager->G << 280 397 if (mesh && mesh->IsActive()) { << 281 // Useful constants... 398 MeshScoreMap scoreMap = mesh->GetScoreMap(); << 282 const G4double length(scale.GetLength()); 399 for(MeshScoreMap::const_iterator i = scoreMa << 283 const G4double halfLength(length / 2.); 400 i != scoreMap.cend(); ++i) { << 284 const G4double tickLength(length / 20.); 401 const G4String& scoreMapName = i->first; << 285 const G4double piBy2(halfpi); 402 const G4THitsMap<G4StatDouble>* foundHits << 286 403 if (foundHits == &hits) { << 287 // Get size of scene... 404 G4DefaultLinearColorMap colorMap("G4VSce << 288 const G4double xmin = sceneExtent.GetXmin(); 405 scoreMapHits = true; << 289 const G4double xmax = sceneExtent.GetXmax(); 406 mesh->DrawMesh(scoreMapName, &colorMap); << 290 const G4double ymin = sceneExtent.GetYmin(); 407 } << 291 const G4double ymax = sceneExtent.GetYmax(); 408 } << 292 const G4double zmin = sceneExtent.GetZmin(); 409 } << 293 const G4double zmax = sceneExtent.GetZmax(); 410 } << 294 411 } << 295 // Create (empty) polylines having the same vis attributes... 412 if (scoreMapHits) { << 296 G4Polyline scaleLine, tick11, tick12, tick21, tick22; 413 static G4bool first = true; << 297 G4VisAttributes visAtts(*scale.GetVisAttributes()); // Long enough life. 414 if (first) { << 298 scaleLine.SetVisAttributes(&visAtts); 415 first = false; << 299 tick11.SetVisAttributes(&visAtts); 416 G4cout << << 300 tick12.SetVisAttributes(&visAtts); 417 "Scoring map drawn with default parameters." << 301 tick21.SetVisAttributes(&visAtts); 418 "\n To get gMocren file for gMocren browser << 302 tick22.SetVisAttributes(&visAtts); 419 "\n /vis/open gMocrenFile" << 303 420 "\n /vis/viewer/flush" << 304 // Add points to the polylines to represent an scale parallel to the 421 "\n Many other options available with /scor << 305 // x-axis centred on the origin... 422 "\n You might want to \"/vis/viewer/set/aut << 306 G4Point3D r1(G4Point3D(-halfLength, 0., 0.)); 423 << G4endl; << 307 G4Point3D r2(G4Point3D( halfLength, 0., 0.)); >> 308 scaleLine.push_back(r1); >> 309 scaleLine.push_back(r2); >> 310 G4Point3D ticky(0., tickLength, 0.); >> 311 G4Point3D tickz(0., 0., tickLength); >> 312 tick11.push_back(r1 + ticky); >> 313 tick11.push_back(r1 - ticky); >> 314 tick12.push_back(r1 + tickz); >> 315 tick12.push_back(r1 - tickz); >> 316 tick21.push_back(r2 + ticky); >> 317 tick21.push_back(r2 - ticky); >> 318 tick22.push_back(r2 + tickz); >> 319 tick22.push_back(r2 - tickz); >> 320 G4Point3D textPosition(0., tickLength, 0.); >> 321 >> 322 // Transform appropriately... >> 323 >> 324 G4Transform3D transformation; >> 325 if (scale.GetAutoPlacing()) { >> 326 G4Transform3D rotation; >> 327 switch (scale.GetDirection()) { >> 328 case G4Scale::x: >> 329 break; >> 330 case G4Scale::y: >> 331 rotation = G4RotateZ3D(piBy2); >> 332 break; >> 333 case G4Scale::z: >> 334 rotation = G4RotateY3D(piBy2); >> 335 break; >> 336 } >> 337 G4double sxmid(scale.GetXmid()); >> 338 G4double symid(scale.GetYmid()); >> 339 G4double szmid(scale.GetZmid()); >> 340 sxmid = xmin + oneMinusMargin * (xmax - xmin); >> 341 symid = ymin + margin * (ymax - ymin); >> 342 szmid = zmin + oneMinusMargin * (zmax - zmin); >> 343 switch (scale.GetDirection()) { >> 344 case G4Scale::x: >> 345 sxmid -= halfLength; >> 346 break; >> 347 case G4Scale::y: >> 348 symid += halfLength; >> 349 break; >> 350 case G4Scale::z: >> 351 szmid -= halfLength; >> 352 break; 424 } 353 } 425 } else { // Not score map hits. Just call << 354 G4Translate3D translation(sxmid, symid, szmid); 426 // Cast away const because DrawAllHits is << 355 transformation = translation * rotation; 427 const_cast<G4THitsMap<G4StatDouble>&>(hits << 356 } else { >> 357 if (fpModel) transformation = fpModel->GetTransformation(); 428 } 358 } 429 } << 430 359 431 void G4VSceneHandler::AddCompound(const G4Mesh << 360 // Draw... 432 { << 361 // We would like to call BeginPrimitives(transformation) here but 433 G4warn << << 362 // calling BeginPrimitives from within an AddPrimitive is not 434 "There has been an attempt to draw a mesh wi << 363 // allowed! So we have to do our own transformation... 435 << fpViewer->GetViewParameters().GetSpecialM << 364 AddPrimitive(scaleLine.transform(transformation)); 436 << "\":\n" << mesh << 365 AddPrimitive(tick11.transform(transformation)); 437 << "but it is not of a recognised type or is << 366 AddPrimitive(tick12.transform(transformation)); 438 "\nby the current graphics driver. Instead w << 367 AddPrimitive(tick21.transform(transformation)); 439 "\ncontainer \"" << mesh.GetContainerVolume( << 368 AddPrimitive(tick22.transform(transformation)); 440 << G4endl; << 369 G4Text text(scale.GetAnnotation(),textPosition.transform(transformation)); 441 const auto& pv = mesh.GetContainerVolume(); << 370 text.SetScreenSize(12.); 442 const auto& lv = pv->GetLogicalVolume(); << 371 AddPrimitive(text); 443 const auto& solid = lv->GetSolid(); << 444 const auto& transform = mesh.GetTransform(); << 445 // Make sure container is visible << 446 G4VisAttributes tmpVisAtts; // Visible, whi << 447 const auto& saveVisAtts = lv->GetVisAttribut << 448 if (saveVisAtts) { << 449 tmpVisAtts = *saveVisAtts; << 450 tmpVisAtts.SetVisibility(true); << 451 auto colour = saveVisAtts->GetColour(); << 452 colour.SetAlpha(1.); << 453 tmpVisAtts.SetColour(colour); << 454 } << 455 // Draw container << 456 PreAddSolid(transform,tmpVisAtts); << 457 solid->DescribeYourselfTo(*this); << 458 PostAddSolid(); << 459 // Restore vis attributes << 460 lv->SetVisAttributes(saveVisAtts); << 461 } << 462 << 463 void G4VSceneHandler::AddViewerToList (G4VView << 464 fViewerList.push_back (pViewer); << 465 } 372 } 466 373 467 void G4VSceneHandler::AddPrimitive (const G4Po 374 void G4VSceneHandler::AddPrimitive (const G4Polymarker& polymarker) { 468 switch (polymarker.GetMarkerType()) { 375 switch (polymarker.GetMarkerType()) { 469 default: << 376 default: 470 case G4Polymarker::dots: << 377 case G4Polymarker::dots: 471 { 378 { 472 G4Circle dot (polymarker); << 379 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { 473 dot.SetWorldSize (0.); << 380 G4Circle dot (polymarker); 474 dot.SetScreenSize (0.1); // Very small << 475 for (std::size_t iPoint = 0; iPoint < po << 476 dot.SetPosition (polymarker[iPoint]); 381 dot.SetPosition (polymarker[iPoint]); 477 AddPrimitive (dot); << 382 dot.SetWorldSize (0.); >> 383 dot.SetScreenSize (0.1); // Very small circle. >> 384 AddPrimitive (dot); 478 } 385 } 479 } 386 } 480 break; << 387 break; 481 case G4Polymarker::circles: << 388 case G4Polymarker::circles: 482 { 389 { 483 G4Circle circle (polymarker); // Defaul << 390 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { 484 for (std::size_t iPoint = 0; iPoint < po << 391 G4Circle circle (polymarker); 485 circle.SetPosition (polymarker[iPoint] << 392 circle.SetPosition (polymarker[iPoint]); 486 AddPrimitive (circle); << 393 AddPrimitive (circle); 487 } 394 } 488 } 395 } 489 break; << 396 break; 490 case G4Polymarker::squares: << 397 case G4Polymarker::squares: 491 { 398 { 492 G4Square square (polymarker); // Defaul << 399 for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) { 493 for (std::size_t iPoint = 0; iPoint < po << 400 G4Square square (polymarker); 494 square.SetPosition (polymarker[iPoint] << 401 square.SetPosition (polymarker[iPoint]); 495 AddPrimitive (square); << 402 AddPrimitive (square); 496 } 403 } 497 } 404 } 498 break; << 405 break; 499 } 406 } 500 } 407 } 501 408 502 void G4VSceneHandler::RemoveViewerFromList (G4 409 void G4VSceneHandler::RemoveViewerFromList (G4VViewer* pViewer) { 503 fViewerList.remove(pViewer); // Does nothin << 410 fViewerList.remove(pViewer); 504 // And reset current viewer << 505 auto visManager = G4VisManager::GetInstance( << 506 visManager->SetCurrentViewer(nullptr); << 507 } << 508 << 509 << 510 void G4VSceneHandler::AddPrimitive (const G4Pl << 511 G4warn << "WARNING: Plotter not implemented << 512 G4warn << " Open a plotter-aware graphics s << 513 G4warn << " /vis/scene/removeModel Plotter" << 514 } 411 } 515 412 516 void G4VSceneHandler::SetScene (G4Scene* pScen 413 void G4VSceneHandler::SetScene (G4Scene* pScene) { 517 fpScene = pScene; 414 fpScene = pScene; 518 // Notify all viewers that a kernel visit is 415 // Notify all viewers that a kernel visit is required. 519 G4ViewerListIterator i; 416 G4ViewerListIterator i; 520 for (i = fViewerList.begin(); i != fViewerLi 417 for (i = fViewerList.begin(); i != fViewerList.end(); i++) { 521 (*i) -> SetNeedKernelVisit (true); 418 (*i) -> SetNeedKernelVisit (true); 522 } 419 } 523 } 420 } 524 421 525 void G4VSceneHandler::RequestPrimitives (const << 422 void G4VSceneHandler::RequestPrimitives (const G4VSolid& solid) { 526 { << 423 BeginPrimitives (*fpObjectTransformation); 527 // Sometimes solids that have no substance g << 424 G4NURBS* pNURBS = 0; 528 // be part of the geometry tree but have bee << 425 G4Polyhedron* pPolyhedron = 0; 529 // example by a Boolean subtraction in which << 426 switch (fpViewer -> GetViewParameters () . GetRepStyle ()) { 530 // is entirely inside the subtractor or an i << 427 case G4ViewParameters::nurbs: 531 // the original volume is entirely outside t << 428 pNURBS = solid.CreateNURBS (); 532 // The problem is that the Boolean Processor << 429 if (pNURBS) { 533 // polyhedron in these cases (IMHO it should << 430 pNURBS -> SetVisAttributes (fpVisAttribs); 534 // workaround is to return before the damage << 431 AddPrimitive (*pNURBS); 535 // Algorithm by Evgueni Tcherniaev << 432 delete pNURBS; 536 auto pSolid = &solid; << 433 break; 537 auto pBooleanSolid = dynamic_cast<const G4Bo << 434 } 538 if (pBooleanSolid) { << 435 else { 539 G4ThreeVector bmin, bmax; << 436 G4VisManager::Verbosity verbosity = 540 pBooleanSolid->BoundingLimits(bmin, bmax); << 437 G4VisManager::GetInstance()->GetVerbosity(); 541 G4bool isGood = false; << 438 if (verbosity >= G4VisManager::errors) { 542 if (dynamic_cast<const G4SubtractionSolid* << 439 G4cout << 543 auto ptrB = pBooleanSolid->GetConstituen << 440 "ERROR: G4VSceneHandler::RequestPrimitives" 544 for (G4int i=0; i<10; ++i) { << 441 "\n NURBS not available for " 545 G4double x = bmin.x() + (bmax.x() - bm << 442 << solid.GetName () << G4endl; 546 G4double y = bmin.y() + (bmax.y() - bm << 443 G4cout << "Trying polyhedron." << G4endl; 547 G4double z = bmin.z() + (bmax.z() - bm << 444 } 548 if (ptrB->Inside(G4ThreeVector(x,y,bmi << 445 } 549 if (ptrB->Inside(G4ThreeVector(x,y,bma << 446 // Dropping through to polyhedron... 550 if (ptrB->Inside(G4ThreeVector(x,bmin. << 447 case G4ViewParameters::polyhedron: 551 if (ptrB->Inside(G4ThreeVector(x,bmax. << 448 default: 552 if (ptrB->Inside(G4ThreeVector(bmin.x( << 449 G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (fpVisAttribs)); 553 if (ptrB->Inside(G4ThreeVector(bmax.x( << 450 pPolyhedron = solid.GetPolyhedron (); 554 } << 451 G4Polyhedron::ResetNumberOfRotationSteps (); 555 } else if (dynamic_cast<const G4Intersecti << 452 if (pPolyhedron) { 556 auto ptrB = pBooleanSolid->GetConstituen << 453 pPolyhedron -> SetVisAttributes (fpVisAttribs); 557 for (G4int i=0; i<10; ++i) { << 454 AddPrimitive (*pPolyhedron); 558 G4double x = bmin.x() + (bmax.x() - bm << 455 } 559 G4double y = bmin.y() + (bmax.y() - bm << 456 else { 560 G4double z = bmin.z() + (bmax.z() - bm << 457 G4VisManager::Verbosity verbosity = 561 if (ptrB->Inside(G4ThreeVector(x,y,bmi << 458 G4VisManager::GetInstance()->GetVerbosity(); 562 if (ptrB->Inside(G4ThreeVector(x,y,bma << 459 if (verbosity >= G4VisManager::errors) { 563 if (ptrB->Inside(G4ThreeVector(x,bmin. << 460 G4cout << 564 if (ptrB->Inside(G4ThreeVector(x,bmax. << 461 "ERROR: G4VSceneHandler::RequestPrimitives" 565 if (ptrB->Inside(G4ThreeVector(bmin.x( << 462 "\n Polyhedron not available for " << solid.GetName () << 566 if (ptrB->Inside(G4ThreeVector(bmax.x( << 463 ".\n This means it cannot be visualized on most systems." 567 } << 464 "\n Contact the Visualization Coordinator." << G4endl; 568 } << 569 if (!isGood) << 570 { << 571 for (G4int i=0; i<10000; ++i) { << 572 G4double x = bmin.x() + (bmax.x() - bm << 573 G4double y = bmin.y() + (bmax.y() - bm << 574 G4double z = bmin.z() + (bmax.z() - bm << 575 if (pBooleanSolid->Inside(G4ThreeVecto << 576 } << 577 } << 578 if (!isGood) return; << 579 } << 580 << 581 const G4ViewParameters::DrawingStyle style = << 582 const G4ViewParameters& vp = fpViewer->GetVi << 583 << 584 switch (style) { << 585 default: << 586 case G4ViewParameters::wireframe: << 587 case G4ViewParameters::hlr: << 588 case G4ViewParameters::hsr: << 589 case G4ViewParameters::hlhsr: << 590 { << 591 // Use polyhedral representation << 592 G4Polyhedron::SetNumberOfRotationSteps ( << 593 G4Polyhedron* pPolyhedron = solid.GetPol << 594 G4Polyhedron::ResetNumberOfRotationSteps << 595 if (pPolyhedron) { << 596 pPolyhedron -> SetVisAttributes (fpVis << 597 BeginPrimitives (fObjectTransformation << 598 AddPrimitive (*pPolyhedron); << 599 EndPrimitives (); << 600 break; << 601 } else { // Print warnings and drop thr << 602 G4VisManager::Verbosity verbosity = G4 << 603 auto pPVModel = dynamic_cast<G4Physica << 604 if (pPVModel) { << 605 auto problematicVolume = pPVModel->G << 606 if (fProblematicVolumes.find(problem << 607 fProblematicVolumes[problematicVol << 608 if (verbosity >= G4VisManager::err << 609 G4warn << << 610 "ERROR: G4VSceneHandler::Request << 611 "\n Polyhedron not available fo << 612 G4warn << "\n Touchable path: " << 613 static G4bool explanation = fals << 614 if (!explanation) { << 615 explanation = true; << 616 G4warn << << 617 "\n This means it cannot be v << 618 "\n 1) The solid may not have << 619 "\n 2) For Boolean solids, th << 620 "\n the resultant polyhedr << 621 "\n Try RayTracer. It uses Ge << 622 } << 623 } << 624 G4warn << "\n Drawing solid with << 625 G4warn << G4endl; << 626 } << 627 } << 628 } << 629 } << 630 [[fallthrough]]; << 631 << 632 case G4ViewParameters::cloud: << 633 { << 634 // Form solid out of cloud of dots on su << 635 G4Polymarker dots; << 636 // Note: OpenGL has a fast implementatio << 637 // to build a polymarker rather than add << 638 // And anyway, in Qt, in the latter case << 639 // entry, something we would want to avo << 640 dots.SetVisAttributes(fpVisAttribs); << 641 dots.SetMarkerType(G4Polymarker::dots); << 642 dots.SetSize(G4VMarker::screen,1.); << 643 G4int numberOfCloudPoints = GetNumberOfC << 644 if (numberOfCloudPoints <= 0) numberOfCl << 645 for (G4int i = 0; i < numberOfCloudPoint << 646 G4ThreeVector p = solid.GetPointOnSurface(); << 647 dots.push_back(p); << 648 } 465 } 649 BeginPrimitives (fObjectTransformation); << 650 AddPrimitive(dots); << 651 EndPrimitives (); << 652 break; << 653 } 466 } >> 467 break; 654 } 468 } >> 469 EndPrimitives (); 655 } 470 } 656 471 657 //namespace { << 472 void G4VSceneHandler::ProcessScene (G4VViewer&) { 658 // void DrawExtent(const G4VModel* pModel) << 659 // { << 660 // // Show extent boxes - debug only, OGLSX << 661 // if (pModel->GetExtent() != G4VisExtent:: << 662 // const auto& extent = pModel->GetExtent << 663 // const auto& centre = extent.GetExtentC << 664 // const auto& position = G4Translate3D(c << 665 // const auto& dx = (extent.GetXmax()-ext << 666 // const auto& dy = (extent.GetYmax()-ext << 667 // const auto& dz = (extent.GetZmax()-ext << 668 // auto visAtts = G4VisAttributes(); << 669 // visAtts.SetForceWireframe(); << 670 // G4Box extentBox("Extent",dx,dy,dz); << 671 // G4VisManager::GetInstance()->Draw(exte << 672 // } << 673 // } << 674 //} << 675 473 676 void G4VSceneHandler::ProcessScene() << 474 if (!fpScene) return; 677 { << 678 // Assumes graphics database store has alrea << 679 // relevant for the particular scene handler << 680 << 681 if(!fpScene) << 682 return; << 683 << 684 if(fpScene->GetExtent() == G4VisExtent::GetN << 685 { << 686 G4Exception("G4VSceneHandler::ProcessScene << 687 "The scene has no extent."); << 688 } << 689 475 690 G4VisManager* visManager = G4VisManager::Get 476 G4VisManager* visManager = G4VisManager::GetInstance(); 691 477 692 if(!visManager->GetConcreteInstance()) << 478 if (!visManager->GetConcreteInstance()) return; 693 return; << 694 479 695 G4VisManager::Verbosity verbosity = visManag 480 G4VisManager::Verbosity verbosity = visManager->GetVerbosity(); 696 481 697 fReadyForTransients = false; 482 fReadyForTransients = false; 698 483 699 // Reset fMarkForClearingTransientStore. (Le << 484 // Clear stored scene, if any, i.e., display lists, scene graphs. >> 485 ClearStore (); >> 486 >> 487 // Reset fMarkForClearingTransientStore. No need to clear transient >> 488 // store since it has just been cleared above. (Leaving 700 // fMarkForClearingTransientStore true cause 489 // fMarkForClearingTransientStore true causes problems with 701 // recomputing transients below.) Restore i 490 // recomputing transients below.) Restore it again at end... 702 G4bool tmpMarkForClearingTransientStore = fM 491 G4bool tmpMarkForClearingTransientStore = fMarkForClearingTransientStore; 703 fMarkForClearingTransientStore = fa << 492 fMarkForClearingTransientStore = false; 704 493 705 // Traverse geometry tree and send drawing p 494 // Traverse geometry tree and send drawing primitives to window(s). 706 495 707 const std::vector<G4Scene::Model>& runDurati << 496 const std::vector<G4VModel*>& runDurationModelList = 708 fpScene->GetRunDurationModelList(); << 497 fpScene -> GetRunDurationModelList (); 709 498 710 if(runDurationModelList.size()) { << 499 if (runDurationModelList.size ()) { 711 if(verbosity >= G4VisManager::confirmation << 500 if (verbosity >= G4VisManager::confirmations) { 712 G4cout << "Traversing scene data..." << 501 G4cout << "Traversing scene data..." << G4endl; 713 static G4int first = true; << 714 if (first) { << 715 first = false; << 716 G4cout << << 717 "(This could happen more than once - i << 718 "\nper rebuild, for opaque, transparen << 719 << G4endl; << 720 } << 721 } 502 } 722 503 723 // Reset visibility of all objects to fals << 504 BeginModeling (); 724 fpViewer->AccessSceneTree().ResetVisibilit << 725 << 726 BeginModeling(); << 727 505 728 // Create modeling parameters from view pa 506 // Create modeling parameters from view parameters... 729 G4ModelingParameters* pMP = CreateModeling << 507 G4ModelingParameters* pMP = CreateModelingParameters (); 730 508 731 for(std::size_t i = 0; i < runDurationMode << 509 for (size_t i = 0; i < runDurationModelList.size (); i++) { 732 if(runDurationModelList[i].fActive) { << 510 G4VModel* pModel = runDurationModelList[i]; 733 fpModel = runDurationModelList[i].fpMo << 511 // Note: this is not the place to take action on 734 fpModel->SetModelingParameters(pMP); << 512 // pModel->GetTransformation(). The model must take care of 735 << 513 // this in pModel->DescribeYourselfTo(*this). See, for example, 736 // Describe to the current scene handl << 514 // G4PhysicalVolumeModel and /vis/scene/add/logo. 737 fpModel->DescribeYourselfTo(*this); << 515 pModel -> SetModelingParameters (pMP); 738 << 516 SetModel (pModel); // Store for use by derived class. 739 // To see the extents of each model re << 517 pModel -> DescribeYourselfTo (*this); 740 // uncomment the next line and DrawExt << 518 pModel -> SetModelingParameters (0); 741 // DrawExtent(fpModel); << 519 } 742 << 520 743 // Enter models in the scene tree. The << 521 // Repeat if required... 744 // the model to the scene tree, i.e., << 522 if (fSecondPassRequested) { 745 fpViewer->InsertModelInSceneTree(fpMod << 523 fSecondPass = true; 746 auto pPVModel = dynamic_cast<G4Physica << 524 for (size_t i = 0; i < runDurationModelList.size (); i++) { 747 if (pPVModel) { << 525 G4VModel* pModel = runDurationModelList[i]; 748 G4VViewer::SceneTreeScene sceneTreeS << 526 pModel -> SetModelingParameters (pMP); 749 fpModel->DescribeYourselfTo(sceneTre << 527 SetModel (pModel); // Store for use by derived class. 750 } << 528 pModel -> DescribeYourselfTo (*this); 751 << 529 pModel -> SetModelingParameters (0); 752 // Reset modeling parameters pointer << 753 fpModel->SetModelingParameters(0); << 754 } 530 } >> 531 fSecondPass = false; >> 532 fSecondPassRequested = false; 755 } 533 } 756 534 757 fpModel = 0; << 758 delete pMP; 535 delete pMP; >> 536 EndModeling (); 759 537 760 EndModeling(); << 761 } 538 } 762 539 763 // Some printing << 540 fpViewer->FinishView(); // Flush streams and/or swap buffers. 764 if(verbosity >= G4VisManager::confirmations) << 765 for (const auto& model: runDurationModelLi << 766 if (model.fActive) { << 767 auto pvModel = dynamic_cast<G4Physical << 768 if (pvModel) { << 769 G4int nTouchables = 0; << 770 G4cout << "Numbers of touchables by << 771 << pvModel->GetGlobalDescription() < << 772 for (const auto& dn : pvModel->GetNu << 773 G4cout << "\n Depth " << dn.first << 774 nTouchables += dn.second; << 775 } << 776 G4cout << "\n Total number of touch << 777 } << 778 } << 779 } << 780 << 781 if (fProblematicVolumes.size() > 0) { << 782 G4cout << "Problematic volumes:"; << 783 for (const auto& prob: fProblematicVolum << 784 G4cout << "\n " << prob.first->GetNam << 785 } << 786 G4cout << G4endl; << 787 } << 788 } << 789 541 790 fReadyForTransients = true; 542 fReadyForTransients = true; 791 543 792 // Refresh event from end-of-event model lis << 544 // Refresh event from end-of-event model list. Allow only in Idle state... 793 // Allow only in Idle or GeomClosed state... << 794 G4StateManager* stateManager = G4StateManage 545 G4StateManager* stateManager = G4StateManager::GetStateManager(); 795 G4ApplicationState state = stateManager- << 546 G4ApplicationState state = stateManager->GetCurrentState(); 796 if(state == G4State_Idle || state == G4State << 547 if (state == G4State_Idle) { 797 { << 548 798 visManager->SetEventRefreshing(true); 549 visManager->SetEventRefreshing(true); 799 550 800 if(visManager->GetRequestedEvent()) << 551 if (visManager->GetRequestedEvent()) { 801 { << 802 DrawEvent(visManager->GetRequestedEvent( 552 DrawEvent(visManager->GetRequestedEvent()); 803 } << 553 804 else << 554 } else { 805 { << 555 806 G4RunManager* runManager = G4RunManagerF << 556 G4RunManager* runManager = G4RunManager::GetRunManager(); 807 if(runManager) << 557 if (runManager) { 808 { << 558 const G4Run* run = runManager->GetCurrentRun(); 809 const G4Run* run = runManager->GetCurr << 559 const std::vector<const G4Event*>* events = 810 // Draw a null event in order to pick << 560 run? run->GetEventVector(): 0; 811 if (run == nullptr) DrawEvent(0); << 561 size_t nKeptEvents = 0; 812 const std::vector<const G4Event*>* eve << 562 if (events) nKeptEvents = events->size(); 813 run ? run->GetEventVector() : 0; << 563 if (nKeptEvents) { 814 std::size_t nKeptEvents = 0; << 564 815 if(events) << 565 if (fpScene->GetRefreshAtEndOfEvent()) { 816 nKeptEvents = events->size(); << 566 817 if(nKeptEvents) << 567 if (verbosity >= G4VisManager::confirmations) { 818 { << 568 G4cout << "Refreshing event..." << G4endl; 819 if(fpScene->GetRefreshAtEndOfEvent() << 569 } 820 { << 570 const G4Event* event = 0; 821 if(verbosity >= G4VisManager::conf << 571 if (events && events->size()) event = events->back(); 822 { << 572 if (event) DrawEvent(event); 823 G4cout << "Refreshing event..." << 573 824 } << 574 } else { // Accumulating events. 825 const G4Event* event = 0; << 575 826 if(events && events->size()) << 576 if (verbosity >= G4VisManager::confirmations) { 827 event = events->back(); << 577 G4cout << "Refreshing events in run..." << G4endl; 828 if(event) << 578 } 829 DrawEvent(event); << 579 for (size_t i = 0; i < nKeptEvents; ++i) { 830 } << 580 const G4Event* event = (*events)[i]; 831 else << 581 if (event) DrawEvent(event); 832 { // Accumulating events. << 582 } 833 << 583 834 if(verbosity >= G4VisManager::conf << 584 if (!fpScene->GetRefreshAtEndOfRun()) { 835 { << 585 if (verbosity >= G4VisManager::warnings) { 836 G4cout << "Refreshing events in << 586 G4cout << 837 } << 587 "WARNING: Cannot refresh events accumulated over more" 838 for(const auto& event : *events) << 588 "\n than one runs. Refreshed just the last run." 839 { << 589 << G4endl; 840 if(event) << 590 } 841 DrawEvent(event); << 591 } 842 } << 592 } 843 << 593 } 844 if(!fpScene->GetRefreshAtEndOfRun( << 845 { << 846 if(verbosity >= G4VisManager::wa << 847 { << 848 G4warn << "WARNING: Cannot ref << 849 "\n than one runs. << 850 << G4endl; << 851 } << 852 } << 853 } << 854 } << 855 } 594 } 856 } 595 } 857 visManager->SetEventRefreshing(false); 596 visManager->SetEventRefreshing(false); 858 } 597 } 859 598 860 // Refresh end-of-run model list. << 861 // Allow only in Idle or GeomClosed state... << 862 if(state == G4State_Idle || state == G4State << 863 { << 864 DrawEndOfRunModels(); << 865 } << 866 << 867 fMarkForClearingTransientStore = tmpMarkForC 599 fMarkForClearingTransientStore = tmpMarkForClearingTransientStore; 868 } 600 } 869 601 870 void G4VSceneHandler::DrawEvent(const G4Event* 602 void G4VSceneHandler::DrawEvent(const G4Event* event) 871 { 603 { 872 if(!fpViewer->ReadyToDraw()) return; << 604 const std::vector<G4VModel*>& EOEModelList = 873 const std::vector<G4Scene::Model>& EOEModelL << 874 fpScene -> GetEndOfEventModelList (); 605 fpScene -> GetEndOfEventModelList (); 875 std::size_t nModels = EOEModelList.size(); << 606 size_t nModels = EOEModelList.size(); 876 if (nModels) { 607 if (nModels) { 877 G4ModelingParameters* pMP = CreateModeling 608 G4ModelingParameters* pMP = CreateModelingParameters(); 878 pMP->SetEvent(event); 609 pMP->SetEvent(event); 879 for (std::size_t i = 0; i < nModels; ++i) << 610 for (size_t i = 0; i < nModels; i++) { 880 if (EOEModelList[i].fActive) { << 611 G4VModel* pModel = EOEModelList [i]; 881 fpModel = EOEModelList[i].fpModel; << 612 pModel -> SetModelingParameters(pMP); 882 fpModel -> SetModelingParameters(pMP); << 613 SetModel (pModel); 883 << 614 pModel -> DescribeYourselfTo (*this); 884 // Describe to the current scene handl << 615 pModel -> SetModelingParameters(0); 885 fpModel -> DescribeYourselfTo (*this); << 886 << 887 // Enter models in the scene tree << 888 fpViewer->InsertModelInSceneTree(fpMod << 889 << 890 // Reset modeling parameters pointer << 891 fpModel -> SetModelingParameters(0); << 892 } << 893 } << 894 fpModel = 0; << 895 delete pMP; << 896 } << 897 } << 898 << 899 void G4VSceneHandler::DrawEndOfRunModels() << 900 { << 901 if(!fpViewer->ReadyToDraw()) return; << 902 const std::vector<G4Scene::Model>& EORModelL << 903 fpScene -> GetEndOfRunModelList (); << 904 std::size_t nModels = EORModelList.size(); << 905 if (nModels) { << 906 G4ModelingParameters* pMP = CreateModeling << 907 pMP->SetEvent(0); << 908 for (std::size_t i = 0; i < nModels; ++i) << 909 if (EORModelList[i].fActive) { << 910 fpModel = EORModelList[i].fpModel; << 911 fpModel -> SetModelingParameters(pMP); << 912 << 913 // Describe to the current scene handl << 914 fpModel -> DescribeYourselfTo (*this); << 915 << 916 // Enter models in the scene tree << 917 fpViewer->InsertModelInSceneTree(fpMod << 918 << 919 // Reset modeling parameters pointer << 920 fpModel -> SetModelingParameters(0); << 921 } << 922 } 616 } 923 fpModel = 0; << 924 delete pMP; 617 delete pMP; >> 618 SetModel (0); 925 } 619 } 926 } 620 } 927 621 928 G4ModelingParameters* G4VSceneHandler::CreateM 622 G4ModelingParameters* G4VSceneHandler::CreateModelingParameters () 929 { 623 { 930 // Create modeling parameters from View Para 624 // Create modeling parameters from View Parameters... 931 if (!fpViewer) return NULL; << 932 << 933 const G4ViewParameters& vp = fpViewer -> Get 625 const G4ViewParameters& vp = fpViewer -> GetViewParameters (); 934 626 935 // Convert drawing styles... 627 // Convert drawing styles... 936 G4ModelingParameters::DrawingStyle modelDraw 628 G4ModelingParameters::DrawingStyle modelDrawingStyle = 937 G4ModelingParameters::wf; << 629 G4ModelingParameters::wf; 938 switch (vp.GetDrawingStyle ()) { 630 switch (vp.GetDrawingStyle ()) { 939 default: << 631 default: 940 case G4ViewParameters::wireframe: << 632 case G4ViewParameters::wireframe: 941 modelDrawingStyle = G4ModelingParameters << 633 modelDrawingStyle = G4ModelingParameters::wf; 942 break; << 634 break; 943 case G4ViewParameters::hlr: << 635 case G4ViewParameters::hlr: 944 modelDrawingStyle = G4ModelingParameters << 636 modelDrawingStyle = G4ModelingParameters::hlr; 945 break; << 637 break; 946 case G4ViewParameters::hsr: << 638 case G4ViewParameters::hsr: 947 modelDrawingStyle = G4ModelingParameters << 639 modelDrawingStyle = G4ModelingParameters::hsr; 948 break; << 640 break; 949 case G4ViewParameters::hlhsr: << 641 case G4ViewParameters::hlhsr: 950 modelDrawingStyle = G4ModelingParameters << 642 modelDrawingStyle = G4ModelingParameters::hlhsr; 951 break; << 643 break; 952 case G4ViewParameters::cloud: << 953 modelDrawingStyle = G4ModelingParameters << 954 break; << 955 } 644 } 956 645 957 // Decide if covered daughters are really to 646 // Decide if covered daughters are really to be culled... 958 G4bool reallyCullCovered = 647 G4bool reallyCullCovered = 959 vp.IsCullingCovered() // Culling daughte 648 vp.IsCullingCovered() // Culling daughters depends also on... 960 && !vp.IsSection () // Sections (DCUT) 649 && !vp.IsSection () // Sections (DCUT) not requested. 961 && !vp.IsCutaway () // Cutaways not re 650 && !vp.IsCutaway () // Cutaways not requested. 962 ; 651 ; 963 652 964 G4ModelingParameters* pModelingParams = new 653 G4ModelingParameters* pModelingParams = new G4ModelingParameters 965 (vp.GetDefaultVisAttributes (), 654 (vp.GetDefaultVisAttributes (), 966 modelDrawingStyle, 655 modelDrawingStyle, 967 vp.IsCulling (), 656 vp.IsCulling (), 968 vp.IsCullingInvisible (), 657 vp.IsCullingInvisible (), 969 vp.IsDensityCulling (), 658 vp.IsDensityCulling (), 970 vp.GetVisibleDensity (), 659 vp.GetVisibleDensity (), 971 reallyCullCovered, 660 reallyCullCovered, 972 vp.GetNoOfSides () 661 vp.GetNoOfSides () 973 ); 662 ); 974 663 975 pModelingParams->SetNumberOfCloudPoints(vp.G << 976 pModelingParams->SetWarning 664 pModelingParams->SetWarning 977 (G4VisManager::GetVerbosity() >= G4VisMana << 665 (G4VisManager::GetInstance()->GetVerbosity() >= G4VisManager::warnings); 978 << 979 pModelingParams->SetCBDAlgorithmNumber(vp.Ge << 980 pModelingParams->SetCBDParameters(vp.GetCBDP << 981 666 982 pModelingParams->SetExplodeFactor(vp.GetExpl 667 pModelingParams->SetExplodeFactor(vp.GetExplodeFactor()); 983 pModelingParams->SetExplodeCentre(vp.GetExpl 668 pModelingParams->SetExplodeCentre(vp.GetExplodeCentre()); 984 669 985 pModelingParams->SetSectionSolid(CreateSecti << 670 pModelingParams->SetSectionPolyhedron(CreateSectionPolyhedron()); 986 << 671 pModelingParams->SetCutawayPolyhedron(CreateCutawayPolyhedron()); 987 if (vp.GetCutawayMode() == G4ViewParameters: << 988 pModelingParams->SetCutawayMode(G4Modeling << 989 } else if (vp.GetCutawayMode() == G4ViewPara << 990 pModelingParams->SetCutawayMode(G4Modeling << 991 } << 992 << 993 pModelingParams->SetCutawaySolid(CreateCutaw << 994 // The polyhedron objects are deleted in the 672 // The polyhedron objects are deleted in the modeling parameters destructor. 995 << 996 pModelingParams->SetVisAttributesModifiers(v << 997 << 998 pModelingParams->SetSpecialMeshRendering(vp. << 999 pModelingParams->SetSpecialMeshVolumes(vp.Ge << 1000 673 1001 return pModelingParams; 674 return pModelingParams; 1002 } 675 } 1003 676 1004 G4DisplacedSolid* G4VSceneHandler::CreateSect << 677 const G4Polyhedron* G4VSceneHandler::CreateSectionPolyhedron() 1005 { 678 { 1006 G4DisplacedSolid* sectioner = 0; << 679 /* Disable for now. Boolean processor not up to it. 1007 << 1008 const G4ViewParameters& vp = fpViewer->GetV 680 const G4ViewParameters& vp = fpViewer->GetViewParameters(); 1009 if (vp.IsSection () ) { 681 if (vp.IsSection () ) { 1010 << 1011 G4double radius = fpScene->GetExtent().Ge 682 G4double radius = fpScene->GetExtent().GetExtentRadius(); 1012 G4double safe = radius + fpScene->GetExte 683 G4double safe = radius + fpScene->GetExtent().GetExtentCentre().mag(); 1013 G4VSolid* sectionBox = << 684 G4Box sectionBox("clipper", 1014 new G4Box("_sectioner", safe, safe, 1.e << 685 safe, safe, 1.e-5 * radius); // Thin in z-plane. 1015 << 686 G4Polyhedron* sectioner = sectionBox.CreatePolyhedron(); 1016 const G4Plane3D& sp = vp.GetSectionPlane << 687 const G4Plane3D& s = vp.GetSectionPlane (); 1017 G4ThreeVector normal = sp.normal(); << 688 G4double a = s.a(); 1018 G4Transform3D requiredTransform = G4Trans << 689 G4double b = s.b(); 1019 G4Rotate3D(G4ThreeVector(0,0,1), G4ThreeV << 690 G4double c = s.c(); 1020 << 691 G4double d = s.d(); 1021 sectioner = new G4DisplacedSolid << 692 G4Transform3D transform = G4TranslateZ3D(-d); 1022 ("_displaced_sectioning_box", sectionBox, << 693 const G4Normal3D normal(a,b,c); >> 694 if (normal != G4Normal3D(0,0,1)) { >> 695 const G4double angle = std::acos(normal.dot(G4Normal3D(0,0,1))); >> 696 const G4Vector3D axis = G4Normal3D(0,0,1).cross(normal); >> 697 transform = G4Rotate3D(angle, axis) * transform; >> 698 } >> 699 sectioner->Transform(transform); >> 700 return sectioner; >> 701 } else { >> 702 return 0; 1023 } 703 } 1024 << 704 */ 1025 return sectioner; << 705 return 0; 1026 } 706 } 1027 707 1028 G4DisplacedSolid* G4VSceneHandler::CreateCuta << 708 const G4Polyhedron* G4VSceneHandler::CreateCutawayPolyhedron() 1029 { 709 { 1030 const auto& vp = fpViewer->GetViewParameter << 710 return 0; 1031 const auto& nPlanes = vp.GetCutawayPlanes() << 1032 << 1033 if (nPlanes == 0) return nullptr; << 1034 << 1035 std::vector<G4DisplacedSolid*> cutaway_soli << 1036 << 1037 G4double radius = fpScene->GetExtent().GetE << 1038 G4double safe = radius + fpScene->GetExtent << 1039 auto cutawayBox = new G4Box("_cutaway_box", << 1040 << 1041 // if (vp.GetCutawayMode() == G4ViewParamet << 1042 // the intersection of displaced cutaway bo << 1043 // positive values a*x+b*y+c*z+d>0, so we h << 1044 // "back to front". The parameter "cutawayU << 1045 // that remain *after* cutaway", because we << 1046 // a "union" of what remains by superimposi << 1047 // and G4OpenGLImmediate/StoredViewer::Proc << 1048 // that is the intersection of inverted cut << 1049 << 1050 // Conversely, if (vp.GetCutawayMode() == G << 1051 // create an intersector that is the inters << 1052 << 1053 for (size_t plane_no = 0; plane_no < nPlane << 1054 { << 1055 const G4Plane3D& sp = vp.GetCutawayPlanes << 1056 G4Transform3D requiredTransform; << 1057 G4ThreeVector normal; << 1058 switch (vp.GetCutawayMode()) { << 1059 case G4ViewParameters::cutawayUnion: << 1060 normal = -sp.normal(); // Invert nor << 1061 requiredTransform = G4Translate3D(nor << 1062 G4Rotate3D(G4ThreeVector(0,0,1), G4Th << 1063 break; << 1064 case G4ViewParameters::cutawayIntersect << 1065 normal = sp.normal(); << 1066 requiredTransform = G4Translate3D(nor << 1067 G4Rotate3D(G4ThreeVector(0,0,1), G4Th << 1068 break; << 1069 } << 1070 cutaway_solids.push_back << 1071 (new G4DisplacedSolid("_displaced_cutaway << 1072 } << 1073 << 1074 if (nPlanes == 1) return (G4DisplacedSolid* << 1075 << 1076 G4IntersectionSolid *union2 = nullptr, *uni << 1077 G4IntersectionSolid *intersection2 = nullpt << 1078 switch (vp.GetCutawayMode()) { << 1079 << 1080 case G4ViewParameters::cutawayUnion: << 1081 // Here we make a subtractor of interse << 1082 union2 = new G4IntersectionSolid("_unio << 1083 if (nPlanes == 2) return (G4DisplacedSo << 1084 else if (nPlanes == 3) { << 1085 union3 = new G4IntersectionSolid("_un << 1086 return (G4DisplacedSolid*)union3; << 1087 } << 1088 break; << 1089 << 1090 case G4ViewParameters::cutawayIntersectio << 1091 // And here we make an intersector of i << 1092 intersection2 << 1093 = new G4IntersectionSolid("_intersectio << 1094 if (nPlanes == 2) return (G4DisplacedSo << 1095 else if (nPlanes == 3) { << 1096 intersection3 << 1097 = new G4IntersectionSolid("_intersect << 1098 return (G4DisplacedSolid*)intersectio << 1099 } << 1100 break; << 1101 } << 1102 << 1103 G4Exception("G4VSceneHandler::CreateCutaway << 1104 "Not programmed for more than 3 << 1105 return nullptr; << 1106 } 711 } 1107 712 1108 void G4VSceneHandler::LoadAtts(const G4Visibl 713 void G4VSceneHandler::LoadAtts(const G4Visible& visible, G4AttHolder* holder) 1109 { 714 { 1110 // Load G4Atts from G4VisAttributes, if any 715 // Load G4Atts from G4VisAttributes, if any... 1111 const G4VisAttributes* va = visible.GetVisA 716 const G4VisAttributes* va = visible.GetVisAttributes(); 1112 if (va) { 717 if (va) { 1113 const std::map<G4String,G4AttDef>* vaDefs 718 const std::map<G4String,G4AttDef>* vaDefs = 1114 va->GetAttDefs(); 719 va->GetAttDefs(); 1115 if (vaDefs) { 720 if (vaDefs) { 1116 holder->AddAtts(visible.GetVisAttribute 721 holder->AddAtts(visible.GetVisAttributes()->CreateAttValues(), vaDefs); 1117 } 722 } 1118 } 723 } 1119 724 1120 G4PhysicalVolumeModel* pPVModel = 725 G4PhysicalVolumeModel* pPVModel = 1121 dynamic_cast<G4PhysicalVolumeModel*>(fpMo 726 dynamic_cast<G4PhysicalVolumeModel*>(fpModel); 1122 if (pPVModel) { 727 if (pPVModel) { 1123 // Load G4Atts from G4PhysicalVolumeModel 728 // Load G4Atts from G4PhysicalVolumeModel... 1124 const std::map<G4String,G4AttDef>* pvDefs << 729 const std::map<G4String,G4AttDef>* defs = pPVModel->GetAttDefs(); 1125 if (pvDefs) { << 730 if (defs) { 1126 holder->AddAtts(pPVModel->CreateCurrent << 731 holder->AddAtts(pPVModel->CreateCurrentAttValues(), defs); 1127 } 732 } 1128 } 733 } 1129 734 1130 G4TrajectoriesModel* trajModel = dynamic_ca 735 G4TrajectoriesModel* trajModel = dynamic_cast<G4TrajectoriesModel*>(fpModel); 1131 if (trajModel) { 736 if (trajModel) { 1132 // Load G4Atts from trajectory model... << 1133 const std::map<G4String,G4AttDef>* trajMo << 1134 if (trajModelDefs) { << 1135 holder->AddAtts(trajModel->CreateCurren << 1136 } << 1137 // Load G4Atts from trajectory... 737 // Load G4Atts from trajectory... 1138 const G4VTrajectory* traj = trajModel->Ge 738 const G4VTrajectory* traj = trajModel->GetCurrentTrajectory(); 1139 if (traj) { << 739 const std::map<G4String,G4AttDef>* defs = traj->GetAttDefs(); 1140 const std::map<G4String,G4AttDef>* traj << 740 if (defs) { 1141 if (trajDefs) { << 741 holder->AddAtts(traj->CreateAttValues(), defs); 1142 holder->AddAtts(traj->CreateAttValues << 742 } 1143 } << 743 G4int nPoints = traj->GetPointEntries(); 1144 G4int nPoints = traj->GetPointEntries() << 744 for (G4int i = 0; i < nPoints; ++i) { 1145 for (G4int i = 0; i < nPoints; ++i) { << 745 G4VTrajectoryPoint* trajPoint = traj->GetPoint(i); 1146 G4VTrajectoryPoint* trajPoint = traj- << 746 const std::map<G4String,G4AttDef>* defs = trajPoint->GetAttDefs(); 1147 if (trajPoint) { << 747 if (defs) { 1148 const std::map<G4String,G4AttDef>* << 748 holder->AddAtts(trajPoint->CreateAttValues(), defs); 1149 if (pointDefs) { << 1150 holder->AddAtts(trajPoint->Create << 1151 } << 1152 } << 1153 } 749 } 1154 } 750 } 1155 } 751 } 1156 752 1157 G4HitsModel* hitsModel = dynamic_cast<G4Hit 753 G4HitsModel* hitsModel = dynamic_cast<G4HitsModel*>(fpModel); 1158 if (hitsModel) { 754 if (hitsModel) { 1159 // Load G4Atts from hit... 755 // Load G4Atts from hit... 1160 const G4VHit* hit = hitsModel->GetCurrent 756 const G4VHit* hit = hitsModel->GetCurrentHit(); 1161 const std::map<G4String,G4AttDef>* hitsDe << 757 const std::map<G4String,G4AttDef>* defs = hit->GetAttDefs(); 1162 if (hitsDefs) { << 758 if (defs) { 1163 holder->AddAtts(hit->CreateAttValues(), << 759 holder->AddAtts(hit->CreateAttValues(), defs); 1164 } 760 } 1165 } 761 } 1166 } 762 } 1167 763 1168 const G4Colour& G4VSceneHandler::GetColour () << 1169 fpVisAttribs = fpViewer->GetApplicableVisAt << 1170 const G4Colour& colour = fpVisAttribs -> Ge << 1171 return colour; << 1172 } << 1173 << 1174 const G4Colour& G4VSceneHandler::GetColour (c 764 const G4Colour& G4VSceneHandler::GetColour (const G4Visible& visible) { 1175 auto pVA = visible.GetVisAttributes(); << 765 // Colour is determined by the applicable vis attributes. 1176 if (!pVA) pVA = fpViewer->GetViewParameters << 766 const G4Colour& colour = fpViewer -> 1177 return pVA->GetColour(); << 767 GetApplicableVisAttributes (visible.GetVisAttributes ()) -> GetColour (); >> 768 return colour; 1178 } 769 } 1179 770 1180 const G4Colour& G4VSceneHandler::GetTextColou 771 const G4Colour& G4VSceneHandler::GetTextColour (const G4Text& text) { 1181 auto pVA = text.GetVisAttributes(); << 772 const G4VisAttributes* pVA = text.GetVisAttributes (); 1182 if (!pVA) pVA = fpViewer->GetViewParameters << 773 if (!pVA) { 1183 return pVA->GetColour(); << 774 pVA = fpViewer -> GetViewParameters (). GetDefaultTextVisAttributes (); >> 775 } >> 776 const G4Colour& colour = pVA -> GetColour (); >> 777 return colour; 1184 } 778 } 1185 779 1186 G4double G4VSceneHandler::GetLineWidth(const 780 G4double G4VSceneHandler::GetLineWidth(const G4VisAttributes* pVisAttribs) 1187 { 781 { 1188 G4double lineWidth = pVisAttribs->GetLineWi 782 G4double lineWidth = pVisAttribs->GetLineWidth(); 1189 if (lineWidth < 1.) lineWidth = 1.; 783 if (lineWidth < 1.) lineWidth = 1.; 1190 lineWidth *= fpViewer -> GetViewParameters( 784 lineWidth *= fpViewer -> GetViewParameters().GetGlobalLineWidthScale(); 1191 if (lineWidth < 1.) lineWidth = 1.; 785 if (lineWidth < 1.) lineWidth = 1.; 1192 return lineWidth; 786 return lineWidth; 1193 } 787 } 1194 788 1195 G4ViewParameters::DrawingStyle G4VSceneHandle 789 G4ViewParameters::DrawingStyle G4VSceneHandler::GetDrawingStyle 1196 (const G4VisAttributes* pVisAttribs) { 790 (const G4VisAttributes* pVisAttribs) { 1197 // Drawing style is normally determined by 791 // Drawing style is normally determined by the view parameters, but 1198 // it can be overriddden by the ForceDrawin 792 // it can be overriddden by the ForceDrawingStyle flag in the vis 1199 // attributes. 793 // attributes. 1200 const G4ViewParameters& vp = fpViewer->GetV << 794 G4ViewParameters::DrawingStyle style = 1201 const G4ViewParameters::DrawingStyle viewer << 795 fpViewer->GetViewParameters().GetDrawingStyle(); 1202 G4ViewParameters::DrawingStyle resultantSty << 1203 if (pVisAttribs -> IsForceDrawingStyle ()) 796 if (pVisAttribs -> IsForceDrawingStyle ()) { 1204 G4VisAttributes::ForcedDrawingStyle force 797 G4VisAttributes::ForcedDrawingStyle forcedStyle = 1205 pVisAttribs -> GetForcedDrawingStyle (); << 798 pVisAttribs -> GetForcedDrawingStyle (); 1206 // This is complicated because if hidden 799 // This is complicated because if hidden line and surface removal 1207 // has been requested we wish to preserve 800 // has been requested we wish to preserve this sometimes. 1208 switch (forcedStyle) { 801 switch (forcedStyle) { 1209 case (G4VisAttributes::solid): << 802 case (G4VisAttributes::solid): 1210 switch (viewerStyle) { << 803 switch (style) { 1211 case (G4ViewParameters::hlr): << 804 case (G4ViewParameters::hlr): 1212 resultantStyle = G4ViewParameters << 805 style = G4ViewParameters::hlhsr; 1213 break; << 806 break; 1214 case (G4ViewParameters::wireframe): << 807 case (G4ViewParameters::wireframe): 1215 resultantStyle = G4ViewParameters << 808 style = G4ViewParameters::hsr; 1216 break; << 809 break; 1217 case (G4ViewParameters::cloud): << 810 case (G4ViewParameters::hlhsr): 1218 resultantStyle = G4ViewParameters << 811 case (G4ViewParameters::hsr): 1219 break; << 1220 case (G4ViewParameters::hlhsr): << 1221 case (G4ViewParameters::hsr): << 1222 break; << 1223 } << 1224 break; << 1225 case (G4VisAttributes::cloud): << 1226 resultantStyle = G4ViewParameters::cl << 1227 break; << 1228 case (G4VisAttributes::wireframe): << 1229 default: 812 default: 1230 // But if forced style is wireframe, << 813 break; 1231 // main uses is in displaying the con << 814 } 1232 // solid and their surfaces overlap w << 815 break; 1233 // solid, making a mess if hlr is spe << 816 case (G4VisAttributes::wireframe): 1234 resultantStyle = G4ViewParameters::wi << 817 default: 1235 break; << 818 // But if forced style is wireframe, do it, because one of its 1236 } << 819 // main uses is in displaying the consituent solids of a Boolean 1237 } << 820 // solid and their surfaces overlap with the resulting Booean 1238 return resultantStyle; << 821 // solid, making a mess if hlr is specified. 1239 } << 822 style = G4ViewParameters::wireframe; 1240 << 823 break; 1241 G4int G4VSceneHandler::GetNumberOfCloudPoints << 824 } 1242 (const G4VisAttributes* pVisAttribs) const { << 1243 // Returns no of cloud points from current << 1244 // has forced through the vis attributes, t << 1245 // current view parameter. << 1246 G4int numberOfCloudPoints = fpViewer->GetVi << 1247 if (pVisAttribs -> IsForceDrawingStyle() && << 1248 pVisAttribs -> GetForcedDrawingStyle() << 1249 pVisAttribs -> GetForcedNumberOfCloudPo << 1250 numberOfCloudPoints = pVisAttribs -> GetF << 1251 } 825 } 1252 return numberOfCloudPoints; << 826 return style; 1253 } 827 } 1254 828 1255 G4bool G4VSceneHandler::GetAuxEdgeVisible (co 829 G4bool G4VSceneHandler::GetAuxEdgeVisible (const G4VisAttributes* pVisAttribs) { 1256 G4bool isAuxEdgeVisible = fpViewer->GetView 830 G4bool isAuxEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible (); 1257 if (pVisAttribs -> IsForceAuxEdgeVisible()) << 831 if (pVisAttribs -> IsForceAuxEdgeVisible()) isAuxEdgeVisible = true; 1258 isAuxEdgeVisible = pVisAttribs->IsForcedA << 1259 } << 1260 return isAuxEdgeVisible; 832 return isAuxEdgeVisible; 1261 } 833 } 1262 834 1263 G4double G4VSceneHandler::GetMarkerSize 835 G4double G4VSceneHandler::GetMarkerSize 1264 (const G4VMarker& marker, 836 (const G4VMarker& marker, 1265 G4VSceneHandler::MarkerSizeType& markerSizeT 837 G4VSceneHandler::MarkerSizeType& markerSizeType) 1266 { 838 { 1267 G4bool userSpecified = marker.GetWorldSize( 839 G4bool userSpecified = marker.GetWorldSize() || marker.GetScreenSize(); 1268 const G4VMarker& defaultMarker = 840 const G4VMarker& defaultMarker = 1269 fpViewer -> GetViewParameters().GetDefaul 841 fpViewer -> GetViewParameters().GetDefaultMarker(); 1270 G4double size = userSpecified ? 842 G4double size = userSpecified ? 1271 marker.GetWorldSize() : defaultMarker.Get 843 marker.GetWorldSize() : defaultMarker.GetWorldSize(); 1272 if (size) { 844 if (size) { 1273 // Draw in world coordinates. 845 // Draw in world coordinates. 1274 markerSizeType = world; 846 markerSizeType = world; 1275 } 847 } 1276 else { 848 else { 1277 size = userSpecified ? 849 size = userSpecified ? 1278 marker.GetScreenSize() : defaultMarker. 850 marker.GetScreenSize() : defaultMarker.GetScreenSize(); 1279 // Draw in screen coordinates. 851 // Draw in screen coordinates. 1280 markerSizeType = screen; 852 markerSizeType = screen; 1281 } 853 } >> 854 if (size <= 1.) size = 1.; 1282 size *= fpViewer -> GetViewParameters().Get 855 size *= fpViewer -> GetViewParameters().GetGlobalMarkerScale(); 1283 if (markerSizeType == screen && size < 1.) << 856 if (size <= 1.) size = 1.; 1284 return size; 857 return size; 1285 } 858 } 1286 859 1287 G4int G4VSceneHandler::GetNoOfSides(const G4V 860 G4int G4VSceneHandler::GetNoOfSides(const G4VisAttributes* pVisAttribs) 1288 { 861 { 1289 // No. of sides (lines segments per circle) 862 // No. of sides (lines segments per circle) is normally determined 1290 // by the view parameters, but it can be ov 863 // by the view parameters, but it can be overriddden by the 1291 // ForceLineSegmentsPerCircle in the vis at 864 // ForceLineSegmentsPerCircle in the vis attributes. 1292 G4int lineSegmentsPerCircle = fpViewer->Get 865 G4int lineSegmentsPerCircle = fpViewer->GetViewParameters().GetNoOfSides(); 1293 if (pVisAttribs) { 866 if (pVisAttribs) { 1294 if (pVisAttribs->IsForceLineSegmentsPerCi 867 if (pVisAttribs->IsForceLineSegmentsPerCircle()) 1295 lineSegmentsPerCircle = pVisAttribs->Ge 868 lineSegmentsPerCircle = pVisAttribs->GetForcedLineSegmentsPerCircle(); 1296 if (lineSegmentsPerCircle < pVisAttribs-> << 869 const G4int nSegmentsMin = 12; 1297 lineSegmentsPerCircle = pVisAttribs->Ge << 870 if (lineSegmentsPerCircle < nSegmentsMin) { 1298 G4warn << << 871 lineSegmentsPerCircle = nSegmentsMin; >> 872 G4cout << 1299 "G4VSceneHandler::GetNoOfSides: attempt to 873 "G4VSceneHandler::GetNoOfSides: attempt to set the" 1300 "\nnumber of line segments per circle < " < << 874 "\nnumber of line segements per circle < " << nSegmentsMin 1301 << "; forced to " << pVisAttribs->GetM << 875 << "; forced to " << lineSegmentsPerCircle << G4endl; 1302 } 876 } 1303 } 877 } 1304 return lineSegmentsPerCircle; 878 return lineSegmentsPerCircle; 1305 } 879 } 1306 880 1307 std::ostream& operator << (std::ostream& os, << 881 std::ostream& operator << (std::ostream& os, const G4VSceneHandler& s) { 1308 882 1309 os << "Scene handler " << sh.fName << " has << 883 os << "Scene handler " << s.fName << " has " 1310 << sh.fViewerList.size () << " viewer(s) << 884 << s.fViewerList.size () << " viewer(s):"; 1311 for (std::size_t i = 0; i < sh.fViewerList. << 885 for (size_t i = 0; i < s.fViewerList.size (); i++) { 1312 os << "\n " << *(sh.fViewerList [i]); << 886 os << "\n " << *(s.fViewerList [i]); 1313 } 887 } 1314 888 1315 if (sh.fpScene) { << 889 if (s.fpScene) { 1316 os << "\n " << *sh.fpScene; << 890 os << "\n " << *s.fpScene; 1317 } 891 } 1318 else { 892 else { 1319 os << "\n This scene handler currently h 893 os << "\n This scene handler currently has no scene."; 1320 } 894 } 1321 895 1322 return os; 896 return os; 1323 } << 1324 << 1325 void G4VSceneHandler::PseudoSceneFor3DRectMes << 1326 if (fpPVModel->GetCurrentDepth() == fpMesh- << 1327 const auto& material = fpPVModel->GetCurr << 1328 const auto& name = material? material->Ge << 1329 const auto& pVisAtts = fpPVModel->GetCurr << 1330 // Get position in world coordinates << 1331 // As a parameterisation the box is trans << 1332 // and its centre, originally by definiti << 1333 const G4ThreeVector& position = fpCurrent << 1334 fPositionByMaterial.insert(std::make_pair << 1335 if (fNameAndVisAttsByMaterial.find(materi << 1336 // Store name and vis attributes of fir << 1337 fNameAndVisAttsByMaterial[material] = N << 1338 } << 1339 } << 1340 << 1341 void G4VSceneHandler::PseudoSceneForTetVertic << 1342 if (fpPVModel->GetCurrentDepth() == fpMesh- << 1343 // Need to know it's a tet !!!! or implem << 1344 try { << 1345 const auto& tet = dynamic_cast<const G4 << 1346 const auto& material = fpPVModel->GetCu << 1347 const auto& name = material? material-> << 1348 const auto& pVisAtts = fpPVModel->GetCu << 1349 // Transform into world coordinates if << 1350 if (fpCurrentObjectTransformation->xx() << 1351 fpCurrentObjectTransformation->yy() << 1352 fpCurrentObjectTransformation->zz() << 1353 const auto& vertices = tet.GetVertice << 1354 fVerticesByMaterial.insert(std::make_ << 1355 } else { << 1356 auto vertices = tet.GetVertices(); << 1357 for (auto&& vertex: vertices) { << 1358 vertex = G4Point3D(vertex).transfor << 1359 } << 1360 fVerticesByMaterial.insert(std::make_ << 1361 } << 1362 if (fNameAndVisAttsByMaterial.find(mate << 1363 // Store name and vis attributes of f << 1364 fNameAndVisAttsByMaterial[material] = << 1365 } << 1366 catch (const std::bad_cast&) { << 1367 G4ExceptionDescription ed; << 1368 ed << "Called for a mesh that is not a << 1369 G4Exception("PseudoSceneForTetVertices" << 1370 } << 1371 } << 1372 } << 1373 << 1374 void G4VSceneHandler::StandardSpecialMeshRend << 1375 // Standard way of special mesh rendering. << 1376 // MySceneHandler::AddCompound(const G4Mesh& << 1377 // appropriate or implement its own special m << 1378 { << 1379 G4bool implemented = false; << 1380 switch (mesh.GetMeshType()) { << 1381 case G4Mesh::rectangle: [[fallthrough]]; << 1382 case G4Mesh::nested3DRectangular: << 1383 switch (fpViewer->GetViewParameters().G << 1384 case G4ViewParameters::meshAsDefault: << 1385 [[fallthrough]]; << 1386 case G4ViewParameters::meshAsDots: << 1387 Draw3DRectMeshAsDots(mesh); // Rec << 1388 implemented = true; << 1389 break; << 1390 case G4ViewParameters::meshAsSurfaces << 1391 Draw3DRectMeshAsSurfaces(mesh); // << 1392 implemented = true; << 1393 break; << 1394 } << 1395 break; << 1396 case G4Mesh::tetrahedron: << 1397 switch (fpViewer->GetViewParameters().G << 1398 case G4ViewParameters::meshAsDefault: << 1399 [[fallthrough]]; << 1400 case G4ViewParameters::meshAsDots: << 1401 DrawTetMeshAsDots(mesh); // Tetrah << 1402 implemented = true; << 1403 break; << 1404 case G4ViewParameters::meshAsSurfaces << 1405 DrawTetMeshAsSurfaces(mesh); // Te << 1406 implemented = true; << 1407 break; << 1408 } << 1409 break; << 1410 case G4Mesh::cylinder: [[fallthrough]]; << 1411 case G4Mesh::sphere: [[fallthrough]]; << 1412 case G4Mesh::invalid: break; << 1413 } << 1414 if (implemented) { << 1415 // Draw container if not marked invisible << 1416 auto container = mesh.GetContainerVolume( << 1417 auto containerLogical = container->GetLog << 1418 auto containerVisAtts = containerLogical- << 1419 if (containerVisAtts == nullptr || contai << 1420 auto solid = containerLogical->GetSolid << 1421 auto polyhedron = solid->GetPolyhedron( << 1422 // Always draw as wireframe << 1423 G4VisAttributes tmpVisAtts; << 1424 if (containerVisAtts != nullptr) tmpVis << 1425 tmpVisAtts.SetForceWireframe(); << 1426 polyhedron->SetVisAttributes(tmpVisAtts << 1427 BeginPrimitives(mesh.GetTransform()); << 1428 AddPrimitive(*polyhedron); << 1429 EndPrimitives(); << 1430 } << 1431 } else { << 1432 // Invoke base class function << 1433 G4VSceneHandler::AddCompound(mesh); << 1434 } << 1435 return; << 1436 } << 1437 << 1438 void G4VSceneHandler::Draw3DRectMeshAsDots(co << 1439 // For a rectangular 3-D mesh, draw as colour << 1440 // one dot randomly placed in each visible me << 1441 { << 1442 // Check << 1443 if (mesh.GetMeshType() != G4Mesh::rectangle << 1444 mesh.GetMeshType() != G4Mesh::nested3DR << 1445 G4ExceptionDescription ed; << 1446 ed << "Called with a mesh that is not rec << 1447 G4Exception("G4VSceneHandler::Draw3DRectM << 1448 return; << 1449 } << 1450 << 1451 static G4bool firstPrint = true; << 1452 const auto& verbosity = G4VisManager::GetVe << 1453 G4bool print = firstPrint && verbosity >= G << 1454 if (print) { << 1455 G4cout << 1456 << "Special case drawing of 3D rectangula << 1457 << '\n' << mesh << 1458 << G4endl; << 1459 } << 1460 << 1461 const auto& container = mesh.GetContainerVo << 1462 << 1463 // This map is static so that once filled i << 1464 static std::map<G4String,std::map<const G4M << 1465 auto& dotsByMaterial = dotsByMaterialAndMes << 1466 << 1467 // Fill map if not already filled << 1468 if (dotsByMaterial.empty()) { << 1469 << 1470 // Get positions and material one cell at << 1471 // The pseudo scene allows a "private" de << 1472 // Instantiate a temporary G4PhysicalVolu << 1473 G4ModelingParameters tmpMP; << 1474 tmpMP.SetCulling(true); // This avoids d << 1475 tmpMP.SetCullingInvisible(true); // ... << 1476 const G4bool useFullExtent = true; // To << 1477 G4PhysicalVolumeModel tmpPVModel << 1478 (container, << 1479 G4PhysicalVolumeModel::UNLIMITED, << 1480 G4Transform3D(), // so that positions a << 1481 &tmpMP, << 1482 useFullExtent); << 1483 // Accumulate information in temporary ma << 1484 std::multimap<const G4Material*,const G4T << 1485 std::map<const G4Material*,G4VSceneHandle << 1486 // Instantiate the pseudo scene << 1487 PseudoSceneFor3DRectMeshPositions pseudoS << 1488 (&tmpPVModel,&mesh,positionByMaterial,nam << 1489 // Make private descent into the paramete << 1490 tmpPVModel.DescribeYourselfTo(pseudoScene << 1491 // Now we have a map of positions by mate << 1492 // Also a map of name and colour by mater << 1493 << 1494 const auto& prms = mesh.GetThreeDRectPara << 1495 const auto& halfX = prms.fHalfX; << 1496 const auto& halfY = prms.fHalfY; << 1497 const auto& halfZ = prms.fHalfZ; << 1498 << 1499 // Fill the permanent (static) map of dot << 1500 G4int nDotsTotal = 0; << 1501 for (const auto& entry: nameAndVisAttsByM << 1502 G4int nDots = 0; << 1503 const auto& material = entry.first; << 1504 const auto& nameAndVisAtts = nameAndVis << 1505 const auto& name = nameAndVisAtts.fName << 1506 const auto& visAtts = nameAndVisAtts.fV << 1507 G4Polymarker dots; << 1508 dots.SetInfo(name); << 1509 dots.SetVisAttributes(visAtts); << 1510 dots.SetMarkerType(G4Polymarker::dots); << 1511 dots.SetSize(G4VMarker::screen,1.); << 1512 // Enter empty polymarker into the map << 1513 dotsByMaterial[material] = dots; << 1514 // Now fill it in situ << 1515 auto& dotsInMap = dotsByMaterial[materi << 1516 const auto& range = positionByMaterial. << 1517 for (auto posByMat = range.first; posBy << 1518 dotsInMap.push_back(GetPointInBox(pos << 1519 ++nDots; << 1520 } << 1521 << 1522 if (print) { << 1523 G4cout << 1524 << std::setw(30) << std::left << name << 1525 << ": " << std::setw(7) << nDots << " << 1526 << ": colour " << std::fixed << std:: << 1527 << visAtts.GetColour() << std::defaul << 1528 << G4endl; << 1529 } << 1530 << 1531 nDotsTotal += nDots; << 1532 } << 1533 << 1534 if (print) { << 1535 G4cout << "Total number of dots: " << n << 1536 } << 1537 } << 1538 << 1539 // Some subsequent expressions apply only t << 1540 auto pPVModel = dynamic_cast<G4PhysicalVolu << 1541 << 1542 G4String parameterisationName; << 1543 if (pPVModel) { << 1544 parameterisationName = pPVModel->GetFullP << 1545 } << 1546 << 1547 // Draw the dots by material << 1548 // Ensure they are "hidden", i.e., use the << 1549 auto keepVP = fpViewer->GetViewParameters() << 1550 auto vp = fpViewer->GetViewParameters(); << 1551 vp.SetMarkerHidden(); << 1552 fpViewer->SetViewParameters(vp); << 1553 // Now we transform to world coordinates << 1554 BeginPrimitives (mesh.GetTransform()); << 1555 for (const auto& entry: dotsByMaterial) { << 1556 const auto& dots = entry.second; << 1557 // The current "leaf" node in the PVPath << 1558 // been converted into polymarkers by mat << 1559 // its name to that of the material (whos << 1560 // so that its appearance in the scene tr << 1561 // an appropriate name and its visibility << 1562 if (pPVModel) { << 1563 const auto& fullPVPath = pPVModel->GetF << 1564 auto leafPV = fullPVPath.back().GetPhys << 1565 leafPV->SetName(dots.GetInfo()); << 1566 } << 1567 // Add dots to the scene << 1568 AddPrimitive(dots); << 1569 } << 1570 EndPrimitives (); << 1571 // Restore view parameters << 1572 fpViewer->SetViewParameters(keepVP); << 1573 // Restore parameterisation name << 1574 if (pPVModel) { << 1575 pPVModel->GetFullPVPath().back().GetPhysi << 1576 } << 1577 << 1578 firstPrint = false; << 1579 return; << 1580 } << 1581 << 1582 void G4VSceneHandler::Draw3DRectMeshAsSurface << 1583 // For a rectangular 3-D mesh, draw as surfac << 1584 // with inner shared faces removed. << 1585 { << 1586 // Check << 1587 if (mesh.GetMeshType() != G4Mesh::rectangle << 1588 mesh.GetMeshType() != G4Mesh::nested3DR << 1589 G4ExceptionDescription ed; << 1590 ed << "Called with a mesh that is not rec << 1591 G4Exception("G4VSceneHandler::Draw3DRectM << 1592 return; << 1593 } << 1594 << 1595 static G4bool firstPrint = true; << 1596 const auto& verbosity = G4VisManager::GetVe << 1597 G4bool print = firstPrint && verbosity >= G << 1598 if (print) { << 1599 G4cout << 1600 << "Special case drawing of 3D rectangula << 1601 << '\n' << mesh << 1602 << G4endl; << 1603 } << 1604 << 1605 const auto& container = mesh.GetContainerVo << 1606 << 1607 // This map is static so that once filled i << 1608 static std::map<G4String,std::map<const G4M << 1609 auto& boxesByMaterial = boxesByMaterialAndM << 1610 << 1611 // Fill map if not already filled << 1612 if (boxesByMaterial.empty()) { << 1613 << 1614 // Get positions and material one cell at << 1615 // The pseudo scene allows a "private" de << 1616 // Instantiate a temporary G4PhysicalVolu << 1617 G4ModelingParameters tmpMP; << 1618 tmpMP.SetCulling(true); // This avoids d << 1619 tmpMP.SetCullingInvisible(true); // ... << 1620 const G4bool useFullExtent = true; // To << 1621 G4PhysicalVolumeModel tmpPVModel << 1622 (container, << 1623 G4PhysicalVolumeModel::UNLIMITED, << 1624 G4Transform3D(), // so that positions a << 1625 &tmpMP, << 1626 useFullExtent); << 1627 // Accumulate information in temporary ma << 1628 std::multimap<const G4Material*,const G4T << 1629 std::map<const G4Material*,G4VSceneHandle << 1630 // Instantiate the pseudo scene << 1631 PseudoSceneFor3DRectMeshPositions pseudoS << 1632 (&tmpPVModel,&mesh,positionByMaterial,nam << 1633 // Make private descent into the paramete << 1634 tmpPVModel.DescribeYourselfTo(pseudoScene << 1635 // Now we have a map of positions by mate << 1636 // Also a map of name and colour by mater << 1637 << 1638 const auto& prms = mesh.GetThreeDRectPara << 1639 const auto& sizeX = 2.*prms.fHalfX; << 1640 const auto& sizeY = 2.*prms.fHalfY; << 1641 const auto& sizeZ = 2.*prms.fHalfZ; << 1642 << 1643 // Fill the permanent (static) map of box << 1644 G4int nBoxesTotal = 0, nFacetsTotal = 0; << 1645 for (const auto& entry: nameAndVisAttsByM << 1646 G4int nBoxes = 0; << 1647 const auto& material = entry.first; << 1648 const auto& nameAndVisAtts = nameAndVis << 1649 const auto& name = nameAndVisAtts.fName << 1650 const auto& visAtts = nameAndVisAtts.fV << 1651 // Transfer positions into a vector rea << 1652 std::vector<G4ThreeVector> positionsFor << 1653 const auto& range = positionByMaterial. << 1654 for (auto posByMat = range.first; posBy << 1655 const auto& position = posByMat->seco << 1656 positionsForPolyhedron.push_back(posi << 1657 ++nBoxes; << 1658 } << 1659 // The polyhedron will be in local coor << 1660 // Add an empty place-holder to the map << 1661 auto& polyhedron = boxesByMaterial[mate << 1662 // Replace with the desired polyhedron << 1663 polyhedron = G4PolyhedronBoxMesh(sizeX, << 1664 polyhedron.SetVisAttributes(visAtts); << 1665 polyhedron.SetInfo(name); << 1666 << 1667 if (print) { << 1668 G4cout << 1669 << std::setw(30) << std::left << name << 1670 << ": " << std::setw(7) << nBoxes << << 1671 << " (" << std::setw(7) << 6*nBoxes < << 1672 << ": reduced to " << std::setw(7) << << 1673 << std::setw(2) << std::fixed << std: << 1674 << "%): colour " << std::fixed << std << 1675 << visAtts.GetColour() << std::defaul << 1676 << G4endl; << 1677 } << 1678 << 1679 nBoxesTotal += nBoxes; << 1680 nFacetsTotal += polyhedron.GetNoFacets( << 1681 } << 1682 << 1683 if (print) { << 1684 G4cout << "Total number of boxes: " << << 1685 << ": reduced to " << nFacetsTotal << " << 1686 << std::setw(2) << std::fixed << std::s << 1687 << G4endl; << 1688 } << 1689 } << 1690 << 1691 // Some subsequent expressions apply only t << 1692 auto pPVModel = dynamic_cast<G4PhysicalVolu << 1693 << 1694 G4String parameterisationName; << 1695 if (pPVModel) { << 1696 parameterisationName = pPVModel->GetFullP << 1697 } << 1698 << 1699 // Draw the boxes by material << 1700 // Now we transform to world coordinates << 1701 BeginPrimitives (mesh.GetTransform()); << 1702 for (const auto& entry: boxesByMaterial) { << 1703 const auto& poly = entry.second; << 1704 // The current "leaf" node in the PVPath << 1705 // been converted into polyhedra by mater << 1706 // its name to that of the material (whos << 1707 // so that its appearance in the scene tr << 1708 // an appropriate name and its visibility << 1709 if (pPVModel) { << 1710 const auto& fullPVPath = pPVModel->GetF << 1711 auto leafPV = fullPVPath.back().GetPhys << 1712 leafPV->SetName(poly.GetInfo()); << 1713 } << 1714 AddPrimitive(poly); << 1715 } << 1716 EndPrimitives (); << 1717 // Restore parameterisation name << 1718 if (pPVModel) { << 1719 pPVModel->GetFullPVPath().back().GetPhysi << 1720 } << 1721 << 1722 firstPrint = false; << 1723 return; << 1724 } << 1725 << 1726 void G4VSceneHandler::DrawTetMeshAsDots(const << 1727 // For a tetrahedron mesh, draw as coloured d << 1728 // one dot randomly placed in each visible me << 1729 { << 1730 // Check << 1731 if (mesh.GetMeshType() != G4Mesh::tetrahedr << 1732 G4ExceptionDescription ed; << 1733 ed << "Called with mesh that is not a tet << 1734 G4Exception("G4VSceneHandler::DrawTetMesh << 1735 return; << 1736 } << 1737 << 1738 static G4bool firstPrint = true; << 1739 const auto& verbosity = G4VisManager::GetVe << 1740 G4bool print = firstPrint && verbosity >= G << 1741 << 1742 if (print) { << 1743 G4cout << 1744 << "Special case drawing of tetrahedron m << 1745 << '\n' << mesh << 1746 << G4endl; << 1747 } << 1748 << 1749 const auto& container = mesh.GetContainerVo << 1750 << 1751 // This map is static so that once filled i << 1752 static std::map<G4String,std::map<const G4M << 1753 auto& dotsByMaterial = dotsByMaterialAndMes << 1754 << 1755 // Fill map if not already filled << 1756 if (dotsByMaterial.empty()) { << 1757 << 1758 // Get vertices and colour one cell at a << 1759 // The pseudo scene allows a "private" de << 1760 // Instantiate a temporary G4PhysicalVolu << 1761 G4ModelingParameters tmpMP; << 1762 tmpMP.SetCulling(true); // This avoids d << 1763 tmpMP.SetCullingInvisible(true); // ... << 1764 const G4bool useFullExtent = true; // To << 1765 G4PhysicalVolumeModel tmpPVModel << 1766 (container, << 1767 G4PhysicalVolumeModel::UNLIMITED, << 1768 G4Transform3D(), // so that positions a << 1769 &tmpMP, << 1770 useFullExtent); << 1771 // Accumulate information in temporary ma << 1772 std::multimap<const G4Material*,std::vect << 1773 std::map<const G4Material*,G4VSceneHandle << 1774 // Instantiate a pseudo scene << 1775 PseudoSceneForTetVertices pseudoScene << 1776 (&tmpPVModel,&mesh,verticesByMaterial,nam << 1777 // Make private descent into the paramete << 1778 tmpPVModel.DescribeYourselfTo(pseudoScene << 1779 // Now we have a map of vertices by mater << 1780 // Also a map of name and colour by mater << 1781 << 1782 // Fill the permanent (static) map of dot << 1783 G4int nDotsTotal = 0; << 1784 for (const auto& entry: nameAndVisAttsByM << 1785 G4int nDots = 0; << 1786 const auto& material = entry.first; << 1787 const auto& nameAndVisAtts = nameAndVis << 1788 const auto& name = nameAndVisAtts.fName << 1789 const auto& visAtts = nameAndVisAtts.fV << 1790 G4Polymarker dots; << 1791 dots.SetVisAttributes(visAtts); << 1792 dots.SetMarkerType(G4Polymarker::dots); << 1793 dots.SetSize(G4VMarker::screen,1.); << 1794 dots.SetInfo(name); << 1795 // Enter empty polymarker into the map << 1796 dotsByMaterial[material] = dots; << 1797 // Now fill it in situ << 1798 auto& dotsInMap = dotsByMaterial[materi << 1799 const auto& range = verticesByMaterial. << 1800 for (auto vByMat = range.first; vByMat << 1801 dotsInMap.push_back(GetPointInTet(vBy << 1802 ++nDots; << 1803 } << 1804 << 1805 if (print) { << 1806 G4cout << 1807 << std::setw(30) << std::left << name << 1808 << ": " << std::setw(7) << nDots << " << 1809 << ": colour " << std::fixed << std:: << 1810 << visAtts.GetColour() << std::defaul << 1811 << G4endl; << 1812 } << 1813 << 1814 nDotsTotal += nDots; << 1815 } << 1816 << 1817 if (print) { << 1818 G4cout << "Total number of dots: " << n << 1819 } << 1820 } << 1821 << 1822 // Some subsequent expressions apply only t << 1823 auto pPVModel = dynamic_cast<G4PhysicalVolu << 1824 << 1825 G4String parameterisationName; << 1826 if (pPVModel) { << 1827 parameterisationName = pPVModel->GetFullP << 1828 } << 1829 << 1830 // Draw the dots by material << 1831 // Ensure they are "hidden", i.e., use the << 1832 auto keepVP = fpViewer->GetViewParameters() << 1833 auto vp = fpViewer->GetViewParameters(); << 1834 vp.SetMarkerHidden(); << 1835 fpViewer->SetViewParameters(vp); << 1836 << 1837 // Now we transform to world coordinates << 1838 BeginPrimitives (mesh.GetTransform()); << 1839 for (const auto& entry: dotsByMaterial) { << 1840 const auto& dots = entry.second; << 1841 // The current "leaf" node in the PVPath << 1842 // been converted into polymarkers by mat << 1843 // its name to that of the material (whos << 1844 // so that its appearance in the scene tr << 1845 // an appropriate name and its visibility << 1846 if (pPVModel) { << 1847 const auto& fullPVPath = pPVModel->GetF << 1848 auto leafPV = fullPVPath.back().GetPhys << 1849 leafPV->SetName(dots.GetInfo()); << 1850 } << 1851 AddPrimitive(dots); << 1852 } << 1853 EndPrimitives (); << 1854 << 1855 // Restore view parameters << 1856 fpViewer->SetViewParameters(keepVP); << 1857 // Restore parameterisation name << 1858 if (pPVModel) { << 1859 pPVModel->GetFullPVPath().back().GetPhysi << 1860 } << 1861 << 1862 firstPrint = false; << 1863 return; << 1864 } << 1865 << 1866 void G4VSceneHandler::DrawTetMeshAsSurfaces(c << 1867 // For a tetrahedron mesh, draw as surfaces b << 1868 // with inner shared faces removed. << 1869 { << 1870 // Check << 1871 if (mesh.GetMeshType() != G4Mesh::tetrahedr << 1872 G4ExceptionDescription ed; << 1873 ed << "Called with mesh that is not a tet << 1874 G4Exception("G4VSceneHandler::DrawTetMesh << 1875 return; << 1876 } << 1877 << 1878 static G4bool firstPrint = true; << 1879 const auto& verbosity = G4VisManager::GetVe << 1880 G4bool print = firstPrint && verbosity >= G << 1881 << 1882 if (print) { << 1883 G4cout << 1884 << "Special case drawing of tetrahedron m << 1885 << '\n' << mesh << 1886 << G4endl; << 1887 } << 1888 << 1889 // This map is static so that once filled i << 1890 static std::map<G4String,std::map<const G4M << 1891 auto& surfacesByMaterial = surfacesByMateri << 1892 << 1893 // Fill map if not already filled << 1894 if (surfacesByMaterial.empty()) { << 1895 << 1896 // Get vertices and colour one cell at a << 1897 // The pseudo scene allows a "private" de << 1898 // Instantiate a temporary G4PhysicalVolu << 1899 G4ModelingParameters tmpMP; << 1900 tmpMP.SetCulling(true); // This avoids d << 1901 tmpMP.SetCullingInvisible(true); // ... << 1902 const G4bool useFullExtent = true; // To << 1903 G4PhysicalVolumeModel tmpPVModel << 1904 (mesh.GetContainerVolume(), << 1905 G4PhysicalVolumeModel::UNLIMITED, << 1906 G4Transform3D(), // so that positions a << 1907 &tmpMP, << 1908 useFullExtent); << 1909 // Accumulate information in temporary ma << 1910 std::multimap<const G4Material*,std::vect << 1911 std::map<const G4Material*,G4VSceneHandle << 1912 // Instantiate a pseudo scene << 1913 PseudoSceneForTetVertices pseudoScene << 1914 (&tmpPVModel,&mesh,verticesByMaterial,nam << 1915 // Make private descent into the paramete << 1916 tmpPVModel.DescribeYourselfTo(pseudoScene << 1917 // Now we have a map of vertices by mater << 1918 // Also a map of name and colour by mater << 1919 << 1920 // Fill the permanent (static) map of sur << 1921 G4int nTetsTotal = 0, nFacetsTotal = 0; << 1922 for (const auto& entry: nameAndVisAttsByM << 1923 G4int nTets = 0; << 1924 const auto& material = entry.first; << 1925 const auto& nameAndVisAtts = nameAndVis << 1926 const auto& name = nameAndVisAtts.fName << 1927 const auto& visAtts = nameAndVisAtts.fV << 1928 // Transfer vertices into a vector read << 1929 std::vector<G4ThreeVector> verticesForP << 1930 const auto& range = verticesByMaterial. << 1931 for (auto vByMat = range.first; vByMat << 1932 const std::vector<G4ThreeVector>& ver << 1933 for (const auto& vertex: vertices) << 1934 verticesForPolyhedron.push_back(ver << 1935 ++nTets; << 1936 } << 1937 // The polyhedron will be in local coor << 1938 // Add an empty place-holder to the map << 1939 auto& polyhedron = surfacesByMaterial[m << 1940 // Replace with the desired polyhedron << 1941 polyhedron = G4PolyhedronTetMesh(vertic << 1942 polyhedron.SetVisAttributes(visAtts); << 1943 polyhedron.SetInfo(name); << 1944 << 1945 if (print) { << 1946 G4cout << 1947 << std::setw(30) << std::left << name << 1948 << ": " << std::setw(7) << nTets << " << 1949 << " (" << std::setw(7) << 4*nTets << << 1950 << ": reduced to " << std::setw(7) << << 1951 << std::setw(2) << std::fixed << std: << 1952 << "%): colour " << std::fixed << std << 1953 << visAtts.GetColour() << std::defaul << 1954 << G4endl; << 1955 } << 1956 << 1957 nTetsTotal += nTets; << 1958 nFacetsTotal += polyhedron.GetNoFacets( << 1959 } << 1960 << 1961 if (print) { << 1962 G4cout << "Total number of tetrahedra: << 1963 << ": reduced to " << nFacetsTotal << " << 1964 << std::setw(2) << std::fixed << std::s << 1965 << G4endl; << 1966 } << 1967 } << 1968 << 1969 // Some subsequent expressions apply only t << 1970 auto pPVModel = dynamic_cast<G4PhysicalVolu << 1971 << 1972 G4String parameterisationName; << 1973 if (pPVModel) { << 1974 parameterisationName = pPVModel->GetFullP << 1975 } << 1976 << 1977 // Draw the surfaces by material << 1978 // Now we transform to world coordinates << 1979 BeginPrimitives (mesh.GetTransform()); << 1980 for (const auto& entry: surfacesByMaterial) << 1981 const auto& poly = entry.second; << 1982 // The current "leaf" node in the PVPath << 1983 // been converted into polyhedra by mater << 1984 // its name to that of the material (whos << 1985 // so that its appearance in the scene tr << 1986 // an appropriate name and its visibility << 1987 if (pPVModel) { << 1988 const auto& fullPVPath = pPVModel->GetF << 1989 auto leafPV = fullPVPath.back().GetPhys << 1990 leafPV->SetName(poly.GetInfo()); << 1991 } << 1992 AddPrimitive(poly); << 1993 } << 1994 EndPrimitives (); << 1995 << 1996 // Restore parameterisation name << 1997 if (pPVModel) { << 1998 pPVModel->GetFullPVPath().back().GetPhysi << 1999 } << 2000 << 2001 firstPrint = false; << 2002 return; << 2003 } << 2004 << 2005 G4ThreeVector << 2006 G4VSceneHandler::GetPointInBox(const G4ThreeV << 2007 G4double halfX << 2008 G4double halfY << 2009 G4double halfZ << 2010 { << 2011 G4double x = pos.getX() + (2.*G4QuickRand() << 2012 G4double y = pos.getY() + (2.*G4QuickRand() << 2013 G4double z = pos.getZ() + (2.*G4QuickRand() << 2014 return G4ThreeVector(x, y, z); << 2015 } << 2016 << 2017 G4ThreeVector << 2018 G4VSceneHandler::GetPointInTet(const std::vec << 2019 { << 2020 G4double p = G4QuickRand(); << 2021 G4double q = G4QuickRand(); << 2022 G4double r = G4QuickRand(); << 2023 if (p + q > 1.) << 2024 { << 2025 p = 1. - p; << 2026 q = 1. - q; << 2027 } << 2028 if (q + r > 1.) << 2029 { << 2030 G4double tmp = r; << 2031 r = 1. - p - q; << 2032 q = 1. - tmp; << 2033 } << 2034 else if (p + q + r > 1.) << 2035 { << 2036 G4double tmp = r; << 2037 r = p + q + r - 1.; << 2038 p = 1. - q - tmp; << 2039 } << 2040 G4double a = 1. - p - q - r; << 2041 return vertices[0]*a + vertices[1]*p + vert << 2042 } 897 } 2043 898