Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveManager.cxx
Go to the documentation of this file.
1 // @(#)root/eve:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TEveManager.h"
13 
14 #include "TEveSelection.h"
15 #include "TEveViewer.h"
16 #include "TEveScene.h"
17 #include "TEveEventManager.h"
18 #include "TEveWindowManager.h"
19 
20 #include "TEveBrowser.h"
21 #include "TEveGedEditor.h"
22 
23 #include "TGStatusBar.h"
24 
25 #include "TGLSAViewer.h"
26 
27 #include "TGeoManager.h"
28 #include "TGeoMatrix.h"
29 #include "TObjString.h"
30 #include "TROOT.h"
31 #include "TFile.h"
32 #include "TMap.h"
33 #include "TExMap.h"
34 #include "TMacro.h"
35 #include "TFolder.h"
36 #include "TBrowser.h"
37 #include "TCanvas.h"
38 #include "TSystem.h"
39 #include "TRint.h"
40 #include "TVirtualX.h"
41 #include "TEnv.h"
42 #include "TColor.h"
43 #include "TVirtualGL.h"
44 #include "TPluginManager.h"
45 #include "TPRegexp.h"
46 #include "TClass.h"
47 
48 #include "Riostream.h"
49 
50 TEveManager* gEve = 0;
51 
52 /** \class TEveManager
53 \ingroup TEve
54 Central application manager for Eve.
55 Manages elements, GUI, GL scenes and GL viewers.
56 */
57 
58 ClassImp(TEveManager);
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 
62 TEveManager::TEveManager(UInt_t w, UInt_t h, Bool_t map_window, Option_t* opt) :
63  fExcHandler (0),
64  fVizDB (0), fVizDBReplace(kTRUE), fVizDBUpdate(kTRUE),
65  fGeometries (0),
66  fGeometryAliases (0),
67  fBrowser (0),
68 
69  fMacroFolder (0),
70 
71  fWindowManager (0),
72  fViewers (0),
73  fScenes (0),
74  fGlobalScene (0),
75  fEventScene (0),
76  fCurrentEvent (0),
77 
78  fRedrawDisabled (0),
79  fResetCameras (kFALSE),
80  fDropLogicals (kFALSE),
81  fKeepEmptyCont (kFALSE),
82  fTimerActive (kFALSE),
83  fRedrawTimer (),
84 
85  fStampedElements(0),
86  fSelection (0),
87  fHighlight (0),
88 
89  fOrphanage (0),
90  fUseOrphanage (kFALSE)
91 {
92  // Constructor.
93  // If map_window is true, the TEveBrowser window is mapped.
94  //
95  // Option string is first parsed for the following characters:
96  // V - spawn a default GL viewer.
97  //
98  // The consumed characters are removed from the options and they
99  // are passed to TEveBrowser for creation of additional plugins.
100  //
101  // Default options: "FIV" - file-browser, command-line, GL-viewer.
102 
103 
104  static const TEveException eh("TEveManager::TEveManager ");
105 
106  if (gEve != 0)
107  throw(eh + "There can be only one!");
108 
109  gEve = this;
110 
111  fExcHandler = new TExceptionHandler;
112 
113  fGeometries = new TMap; fGeometries->SetOwnerKeyValue();
114  fGeometryAliases = new TMap; fGeometryAliases->SetOwnerKeyValue();
115  fVizDB = new TMap; fVizDB->SetOwnerKeyValue();
116 
117  fStampedElements = new TExMap;
118 
119  fSelection = new TEveSelection("Global Selection");
120  fSelection->IncDenyDestroy();
121  fHighlight = new TEveSelection("Global Highlight");
122  fHighlight->SetHighlightMode();
123  fHighlight->IncDenyDestroy();
124 
125  fOrphanage = new TEveElementList("Global Orphanage");
126  fOrphanage->IncDenyDestroy();
127 
128  fRedrawTimer.Connect("Timeout()", "TEveManager", this, "DoRedraw3D()");
129  fMacroFolder = new TFolder("EVE", "Visualization macros");
130  gROOT->GetListOfBrowsables()->Add(fMacroFolder);
131 
132 
133  fWindowManager = new TEveWindowManager("WindowManager", "Manager of EVE windows");
134 
135  // Build GUI
136  fBrowser = new TEveBrowser(w, h);
137 
138  // ListTreeEditor
139  fBrowser->StartEmbedding(0);
140  fLTEFrame = new TEveGListTreeEditorFrame;
141  fBrowser->StopEmbedding("Eve");
142  fLTEFrame->ConnectSignals();
143 
144  // See how many GL viewers are requested, remove from options.
145  TString str_opt(opt);
146  TPMERegexp viewer_re("V", "g");
147  Int_t viewer_count = viewer_re.Substitute(str_opt, "", kFALSE);
148 
149  // Create the main window / browse.
150  fBrowser->InitPlugins(str_opt);
151  if (map_window)
152  fBrowser->MapWindow();
153 
154  // --------------------------------
155 
156  fWindowManager->IncDenyDestroy();
157  AddToListTree(fWindowManager, kFALSE);
158 
159  fViewers = new TEveViewerList("Viewers");
160  fViewers->IncDenyDestroy();
161  AddToListTree(fViewers, kFALSE);
162 
163  fScenes = new TEveSceneList ("Scenes");
164  fScenes->IncDenyDestroy();
165  AddToListTree(fScenes, kFALSE);
166 
167  fGlobalScene = new TEveScene("Geometry scene");
168  fGlobalScene->IncDenyDestroy();
169  fScenes->AddElement(fGlobalScene);
170 
171  fEventScene = new TEveScene("Event scene");
172  fEventScene->IncDenyDestroy();
173  fScenes->AddElement(fEventScene);
174 
175  for (Int_t vc = 0; vc < viewer_count; ++vc)
176  {
177  TEveViewer* v = SpawnNewViewer(Form("Viewer %d", vc+1));
178  v->AddScene(fGlobalScene);
179  v->AddScene(fEventScene);
180  }
181 
182  if (GetDefaultViewer())
183  {
184  EditElement(GetDefaultViewer());
185  }
186 
187  gSystem->ProcessEvents();
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// Destructor.
192 
193 TEveManager::~TEveManager()
194 {
195  // Stop timer and deny further redraw requests.
196  fRedrawTimer.Stop();
197  fTimerActive = kTRUE;
198 
199  delete fCurrentEvent;
200  fCurrentEvent = 0;
201 
202  fGlobalScene->DecDenyDestroy();
203  fEventScene->DecDenyDestroy();
204  fScenes->DestroyScenes();
205  fScenes->DecDenyDestroy();
206  fScenes->Destroy();
207  fScenes = 0;
208 
209  fViewers->DestroyElements();
210  fViewers->DecDenyDestroy();
211  fViewers->Destroy();
212  fViewers = 0;
213 
214  fWindowManager->DestroyWindows();
215  fWindowManager->DecDenyDestroy();
216  fWindowManager->Destroy();
217  fWindowManager = 0;
218 
219  fOrphanage->DecDenyDestroy();
220  fHighlight->DecDenyDestroy();
221  fSelection->DecDenyDestroy();
222 
223  gROOT->GetListOfBrowsables()->Remove(fMacroFolder);
224  delete fMacroFolder;
225 
226  delete fGeometryAliases;
227  delete fGeometries;
228  delete fVizDB;
229  delete fExcHandler;
230  delete fStampedElements;
231 
232  fLTEFrame->DeleteWindow();
233 
234  fBrowser->DontCallClose();
235  fBrowser->TRootBrowser::CloseWindow();
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Clear the orphanage.
240 
241 void TEveManager::ClearOrphanage()
242 {
243  Bool_t old_state = fUseOrphanage;
244  fUseOrphanage = kFALSE;
245  fOrphanage->DestroyElements();
246  fUseOrphanage = old_state;
247 }
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// Get the main window, i.e. EVE-browser.
251 
252 TGWindow* TEveManager::GetMainWindow() const
253 {
254  return fBrowser;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Returns the default viewer - the first one in the fViewers list.
259 
260 TEveViewer* TEveManager::GetDefaultViewer() const
261 {
262  return dynamic_cast<TEveViewer*>(fViewers->FirstChild());
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Get TGLViewer of the default TEveViewer.
267 
268 TGLViewer* TEveManager::GetDefaultGLViewer() const
269 {
270  TEveViewer *ev = GetDefaultViewer();
271  return ev ? ev->GetGLViewer() : 0;
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Returns main object editor.
276 
277 TEveGedEditor* TEveManager::GetEditor() const
278 {
279  return fLTEFrame->GetEditor();
280 }
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 /// Returns main window status bar.
284 
285 TGStatusBar* TEveManager::GetStatusBar() const
286 {
287  return fBrowser->GetStatusBar();
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Add a new canvas tab.
292 
293 TCanvas* TEveManager::AddCanvasTab(const char* name)
294 {
295  fBrowser->StartEmbedding(1, -1);
296  TCanvas* c = new TCanvas;
297  fBrowser->StopEmbedding(name);
298 
299  return c;
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Create a new GL viewer.
304 
305 TEveViewer* TEveManager::SpawnNewViewer(const char* name, const char* title,
306  Bool_t embed)
307 {
308  TEveWindowSlot* slot = 0;
309  if (embed)
310  {
311  slot = fWindowManager->GetCurrentWindowAsSlot();
312  if (slot == 0)
313  {
314  // In principle should have some default/current container
315  // in TEveWindowManager.
316  // Also to store closed windows.
317  slot = TEveWindow::CreateWindowInTab(fBrowser->GetTabRight());
318  fBrowser->SanitizeTabCounts();
319  }
320  }
321  else
322  {
323  slot = TEveWindow::CreateWindowMainFrame();
324  }
325 
326  TEveViewer* v = new TEveViewer(name, title);
327  v->SpawnGLViewer(embed ? GetEditor() : 0);
328 
329  slot->ReplaceWindow(v);
330 
331  fViewers->AddElement(v);
332 
333  return v;
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Create a new scene.
338 
339 TEveScene* TEveManager::SpawnNewScene(const char* name, const char* title)
340 {
341  TEveScene* s = new TEveScene(name, title);
342  AddElement(s, fScenes);
343  return s;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Find macro in fMacroFolder by name.
348 
349 TMacro* TEveManager::GetMacro(const char* name) const
350 {
351  return dynamic_cast<TMacro*>(fMacroFolder->FindObject(name));
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Show element in default editor.
356 
357 void TEveManager::EditElement(TEveElement* element)
358 {
359  static const TEveException eh("TEveManager::EditElement ");
360 
361  GetEditor()->DisplayElement(element);
362 }
363 
364 ////////////////////////////////////////////////////////////////////////////////
365 /// Register a request for 3D redraw.
366 
367 void TEveManager::RegisterRedraw3D()
368 {
369  fRedrawTimer.Start(0, kTRUE);
370  fTimerActive = kTRUE;
371 }
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 /// Perform 3D redraw of scenes and viewers whose contents has
375 /// changed.
376 
377 void TEveManager::DoRedraw3D()
378 {
379  static const TEveException eh("TEveManager::DoRedraw3D ");
380 
381  // printf("TEveManager::DoRedraw3D redraw triggered\n");
382 
383  // Process element visibility changes, mark relevant scenes as changed.
384  {
385  TEveElement::List_t scenes;
386  Long64_t key, value;
387  TExMapIter stamped_elements(fStampedElements);
388  while (stamped_elements.Next(key, value))
389  {
390  TEveElement *el = reinterpret_cast<TEveElement*>(key);
391  if (el->GetChangeBits() & TEveElement::kCBVisibility)
392  {
393  el->CollectSceneParents(scenes);
394  }
395  }
396  ScenesChanged(scenes);
397  }
398 
399  // Process changes in scenes.
400  fScenes ->ProcessSceneChanges(fDropLogicals, fStampedElements);
401  fViewers->RepaintChangedViewers(fResetCameras, fDropLogicals);
402 
403  // Process changed elements again, update GUI (just editor so far,
404  // but more can come).
405  {
406  Long64_t key, value;
407  TExMapIter stamped_elements(fStampedElements);
408  while (stamped_elements.Next(key, value))
409  {
410  TEveElement *el = reinterpret_cast<TEveElement*>(key);
411  if (GetEditor()->GetModel() == el->GetEditorObject(eh))
412  EditElement(el);
413  TEveGedEditor::ElementChanged(el);
414 
415  el->ClearStamps();
416  }
417  }
418  fStampedElements->Delete();
419  GetListTree()->ClearViewPort(); // Fix this when several list-trees can be added.
420 
421  fResetCameras = kFALSE;
422  fDropLogicals = kFALSE;
423 
424  fTimerActive = kFALSE;
425 }
426 
427 ////////////////////////////////////////////////////////////////////////////////
428 /// Perform 3D redraw of all scenes and viewers.
429 
430 void TEveManager::FullRedraw3D(Bool_t resetCameras, Bool_t dropLogicals)
431 {
432  fScenes ->RepaintAllScenes (dropLogicals);
433  fViewers->RepaintAllViewers(resetCameras, dropLogicals);
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Element was changed, perform framework side action.
438 /// Called from TEveElement::ElementChanged().
439 
440 void TEveManager::ElementChanged(TEveElement* element, Bool_t update_scenes, Bool_t redraw)
441 {
442  static const TEveException eh("TEveElement::ElementChanged ");
443 
444  if (GetEditor()->GetModel() == element->GetEditorObject(eh))
445  EditElement(element);
446  TEveGedEditor::ElementChanged(element);
447 
448  if (update_scenes) {
449  TEveElement::List_t scenes;
450  element->CollectSceneParents(scenes);
451  ScenesChanged(scenes);
452  }
453 
454  if (redraw)
455  Redraw3D();
456 }
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 /// Mark all scenes from the given list as changed.
460 
461 void TEveManager::ScenesChanged(TEveElement::List_t& scenes)
462 {
463  for (TEveElement::List_i s=scenes.begin(); s!=scenes.end(); ++s)
464  ((TEveScene*)*s)->Changed();
465 }
466 
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Mark element as changed -- it will be processed on next redraw.
469 
470 void TEveManager::ElementStamped(TEveElement* element)
471 {
472  UInt_t slot;
473  if (fStampedElements->GetValue((ULong64_t) element, (Long64_t) element, slot) == 0)
474  {
475  fStampedElements->AddAt(slot, (ULong64_t) element, (Long64_t) element, 1);
476  }
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Get default list-tree widget.
481 
482 TGListTree* TEveManager::GetListTree() const
483 {
484  return fLTEFrame->fListTree;
485 }
486 
487 TGListTreeItem*
488 TEveManager::AddToListTree(TEveElement* re, Bool_t open, TGListTree* lt)
489 {
490  // Add element as a top-level to a list-tree.
491  // Only add a single copy of a render-element as a top level.
492 
493  if (lt == 0) lt = GetListTree();
494  TGListTreeItem* lti = re->AddIntoListTree(lt, (TGListTreeItem*)0);
495  if (open) lt->OpenItem(lti);
496  return lti;
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// Remove top-level element from list-tree with specified tree-item.
501 
502 void TEveManager::RemoveFromListTree(TEveElement* element,
503  TGListTree* lt, TGListTreeItem* lti)
504 {
505  static const TEveException eh("TEveManager::RemoveFromListTree ");
506 
507  if (lti->GetParent())
508  throw(eh + "not a top-level item.");
509 
510  element->RemoveFromListTree(lt, 0);
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Add a new event and make it the current event.
515 /// It is added into the event-scene and as a top-level list-tree
516 /// item.
517 
518 TGListTreeItem* TEveManager::AddEvent(TEveEventManager* event)
519 {
520  fCurrentEvent = event;
521  fCurrentEvent->IncDenyDestroy();
522  AddElement(fCurrentEvent, fEventScene);
523  return AddToListTree(event, kTRUE);
524 }
525 
526 ////////////////////////////////////////////////////////////////////////////////
527 /// Add an element. If parent is not specified it is added into
528 /// current event (which is created if does not exist).
529 
530 void TEveManager::AddElement(TEveElement* element, TEveElement* parent)
531 {
532  if (parent == 0) {
533  if (fCurrentEvent == 0)
534  AddEvent(new TEveEventManager("Event", "Auto-created event directory"));
535  parent = fCurrentEvent;
536  }
537 
538  parent->AddElement(element);
539 }
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Add a global element, i.e. one that does not change on each
543 /// event, like geometry or projection manager.
544 /// If parent is not specified it is added to a global scene.
545 
546 void TEveManager::AddGlobalElement(TEveElement* element, TEveElement* parent)
547 {
548  if (parent == 0)
549  parent = fGlobalScene;
550 
551  parent->AddElement(element);
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Remove element from parent.
556 
557 void TEveManager::RemoveElement(TEveElement* element,
558  TEveElement* parent)
559 {
560  parent->RemoveElement(element);
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// Called from TEveElement prior to its destruction so the
565 /// framework components (like object editor) can unreference it.
566 
567 void TEveManager::PreDeleteElement(TEveElement* element)
568 {
569  if (GetEditor()->GetEveElement() == element)
570  EditElement(0);
571  TEveGedEditor::ElementDeleted(element);
572 
573  if (fScenes)
574  fScenes->DestroyElementRenderers(element);
575 
576  if (fStampedElements->GetValue((ULong64_t) element, (Long64_t) element) != 0)
577  fStampedElements->Remove((ULong64_t) element, (Long64_t) element);
578 
579  if (element->fImpliedSelected > 0)
580  fSelection->RemoveImpliedSelected(element);
581  if (element->fImpliedHighlighted > 0)
582  fHighlight->RemoveImpliedSelected(element);
583 }
584 
585 ////////////////////////////////////////////////////////////////////////////////
586 /// Select an element.
587 /// Now it only calls EditElement() - should also update selection state.
588 
589 void TEveManager::ElementSelect(TEveElement* element)
590 {
591  if (element != 0)
592  EditElement(element);
593 }
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 /// Paste has been called.
597 
598 Bool_t TEveManager::ElementPaste(TEveElement* element)
599 {
600  // The object to paste is taken from the editor (this is not
601  // exactly right) and handed to 'element' for pasting.
602 
603  TEveElement* src = GetEditor()->GetEveElement();
604  if (src)
605  return element->HandleElementPaste(src);
606  return kFALSE;
607 }
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 /// Insert a new visualization-parameter database entry. Returns
611 /// true if the element is inserted successfully.
612 /// If entry with the same key already exists the behaviour depends on the
613 /// 'replace' flag:
614 /// - true - The old model is deleted and new one is inserted (default).
615 /// Clients of the old model are transferred to the new one and
616 /// if 'update' flag is true (default), the new model's parameters
617 /// are assigned to all clients.
618 /// - false - The old model is kept, false is returned.
619 ///
620 /// If insert is successful, the ownership of the model-element is
621 /// transferred to the manager.
622 
623 Bool_t TEveManager::InsertVizDBEntry(const TString& tag, TEveElement* model,
624  Bool_t replace, Bool_t update)
625 {
626  TPair* pair = (TPair*) fVizDB->FindObject(tag);
627  if (pair)
628  {
629  if (replace)
630  {
631  model->IncDenyDestroy();
632  model->SetRnrChildren(kFALSE);
633 
634  TEveElement* old_model = dynamic_cast<TEveElement*>(pair->Value());
635  if (old_model)
636  {
637  while (old_model->HasChildren())
638  {
639  TEveElement *el = old_model->FirstChild();
640  el->SetVizModel(model);
641  if (update)
642  {
643  el->CopyVizParams(model);
644  el->PropagateVizParamsToProjecteds();
645  }
646  }
647  old_model->DecDenyDestroy();
648  }
649  pair->SetValue(dynamic_cast<TObject*>(model));
650  return kTRUE;
651  }
652  else
653  {
654  return kFALSE;
655  }
656  }
657  else
658  {
659  model->IncDenyDestroy();
660  model->SetRnrChildren(kFALSE);
661  fVizDB->Add(new TObjString(tag), dynamic_cast<TObject*>(model));
662  return kTRUE;
663  }
664 }
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Insert a new visualization-parameter database entry with the default
668 /// parameters for replace and update, as specified by members
669 /// fVizDBReplace(default=kTRUE) and fVizDBUpdate(default=kTRUE).
670 /// See docs of the above function.
671 
672 Bool_t TEveManager::InsertVizDBEntry(const TString& tag, TEveElement* model)
673 {
674  return InsertVizDBEntry(tag, model, fVizDBReplace, fVizDBUpdate);
675 }
676 
677 ////////////////////////////////////////////////////////////////////////////////
678 /// Find a visualization-parameter database entry corresponding to tag.
679 /// If the entry is not found 0 is returned.
680 
681 TEveElement* TEveManager::FindVizDBEntry(const TString& tag)
682 {
683  return dynamic_cast<TEveElement*>(fVizDB->GetValue(tag));
684 }
685 
686 ////////////////////////////////////////////////////////////////////////////////
687 /// Load visualization-parameter database from file filename. The
688 /// replace, update arguments replace the values of fVizDBReplace
689 /// and fVizDBUpdate members for the duration of the macro
690 /// execution.
691 
692 void TEveManager::LoadVizDB(const TString& filename, Bool_t replace, Bool_t update)
693 {
694  Bool_t ex_replace = fVizDBReplace;
695  Bool_t ex_update = fVizDBUpdate;
696  fVizDBReplace = replace;
697  fVizDBUpdate = update;
698 
699  LoadVizDB(filename);
700 
701  fVizDBReplace = ex_replace;
702  fVizDBUpdate = ex_update;
703 }
704 
705 ////////////////////////////////////////////////////////////////////////////////
706 /// Load visualization-parameter database from file filename.
707 /// State of data-members fVizDBReplace and fVizDBUpdate determine
708 /// how the registered entries are handled.
709 
710 void TEveManager::LoadVizDB(const TString& filename)
711 {
712  TEveUtil::Macro(filename);
713  Redraw3D();
714 }
715 
716 ////////////////////////////////////////////////////////////////////////////////
717 /// Save visualization-parameter database to file filename.
718 
719 void TEveManager::SaveVizDB(const TString& filename)
720 {
721  TPMERegexp re("(.+)\\.\\w+");
722  if (re.Match(filename) != 2) {
723  Error("SaveVizDB", "filename does not match required format '(.+)\\.\\w+'.");
724  return;
725  }
726 
727  TString exp_filename(filename);
728  gSystem->ExpandPathName(exp_filename);
729 
730  std::ofstream out(exp_filename, std::ios::out | std::ios::trunc);
731  out << "void " << re[1] << "()\n";
732  out << "{\n";
733  out << " TEveManager::Create();\n";
734 
735  ClearROOTClassSaved();
736 
737  Int_t var_id = 0;
738  TString var_name;
739  TIter next(fVizDB);
740  TObjString *key;
741  while ((key = (TObjString*)next()))
742  {
743  TEveElement* mdl = dynamic_cast<TEveElement*>(fVizDB->GetValue(key));
744  if (mdl)
745  {
746  var_name.Form("x%03d", var_id++);
747  mdl->SaveVizParams(out, key->String(), var_name);
748  }
749  else
750  {
751  Warning("SaveVizDB", "Saving failed for key '%s'.", key->String().Data());
752  }
753  }
754 
755  out << "}\n";
756  out.close();
757 }
758 
759 ////////////////////////////////////////////////////////////////////////////////
760 /// Get geometry with given filename.
761 /// This is cached internally so the second time this function is
762 /// called with the same argument the same geo-manager is returned.
763 /// gGeoManager is set to the return value.
764 
765 TGeoManager* TEveManager::GetGeometry(const TString& filename)
766 {
767  static const TEveException eh("TEveManager::GetGeometry ");
768 
769  TString exp_filename = filename;
770  gSystem->ExpandPathName(exp_filename);
771  printf("%s loading: '%s' -> '%s'.\n", eh.Data(),
772  filename.Data(), exp_filename.Data());
773 
774  gGeoManager = (TGeoManager*) fGeometries->GetValue(filename);
775  if (gGeoManager)
776  {
777  gGeoIdentity = (TGeoIdentity*) gGeoManager->GetListOfMatrices()->At(0);
778  }
779  else
780  {
781  Bool_t locked = TGeoManager::IsLocked();
782  if (locked) {
783  Warning(eh, "TGeoManager is locked ... unlocking it.");
784  TGeoManager::UnlockGeometry();
785  }
786  if (TGeoManager::Import(filename) == 0) {
787  throw(eh + "TGeoManager::Import() failed for '" + exp_filename + "'.");
788  }
789  if (locked) {
790  TGeoManager::LockGeometry();
791  }
792 
793  gGeoManager->GetTopVolume()->VisibleDaughters(1);
794 
795  // Import colors exported by Gled, if they exist.
796  {
797  TFile f(exp_filename, "READ");
798  TObjArray* collist = (TObjArray*) f.Get("ColorList");
799  f.Close();
800  if (collist != 0) {
801  TIter next(gGeoManager->GetListOfVolumes());
802  TGeoVolume* vol;
803  while ((vol = (TGeoVolume*) next()) != 0)
804  {
805  Int_t oldID = vol->GetLineColor();
806  TColor* col = (TColor*)collist->At(oldID);
807  Float_t r, g, b;
808  col->GetRGB(r, g, b);
809  Int_t newID = TColor::GetColor(r,g,b);
810  vol->SetLineColor(newID);
811  }
812  }
813  }
814 
815  fGeometries->Add(new TObjString(filename), gGeoManager);
816  }
817  return gGeoManager;
818 }
819 
820 ////////////////////////////////////////////////////////////////////////////////
821 /// Get geometry with given alias.
822 /// The alias must be registered via RegisterGeometryAlias().
823 
824 TGeoManager* TEveManager::GetGeometryByAlias(const TString& alias)
825 {
826  static const TEveException eh("TEveManager::GetGeometry ");
827 
828  TObjString* full_name = (TObjString*) fGeometryAliases->GetValue(alias);
829  if (!full_name)
830  throw(eh + "geometry alias '" + alias + "' not registered.");
831  return GetGeometry(full_name->String());
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 /// Get the default geometry.
836 /// It should be registered via RegisterGeometryName("Default", <URL>).
837 
838 TGeoManager* TEveManager::GetDefaultGeometry()
839 {
840  return GetGeometryByAlias("Default");
841 }
842 
843 ////////////////////////////////////////////////////////////////////////////////
844 /// Register 'name' as an alias for geometry file 'filename'.
845 /// The old aliases are silently overwritten.
846 /// After that the geometry can be retrieved also by calling:
847 /// gEve->GetGeometryByName(name);
848 
849 void TEveManager::RegisterGeometryAlias(const TString& alias, const TString& filename)
850 {
851  fGeometryAliases->Add(new TObjString(alias), new TObjString(filename));
852 }
853 
854 ////////////////////////////////////////////////////////////////////////////////
855 /// Set the text in the right side of browser's status bar.
856 
857 void TEveManager::SetStatusLine(const char* text)
858 {
859  fBrowser->SetStatusText(text, 1);
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// Work-around uber ugly hack used in SavePrimitive and co.
864 
865 void TEveManager::ClearROOTClassSaved()
866 {
867  TIter nextcl(gROOT->GetListOfClasses());
868  TClass *cls;
869  while((cls = (TClass *)nextcl()))
870  {
871  cls->ResetBit(TClass::kClassSaved);
872  }
873 }
874 
875 ////////////////////////////////////////////////////////////////////////////////
876 /// Close button has been clicked on EVE main window (browser).
877 /// Cleanup and terminate application.
878 
879 void TEveManager::CloseEveWindow()
880 {
881  TGMainFrame *mf = (TGMainFrame*) gTQSender;
882  TEveBrowser *eb = dynamic_cast<TEveBrowser*>(mf);
883  if (eb == fBrowser)
884  {
885  mf->DontCallClose();
886  Terminate();
887  gApplication->Terminate();
888  }
889 }
890 
891 ////////////////////////////////////////////////////////////////////////////////
892 /// If global TEveManager* gEve is not set initialize it.
893 /// Returns gEve.
894 
895 TEveManager* TEveManager::Create(Bool_t map_window, Option_t* opt)
896 {
897  static const TEveException eh("TEveManager::Create ");
898 
899  if (gEve == 0)
900  {
901  // Make sure that the GUI system is initialized.
902  if (gROOT->IsBatch())
903  {
904  throw eh + "ROOT is running in batch mode.";
905  }
906  TApplication::NeedGraphicsLibs();
907  gApplication->InitializeGraphics();
908  if (gROOT->IsBatch() || gClient == 0 || gClient->IsZombie())
909  {
910  throw eh + "window system not initialized.";
911  }
912 
913  Int_t w = 1024;
914  Int_t h = 768;
915 
916  TEveUtil::SetupEnvironment();
917  TEveUtil::SetupGUI();
918  gEve = new TEveManager(w, h, map_window, opt);
919  }
920  return gEve;
921 }
922 
923 ////////////////////////////////////////////////////////////////////////////////
924 /// Properly terminate global TEveManager.
925 
926 void TEveManager::Terminate()
927 {
928  if (!gEve) return;
929 
930  TEveGedEditor::DestroyEditors();
931 
932  delete gEve;
933  gEve = 0;
934 }
935 
936 /** \class TEveManager::TExceptionHandler
937 \ingroup TEve
938 Exception handler for Eve exceptions.
939 */
940 
941 ClassImp(TEveManager::TExceptionHandler);
942 
943 ////////////////////////////////////////////////////////////////////////////////
944 /// Handle exceptions deriving from TEveException.
945 
946 TStdExceptionHandler::EStatus
947 TEveManager::TExceptionHandler::Handle(std::exception& exc)
948 {
949  TEveException* ex = dynamic_cast<TEveException*>(&exc);
950  if (ex) {
951  Info("Handle", "%s", ex->Data());
952  gEve->SetStatusLine(ex->Data());
953  gSystem->Beep();
954  return kSEHandled;
955  } else {
956  return kSEProceed;
957  }
958 }