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