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: G4VViewer.cc,v 1.24 2007/01/05 16:25:15 allison Exp $ >> 28 // GEANT4 tag $Name: geant4-09-01-patch-03 $ 27 // 29 // 28 // << 30 // 29 // John Allison 27th March 1996 31 // John Allison 27th March 1996 30 // Abstract interface class for graphics views 32 // Abstract interface class for graphics views. 31 33 32 #include "G4VViewer.hh" 34 #include "G4VViewer.hh" 33 35 34 #include "G4PhysicalVolumeStore.hh" << 35 #include "G4Scene.hh" << 36 #include "G4Timer.hh" << 37 #include "G4Transform3D.hh" << 38 #include "G4UImanager.hh" << 39 #include "G4UIsession.hh" << 40 #include "G4VGraphicsSystem.hh" << 41 #include "G4VInteractiveSession.hh" << 42 #include "G4VPhysicalVolume.hh" << 43 #include "G4VSceneHandler.hh" << 44 #include "G4VisManager.hh" << 45 #include "G4ios.hh" 36 #include "G4ios.hh" 46 << 47 #include <sstream> 37 #include <sstream> 48 38 49 G4VViewer::G4VViewer(G4VSceneHandler& sceneHan << 39 #include "G4VisManager.hh" 50 : fSceneHandler(sceneHandler), fViewId(id), << 40 #include "G4VGraphicsSystem.hh" >> 41 #include "G4VSceneHandler.hh" >> 42 #include "G4Scene.hh" >> 43 #include "G4VPhysicalVolume.hh" >> 44 #include "G4Transform3D.hh" >> 45 >> 46 G4VViewer::G4VViewer (G4VSceneHandler& sceneHandler, >> 47 G4int id, const G4String& name): >> 48 fSceneHandler (sceneHandler), >> 49 fViewId (id), >> 50 //fModified (true), >> 51 fNeedKernelVisit (true) 51 { 52 { 52 if (name == "") { 53 if (name == "") { 53 std::ostringstream ost; 54 std::ostringstream ost; 54 ost << fSceneHandler.GetName() << '-' << f << 55 ost << fSceneHandler.GetName () << '-' << fViewId; 55 fName = ost.str(); 56 fName = ost.str(); 56 } 57 } 57 else { 58 else { 58 fName = name; 59 fName = name; 59 } 60 } 60 fShortName = fName.substr(0, fName.find(' ') << 61 fShortName = fName (0, fName.find (' ')); 61 G4StrUtil::strip(fShortName); << 62 fShortName.strip (); 62 << 63 fVP = G4VisManager::GetInstance()->GetDefaul << 64 fDefaultVP = fVP; << 65 63 66 fSceneTree.SetType(G4SceneTreeItem::root); << 64 G4VisManager* pVisMan = G4VisManager::GetInstance(); 67 fSceneTree.SetDescription(fName); << 65 G4int xHint, yHint; >> 66 pVisMan->GetWindowSizeHint(xHint, yHint); >> 67 const G4String& XGeometryString = pVisMan->GetXGeometryString(); >> 68 fVP.SetWindowSizeHint(xHint,yHint); >> 69 fVP.SetXGeometryString(XGeometryString); >> 70 fDefaultVP.SetWindowSizeHint(xHint,yHint); >> 71 fDefaultVP.SetXGeometryString(XGeometryString); 68 } 72 } 69 73 70 G4VViewer::~G4VViewer() << 74 G4VViewer::~G4VViewer () {} 71 { << 72 fSceneHandler.RemoveViewerFromList(this); << 73 } << 74 75 75 void G4VViewer::SetName(const G4String& name) << 76 void G4VViewer::SetName (const G4String& name) { 76 { << 77 fName = name; 77 fName = name; 78 fShortName = fName.substr(0, fName.find(' ') << 78 fShortName = fName (0, fName.find (' ')); 79 G4StrUtil::strip(fShortName); << 79 fShortName.strip (); 80 } 80 } 81 81 82 void G4VViewer::NeedKernelVisit() << 82 const G4VisAttributes* G4VViewer::GetApplicableVisAttributes 83 { << 83 (const G4VisAttributes* pVisAttribs) const { >> 84 // If pVisAttribs is zero, pick up the default vis attributes from >> 85 // the view parameters. >> 86 if (!pVisAttribs) >> 87 pVisAttribs = GetViewParameters ().GetDefaultVisAttributes (); >> 88 return pVisAttribs; >> 89 } >> 90 >> 91 void G4VViewer::NeedKernelVisit () { >> 92 84 fNeedKernelVisit = true; 93 fNeedKernelVisit = true; 85 94 86 // At one time I thought we'd better notify 95 // At one time I thought we'd better notify all viewers. But I guess 87 // each viewer can take care of itself, so t 96 // each viewer can take care of itself, so the following code is 88 // redundant (but keep it commented out for 97 // redundant (but keep it commented out for now). (John Allison) 89 // Notify all viewers that a kernel visit is 98 // Notify all viewers that a kernel visit is required. 90 // const G4ViewerList& viewerList = fSceneHa 99 // const G4ViewerList& viewerList = fSceneHandler.GetViewerList (); 91 // G4ViewerListConstIterator i; 100 // G4ViewerListConstIterator i; 92 // for (i = viewerList.begin(); i != viewerL 101 // for (i = viewerList.begin(); i != viewerList.end(); i++) { 93 // (*i) -> SetNeedKernelVisit (); 102 // (*i) -> SetNeedKernelVisit (); 94 // } 103 // } 95 // ??...but, there's a problem in OpenGL Sto 104 // ??...but, there's a problem in OpenGL Stored which seems to 96 // require *all* viewers to revisit the kern 105 // require *all* viewers to revisit the kernel, so... 97 // const G4ViewerList& viewerList = fSceneH << 106 /* 98 // G4ViewerListConstIterator i; << 107 const G4ViewerList& viewerList = fSceneHandler.GetViewerList (); 99 // for (i = viewerList.begin(); i != viewer << 108 G4ViewerListConstIterator i; 100 // (*i) -> SetNeedKernelVisit (true); << 109 for (i = viewerList.begin(); i != viewerList.end(); i++) { 101 // } << 110 (*i) -> SetNeedKernelVisit (true); >> 111 } >> 112 */ 102 // Feb 2005 - commented out. Let's fix Open 113 // Feb 2005 - commented out. Let's fix OpenGL if necessary. 103 } 114 } 104 115 105 void G4VViewer::FinishView() {} << 116 void G4VViewer::FinishView () {} 106 117 107 void G4VViewer::ShowView() {} << 118 void G4VViewer::ShowView () {} 108 119 109 void G4VViewer::ProcessView() << 120 void G4VViewer::ProcessView () 110 { 121 { 111 // If the scene has changed, or if the concr << 122 // If ClearStore has been requested, e.g., if the scene has changed, 112 // that it necessary to visit the kernel, pe << 123 // or if the concrete viewer has decided that it necessary to visit 113 // parameters have changed significantly (th << 124 // the kernel, perhaps because the view parameters have changed 114 // concrete viewer's DrawView)... << 125 // significantly (this should be done in the concrete viewer's >> 126 // DrawView)... 115 if (fNeedKernelVisit) { 127 if (fNeedKernelVisit) { 116 // Reset flag. This must be done before P 128 // Reset flag. This must be done before ProcessScene to prevent 117 // recursive calls when recomputing transi 129 // recursive calls when recomputing transients... 118 G4Timer timer; << 119 timer.Start(); << 120 fNeedKernelVisit = false; 130 fNeedKernelVisit = false; 121 fSceneHandler.ClearStore(); << 131 fSceneHandler.ProcessScene (*this); 122 fSceneHandler.ProcessScene(); << 123 UpdateGUISceneTree(); << 124 timer.Stop(); << 125 fKernelVisitElapsedTimeSeconds = timer.Get << 126 } 132 } 127 } 133 } 128 134 129 void G4VViewer::SetViewParameters(const G4View << 135 void G4VViewer::SetViewParameters (const G4ViewParameters& vp) { 130 { << 131 fVP = vp; 136 fVP = vp; 132 } 137 } 133 138 134 void G4VViewer::SetTouchable( << 139 std::ostream& operator << (std::ostream& os, const G4VViewer& v) { 135 const std::vector<G4PhysicalVolumeModel::G4P << 136 { << 137 // Set the touchable for /vis/touchable/set/ << 138 std::ostringstream oss; << 139 const auto& pvStore = G4PhysicalVolumeStore: << 140 for (const auto& pvNodeId : fullPath) { << 141 const auto& pv = pvNodeId.GetPhysicalVolum << 142 auto iterator = find(pvStore->cbegin(), pv << 143 if (iterator == pvStore->cend()) { << 144 G4ExceptionDescription ed; << 145 ed << "Volume no longer in physical volu << 146 G4Exception("G4VViewer::SetTouchable", " << 147 } << 148 else { << 149 oss << ' ' << pvNodeId.GetPhysicalVolume << 150 } << 151 } << 152 G4UImanager::GetUIpointer()->ApplyCommand("/ << 153 } << 154 << 155 void G4VViewer::TouchableSetVisibility( << 156 const std::vector<G4PhysicalVolumeModel::G4P << 157 { << 158 // Changes the Vis Attribute Modifiers and s << 159 << 160 // The following is equivalent to << 161 // G4UImanager::GetUIpointer()->ApplyComman << 162 // (assuming the touchable has already been << 163 << 164 // Instantiate a working copy of a G4VisAttr << 165 G4VisAttributes workingVisAtts; << 166 // and set the visibility. << 167 workingVisAtts.SetVisibility(visibiity); << 168 << 169 fVP.AddVisAttributesModifier(G4ModelingParam << 170 workingVisAtts, G4ModelingParameters::VASV << 171 G4PhysicalVolumeModel::GetPVNameCopyNoPath << 172 // G4ModelingParameters::VASVisibility (VAS << 173 // signifies that it is the visibility that << 174 // and merged with the touchable's normal vi << 175 << 176 // Find scene tree item and set visibility << 177 // The scene tree works with strings << 178 G4String fullPathString = G4PhysicalVolumeMo << 179 std::list<G4SceneTreeItem>::iterator foundIt << 180 if (fSceneTree.FindTouchableFromRoot(fullPat << 181 foundIter->AccessVisAttributes().SetVisibi << 182 UpdateGUISceneTree(); << 183 } << 184 else { << 185 G4ExceptionDescription ed; << 186 ed << "Touchable \"" << fullPath << "\" no << 187 G4Exception("G4VViewer::TouchableSetVisibi << 188 } << 189 } << 190 << 191 void G4VViewer::TouchableSetColour( << 192 const std::vector<G4PhysicalVolumeModel::G4P << 193 const G4Colour& colour) << 194 { << 195 // Changes the Vis Attribute Modifiers and s << 196 << 197 // The following is equivalent to << 198 // G4UImanager::GetUIpointer()->ApplyComman << 199 // (assuming the touchable has already been << 200 << 201 // Instantiate a working copy of a G4VisAttr << 202 G4VisAttributes workingVisAtts; << 203 // and set the colour. << 204 workingVisAtts.SetColour(colour); << 205 << 206 fVP.AddVisAttributesModifier(G4ModelingParam << 207 workingVisAtts, G4ModelingParameters::VASC << 208 G4PhysicalVolumeModel::GetPVNameCopyNoPath << 209 // G4ModelingParameters::VASColour (VAS = Vi << 210 // signifies that it is the colour that shou << 211 // and merged with the touchable's normal vi << 212 << 213 // Find scene tree item and set colour << 214 // The scene tree works with strings << 215 G4String fullPathString = G4PhysicalVolumeMo << 216 std::list<G4SceneTreeItem>::iterator foundIt << 217 if (fSceneTree.FindTouchableFromRoot(fullPat << 218 foundIter->AccessVisAttributes().SetColour << 219 UpdateGUISceneTree(); << 220 } << 221 else { << 222 G4ExceptionDescription ed; << 223 ed << "Touchable \"" << fullPath << "\" no << 224 G4Exception("G4VViewer::TouchableSetColour << 225 } << 226 } << 227 << 228 void G4VViewer::UpdateGUISceneTree() << 229 { << 230 G4UImanager* UI = G4UImanager::GetUIpointer( << 231 auto uiWindow = dynamic_cast<G4VInteractiveS << 232 if (uiWindow) uiWindow->UpdateSceneTree(fSce << 233 } << 234 << 235 void G4VViewer::InsertModelInSceneTree(G4VMode << 236 { << 237 const auto& modelType = model->GetType(); << 238 const auto& modelDescription = model->GetGlo << 239 << 240 auto type = G4SceneTreeItem::model; << 241 auto pvModel = dynamic_cast<G4PhysicalVolume << 242 if (pvModel) type = G4SceneTreeItem::pvmodel << 243 << 244 fCurtailDescent = false; // This is used la << 245 G4String furtherInfo; << 246 if (pvModel) { << 247 struct : public G4PseudoScene { << 248 void ProcessVolume(const G4VSolid&) {++f << 249 G4int fNTotalTouchables = 0; << 250 } counter; << 251 pvModel->DescribeYourselfTo(counter); // << 252 if (counter.fNTotalTouchables > fMaxNTouch << 253 std::ostringstream oss; << 254 oss << counter.fNTotalTouchables << " to << 255 furtherInfo = oss.str(); << 256 if (G4VisManager::GetInstance()->GetVerb << 257 G4ExceptionDescription ed; << 258 ed << pvModel->GetGlobalDescription() << 259 ":\n Too many touchables (" << counte << 260 << ") for scene tree. Scene tree for t << 261 G4Exception("G4VViewer::InsertModelInS << 262 } << 263 fCurtailDescent = true; // This is used << 264 } << 265 } << 266 << 267 // Find appropriate model << 268 auto& modelItems = fSceneTree.AccessChildren << 269 auto modelIter = modelItems.begin(); << 270 auto pvModelIter = modelItems.end(); << 271 for (; modelIter != modelItems.end(); ++mode << 272 if (modelIter->GetType() == G4SceneTreeIte << 273 pvModelIter = modelIter; // Last pre-ex << 274 } << 275 if (modelIter->GetModelDescription() == mo << 276 } << 277 << 278 if (modelIter == modelItems.end()) { // Mod << 279 G4SceneTreeItem modelItem(type); << 280 modelItem.SetDescription("model"); << 281 modelItem.SetModelType(modelType); << 282 modelItem.SetModelDescription(modelDescrip << 283 modelItem.SetFurtherInfo(furtherInfo); << 284 if (pvModelIter != modelItems.end() && // << 285 type == G4SceneTreeItem::pvmodel) { << 286 fSceneTree.InsertChild(++pvModelIter, mo << 287 } else { << 288 fSceneTree.InsertChild(modelIter, modelI << 289 } << 290 } else { // Existing model - mark visible = << 291 modelIter->AccessVisAttributes().SetVisibi << 292 } << 293 } << 294 << 295 G4VViewer::SceneTreeScene::SceneTreeScene(G4VV << 296 : fpViewer (pViewer) << 297 , fpPVModel(pPVModel) << 298 { << 299 if (fpPVModel == nullptr) { << 300 G4Exception("G4VViewer::SceneTreeScene::Sc << 301 "G4PhysicalVolumeModel pointer << 302 return; // To keep Coverity happy << 303 } << 304 << 305 // Describe the model to an empty scene simp << 306 struct : public G4PseudoScene { << 307 void ProcessVolume(const G4VSolid&) {} << 308 } counter; << 309 fpPVModel->DescribeYourselfTo(counter); // << 310 << 311 // Limit the expanded depth to limit the num << 312 G4int expanded = 0; << 313 for (const auto& dn : fpPVModel->GetNumberOf << 314 expanded += dn.second; << 315 if (fMaximumExpandedDepth < dn.first) fMax << 316 if (expanded > fMaximumExpanded) break; << 317 } << 318 << 319 // Find appropriate model and its iterator << 320 const auto& modelID = fpPVModel->GetGlobalDe << 321 auto& modelItems = fpViewer->fSceneTree.Acce << 322 fModelIter = modelItems.begin(); << 323 for (; fModelIter != modelItems.end(); ++fMo << 324 if (fModelIter->GetModelDescription() == m << 325 } << 326 if (fModelIter == modelItems.end()) { << 327 G4Exception("G4VViewer::SceneTreeScene::Sc << 328 "Model not found"); << 329 } << 330 } << 331 << 332 void G4VViewer::SceneTreeScene::ProcessVolume( << 333 { << 334 if (fpViewer->fCurtailDescent) { << 335 fpPVModel->CurtailDescent(); << 336 return; << 337 } << 338 << 339 const auto& modelID = fpPVModel->GetGlobalDe << 340 << 341 std::ostringstream oss; << 342 oss << fpPVModel->GetFullPVPath(); // of th << 343 G4String fullPathString(oss.str()); // Has << 344 << 345 // Navigate scene tree and find or insert to << 346 // Work down the path - "name id", then "nam << 347 const auto& nodeIDs = fpPVModel->GetFullPVPa << 348 G4String partialPathString; << 349 auto currentIter = fModelIter; << 350 G4int depth = 0; << 351 for (const auto& nodeID : nodeIDs) { << 352 std::ostringstream oss1; << 353 oss1 << nodeID; << 354 partialPathString += ' ' + oss1.str(); << 355 currentIter = << 356 FindOrInsertTouchable(modelID, *currentIte << 357 } << 358 } << 359 << 360 // clang-format off << 361 std::list<G4SceneTreeItem>::iterator G4VViewer << 362 (const G4String& modelID, G4SceneTreeItem& mo << 363 G4int depth, const G4String& partialPathStri << 364 { << 365 auto& children = mother.AccessChildren(); << 366 auto childIter = children.begin(); << 367 for (; childIter != children.end(); ++childI << 368 if (childIter->GetPVPath() == partialPathS << 369 } << 370 if (childIter != children.end()) { << 371 << 372 // Item already exists << 373 << 374 if (childIter->GetType() == G4SceneTreeIte << 375 << 376 // Previously it was a ghost - but maybe << 377 << 378 if (partialPathString == fullPathString) << 379 // Partial path string refers to the a << 380 childIter->SetType(G4SceneTreeItem::to << 381 // Populate with information << 382 childIter->SetDescription(fpPVModel->G << 383 childIter->SetModelType(fpPVModel->Get << 384 childIter->SetModelDescription(modelID << 385 childIter->SetPVPath(partialPathString << 386 if (fpVisAttributes) childIter->SetVis << 387 childIter->SetAttDefs(fpPVModel->GetAt << 388 childIter->SetAttValues(fpPVModel->Cre << 389 } // Partial path string refers to an a << 390 << 391 } else { << 392 << 393 // Already a pre-existing full touchable << 394 << 395 if (partialPathString == fullPathString) << 396 // Partial path string refers to the a << 397 // Replace vis attributes (if any) - t << 398 if (fpVisAttributes) childIter->SetVis << 399 } // Partial path string refers to an a << 400 << 401 } << 402 << 403 } else { << 404 << 405 // Item does not yet exist << 406 << 407 if (partialPathString == fullPathString) { << 408 << 409 // Partial path string refers to the act << 410 // Insert new touchable item << 411 G4SceneTreeItem touchable(G4SceneTreeIte << 412 touchable.SetExpanded(depth > fMaximumEx << 413 touchable.SetDescription(fpPVModel->GetC << 414 touchable.SetModelType(fpPVModel->GetTyp << 415 touchable.SetModelDescription(modelID); << 416 touchable.SetPVPath(partialPathString); << 417 if (fpVisAttributes) touchable.SetVisAtt << 418 touchable.SetAttDefs(fpPVModel->GetAttDe << 419 touchable.SetAttValues(fpPVModel->Create << 420 childIter = mother.InsertChild(childIter << 421 << 422 } else { << 423 << 424 // Partial path string refers to an ance << 425 G4SceneTreeItem ghost(G4SceneTreeItem::g << 426 ghost.SetExpanded(depth > fMaximumExpand << 427 // Create a tag from the partial path << 428 std::istringstream iss(partialPathString << 429 G4String name, copyNo; << 430 while (iss >> name >> copyNo); << 431 std::ostringstream oss; << 432 oss << name << ':' << copyNo; << 433 ghost.SetDescription(oss.str()); << 434 ghost.SetModelType(fpPVModel->GetType()) << 435 ghost.SetModelDescription(modelID); << 436 ghost.SetPVPath(partialPathString); << 437 ghost.AccessVisAttributes().SetVisibilit << 438 childIter = mother.InsertChild(childIter << 439 } << 440 } << 441 << 442 return childIter; << 443 } << 444 // clang-format on << 445 << 446 std::ostream& operator<<(std::ostream& os, con << 447 { << 448 os << "View " << v.fName << ":\n"; 140 os << "View " << v.fName << ":\n"; 449 os << v.fVP; 141 os << v.fVP; 450 return os; 142 return os; 451 } 143 } 452 144