Geant4 Cross Reference |
>> 1 // This code implementation is the intellectual property of >> 2 // the GEANT4 collaboration. 1 // 3 // 2 // ******************************************* << 4 // By copying, distributing or modifying the Program (or any work 3 // * License and Disclaimer << 5 // based on the Program) you indicate your acceptance of this statement, 4 // * << 6 // and all its terms. 5 // * The Geant4 software is copyright of th << 6 // * the Geant4 Collaboration. It is provided << 7 // * conditions of the Geant4 Software License << 8 // * LICENSE and available at http://cern.ch/ << 9 // * include a list of copyright holders. << 10 // * << 11 // * Neither the authors of this software syst << 12 // * institutes,nor the agencies providing fin << 13 // * work make any representation or warran << 14 // * regarding this software system or assum << 15 // * use. Please see the license in the file << 16 // * for the full disclaimer and the limitatio << 17 // * << 18 // * This code implementation is the result << 19 // * technical work of the GEANT4 collaboratio << 20 // * By using, copying, modifying or distri << 21 // * any work based on the software) you ag << 22 // * use in resulting scientific publicati << 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* << 25 // << 26 // << 27 // 7 // >> 8 // $Id: G4VViewer.cc,v 1.4.4.1 1999/12/07 20:53:59 gunter Exp $ >> 9 // GEANT4 tag $Name: geant4-01-00 $ 28 // 10 // >> 11 // 29 // John Allison 27th March 1996 12 // John Allison 27th March 1996 30 // Abstract interface class for graphics views 13 // Abstract interface class for graphics views. 31 14 32 #include "G4VViewer.hh" 15 #include "G4VViewer.hh" 33 16 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" 17 #include "G4ios.hh" >> 18 #ifdef WIN32 >> 19 #include <strstrea.h> >> 20 #else >> 21 #include <strstream.h> >> 22 #endif 46 23 47 #include <sstream> << 24 #include "G4VisManager.hh" >> 25 #include "G4VGraphicsSystem.hh" >> 26 #include "G4VSceneHandler.hh" >> 27 #include "G4VPhysicalVolume.hh" >> 28 #include "G4Transform3D.hh" >> 29 #include "G4Event.hh" 48 30 49 G4VViewer::G4VViewer(G4VSceneHandler& sceneHan << 31 G4VViewer::G4VViewer (G4VSceneHandler& scene, G4int id, const G4String& name): 50 : fSceneHandler(sceneHandler), fViewId(id), << 32 fSceneHandler (scene), >> 33 fViewId (id), >> 34 fModified (true), >> 35 fNeedKernelVisit (true) 51 { 36 { >> 37 G4VisManager* pVMan = G4VisManager::GetInstance (); >> 38 fVP = pVMan -> GetCurrentViewParameters (); 52 if (name == "") { 39 if (name == "") { 53 std::ostringstream ost; << 40 char charname [50]; 54 ost << fSceneHandler.GetName() << '-' << f << 41 ostrstream ost (charname, 50); 55 fName = ost.str(); << 42 ost << fSceneHandler.GetName () << '-' << fViewId << ends; >> 43 fName = charname; 56 } 44 } 57 else { 45 else { 58 fName = name; 46 fName = name; 59 } 47 } 60 fShortName = fName.substr(0, fName.find(' ') << 61 G4StrUtil::strip(fShortName); << 62 << 63 fVP = G4VisManager::GetInstance()->GetDefaul << 64 fDefaultVP = fVP; << 65 << 66 fSceneTree.SetType(G4SceneTreeItem::root); << 67 fSceneTree.SetDescription(fName); << 68 } << 69 << 70 G4VViewer::~G4VViewer() << 71 { << 72 fSceneHandler.RemoveViewerFromList(this); << 73 } << 74 << 75 void G4VViewer::SetName(const G4String& name) << 76 { << 77 fName = name; << 78 fShortName = fName.substr(0, fName.find(' ') << 79 G4StrUtil::strip(fShortName); << 80 } << 81 << 82 void G4VViewer::NeedKernelVisit() << 83 { << 84 fNeedKernelVisit = true; << 85 << 86 // At one time I thought we'd better notify << 87 // each viewer can take care of itself, so t << 88 // redundant (but keep it commented out for << 89 // Notify all viewers that a kernel visit is << 90 // const G4ViewerList& viewerList = fSceneHa << 91 // G4ViewerListConstIterator i; << 92 // for (i = viewerList.begin(); i != viewerL << 93 // (*i) -> SetNeedKernelVisit (); << 94 // } << 95 // ??...but, there's a problem in OpenGL Sto << 96 // require *all* viewers to revisit the kern << 97 // const G4ViewerList& viewerList = fSceneH << 98 // G4ViewerListConstIterator i; << 99 // for (i = viewerList.begin(); i != viewer << 100 // (*i) -> SetNeedKernelVisit (true); << 101 // } << 102 // Feb 2005 - commented out. Let's fix Open << 103 } << 104 << 105 void G4VViewer::FinishView() {} << 106 << 107 void G4VViewer::ShowView() {} << 108 << 109 void G4VViewer::ProcessView() << 110 { << 111 // If the scene has changed, or if the concr << 112 // that it necessary to visit the kernel, pe << 113 // parameters have changed significantly (th << 114 // concrete viewer's DrawView)... << 115 if (fNeedKernelVisit) { << 116 // Reset flag. This must be done before P << 117 // recursive calls when recomputing transi << 118 G4Timer timer; << 119 timer.Start(); << 120 fNeedKernelVisit = false; << 121 fSceneHandler.ClearStore(); << 122 fSceneHandler.ProcessScene(); << 123 UpdateGUISceneTree(); << 124 timer.Stop(); << 125 fKernelVisitElapsedTimeSeconds = timer.Get << 126 } << 127 } << 128 << 129 void G4VViewer::SetViewParameters(const G4View << 130 { << 131 fVP = vp; << 132 } << 133 << 134 void G4VViewer::SetTouchable( << 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 } 48 } 154 49 155 void G4VViewer::TouchableSetVisibility( << 50 G4VViewer::~G4VViewer () {} 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 51 228 void G4VViewer::UpdateGUISceneTree() << 52 const G4VisAttributes* G4VViewer::GetApplicableVisAttributes 229 { << 53 (const G4VisAttributes* pVisAttribs) const { 230 G4UImanager* UI = G4UImanager::GetUIpointer( << 54 // If the pointer is null, pick up the default vis attributes from 231 auto uiWindow = dynamic_cast<G4VInteractiveS << 55 // the view parameters. 232 if (uiWindow) uiWindow->UpdateSceneTree(fSce << 56 if (!pVisAttribs) >> 57 pVisAttribs = GetViewParameters ().GetDefaultVisAttributes (); >> 58 return pVisAttribs; 233 } 59 } 234 60 235 void G4VViewer::InsertModelInSceneTree(G4VMode << 61 void G4VViewer::NeedKernelVisit () { 236 { << 62 // Notify all views that a kernel visit is required. 237 const auto& modelType = model->GetType(); << 63 const G4ViewerList& viewList = fSceneHandler.GetViewerList (); 238 const auto& modelDescription = model->GetGlo << 64 for (int i = 0; i < viewList.entries (); i++) { 239 << 65 viewList [i] -> SetNeedKernelVisit (); 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 } 66 } 293 } 67 } 294 68 295 G4VViewer::SceneTreeScene::SceneTreeScene(G4VV << 69 void G4VViewer::ShowView () {} 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 70 319 // Find appropriate model and its iterator << 71 void G4VViewer::ProcessView () { 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 72 332 void G4VViewer::SceneTreeScene::ProcessVolume( << 73 // If view parameters have been modified, SetView () works out consequences. 333 { << 74 if (fModified) { 334 if (fpViewer->fCurtailDescent) { << 75 fModified = false; 335 fpPVModel->CurtailDescent(); << 76 SetView (); 336 return; << 337 } 77 } 338 78 339 const auto& modelID = fpPVModel->GetGlobalDe << 79 // If the scene data has changed (fNeedVisit is set to true in 340 << 80 // G4VSceneHandler::SetSceneData), or if the concrete view has decided that it 341 std::ostringstream oss; << 81 // necessary to visit the kernel (this should be Done in the concrete 342 oss << fpPVModel->GetFullPVPath(); // of th << 82 // object's DrawView ())... 343 G4String fullPathString(oss.str()); // Has << 83 if (fNeedKernelVisit) { 344 << 84 fSceneHandler.ProcessScene (*this); 345 // Navigate scene tree and find or insert to << 85 fNeedKernelVisit = false; 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 } 86 } 358 } 87 } 359 88 360 // clang-format off << 89 void G4VViewer::SetViewParameters (const G4ViewParameters& vp) { 361 std::list<G4SceneTreeItem>::iterator G4VViewer << 90 fVP = vp; 362 (const G4String& modelID, G4SceneTreeItem& mo << 91 fModified = true; 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 } 92 } 444 // clang-format on << 445 93 446 std::ostream& operator<<(std::ostream& os, con << 94 ostream& operator << (ostream& os, const G4VViewer& v) { 447 { << 448 os << "View " << v.fName << ":\n"; 95 os << "View " << v.fName << ":\n"; 449 os << v.fVP; 96 os << v.fVP; 450 return os; 97 return os; 451 } 98 } 452 99